1+ module TermReducer where
2+
3+ import CLTerm
4+
5+
6+ -- data CL = Com Combinator | INT Integer | CL :@ CL
7+
8+ reduce :: CL -> IO CL
9+ reduce (Com c) = pure $ Com c
10+ reduce (INT i) = pure $ INT i
11+ reduce (Com I :@ t) = pure t
12+ reduce (Com K :@ t :@ _) = pure t
13+ reduce (Com S :@ t :@ u :@ v) = pure $ (t :@ v) :@ (u :@ v)
14+ reduce (Com B :@ f :@ g :@ x) = pure $ f :@ (g :@ x) -- B F G X = F (G X)
15+ reduce (Com C :@ t :@ u :@ v) = pure $ t :@ v :@ u
16+ reduce (Com Y :@ t) = pure $ t :@ (Com Y :@ t)
17+ reduce (Com P :@ t :@ u) = pure $ Com P :@ t :@ u
18+ reduce (Com R :@ t :@ u) = pure $ Com R :@ t :@ u
19+ reduce (Com ADD :@ INT i :@ INT j) = pure $ INT (i + j)
20+ reduce (Com ADD :@ i :@ j) = do ri <- red i; rj <- red j; reduce (Com ADD :@ ri :@ rj)
21+ reduce (Com SUB :@ INT i :@ INT j) = pure $ INT (i - j)
22+ reduce (Com SUB :@ i :@ j) = do ri <- red i; rj <- red j; reduce (Com SUB :@ ri :@ rj)
23+ reduce (Com MUL :@ INT i :@ INT j) = pure $ INT (i * j)
24+ reduce (Com MUL :@ i :@ j) = do ri <- red i; rj <- red j; reduce (Com MUL :@ ri :@ rj)
25+ reduce (Com DIV :@ INT i :@ INT j) = pure $ INT (i `div` j)
26+ reduce (Com DIV :@ i :@ j) = do ri <- red i; rj <- red j; reduce (Com DIV :@ ri :@ rj)
27+ reduce (Com REM :@ INT i :@ INT j) = pure $ INT (i `rem` j)
28+ reduce (Com REM :@ i :@ j) = do ri <- red i; rj <- red j; reduce (Com REM :@ ri :@ rj)
29+ reduce (Com SUB1 :@ INT i) = pure $ INT (i - 1 )
30+ reduce (Com SUB1 :@ i) = do ri <- red i; reduce (Com SUB1 :@ ri)
31+ reduce (Com EQL :@ INT i :@ INT j) = if i == j then pure $ INT 1 else pure $ INT 0
32+ reduce (Com EQL :@ i :@ j) = do ri <- red i; rj <- red j; reduce (Com EQL :@ ri :@ rj)
33+ reduce (Com GEQ :@ INT i :@ INT j) = if i >= j then pure $ INT 1 else pure $ INT 0
34+ reduce (Com GEQ :@ i :@ j) = do ri <- red i; rj <- red j; reduce (Com GEQ :@ ri :@ rj)
35+ reduce (Com ZEROP :@ INT i) = if i == 0 then pure $ INT 1 else pure $ INT 0
36+ reduce (Com ZEROP :@ i) = do ri <- red i; reduce (Com ZEROP :@ ri)
37+ reduce (Com IF :@ (INT t) :@ u :@ v) = if t == 1 then red u else red v
38+ reduce (Com IF :@ t :@ u :@ v) = do rt <- red t; if rt == INT 1 then red u else red v
39+ reduce (Com B' :@ t :@ u :@ v) = pure $ t :@ (u :@ v)
40+ reduce (Com C' :@ t :@ u :@ v) = pure $ t :@ v :@ u
41+ reduce (Com S' :@ t :@ u :@ v) = pure $ (t :@ v) :@ (u :@ v)
42+ reduce (Com T :@ t) = reduce t
43+ reduce (t :@ u) = do rt <- red t; ru <- red u; reduce $ rt :@ ru
44+
45+ red :: CL -> IO CL
46+ red x@ (INT i) = do print x; pure x
47+ red x@ (Com c) = do print x; pure x
48+ red x = do print x; red =<< reduce x
0 commit comments