* boot-9.scm (while): Use a new key dynamically for each loop, so
authorKevin Ryde <user42@zip.com.au>
Sun, 17 Aug 2003 00:36:04 +0000 (00:36 +0000)
committerKevin Ryde <user42@zip.com.au>
Sun, 17 Aug 2003 00:36:04 +0000 (00:36 +0000)
break and continue associate to their loop even when recursing.

ice-9/boot-9.scm

index 93f3bf3..afdaec1 100644 (file)
 ;;;
 
 ;; The inner `do' loop avoids re-establishing a catch every iteration,
-;; that's only necessary if continue is actually used.
+;; that's only necessary if continue is actually used.  A new key is
+;; generated every time, so break and continue apply to their originating
+;; `while' even when recursing.  `while-helper' is an easy way to keep the
+;; `key' binding away from the cond and body code.
 ;;
 (define-macro (while cond . body)
-  (let ((key (make-symbol "while-key")))
-    `(,do ((break    ,(lambda () (throw key #t)))
-          (continue ,(lambda () (throw key #f))))
-        ((,catch (,quote ,key)
-                 (,lambda ()
+  (define (while-helper proc)
+    (do ((key (make-symbol "while-key")))
+       ((catch key
+               (lambda ()
+                 (proc (lambda () (throw key #t))
+                       (lambda () (throw key #f))))
+               (lambda (key arg) arg)))))
+  `(,while-helper (,lambda (break continue)
                    (,do ()
                        ((,not ,cond))
                      ,@body)
-                   #t)
-                 ,(lambda (key arg) arg))))))
+                   #t)))
+
 
 \f
 ;;; {Module System Macros}