go: defer + LIFO drain → eval 86/86, total 503/503 [shapes-scheduler]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 32s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 32s
Phase 6 first slice. New :defer stmt dispatch, go-eval-defer-stmt captures (callee, eagerly-evaluated args) onto a frame-local __go-defer-stack mutable list. go-eval-call installs the stack and drains LIFO before returning; go-eval-program does the same for the implicit main frame. New :quoted-value AST node lets defer re-invoke calls with the frozen arg values. 6 eval tests: single defer, multi-LIFO, args-eager-at-defer-time, fires-on-early-return, frame-local (no bleed to outer), defer-in-loop. Shape: defer is a per-frame cleanup queue (LIFO on frame exit) that the scheduler kit will reuse for panic-unwind + clean-exit + select- case-rollback paths. Distinct from the scheduler's ready-queue — diary updated to keep that distinction explicit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -356,9 +356,11 @@ Progress-log line → push `origin/loops/go`.
|
||||
- **Acceptance:** runtime/ +20 tests.
|
||||
|
||||
### Phase 6 — `defer` + panic/recover ⬜
|
||||
- Defer stack per function frame; runs LIFO on return (normal or panic).
|
||||
- `panic(v)` unwinds frames running deferreds; `recover()` inside a
|
||||
deferred fn captures the panic value and stops unwinding.
|
||||
- [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.
|
||||
- [ ] `panic(v)` unwinds frames running deferreds; `recover()` inside a
|
||||
deferred fn captures the panic value and stops unwinding.
|
||||
- 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,
|
||||
@@ -609,6 +611,21 @@ 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 first slice: defer + LIFO.** Added
|
||||
`go-eval-defer-stmt`, `go-run-defers!`, `go-run-defers-prefix!`,
|
||||
plus new `:quoted-value` AST node so deferred calls can be
|
||||
re-invoked with values captured at defer-time. Frame: `go-eval-call`
|
||||
installs a fresh `__go-defer-stack` (mutable list) in the call env,
|
||||
drains LIFO before returning. `go-eval-program` does the same for
|
||||
the implicit main frame. 6 tests on eval/: single defer,
|
||||
multi-defer LIFO, args eager at defer-time, defer fires on early
|
||||
return, frame-local stack (inner defers don't bleed to outer),
|
||||
defer-in-loop (all iterations defer to fn return). 503/503 total.
|
||||
**Shape:** SX assignment shadows rather than mutates, so the
|
||||
natural defer side-effect channel is the *channel buffer* — shared
|
||||
via closure identity. Drove the test design and matches the eventual
|
||||
panic/recover shape (errors will need to escape through a similar
|
||||
out-of-band mechanism, not through env mutation). [shapes-scheduler]
|
||||
- 2026-05-27 — **Phase 5 acceptance bar hit (40/40 runtime, 497/497
|
||||
total).** Added `after(d)` builtin (v0 timer stub: returns a channel
|
||||
already buffered with `:tick`) and 13 canonical-pattern tests:
|
||||
|
||||
Reference in New Issue
Block a user