(module producer mzscheme
(require (lib "plt-match.ss"))
(require "maybe.ss")
(define (generate-producer body)
(define resume (box (make-nothing)))
(lambda (real-send)
(define send-to (box real-send))
(define (send value-to-send)
(set-box! send-to
(let/cc k
(begin
(set-box! resume (make-just k))
((unbox send-to) value-to-send)))))
(if (just? (unbox resume))
((just-value (unbox resume)) real-send)
(body send))))
(define (yield-producer i)
(let/cc k (i k)))
(define (yield-producer* i)
(let loop ([result (list)])
(match (yield-producer i)
[(struct nothing ())
result]
[(struct just (v))
(loop (list* v result))]))))