(define-macro (store/cc! name . body)
(let ((k (gensym)))
`(call-with-current-continuation
(lambda (,k) (set! ,name ,k) ,@body))))
(define-macro (let/ name value . args)
`(match-let ((,name ,value)) ,@args))
(define (generator routine)
(let/ (current status exit next) (list routine 'suspended #f #f)
(match-lambda*
(() (if (eq? status 'dead)
(error 'dead-generator)
(let/ continuation-and-value
(store/cc! exit
(let/ yield
(lambda (value)
(store/cc! next
(exit (cons next value))))
(current yield) (set! status 'dead)
(error 'dead-generator)))
(if (pair? continuation-and-value)
(begin (set! current (car continuation-and-value))
(cdr continuation-and-value))
continuation-and-value))))
(('status?) status)
(('dead?) (eq? status 'dead))
(('alive?) (not (eq? status 'dead)))
(('kill!) (set! status 'dead)))))
(define test
(generator (lambda (yield)
(yield "HELLO!")
(yield "WORLD!"))))
(test 'status?) (test 'dead?) (test 'alive?) (test) (test) (test) (test 'status?) (test 'dead?)
(define (list->iterator list)
(generator (lambda (yield)
(for-each yield list))))
(define (iterator-empty? iterator)
(iterator 'dead?))
(define my-iterator
(list->iterator (list 1 2 3)))
(my-iterator) (my-iterator) (my-iterator) (iterator-empty? my-iterator)