|
147 | 147 |
|
148 | 148 | ;; We will test this function directly, so it must do
|
149 | 149 | ;; as described in the assignment
|
150 |
| -(define (free-vars-helper e not-free) |
151 |
| - ;;(println not-free) |
152 |
| - ;;(print e) |
153 |
| - (let ([f (lambda (g e) (free-vars-helper (g e) not-free))]) |
| 150 | +(define (free-vars-helper e) |
| 151 | + (let ([f (lambda (g e) (free-vars-helper (g e)))]) |
154 | 152 | (cond [(fun? e)
|
155 | 153 | (let* ([arg (fun-formal e)]
|
156 | 154 | [body (fun-body e)]
|
157 |
| - [s (free-vars-helper body (set-add not-free arg))]) |
158 |
| - (cons (fun-challenge (fun-nameopt e) arg (car s) (cdr s)) (cdr s)))] |
| 155 | + [s (free-vars-helper body)] |
| 156 | + [freevars (set-remove (cdr s) arg)]) |
| 157 | + (cons (fun-challenge (fun-nameopt e) arg (car s) freevars) freevars))] |
159 | 158 | [(var? e)
|
160 |
| - (cons e (if (set-member? not-free (var-string e)) (set) (set (var-string e))))] |
| 159 | + (cons e (set (var-string e)))] |
161 | 160 | [(mlet? e)
|
162 | 161 | (let* ([name (mlet-var e)]
|
163 | 162 | [val (mlet-e e)]
|
164 | 163 | [body (mlet-body e)]
|
165 |
| - [s1 (free-vars-helper val not-free)] |
166 |
| - [s2 (free-vars-helper body (set-add not-free name))]) |
| 164 | + [s1 (free-vars-helper val)] |
| 165 | + [s2 (free-vars-helper body)]) |
167 | 166 | (cons (mlet name (car s1) (car s2))
|
168 |
| - (set-union (cdr s1) (cdr s2))))] |
| 167 | + (set-union (cdr s1) (set-remove (cdr s2) name))))] |
169 | 168 | [(add? e)
|
170 | 169 | (let ([s1 (f add-e1 e)]
|
171 | 170 | [s2 (f add-e2 e)])
|
|
203 | 202 |
|
204 | 203 |
|
205 | 204 | (define (compute-free-vars e)
|
206 |
| - (car (free-vars-helper e (set)))) |
| 205 | + (car (free-vars-helper e))) |
207 | 206 |
|
208 | 207 |
|
209 | 208 |
|
210 | 209 |
|
211 | 210 | ;; Do NOT share code with eval-under-env because that will make
|
212 | 211 | ;; auto-grading and peer assessment more difficult, so
|
213 | 212 | ;; copy most of your interpreter here and make minor changes
|
| 213 | + |
| 214 | +(define (compute-env env freevars) |
| 215 | + (set-map freevars (lambda (x) (cons x (envlookup env x))))) |
| 216 | + |
| 217 | + |
214 | 218 | (define (eval-under-env-c e env)
|
| 219 | + (println e) |
| 220 | + (println env) |
215 | 221 | (cond [(var? e)
|
216 | 222 | (envlookup env (var-string e))]
|
217 | 223 | [(add? e)
|
|
257 | 263 | (if (var? fn-call)
|
258 | 264 | (cons (cons (var-string fn-call) clojure) clojure-env) ;; Add bindings for recursive call
|
259 | 265 | clojure-env))]
|
260 |
| - [arg-name (fun-formal fn)] |
261 |
| - [fn-body (fun-body fn)]) |
262 |
| - (eval-under-env-c fn-body (cons (cons arg-name arg) envi)))] |
| 266 | + [reduced-envi (compute-env envi (fun-challenge-freevars fn))] |
| 267 | + [arg-name (fun-challenge-formal fn)] |
| 268 | + [fn-body (fun-challenge-body fn)]) |
| 269 | + (eval-under-env-c fn-body (cons (cons arg-name arg) reduced-envi)))] |
263 | 270 | [(apair? e)
|
264 | 271 | (apair (eval-under-env-c (apair-e1 e) env) (eval-under-env-c (apair-e2 e) env))]
|
265 | 272 | [(fst? e) (let ([pair (eval-under-env-c (fst-e e) env)])
|
266 | 273 | (if (apair? pair) (apair-e1 pair) (error "MUPL fst applied to non-pair")))]
|
267 | 274 | [(snd? e) (let ([pair (eval-under-env-c (snd-e e) env)])
|
268 | 275 | (if (apair? pair) (apair-e2 pair) (error "MUPL snd applied to non-pair")))]
|
269 | 276 | [(isaunit? e) (if (aunit? (eval-under-env-c (isaunit-e e) env)) (int 1) (int 0))]
|
270 |
| - ;; |
271 | 277 | [#t (error (format "bad MUPL expression: ~v" e))]))
|
272 | 278 |
|
273 | 279 | ;; Do NOT change this
|
|
0 commit comments