module Main where import Control.Monad import Control.Monad.Except import Data.Either import System.Environment import System.Exit import qualified LLVM.General as General import qualified LLVM.General.Context as General -- import qualified LLVM.General.Target as General import Check import Codegen import Parser import PShow fromLeft :: Either a b -> a fromLeft (Left a) = a fromLeft (Right _) = error "Either is not a Left" fromRight :: Either a b -> b fromRight (Right b) = b fromRight (Left _) = error "Either is not a Right" dieShow :: (Show a) => a -> IO () dieShow = die . show assert :: ExceptT String IO a -> IO a assert ex = do e <- runExceptT ex either die return e >> (return $ (\(Right r) -> r) e) main :: IO () main = do args <- getArgs when (length args /= 1) $ die "Pass NL file name as a command-line parameter" let fname = args !! 0 parseResult <- (\file -> parseProgram file fname) <$> readFile fname when (isLeft parseResult) $ dieShow $ fromLeft parseResult let ast = fromRight parseResult putStrLn $ pshow ast checked <- either die return $ checkProgram ast putStrLn "After checking:" putStrLn $ pshow checked llvmMod <- either die return $ codegen checked "Module" fname -- putStrLn "Module:" -- print llvmMod putStrLn "Calling withContext:" General.withContext $ \context -> do putStrLn "Calling withModuleFromAST:" assert $ General.withModuleFromAST context llvmMod $ \genmod -> do putStrLn "Calling moduleLLVMAssembly:" llvmasm <- General.moduleLLVMAssembly genmod putStr llvmasm putStrLn "" -- assert $ General.withHostTargetMachine $ \machine -> do -- General.getTargetMachineTriple machine >>= putStrLn -- putStrLn "" -- assert (General.moduleTargetAssembly machine genmod) -- >>= putStr -- bs <- assert $ General.moduleObject machine genmod -- BS.writeFile "output_gen.o" bs