-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUtils.hs
37 lines (32 loc) · 1.07 KB
/
Utils.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
module Utils where
import VM
import Data.Set
import qualified LC
fvs :: LExpr -> Set String
fvs e = case e of
Var l v -> singleton v
Lam l v b -> delete v $ fvs b
App l m n -> fvs m `union` fvs n
_ -> empty
inline :: LExpr -> LExpr
inline e = inline' e where
inline' e = case e of
App l n@(Lam l' v b) m | isValue m && fvs m == empty -> replace v (inline m) (inline b)
| otherwise -> App l (inline n) (inline m)
Lam l v b -> Lam l v $ inline' b
e -> e
replace v m e = case e of
Var l v' -> if v' == v then m else e
Lam l v' b -> if v' == v then e else Lam l v' $ replace v m b
App l n o -> App l (replace v m n) (replace v m o)
_ -> e
deadCodeElim :: LExpr -> LExpr
deadCodeElim e = case e of
App l (Lam l' v b) m | not (member v $ fvs b') -> b'
| otherwise -> App l (Lam l' v b') $ deadCodeElim m
where b' = deadCodeElim b
Lam l v b -> Lam l v $ deadCodeElim b
e -> e
opt :: LExpr -> LExpr
opt = inline . deadCodeElim
-- lifts every let binding to right below its lowest binding variable.