go: parse.sx — go/defer/send/for-range + 9 tests [shapes-scheduler]
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
Adds Go's concurrency + iteration primitives to the statement parser:
go EXPR → (list :go EXPR)
defer EXPR → (list :defer EXPR)
ch <- v → (list :send CHAN VALUE)
for range COLL { ... } → (list :range-for nil nil nil COLL BODY)
for k := range C { ... } → (list :range-for :short-decl KEY nil COLL BODY)
for k, v := range C { } → (list :range-for :short-decl KEY VAL COLL BODY)
for k, v = range C { ... } → (list :range-for :assign KEY VAL COLL BODY)
gp-for-find-range pre-scans the for-header (to '{' or eof) looking
for the 'range' keyword; if present, dispatches to gp-parse-for-range
which handles the four range shapes. C-style and while-like and
infinite are now in gp-parse-for-c-style — gp-parse-for is just a
dispatcher.
Send statement detection lives in the LHS-list branch of gp-parse-stmt:
after parsing a single LHS expression, '<-' triggers (:send LHS RHS).
Channel-recv (`<-ch`) was already parsed as unary `<-` in the expression
layer, so both directions cover.
This is the **chiselling-relevant iteration** for the scheduler sister
kit: the AST shapes Go-on-SX will eventually feed into the kit's
scheduler primitives (sched-spawn, sched-defer, chan-op) have landed.
Sister-plan diary updated with three design insights:
* :go / :defer both wrap a single expr — kit's sched-spawn should
accept a thunk uniformly across Erlang's spawn(M,F,A) and Go's
go fn().
* :send carries CHAN+VALUE symmetrically with the unary <- recv —
both reduce to (chan-op direction chan value) in the kit.
* `for v := range ch` uses the same :range-for shape as range-over-
slice; the scheduler kit's range dispatch is where chan-recv ⇄
iteration polymorphism lives.
parse 161/161, total 290/290.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -231,5 +231,37 @@ real result.
|
||||
|
||||
_Newest first. Append one dated entry per milestone landed._
|
||||
|
||||
- 2026-05-27 — From Go-on-SX Phase 2 (parser side, ahead of scheduler
|
||||
implementation): the **parsed AST shapes** for Go's concurrency
|
||||
primitives have landed and are worth recording before Phase 5 builds
|
||||
the scheduler.
|
||||
|
||||
```
|
||||
go EXPR → (list :go EXPR)
|
||||
defer EXPR → (list :defer EXPR)
|
||||
ch <- v → (list :send CHAN VALUE)
|
||||
<-ch → (list :app (:var "<-") [CHAN]) ; unary recv
|
||||
for range COLL { } → (list :range-for nil nil nil COLL BODY)
|
||||
for k, v := range C → (list :range-for :short-decl KEY VAL COLL BODY)
|
||||
```
|
||||
|
||||
**Design insight for the kit**: the `:go` and `:defer` shapes are
|
||||
pleasingly minimal — both wrap a single expression. Erlang's
|
||||
`spawn(Mod, Fun, Args)` will produce something more elaborate; the
|
||||
scheduler kit primitive `(sched-spawn task)` should accept a thunk so
|
||||
both languages reduce to a uniform spawn API.
|
||||
|
||||
The `:send` shape carries CHAN + VALUE — symmetric with channel-recv
|
||||
as the unary `<-` form. Once the scheduler has channel primitives,
|
||||
both shapes thunk-down to a single `(chan-op direction chan value)`
|
||||
abstraction.
|
||||
|
||||
Range over channels (`for v := range ch`) is currently parsed as
|
||||
range-for with `coll = ch`; the scheduler kit will dispatch on the
|
||||
type of `coll` at execution time (channels yield via receive,
|
||||
collections via iteration). This dispatch is the right place for the
|
||||
scheduler kit to express the channel-receive ⇄ iteration polymorphism.
|
||||
Source: Go-on-SX commit `parse.sx — go/defer/send/range`.
|
||||
|
||||
- 2026-05-26 — Plan drafted. Phase 0 unstarted. Awaiting Go-on-SX to begin
|
||||
Phase 1.
|
||||
|
||||
Reference in New Issue
Block a user