Make `in-producer' treat any number of values uniformly.
The previous version was broken in its inconsistent treatment of multiple values, which was motivated by an `in-generator' use case. (`in-generator' should be fixed too now.) The new version is much simpler since there's no need for three almost-exact copies of the same code.
This commit is contained in:
parent
609db13fa7
commit
710e59bf13
|
@ -1826,67 +1826,27 @@
|
||||||
(lambda () #'in-producer)
|
(lambda () #'in-producer)
|
||||||
(lambda (stx)
|
(lambda (stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[[(id) (_ producer stop more ...)]
|
;; cheap & simple stop-less and arg-less version
|
||||||
(with-syntax ([(more* ...) (generate-temporaries #'(more ...))])
|
[[(id ...) (_ producer)]
|
||||||
#'[(id)
|
#'[(id ...)
|
||||||
(:do-in
|
(:do-in ([(producer*) producer]) #t () #t ([(id ...) (producer*)])
|
||||||
;;outer bindings
|
#t #t ())]]
|
||||||
([(producer*) producer] [(more*) more] ...
|
;; full version
|
||||||
[(stop?) (let ([s stop])
|
|
||||||
(if (procedure? s) s (lambda (x) (eq? x s))))])
|
|
||||||
;; outer check
|
|
||||||
#t
|
|
||||||
;; loop bindings
|
|
||||||
()
|
|
||||||
;; pos check
|
|
||||||
#t
|
|
||||||
;; inner bindings
|
|
||||||
([(id) (producer* more* ...)])
|
|
||||||
;; pre guard
|
|
||||||
(not (stop? id))
|
|
||||||
;; post guard
|
|
||||||
#t
|
|
||||||
;; loop args
|
|
||||||
())])]
|
|
||||||
[[() (_ producer stop more ...)]
|
|
||||||
(with-syntax ([(more* ...) (generate-temporaries #'(more ...))])
|
|
||||||
#'[()
|
|
||||||
(:do-in
|
|
||||||
([(producer*) producer] [(more*) more] ...
|
|
||||||
[(stop?) (let ([s stop])
|
|
||||||
(if (procedure? s)
|
|
||||||
s
|
|
||||||
(lambda (args)
|
|
||||||
(and (not (null? args))
|
|
||||||
(eq? (car args) s)))))])
|
|
||||||
;; outer check
|
|
||||||
#t
|
|
||||||
;; loop bindings
|
|
||||||
()
|
|
||||||
;; pos check
|
|
||||||
#t
|
|
||||||
;; inner bindings
|
|
||||||
([(check) (call-with-values (lambda () (producer* more* ...))
|
|
||||||
(lambda vs vs))])
|
|
||||||
;; pre guard
|
|
||||||
(not (stop? check))
|
|
||||||
;; post guard
|
|
||||||
#t
|
|
||||||
;; loop args
|
|
||||||
())])]
|
|
||||||
;; multiple-values version
|
|
||||||
[[(id ...) (_ producer stop more ...)]
|
[[(id ...) (_ producer stop more ...)]
|
||||||
(with-syntax ([(more* ...) (generate-temporaries #'(more ...))])
|
(with-syntax ([(more* ...) (generate-temporaries #'(more ...))]
|
||||||
|
[single? (= 1 (length (syntax->list #'(id ...))))])
|
||||||
#'[(id ...)
|
#'[(id ...)
|
||||||
(:do-in
|
(:do-in
|
||||||
;; outer bindings
|
;; outer bindings
|
||||||
([(producer*) producer] [(more*) more] ...
|
([(producer*) producer]
|
||||||
[(stop?) (let ([s stop])
|
[(more*) more] ...
|
||||||
(if (procedure? s)
|
[(stop?)
|
||||||
s
|
(let ([s stop])
|
||||||
(error 'in-producer
|
(cond [(procedure? s) s]
|
||||||
|
['single? (lambda (x) (eq? x s))]
|
||||||
|
[else (error 'in-producer
|
||||||
"stop condition for ~a, got: ~e"
|
"stop condition for ~a, got: ~e"
|
||||||
"multiple values must be a predicate" s)))])
|
"multiple values must be a predicate" s)]))])
|
||||||
;; outer check
|
;; outer check
|
||||||
#t
|
#t
|
||||||
;; loop bindings
|
;; loop bindings
|
||||||
|
@ -1900,21 +1860,7 @@
|
||||||
;; post guard
|
;; post guard
|
||||||
#t
|
#t
|
||||||
;; loop args
|
;; loop args
|
||||||
())])]
|
())])])))
|
||||||
;; stop-less versions
|
|
||||||
[[(id) (_ producer)]
|
|
||||||
#'[(id)
|
|
||||||
(:do-in ([(producer*) producer]) #t () #t ([(id) (producer*)])
|
|
||||||
#t #t ())]]
|
|
||||||
[[() (_ producer)]
|
|
||||||
#'[()
|
|
||||||
(:do-in ([(producer*) producer]) #t () #t
|
|
||||||
([(check) (call-with-values producer* (lambda vs vs))])
|
|
||||||
#t #t ())]]
|
|
||||||
[[(id ...) (_ producer stop more ...)]
|
|
||||||
#'[(id ...)
|
|
||||||
(:do-in ([(producer*) producer]) #t () #t ([(id ...) (producer*)])
|
|
||||||
#t #t ())]])))
|
|
||||||
|
|
||||||
;; Some iterators that are implemented using `*in-producer' (note: do not use
|
;; Some iterators that are implemented using `*in-producer' (note: do not use
|
||||||
;; `in-producer', since in this module it is the procedure version).
|
;; `in-producer', since in this module it is the procedure version).
|
||||||
|
|
Loading…
Reference in New Issue
Block a user