-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpret.scm
65 lines (52 loc) · 1.51 KB
/
interpret.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
(define primitive-environment
`((apply . ,apply) (assq . ,assq)
(car . ,car) (cadr . ,cadr) (caddr . ,caddr)
(cadddr . ,cadddr) (cddr . ,cddr) (cdr . ,cdr)
(cons . ,cons) (eq? . ,eq?) (list . ,list) (map . ,map)
(memv . ,memv) (null? . ,null?) (pair? . ,pair?)
(read . ,read) (set-car! . ,set-car!)
(set-cdr! . ,set-cdr!) (symbol? . ,symbol?)))
(define new-env
(lambda (formals actuals env)
(cond
((null? formals) env)
((symbol? formals) (cons (cons formals actuals) env))
(else
(cons
(cons (car formals) (car actuals))
(new-env(cdr formals) (cdr actuals) env))))))
(define lookup
(lambda (var env)
(cdr (assq var env))))
(define assign
(lambda (var val env)
(set-cdr! (assq var env) val)))
(define exec
(lambda (expr env)
(cond
((symbol? expr) (lookup expr env))
((pair? expr)
(case (car expr)
((quote) (cadr expr))
((lambda)
(lambda vals
(let ((env (new-env (cadr expr) vals env)))
(let loop ((exprs (cddr expr)))
(if (null? (cdr exprs))
(exec (car exprs) env)
(begin
(exec (car exprs) env)
(loop (cdr exprs))))))))
((if)
(if (exec (cadr expr) env)
(exec (caddr expr) env)
(exec (cadddr expr) env)))
((set!) (assign (cadr expr) (exec (caddr expr) env) env))
(else
(apply
(exec (car expr) env)
(map (lambda (x) (exec x env)) (cdr expr))))))
(else expr))))
(define interpret
(lambda (expr)
(exec expr primitive-environment)))