Commit | Line | Data |
---|---|---|
141443d7 | 1 | ;;;; eval.test --- tests guile's evaluator -*- scheme -*- |
d062a8c1 | 2 | ;;;; Copyright (C) 2000, 2001, 2006, 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. |
141443d7 | 3 | ;;;; |
73be1d9e MV |
4 | ;;;; This library is free software; you can redistribute it and/or |
5 | ;;;; modify it under the terms of the GNU Lesser General Public | |
6 | ;;;; License as published by the Free Software Foundation; either | |
53befeb7 | 7 | ;;;; version 3 of the License, or (at your option) any later version. |
73be1d9e MV |
8 | ;;;; |
9 | ;;;; This library is distributed in the hope that it will be useful, | |
141443d7 | 10 | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
73be1d9e MV |
11 | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | ;;;; Lesser General Public License for more details. | |
13 | ;;;; | |
14 | ;;;; You should have received a copy of the GNU Lesser General Public | |
15 | ;;;; License along with this library; if not, write to the Free Software | |
92205699 | 16 | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
141443d7 | 17 | |
d6e04e7c DH |
18 | (define-module (test-suite test-eval) |
19 | :use-module (test-suite lib) | |
113e7c25 | 20 | :use-module ((srfi srfi-1) :select (unfold count)) |
ea9f4f4b | 21 | :use-module ((system vm vm) :select (make-vm call-with-vm)) |
d062a8c1 AW |
22 | :use-module (ice-9 documentation) |
23 | :use-module (ice-9 local-eval)) | |
141443d7 DH |
24 | |
25 | ||
62360b89 DH |
26 | (define exception:bad-expression |
27 | (cons 'syntax-error "Bad expression")) | |
28 | ||
8bb0b3cc AW |
29 | (define exception:failed-match |
30 | (cons 'syntax-error "failed to match any pattern")) | |
31 | ||
a2230b65 AW |
32 | (define exception:not-a-list |
33 | (cons 'wrong-type-arg "Not a list")) | |
34 | ||
35 | (define exception:wrong-length | |
36 | (cons 'wrong-type-arg "wrong length")) | |
62360b89 | 37 | |
141443d7 DH |
38 | ;;; |
39 | ;;; miscellaneous | |
40 | ;;; | |
41 | ||
141443d7 | 42 | (define (documented? object) |
5c96bc39 | 43 | (not (not (object-documentation object)))) |
141443d7 DH |
44 | |
45 | ||
46 | ;;; | |
62360b89 | 47 | ;;; memoization |
141443d7 DH |
48 | ;;; |
49 | ||
62360b89 DH |
50 | (with-test-prefix "memoization" |
51 | ||
52 | (with-test-prefix "copy-tree" | |
53 | ||
54 | (pass-if "(#t . #(#t))" | |
55 | (let* ((foo (cons #t (vector #t))) | |
56 | (bar (copy-tree foo))) | |
57 | (vector-set! (cdr foo) 0 #f) | |
58 | (equal? bar '(#t . #(#t))))) | |
59 | ||
60 | (pass-if-exception "circular lists in forms" | |
0f458a37 | 61 | exception:wrong-type-arg |
62360b89 DH |
62 | (let ((foo (list #f))) |
63 | (set-cdr! foo foo) | |
64 | (copy-tree foo)))) | |
141443d7 | 65 | |
62360b89 DH |
66 | (pass-if "transparency" |
67 | (let ((x '(begin 1))) | |
68 | (eval x (current-module)) | |
69 | (equal? '(begin 1) x)))) | |
414959ca | 70 | |
62360b89 DH |
71 | |
72 | ;;; | |
73 | ;;; eval | |
74 | ;;; | |
75 | ||
76 | (with-test-prefix "evaluator" | |
414959ca | 77 | |
adb8054c MW |
78 | (pass-if "definitions return #<unspecified>" |
79 | (eq? (primitive-eval '(define test-var 'foo)) | |
80 | (if #f #f))) | |
81 | ||
08c608e1 DH |
82 | (with-test-prefix "symbol lookup" |
83 | ||
84 | (with-test-prefix "top level" | |
85 | ||
86 | (with-test-prefix "unbound" | |
87 | ||
88 | (pass-if-exception "variable reference" | |
89 | exception:unbound-var | |
90 | x) | |
91 | ||
92 | (pass-if-exception "procedure" | |
93 | exception:unbound-var | |
94 | (x))))) | |
95 | ||
141443d7 DH |
96 | (with-test-prefix "parameter error" |
97 | ||
98 | ;; This is currently a bug in guile: | |
99 | ;; Macros are accepted as function parameters. | |
100 | ;; Functions that 'apply' macros are rewritten!!! | |
101 | ||
8bb0b3cc AW |
102 | (pass-if-exception "macro as argument" |
103 | exception:failed-match | |
104 | (primitive-eval | |
105 | '(let ((f (lambda (p a b) (p a b)))) | |
106 | (f and #t #t)))) | |
107 | ||
108 | (pass-if-exception "passing macro as parameter" | |
109 | exception:failed-match | |
110 | (primitive-eval | |
111 | '(let* ((f (lambda (p a b) (p a b))) | |
112 | (foo (procedure-source f))) | |
113 | (f and #t #t) | |
114 | (equal? (procedure-source f) foo)))) | |
141443d7 DH |
115 | |
116 | )) | |
117 | ||
08c608e1 | 118 | ;;; |
8ab3d8a0 | 119 | ;;; call |
08c608e1 DH |
120 | ;;; |
121 | ||
8ab3d8a0 | 122 | (with-test-prefix "call" |
08c608e1 DH |
123 | |
124 | (with-test-prefix "wrong number of arguments" | |
125 | ||
126 | (pass-if-exception "((lambda () #f) 1)" | |
127 | exception:wrong-num-args | |
128 | ((lambda () #f) 1)) | |
129 | ||
130 | (pass-if-exception "((lambda (x) #f))" | |
131 | exception:wrong-num-args | |
132 | ((lambda (x) #f))) | |
133 | ||
134 | (pass-if-exception "((lambda (x) #f) 1 2)" | |
135 | exception:wrong-num-args | |
136 | ((lambda (x) #f) 1 2)) | |
137 | ||
138 | (pass-if-exception "((lambda (x y) #f))" | |
139 | exception:wrong-num-args | |
140 | ((lambda (x y) #f))) | |
141 | ||
142 | (pass-if-exception "((lambda (x y) #f) 1)" | |
143 | exception:wrong-num-args | |
144 | ((lambda (x y) #f) 1)) | |
145 | ||
146 | (pass-if-exception "((lambda (x y) #f) 1 2 3)" | |
147 | exception:wrong-num-args | |
148 | ((lambda (x y) #f) 1 2 3)) | |
149 | ||
150 | (pass-if-exception "((lambda (x . rest) #f))" | |
151 | exception:wrong-num-args | |
152 | ((lambda (x . rest) #f))) | |
153 | ||
154 | (pass-if-exception "((lambda (x y . rest) #f))" | |
155 | exception:wrong-num-args | |
156 | ((lambda (x y . rest) #f))) | |
157 | ||
158 | (pass-if-exception "((lambda (x y . rest) #f) 1)" | |
159 | exception:wrong-num-args | |
160 | ((lambda (x y . rest) #f) 1)))) | |
161 | ||
8ab3d8a0 KR |
162 | ;;; |
163 | ;;; apply | |
164 | ;;; | |
165 | ||
166 | (with-test-prefix "apply" | |
167 | ||
168 | (with-test-prefix "scm_tc7_subr_2o" | |
169 | ||
170 | ;; prior to guile 1.6.9 and 1.8.1 this called the function with | |
0f458a37 | 171 | ;; SCM_UNDEFINED, which in the case of make-vector resulted in |
8ab3d8a0 KR |
172 | ;; wrong-type-arg, instead of the intended wrong-num-args |
173 | (pass-if-exception "0 args" exception:wrong-num-args | |
174 | (apply make-vector '())) | |
175 | ||
176 | (pass-if "1 arg" | |
177 | (vector? (apply make-vector '(1)))) | |
178 | ||
179 | (pass-if "2 args" | |
180 | (vector? (apply make-vector '(1 2)))) | |
181 | ||
182 | ;; prior to guile 1.6.9 and 1.8.1 this error wasn't detected | |
183 | (pass-if-exception "3 args" exception:wrong-num-args | |
184 | (apply make-vector '(1 2 3))))) | |
185 | ||
141443d7 DH |
186 | ;;; |
187 | ;;; map | |
188 | ;;; | |
189 | ||
190 | (with-test-prefix "map" | |
191 | ||
192 | ;; Is documentation available? | |
193 | ||
194 | (expect-fail "documented?" | |
6ad9007a | 195 | (documented? map)) |
141443d7 DH |
196 | |
197 | (with-test-prefix "argument error" | |
198 | ||
199 | (with-test-prefix "non list argument" | |
200 | #t) | |
201 | ||
202 | (with-test-prefix "different length lists" | |
203 | ||
6b4113af | 204 | (pass-if-exception "first list empty" |
a2230b65 | 205 | exception:wrong-length |
6b4113af DH |
206 | (map + '() '(1))) |
207 | ||
208 | (pass-if-exception "second list empty" | |
a2230b65 | 209 | exception:wrong-length |
6b4113af DH |
210 | (map + '(1) '())) |
211 | ||
212 | (pass-if-exception "first list shorter" | |
a2230b65 | 213 | exception:wrong-length |
6b4113af DH |
214 | (map + '(1) '(2 3))) |
215 | ||
216 | (pass-if-exception "second list shorter" | |
a2230b65 | 217 | exception:wrong-length |
6b4113af | 218 | (map + '(1 2) '(3))) |
141443d7 | 219 | ))) |
23d72566 KR |
220 | |
221 | ;;; | |
222 | ;;; define with procedure-name | |
223 | ;;; | |
224 | ||
23d72566 KR |
225 | ;; names are only set on top-level procedures (currently), so these can't be |
226 | ;; hidden in a let | |
227 | ;; | |
228 | (define foo-closure (lambda () "hello")) | |
229 | (define bar-closure foo-closure) | |
3fd8807e AW |
230 | ;; make sure that make-procedure-with-setter returns an anonymous |
231 | ;; procedure-with-setter by passing it an anonymous getter. | |
232 | (define foo-pws (make-procedure-with-setter | |
233 | (lambda (x) (car x)) | |
234 | (lambda (x y) (set-car! x y)))) | |
23d72566 KR |
235 | (define bar-pws foo-pws) |
236 | ||
237 | (with-test-prefix "define set procedure-name" | |
238 | ||
936d0bf3 | 239 | (pass-if "closure" |
23d72566 KR |
240 | (eq? 'foo-closure (procedure-name bar-closure))) |
241 | ||
936d0bf3 | 242 | (expect-fail "procedure-with-setter" ; FIXME: `pass-if' when it's supported |
3fd8807e | 243 | (eq? 'foo-pws (procedure-name bar-pws)))) |
23d72566 | 244 | |
2b6b5908 DH |
245 | ;;; |
246 | ;;; promises | |
247 | ;;; | |
248 | ||
249 | (with-test-prefix "promises" | |
250 | ||
251 | (with-test-prefix "basic promise behaviour" | |
252 | ||
253 | (pass-if "delay gives a promise" | |
254 | (promise? (delay 1))) | |
255 | ||
256 | (pass-if "force evaluates a promise" | |
257 | (eqv? (force (delay (+ 1 2))) 3)) | |
258 | ||
259 | (pass-if "a forced promise is a promise" | |
260 | (let ((p (delay (+ 1 2)))) | |
261 | (force p) | |
262 | (promise? p))) | |
263 | ||
264 | (pass-if "forcing a forced promise works" | |
265 | (let ((p (delay (+ 1 2)))) | |
266 | (force p) | |
267 | (eqv? (force p) 3))) | |
268 | ||
269 | (pass-if "a promise is evaluated once" | |
270 | (let* ((x 1) | |
271 | (p (delay (+ x 1)))) | |
272 | (force p) | |
273 | (set! x (+ x 1)) | |
274 | (eqv? (force p) 2))) | |
275 | ||
276 | (pass-if "a promise may call itself" | |
277 | (define p | |
278 | (let ((x 0)) | |
279 | (delay | |
280 | (begin | |
281 | (set! x (+ x 1)) | |
282 | (if (> x 1) x (force p)))))) | |
283 | (eqv? (force p) 2)) | |
284 | ||
285 | (pass-if "a promise carries its environment" | |
286 | (let* ((x 1) (p #f)) | |
287 | (let* ((x 2)) | |
288 | (set! p (delay (+ x 1)))) | |
289 | (eqv? (force p) 3))) | |
290 | ||
291 | (pass-if "a forced promise does not reference its environment" | |
292 | (let* ((g (make-guardian)) | |
293 | (p #f)) | |
294 | (let* ((x (cons #f #f))) | |
295 | (g x) | |
296 | (set! p (delay (car x)))) | |
297 | (force p) | |
298 | (gc) | |
299 | (if (not (equal? (g) (cons #f #f))) | |
300 | (throw 'unresolved) | |
301 | #t)))) | |
302 | ||
303 | (with-test-prefix "extended promise behaviour" | |
304 | ||
305 | (pass-if-exception "forcing a non-promise object is not supported" | |
306 | exception:wrong-type-arg | |
307 | (force 1)) | |
308 | ||
e10cf6b9 AW |
309 | (pass-if "unmemoizing a promise" |
310 | (display-backtrace | |
311 | (let ((stack #f)) | |
312 | (false-if-exception | |
313 | (with-throw-handler #t | |
314 | (lambda () | |
315 | (let ((f (lambda (g) (delay (g))))) | |
316 | (force (f error)))) | |
317 | (lambda _ | |
318 | (set! stack (make-stack #t))))) | |
319 | stack) | |
320 | (%make-void-port "w")) | |
321 | #t))) | |
2b6b5908 | 322 | |
113e7c25 LC |
323 | |
324 | ;;; | |
325 | ;;; stacks | |
326 | ;;; | |
327 | ||
328 | (define (stack->frames stack) | |
329 | ;; Return the list of frames comprising STACK. | |
330 | (unfold (lambda (i) | |
331 | (>= i (stack-length stack))) | |
332 | (lambda (i) | |
333 | (stack-ref stack i)) | |
334 | 1+ | |
335 | 0)) | |
336 | ||
99d7688b NL |
337 | (define (make-tagged-trimmed-stack tag spec) |
338 | (catch 'result | |
339 | (lambda () | |
340 | (call-with-prompt | |
341 | tag | |
342 | (lambda () | |
343 | (with-throw-handler 'wrong-type-arg | |
344 | (lambda () (substring 'wrong 'type 'arg)) | |
345 | (lambda _ (throw 'result (apply make-stack spec))))) | |
346 | (lambda () (throw 'make-stack-failed)))) | |
347 | (lambda (key result) result))) | |
348 | ||
349 | (define tag (make-prompt-tag "foo")) | |
350 | ||
649d3ea7 NL |
351 | (with-test-prefix "stacks" |
352 | (pass-if "stack involving a primitive" | |
353 | ;; The primitive involving the error must appear exactly once on the | |
354 | ;; stack. | |
355 | (let* ((stack (make-tagged-trimmed-stack tag '(#t))) | |
356 | (frames (stack->frames stack)) | |
357 | (num (count (lambda (frame) (eq? (frame-procedure frame) | |
358 | substring)) | |
359 | frames))) | |
360 | (= num 1))) | |
361 | ||
362 | (pass-if "arguments of a primitive stack frame" | |
363 | ;; Create a stack with two primitive frames and make sure the | |
364 | ;; arguments are correct. | |
365 | (let* ((stack (make-tagged-trimmed-stack tag '(#t))) | |
366 | (call-list (map (lambda (frame) | |
367 | (cons (frame-procedure frame) | |
368 | (frame-arguments frame))) | |
369 | (stack->frames stack)))) | |
370 | (and (equal? (car call-list) `(,make-stack #t)) | |
371 | (pair? (member `(,substring wrong type arg) | |
372 | (cdr call-list)))))) | |
373 | ||
99d7688b NL |
374 | (pass-if "inner trim with prompt tag" |
375 | (let* ((stack (make-tagged-trimmed-stack tag `(#t ,tag))) | |
376 | (frames (stack->frames stack))) | |
377 | ;; the top frame on the stack is the lambda inside the 'catch, and the | |
378 | ;; next frame is the (catch 'result ...) | |
379 | (and (eq? (frame-procedure (cadr frames)) | |
380 | catch) | |
381 | (eq? (car (frame-arguments (cadr frames))) | |
382 | 'result)))) | |
383 | ||
384 | (pass-if "outer trim with prompt tag" | |
385 | (let* ((stack (make-tagged-trimmed-stack tag `(#t 0 ,tag))) | |
386 | (frames (stack->frames stack))) | |
387 | ;; the top frame on the stack is the make-stack call, and the last | |
388 | ;; frame is the (with-throw-handler 'wrong-type-arg ...) | |
389 | (and (eq? (frame-procedure (car frames)) | |
390 | make-stack) | |
391 | (eq? (frame-procedure (car (last-pair frames))) | |
392 | with-throw-handler) | |
393 | (eq? (car (frame-arguments (car (last-pair frames)))) | |
394 | 'wrong-type-arg))))) | |
395 | ||
d2797644 NJ |
396 | ;;; |
397 | ;;; letrec init evaluation | |
398 | ;;; | |
399 | ||
400 | (with-test-prefix "letrec init evaluation" | |
401 | ||
402 | (pass-if "lots of inits calculated in correct order" | |
403 | (equal? (letrec ((a 'a) (b 'b) (c 'c) (d 'd) | |
404 | (e 'e) (f 'f) (g 'g) (h 'h) | |
405 | (i 'i) (j 'j) (k 'k) (l 'l) | |
406 | (m 'm) (n 'n) (o 'o) (p 'p) | |
407 | (q 'q) (r 'r) (s 's) (t 't) | |
408 | (u 'u) (v 'v) (w 'w) (x 'x) | |
409 | (y 'y) (z 'z)) | |
410 | (list a b c d e f g h i j k l m | |
411 | n o p q r s t u v w x y z)) | |
412 | '(a b c d e f g h i j k l m | |
413 | n o p q r s t u v w x y z)))) | |
414 | ||
42ddb3cb LC |
415 | ;;; |
416 | ;;; values | |
417 | ;;; | |
418 | ||
419 | (with-test-prefix "values" | |
420 | ||
421 | (pass-if "single value" | |
422 | (equal? 1 (values 1))) | |
423 | ||
424 | (pass-if "call-with-values" | |
425 | (equal? (call-with-values (lambda () (values 1 2 3 4)) list) | |
426 | '(1 2 3 4))) | |
427 | ||
428 | (pass-if "equal?" | |
429 | (equal? (values 1 2 3 4) (values 1 2 3 4)))) | |
4f2ec3be | 430 | |
f1046e6b LC |
431 | ;;; |
432 | ;;; stack overflow handling | |
433 | ;;; | |
434 | ||
435 | (with-test-prefix "stack overflow" | |
436 | ||
ea9f4f4b | 437 | ;; FIXME: this test does not test what it is intending to test |
f1046e6b LC |
438 | (pass-if-exception "exception raised" |
439 | exception:vm-error | |
440 | (let ((vm (make-vm)) | |
441 | (thunk (let loop () (cons 's (loop))))) | |
ea9f4f4b | 442 | (call-with-vm vm thunk)))) |
f1046e6b | 443 | |
c438cd71 LC |
444 | ;;; |
445 | ;;; docstrings | |
446 | ;;; | |
447 | ||
448 | (with-test-prefix "docstrings" | |
449 | ||
450 | (pass-if-equal "fixed closure" | |
451 | '("hello" "world") | |
452 | (map procedure-documentation | |
453 | (list (eval '(lambda (a b) "hello" (+ a b)) | |
454 | (current-module)) | |
455 | (eval '(lambda (a b) "world" (- a b)) | |
456 | (current-module))))) | |
457 | ||
458 | (pass-if-equal "fixed closure with many args" | |
459 | "So many args." | |
460 | (procedure-documentation | |
461 | (eval '(lambda (a b c d e f g h i j k) | |
462 | "So many args." | |
463 | (+ a b)) | |
464 | (current-module)))) | |
465 | ||
466 | (pass-if-equal "general closure" | |
467 | "How general." | |
468 | (procedure-documentation | |
469 | (eval '(lambda* (a b #:key k #:rest r) | |
470 | "How general." | |
471 | (+ a b)) | |
472 | (current-module))))) | |
473 | ||
d062a8c1 AW |
474 | ;;; |
475 | ;;; local-eval | |
476 | ;;; | |
477 | ||
478 | (with-test-prefix "local evaluation" | |
479 | ||
480 | (pass-if "local-eval" | |
481 | ||
2f3e4364 MW |
482 | (let* ((env1 (local-eval '(let ((x 1) (y 2) (z 3)) |
483 | (define-syntax-rule (foo x) (quote x)) | |
484 | (the-environment)) | |
485 | (current-module))) | |
d062a8c1 AW |
486 | (env2 (local-eval '(let ((x 111) (a 'a)) |
487 | (define-syntax-rule (bar x) (quote x)) | |
488 | (the-environment)) | |
489 | env1))) | |
490 | (local-eval '(set! x 11) env1) | |
491 | (local-eval '(set! y 22) env1) | |
492 | (local-eval '(set! z 33) env2) | |
493 | (and (equal? (local-eval '(list x y z) env1) | |
494 | '(11 22 33)) | |
495 | (equal? (local-eval '(list x y z a) env2) | |
496 | '(111 22 33 a))))) | |
497 | ||
498 | (pass-if "local-compile" | |
499 | ||
2f3e4364 MW |
500 | (let* ((env1 (local-compile '(let ((x 1) (y 2) (z 3)) |
501 | (define-syntax-rule (foo x) (quote x)) | |
502 | (the-environment)) | |
503 | (current-module))) | |
d062a8c1 AW |
504 | (env2 (local-compile '(let ((x 111) (a 'a)) |
505 | (define-syntax-rule (bar x) (quote x)) | |
506 | (the-environment)) | |
507 | env1))) | |
508 | (local-compile '(set! x 11) env1) | |
509 | (local-compile '(set! y 22) env1) | |
510 | (local-compile '(set! z 33) env2) | |
511 | (and (equal? (local-compile '(list x y z) env1) | |
512 | '(11 22 33)) | |
513 | (equal? (local-compile '(list x y z a) env2) | |
514 | '(111 22 33 a))))) | |
515 | ||
516 | (pass-if "the-environment within a macro" | |
517 | (let ((module-a-name '(test module the-environment a)) | |
518 | (module-b-name '(test module the-environment b))) | |
519 | (let ((module-a (resolve-module module-a-name)) | |
520 | (module-b (resolve-module module-b-name))) | |
521 | (module-use! module-a (resolve-interface '(guile))) | |
522 | (module-use! module-a (resolve-interface '(ice-9 local-eval))) | |
523 | (eval '(begin | |
524 | (define z 3) | |
525 | (define-syntax-rule (test) | |
526 | (let ((x 1) (y 2)) | |
527 | (the-environment)))) | |
528 | module-a) | |
529 | (module-use! module-b (resolve-interface '(guile))) | |
2f3e4364 MW |
530 | (let ((env (local-eval `(let ((x 111) (y 222)) |
531 | ((@@ ,module-a-name test))) | |
532 | module-b))) | |
d062a8c1 AW |
533 | (equal? (local-eval '(list x y z) env) |
534 | '(1 2 3)))))) | |
535 | ||
536 | (pass-if "capture pattern variables" | |
537 | (let ((env (syntax-case #'(((a 1) (b 2) (c 3)) | |
538 | ((d 4) (e 5) (f 6))) () | |
539 | ((((k v) ...) ...) (the-environment))))) | |
540 | (equal? (syntax->datum (local-eval '#'((k ... v ...) ...) env)) | |
541 | '((a b c 1 2 3) (d e f 4 5 6))))) | |
542 | ||
543 | (pass-if "mixed primitive-eval, local-eval and local-compile" | |
544 | ||
545 | (let* ((env1 (primitive-eval '(let ((x 1) (y 2) (z 3)) | |
546 | (define-syntax-rule (foo x) (quote x)) | |
547 | (the-environment)))) | |
548 | (env2 (local-eval '(let ((x 111) (a 'a)) | |
549 | (define-syntax-rule (bar x) (quote x)) | |
550 | (the-environment)) | |
551 | env1)) | |
552 | (env3 (local-compile '(let ((y 222) (b 'b)) | |
553 | (the-environment)) | |
554 | env2))) | |
555 | (local-eval '(set! x 11) env1) | |
556 | (local-compile '(set! y 22) env2) | |
557 | (local-eval '(set! z 33) env2) | |
558 | (local-compile '(set! a (* y 2)) env3) | |
559 | (and (equal? (local-compile '(list x y z) env1) | |
560 | '(11 22 33)) | |
561 | (equal? (local-eval '(list x y z a) env2) | |
562 | '(111 22 33 444)) | |
563 | (equal? (local-eval '(list x y z a b) env3) | |
564 | '(111 222 33 444 b)))))) | |
565 | ||
414959ca | 566 | ;;; eval.test ends here |