From b693854dc4c956fe13906522fa71f9b2e54b4a06 Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 27 May 2026 21:55:41 +0000 Subject: [PATCH] =?UTF-8?q?go:=20sched.sx=20=E2=80=94=20channels=20+=20gor?= =?UTF-8?q?outines=20(v0=20synchronous)=20+=2012=20tests;=20Phase=205=20st?= =?UTF-8?q?arts=20[shapes-scheduler]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 5 (goroutines + channels) opens. lib/go/sched.sx is the **independent implementation** referenced by plans/lib-guest-scheduler.md — the first-consumer cut whose realised shape will inform the eventual sister kit. Channel representation: (list :go-chan SEND-FN RECV-FN CLOSED?-FN CLOSE!-FN) Each closure shares a mutable `buf` (a list mutated via append! and set!) and a `closed` flag. Channel identity is closure-instance — two `make()` calls produce distinct values per Go spec § Channel types. Primitive API in sched.sx: go-make-chan / go-chan? / go-chan-send! / go-chan-recv! / go-chan-closed? / go-chan-close! Eval integration in eval.sx: * `make` and `close` added as builtins. v0 `make()` takes no args and returns an unbounded-buffer channel. * `:send` stmt → go-chan-send! on the channel. * Unary `<-` recv on channel values → go-chan-recv!. `:empty` sentinel converted to nil (stand-in for blocking semantics). * `:go expr` → synchronous eval (v0 limitation, see sched.sx header). **v0 concurrency model — synchronous goroutines.** SX doesn't expose first-class continuations to guest code, so v0 runs `go f()` immediately and depends on the spawned goroutine running to completion before the main goroutine receives. This is the right semantics for the simple producer/consumer patterns covered here. True preemption with blocking send/recv is Phase 5b — requires either a CEK-style trampolining eval rewrite or kit-level continuation support. Logged in sched.sx header and in the sister-plan diary. Runtime suite (12 tests): * 6 direct API tests: identity, FIFO order, closed-flag * 6 source-level: make + send + recv, go ping-pong, close, multi-goroutine fan-in, worker-with-result Sister-plan scheduler diary updated with the channel-as-closure- bundle insight and the v0 synchronous-spawn caveat. runtime 12/12, total 469/469. Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/go/conformance.sh | 7 ++- lib/go/eval.sx | 44 +++++++++++++- lib/go/sched.sx | 64 +++++++++++++++++++++ lib/go/scoreboard.json | 6 +- lib/go/scoreboard.md | 4 +- lib/go/tests/runtime.sx | 108 +++++++++++++++++++++++++++++++++++ plans/go-on-sx.md | 27 +++++++++ plans/lib-guest-scheduler.md | 33 +++++++++++ 8 files changed, 282 insertions(+), 11 deletions(-) create mode 100644 lib/go/sched.sx create mode 100644 lib/go/tests/runtime.sx diff --git a/lib/go/conformance.sh b/lib/go/conformance.sh index b86930e3..23b1d8c8 100755 --- a/lib/go/conformance.sh +++ b/lib/go/conformance.sh @@ -31,6 +31,7 @@ SUITES=( "parse|go-parse-test-pass|go-parse-test-count" "types|go-types-test-pass|go-types-test-count" "eval|go-eval-test-pass|go-eval-test-count" + "runtime|go-rt-test-pass|go-rt-test-count" ) cat > "$TMPFILE" <<'EPOCHS' @@ -41,11 +42,13 @@ cat > "$TMPFILE" <<'EPOCHS' (load "lib/go/lex.sx") (load "lib/go/parse.sx") (load "lib/go/types.sx") +(load "lib/go/sched.sx") (load "lib/go/eval.sx") (load "lib/go/tests/lex.sx") (load "lib/go/tests/parse.sx") (load "lib/go/tests/types.sx") (load "lib/go/tests/eval.sx") +(load "lib/go/tests/runtime.sx") EPOCHS idx=0 @@ -110,7 +113,6 @@ cat > lib/go/scoreboard.json < lib/go/scoreboard.md <