blob: 1a7a907bb123f8bf9c672d19a4fd7f613b044129 (
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
|
module Codegen(codegen) where
-- import Control.Monad
-- import Data.Maybe
-- import qualified Data.Map.Strict as Map
import qualified LLVM.General.AST.Type as A
import qualified LLVM.General.AST.Global as A.G
import qualified LLVM.General.AST.Constant as A.C
-- import qualified LLVM.General.AST.Operand as A
-- import qualified LLVM.General.AST.Name as A
-- import qualified LLVM.General.AST.Instruction as A
import qualified LLVM.General.AST as A
-- import Debug.Trace
import AST
type Error a = Either String a
codegen :: Program -- Program to compile
-> String -- Module name
-> String -- File name of source
-> Error A.Module
codegen prog name fname = do
defs <- generateDefs prog
return $ A.defaultModule {
A.moduleName = name,
A.moduleSourceFileName = fname,
A.moduleDefinitions = defs
}
generateDefs :: Program -> Error [A.Definition]
generateDefs prog = do
vardecls <- genGlobalVars prog
return vardecls
genGlobalVars :: Program -> Error [A.Definition]
genGlobalVars (Program decs) = mapM gen $ filter isDecVariable decs
where
gen (DecVariable t n Nothing) = return $ A.GlobalDefinition $
A.globalVariableDefaults {
A.G.name = A.Name n,
A.G.type' = toLLVMType t,
A.G.initializer = Just $ initializerFor t
}
gen (DecVariable _ _ (Just _)) = Left $ "Initialised global variables not supported yet"
gen _ = undefined
toLLVMType :: Type -> A.Type
toLLVMType (TypeInt s) = A.IntegerType $ fromIntegral s
toLLVMType (TypeUInt s) = A.IntegerType $ fromIntegral s
toLLVMType TypeFloat = A.float
toLLVMType TypeDouble = A.double
toLLVMType (TypePtr t) = A.ptr $ toLLVMType t
toLLVMType (TypeName _) = undefined
initializerFor :: Type -> A.C.Constant
initializerFor (TypeInt s) = A.C.Int (fromIntegral s) 0
initializerFor (TypeUInt s) = A.C.Int (fromIntegral s) 0
initializerFor _ = undefined
isDecVariable :: Declaration -> Bool
isDecVariable (DecVariable {}) = True
isDecVariable _ = False
|