forked from vizziv/Dwimiykwim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemo.scm
150 lines (115 loc) · 2.86 KB
/
demo.scm
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
;;;; Demo: an evaluator for arithmetic expressions with let bindings
;;; Arithmetic
(define (binop? exp)
(and (pair? exp)
(member (car exp) '(+ - * /))))
(define (binop-op (exp binop?))
(car exp))
(define (binop-left (exp binop?))
(cadr exp))
(define (binop-right (exp binop?))
(caddr exp))
(define (apply-binop (op symbol?)
(left (~~? 'left))
(right (~~? 'right)))
((cadr (assq op
(list (list '+ +)
(list '- -)
(list '* *)
(list '/ /))))
left
right))
;; ;dwimiykwim>
;; (apply-binop '+ (~~ 'left 4) (~~ 'right 2))
;; ;=> 6
;; ;dwimiykwim>
;; (apply-binop '- (~~ 'left 4) (~~ 'right 2))
;; ;=> 2
;; ;dwimiykwim>
;; (apply-binop '- (~~ 'right 4) (~~ 'left 2))
;; ;=> -2
(define (exp? x)
(null? (tags x)))
(define (primitive? (exp exp?))
(number? exp))
(define (operation? (exp exp?))
(binop? exp))
(define (eval (exp exp?))
(cond
((?? primitive?)
exp)
((?? operation?)
(madblock-inherit
(~~ 'left (?? eval (?? binop-left)))
(~~ 'right (?? eval (?? binop-right)))
(?? binop-op)
(?? apply-binop)))))
;; ;dwimiykwim>
;; (eval '(- (+ 3 4) 9))
;; ;=> -2
;;; Let bindings
(define ctx?
(~~? 'ctx))
(define empty-ctx
(~~ 'ctx '()))
(define (list-of p?)
(lambda (xs)
(and (list? xs)
(every p? xs))))
(define (extend-ctx (ctx ctx?)
(vars (list-of symbol?))
(vals (list-of number?)))
(~~ 'ctx (append (map list vars vals)
(~~:delq 'ctx ctx))))
(define (lookup (ctx ctx?)
(var symbol?))
(cadr (assq var ctx)))
(define (let? exp)
(and (pair? exp)
(eq? (car exp) 'let)))
(define (let-vars (exp let?))
(map car (cadr exp)))
(define (let-vals (exp let?))
(map cadr (cadr exp)))
(define (let-body (exp let?))
(caddr exp))
;; ;dwimiykwim>
;; (let-vars '(let ((x (+ 2 2))) (+ x 2)))
;; ;=> (x)
;; ;dwimiykwim>
;; (let-vals '(let ((x (+ 2 2))) (+ x 2)))
;; ;=> ((+ 2 2))
;; ;dwimiykwim>
;; (let-body '(let ((x (+ 2 2))) (+ x 2)))
;; ;=> (+ x 2)
;; ;dwimiykwim>
;; (let? '(let ((x (+ 2 2))) (+ x 2)))
;; ;=> #t
;; ;dwimiykwim>
;; (let? '(not-let ((x (+ 2 2))) (+ x 2)))
;; ;=> #f
(define (variable? (exp exp?))
(symbol? exp))
(define (declaration? (exp exp?))
(let? exp))
(define (eval (ctx ctx?)
(exp exp?))
(cond
((?? primitive?)
exp)
((?? operation?)
(madblock-inherit
(~~ 'left (?? eval (?? binop-left)))
(~~ 'right (?? eval (?? binop-right)))
(?? binop-op)
(?? apply-binop)))
((?? variable?)
(?? lookup))
((?? declaration?)
(madblock-inherit
(map (??:apply eval) (?? let-vals))
(?? let-vars)
(eval (?? extend-ctx) (?? let-body))))))
;; ;dwimiykwim>
;; (eval empty-ctx '(let ((x (+ 2 2)) (y (- 6 3))) (+ (* x x) (* y y))))
;; ;=> 25