js: coroutine JS step — pre-load spec/coroutines.sx in run_tests.js

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 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 16:43:02 +00:00
parent 9eb12c66fd
commit b78e06a772
2 changed files with 19 additions and 1 deletions

View File

@@ -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) // Load tw system (needed by spec/tests/test-tw.sx)
const twDir = path.join(projectDir, "shared", "sx", "templates"); const twDir = path.join(projectDir, "shared", "sx", "templates");
for (const twFile of ["tw-type.sx", "tw-layout.sx", "tw.sx"]) { for (const twFile of ["tw-type.sx", "tw-layout.sx", "tw.sx"]) {

View File

@@ -133,7 +133,10 @@ using call/cc+perform/resume.
- [x] OCaml: implement coroutine type; wire resume/yield through CEK suspension. - [x] OCaml: implement coroutine type; wire resume/yield through CEK suspension.
No new native type needed — dict-based coroutine identity + existing cek-step-loop/ 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. 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, - [ ] Tests: 25+ tests — multi-yield, final return, arg passthrough, alive? predicate,
nested coroutines, "final return vs yield" distinction (the Lua gotcha). nested coroutines, "final return vs yield" distinction (the Lua gotcha).
- [ ] Commit: `spec: coroutine primitive (make-coroutine/resume/yield)` - [ ] 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._ _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 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 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. - 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.