|
60 | 60 | (error "argument type does not match parameter type"
|
61 | 61 | (list ts pts)))
|
62 | 62 | ret))
|
63 |
| - |
| 63 | + |
| 64 | + ;; The introduction of has-type should have been done in vectors.rkt |
| 65 | + ;; and not here because it's not needed yet. -Jeremy |
64 | 66 | (define/public (type-check env)
|
65 | 67 | (lambda (e)
|
66 | 68 | (vomit "conditionals/type-check" e env)
|
|
120 | 122 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
121 | 123 | ;; flatten : S1 -> C1-expr x (C1-stmt list)
|
122 | 124 |
|
123 |
| - (define/override (collect-locals) |
124 |
| - (lambda (ast) |
125 |
| - (match ast |
126 |
| - [`(if ,cnd ,thn ,els) |
127 |
| - (append (append* (map (collect-locals) thn)) |
128 |
| - (append* (map (collect-locals) els)))] |
129 |
| - [else ((super collect-locals) ast)]))) |
130 |
| - |
131 |
| - (define optimize-if #f) |
| 125 | + (field [optimize-if #f]) |
132 | 126 |
|
133 |
| - (define/public (flatten-if new-thn thn-ss new-els els-ss) |
| 127 | + (define/public (flatten-if new-thn thn-ss new-els els-ss xs) |
134 | 128 | (lambda (cnd)
|
135 | 129 | (vomit "flatten-if" cnd)
|
136 | 130 | (match cnd
|
137 | 131 | [`(has-type ,cnd ,t)
|
138 | 132 | (match cnd
|
139 | 133 | [#t #:when optimize-if
|
140 |
| - (values new-thn thn-ss)] |
| 134 | + (values new-thn thn-ss xs)] |
141 | 135 | [#f #:when optimize-if
|
142 |
| - (values new-els els-ss)] |
| 136 | + (values new-els els-ss xs)] |
143 | 137 | [`(let ([,x ,e]) ,body) #:when optimize-if
|
144 |
| - (define-values (new-e e-ss) ((flatten #f) e)) |
145 |
| - (define-values (new-body body-ss) |
146 |
| - ((flatten-if new-thn thn-ss new-els els-ss) body)) |
| 138 | + (define-values (new-e e-ss xs1) ((flatten #f) e)) |
| 139 | + (define-values (new-body body-ss xs2) |
| 140 | + ((flatten-if new-thn thn-ss new-els els-ss xs) body)) |
147 | 141 | (values new-body
|
148 | 142 | (append e-ss
|
149 | 143 | `((assign ,x ,new-e))
|
150 |
| - body-ss))] |
| 144 | + body-ss) |
| 145 | + (append xs1 xs2))] |
151 | 146 | [`(not ,cnd) #:when optimize-if
|
152 |
| - ((flatten-if new-els els-ss new-thn thn-ss) cnd)] |
| 147 | + ((flatten-if new-els els-ss new-thn thn-ss xs) cnd)] |
153 | 148 | [`(,cmp ,e1 ,e2)
|
154 | 149 | #:when (and optimize-if (set-member? (comparison-ops) cmp))
|
155 |
| - (define-values (new-e1 e1-ss) ((flatten #t) e1)) |
156 |
| - (define-values (new-e2 e2-ss) ((flatten #t) e2)) |
| 150 | + (define-values (new-e1 e1-ss xs1) ((flatten #t) e1)) |
| 151 | + (define-values (new-e2 e2-ss xs2) ((flatten #t) e2)) |
157 | 152 | (define tmp (gensym 'if))
|
158 | 153 | (define thn-ret `(assign ,tmp ,new-thn))
|
159 | 154 | (define els-ret `(assign ,tmp ,new-els))
|
160 | 155 | (values `(has-type ,tmp ,t)
|
161 | 156 | (append e1-ss e2-ss
|
162 | 157 | `((if (,cmp ,new-e1 ,new-e2)
|
163 | 158 | ,(append thn-ss (list thn-ret))
|
164 |
| - ,(append els-ss (list els-ret))))))] |
| 159 | + ,(append els-ss (list els-ret))))) |
| 160 | + (cons tmp (append xs1 xs2 xs)) |
| 161 | + )] |
165 | 162 | [else
|
166 |
| - (define-values (new-cnd cnd-ss) ((flatten #t) |
167 |
| - `(has-type ,cnd ,t))) |
| 163 | + (define-values (new-cnd cnd-ss xs1) |
| 164 | + ((flatten #t) `(has-type ,cnd ,t))) |
168 | 165 | (define tmp (gensym 'if))
|
169 | 166 | (define thn-ret `(assign ,tmp ,new-thn))
|
170 | 167 | (define els-ret `(assign ,tmp ,new-els))
|
171 | 168 | (values `(has-type ,tmp ,t)
|
172 | 169 | (append cnd-ss
|
173 | 170 | `((if (eq? (has-type #t Boolean) ,new-cnd)
|
174 | 171 | ,(append thn-ss (list thn-ret))
|
175 |
| - ,(append els-ss (list els-ret))))))])] |
| 172 | + ,(append els-ss (list els-ret))))) |
| 173 | + (cons tmp (append xs1 xs)) |
| 174 | + )])] |
176 | 175 | [other (error 'flatten-if "unmatched ~a" other)])))
|
177 | 176 |
|
178 | 177 | (define/override (flatten need-atomic)
|
|
181 | 180 | (match e
|
182 | 181 | ;; For atomic stuff, we keep the has-type annotation. -Jeremy
|
183 | 182 | [`(has-type (void) ,t)
|
184 |
| - (values `(has-type (void) ,t) '())] |
185 |
| - [`(has-type ,e ,t) #:when (or (symbol? e) (integer? e) (boolean? e)) |
186 |
| - (values `(has-type ,e ,t) '())] |
| 183 | + (values `(has-type (void) ,t) '() '())] |
| 184 | + [`(has-type ,e1 ,t) |
| 185 | + #:when (or (symbol? e1) (integer? e1) (boolean? e1)) |
| 186 | + (values `(has-type ,e1 ,t) '() '())] |
187 | 187 |
|
188 | 188 | ;; We override 'and' to place has-type's around the #t and #f
|
189 | 189 | ;; in the generated code. -Jeremy
|
190 | 190 | [`(has-type (and ,e1 ,e2) ,t)
|
191 |
| - (define-values (new-e1 e1-ss) ((flatten #t) e1)) |
192 |
| - (define-values (new-e2 e2-ss) ((flatten #f) e2)) |
| 191 | + (define-values (new-e1 e1-ss xs1) ((flatten #t) e1)) |
| 192 | + (define-values (new-e2 e2-ss xs2) ((flatten #f) e2)) |
193 | 193 | (define tmp (gensym 'and))
|
194 | 194 | (values `(has-type ,tmp ,t)
|
195 | 195 | (append e1-ss
|
196 | 196 | `((if (eq? (has-type #t Boolean) ,new-e1)
|
197 | 197 | ,(append e2-ss `((assign ,tmp ,new-e2)))
|
198 |
| - ((assign ,tmp (has-type #f Boolean)))))))] |
| 198 | + ((assign ,tmp (has-type #f Boolean)))))) |
| 199 | + (cons tmp (append xs1 xs2)) |
| 200 | + )] |
199 | 201 |
|
200 | 202 | ;; We override flattening for op's because we
|
201 | 203 | ;; need to put a has-type on the LHS of the assign. -Jeremy
|
202 |
| - [`(has-type (,op ,es ...) ,t) |
203 |
| - #:when (set-member? (primitives) op) |
204 |
| - (define-values (new-es sss) (map2 (flatten #t) es)) |
| 204 | + [`(has-type (,op ,es ...) ,t) #:when (set-member? (primitives) op) |
| 205 | + (define-values (new-es sss xss) (map3 (flatten #t) es)) |
205 | 206 | (define ss (append* sss))
|
| 207 | + (define xs (append* xss)) |
206 | 208 | (define prim-apply `(,op ,@new-es))
|
207 | 209 | (cond
|
208 | 210 | [need-atomic
|
209 | 211 | (define tmp (gensym 'tmp))
|
210 | 212 | (values `(has-type ,tmp ,t)
|
211 |
| - (append ss `((assign ,tmp (has-type ,prim-apply ,t)))))] |
212 |
| - [else (values `(has-type ,prim-apply ,t) ss)])] |
| 213 | + (append ss `((assign ,tmp (has-type ,prim-apply ,t)))) |
| 214 | + (cons tmp xs) )] |
| 215 | + [else (values `(has-type ,prim-apply ,t) ss xs)])] |
213 | 216 |
|
214 | 217 | ;; For 'let' we just need to strip the enclosing has-type. -Jeremy
|
215 |
| - [`(has-type (let ([,x ,e]) ,body) ,t) |
216 |
| - ((flatten need-atomic) `(let ([,x ,e]) ,body))] |
| 218 | + [`(has-type (let ([,x ,rhs]) ,body) ,t) |
| 219 | + ((flatten need-atomic) `(let ([,x ,rhs]) ,body))] |
217 | 220 |
|
218 | 221 | [`(has-type (if ,cnd ,thn ,els) ,t)
|
219 |
| - (define-values (new-thn thn-ss) ((flatten #t) thn)) |
220 |
| - (define-values (new-els els-ss) ((flatten #t) els)) |
221 |
| - ((flatten-if new-thn thn-ss new-els els-ss) cnd)] |
222 |
| - |
223 |
| - [`(program ,e) |
224 |
| - (define-values (new-e ss) ((flatten #t) e)) |
225 |
| - (define xs (append* (map (collect-locals) ss))) |
226 |
| - `(program ,(remove-duplicates xs) |
227 |
| - ,@(append ss `((return ,new-e))))] |
228 |
| - [`(program (type ,ty) ,e) |
229 |
| - (define-values (new-e ss) ((flatten #t) e)) |
230 |
| - (define xs (append* (map (collect-locals) ss))) |
231 |
| - `(program ,(remove-duplicates xs) (type ,ty) |
232 |
| - ,@(append ss `((return ,new-e))))] |
233 |
| - [else ((super flatten need-atomic) e)]))) |
| 222 | + (define-values (new-thn thn-ss xs1) ((flatten #t) thn)) |
| 223 | + (define-values (new-els els-ss xs2) ((flatten #t) els)) |
| 224 | + ((flatten-if new-thn thn-ss new-els els-ss (append xs1 xs2)) cnd)] |
| 225 | + |
| 226 | + [`(program ,body) |
| 227 | + (define-values (new-body ss xs) ((flatten #t) body)) |
| 228 | + `(program ,xs ,@(append ss `((return ,new-body))))] |
| 229 | + [`(program (type ,ty) ,body) |
| 230 | + (define-values (new-body ss xs) ((flatten #t) body)) |
| 231 | + `(program ,xs (type ,ty) |
| 232 | + ,@(append ss `((return ,new-body))))] |
| 233 | + [else |
| 234 | + ((super flatten need-atomic) e)]))) |
234 | 235 |
|
235 | 236 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
236 | 237 | ;; select-instructions : env -> S1 -> S1
|
|
261 | 262 | [else (error 'compare->cc "unmatched ~a" cmp)]
|
262 | 263 | ))
|
263 | 264 |
|
264 |
| - |
265 | 265 | (define/override (select-instructions)
|
266 | 266 | (lambda (e)
|
267 | 267 | (match e
|
|
0 commit comments