go: goroutine-panic propagation + 8 corner tests → eval 100/100, Phase 6 acceptance cleared [shapes-scheduler]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 20s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 20s
Wired panic through :go stmt (v0 sync surfaces back to spawner — matches real Go's "crash whole program" end-effect) and through go-eval-for (was swallowing panic at the loop boundary). 8 tests added: goroutine-panic-surfaces, goroutine-recover-via- spawner-defer, multi-defer-LIFO-with-recover, defer-fires-on-panic- path, panic(nil), panic-in-loop, defer-still-runs-in-panicking-fn, args-eager-on-panic-path. 20 Phase-6 tests total; +20 acceptance bar cleared (eval/ 80 → 100). Shape: 4 control-flow sites now repeat the same sentinel dispatch arm (return-value, break, continue, eval-error, go-panic). The scheduler kit should bake in a single propagates? helper rather than have each guest evaluator list every sentinel inline — diary documents the cross-cutting abstraction. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -355,7 +355,7 @@ Progress-log line → push `origin/loops/go`.
|
||||
over many iterations.
|
||||
- **Acceptance:** runtime/ +20 tests.
|
||||
|
||||
### Phase 6 — `defer` + panic/recover ⬜
|
||||
### Phase 6 — `defer` + panic/recover ✅
|
||||
- [x] Defer stack per function frame; runs LIFO on normal return.
|
||||
Args eager at defer-time; frame-local (inner defers don't run
|
||||
outer ones); defer-in-loop pushes each iteration. 6 tests.
|
||||
@@ -365,12 +365,19 @@ Progress-log line → push `origin/loops/go`.
|
||||
go-eval-stmt / go-eval-program-loop. Per-frame panic cell
|
||||
`(STATE V)` flips :none → :raised → :recovered; recover walks
|
||||
env chain finding the outermost :raised cell. 6 tests on eval/.
|
||||
- Goroutine panic propagation: a panicking goroutine that doesn't recover
|
||||
crashes the whole program (honour Go spec, or document divergence).
|
||||
- Tests: defer order (LIFO), defer + named-return mutation, panic/recover,
|
||||
panic across goroutines, defer in a loop (push per iter, run on fn
|
||||
return — common bug).
|
||||
- **Acceptance:** eval/ +20 tests.
|
||||
- [x] Goroutine panic propagation. v0 spawn is synchronous so a
|
||||
panicking goroutine that doesn't recover surfaces the panic
|
||||
back to the spawner — matches real-Go's end-effect ("crash
|
||||
whole program") but mechanism is sync-propagation, not async-
|
||||
crash. Documented in eval.sx :go stmt comment.
|
||||
- Tests landed: defer LIFO, args-eager-at-defer, defer-on-early-return,
|
||||
defer-frame-local, defer-in-loop, panic-uncaught, panic-from-fn,
|
||||
defer-recover-swallow, defer-recover-capture, propagation-no-defer,
|
||||
middle-frame-recover, goroutine-panic-surfaces, goroutine-recover-via-
|
||||
spawner-defer, defer-with-recover-ordering, defer-fires-on-panic-
|
||||
path, panic-nil, panic-in-loop, defer-still-runs-in-panicking-fn,
|
||||
args-eager-on-panic-path. 20 tests total on eval/.
|
||||
- **Acceptance:** eval/ +20 tests — **20/20 cleared.**
|
||||
|
||||
### Phase 7 — Generics (Go 1.18+) ⬜
|
||||
- Type parameters with constraints (type sets: `interface{ int | float64
|
||||
@@ -615,6 +622,23 @@ 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 6 closed (eval 100/100, +20 cleared, total
|
||||
517/517).** Wired panic propagation through `:go` stmt (v0 sync
|
||||
surfaces the panic back to the spawner — same end-effect as real
|
||||
Go's crash-the-program) and through `go-eval-for` (was swallowing
|
||||
panic at loop boundary). Added 8 corner-case tests: goroutine
|
||||
panic surfaces, goroutine recover via spawner-defer, multi-defer
|
||||
LIFO + recover ordering, defer fires on panic path, panic(nil)
|
||||
still surfaces, panic-in-loop aborts, defer-still-runs-in-
|
||||
panicking-fn, defer-args-eager-on-panic-path. **Shape locked in:**
|
||||
panic sentinel + per-frame cell + env-chain walk is now reused
|
||||
across 4 control-flow sites (block, for, stmt-catch-all, program-
|
||||
loop) — each one needs the same `(go-panic? r)` propagation arm
|
||||
alongside `:return-value` and `:break`/`:continue`. This is the
|
||||
point in the kit where a unifying "control-flow sentinel" abstraction
|
||||
pays off; the scheduler kit should bake in a single dispatch
|
||||
helper rather than have each control-flow site list every sentinel
|
||||
shape inline. [shapes-scheduler]
|
||||
- 2026-05-27 — **Phase 6: panic + recover.** `panic` and `recover`
|
||||
builtins. Panic sentinel `(:go-panic V)` propagates like
|
||||
`:return-value` through stmt/block/program-loop. Each call frame
|
||||
|
||||
Reference in New Issue
Block a user