-
Notifications
You must be signed in to change notification settings - Fork 1
/
CompLam.hs
112 lines (90 loc) · 2.44 KB
/
CompLam.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
module CompLam where
import Control.Monad.State
import BigArray
data Inst
= Push Int | PushReg | Restack | Swap | Pop
| Cons | Decons
| Load Int | Add
deriving Show
data Exit = Jump Int | Return
deriving Show
type Block = ([Inst], Exit)
type Heap v = (Int, Arr Int v)
type Prog = Heap Block
type Store = Heap (Int, Int)
alloc :: v -> State (Heap v) Int
alloc v = do
(n, vs) <- get
put (n + 1, insertArr (n, v) vs)
return n
hunt :: Int -> State (Heap v) v
hunt i = do
(n, vs) <- get
let Just v = findArr i vs
return v
type Config =
( Int -- register
, [Int] -- stack
, Store
)
inst :: Config -> Inst -> Config
inst (r, s, m) (Push i) = (r, i : s, m)
inst (r, s, m) PushReg = (r, r : s, m)
inst (r, h : s, m) Restack = (h, r : s, m)
inst (r, x : y : s, m) Swap = (r, y : x : s, m)
inst (r, _ : s, m) Pop = (r, s, m)
inst (r, x : s, m) Cons = (r', s, m') where
(r', m') = runState (alloc (x, r)) m
inst (r, s, m) Decons = (r', x : s, m) where
(x, r') = evalState (hunt r) m
inst (_, s, m) (Load n) = (n, s, m)
inst (x, y : s, m) Add = (x + y, s, m)
run :: Prog -> Exit -> Config -> (Int, Store)
run p Return (r, [], m) = (r, m)
run p Return (r, i : s, m) = run p (Jump i) (r, s, m)
run p (Jump i) c = run p e (foldl inst c is) where
(is, e) = evalState (hunt i) p
data Tm
= V Int
| L Tm
| Tm :$ Tm
| N Int
| Tm :+ Tm
deriving Show
compile :: [Inst] -- prefix
-> Tm -- code
-> Int -- exit point
-> State Prog Int
compile is (L t) k = do
ret <- alloc ([], Return)
bod <- compile [] t ret
alloc (is ++ [Push bod, Cons], Jump k)
compile is (V i) k =
alloc (is ++ concat (replicate i [Decons, Pop]) ++ [Decons, Restack, Pop], Jump k)
compile is (f :$ s) k = do
fin <- alloc ([Decons, Swap, Cons, Push k, Swap], Return)
fun <- compile [Restack] f fin
compile (is ++ [PushReg]) s fun
compile is (N n) k = alloc (is ++ [Load n], Jump k)
compile is (s :+ t) k = do
add <- alloc ([Add], Jump k)
s' <- compile [Restack] s add
compile (is ++ [PushReg]) t s'
topLevel :: Tm -> (Int, Prog)
topLevel t = runState p (0, emptyArr)
where
p = do
ret <- alloc ([], Return)
compile [] t ret
try :: Tm -> (Int, Store)
try t = run p (Jump e) (negate 1, [], (0, emptyArr)) where
(e, p) = topLevel t
---
cze :: Tm
cze = L (L (V 0))
csu :: Tm
csu = L (L (L (V 1 :$ ((V 2 :$ V 1) :$ V 0))))
c2 :: Tm
c2 = csu :$ (csu :$ cze)
nsu :: Tm
nsu = L (N 1 :+ V 0)