svn: r15805
This commit is contained in:
Eli Barzilay 2009-08-26 21:05:04 +00:00
parent f61f933b8b
commit ab7caff9bc

View File

@ -7,40 +7,43 @@
(provide yield lambda-generator define-generator) (provide yield lambda-generator define-generator)
(define-syntax-parameter yield (lambda (stx) (define-syntax-parameter yield
(raise-syntax-error #f "yield is only bound inside a sequence generator"))) (lambda (stx)
(raise-syntax-error #f "yield is only bound inside a sequence generator")))
;; better version of shift/reset using continuation tags ;; better version of shift/reset using continuation tags also use a
;; also use a unique value to determine the end of the sequence instead of using #f ;; unique value to determine the end of the sequence instead of using #f
(define-syntax lambda-generator (define-syntax lambda-generator
(syntax-rules () (syntax-rules ()
[(_ (args ...) body0 bodies ...) [(_ (args ...) body0 bodies ...)
(lambda (args ...) (lambda (args ...)
(let* ([last (lambda () (void))] (let* ([last (lambda () (void))]
;; current is a function that invokes user code and produces values ;; current is a function that invokes user code and
[current (lambda () ;; produces values
;; a unique tag to jump to [current
(define tag (make-continuation-prompt-tag)) (lambda ()
;; give the value to the sequence ;; a unique tag to jump to
(define next (lambda (value) (define tag (make-continuation-prompt-tag))
(shift-at tag f (values value f)))) ;; give the value to the sequence
(syntax-parameterize ([yield (make-rename-transformer #'next)]) (define next (lambda (value)
(reset-at tag (shift-at tag f (values value f))))
body0 bodies ... (syntax-parameterize ([yield (make-rename-transformer #'next)])
(values #f last) (reset-at tag body0 bodies ... (values #f last))))]
)))] [seq
[seq (make-do-sequence (lambda () (make-do-sequence
(values (lambda ()
;; produce a value and a continuation (values
(lambda (i) (let-values ([(value next) (current)]) ;; produce a value and a continuation
;; set! is ugly but can we do better? (lambda (i)
(set! current next) (let-values ([(value next) (current)])
value)) ;; set! is ugly but can we do better?
(lambda (x) (add1 x)) (set! current next)
0 value))
(lambda (x) (not (eq? last current))) (lambda (x) (add1 x))
(lambda (v) (not (eq? last current))) 0
(lambda (x v) (not (eq? last current))))))]) (lambda (x) (not (eq? last current)))
(lambda (v) (not (eq? last current)))
(lambda (x v) (not (eq? last current))))))])
seq))])) seq))]))
(define-syntax define-generator (define-syntax define-generator
@ -51,6 +54,6 @@
#| #|
;; example ;; example
(define-generator (blah) (define-generator (blah)
(for ([x (in-range 0 10)]) (for ([x (in-range 0 10)])
(yield x))) (yield x)))
|# |#