feat(metatype): make_enum — general enum constructor over a []EnumVariant value
make_enum(name, variants: []EnumVariant) -> Type mints a nominal enum from a variant list passed as a VALUE, not a hardcoded literal — the open-ended form the channel-result constructors are special cases of. Pure sx over declare/define; no compiler machinery. Because variants is an ordinary comptime value, a non-generic builder can ASSEMBLE it in a local before minting. examples/0620: build_level fills a local array, then make_enum mints Level from it — exercising 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).
This commit is contained in:
41
examples/0620-comptime-metatype-make-enum.sx
Normal file
41
examples/0620-comptime-metatype-make-enum.sx
Normal file
@@ -0,0 +1,41 @@
|
||||
// make_enum — the GENERAL comptime enum constructor over declare/define: mint a
|
||||
// nominal enum from a `[]EnumVariant` VALUE, rather than a hardcoded literal
|
||||
// (the channel-result constructors hardcode theirs). The variant list is an
|
||||
// ordinary comptime value, so a builder ASSEMBLES it in a local before minting —
|
||||
// here `build_level` constructs `vs` (a local array, which could be filled
|
||||
// conditionally / in a loop), then mints `Level` from it.
|
||||
//
|
||||
// This exercises `define` decoding a value-arg SLICE (`decodeVariantElements`'s
|
||||
// slice-fat-pointer branch), as opposed to the inline `.[ … ]` array the
|
||||
// 0614–0618 examples pass directly into `.enum(...)`.
|
||||
#import "modules/std.sx";
|
||||
#import "modules/std/meta.sx";
|
||||
|
||||
build_level :: () -> Type {
|
||||
// The variant list lives in a local (not inlined into `define`): a non-
|
||||
// generic `() -> Type` builder has its whole body comptime-evaluated, so
|
||||
// `vs` is in scope when `make_enum` mints from it.
|
||||
vs := EnumVariant.[
|
||||
EnumVariant.{ name = "info", payload = void },
|
||||
EnumVariant.{ name = "warn", payload = void },
|
||||
EnumVariant.{ name = "fatal", payload = i64 }, // carries an exit code
|
||||
];
|
||||
return make_enum("Level", vs);
|
||||
}
|
||||
|
||||
Level :: build_level();
|
||||
|
||||
show :: (l: Level) {
|
||||
if l == {
|
||||
case .info: { print("info\n"); }
|
||||
case .warn: { print("warn\n"); }
|
||||
case .fatal: (c) { print("fatal code={}\n", c); }
|
||||
}
|
||||
}
|
||||
|
||||
main :: () -> i32 {
|
||||
show(.info);
|
||||
show(.warn);
|
||||
show(.fatal(70));
|
||||
return 0;
|
||||
}
|
||||
1
examples/expected/0620-comptime-metatype-make-enum.exit
Normal file
1
examples/expected/0620-comptime-metatype-make-enum.exit
Normal file
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
info
|
||||
warn
|
||||
fatal code=70
|
||||
Reference in New Issue
Block a user