; lib/fiber.sx — pure SX fiber library using call/cc
;
; A fiber is a cooperative coroutine with true suspension (no eager
; pre-execution). Each fiber is a dict {:resume fn :done? fn}.
;
; make-fiber body   → fiber dict
;   body = (fn (yield init-val) ...)  — body receives yield + first resume val
;   yield = (fn (val) ...)            — suspends fiber, returns val to resumer
;
; fiber-resume f v  → next yielded value, or nil when body returns
; fiber-done? f     → true after body has returned

(define make-fiber
  (fn (body)
    (let
      ((resume-k nil)
        (caller-k nil)
        (done false))
      (let
        ((yield
            (fn (val)
              (call/cc
                (fn (k)
                  (set! resume-k k)
                  (caller-k val))))))
        {:resume
         (fn (val)
           (if
             done
             nil
             (call/cc
               (fn (k)
                 (set! caller-k k)
                 (if
                   (nil? resume-k)
                   (begin
                     (body yield val)
                     (set! done true)
                     (k nil))
                   (resume-k val))))))
         :done? (fn () done)}))))

(define fiber-resume (fn (f v) ((get f :resume) v)))
(define fiber-done?  (fn (f) ((get f :done?))))
