blob: c7961abb0901f4f0a8d0bc8e8353b75dad91ef13 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
module Main where
import Control.Monad
import Control.Monad.Except
import Data.Either
import System.Environment
import System.Exit
import qualified Data.ByteString as BS
import qualified LLVM.General as General
import qualified LLVM.General.Analysis as General
import qualified LLVM.General.Context as General
import qualified LLVM.General.PassManager 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 withPassManager:"
General.withPassManager (General.defaultCuratedPassSetSpec {General.optLevel = Just 1}) $ \pm -> do
putStrLn "Calling moduleLLVMAssembly:"
llvmasm1 <- General.moduleLLVMAssembly genmod
putStr llvmasm1
putStrLn ""
putStrLn "Calling verify:"
res <- runExceptT (General.verify genmod)
either die return res
putStrLn "Calling runPassManager:"
modified <- General.runPassManager pm genmod
if modified
then putStrLn "Pass manager modified the module"
else putStrLn "Pass manager had no effect on the module"
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
|