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