mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-07 18:30:25 +02:00
(while): Rewrite, continue as proper escape, break
without return value, break and continue new for each while form, don't depend on bindings in expansion environment.
This commit is contained in:
parent
88a63bfc10
commit
773abfbb81
1 changed files with 20 additions and 12 deletions
|
@ -2491,18 +2491,6 @@
|
|||
(loop (1- count) (cons count result)))))
|
||||
|
||||
|
||||
;;; {While}
|
||||
;;;
|
||||
;;; with `continue' and `break'.
|
||||
;;;
|
||||
|
||||
(defmacro while (cond . body)
|
||||
`(letrec ((continue (lambda () (or (not ,cond) (begin (begin ,@ body) (continue)))))
|
||||
(break (lambda val (apply throw 'break val))))
|
||||
(catch 'break
|
||||
(lambda () (continue))
|
||||
(lambda v (cadr v)))))
|
||||
|
||||
;;; {collect}
|
||||
;;;
|
||||
;;; Similar to `begin' but returns a list of the results of all constituent
|
||||
|
@ -2560,6 +2548,26 @@
|
|||
(else
|
||||
(error "define-syntax-macro can only be used at the top level")))))
|
||||
|
||||
;;; {While}
|
||||
;;;
|
||||
;;; with `continue' and `break'.
|
||||
;;;
|
||||
|
||||
;; The inner `do' loop avoids re-establishing a catch every iteration,
|
||||
;; that's only necessary if continue is actually used.
|
||||
;;
|
||||
(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 ()
|
||||
(,do ()
|
||||
((,not ,cond))
|
||||
,@body)
|
||||
#t)
|
||||
,(lambda (key arg) arg))))))
|
||||
|
||||
|
||||
;;; {Module System Macros}
|
||||
;;;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue