From 0596376199c446b96afbbfc5e71d847dbabec001 Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 6 May 2026 16:58:18 +0000 Subject: [PATCH] =?UTF-8?q?tcl:=20Phase=202=20fiber.sx=20=E2=80=94=20make-?= =?UTF-8?q?fiber/fiber-resume/fiber-done=3F=20via=20call/cc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- lib/fiber.sx | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 lib/fiber.sx diff --git a/lib/fiber.sx b/lib/fiber.sx new file mode 100644 index 00000000..68390720 --- /dev/null +++ b/lib/fiber.sx @@ -0,0 +1,44 @@ +; 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?))))