From ad82847b7679bcdb57e3fe5c6ff719680f27ca46 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 09:46:34 +0300 Subject: [PATCH] =?UTF-8?q?ffi=20M5.A.next.1a:=20variadic=20heterogeneous?= =?UTF-8?q?=20type=20packs=20=E2=80=94=20parse=20lockin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First slice of the `..$args` (variadic heterogeneous type pack) feature. Locks in the current parser-rejection behavior so the next commit's parser extension shows up as a behavior shift. `examples/150-pack-parse.sx` declares `foo :: (..$args) -> s64`. Today's parser hits `..` where it expects a parameter name (parseParams in src/parser.zig:1558 only handles `..` inside the type position after a colon) and emits "expected parameter name". Expected output captures this rejection. Per FFI cadence rule, this is the "test fails today, passes after next commit's parser change" pair. Pack feature plan saved at ~/.claude/plans/lets-see-options-for-merry-dijkstra.md ("Variadic heterogeneous type packs" section). Motivates replacing the hand-rolled per-signature `Into(Block)` impls with one generic `impl Into(Block) for Closure(..$args) -> $R`; also unlocks compile-time arity/type errors for `print`/`format`. 191/191 example tests + `zig build test` green. --- current/CHECKPOINT-FFI.md | 33 ++++++++++++++++++++++++++++++ examples/150-pack-parse.sx | 22 ++++++++++++++++++++ tests/expected/150-pack-parse.exit | 1 + tests/expected/150-pack-parse.txt | 1 + 4 files changed, 57 insertions(+) create mode 100644 examples/150-pack-parse.sx create mode 100644 tests/expected/150-pack-parse.exit create mode 100644 tests/expected/150-pack-parse.txt diff --git a/current/CHECKPOINT-FFI.md b/current/CHECKPOINT-FFI.md index d2774d8..97540a1 100644 --- a/current/CHECKPOINT-FFI.md +++ b/current/CHECKPOINT-FFI.md @@ -6,6 +6,39 @@ add a test and make it pass — that's two commits). ## Last completed step +**M5.A.next.1a — variadic heterogeneous type packs: parse lockin** +(this commit). + +First slice of the `..$args` (variadic heterogeneous type pack) +feature per the plan saved at +`~/.claude/plans/lets-see-options-for-merry-dijkstra.md` (see the +"Variadic heterogeneous type packs" section). Locks in the +current parser-rejection behavior so the next commit's parser +extension shows up as a behavior shift. + +New: `examples/150-pack-parse.sx` declares +`foo :: (..$args) -> s64`. Today's parser hits `..` where it +expects a parameter name (after parsing the leading `dollar` +sigil that doesn't appear) and emits "expected parameter name" +at column 9 of line 15. Expected output captures this rejection. + +Per FFI cadence rule, this is a "test that fails today, passes +after the next commit's parser change" pair. The next commit +extends `parseParams()` (src/parser.zig:1558) to accept `..` at +the start of a parameter — currently the parser only handles `..` +inside the type position (after the colon). + +191 example tests + `zig build test` green. + +The pack feature itself lives in the FFI stream because its +primary motivation is replacing the hand-rolled per-signature +`Into(Block)` impls in `library/modules/std/objc_block.sx` with +one generic `impl Into(Block) for Closure(..$args) -> $R`. Payoff +extends beyond blocks — `print`/`format` get compile-time arity +and type-mismatch errors instead of `..Any` runtime tag dispatch. + +--- + **M1.2 A.0 — `objc_defined_class_cache` + scan-pass registration** (`61a2593`). diff --git a/examples/150-pack-parse.sx b/examples/150-pack-parse.sx new file mode 100644 index 0000000..23ef749 --- /dev/null +++ b/examples/150-pack-parse.sx @@ -0,0 +1,22 @@ +// Variadic heterogeneous type packs — `..$args` — parse lockin. +// +// First slice of the pack feature: the parser does not yet accept +// `..$args` (variadic-marker + comptime sigil + name, no type +// annotation). This test pins the current parse-rejection so the +// next commit's parser change is visible as a behavior shift. +// +// Expected next commit: parser accepts `..$args` and this test +// either flips to a successful parse (compile error from later +// passes that haven't been wired up yet) or is replaced by a +// positive test. + +#import "modules/std.sx"; + +foo :: (..$args) -> s64 { + return 0; +} + +main :: () -> s32 { + print("never reached\n"); + return 0; +} diff --git a/tests/expected/150-pack-parse.exit b/tests/expected/150-pack-parse.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/expected/150-pack-parse.exit @@ -0,0 +1 @@ +1 diff --git a/tests/expected/150-pack-parse.txt b/tests/expected/150-pack-parse.txt new file mode 100644 index 0000000..58d8286 --- /dev/null +++ b/tests/expected/150-pack-parse.txt @@ -0,0 +1 @@ +/Users/agra/projects/sx/examples/150-pack-parse.sx:15:9: error: expected parameter name