|
17 | 17 | (match e+ |
18 | 18 | [`(begin ,@(list `(define (,fs . ,xss) ,es) ...) ,e) |
19 | 19 | `(letrec ,(map (λ (f xs e) `(,f (λ ,xs ,(desugar e)))) fs xss es) |
20 | | - ,(desugar e))] |
| 20 | + ,(desugar e))] |
21 | 21 | [(? symbol? x) x] |
22 | 22 | [(? imm? i) i] |
23 | 23 | [`',(? symbol? s) `',s] |
24 | | - [`',d (desugar (quote->expr d))] ;; quote & quasiquote as expansions |
25 | | - [(list 'quasiquote d) (desugar (quasiquote->expr d))] |
26 | | - [`(box ,e0) `(box ,(desugar e0))] |
27 | | - [`(unbox ,e0) `(unbox ,(desugar e0))] |
28 | | - [`(cons ,e0 ,e1) `(cons ,(desugar e0) ,(desugar e1))] |
29 | | - [`(car ,e0) `(car ,(desugar e0))] |
30 | | - [`(cdr ,e0) `(cdr ,(desugar e0))] |
31 | | - [`(add1 ,e0) `(add1 ,(desugar e0))] |
32 | | - [`(sub1 ,e0) `(sub1 ,(desugar e0))] |
33 | | - [`(zero? ,e0) `(zero? ,(desugar e0))] |
34 | | - [`(empty? ,e0) `(empty? ,(desugar e0))] |
| 24 | + [`',d (quote->expr d)] |
| 25 | + [`(,(? prim? p) . ,es) `(,p ,@(map desugar es))] |
35 | 26 | [`(if ,e0 ,e1 ,e2) `(if ,(desugar e0) ,(desugar e1) ,(desugar e2))] |
36 | | - [`(+ ,e0 ,e1) `(+ ,(desugar e0) ,(desugar e1))] |
37 | 27 | [`(let ((,x ,e0)) ,e1) `(let ((,x ,(desugar e0))) ,(desugar e1))] |
38 | 28 | [`(letrec ,bs ,e0) |
39 | 29 | `(letrec ,(map (λ (b) (list (first b) (desugar (second b)))) bs) |
|
47 | 37 |
|
48 | 38 | ;; S-Expr -> Expr |
49 | 39 | ;; Produce an expression that evaluates to given s-expression, without |
50 | | -;; use of quote (except for symbols) |
| 40 | +;; use of quote (except for symbols and empty list) |
51 | 41 | (define (quote->expr d) |
52 | 42 | (match d |
53 | 43 | [(? boolean?) d] |
54 | 44 | [(? integer?) d] |
55 | 45 | [(? string?) d] |
56 | 46 | [(? char?) d] |
57 | 47 | [(? symbol?) (list 'quote d)] |
58 | | - ;[(cons x y) (list 'cons (quote->expr x) (quote->expr y))] |
59 | | - [(cons x y) (list 'cons (list 'quote x) (list 'quote y))] |
| 48 | + [(cons x y) (list 'cons (quote->expr x) (quote->expr y))] |
60 | 49 | ['() ''()])) |
61 | 50 |
|
62 | | -(define (quasiquote->expr d) |
| 51 | +(define (quasiquote->expr d) |
63 | 52 | (match d |
64 | 53 | [(? boolean?) d] |
65 | 54 | [(? integer?) d] |
|
69 | 58 | [(cons 'quasiquote d) |
70 | 59 | (quasiquote->expr (quasiquote->expr d))] |
71 | 60 | [(cons 'unquote d) d] |
72 | | - [(cons 'unquote-splicing d) 'ERROR] |
| 61 | + [(cons 'unquote-splicing d) 'ERROR] |
73 | 62 | [(cons x y) |
74 | 63 | `(append ,(quasiquote->list-expr x) |
75 | 64 | ,(quasiquote->expr y))] |
76 | 65 | ['() ''()])) |
77 | 66 |
|
78 | | -(define (quasiquote->list-expr d) |
79 | | - (match d |
| 67 | +(define (quasiquote->list-expr d) |
| 68 | + (match d |
80 | 69 | [(? symbol?) (list 'quote d)] |
81 | 70 | ['() ''()] |
82 | 71 | [(cons 'quasiquote d) |
83 | 72 | (quasiquote->expr (quasiquote->expr d))] |
84 | 73 | [(cons 'unquote d) `(list ,d)] |
85 | | - [(cons 'unquote-splicing d) d] |
| 74 | + [(cons 'unquote-splicing d) d] |
86 | 75 | [(cons x y) |
87 | 76 | `(list (append ,(quasiquote->list-expr x) |
88 | 77 | ,(quasiquote->expr y)))] |
89 | 78 | [_ `'(,d)])) |
90 | 79 |
|
| 80 | +;; Expr -> Expr |
91 | 81 | (define (cond->if c) |
92 | 82 | (match c |
93 | 83 | [`(cond (else ,e)) e] |
94 | 84 | [`(cond (,c ,e) . ,r) |
95 | 85 | `(if ,c ,e (cond ,@r))])) |
96 | 86 |
|
| 87 | +;; Expr -> Expr |
97 | 88 | (define (and->if c) |
98 | 89 | (match c |
99 | 90 | [`(and) #t] |
100 | 91 | [`(and ,e) e] |
101 | 92 | [`(and ,e . ,r) |
102 | 93 | `(if ,e (and ,@r) #f)])) |
103 | 94 |
|
| 95 | +;; Expr -> Expr |
104 | 96 | (define (or->if c) |
105 | 97 | (match c |
106 | 98 | [`(or) #f] |
|
142 | 134 | [else `(append . ,r)])] |
143 | 135 | [_ |
144 | 136 | `'(,x)])) |
145 | | - |
| 137 | + |
146 | 138 |
|
147 | 139 |
|
148 | 140 | ;; Any -> Boolean |
|
157 | 149 | (match e |
158 | 150 | [(? symbol? x) x] |
159 | 151 | [(? imm? i) i] |
160 | | - [`(box ,e0) `(box ,(label-λ e0))] |
161 | | - [`(unbox ,e0) `(unbox ,(label-λ e0))] |
162 | | - [`(cons ,e0 ,e1) `(cons ,(label-λ e0) ,(label-λ e1))] |
163 | | - [`(car ,e0) `(car ,(label-λ e0))] |
164 | | - [`(cdr ,e0) `(cdr ,(label-λ e0))] |
165 | | - [`(add1 ,e0) `(add1 ,(label-λ e0))] |
166 | | - [`(sub1 ,e0) `(sub1 ,(label-λ e0))] |
167 | | - [`(zero? ,e0) `(zero? ,(label-λ e0))] |
168 | | - [`(empty? ,e0) `(empty? ,(label-λ e0))] |
| 152 | + [`(,(? prim? p) . ,es) `(,p ,@(map label-λ es))] |
169 | 153 | [`(if ,e0 ,e1 ,e2) `(if ,(label-λ e0) ,(label-λ e1) ,(label-λ e2))] |
170 | | - [`(+ ,e0 ,e1) `(+ ,(label-λ e0) ,(label-λ e1))] |
171 | 154 | [`(let ((,x ,e0)) ,e1) `(let ((,x ,(label-λ e0))) ,(label-λ e1))] |
172 | 155 | [`(letrec ,bs ,e0) `(letrec ,(map (λ (b) (list (first b) (label-λ (second b)))) bs) |
173 | 156 | ,(label-λ e0))] |
174 | | - [`(λ ,xs ,e0) `(λ ,xs ',(gensym) ,(label-λ e0))] |
| 157 | + [`(λ ,xs ,e0) `(λ ,xs ',(gensym) ,(label-λ e0))] |
175 | 158 | [`(,e . ,es) `(,(label-λ e) ,@(map label-λ es))])) |
176 | 159 |
|
177 | 160 | ;; LExpr -> (Listof LExpr) |
|
180 | 163 | (match e |
181 | 164 | [(? symbol? x) '()] |
182 | 165 | [(? imm? i) '()] |
183 | | - [`(box ,e0) (λs e0)] |
184 | | - [`(unbox ,e0) (λs e0)] |
185 | | - [`(cons ,e0 ,e1) (append (λs e0) (λs e1))] |
186 | | - [`(car ,e0) (λs e0)] |
187 | | - [`(cdr ,e0) (λs e0)] |
188 | | - [`(add1 ,e0) (λs e0)] |
189 | | - [`(sub1 ,e0) (λs e0)] |
190 | | - [`(zero? ,e0) (λs e0)] |
191 | | - [`(empty? ,e0) (λs e0)] |
| 166 | + [`(,(? prim? p) . ,es) (append-map λs es)] |
192 | 167 | [`(if ,e0 ,e1 ,e2) (append (λs e0) (λs e1) (λs e2))] |
193 | | - [`(+ ,e0 ,e1) (append (λs e0) (λs e1))] |
194 | 168 | [`(let ((,x ,e0)) ,e1) (append (λs e0) (λs e1))] |
195 | 169 | [`(letrec ,bs ,e0) (append (apply append (map (compose λs second) bs)) (λs e0))] |
196 | 170 | [`(λ ,xs ,l ,e0) (cons e (λs e0))] |
|
202 | 176 | (match e |
203 | 177 | [(? symbol? x) (list x)] |
204 | 178 | [(? imm? i) '()] |
205 | | - [`(box ,e0) (fvs e0)] |
206 | | - [`(unbox ,e0) (fvs e0)] |
207 | | - [`(cons ,e0 ,e1) (append (fvs e0) (fvs e1))] |
208 | | - [`(car ,e0) (fvs e0)] |
209 | | - [`(cdr ,e0) (fvs e0)] |
210 | | - [`(add1 ,e0) (fvs e0)] |
211 | | - [`(sub1 ,e0) (fvs e0)] |
212 | | - [`(zero? ,e0) (fvs e0)] |
213 | | - [`(empty? ,e0) (fvs e0)] |
| 179 | + [`(,(? prim? p) . ,es) (append-map fvs es)] |
214 | 180 | [`(if ,e0 ,e1 ,e2) (append (fvs e0) (fvs e1) (fvs e2))] |
215 | | - [`(+ ,e0 ,e1) (append (fvs e0) (fvs e1))] |
216 | 181 | [`(let ((,x ,e0)) ,e1) (append (fvs e0) (remq* (list x) (fvs e1)))] |
217 | 182 | [`(letrec ,bs ,e0) (remq* (map first bs) |
218 | | - (apply append (fvs e0) (map fvs (map second bs))))] |
| 183 | + (apply append (fvs e0) (map fvs (map second bs))))] |
219 | 184 | [`(λ ,xs ,l ,e0) (remq* xs (fvs e0))] |
220 | | - [`(,e . ,es) (append (fvs e) (apply append (map fvs es)))])) |
| 185 | + [`(,e . ,es) (append (fvs e) (apply append (map fvs es)))])) |
221 | 186 | (remove-duplicates (fvs e))) |
| 187 | + |
| 188 | +;; Any -> Boolean |
| 189 | +(define (prim? x) |
| 190 | + (and (symbol? x) |
| 191 | + (memq x '(add1 sub1 zero? abs - char? boolean? integer? integer->char char->integer |
| 192 | + string? box? empty? cons cons? box unbox car cdr string-length |
| 193 | + make-string string-ref = < <= char=? boolean=? + eq? gensym symbol? |
| 194 | + procedure?)))) |
0 commit comments