Commit Graph

5 Commits

Author SHA1 Message Date
b693854dc4 go: sched.sx — channels + goroutines (v0 synchronous) + 12 tests; Phase 5 starts [shapes-scheduler]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 26s
Phase 5 (goroutines + channels) opens.

lib/go/sched.sx is the **independent implementation** referenced by
plans/lib-guest-scheduler.md — the first-consumer cut whose realised
shape will inform the eventual sister kit.

Channel representation:
  (list :go-chan SEND-FN RECV-FN CLOSED?-FN CLOSE!-FN)
Each closure shares a mutable `buf` (a list mutated via append! and
set!) and a `closed` flag. Channel identity is closure-instance —
two `make()` calls produce distinct values per Go spec § Channel types.

Primitive API in sched.sx:
  go-make-chan / go-chan? / go-chan-send! / go-chan-recv! /
  go-chan-closed? / go-chan-close!

Eval integration in eval.sx:
  * `make` and `close` added as builtins. v0 `make()` takes no args
    and returns an unbounded-buffer channel.
  * `:send` stmt → go-chan-send! on the channel.
  * Unary `<-` recv on channel values → go-chan-recv!. `:empty`
    sentinel converted to nil (stand-in for blocking semantics).
  * `:go expr` → synchronous eval (v0 limitation, see sched.sx
    header).

**v0 concurrency model — synchronous goroutines.** SX doesn't expose
first-class continuations to guest code, so v0 runs `go f()`
immediately and depends on the spawned goroutine running to
completion before the main goroutine receives. This is the right
semantics for the simple producer/consumer patterns covered here.
True preemption with blocking send/recv is Phase 5b — requires either
a CEK-style trampolining eval rewrite or kit-level continuation
support. Logged in sched.sx header and in the sister-plan diary.

Runtime suite (12 tests):
  * 6 direct API tests: identity, FIFO order, closed-flag
  * 6 source-level: make + send + recv, go ping-pong, close,
    multi-goroutine fan-in, worker-with-result

Sister-plan scheduler diary updated with the channel-as-closure-
bundle insight and the v0 synchronous-spawn caveat.

runtime 12/12, total 469/469.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 21:55:41 +00:00
ff9abe3ae6 go: eval.sx scaffold — literals + vars + binops + 25 tests; Phase 3 closed [nothing]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s
Phase 3 — bidirectional type checker — is fully ticked (short-decl
was already implemented). Phase 4 starts here.

lib/go/eval.sx single judgment:

  (go-eval ENV EXPR)  →  VALUE | (list :eval-error TAG ...)

ENV is an association list of (NAME VALUE) bindings — same shape as
the type checker's ctx, but the entries are runtime values. Values
are represented directly in SX: integers/floats as SX numbers,
strings as SX strings, booleans as true/false, nil as nil. Composite
values (slices/maps/structs/pointers/channels) arrive in later slices.

First-slice coverage:

  * go-env-empty / -lookup / -extend
  * Literal decoding:
      decimal (with underscores)
      hex (0x.. / 0X..)
      oct (0o.. / 0O..)
      bin (0b.. / 0B..)
    via go-hex-digit-value (explicit char equality — SX's nth on
    strings returns single-char strings, not numeric codes; the
    arithmetic-on-char-codes pattern from the OCaml kernel ports
    doesn't work here).
  * Identifier lookup with predeclared true / false / nil.
  * Binops: + - * / and the six comparison ops and && / ||.
  * Errors as (:eval-error TAG ...) sentinels.

Statements (block / return / short-decl / assign), control flow
(if / for), and function application / closures arrive in subsequent
slices.

eval 25/25, total 402/402.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 21:11:20 +00:00
6c3b7d1cf9 go: types.sx scaffold — synth/check skeleton + 12 tests; Phase 3 starts [shapes-static-types-bidirectional]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s
First slice of Phase 3 (bidirectional type checker).

lib/go/types.sx defines:
  * go-ctx-empty / go-ctx-extend / go-ctx-lookup — context as a value.
  * go-ctx-extend-field — consumes the (:field NAMES TYPE) shape from
    the parser, binding every name to the shared type. This is the
    cross-deliverable validation of the :field binding-group
    observation made during Phase 2 func decls: parser produces it,
    type checker consumes it, same shape end-to-end.
  * go-predeclared — true / false / nil baked in. Full list expanded
    on demand.
  * go-synth — currently handles variable lookup; literals / calls /
    binops follow in subsequent iterations.
  * go-check — v0 defers to synth + structural type equality. Untyped-
    constant flow and assignment-compatibility relations land later.
  * Type errors carry first-class tags (:unbound, :mismatch,
    :unsupported-synth) so consumers and tooling can dispatch.

Conformance.sh wired with new types suite. Scoreboard cleanup: drop
the "pending" types row since the suite is now real.

types 12/12, total 317/317. Phase 3 underway.

Sister-plan static-types-bidirectional diary updated with the
synth/check shape: judgment skeleton, error tag structure, and the
proposal that `check` should accept a `subtype?` predicate parameter
so each consumer (Go untyped-constants, TS variance, Rust lifetimes)
plugs in its own variance discipline without rewriting the judgment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 20:41:02 +00:00
976c6dd0ef go: parse.sx scaffold — primary expressions + Go precedence table + 17 tests [consumes-pratt consumes-ast]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 21s
Starts Phase 2. lib/go/parse.sx defines:
  * go-precedence-table — Go's five operator-precedence levels in the
    (NAME PREC ASSOC) entry shape from lib/guest/pratt.sx, ready for the
    binary-operator iteration to consume via pratt-op-lookup.
  * go-parse(src) — tokenises and parses ONE primary expression: int,
    float, imag, string, rune literals become (ast-literal VALUE);
    identifiers become (ast-var NAME). Built directly on lib/guest/ast.sx
    constructors — no intermediate AST shape.

Conformance.sh extended to load lib/guest/{ast,pratt}.sx and run the
new parse suite. Scoreboard cleanup: drop the "pending" parse row since
the suite is now real.

parse 17/17 (lex still 129/129). Total 146/146.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 07:33:31 +00:00
4fc73a97f4 go: lex.sx — keywords, ident/int/string/rune lits, comments, ops, ASI + 78 tests [consumes-lex]
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 23s
First Go-on-SX iteration. Tokenizer consumes lib/guest/lex.sx character-class
predicates. Automatic semicolon insertion per Go spec § Semicolons fires on
newline, EOF, and block comments containing a newline, after
ident/int/string/rune/{break,continue,fallthrough,return}/{++,--,),],}}.

Scoreboard + conformance.sh wired; lex 78/78. Plan Phase 1 sub-items
checked; floats/raw-strings/hex-ints still .

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 21:13:06 +00:00