|
1 | 1 | #lang racket |
2 | 2 | (provide (all-defined-out)) |
3 | | -(require "syntax.rkt") |
| 3 | +(require "ast.rkt" "syntax.rkt") |
4 | 4 |
|
5 | 5 | ;; type Expr = |
6 | 6 | ;; ... |
|
16 | 16 |
|
17 | 17 | ;; Expr -> Answer |
18 | 18 | (define (interp e) |
19 | | - (interp-env (desugar e) '())) |
| 19 | + (match (desugar-prog e) |
| 20 | + [(prog _ e) |
| 21 | + (interp-env e '())])) |
20 | 22 |
|
21 | 23 | ;; Expr REnv -> Answer |
22 | 24 | (define (interp-env e r) |
23 | 25 | (match e |
24 | | - [''() '()] |
25 | | - [(? syntactic-value? v) v] |
26 | | - [(list (? prim? p) es ...) |
| 26 | + [(nil-e) '()] |
| 27 | + [(int-e i) i] |
| 28 | + [(bool-e b) b] |
| 29 | + [(prim-e p es) |
27 | 30 | (match (interp-env* es r) |
28 | 31 | [(list vs ...) (interp-prim p vs)] |
29 | 32 | [_ 'err])] |
30 | | - [`(if ,e0 ,e1 ,e2) |
| 33 | + [(if-e e0 e1 e2) |
31 | 34 | (match (interp-env e0 r) |
32 | 35 | ['err 'err] |
33 | 36 | [v |
34 | 37 | (if v |
35 | 38 | (interp-env e1 r) |
36 | 39 | (interp-env e2 r))])] |
37 | | - [(? symbol? x) |
| 40 | + [(var-e x) |
38 | 41 | (lookup r x)] |
39 | | - [`(let ((,x ,e0)) ,e1) |
| 42 | + [(let-e (list (binding x e0)) e1) |
40 | 43 | (match (interp-env e0 r) |
41 | 44 | ['err 'err] |
42 | 45 | [v |
43 | 46 | (interp-env e1 (ext r x v))])] |
44 | | - [`(letrec ,bs ,e) |
| 47 | + [(letr-e bs e) |
45 | 48 | (letrec ((r* (λ () |
46 | 49 | (append |
47 | | - (zip (map first bs) |
| 50 | + (zip (get-vars bs) |
48 | 51 | ;; η-expansion to delay evaluating r* |
49 | 52 | ;; relies on RHSs being functions |
50 | | - (map (λ (l) `(rec-closure ,l ,r*)) |
51 | | - (map second bs))) |
| 53 | + (map (λ (l) (rec-closure l r*)) |
| 54 | + (get-defs bs))) |
52 | 55 | r)))) |
53 | 56 | (interp-env e (r*)))] |
54 | | - |
55 | | - [`(λ (,xs ...) ,e) |
56 | | - `(closure ,xs ,e ,r)] |
57 | | - [`(,e . ,es) |
| 57 | + [(lam-e xs e) |
| 58 | + (closure xs e r)] |
| 59 | + [(app-e e es) |
58 | 60 | (match (interp-env* (cons e es) r) |
59 | 61 | [(list (? function? f) vs ...) |
60 | 62 | (apply apply-function f vs)] |
61 | 63 | [_ 'err])])) |
62 | 64 |
|
63 | 65 | (define (function? f) |
64 | 66 | (match f |
65 | | - [`(closure . ,_) #t] |
66 | | - [`(rec-closure . ,_) #t] |
| 67 | + [(closure _ _ _) #t] |
| 68 | + [(rec-closure _ _) #t] |
67 | 69 | [_ #f])) |
68 | 70 |
|
69 | 71 | ;; Function Value ... -> Answer |
70 | 72 | (define (apply-function f . vs) |
71 | 73 | (match f |
72 | | - [`(closure ,xs ,e ,r) |
| 74 | + [(closure xs e r) |
73 | 75 | (if (= (length xs) (length vs)) |
74 | 76 | (interp-env e (append (zip xs vs) r)) |
75 | 77 | 'err)] |
76 | | - [`(rec-closure (λ (,xs ...) ,e) ,r*) |
77 | | - (apply apply-function `(closure ,xs ,e ,(r*)) vs)])) |
| 78 | + [(rec-closure (lam-e xs e) r*) |
| 79 | + ; You've got to apply the the r* thunk |
| 80 | + (apply apply-function (closure xs e (r*)) vs)])) |
78 | 81 |
|
79 | 82 |
|
80 | 83 | ;; (Listof Expr) REnv -> (Listof Value) | 'err |
|
94 | 97 |
|
95 | 98 | ;; Any -> Boolean |
96 | 99 | (define (syntactic-value? x) |
97 | | - (or (integer? x) |
98 | | - (boolean? x) |
99 | | - (null? x))) |
| 100 | + (or (int-e? x) |
| 101 | + (bool-e? x) |
| 102 | + (nil-e? x))) |
100 | 103 |
|
101 | 104 | ;; Prim (Listof Value) -> Answer |
102 | 105 | (define (interp-prim p vs) |
|
123 | 126 | [(cons (list y i) env) |
124 | 127 | (match (symbol=? x y) |
125 | 128 | [#t i] |
126 | | - [#f (lookup env x)])])) |
| 129 | + [#f (lookup env x)])] |
| 130 | + [_ (error (~a "Lookup failed, var: " x "\n\tthe env: " env))])) |
127 | 131 |
|
128 | 132 | ;; Env Variable Value -> Value |
129 | 133 | (define (ext r x i) |
|
0 commit comments