Files
sx/examples/0620-comptime-metatype-make-enum.sx
agra 2250652ba5 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).
2026-06-17 04:55:48 +03:00

42 lines
1.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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
// 06140618 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;
}