go: eval.sx + sched.sx — select stmt evaluation + 6 tests [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 28s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 28s
Phase 5 cont. Adds `select` statement evaluation:
go-select-try-case env COMM →
:not-ready / extended-env / :eval-error
go-select-pick env CASES DEFAULT-OR-NIL →
body-result / blocked-error
go-eval-select-stmt env STMT — public entry
Walks cases in declared order:
* :send case — always ready in v0 (unbounded buffer). Sends value
via go-chan-send! and returns env unchanged.
* :short-decl / :assign case — RHS expected to be unary <- on a
channel. Ready iff go-chan-len > 0; on success, recv-into-var
binds the new value in env.
* Bare recv (:app (:var "<-") [CHAN]) — ready iff len > 0; consumes
the value (discarded).
* :default — deferred until end of walk. Runs if no other case
ready. Absence + no ready case → (:eval-error :select-blocked-
no-default).
New `go-chan-len` accessor on the channel closure-bundle so the
select can peek without consuming.
Subtle bug fix: the :select stmt branch in go-eval-stmt was returning
the old env instead of the env returned by the case body. Assignments
inside select cases (`select { case <-ch: x = 1 ; default: x = 99 }`)
now stick.
Tests (6):
default fires when no case ready
recv case fires when ready
recv-into-var binds the value
send case always ready
picks first ready case (deterministic order in v0)
no default + nothing ready → blocked error
combined with goroutine fan-in
runtime 18/18, total 475/475.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -313,7 +313,13 @@ Progress-log line → push `origin/loops/go`.
|
||||
sched.sx header).
|
||||
- [ ] Real preemption (suspending sends on full buffer / recvs on empty).
|
||||
Requires reified execution state; deferred to Phase 5b.
|
||||
- [ ] `select { case ... }` multiplexing.
|
||||
- [x] `select { case ... }` multiplexing. v0 tries cases in declared
|
||||
order, picks first ready (sends always ready; recv ready iff
|
||||
channel has buffered values). Default runs if nothing else
|
||||
ready; no default and nothing ready → typed error.
|
||||
Recv-into-var (`case v := <-ch`) binds; recv-into-assign
|
||||
(`case v = <-ch`) re-binds. Real-Go random selection among
|
||||
ready cases deferred (v0 deterministic).
|
||||
- [ ] `range` over channels.
|
||||
- [ ] `time.After`-like timer channel.
|
||||
- **Independent implementation.** Do NOT use lib/guest/scheduler/ — that
|
||||
@@ -597,6 +603,18 @@ Minimal repro: see `lib/go/lex.sx#gl-oct-digit?` and `#gl-match-op`.
|
||||
|
||||
_Newest first. Append one dated entry per commit._
|
||||
|
||||
- 2026-05-27 — Phase 5 cont.: `select` statement evaluation. New
|
||||
`go-eval-select-stmt` + `go-select-pick` + `go-select-try-case`.
|
||||
Walks cases in declared order: send always ready in v0; recv ready
|
||||
iff `(go-chan-len ch) > 0` (new accessor added to sched.sx);
|
||||
recv-into-decl/assign binds the value into env. Default deferred
|
||||
until end of walk; if nothing ready and no default, returns
|
||||
`(:eval-error :select-blocked-no-default)`. Subtle bug fixed where
|
||||
`:select` stmt was returning the old env instead of the
|
||||
case-body-extended env — assignments inside cases now stick. +6
|
||||
tests, runtime 18/18, total 475/475. `[nothing]` — `:select-case`
|
||||
uniform shape was already chiselled into the sister-plan diary when
|
||||
the parser landed.
|
||||
- 2026-05-27 — **Phase 5 first slice.** `lib/go/sched.sx` lands with
|
||||
the v0 channel primitive: `go-make-chan` returns a closures-over-
|
||||
mutable-buf channel. Send appends, recv pops first, close flips a
|
||||
|
||||
Reference in New Issue
Block a user