@@ -11,6 +11,7 @@ import Data.List
11data DExp = DV LVar
11data DExp = DV LVar
12 | DApp Bool Name [DExp] -- True = tail call
12 | DApp Bool Name [DExp] -- True = tail call
13 | DLet Name DExp DExp -- name just for pretty printing
13 | DLet Name DExp DExp -- name just for pretty printing
14+ | DUpdate Name DExp -- eval expression, then update var with it
14 | DProj DExp Int
15 | DProj DExp Int
15 | DC Int Name [DExp]
16 | DC Int Name [DExp]
16 | DCase DExp [DAlt]
17 | DCase DExp [DAlt]
@@ -87,6 +88,8 @@ addApps defs (n, LFun _ args e) = (n, DFun n args (aa args e))
87 aa env (LForce e) = eEVAL (aa env e)
88 aa env (LForce e) = eEVAL (aa env e)
88 aa env (LLet n v sc) = DLet n (aa env v) (aa (n : env) sc)
89 aa env (LLet n v sc) = DLet n (aa env v) (aa (n : env) sc)
89 aa env (LCon i n args) = DC i n (map (aa env) args)
90 aa env (LCon i n args) = DC i n (map (aa env) args)
91+ aa env (LProj t@(LV (Glob n)) i)
92+ = DProj (DUpdate n (eEVAL (aa env t))) i
90 aa env (LProj t i) = DProj (eEVAL (aa env t)) i
93 aa env (LProj t i) = DProj (eEVAL (aa env t)) i
91 aa env (LCase e alts) = DCase (eEVAL (aa env e)) (map (aaAlt env) alts)
94 aa env (LCase e alts) = DCase (eEVAL (aa env e)) (map (aaAlt env) alts)
92 aa env (LConst c) = DConst c
95 aa env (LConst c) = DConst c
@@ -115,11 +118,33 @@ addApps defs (n, LFun _ args e) = (n, DFun n args (aa args e))
115 chainAPPLY f [] = f
118 chainAPPLY f [] = f
116 chainAPPLY f (a : as) = chainAPPLY (DApp False (MN 0 "APPLY") [f, a]) as
119 chainAPPLY f (a : as) = chainAPPLY (DApp False (MN 0 "APPLY") [f, a]) as
121+ -- if anything in the DExp is projected from, we'll need to evaluate it,
122+ -- but we only want to do it once, rather than every time we project.
126+ | needsEval x t = DLet x (eEVAL (DV (Glob x))) (preEval xs t)
127+ | otherwise = preEval xs t
129+ needsEval x (DApp _ _ args) = or (map (needsEval x) args)
130+ needsEval x (DC _ _ args) = or (map (needsEval x) args)
131+ needsEval x (DCase e alts) = needsEval x e || or (map nec alts)
132+ where nec (DConCase _ _ _ e) = needsEval x e
133+ nec (DConstCase _ e) = needsEval x e
134+ nec (DDefaultCase e) = needsEval x e
135+ needsEval x (DLet n v e)
136+ | x == n = needsEval x v
137+ | otherwise = needsEval x v || needsEval x e
138+ needsEval x (DForeign _ _ _ args) = or (map (needsEval x) (map snd args))
139+ needsEval x (DOp op args) = or (map (needsEval x) args)
140+ needsEval x (DProj (DV (Glob x')) _) = x == x'
141+ needsEval x _ = False
118eEVAL x = DApp False (MN 0 "EVAL") [x]
143eEVAL x = DApp False (MN 0 "EVAL") [x]
120−data EvalApply a = EvalCase a
145+data EvalApply a = EvalCase (Name -> a)
121 | ApplyCase a
146 | ApplyCase a
122− deriving Show
147+-- deriving Show
124-- For a function name, generate a list of
149-- For a function name, generate a list of
125-- data constuctors, and whether to handle them in EVAL or APPLY
150-- data constuctors, and whether to handle them in EVAL or APPLY
@@ -127,26 +152,29 @@ data EvalApply a = EvalCase a
127toCons :: (Name, Int) -> [(Name, Int, EvalApply DAlt)]
152toCons :: (Name, Int) -> [(Name, Int, EvalApply DAlt)]
128toCons (n, i)
153toCons (n, i)
129 = (mkFnCon n, i,
154 = (mkFnCon n, i,
130− EvalCase (DConCase (-1) (mkFnCon n) (take i (genArgs 0))
156+ (DConCase (-1) (mkFnCon n) (take i (genArgs 0))
131− (eEVAL (DApp False n (map (DV . Glob) (take i (genArgs 0)))))))
158+ (eEVAL (DApp False n (map (DV . Glob) (take i (genArgs 0)))))))))
132− : mkApplyCase n 0 i
159+ : mkApplyCase n 0 i
160+ where dupdate tlarg x = x
134mkApplyCase fname n ar | n == ar = []
162mkApplyCase fname n ar | n == ar = []
135mkApplyCase fname n ar
163mkApplyCase fname n ar
136 = let nm = mkUnderCon fname (ar - n) in
164 = let nm = mkUnderCon fname (ar - n) in
137 (nm, n, ApplyCase (DConCase (-1) nm (take n (genArgs 0))
165 (nm, n, ApplyCase (DConCase (-1) nm (take n (genArgs 0))
138− (DApp False (mkUnderCon fname (ar - (n + 1)))
166+ (DApp False (mkUnderCon fname (ar - (n + 1)))
139− (map (DV . Glob) (take n (genArgs 0) ++
167+ (map (DV . Glob) (take n (genArgs 0) ++
140− [MN 0 "arg"])))))
168+ [MN 0 "arg"])))))
141 : mkApplyCase fname (n + 1) ar
169 : mkApplyCase fname (n + 1) ar
143mkEval :: [(Name, Int, EvalApply DAlt)] -> (Name, DDecl)
171mkEval :: [(Name, Int, EvalApply DAlt)] -> (Name, DDecl)
144mkEval xs = (MN 0 "EVAL", DFun (MN 0 "EVAL") [MN 0 "arg"]
172mkEval xs = (MN 0 "EVAL", DFun (MN 0 "EVAL") [MN 0 "arg"]
145− (mkBigCase (MN 0 "EVAL") 256 (DV (Glob (MN 0 "arg")))
173+ (mkBigCase (MN 0 "EVAL") 256 (DV (Glob (MN 0 "arg")))
146− (mapMaybe evalCase xs ++
174+ (mapMaybe evalCase xs ++
147− [DDefaultCase (DV (Glob (MN 0 "arg")))])))
175+ [DDefaultCase (DV (Glob (MN 0 "arg")))])))
149− evalCase (n, t, EvalCase x) = Just x
177+ evalCase (n, t, EvalCase x) = Just (x (MN 0 "arg"))
150 evalCase _ = Nothing
178 evalCase _ = Nothing
152mkApply :: [(Name, Int, EvalApply DAlt)] -> (Name, DDecl)
180mkApply :: [(Name, Int, EvalApply DAlt)] -> (Name, DDecl)
@@ -180,6 +208,7 @@ instance Show DExp where
180 showSep ", " (map (show' env) args) ++")"
208 showSep ", " (map (show' env) args) ++")"
181 show' env (DLet n v e) = "let " ++ show n ++ " = " ++ show' env v ++ " in " ++
209 show' env (DLet n v e) = "let " ++ show n ++ " = " ++ show' env v ++ " in " ++
182 show' (env ++ [show n]) e
210 show' (env ++ [show n]) e
211+ show' env (DUpdate n e) = "!update " ++ show n ++ "(" ++ show' env e ++ ")"
183 show' env (DC i n args) = show n ++ ")" ++ showSep ", " (map (show' env) args) ++ ")"
212 show' env (DC i n args) = show n ++ ")" ++ showSep ", " (map (show' env) args) ++ ")"
184 show' env (DProj t i) = show t ++ "!" ++ show i
213 show' env (DProj t i) = show t ++ "!" ++ show i
185 show' env (DCase e alts) = "case " ++ show' env e ++ " of {\n\t" ++
214 show' env (DCase e alts) = "case " ++ show' env e ++ " of {\n\t" ++