From b78e06a772607862c689f2d880c2ab19379a370c Mon Sep 17 00:00:00 2001 From: giles Date: Sun, 26 Apr 2026 16:43:02 +0000 Subject: [PATCH] =?UTF-8?q?js:=20coroutine=20JS=20step=20=E2=80=94=20pre-l?= =?UTF-8?q?oad=20spec/coroutines.sx=20in=20run=5Ftests.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All CEK primitives (cek-step-loop/cek-resume/make-cek-state/cek-suspended?/ cek-io-request/cek-terminal?/cek-value) were already registered in sx-browser.js. Root cause of test failure: (import (sx coroutines)) creates an io-suspended state when the library isn't pre-loaded; overridden cekRun throws on suspension. Fix: pre-load spec/signals.sx + spec/coroutines.sx before test files run. 17/17 coroutine tests pass in JS. 1965/2500 total (+25 vs 1940 baseline), zero new failures. Co-Authored-By: Claude Sonnet 4.6 --- hosts/javascript/run_tests.js | 14 ++++++++++++++ plans/agent-briefings/primitives-loop.md | 6 +++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/hosts/javascript/run_tests.js b/hosts/javascript/run_tests.js index 08a64f48..eb580306 100644 --- a/hosts/javascript/run_tests.js +++ b/hosts/javascript/run_tests.js @@ -343,6 +343,20 @@ if (fs.existsSync(swapPath)) { } } +// Load spec library files (define-library modules imported by tests) +for (const libFile of ["signals.sx", "coroutines.sx"]) { + const libPath = path.join(projectDir, "spec", libFile); + if (fs.existsSync(libPath)) { + const libSrc = fs.readFileSync(libPath, "utf8"); + const libExprs = Sx.parse(libSrc); + for (const expr of libExprs) { + try { Sx.eval(expr, env); } catch (e) { + console.error(`Error loading spec/${libFile}: ${e.message}`); + } + } + } +} + // Load tw system (needed by spec/tests/test-tw.sx) const twDir = path.join(projectDir, "shared", "sx", "templates"); for (const twFile of ["tw-type.sx", "tw-layout.sx", "tw.sx"]) { diff --git a/plans/agent-briefings/primitives-loop.md b/plans/agent-briefings/primitives-loop.md index ed23dc4c..7f832c4b 100644 --- a/plans/agent-briefings/primitives-loop.md +++ b/plans/agent-briefings/primitives-loop.md @@ -133,7 +133,10 @@ using call/cc+perform/resume. - [x] OCaml: implement coroutine type; wire resume/yield through CEK suspension. No new native type needed — dict-based coroutine identity + existing cek-step-loop/ cek-resume/perform primitives in run_tests.ml ARE the OCaml implementation. 17/17 pass. -- [ ] JS bootstrapper: update. +- [x] JS bootstrapper: update. + All CEK primitives already in sx-browser.js. Fix: pre-load spec/coroutines.sx + + spec/signals.sx in run_tests.js so (import (sx coroutines)) resolves without suspension. + 17/17 pass in JS. 1965/2500 (+25 vs 1940 baseline). Zero new failures. - [ ] Tests: 25+ tests — multi-yield, final return, arg passthrough, alive? predicate, nested coroutines, "final return vs yield" distinction (the Lua gotcha). - [ ] Commit: `spec: coroutine primitive (make-coroutine/resume/yield)` @@ -668,6 +671,7 @@ Brief each language's loop agent (or do inline) after rebasing their branch onto _Newest first._ +- 2026-04-26: Phase 4 JS step done — all CEK primitives already in sx-browser.js; fix was pre-loading spec/coroutines.sx+spec/signals.sx in run_tests.js so (import (sx coroutines)) resolves synchronously. 17/17 coroutine tests pass JS. 1965/2500 total (+25), zero new failures. - 2026-04-26: Phase 4 OCaml step done — no native SxCoroutine type needed; existing cek-step-loop/cek-resume/perform/make-cek-state primitives in run_tests.ml fully support the spec/coroutines.sx library. 284/284 pass (coroutines+vectors+numeric-tower+dynamic-wind), zero regressions. - 2026-04-26: Phase 4 Spec step done — spec/coroutines.sx define-library with make-coroutine/coroutine-resume/coroutine-yield/coroutine?/coroutine-alive?; make-coroutine stub in evaluator.sx; 17/17 coroutine tests pass (OCaml). Key insight: coroutine body must use (define loop (fn...)) + (loop 0) not named let — named let uses cek_call→cek_run which errors on IO suspension. - 2026-04-26: Phase 3 complete — OCaml+JS done. CallccContinuation gains winders-depth int; make_callcc_continuation/callcc_continuation_winders_len wired; wind-after/wind-return CekFrame fields fixed (cf_f=after-thunk, cf_extra=winders-len, cf_name=body-result); get_val + transpiler.sx updated. 8/8 dynamic-wind tests pass on OCaml; 235/235 (callcc+guard+do+r7rs) zero regressions. Committed 6602ec8c.