spec: coroutine primitive — make-coroutine/resume/yield via perform/cek-step-loop

spec/coroutines.sx: define-library with make-coroutine, coroutine-resume,
coroutine-yield, coroutine?, coroutine-alive?. Built on existing perform/
cek-step-loop/cek-resume suspension machinery.

spec/tests/test-coroutines.sx: 17 tests — multi-yield, final return,
arg passthrough, alive? predicate, nested coroutines, recursive iteration,
independent coroutine interleaving.

Key: coroutine body must use (define loop (fn…)) not named let — named let
transpiles to cek_call→cek_run which rejects IO suspension. All 17/17 pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 16:15:48 +00:00
parent d84cf1882a
commit 21cb9cf51a
5 changed files with 267 additions and 1 deletions

View File

@@ -4431,6 +4431,8 @@
(val)
(if (thunk? val) (eval-expr-cek (thunk-expr val) (thunk-env val)) val)))
(define make-coroutine (fn (thunk) {:suspension nil :thunk thunk :type "coroutine" :state "ready"}))
(define
eval-expr
(fn (expr (env :as dict)) (cek-run (make-cek-state expr env (list)))))