wcc: Hare-style enum [storage] { ... } type
`type Foo = enum [intT] { NAME [= expr], ... };`. Storage defaults
to i32; members auto-increment from 0 (or last+1) when `= expr` is
omitted, and value expressions can reference earlier siblings —
enough surface for io::mode-style flag enums (`RDWR = READ | WRITE`).
`Foo.MEMBER` folds to an N_INTLIT in the checker, typed as the
named enum. Binops on enum values yield the same enum (type_eq on
the named pointer), so `mode.R | mode.W` is a `mode`. Enum ↔ int
is a reinterpret-only `as` cast — same register, no tag wrap — so
`mode.RDWR as i32` and `1 as mode` both work without runtime ops.
`is`/`?`/`!` are still tagged-union-only. CSP runtime (chan/proc)
is unchanged; only the type-system slot is touched here.
This commit is contained in:
@@ -167,6 +167,11 @@ main(void)
|
||||
"fn ti(r: (i64 | i32)) bool = { return r is i64; };",
|
||||
"fn ai(r: (i64 | i32)) i64 = { return r as i64; };",
|
||||
"fn br(r: (i64 | str)) i32 = { if (r is i64) { return 1; }; return 0; };",
|
||||
|
||||
/* Hare-style enum types */
|
||||
"type color = enum { RED, GREEN, BLUE, };",
|
||||
"type mode = enum u8 { NONE = 0, READ = 1, WRITE = 2, RDWR = READ | WRITE };",
|
||||
"type whence = enum i32 { SET = 0, CUR, END };",
|
||||
};
|
||||
int n = sizeof parses / sizeof parses[0];
|
||||
for (int i = 0; i < n; i++) {
|
||||
|
||||
@@ -162,6 +162,23 @@ static const struct row rows[] = {
|
||||
"case str | f64 => return 9; case let b: bool => return 1; }; "
|
||||
"return 0; };",
|
||||
"case: f64 is not a variant" },
|
||||
|
||||
/* enum types */
|
||||
{ "type color = enum { RED, GREEN, BLUE };\n"
|
||||
"fn f() i32 = { return color.GREEN as i32; };", "ok" },
|
||||
{ "type mode = enum u8 { R = 1, W = 2, RW = R | W };\n"
|
||||
"fn f() i32 = { let m: mode = mode.RW; return m as i32; };", "ok" },
|
||||
{ "type mode = enum u8 { R = 1, W = 2 };\n"
|
||||
"fn f() i32 = { return (mode.R | mode.W) as i32; };", "ok" },
|
||||
{ "type c = enum { A, B };\n"
|
||||
"fn f() i32 = { return c.NOPE as i32; };",
|
||||
"no enum member 'NOPE'" },
|
||||
{ "type c = enum { A, A };\n"
|
||||
"fn f() i32 = { return c.A as i32; };",
|
||||
"duplicate enum member" },
|
||||
{ "type c = enum bool { A };\n"
|
||||
"fn f() i32 = { return c.A as i32; };",
|
||||
"enum storage type must be integer" },
|
||||
};
|
||||
|
||||
int
|
||||
|
||||
@@ -1086,6 +1086,20 @@ static const struct row rows[] = {
|
||||
" let e: str = r as str;\n"
|
||||
" return e.len: i32;\n"
|
||||
"};", 3 },
|
||||
/* enum: auto-increment, explicit value, sibling-ref */
|
||||
{ "type color = enum { RED, GREEN, BLUE };\n"
|
||||
"fn main() i32 = { return color.BLUE as i32; };", 2 },
|
||||
{ "type mode = enum u8 { R = 1, W = 2, RW = R | W };\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let m: mode = mode.RW;\n"
|
||||
" return m as i32;\n"
|
||||
"};", 3 },
|
||||
/* enum: bitwise op between two members yields the same enum type */
|
||||
{ "type mode = enum u8 { R = 1, W = 2 };\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let m: mode = mode.R | mode.W;\n"
|
||||
" return m as i32;\n"
|
||||
"};", 3 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user