residualize names into procedures. re-implement srfi-61. module naming foo.
[bpt/guile.git] / test-suite / tests / syntax.test
CommitLineData
08c608e1
DH
1;;;; syntax.test --- test suite for Guile's syntactic forms -*- scheme -*-
2;;;;
6e7d5622 3;;;; Copyright (C) 2001,2003,2004, 2005, 2006 Free Software Foundation, Inc.
08c608e1
DH
4;;;;
5;;;; This program is free software; you can redistribute it and/or modify
6;;;; it under the terms of the GNU General Public License as published by
7;;;; the Free Software Foundation; either version 2, or (at your option)
8;;;; any later version.
9;;;;
10;;;; This program is distributed in the hope that it will be useful,
11;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13;;;; GNU General Public License for more details.
14;;;;
15;;;; You should have received a copy of the GNU General Public License
16;;;; along with this software; see the file COPYING. If not, write to
92205699
MV
17;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18;;;; Boston, MA 02110-1301 USA
08c608e1 19
8aa28a91
DH
20(define-module (test-suite test-syntax)
21 :use-module (test-suite lib))
08c608e1 22
2a6f7afe 23
40b36cfb 24(define exception:generic-syncase-error
02604212 25 (cons 'syntax-error "source expression failed to match"))
40b36cfb
AW
26(define exception:unexpected-syntax
27 (cons 'syntax-error "unexpected syntax"))
28
2a6f7afe
DH
29(define exception:bad-expression
30 (cons 'syntax-error "Bad expression"))
cc56ba80 31
21628685 32(define exception:missing/extra-expr
89bff2fc 33 (cons 'syntax-error "Missing or extra expression"))
cc56ba80
DH
34(define exception:missing-expr
35 (cons 'syntax-error "Missing expression"))
ced8edb0
DH
36(define exception:missing-body-expr
37 (cons 'syntax-error "Missing body expression"))
cc56ba80
DH
38(define exception:extra-expr
39 (cons 'syntax-error "Extra expression"))
89bff2fc
DH
40(define exception:illegal-empty-combination
41 (cons 'syntax-error "Illegal empty combination"))
cc56ba80 42
dc1eed52
AW
43(define exception:bad-lambda
44 '(syntax-error . "bad lambda"))
45(define exception:bad-let
46 '(syntax-error . "bad let "))
47(define exception:bad-letrec
48 '(syntax-error . "bad letrec "))
08c608e1 49(define exception:bad-bindings
d6754c23
DH
50 (cons 'syntax-error "Bad bindings"))
51(define exception:bad-binding
52 (cons 'syntax-error "Bad binding"))
53(define exception:duplicate-binding
dc1eed52 54 (cons 'syntax-error "duplicate bound variable"))
08c608e1
DH
55(define exception:bad-body
56 (cons 'misc-error "^bad body"))
57(define exception:bad-formals
dc1eed52 58 '(syntax-error . "invalid parameter list"))
03a3e941
DH
59(define exception:bad-formal
60 (cons 'syntax-error "Bad formal"))
61(define exception:duplicate-formal
62 (cons 'syntax-error "Duplicate formal"))
cc56ba80 63
2a6f7afe
DH
64(define exception:missing-clauses
65 (cons 'syntax-error "Missing clauses"))
609a8b86
DH
66(define exception:misplaced-else-clause
67 (cons 'syntax-error "Misplaced else clause"))
2a6f7afe
DH
68(define exception:bad-case-clause
69 (cons 'syntax-error "Bad case clause"))
2a6f7afe
DH
70(define exception:bad-case-labels
71 (cons 'syntax-error "Bad case labels"))
609a8b86
DH
72(define exception:bad-cond-clause
73 (cons 'syntax-error "Bad cond clause"))
cc56ba80 74
08c608e1
DH
75
76(with-test-prefix "expressions"
77
d6e04e7c
DH
78 (with-test-prefix "Bad argument list"
79
80 (pass-if-exception "improper argument list of length 1"
40b36cfb 81 exception:generic-syncase-error
d6e04e7c
DH
82 (eval '(let ((foo (lambda (x y) #t)))
83 (foo . 1))
84 (interaction-environment)))
85
86 (pass-if-exception "improper argument list of length 2"
40b36cfb 87 exception:generic-syncase-error
d6e04e7c
DH
88 (eval '(let ((foo (lambda (x y) #t)))
89 (foo 1 . 2))
90 (interaction-environment))))
91
08c608e1
DH
92 (with-test-prefix "missing or extra expression"
93
94 ;; R5RS says:
95 ;; *Note:* In many dialects of Lisp, the empty combination, (),
96 ;; is a legitimate expression. In Scheme, combinations must
97 ;; have at least one subexpression, so () is not a syntactically
98 ;; valid expression.
1c54a87c
MV
99
100 ;; Fixed on 2001-3-3
101 (pass-if-exception "empty parentheses \"()\""
40b36cfb 102 exception:unexpected-syntax
d6e04e7c
DH
103 (eval '()
104 (interaction-environment)))))
08c608e1 105
7171f1ab
DH
106(with-test-prefix "quote"
107 #t)
108
109(with-test-prefix "quasiquote"
110
111 (with-test-prefix "unquote"
112
113 (pass-if "repeated execution"
114 (let ((foo (let ((i 0)) (lambda () (set! i (+ i 1)) `(,i)))))
115 (and (equal? (foo) '(1)) (equal? (foo) '(2))))))
116
117 (with-test-prefix "unquote-splicing"
118
119 (pass-if-exception "extra arguments"
02604212
AW
120 '(syntax-error . "unquote-splicing takes exactly one argument")
121 (eval '(quasiquote ((unquote-splicing (list 1 2) (list 3 4))))
122 (interaction-environment)))))
7171f1ab
DH
123
124(with-test-prefix "begin"
125
126 (pass-if "legal (begin)"
ce09ee19 127 (eval '(begin (begin) #t) (interaction-environment)))
7171f1ab 128
aa498d0c
DH
129 (with-test-prefix "unmemoization"
130
02604212
AW
131 ;; FIXME. I have no idea why, but the expander is filling in (if #f
132 ;; #f) as the second arm of the if, if the second arm is missing. I
133 ;; thought I made it not do that. But in the meantime, let's adapt,
134 ;; since that's not what we're testing.
135
aa498d0c 136 (pass-if "normal begin"
02604212 137 (let ((foo (lambda () (if (= 1 1) (begin (+ 1) (+ 2)) #f))))
aa498d0c 138 (equal? (procedure-source foo)
02604212 139 '(lambda () (if (= 1 1) (begin (+ 1) (+ 2)) #f)))))
aa498d0c
DH
140
141 (pass-if "redundant nested begin"
02604212 142 (let ((foo (lambda () (if (= 1 1) (begin (+ 1) (begin (+ 2) (+ 3))) #f))))
aa498d0c
DH
143 (foo) ; make sure, memoization has been performed
144 (equal? (procedure-source foo)
02604212 145 '(lambda () (if (= 1 1) (begin (+ 1) (begin (+ 2) (+ 3))) #f)))))
aa498d0c
DH
146
147 (pass-if "redundant begin at start of body"
148 (let ((foo (lambda () (begin (+ 1) (+ 2))))) ; should be optimized
149 (foo) ; make sure, memoization has been performed
150 (equal? (procedure-source foo)
151 '(lambda () (begin (+ 1) (+ 2)))))))
152
02604212
AW
153 (pass-if-exception "illegal (begin)"
154 exception:generic-syncase-error
ce09ee19 155 (eval '(begin (if #t (begin)) #t) (interaction-environment))))
7171f1ab 156
02604212
AW
157(define-syntax matches?
158 (syntax-rules (_)
159 ((_ (op arg ...) pat) (let ((x (op arg ...)))
160 (matches? x pat)))
161 ((_ x ()) (null? x))
162 ((_ x (a . b)) (and (pair? x)
163 (matches? (car x) a)
164 (matches? (cdr x) b)))
165 ((_ x _) #t)
166 ((_ x pat) (equal? x 'pat))))
167
08c608e1
DH
168(with-test-prefix "lambda"
169
aa498d0c
DH
170 (with-test-prefix "unmemoization"
171
172 (pass-if "normal lambda"
173 (let ((foo (lambda () (lambda (x y) (+ x y)))))
02604212
AW
174 (matches? (procedure-source foo)
175 (lambda () (lambda (_ _) (+ _ _))))))
aa498d0c
DH
176
177 (pass-if "lambda with documentation"
178 (let ((foo (lambda () (lambda (x y) "docstring" (+ x y)))))
02604212
AW
179 (matches? (procedure-source foo)
180 (lambda () (lambda (_ _) "docstring" (+ _ _)))))))
aa498d0c 181
08c608e1
DH
182 (with-test-prefix "bad formals"
183
ea6c2147 184 (pass-if-exception "(lambda)"
dc1eed52 185 exception:bad-lambda
d6e04e7c
DH
186 (eval '(lambda)
187 (interaction-environment)))
ea6c2147
DH
188
189 (pass-if-exception "(lambda . \"foo\")"
dc1eed52 190 exception:bad-lambda
d6e04e7c
DH
191 (eval '(lambda . "foo")
192 (interaction-environment)))
ea6c2147 193
ea6c2147 194 (pass-if-exception "(lambda \"foo\")"
dc1eed52 195 exception:bad-lambda
d6e04e7c
DH
196 (eval '(lambda "foo")
197 (interaction-environment)))
ea6c2147
DH
198
199 (pass-if-exception "(lambda \"foo\" #f)"
200 exception:bad-formals
4dce3c96
DH
201 (eval '(lambda "foo" #f)
202 (interaction-environment)))
ea6c2147
DH
203
204 (pass-if-exception "(lambda (x 1) 2)"
dc1eed52 205 exception:bad-formals
d6e04e7c
DH
206 (eval '(lambda (x 1) 2)
207 (interaction-environment)))
08c608e1
DH
208
209 (pass-if-exception "(lambda (1 x) 2)"
dc1eed52 210 exception:bad-formals
d6e04e7c
DH
211 (eval '(lambda (1 x) 2)
212 (interaction-environment)))
08c608e1
DH
213
214 (pass-if-exception "(lambda (x \"a\") 2)"
dc1eed52 215 exception:bad-formals
d6e04e7c
DH
216 (eval '(lambda (x "a") 2)
217 (interaction-environment)))
08c608e1
DH
218
219 (pass-if-exception "(lambda (\"a\" x) 2)"
dc1eed52 220 exception:bad-formals
d6e04e7c
DH
221 (eval '(lambda ("a" x) 2)
222 (interaction-environment))))
08c608e1 223
1c54a87c
MV
224 (with-test-prefix "duplicate formals"
225
226 ;; Fixed on 2001-3-3
227 (pass-if-exception "(lambda (x x) 1)"
dc1eed52 228 exception:bad-formals
d6e04e7c
DH
229 (eval '(lambda (x x) 1)
230 (interaction-environment)))
08c608e1 231
1c54a87c
MV
232 ;; Fixed on 2001-3-3
233 (pass-if-exception "(lambda (x x x) 1)"
dc1eed52 234 exception:bad-formals
d6e04e7c
DH
235 (eval '(lambda (x x x) 1)
236 (interaction-environment))))
7171f1ab
DH
237
238 (with-test-prefix "bad body"
239
240 (pass-if-exception "(lambda ())"
dc1eed52 241 exception:bad-lambda
d6e04e7c
DH
242 (eval '(lambda ())
243 (interaction-environment)))))
08c608e1
DH
244
245(with-test-prefix "let"
246
aa498d0c
DH
247 (with-test-prefix "unmemoization"
248
249 (pass-if "normal let"
250 (let ((foo (lambda () (let ((i 1) (j 2)) (+ i j)))))
dc1eed52
AW
251 (matches? (procedure-source foo)
252 (lambda () (let ((_ 1) (_ 2)) (+ _ _)))))))
aa498d0c 253
08c608e1
DH
254 (with-test-prefix "bindings"
255
256 (pass-if-exception "late binding"
257 exception:unbound-var
258 (let ((x 1) (y x)) y)))
259
7171f1ab 260 (with-test-prefix "bad bindings"
08c608e1 261
08c608e1 262 (pass-if-exception "(let)"
dc1eed52 263 exception:bad-let
d6e04e7c
DH
264 (eval '(let)
265 (interaction-environment)))
08c608e1 266
08c608e1 267 (pass-if-exception "(let 1)"
dc1eed52 268 exception:bad-let
d6e04e7c
DH
269 (eval '(let 1)
270 (interaction-environment)))
08c608e1 271
08c608e1 272 (pass-if-exception "(let (x))"
dc1eed52 273 exception:bad-let
d6e04e7c
DH
274 (eval '(let (x))
275 (interaction-environment)))
08c608e1 276
7171f1ab 277 (pass-if-exception "(let ((x)))"
dc1eed52 278 exception:bad-let
d6e04e7c
DH
279 (eval '(let ((x)))
280 (interaction-environment)))
08c608e1
DH
281
282 (pass-if-exception "(let (x) 1)"
dc1eed52 283 exception:bad-let
d6e04e7c
DH
284 (eval '(let (x) 1)
285 (interaction-environment)))
08c608e1
DH
286
287 (pass-if-exception "(let ((x)) 3)"
dc1eed52 288 exception:bad-let
d6e04e7c
DH
289 (eval '(let ((x)) 3)
290 (interaction-environment)))
08c608e1
DH
291
292 (pass-if-exception "(let ((x 1) y) x)"
dc1eed52 293 exception:bad-let
d6e04e7c
DH
294 (eval '(let ((x 1) y) x)
295 (interaction-environment)))
08c608e1
DH
296
297 (pass-if-exception "(let ((1 2)) 3)"
dc1eed52 298 exception:bad-let
4dce3c96
DH
299 (eval '(let ((1 2)) 3)
300 (interaction-environment))))
08c608e1 301
c0ed1605
MV
302 (with-test-prefix "duplicate bindings"
303
304 (pass-if-exception "(let ((x 1) (x 2)) x)"
d6754c23 305 exception:duplicate-binding
d6e04e7c
DH
306 (eval '(let ((x 1) (x 2)) x)
307 (interaction-environment))))
7171f1ab
DH
308
309 (with-test-prefix "bad body"
310
311 (pass-if-exception "(let ())"
dc1eed52 312 exception:bad-let
d6e04e7c
DH
313 (eval '(let ())
314 (interaction-environment)))
7171f1ab
DH
315
316 (pass-if-exception "(let ((x 1)))"
dc1eed52 317 exception:bad-let
d6e04e7c
DH
318 (eval '(let ((x 1)))
319 (interaction-environment)))))
08c608e1
DH
320
321(with-test-prefix "named let"
322
7171f1ab
DH
323 (with-test-prefix "initializers"
324
325 (pass-if "evaluated in outer environment"
326 (let ((f -))
327 (eqv? (let f ((n (f 1))) n) -1))))
328
329 (with-test-prefix "bad bindings"
330
331 (pass-if-exception "(let x (y))"
dc1eed52 332 exception:bad-let
d6e04e7c
DH
333 (eval '(let x (y))
334 (interaction-environment))))
7171f1ab 335
08c608e1
DH
336 (with-test-prefix "bad body"
337
338 (pass-if-exception "(let x ())"
dc1eed52 339 exception:bad-let
d6e04e7c
DH
340 (eval '(let x ())
341 (interaction-environment)))
08c608e1
DH
342
343 (pass-if-exception "(let x ((y 1)))"
dc1eed52 344 exception:bad-let
d6e04e7c
DH
345 (eval '(let x ((y 1)))
346 (interaction-environment)))))
08c608e1
DH
347
348(with-test-prefix "let*"
349
aa498d0c
DH
350 (with-test-prefix "unmemoization"
351
352 (pass-if "normal let*"
353 (let ((foo (lambda () (let* ((x 1) (y 2)) (+ x y)))))
dc1eed52
AW
354 (matches? (procedure-source foo)
355 (lambda () (let ((_ 1)) (let ((_ 2)) (+ _ _)))))))
aa498d0c
DH
356
357 (pass-if "let* without bindings"
358 (let ((foo (lambda () (let ((x 1) (y 2))
359 (let* ()
360 (and (= x 1) (= y 2)))))))
dc1eed52
AW
361 (matches? (procedure-source foo)
362 (lambda () (let ((_ 1) (_ 2))
363 (if (= _ 1) (= _ 2) #f)))))))
aa498d0c 364
e1a7b2ce
DH
365 (with-test-prefix "bindings"
366
367 (pass-if "(let* ((x 1) (x 2)) ...)"
368 (let* ((x 1) (x 2))
369 (= x 2)))
370
371 (pass-if "(let* ((x 1) (x x)) ...)"
372 (let* ((x 1) (x x))
aa498d0c
DH
373 (= x 1)))
374
375 (pass-if "(let ((x 1) (y 2)) (let* () ...))"
376 (let ((x 1) (y 2))
377 (let* ()
378 (and (= x 1) (= y 2))))))
e1a7b2ce 379
7171f1ab 380 (with-test-prefix "bad bindings"
08c608e1 381
08c608e1 382 (pass-if-exception "(let*)"
dc1eed52 383 exception:generic-syncase-error
d6e04e7c
DH
384 (eval '(let*)
385 (interaction-environment)))
08c608e1 386
08c608e1 387 (pass-if-exception "(let* 1)"
dc1eed52 388 exception:generic-syncase-error
d6e04e7c
DH
389 (eval '(let* 1)
390 (interaction-environment)))
08c608e1 391
08c608e1 392 (pass-if-exception "(let* (x))"
dc1eed52 393 exception:generic-syncase-error
d6e04e7c
DH
394 (eval '(let* (x))
395 (interaction-environment)))
08c608e1
DH
396
397 (pass-if-exception "(let* (x) 1)"
dc1eed52 398 exception:generic-syncase-error
d6e04e7c
DH
399 (eval '(let* (x) 1)
400 (interaction-environment)))
08c608e1
DH
401
402 (pass-if-exception "(let* ((x)) 3)"
dc1eed52 403 exception:generic-syncase-error
d6e04e7c
DH
404 (eval '(let* ((x)) 3)
405 (interaction-environment)))
08c608e1
DH
406
407 (pass-if-exception "(let* ((x 1) y) x)"
dc1eed52 408 exception:generic-syncase-error
d6e04e7c
DH
409 (eval '(let* ((x 1) y) x)
410 (interaction-environment)))
08c608e1
DH
411
412 (pass-if-exception "(let* x ())"
dc1eed52 413 exception:generic-syncase-error
4dce3c96
DH
414 (eval '(let* x ())
415 (interaction-environment)))
08c608e1
DH
416
417 (pass-if-exception "(let* x (y))"
dc1eed52 418 exception:generic-syncase-error
4dce3c96
DH
419 (eval '(let* x (y))
420 (interaction-environment)))
08c608e1
DH
421
422 (pass-if-exception "(let* ((1 2)) 3)"
dc1eed52 423 exception:generic-syncase-error
4dce3c96
DH
424 (eval '(let* ((1 2)) 3)
425 (interaction-environment))))
7171f1ab
DH
426
427 (with-test-prefix "bad body"
428
429 (pass-if-exception "(let* ())"
dc1eed52 430 exception:generic-syncase-error
d6e04e7c
DH
431 (eval '(let* ())
432 (interaction-environment)))
7171f1ab
DH
433
434 (pass-if-exception "(let* ((x 1)))"
dc1eed52 435 exception:generic-syncase-error
d6e04e7c
DH
436 (eval '(let* ((x 1)))
437 (interaction-environment)))))
08c608e1
DH
438
439(with-test-prefix "letrec"
440
aa498d0c
DH
441 (with-test-prefix "unmemoization"
442
443 (pass-if "normal letrec"
444 (let ((foo (lambda () (letrec ((i 1) (j 2)) (+ i j)))))
dc1eed52
AW
445 (matches? (procedure-source foo)
446 (lambda () (letrec ((_ 1) (_ 2)) (+ _ _)))))))
aa498d0c 447
08c608e1
DH
448 (with-test-prefix "bindings"
449
450 (pass-if-exception "initial bindings are undefined"
0ac46745 451 exception:used-before-defined
08c608e1
DH
452 (let ((x 1))
453 (letrec ((x 1) (y x)) y))))
454
7171f1ab 455 (with-test-prefix "bad bindings"
08c608e1 456
08c608e1 457 (pass-if-exception "(letrec)"
dc1eed52 458 exception:bad-letrec
d6e04e7c
DH
459 (eval '(letrec)
460 (interaction-environment)))
08c608e1 461
08c608e1 462 (pass-if-exception "(letrec 1)"
dc1eed52 463 exception:bad-letrec
d6e04e7c
DH
464 (eval '(letrec 1)
465 (interaction-environment)))
08c608e1 466
08c608e1 467 (pass-if-exception "(letrec (x))"
dc1eed52 468 exception:bad-letrec
d6e04e7c
DH
469 (eval '(letrec (x))
470 (interaction-environment)))
08c608e1
DH
471
472 (pass-if-exception "(letrec (x) 1)"
dc1eed52 473 exception:bad-letrec
d6e04e7c
DH
474 (eval '(letrec (x) 1)
475 (interaction-environment)))
08c608e1
DH
476
477 (pass-if-exception "(letrec ((x)) 3)"
dc1eed52 478 exception:bad-letrec
d6e04e7c
DH
479 (eval '(letrec ((x)) 3)
480 (interaction-environment)))
08c608e1
DH
481
482 (pass-if-exception "(letrec ((x 1) y) x)"
dc1eed52 483 exception:bad-letrec
d6e04e7c
DH
484 (eval '(letrec ((x 1) y) x)
485 (interaction-environment)))
08c608e1
DH
486
487 (pass-if-exception "(letrec x ())"
dc1eed52 488 exception:bad-letrec
4dce3c96
DH
489 (eval '(letrec x ())
490 (interaction-environment)))
08c608e1
DH
491
492 (pass-if-exception "(letrec x (y))"
dc1eed52 493 exception:bad-letrec
4dce3c96
DH
494 (eval '(letrec x (y))
495 (interaction-environment)))
08c608e1
DH
496
497 (pass-if-exception "(letrec ((1 2)) 3)"
dc1eed52 498 exception:bad-letrec
4dce3c96
DH
499 (eval '(letrec ((1 2)) 3)
500 (interaction-environment))))
08c608e1 501
c0ed1605
MV
502 (with-test-prefix "duplicate bindings"
503
504 (pass-if-exception "(letrec ((x 1) (x 2)) x)"
d6754c23 505 exception:duplicate-binding
d6e04e7c
DH
506 (eval '(letrec ((x 1) (x 2)) x)
507 (interaction-environment))))
7171f1ab
DH
508
509 (with-test-prefix "bad body"
510
511 (pass-if-exception "(letrec ())"
dc1eed52 512 exception:bad-letrec
d6e04e7c
DH
513 (eval '(letrec ())
514 (interaction-environment)))
7171f1ab
DH
515
516 (pass-if-exception "(letrec ((x 1)))"
dc1eed52 517 exception:bad-letrec
d6e04e7c
DH
518 (eval '(letrec ((x 1)))
519 (interaction-environment)))))
08c608e1
DH
520
521(with-test-prefix "if"
522
aa498d0c
DH
523 (with-test-prefix "unmemoization"
524
525 (pass-if "normal if"
526 (let ((foo (lambda (x) (if x (+ 1) (+ 2)))))
527 (foo #t) ; make sure, memoization has been performed
528 (foo #f) ; make sure, memoization has been performed
dc1eed52
AW
529 (matches? (procedure-source foo)
530 (lambda (_) (if _ (+ 1) (+ 2))))))
aa498d0c 531
dc1eed52 532 (expect-fail "if without else"
aa498d0c
DH
533 (let ((foo (lambda (x) (if x (+ 1)))))
534 (foo #t) ; make sure, memoization has been performed
535 (foo #f) ; make sure, memoization has been performed
536 (equal? (procedure-source foo)
537 '(lambda (x) (if x (+ 1))))))
538
dc1eed52 539 (expect-fail "if #f without else"
aa498d0c
DH
540 (let ((foo (lambda () (if #f #f))))
541 (foo) ; make sure, memoization has been performed
542 (equal? (procedure-source foo)
543 `(lambda () (if #f #f))))))
544
08c608e1
DH
545 (with-test-prefix "missing or extra expressions"
546
547 (pass-if-exception "(if)"
dc1eed52 548 exception:generic-syncase-error
4dce3c96
DH
549 (eval '(if)
550 (interaction-environment)))
08c608e1
DH
551
552 (pass-if-exception "(if 1 2 3 4)"
dc1eed52 553 exception:generic-syncase-error
4dce3c96
DH
554 (eval '(if 1 2 3 4)
555 (interaction-environment)))))
08c608e1
DH
556
557(with-test-prefix "cond"
558
aa498d0c
DH
559 (with-test-prefix "cond is hygienic"
560
561 (pass-if "bound 'else is handled correctly"
562 (eq? (let ((else 'ok)) (cond (else))) 'ok))
563
564 (with-test-prefix "bound '=> is handled correctly"
565
566 (pass-if "#t => 'ok"
567 (let ((=> 'foo))
568 (eq? (cond (#t => 'ok)) 'ok)))
569
570 (pass-if "else =>"
571 (let ((=> 'foo))
572 (eq? (cond (else =>)) 'foo)))
573
574 (pass-if "else => identity"
575 (let ((=> 'foo))
576 (eq? (cond (else => identity)) identity)))))
577
9ee0f678
LC
578 (with-test-prefix "SRFI-61"
579
580 (pass-if "always available"
581 (cond-expand (srfi-61 #t) (else #f)))
582
583 (pass-if "single value consequent"
584 (eq? 'ok (cond (#t identity => (lambda (x) 'ok)) (else #f))))
585
586 (pass-if "single value alternate"
587 (eq? 'ok (cond (#t not => (lambda (x) #f)) (else 'ok))))
588
589 (pass-if-exception "doesn't affect standard =>"
590 exception:wrong-num-args
591 (cond ((values 1 2) => (lambda (x y) #t))))
592
593 (pass-if "multiple values consequent"
594 (equal? '(2 1) (cond ((values 1 2)
595 (lambda (one two)
596 (and (= 1 one) (= 2 two))) =>
597 (lambda (one two) (list two one)))
598 (else #f))))
599
600 (pass-if "multiple values alternate"
601 (eq? 'ok (cond ((values 2 3 4)
602 (lambda args (equal? '(1 2 3) args)) =>
603 (lambda (x y z) #f))
604 (else 'ok))))
605
606 (pass-if "zero values"
607 (eq? 'ok (cond ((values) (lambda () #t) => (lambda () 'ok))
608 (else #f))))
609
610 (pass-if "bound => is handled correctly"
611 (let ((=> 'ok))
612 (eq? 'ok (cond (#t identity =>) (else #f)))))
613
614 (pass-if-exception "missing recipient"
dc1eed52 615 '(syntax-error . "cond: wrong number of receiver expressions")
9ee0f678
LC
616 (cond (#t identity =>)))
617
618 (pass-if-exception "extra recipient"
dc1eed52 619 '(syntax-error . "cond: wrong number of receiver expressions")
9ee0f678
LC
620 (cond (#t identity => identity identity))))
621
aa498d0c
DH
622 (with-test-prefix "unmemoization"
623
dc1eed52 624 ;; FIXME: the (if #f #f) is a hack!
aa498d0c 625 (pass-if "normal clauses"
dc1eed52 626 (let ((foo (lambda () (cond ((= x 1) 'bar) ((= x 2) 'baz)))))
aa498d0c 627 (equal? (procedure-source foo)
dc1eed52 628 '(lambda () (if (= x 1) 'bar (if (= x 2) 'baz (if #f #f)))))))
aa498d0c
DH
629
630 (pass-if "else"
631 (let ((foo (lambda () (cond (else 'bar)))))
aa498d0c 632 (equal? (procedure-source foo)
dc1eed52 633 '(lambda () 'bar))))
aa498d0c 634
dc1eed52 635 ;; FIXME: the (if #f #f) is a hack!
aa498d0c
DH
636 (pass-if "=>"
637 (let ((foo (lambda () (cond (#t => identity)))))
dc1eed52
AW
638 (matches? (procedure-source foo)
639 (lambda () (let ((_ #t))
640 (if _ (identity _) (if #f #f))))))))
aa498d0c 641
08c608e1
DH
642 (with-test-prefix "bad or missing clauses"
643
644 (pass-if-exception "(cond)"
dc1eed52 645 exception:generic-syncase-error
d6e04e7c
DH
646 (eval '(cond)
647 (interaction-environment)))
08c608e1
DH
648
649 (pass-if-exception "(cond #t)"
dc1eed52 650 exception:generic-syncase-error
d6e04e7c
DH
651 (eval '(cond #t)
652 (interaction-environment)))
08c608e1
DH
653
654 (pass-if-exception "(cond 1)"
dc1eed52 655 exception:generic-syncase-error
d6e04e7c
DH
656 (eval '(cond 1)
657 (interaction-environment)))
08c608e1
DH
658
659 (pass-if-exception "(cond 1 2)"
dc1eed52 660 exception:generic-syncase-error
d6e04e7c
DH
661 (eval '(cond 1 2)
662 (interaction-environment)))
08c608e1
DH
663
664 (pass-if-exception "(cond 1 2 3)"
dc1eed52 665 exception:generic-syncase-error
d6e04e7c
DH
666 (eval '(cond 1 2 3)
667 (interaction-environment)))
08c608e1
DH
668
669 (pass-if-exception "(cond 1 2 3 4)"
dc1eed52 670 exception:generic-syncase-error
d6e04e7c
DH
671 (eval '(cond 1 2 3 4)
672 (interaction-environment)))
08c608e1
DH
673
674 (pass-if-exception "(cond ())"
dc1eed52 675 exception:generic-syncase-error
d6e04e7c
DH
676 (eval '(cond ())
677 (interaction-environment)))
08c608e1
DH
678
679 (pass-if-exception "(cond () 1)"
dc1eed52 680 exception:generic-syncase-error
d6e04e7c
DH
681 (eval '(cond () 1)
682 (interaction-environment)))
08c608e1
DH
683
684 (pass-if-exception "(cond (1) 1)"
dc1eed52 685 exception:generic-syncase-error
d6e04e7c 686 (eval '(cond (1) 1)
aa498d0c 687 (interaction-environment))))
b461abe7 688
d6e04e7c 689 (with-test-prefix "wrong number of arguments"
08c608e1 690
d6e04e7c
DH
691 (pass-if-exception "=> (lambda (x y) #t)"
692 exception:wrong-num-args
693 (cond (1 => (lambda (x y) #t))))))
08c608e1 694
27a22666
DH
695(with-test-prefix "case"
696
58a2510b
DH
697 (pass-if "clause with empty labels list"
698 (case 1 (() #f) (else #t)))
699
2a6f7afe
DH
700 (with-test-prefix "case is hygienic"
701
702 (pass-if-exception "bound 'else is handled correctly"
dc1eed52 703 exception:generic-syncase-error
2a6f7afe
DH
704 (eval '(let ((else #f)) (case 1 (else #f)))
705 (interaction-environment))))
706
aa498d0c
DH
707 (with-test-prefix "unmemoization"
708
709 (pass-if "normal clauses"
710 (let ((foo (lambda (x) (case x ((1) 'bar) ((2) 'baz) (else 'foobar)))))
dc1eed52
AW
711 (matches? (procedure-source foo)
712 (lambda (_)
713 (if ((@@ (guile) memv) _ '(1))
714 'bar
715 (if ((@@ (guile) memv) _ '(2))
716 'baz
717 'foobar))))))
aa498d0c
DH
718
719 (pass-if "empty labels"
720 (let ((foo (lambda (x) (case x ((1) 'bar) (() 'baz) (else 'foobar)))))
dc1eed52
AW
721 (matches? (procedure-source foo)
722 (lambda (_)
723 (if ((@@ (guile) memv) _ '(1))
724 'bar
725 (if ((@@ (guile) memv) _ '())
726 'baz
727 'foobar)))))))
aa498d0c 728
27a22666
DH
729 (with-test-prefix "bad or missing clauses"
730
731 (pass-if-exception "(case)"
dc1eed52 732 exception:generic-syncase-error
d6e04e7c
DH
733 (eval '(case)
734 (interaction-environment)))
27a22666 735
27a22666 736 (pass-if-exception "(case . \"foo\")"
dc1eed52 737 exception:generic-syncase-error
d6e04e7c
DH
738 (eval '(case . "foo")
739 (interaction-environment)))
27a22666
DH
740
741 (pass-if-exception "(case 1)"
dc1eed52 742 exception:generic-syncase-error
d6e04e7c
DH
743 (eval '(case 1)
744 (interaction-environment)))
27a22666 745
27a22666 746 (pass-if-exception "(case 1 . \"foo\")"
dc1eed52 747 exception:generic-syncase-error
d6e04e7c
DH
748 (eval '(case 1 . "foo")
749 (interaction-environment)))
27a22666
DH
750
751 (pass-if-exception "(case 1 \"foo\")"
dc1eed52 752 exception:generic-syncase-error
d6e04e7c
DH
753 (eval '(case 1 "foo")
754 (interaction-environment)))
27a22666
DH
755
756 (pass-if-exception "(case 1 ())"
dc1eed52 757 exception:generic-syncase-error
d6e04e7c
DH
758 (eval '(case 1 ())
759 (interaction-environment)))
27a22666
DH
760
761 (pass-if-exception "(case 1 (\"foo\"))"
dc1eed52 762 exception:generic-syncase-error
d6e04e7c
DH
763 (eval '(case 1 ("foo"))
764 (interaction-environment)))
27a22666
DH
765
766 (pass-if-exception "(case 1 (\"foo\" \"bar\"))"
dc1eed52 767 exception:generic-syncase-error
d6e04e7c
DH
768 (eval '(case 1 ("foo" "bar"))
769 (interaction-environment)))
27a22666 770
27a22666 771 (pass-if-exception "(case 1 ((2) \"bar\") . \"foo\")"
dc1eed52 772 exception:generic-syncase-error
d6e04e7c
DH
773 (eval '(case 1 ((2) "bar") . "foo")
774 (interaction-environment)))
27a22666 775
d6e04e7c 776 (pass-if-exception "(case 1 ((2) \"bar\") (else))"
dc1eed52 777 exception:generic-syncase-error
d6e04e7c
DH
778 (eval '(case 1 ((2) "bar") (else))
779 (interaction-environment)))
27a22666 780
27a22666 781 (pass-if-exception "(case 1 (else #f) . \"foo\")"
dc1eed52 782 exception:generic-syncase-error
d6e04e7c
DH
783 (eval '(case 1 (else #f) . "foo")
784 (interaction-environment)))
27a22666
DH
785
786 (pass-if-exception "(case 1 (else #f) ((1) #t))"
dc1eed52 787 exception:generic-syncase-error
d6e04e7c
DH
788 (eval '(case 1 (else #f) ((1) #t))
789 (interaction-environment)))))
27a22666 790
ced8edb0 791(with-test-prefix "top-level define"
08c608e1 792
3dcf3373
LC
793 (pass-if "redefinition"
794 (let ((m (make-module)))
795 (beautify-user-module! m)
796
797 ;; The previous value of `round' must still be visible at the time the
798 ;; new `round' is defined. According to R5RS (Section 5.2.1), `define'
799 ;; should behave like `set!' in this case (except that in the case of
800 ;; Guile, we respect module boundaries).
801 (eval '(define round round) m)
802 (eq? (module-ref m 'round) round)))
36245b66 803
7171f1ab
DH
804 (with-test-prefix "currying"
805
806 (pass-if "(define ((foo)) #f)"
ced8edb0
DH
807 (eval '(begin
808 (define ((foo)) #t)
809 ((foo)))
810 (interaction-environment))))
7171f1ab 811
c454c4e6
DH
812 (with-test-prefix "unmemoization"
813
814 (pass-if "definition unmemoized without prior execution"
815 (eval '(begin
816 (define (blub) (cons ('(1 . 2)) 2))
817 (equal?
818 (procedure-source blub)
819 '(lambda () (cons ('(1 . 2)) 2))))
820 (interaction-environment)))
821
822 (pass-if "definition with documentation unmemoized without prior execution"
823 (eval '(begin
824 (define (blub) "Comment" (cons ('(1 . 2)) 2))
825 (equal?
826 (procedure-source blub)
827 '(lambda () "Comment" (cons ('(1 . 2)) 2))))
828 (interaction-environment))))
829
08c608e1
DH
830 (with-test-prefix "missing or extra expressions"
831
832 (pass-if-exception "(define)"
cc56ba80 833 exception:missing-expr
d6e04e7c
DH
834 (eval '(define)
835 (interaction-environment)))))
08c608e1 836
ced8edb0
DH
837(with-test-prefix "internal define"
838
839 (pass-if "internal defines become letrec"
840 (eval '(let ((a identity) (b identity) (c identity))
841 (define (a x) (if (= x 0) 'a (b (- x 1))))
842 (define (b x) (if (= x 0) 'b (c (- x 1))))
843 (define (c x) (if (= x 0) 'c (a (- x 1))))
844 (and (eq? 'a (a 0) (a 3))
845 (eq? 'b (a 1) (a 4))
846 (eq? 'c (a 2) (a 5))))
847 (interaction-environment)))
848
3dcf3373
LC
849 (pass-if "binding is created before expression is evaluated"
850 ;; Internal defines are equivalent to `letrec' (R5RS, Section 5.2.2).
851 (= (eval '(let ()
852 (define foo
853 (begin
854 (set! foo 1)
855 (+ foo 1)))
856 foo)
857 (interaction-environment))
858 2))
859
c86c440b 860 (pass-if "internal defines with begin"
ced8edb0
DH
861 (false-if-exception
862 (eval '(let ((a identity) (b identity) (c identity))
863 (define (a x) (if (= x 0) 'a (b (- x 1))))
864 (begin
865 (define (b x) (if (= x 0) 'b (c (- x 1)))))
866 (define (c x) (if (= x 0) 'c (a (- x 1))))
867 (and (eq? 'a (a 0) (a 3))
868 (eq? 'b (a 1) (a 4))
869 (eq? 'c (a 2) (a 5))))
870 (interaction-environment))))
871
c86c440b 872 (pass-if "internal defines with empty begin"
ced8edb0
DH
873 (false-if-exception
874 (eval '(let ((a identity) (b identity) (c identity))
875 (define (a x) (if (= x 0) 'a (b (- x 1))))
876 (begin)
877 (define (b x) (if (= x 0) 'b (c (- x 1))))
878 (define (c x) (if (= x 0) 'c (a (- x 1))))
879 (and (eq? 'a (a 0) (a 3))
880 (eq? 'b (a 1) (a 4))
881 (eq? 'c (a 2) (a 5))))
882 (interaction-environment))))
883
c3d94801 884 (pass-if "internal defines with macro application"
560434b3
DH
885 (false-if-exception
886 (eval '(begin
c3d94801 887 (defmacro my-define forms
560434b3 888 (cons 'define forms))
c3d94801
DH
889 (let ((a identity) (b identity) (c identity))
890 (define (a x) (if (= x 0) 'a (b (- x 1))))
891 (my-define (b x) (if (= x 0) 'b (c (- x 1))))
892 (define (c x) (if (= x 0) 'c (a (- x 1))))
893 (and (eq? 'a (a 0) (a 3))
894 (eq? 'b (a 1) (a 4))
895 (eq? 'c (a 2) (a 5)))))
560434b3
DH
896 (interaction-environment))))
897
ced8edb0
DH
898 (pass-if-exception "missing body expression"
899 exception:missing-body-expr
900 (eval '(let () (define x #t))
a264c013
DH
901 (interaction-environment)))
902
903 (pass-if "unmemoization"
904 (eval '(begin
905 (define (foo)
906 (define (bar)
907 'ok)
908 (bar))
909 (foo)
910 (equal?
911 (procedure-source foo)
912 '(lambda () (letrec ((bar (lambda () (quote ok)))) (bar)))))
ced8edb0
DH
913 (interaction-environment))))
914
aa498d0c
DH
915(with-test-prefix "do"
916
917 (with-test-prefix "unmemoization"
918
919 (pass-if "normal case"
920 (let ((foo (lambda () (do ((i 1 (+ i 1)) (j 2))
921 ((> i 9) (+ i j))
922 (identity i)))))
923 (foo) ; make sure, memoization has been performed
924 (equal? (procedure-source foo)
925 '(lambda () (do ((i 1 (+ i 1)) (j 2))
926 ((> i 9) (+ i j))
927 (identity i))))))
928
929 (pass-if "reduced case"
930 (let ((foo (lambda () (do ((i 1 (+ i 1)) (j 2 j)) ; redundant step for j
931 ((> i 9) (+ i j))
932 (identity i)))))
933 (foo) ; make sure, memoization has been performed
934 (equal? (procedure-source foo)
935 '(lambda () (do ((i 1 (+ i 1)) (j 2)) ; no redundancy here
936 ((> i 9) (+ i j))
937 (identity i))))))))
938
08c608e1
DH
939(with-test-prefix "set!"
940
aa498d0c
DH
941 (with-test-prefix "unmemoization"
942
943 (pass-if "normal set!"
944 (let ((foo (lambda (x) (set! x (+ 1 x)))))
945 (foo 1) ; make sure, memoization has been performed
946 (equal? (procedure-source foo)
947 '(lambda (x) (set! x (+ 1 x)))))))
948
08c608e1
DH
949 (with-test-prefix "missing or extra expressions"
950
951 (pass-if-exception "(set!)"
da48db62 952 exception:missing/extra-expr
4dce3c96
DH
953 (eval '(set!)
954 (interaction-environment)))
08c608e1
DH
955
956 (pass-if-exception "(set! 1)"
da48db62 957 exception:missing/extra-expr
4dce3c96
DH
958 (eval '(set! 1)
959 (interaction-environment)))
08c608e1
DH
960
961 (pass-if-exception "(set! 1 2 3)"
da48db62 962 exception:missing/extra-expr
4dce3c96
DH
963 (eval '(set! 1 2 3)
964 (interaction-environment))))
08c608e1
DH
965
966 (with-test-prefix "bad variable"
967
968 (pass-if-exception "(set! \"\" #t)"
da48db62 969 exception:bad-variable
4dce3c96
DH
970 (eval '(set! "" #t)
971 (interaction-environment)))
08c608e1
DH
972
973 (pass-if-exception "(set! 1 #t)"
da48db62 974 exception:bad-variable
4dce3c96
DH
975 (eval '(set! 1 #t)
976 (interaction-environment)))
08c608e1
DH
977
978 (pass-if-exception "(set! #t #f)"
da48db62 979 exception:bad-variable
4dce3c96
DH
980 (eval '(set! #t #f)
981 (interaction-environment)))
08c608e1
DH
982
983 (pass-if-exception "(set! #f #t)"
da48db62 984 exception:bad-variable
4dce3c96
DH
985 (eval '(set! #f #t)
986 (interaction-environment)))
08c608e1 987
96dfea7d 988 (pass-if-exception "(set! #\\space #f)"
da48db62 989 exception:bad-variable
4dce3c96
DH
990 (eval '(set! #\space #f)
991 (interaction-environment)))))
08c608e1 992
08c608e1
DH
993(with-test-prefix "quote"
994
995 (with-test-prefix "missing or extra expression"
996
997 (pass-if-exception "(quote)"
998 exception:missing/extra-expr
4dce3c96
DH
999 (eval '(quote)
1000 (interaction-environment)))
08c608e1
DH
1001
1002 (pass-if-exception "(quote a b)"
1003 exception:missing/extra-expr
4dce3c96
DH
1004 (eval '(quote a b)
1005 (interaction-environment)))))
2798ba71
KR
1006
1007(with-test-prefix "while"
1008
1009 (define (unreachable)
1010 (error "unreachable code has been reached!"))
1011
2798ba71
KR
1012 ;; Return a new procedure COND which when called (COND) will return #t the
1013 ;; first N times, then #f, then any further call is an error. N=0 is
1014 ;; allowed, in which case #f is returned by the first call.
1015 (define (make-iterations-cond n)
1016 (lambda ()
1017 (cond ((not n)
1018 (error "oops, condition re-tested after giving false"))
1019 ((= 0 n)
1020 (set! n #f)
1021 #f)
1022 (else
1023 (set! n (1- n))
1024 #t))))
1025
1026
1027 (pass-if-exception "too few args" exception:wrong-num-args
d6e04e7c 1028 (eval '(while) (interaction-environment)))
2798ba71
KR
1029
1030 (with-test-prefix "empty body"
1031 (do ((n 0 (1+ n)))
1032 ((> n 5))
1033 (pass-if n
ce09ee19
AW
1034 (eval `(letrec ((make-iterations-cond
1035 (lambda (n)
1036 (lambda ()
1037 (cond ((not n)
1038 (error "oops, condition re-tested after giving false"))
1039 ((= 0 n)
1040 (set! n #f)
1041 #f)
1042 (else
1043 (set! n (1- n))
1044 #t))))))
1045 (let ((cond (make-iterations-cond ,n)))
1046 (while (cond))
1047 #t))
1048 (interaction-environment)))))
2798ba71
KR
1049
1050 (pass-if "initially false"
1051 (while #f
1052 (unreachable))
1053 #t)
1054
1055 (with-test-prefix "in empty environment"
d6e04e7c
DH
1056
1057 ;; an environment with no bindings at all
1058 (define empty-environment
1059 (make-module 1))
2ebe323a
KR
1060
1061 ;; these tests are 'unresolved because to work with ice-9 syncase it was
1062 ;; necessary to drop the unquote from `do' in the implementation, and
1063 ;; unfortunately that makes `while' depend on its evaluation environment
d6e04e7c 1064
2798ba71 1065 (pass-if "empty body"
2ebe323a 1066 (throw 'unresolved)
2798ba71
KR
1067 (eval `(,while #f)
1068 empty-environment)
1069 #t)
1070
1071 (pass-if "initially false"
2ebe323a 1072 (throw 'unresolved)
2798ba71
KR
1073 (eval `(,while #f
1074 #f)
1075 empty-environment)
1076 #t)
1077
1078 (pass-if "iterating"
2ebe323a 1079 (throw 'unresolved)
2798ba71
KR
1080 (let ((cond (make-iterations-cond 3)))
1081 (eval `(,while (,cond)
1082 123 456)
1083 empty-environment))
1084 #t))
1085
1086 (with-test-prefix "iterations"
1087 (do ((n 0 (1+ n)))
1088 ((> n 5))
1089 (pass-if n
1090 (let ((cond (make-iterations-cond n))
1091 (i 0))
1092 (while (cond)
1093 (set! i (1+ i)))
1094 (= i n)))))
1095
1096 (with-test-prefix "break"
1097
1098 (pass-if-exception "too many args" exception:wrong-num-args
1099 (while #t
1100 (break 1)))
1101
1102 (with-test-prefix "from cond"
1103 (pass-if "first"
1104 (while (begin
1105 (break)
1106 (unreachable))
1107 (unreachable))
1108 #t)
1109
1110 (do ((n 0 (1+ n)))
1111 ((> n 5))
1112 (pass-if n
1113 (let ((cond (make-iterations-cond n))
1114 (i 0))
1115 (while (if (cond)
1116 #t
1117 (begin
1118 (break)
1119 (unreachable)))
1120 (set! i (1+ i)))
1121 (= i n)))))
1122
1123 (with-test-prefix "from body"
1124 (pass-if "first"
1125 (while #t
1126 (break)
1127 (unreachable))
1128 #t)
1129
1130 (do ((n 0 (1+ n)))
1131 ((> n 5))
1132 (pass-if n
1133 (let ((cond (make-iterations-cond n))
1134 (i 0))
1135 (while #t
1136 (if (not (cond))
1137 (begin
1138 (break)
1139 (unreachable)))
1140 (set! i (1+ i)))
1141 (= i n)))))
1142
1143 (pass-if "from nested"
1144 (while #t
1145 (let ((outer-break break))
1146 (while #t
1147 (outer-break)
1148 (unreachable)))
1149 (unreachable))
cc08aafd
KR
1150 #t)
1151
1152 (pass-if "from recursive"
1153 (let ((outer-break #f))
1154 (define (r n)
1155 (while #t
1156 (if (eq? n 'outer)
1157 (begin
1158 (set! outer-break break)
1159 (r 'inner))
1160 (begin
1161 (outer-break)
1162 (unreachable))))
1163 (if (eq? n 'inner)
1164 (error "broke only from inner loop")))
1165 (r 'outer))
2798ba71
KR
1166 #t))
1167
1168 (with-test-prefix "continue"
1169
1170 (pass-if-exception "too many args" exception:wrong-num-args
1171 (while #t
1172 (continue 1)))
1173
1174 (with-test-prefix "from cond"
1175 (do ((n 0 (1+ n)))
1176 ((> n 5))
1177 (pass-if n
1178 (let ((cond (make-iterations-cond n))
1179 (i 0))
1180 (while (if (cond)
1181 (begin
1182 (set! i (1+ i))
1183 (continue)
1184 (unreachable))
1185 #f)
1186 (unreachable))
1187 (= i n)))))
1188
1189 (with-test-prefix "from body"
1190 (do ((n 0 (1+ n)))
1191 ((> n 5))
1192 (pass-if n
1193 (let ((cond (make-iterations-cond n))
1194 (i 0))
1195 (while (cond)
1196 (set! i (1+ i))
1197 (continue)
1198 (unreachable))
1199 (= i n)))))
1200
1201 (pass-if "from nested"
1202 (let ((cond (make-iterations-cond 3)))
1203 (while (cond)
1204 (let ((outer-continue continue))
1205 (while #t
1206 (outer-continue)
1207 (unreachable)))))
cc08aafd
KR
1208 #t)
1209
1210 (pass-if "from recursive"
1211 (let ((outer-continue #f))
1212 (define (r n)
1213 (let ((cond (make-iterations-cond 3))
1214 (first #t))
1215 (while (begin
1216 (if (and (not first)
1217 (eq? n 'inner))
1218 (error "continued only to inner loop"))
1219 (cond))
1220 (set! first #f)
1221 (if (eq? n 'outer)
1222 (begin
1223 (set! outer-continue continue)
1224 (r 'inner))
1225 (begin
1226 (outer-continue)
1227 (unreachable))))))
1228 (r 'outer))
2798ba71 1229 #t)))