go: eval.sx — maps + index-assign + 8 tests; word-count e2e [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 23s

Phase 4 cont. Adds map values and index-assignment for both
slices and maps.

Map representation: (list :go-map ENTRIES) where ENTRIES is an
association list of (key value) pairs.

  go-map-get / go-map-set    — primitive lookup + functional-update.
  go-slice-set               — same idea for slices.

go-extract-map-entries reads each :kv element in a composite literal,
evaluating key and value. go-eval-composite dispatches on :ty-map to
build the :go-map value.

go-eval-index extended: when OBJ is a :go-map, look up the key via
go-map-get. Missing keys return nil in v0 (Go's real semantics is
the zero value of the value type — needs runtime type info that this
slice doesn't yet thread through).

go-eval-builtin's len handles :go-map alongside :go-slice and strings.

go-eval-assign-pairs gets a new branch for (:index OBJ IDX) LHS:
  - var-rooted indexing only (a[i] = v / m["k"] = v)
  - slice → go-slice-set then rebind the var
  - map   → go-map-set then rebind the var

**Word-counter via map[string]int works end-to-end:**

  words := []string{"a", "b", "a", "c", "a"}
  counts := map[string]int{}
  for i := 0; i < len(words); i++ {
    counts[words[i]] = counts[words[i]] + 1
  }
  // counts["a"] == 3

Builds on:
  - map composite literal eval
  - map index lookup
  - map index-assign
  - slice indexing
  - len() builtin
  - nil + 1 = 1 (numeric-coercion of missing-key default)

eval 58/58, total 435/435.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 21:33:17 +00:00
parent ab04ec1cf7
commit 9ed58bd0fc
5 changed files with 163 additions and 11 deletions

View File

@@ -282,14 +282,18 @@ Progress-log line → push `origin/loops/go`.
indexes, `a[low:high]` slices, `len(a)` returns count, `append(a, ...)`
extends. The full triple with capacity-grow comes in a later
slice when programs need it.
- [ ] Maps: SX dict + key-type metadata.
- [x] Maps: v0 represents `m` as `(list :go-map ENTRIES)` where ENTRIES
is an assoc list. Composite-literal `map[K]V{...}`, `m[k]` lookup
(nil for missing key, until runtime type info enables zero-value),
`m[k] = v` index-assignment, `len(m)`. Index-assignment for slices
also lands here (`a[i] = v` rebuilds via `go-slice-set`).
- [ ] Structs: SX dict + type tag. Methods looked up via type's table.
- [/] Functions: top-level definition + call (incl. recursion via the
calling env). Lexical closures and multiple return values pending.
- [ ] Channels: stub (Phase 5 wires them).
- Tests: arithmetic, control flow, recursion, closures, slices, maps,
structs, methods, pointer semantics, multiple-return.
- **Acceptance:** eval/ suite at 80+ tests. Current: 50/50. No concurrency yet.
- **Acceptance:** eval/ suite at 80+ tests. Current: 58/58. No concurrency yet.
### Phase 5 — Goroutines + channels + select (`lib/go/sched.sx`) ⬜
- **Independent implementation.** Do NOT use lib/guest/scheduler/ — that
@@ -573,6 +577,16 @@ 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 4 cont.: maps + index-assignment. Maps represented
as `(list :go-map ENTRIES)` where ENTRIES is an assoc list. New
helpers `go-map-get` / `go-map-set` / `go-slice-set`. Composite-lit
for `map[K]V{...}` evaluates via `go-extract-map-entries`. `m[k]`
index lookup added to `go-eval-index`; `len(m)` extended in
`go-eval-builtin`. **Index-assignment** for both slices and maps
added to `go-eval-assign-pairs`: only var-rooted LHS for v0
(`a[0] = 99`, `m["k"] = v`), enough for canonical programs.
**Word-count via `counts[words[i]] = counts[words[i]] + 1` works
end-to-end.** +8 tests, eval 58/58, total 435/435. `[nothing]`.
- 2026-05-27 — Phase 4 cont.: slice values + index/slice exprs + the
`len`/`append`/`print` builtins. Slice representation is
`(list :go-slice ELEMS)` for v0 (deferring the full length/cap/