|
1 | 1 | #lang racket |
2 | 2 | (provide (all-defined-out)) |
3 | 3 |
|
| 4 | + |
| 5 | +;; type Expr = |
| 6 | +;; ... |
| 7 | +;; | `(λ ,(Listof Variable) ,Expr) |
| 8 | + |
| 9 | +;; type Value = |
| 10 | +;; ... |
| 11 | +;; | ((Listof Value) -> Answer) |
| 12 | + |
| 13 | +;; Expr REnv -> Answer |
| 14 | +(define (interp-env e r) |
| 15 | + (match e |
| 16 | + [''() '()] |
| 17 | + [(? syntactic-value? v) v] |
| 18 | + [(list (? prim? p) es ...) |
| 19 | + (match (interp-env* es r) |
| 20 | + [(list vs ...) (interp-prim p vs)] |
| 21 | + [_ 'err])] |
| 22 | + [`(if ,e0 ,e1 ,e2) |
| 23 | + (match (interp-env e0 r) |
| 24 | + ['err 'err] |
| 25 | + [v |
| 26 | + (if v |
| 27 | + (interp-env e1 r) |
| 28 | + (interp-env e2 r))])] |
| 29 | + [(? symbol? x) |
| 30 | + (lookup r x)] |
| 31 | + [`(let ((,x ,e0)) ,e1) |
| 32 | + (match (interp-env e0 r) |
| 33 | + ['err 'err] |
| 34 | + [v |
| 35 | + (interp-env e1 (ext r x v))])] |
| 36 | + |
| 37 | + [`(λ (,xs ...) ,e) |
| 38 | + |
| 39 | + (λ (vs) (interp-env e (append (zip xs vs) r)))] |
| 40 | + |
| 41 | + [`(,e . ,es) |
| 42 | + (match (interp-env* (cons e es) r) |
| 43 | + [(list f vs ...) (f vs)] |
| 44 | + [_ 'err])])) |
| 45 | + |
| 46 | + |
| 47 | +;; (Listof Expr) REnv -> (Listof Value) | 'err |
| 48 | +(define (interp-env* es r) |
| 49 | + (match es |
| 50 | + ['() '()] |
| 51 | + [(cons e es) |
| 52 | + (match (interp-env e r) |
| 53 | + ['err 'err] |
| 54 | + [v (cons v (interp-env* es r))])])) |
| 55 | + |
| 56 | + |
| 57 | +(define Y '(λ (t) ((λ (f) (t (λ (z) ((f f) z)))) |
| 58 | + (λ (f) (t (λ (z) ((f f) z))))))) |
| 59 | + |
| 60 | +(define Tri `(,Y |
| 61 | + (λ (tri) |
| 62 | + (λ (n) |
| 63 | + (if (zero? n) |
| 64 | + 1 |
| 65 | + (+ n (tri (sub1 n)))))))) |
| 66 | + |
4 | 67 | ;; type Prog = |
5 | 68 | ;; | `(begin ,@(Listof Defn) ,Expr) |
6 | 69 | ;; | Expr |
7 | 70 |
|
8 | 71 | ;; type Defn = `(define (,Variable ,@(Listof Variable)) ,Expr) |
9 | 72 |
|
| 73 | + |
10 | 74 | ;; Prog -> Answer |
11 | 75 | (define (interp p) |
12 | 76 | (match p |
13 | 77 | [(list 'begin ds ... e) |
14 | | - (interp-env e '() ds)] |
15 | | - [e (interp-env e '() '())])) |
| 78 | + (interp-env e (interp-defns ds))] |
| 79 | + [e (interp-env e '())])) |
| 80 | + |
| 81 | +;; (Listof Defn) -> REnv |
| 82 | +(define (interp-defns ds) |
| 83 | + (map (lambda (d) |
| 84 | + (match d |
| 85 | + [`(define (,f . ,xs) ,e) |
| 86 | + (list f (interp-defn d ds))])) |
| 87 | + ds)) |
| 88 | + |
| 89 | +;; Defn (Listof Defn) -> ((Listof Value) -> Answer) |
| 90 | +(define (interp-defn d ds) |
| 91 | + (match d |
| 92 | + [`(define (,f . ,xs) ,e) |
| 93 | + (lambda (vs) |
| 94 | + (if (= (length vs) (length xs)) |
| 95 | + (interp-env e (append (interp-defns ds) (zip xs vs))) |
| 96 | + 'err))])) |
16 | 97 |
|
17 | | -;; Expr REnv (Listof Defn) -> Answer |
18 | | -(define (interp-env e r ds) |
| 98 | + |
| 99 | + |
| 100 | +;; type Value = |
| 101 | +;; ... |
| 102 | +;; | `(closure ,(Listof Variable) ,Expr ,Env) |
| 103 | + |
| 104 | +(define (interp-closure e) |
| 105 | + (interp-env-closure e '())) |
| 106 | + |
| 107 | +;; Expr REnv -> Answer |
| 108 | +(define (interp-env-closure e r) |
19 | 109 | (match e |
20 | 110 | [''() '()] |
21 | | - [(? value? v) v] |
| 111 | + [(? syntactic-value? v) v] |
22 | 112 | [(list (? prim? p) es ...) |
23 | | - (match (interp-env* es r ds) |
| 113 | + (match (interp-env-closure* es r) |
24 | 114 | [(list vs ...) (interp-prim p vs)] |
25 | 115 | [_ 'err])] |
26 | 116 | [`(if ,e0 ,e1 ,e2) |
27 | | - (match (interp-env e0 r ds) |
| 117 | + (match (interp-env-closure e0 r) |
28 | 118 | ['err 'err] |
29 | 119 | [v |
30 | 120 | (if v |
31 | | - (interp-env e1 r ds) |
32 | | - (interp-env e2 r ds))])] |
| 121 | + (interp-env-closure e1 r) |
| 122 | + (interp-env-closure e2 r))])] |
33 | 123 | [(? symbol? x) |
34 | 124 | (lookup r x)] |
35 | 125 | [`(let ((,x ,e0)) ,e1) |
36 | | - (match (interp-env e0 r ds) |
| 126 | + (match (interp-env-closure e0 r) |
37 | 127 | ['err 'err] |
38 | 128 | [v |
39 | | - (interp-env e1 (ext r x v) ds)])] |
| 129 | + (interp-env-closure e1 (ext r x v))])] |
| 130 | + |
| 131 | + [`(λ (,xs ...) ,e) |
| 132 | + `(closure ,xs ,e ,r)] |
40 | 133 |
|
41 | | - [`(,f . ,es) |
42 | | - (match (interp-env* es r ds) |
43 | | - [(list vs ...) |
44 | | - (match (defns-lookup ds f) |
45 | | - [`(define (,f ,xs ...) ,e) |
46 | | - ; check arity matches |
47 | | - (if (= (length xs) (length vs)) |
48 | | - (interp-env e (zip xs vs) ds) |
49 | | - 'err)])] |
| 134 | + [`(,e . ,es) |
| 135 | + (match (interp-env-closure* (cons e es) r) |
| 136 | + [(list `(closure ,xs ,e ,r) vs ...) |
| 137 | + (if (= (length vs) (length xs)) |
| 138 | + (interp-env-closure e (append (zip xs vs) r)) |
| 139 | + 'err)] |
50 | 140 | [_ 'err])])) |
51 | 141 |
|
52 | | -;; (Listof Defn) Symbol -> Defn |
53 | | -(define (defns-lookup ds f) |
54 | | - (findf (match-lambda [`(define (,g . ,_) ,_) (eq? f g)]) |
55 | | - ds)) |
| 142 | + |
56 | 143 |
|
57 | 144 | ;; (Listof Expr) REnv -> (Listof Value) | 'err |
58 | | -(define (interp-env* es r ds) |
| 145 | +(define (interp-env-closure* es r) |
59 | 146 | (match es |
60 | 147 | ['() '()] |
61 | 148 | [(cons e es) |
62 | | - (match (interp-env e r ds) |
| 149 | + (match (interp-env-closure e r) |
63 | 150 | ['err 'err] |
64 | | - [v (cons v (interp-env* es r ds))])])) |
| 151 | + [v (cons v (interp-env-closure* es r))])])) |
| 152 | + |
| 153 | + |
| 154 | + |
| 155 | + |
| 156 | + |
65 | 157 |
|
66 | 158 | ;; Any -> Boolean |
67 | 159 | (define (prim? x) |
|
70 | 162 | box unbox empty? cons car cdr)))) |
71 | 163 |
|
72 | 164 | ;; Any -> Boolean |
73 | | -(define (value? x) |
| 165 | +(define (syntactic-value? x) |
74 | 166 | (or (integer? x) |
75 | 167 | (boolean? x) |
76 | | - (null? x) |
77 | | - (and (pair? x) |
78 | | - (value? (car x)) |
79 | | - (value? (cdr x))))) |
| 168 | + (null? x))) |
80 | 169 |
|
81 | 170 | ;; Prim (Listof Value) -> Answer |
82 | 171 | (define (interp-prim p vs) |
|
0 commit comments