Files
sx/examples/comptime/0618-comptime-metatype-self-reference.sx
agra 66bdc70bf1 test: group examples into per-category folders
Move examples/*.sx and their expected/ snapshots into per-category
subfolders (examples/<category>/...). Folder = leading filename token,
with ffi-objc/ffi-jni kept whole; filenames are unchanged. The corpus
runner and LSP sweep now discover each category's expected/ dir, while
issues/ stays flat. Example 1058's repo-root-relative companion import
is made file-relative. Path strings embedded in 164 snapshots were
regenerated (path-only changes). Test-layout docs in CLAUDE.md updated.
2026-06-21 14:41:34 +03:00

51 lines
1.6 KiB
Plaintext

// Comptime type construction — SELF-REFERENCE: a recursive enum minted via
// declare/define. `declare("List")` names a forward type the compiler registers
// at compile time, so the body can reference it as `*List` (a pointer to a type
// that isn't defined yet — legal, since a pointer needs no layout). `define`
// then fills the body in place. A by-VALUE self-reference would be infinite-size
// and rejected; `*List` is the idiom.
//
// Builds a 3-node cons-list (c -> b -> a -> nil), matches through the pointer
// payload directly (`if p ==`) and via deref (`n.*`), and counts it recursively.
#import "modules/std.sx";
#import "modules/std/meta.sx";
make_list :: () -> Type {
h := declare("List");
return define(h, .enum(.{ variants = .[
EnumVariant.{ name = "cons", payload = *List }, // self-reference
EnumVariant.{ name = "nil", payload = void },
] }));
}
List :: make_list();
// Recursive traversal: `count` matches `n.*` (deref) into the same nominal type.
count :: (n: *List) -> i64 {
if n.* == {
case .cons: (next) { return 1 + count(next); }
case .nil: { return 0; }
}
return 0;
}
main :: () -> i32 {
a : List = .nil;
b : List = .cons(@a);
c : List = .cons(@b);
// Match the payload pointer directly (match auto-derefs).
if c == {
case .cons: (p) {
if p == {
case .cons: { print("c -> cons\n"); }
case .nil: { print("c -> nil\n"); }
}
}
case .nil: { print("c is nil\n"); }
}
print("len = {}\n", count(@c));
return 0;
}