Added stop-after and stop-before

These are equivalent to their racket for loop counterparts, and creates
an iterator that signals exhaustion befor or after yielding a value
where a predicate returns true. Not useful in non-nested loops, but
could be useful in inner loops where you want to exit to an outerloop
instead of :break-ing.

Also fixed some bugs in other generator clauses.
This commit is contained in:
Linus 2021-05-11 09:48:21 +02:00
parent 3908019bbc
commit a38170a25b
2 changed files with 82 additions and 46 deletions

View file

@ -244,7 +244,7 @@
(define-syntax in-generator
(syntax-rules ()
((_ :for ((var) (source)) next . rest)
((_ :for ((var) source) next . rest)
(next ((gen source))
((var (gen) (gen)))
((eof-object? var))
@ -307,7 +307,7 @@
(define-syntax in-hash
(syntax-rules ()
((in-hash :for ((bindings) (expr)) n . rest)
((in-hash :for ((bindings) expr) n . rest)
(n
()
((cursor (hash-map->list cons expr) (cdr cursor)))
@ -472,7 +472,7 @@
(define-syntax in-cycle
(syntax-rules ()
((_ ((id) (source)) n . rest)
((_ :for ((id) (source)) n . rest)
(n ((gen (generator-cycle source)))
()
()
@ -492,11 +492,42 @@
(cons index res)))))))
(define-syntax in-indexed
(syntax-rules ()
((_ ((binding) (source)) n . rest)
(syntax-rules (:for)
((_ :for ((binding) (source)) n . rest)
(n ((gen (generator-indexed source)))
((i (gen) (gen)))
((eof-object? i))
((binding i))
()
. rest))))
(define (stop-before-generator gen pred)
(lambda ()
(let ((v (gen)))
(if (pred v)
(eof-object)
v))))
(define (stop-after-generator gen pred)
(let ((done? #f))
(lambda ()
(if done?
(eof-object)
(let ((v (gen)))
(when (pred v)
(set! done? #t))
v)))))
(define-syntax stop-before
(syntax-rules (:for)
((_ :for ((binding) (source pred)) n . rest)
(in-generator :for ((binding) (stop-before-generator source pred)) n . rest))
((_ expr pred)
(stop-before-generator expr pred))))
(define-syntax stop-after
(syntax-rules (:for)
((_ :for ((binding) (source pred)) n . rest)
(in-generator :for ((binding) (stop-after-generator source pred)) n . rest))
((_ expr pred) (stop-after-generator expr pred))))