/
eval
38 lines (35 loc) · 1.07 KB
/
eval
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
#lang racket
(define eval-expr
(lambda (expr env)
(match expr
[(? number?) expr]
[(? string?) expr]
['null '()]
[#f #f]
[#t #t]
[`(quote ,datum) datum]
[`(null? ,e) (null? (eval-expr e env))]
[`(not ,e) (not (eval-expr e env))]
[`(* ,e1 ,e2) (* (eval-expr e1 env) (eval-expr e2 env))]
[`(sub1 ,e) (sub1 (eval-expr e env))]
[`(zero? ,e) (zero? (eval-expr e env))]
[`(if ,e1 ,e2 ,e3) (if (eval-expr e1 env)
(eval-expr e2 env)
(eval-expr e3 env))]
[(? symbol?) (lookup expr env)] ; var
[`(lambda (,x) ,body)
`(closure ,x ,body ,env)]
[`(,e1 ,e2)
(let ((proc (eval-expr e1 env))
(arg (eval-expr e2 env)))
(match proc
[`(closure ,x ,body ,env^)
(eval-expr body `((,x . ,arg) . ,env^))]))])))
(define lookup
(lambda (x env)
(match env
['() (error "unbound variable")]
[`((,y . ,v) . ,rest)
(if (equal? x y)
v
(lookup x rest))])))