-
Notifications
You must be signed in to change notification settings - Fork 55
/
Copy pathcek.clj
86 lines (78 loc) · 1.62 KB
/
cek.clj
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
(ns cek
(:require [meander.epsilon :as m]))
;; C ::= x
;; | (lambda x t)
;; | (t1 t2)
;; E ::= {x ((lambda x t) E)}
;; K ::= Done
;; | (EArg t, E, K)
;; | (Call t, E, K)
(defn step [state]
(m/rewrite state
{:C (m/pred symbol? ?x)
:E {?x (?lambda ?E*)}
:K ?K}
;; =>
{:C ?lambda
:E ?E*
:K ?K}
{:C (?t1 ?t2)
:E ?E
:K ?K}
;; =>
{:C ?t1
:E ?E
:K (EArg ?t2 ?E ?K)}
{:C (lambda ?x ?t)
:E ?E
:K (EArg ?t* ?E* ?K)}
;; =>
{:C ?t*
:E ?E*
:K (ECall (lambda ?x ?t) ?E ?K)}
{:C (lambda ?x ?t :as ?lambda)
:E ?E
:K (ECall (lambda ?y ?t*) ?E* ?K)}
;; =>
{:C ?t*
:E {?y (?lambda ?E) & ?E*}
:K ?K}
?state
;; =>
?state))
(defn steps [state]
(m/rewrite (iterate step state)
(!states ... ?state ?state & _)
[!states ... ?state]))
(comment
(steps '{:C ((lambda x x) ((lambda y y) (lambda z z)))
:E {}
:K Done})
;; =>
[{:C ((lambda x x) ((lambda y y) (lambda z z)))
:E {}
:K Done}
{:C (lambda x x)
:E {}
:K (EArg ((lambda y y) (lambda z z)) {} Done)}
{:C ((lambda y y) (lambda z z))
:E {}
:K (ECall (lambda x x) {} Done)}
{:C (lambda y y)
:E {}
:K (EArg (lambda z z) {} (ECall (lambda x x) {} Done))}
{:C (lambda z z)
:E {}
:K (ECall (lambda y y) {} (ECall (lambda x x) {} Done))}
{:C y
:E {y ((lambda z z) {})}
:K (ECall (lambda x x) {} Done)}
{:C (lambda z z)
:E {}
:K (ECall (lambda x x) {} Done)}
{:C x
:E {x ((lambda z z) {})}
:K Done}
{:C (lambda z z)
:E {}
:K Done}])