2 | module Compiler.ES.ToAst
5 | import Core.CompileExpr
7 | import Compiler.ES.Ast
8 | import Compiler.ES.State
15 | tag : Name -> Maybe Int -> Tag
16 | tag n Nothing = TypeCon n
17 | tag n (Just i) = DataCon i n
20 | assign : (e : Effect) -> Exp -> Stmt (Just e)
21 | assign Returns = Return
22 | assign (ErrorWithout v) = Assign v
25 | getInteger : NamedCExp -> Maybe Integer
26 | getInteger (NmPrimVal _ $
BI x) = Just x
27 | getInteger x = integerArith x
33 | integerArith : NamedCExp -> Maybe Integer
34 | integerArith (NmOp _ (Add IntegerType) [x,y]) =
35 | [| getInteger x + getInteger y |]
36 | integerArith (NmOp _ (Mul IntegerType) [x,y]) =
37 | [| getInteger x * getInteger y |]
38 | integerArith _ = Nothing
51 | lift : { auto c : Ref ESs ESSt }
53 | -> (filter : Exp -> Maybe a)
54 | -> (fromVar : Var -> a)
55 | -> Core (List (Stmt Nothing), a)
56 | lift n filter fromVar = do
58 | b <- stmt (ErrorWithout l) n
59 | let pair = ([declare b], fromVar l)
62 | Assign _ e => pure $
maybe pair (the (List _) [],) (filter e)
70 | liftArg : { auto c : Ref ESs ESSt }
72 | -> Core (List (Stmt Nothing), Exp)
74 | f <- isArg <$> get ESs
75 | lift x (\e => guard (f e) $> e) (EMinimal . MVar)
79 | liftFun : { auto c : Ref ESs ESSt }
81 | -> Core (List (Stmt Nothing), Exp)
83 | f <- isFun <$> get ESs
84 | lift x (\e => guard (f e) $> e) (EMinimal . MVar)
88 | liftArgsVect : { auto c : Ref ESs ESSt }
90 | -> Core (List (Stmt Nothing), Vect n Exp)
91 | liftArgsVect xs = do
92 | ps <- traverseVect liftArg xs
93 | pure (concatMap fst ps, map snd ps)
97 | liftArgs : { auto c : Ref ESs ESSt }
99 | -> Core (List (Stmt Nothing), List Exp)
101 | ps <- traverse liftArg xs
102 | pure (concatMap fst ps, map snd ps)
109 | liftMinimal : { auto c : Ref ESs ESSt }
111 | -> Core (List (Stmt Nothing), Minimal)
112 | liftMinimal n = lift n toMinimal MVar
115 | lambda : {auto c : Ref ESs ESSt} -> Name -> NamedCExp -> Core Exp
116 | lambda n x = go [n] x
117 | where go : List Name -> NamedCExp -> Core Exp
118 | go ns (NmLam _ n x) = go (n :: ns) x
120 | vs <- traverse registerLocal (reverse ns)
121 | ELam vs <$> stmt Returns x
125 | stmt : {auto c : Ref ESs ESSt}
128 | -> Core (Stmt $
Just e)
130 | stmt e (NmLocal _ n) = assign e . EMinimal <$> getOrRegisterLocal n
133 | stmt e (NmRef _ n) = assign e . EMinimal . MVar <$> getOrRegisterRef n
135 | stmt e (NmLam _ n x) = assign e <$> lambda n x
141 | stmt e (NmLet _ n y z) = do
143 | b1 <- stmt (ErrorWithout v) y
144 | addLocal n (MVar v)
146 | pure $
prepend [declare b1] b2
151 | stmt e (NmApp _ x xs) = do
152 | (mbx, vx) <- liftFun x
153 | (mbxs, args) <- liftArgs xs
154 | pure . prepend (mbx ++ mbxs) $
assign e (EApp vx args)
156 | stmt e (NmCon _ n ci tg xs) = do
157 | (mbxs, args) <- liftArgs xs
158 | pure . prepend mbxs $
assign e (ECon (tag n tg) ci args)
160 | stmt e o@(NmOp _ x xs) =
161 | case integerArith o of
162 | Just n => pure . assign e $
EPrimVal (BI n)
164 | (mbxs, args) <- liftArgsVect xs
165 | pure . prepend mbxs $
assign e (EOp x args)
167 | stmt e (NmExtPrim _ n xs) = do
168 | (mbxs, args) <- liftArgs xs
169 | pure . prepend mbxs $
assign e (EExtPrim n args)
171 | stmt e (NmForce _ _ x) = do
172 | (mbx, vx) <- liftFun x
173 | pure . prepend mbx $
assign e (EApp vx [])
175 | stmt e (NmDelay _ _ x) = assign e . ELam [] <$> stmt Returns x
181 | stmt e (NmConCase _ sc [x] Nothing) = do
182 | (mbx, vx) <- liftMinimal sc
183 | b <- body <$> conAlt e vx x
184 | pure $
prepend mbx b
188 | stmt e (NmConCase _ _ [] (Just x)) = stmt e x
193 | stmt e (NmConCase _ sc xs x) = do
194 | (mbx, vx) <- liftMinimal sc
195 | alts <- traverse (conAlt e vx) xs
196 | def <- traverseOpt (stmt e) x
197 | pure . prepend mbx $
ConSwitch e vx alts def
201 | stmt e (NmConstCase _ _ [x] Nothing) = body <$> constAlt e x
202 | stmt e (NmConstCase _ _ [] (Just x)) = stmt e x
203 | stmt e (NmConstCase _ sc xs x) = do
204 | (mbx, ex) <- liftArg sc
205 | alts <- traverse (constAlt e) xs
206 | def <- traverseOpt (stmt e) x
207 | pure . prepend mbx $
ConstSwitch e ex alts def
209 | stmt e (NmPrimVal _ x) = pure . assign e $
EPrimVal x
211 | stmt e (NmErased _) = pure . assign e $
EErased
213 | stmt _ (NmCrash _ x) = pure $
Error x
216 | conAlt : { auto c : Ref ESs ESSt }
218 | -> (scrutinee : Minimal)
220 | -> Core (EConAlt e)
221 | conAlt e sc (MkNConAlt n ci tg args x) = do
225 | projections sc args
226 | MkEConAlt (tag n tg) ci <$> stmt e x
229 | constAlt : { auto c : Ref ESs ESSt }
232 | -> Core (EConstAlt e)
233 | constAlt e (MkNConstAlt c x) = MkEConstAlt c <$> stmt e x