|
22 | 22 |
|
23 | 23 | ;; Prog Defns -> Answer |
24 | 24 | (define (interp p) |
25 | | - (match p |
26 | | - [(Prog ds e) |
27 | | - (interp-env e '() ds)])) |
| 25 | + (interp-env (desugar p) '())) |
28 | 26 |
|
29 | 27 | ;; Expr Env Defns -> Answer |
30 | | -(define (interp-env e r ds) |
| 28 | +(define (interp-env e r) |
31 | 29 | (match e |
| 30 | + [(Prog '() e) (interp-env e r)] |
32 | 31 | [(Int i) i] |
33 | 32 | [(Bool b) b] |
34 | 33 | [(Char c) c] |
|
39 | 38 | [(Prim0 'read-byte) (read-byte)] |
40 | 39 | [(Prim0 'peek-byte) (peek-byte)] |
41 | 40 | [(Prim1 p e) |
42 | | - (match (interp-env e r ds) |
| 41 | + (match (interp-env e r) |
43 | 42 | ['err 'err] |
44 | 43 | [v (interp-prim1 p v)])] |
45 | 44 | [(Prim2 p e1 e2) |
46 | | - (match (interp-env e1 r ds) |
| 45 | + (match (interp-env e1 r) |
47 | 46 | ['err 'err] |
48 | | - [v1 (match (interp-env e2 r ds) |
| 47 | + [v1 (match (interp-env e2 r) |
49 | 48 | ['err 'err] |
50 | 49 | [v2 (interp-prim2 p v1 v2)])])] |
51 | 50 | [(If p e1 e2) |
52 | | - (match (interp-env p r ds) |
| 51 | + (match (interp-env p r) |
53 | 52 | ['err 'err] |
54 | 53 | [v |
55 | 54 | (if v |
56 | | - (interp-env e1 r ds) |
57 | | - (interp-env e2 r ds))])] |
| 55 | + (interp-env e1 r) |
| 56 | + (interp-env e2 r))])] |
58 | 57 | [(Begin e1 e2) |
59 | | - (match (interp-env e1 r ds) |
| 58 | + (match (interp-env e1 r) |
60 | 59 | ['err 'err] |
61 | | - [_ (interp-env e2 r ds)])] |
| 60 | + [_ (interp-env e2 r)])] |
62 | 61 | [(Let x e1 e2) |
63 | | - (match (interp-env e1 r ds) |
| 62 | + (match (interp-env e1 r) |
64 | 63 | ['err 'err] |
65 | | - [v (interp-env e2 (ext r x v) ds)])] |
66 | | - [(App f es) |
67 | | - (match (interp-env* es r ds) |
68 | | - [(list vs ...) |
69 | | - (match (defns-lookup ds f) |
70 | | - [(Defn f xs body) |
71 | | - ; arity check |
| 64 | + [v (interp-env e2 (ext r x v))])] |
| 65 | + [(LetRec bs e) |
| 66 | + (letrec ((r* (λ () |
| 67 | + (append |
| 68 | + (zip (map car bs) |
| 69 | + ;; η-expansion to delay evaluating r* |
| 70 | + ;; relies on RHSs being functions |
| 71 | + (map (λ (l) (λ vs (apply (interp-env l (r*)) vs))) |
| 72 | + (map cadr bs))) |
| 73 | + r)))) |
| 74 | + (interp-env e (r*)))] |
| 75 | + [(Lam _ xs e1) |
| 76 | + (lambda vs |
72 | 77 | (if (= (length vs) (length xs)) |
73 | | - (interp-env body (zip xs vs) ds) |
74 | | - 'err)])])] |
75 | | - [(Fun f) |
76 | | - (match (defns-lookup ds f) |
77 | | - [(Defn f xs body) |
78 | | - (lambda (es r) |
79 | | - (match (interp-env* es r ds) |
80 | | - [(list vs ...) |
81 | | - (if (= (length vs) (length xs)) |
82 | | - (interp-env body (zip xs vs) ds) |
83 | | - 'err)]))] |
84 | | - [_ 'err])] |
85 | | - [(FCall f es) |
86 | | - (match (interp-env f r ds) |
87 | | - [(? procedure? f) (f es r)] |
88 | | - [_ 'err])] |
| 78 | + (interp-env e1 (append (zip xs vs) r)) |
| 79 | + 'err))] |
| 80 | + [(App f es) |
| 81 | + (match (interp-env* (cons f es) r) |
| 82 | + [(list f vs ...) |
| 83 | + (if (procedure? f) |
| 84 | + (apply f vs) |
| 85 | + 'err)])] |
89 | 86 | [_ 'err])) |
90 | 87 |
|
91 | 88 | ;; (Listof Expr) REnv Defns -> (Listof Value) | 'err |
92 | | -(define (interp-env* es r ds) |
| 89 | +(define (interp-env* es r) |
93 | 90 | (match es |
94 | 91 | ['() '()] |
95 | 92 | [(cons e es) |
96 | | - (match (interp-env e r ds) |
| 93 | + (match (interp-env e r) |
97 | 94 | ['err 'err] |
98 | | - [v (cons v (interp-env* es r ds))])])) |
99 | | - |
100 | | -;; Defns Symbol -> Defn |
101 | | -(define (defns-lookup ds f) |
102 | | - (findf (match-lambda [(Defn g _ _) (eq? f g)]) |
103 | | - ds)) |
| 95 | + [v (cons v (interp-env* es r))])])) |
104 | 96 |
|
105 | 97 | (define (zip xs ys) |
106 | 98 | (match* (xs ys) |
|
0 commit comments