From 21626628cdb42616f3ed0f21b7b9809f5bb66a33 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 19:20:54 +0300 Subject: [PATCH] ffi M5.A.next.4A.bare.5: end-to-end smoke for bare $args + dynamic reflection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 4A final-slice's smoke test. Exercises the FULL surface step 5's generic Into(Block) impl needs to operate: 1. A pack-fn binds $args (whole pack as []Type). 2. The body walks `list := $args` at INTERP time. 3. Per position, calls `type_name(list[i])` — the dynamic form that emits `callBuiltin(.type_name, ...)` at lower time, dispatched at interp time to read the runtime Value.type_tag and return the concrete type name. `examples/172-pack-builder-smoke.sx` exercises four call shapes via #run: describe() → [] describe(42) → [s64] describe(42, "hi") → [s64, string] describe(true, 3.14, "x", 99) → [bool, f64, string, s64] Each call shape builds its own [N x Any] slice of .type_tag values at lowering time, the interp walks the slice, and the per-element type names come out kind-honestly. 212/212 example tests + zig build test green. --- examples/172-pack-builder-smoke.sx | 48 ++++++++++++++++++++++ tests/expected/172-pack-builder-smoke.exit | 1 + tests/expected/172-pack-builder-smoke.txt | 6 +++ 3 files changed, 55 insertions(+) create mode 100644 examples/172-pack-builder-smoke.sx create mode 100644 tests/expected/172-pack-builder-smoke.exit create mode 100644 tests/expected/172-pack-builder-smoke.txt diff --git a/examples/172-pack-builder-smoke.sx b/examples/172-pack-builder-smoke.sx new file mode 100644 index 0000000..66ded48 --- /dev/null +++ b/examples/172-pack-builder-smoke.sx @@ -0,0 +1,48 @@ +// Variadic heterogeneous type packs — step 4A end-to-end +// smoke. Exercises the FULL chain step 5's generic +// `Into(Block)` impl needs: +// +// 1. A pack-fn that passes its bound `$args` to a builder +// via `#run` / `#insert` (here `#run` for simplicity). +// 2. The builder receives a `[]Type` slice and walks it, +// calling `type_name(list[i])` per position. +// 3. `type_name(list[i])` is the DYNAMIC form — the index_expr +// argument can't be statically resolved at lower time, so +// the lowering emits a `callBuiltin(.type_name, ...)` that +// the interp's arm handles by reading the runtime +// `Value.type_tag(TypeId)` and returning the per-position +// name. +// +// The smoke demonstrates that step 4's full surface — bare +// `$args` (whole pack as []Type) + dynamic reflection +// intrinsics + per-position type discovery at interp time — +// hangs together end-to-end. This is the foundation step 5's +// builder-driven generic Into(Block) impl rests on. + +#import "modules/std.sx"; +#import "modules/compiler.sx"; + +// Generic "describe pack" builder. Receives the pack as +// []Type, returns a joined string with each type's name. +describe :: (..$args) -> string { + list := $args; + s := "["; + i : s64 = 0; + while i < list.len { + if i > 0 { s = concat(s, ", "); } + s = concat(s, type_name(list[i])); + i = i + 1; + } + s = concat(s, "]"); + return s; +} + +run_all :: () { + print("{}\n", describe()); // [] + print("{}\n", describe(42)); // [s64] + print("{}\n", describe(42, "hi")); // [s64, string] + print("{}\n", describe(true, 3.14, "x", 99)); // [bool, f64, string, s64] +} +#run run_all(); + +main :: () { print("rt\n"); } diff --git a/tests/expected/172-pack-builder-smoke.exit b/tests/expected/172-pack-builder-smoke.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/tests/expected/172-pack-builder-smoke.exit @@ -0,0 +1 @@ +0 diff --git a/tests/expected/172-pack-builder-smoke.txt b/tests/expected/172-pack-builder-smoke.txt new file mode 100644 index 0000000..f8d3158 --- /dev/null +++ b/tests/expected/172-pack-builder-smoke.txt @@ -0,0 +1,6 @@ +[] +[s64] +[s64, string] +[bool, f64, string, s64] +--- build done --- +rt