;;; generator.lsp — coroutine-style generators using full continuations
;;; Run: python3 lumbda.py --fast examples/generator.lsp

(define (make-generator thunk)
  (let ((k #f) (done #f))
    (lambda ()
      (if done 'done
          (call/cc
            (lambda (return)
              (if k
                  (k return)
                  (begin
                    (thunk (lambda (val)
                             (call/cc (lambda (next)
                                        (set! k next)
                                        (return val)))))
                    (set! done #t)
                    (return 'done)))))))))

;; Range generator
(define (range-gen start end)
  (make-generator
    (lambda (yield)
      (let loop ((i start))
        (when (< i end)
          (yield i)
          (loop (+ i 1)))))))

(define gen (range-gen 0 5))
(display "Generator: ")
(let loop ()
  (let ((v (gen)))
    (unless (eq? v 'done)
      (display v) (display " ")
      (loop))))
(newline)

;; Fibonacci generator (infinite)
(define (fib-gen)
  (make-generator
    (lambda (yield)
      (let loop ((a 0) (b 1))
        (yield a)
        (loop b (+ a b))))))

(define fibs (fib-gen))
(display "First 10 fibs: ")
(do ((i 0 (+ i 1))) ((= i 10))
  (display (fibs)) (display " "))
(newline)
