From d83f5fa90d74ce53b0678f27b1ebad262f21fd55 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 17 Jun 2026 06:59:17 +0300 Subject: [PATCH] docs(metatype): struct widening done; tuple is the last shape --- current/CHECKPOINT-METATYPE.md | 48 ++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/current/CHECKPOINT-METATYPE.md b/current/CHECKPOINT-METATYPE.md index 92e9d087..e2899601 100644 --- a/current/CHECKPOINT-METATYPE.md +++ b/current/CHECKPOINT-METATYPE.md @@ -4,17 +4,26 @@ Companion to [PLAN-METATYPE.md](PLAN-METATYPE.md). Update after every step (one step at a time, per the cadence rule). ## Last completed step +**`type_info` / `define` widened to STRUCT types.** `TypeInfo` gained a +`` `struct(StructInfo) `` variant (`StructField{ name, type }`); the metatype +system now reflects AND constructs structs, not only enums. +- `meta.sx`: `StructField` / `StructInfo` / `` `struct `` TypeInfo variant. +- `interp.zig`: `reflectTypeInfo` builds `.struct` (tag 1) for a source + `@"struct"`; `define` dispatches on the TypeInfo tag (`defineType` → + `defineEnum` (0) / `defineStruct` (1)). `defineStruct` mirrors `defineEnum` + (duplicate-field-name check included) but completes the declare slot AS a + struct via `replaceKeyedInfo` — a KIND change re-keys the intern map, whereas + `updatePreservingKey` (the enum path) asserts the key is unchanged. +- `lower/call.zig`: the lower-time `type_info` guard now admits `@"struct"`. +- `examples/0622`: programmatic `Vec2` via `.struct(.{ fields = … })` + a + source-struct round-trip `define(declare("RowCopy"), type_info(Row))`. Enum + path (`0619`) unchanged. Suite green (683). Tuple is the last shape (Next step). + +## Earlier — make_enum **`make_enum(name, variants: []EnumVariant) -> Type`** — the general enum constructor over `declare`/`define`, minting a nominal enum from a variant list -passed as a VALUE (not a hardcoded literal). Pure sx in `meta.sx`, no compiler -machinery — the open-ended form the channel-result constructors are special cases -of. Because `variants` is an ordinary comptime value, a non-generic builder -assembles it in a local before minting; `examples/0620` (`build_level` fills a -local array → `make_enum` mints `Level`) exercises `define` decoding a value-arg -SLICE (`decodeVariantElements`' slice branch) vs. the inline `.[ … ]` array the -0614–0618 examples pass directly. No compiler change (locks existing capability). -Suite green (678). See "make_enum follow-ups" under Next step for the deferred -free-form-construction gaps (subslice/List at comptime, generic-type-fn locals). +passed as a VALUE. Pure sx in `meta.sx`. `examples/0620` assembles the list in a +local then mints, exercising `define`'s value-arg SLICE decode. ## Prior step **`type_info($T)` reflection — enum round-trip.** Reflect a type INTO a `TypeInfo` @@ -78,9 +87,10 @@ traversal)**; `field_type` reflection `0616`. Full suite green (674 examples). (reflection). No constructor-name knowledge anywhere in the compiler — every named constructor is sx. `declare(name)` carries the type name (compile-time string) for forward-type registration. -- `type_info($T)` reflects an `enum`/`tagged_union` INTO a `TypeInfo` value - (`call.zig` emits `callBuiltin(.type_info)`; `interp.zig:reflectTypeInfo` builds - the Value). Enum-only; struct/tuple widening pending. `examples/0619` round-trip. +- `type_info($T)` reflects an `enum`/`tagged_union`/`struct` INTO a `TypeInfo` + value (`call.zig` emits `callBuiltin(.type_info)`; `interp.zig:reflectTypeInfo` + builds the Value). `define` decodes `.enum` → tagged_union and `.struct` → + struct. Tuple widening pending. `examples/0619` (enum) / `0622` (struct) round-trip. ## Decision (kept) **Meta lives in `modules/std/meta.sx`, not the prelude.** Declaring its data types @@ -89,10 +99,10 @@ shifts every `.ir` snapshot. On-demand import keeps the prelude clean. ## Next step Pick any (independent): -- **Widen `type_info` / `TypeInfo` past `` `enum ``** — struct/tuple variants: - add `` .`struct ``/`` .`tuple `` to the `TypeInfo` enum in `meta.sx`, teach - `reflectTypeInfo` to build them, and teach `defineEnum` (→ a `defineType`) to - decode them. Round-trips a struct through `define` once it lands. +- **Widen `type_info` / `TypeInfo` to `` `tuple ``** — the last shape. `` `enum `` + and `` `struct `` now ship (`examples/0619`/`0622`). A tuple has positional + (unnamed) element types; needs a `TupleInfo { elements: []Type }` in `meta.sx`, + a `reflectTypeInfo` arm for `.tuple`, and a `defineTuple` (mints a `.tuple` type). - ~~**Validation + loud diagnostics**~~ — COMPLETE. duplicate variant names (`examples/1180`); `declare()` never `define()`d (`examples/1181`, was a `verifySizes` panic); by-value self-reference for both source (`1178`) and @@ -135,6 +145,12 @@ capabilities would let the variant list be built more freely; both error cleanly `examples/1178` locks it). ## Log +- **Struct widening done.** `TypeInfo` gained `` `struct(StructInfo) ``; `define` + dispatches on the tag (`defineType` → `defineEnum`/`defineStruct`), `reflectTypeInfo` + reflects a `@"struct"`, and the lower-time `type_info` guard admits structs. + `defineStruct` uses `replaceKeyedInfo` (kind change: tagged_union declare slot → + struct). `examples/0622` (programmatic build + source round-trip). Suite green + (683). Tuple is the last remaining shape. - **Validation story COMPLETE.** use-before-define needs no new check — subsumed by `checkInfiniteSize` (by-value cycles), declare-never-defined (unfinished slots), 0140 bails (bad payloads), and in-place slot mutation (forward refs);