-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPufCompilerTypes.hs
186 lines (167 loc) · 5.68 KB
/
PufCompilerTypes.hs
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
module PufCompilerTypes where
import PufAST
import qualified Data.Map as Map
import qualified Data.Set as Set
data Instruction
= Mkbasic
| Getbasic
| Eval
| Add
| Sub
| Mul
| Div
| Leq
| Eq
| Apply
| Update
| Halt
| Neg
| Not
| Mod
| Neq
| Le
| Geq
| Gr
| Or
| And
| Nil
| Cons
| Loadc Int
| Pushloc Int
| Pushglob Int
| Targ Int
| Return Int
| Slide Int
| Alloc Int
| Rewrite Int
| Mkvec Int
| Getvec Int
| Get Int
| Mkclos Int
| Mkfunval Int
| Mark Int
| Jumpz Int
| Jump Int
| Tlist Int
| Move Int Int
| Label Int
| Cat Instruction Instruction
deriving (Show,Eq)
data VariableType = Local
| Global
deriving (Show)
type InstList = Instruction
type Environment = Map.Map String (VariableType,Int)
initialEnvironment = Map.empty :: Environment
envSingle :: String -> (VariableType,Int) -> Environment
envSingle k a = Map.singleton k a
envAdd :: Environment -> (String,(VariableType,Int)) -> Environment
envAdd e (name,v) = Map.insert name v e
envGet :: String -> Environment -> (VariableType,Int)
envGet name e = case Map.lookup name e of
Just r -> r
Nothing -> error ("Unknown variable " ++ name)
envUnion :: Environment -> Environment -> Environment
{- Map.union prefers elements from the left map,
- but when using envUnion we want to prefer
- elements from right map because that is more local scope.
-}
envUnion m1 m2 = Map.unionWith (\_ b -> b) m1 m2
data CompilerState = CompilerState Int
deriving (Show)
initialState = CompilerState 0
infixr 6 <>
(<>) :: InstList -> InstList -> InstList
x <> y = Cat x y
free :: AST String -> [String]
free ast = Set.elems $ free' Set.empty ast
type Variables = Set.Set String
free' :: Variables -> AST String -> Variables
free' bound (Var name) = if Set.member name bound then Set.empty
else Set.singleton name
free' _ (Num _) = Set.empty
free' _ (Prim _) = Set.empty
free' b (Cond c e0 e1) = free' b c `Set.union` free' b e0
`Set.union` free' b e1
free' b (Fun name e) = free' (Set.insert name b) e
free' b (App e0 e1) = free' b e0 `Set.union` free' b e1
free' bound (Let decls e)
= let bounds = scanl Set.union bound (
map (\l -> case l of
Sdecl n _ -> Set.singleton n
Tdecl ns _ -> foldl (\s e -> Set.insert e s)
Set.empty ns
) decls
)
in foldl1 Set.union
(zipWith (\l b -> case l of
Sdecl _ e -> free' b e
Tdecl _ e -> free' b e
) decls bounds)
free' b (Tuple exprs) = foldl (\s e -> Set.union s (free' b e)) Set.empty exprs
free' b (Select _ e) = free' b e
free' _ (PufAST.Nil) = Set.empty
free' b (PufAST.Cons e0 e1) = free' b e0 `Set.union` free' b e1
free' b (Case e0 e1 h t e2) = free' b e0 `Set.union` free' b e1 `Set.union`
free' (foldr Set.insert b [h,t]) e2
printInstruction :: Instruction -> String
printInstruction x = case x of
Mkbasic -> "mkbasic"
Getbasic -> "getbasic"
Eval -> "eval"
Add -> "add"
Sub -> "sub"
Mul -> "mul"
Div -> "div"
Leq -> "leq"
Eq -> "eq"
Apply -> "apply"
Update -> "update"
Halt -> "halt"
Neg -> "neg"
Not -> "not"
Mod -> "mod"
Neq -> "neq"
Le -> "le"
Geq -> "geq"
Gr -> "gr"
Or -> "or"
And -> "and"
PufCompilerTypes.Nil -> "nil"
PufCompilerTypes.Cons -> "cons"
Loadc i -> "loadc " ++ show i
Pushloc i -> "pushloc " ++ show i
Pushglob i -> "pushglob " ++ show i
Targ i -> "targ " ++ show i
Return i -> "return " ++ show i
Slide i -> "slide " ++ show i
Alloc i -> "alloc " ++ show i
Rewrite i -> "rewrite " ++ show i
Mkvec i -> "mkvec " ++ show i
Getvec i -> "getvec " ++ show i
Get i -> "get " ++ show i
Mkclos i -> "mkclos _" ++ show i
Mkfunval i -> "mkfunval _" ++ show i
Mark i -> "mark _" ++ show i
Jumpz i -> "jumpz _" ++ show i
Jump i -> "jump _" ++ show i
Tlist i -> "tlist _" ++ show i
Move i1 i2 -> "move " ++ show i1 ++ " " ++ show i2
Label i -> "\t_" ++ show i ++ ":"
_ -> error "pInst"
builtinInst :: Builtin -> Instruction
builtinInst UNeg = Neg
builtinInst UNot = Not
builtinInst BAdd = Add
builtinInst BSub = Sub
builtinInst BMul = Mul
builtinInst BDiv = Div
builtinInst BMod = Mod
builtinInst BEq = Eq
builtinInst BNe = Neq
builtinInst BLe = Leq
builtinInst BLt = Le
builtinInst BGe = Geq
builtinInst BGt = Gr
builtinInst BOr = Or
builtinInst BAnd = And