feat: nested multi-field enum patterns (bootstrap + selfhost)

Multi-field variants use Enum_Variant_Payload nested types (avoids tag name clash).
Sema resolves data.Variant.Variant_i; enum field types fully resolve tuples.
Selfhost parses full type exprs in enum payloads; emit structs/tuples before enums.
Example: examples/nested_patterns.bux (Pair::Two, Box::Val((a,c)), Shape::Dot).
This commit is contained in:
2026-07-18 01:33:36 +03:00
parent f9185c96b2
commit 66f11d1869
12 changed files with 383 additions and 209 deletions
+27 -5
View File
@@ -148,6 +148,28 @@ func parserExpectIdentOrKeyword(p: *Parser, msg: String) -> LexToken {
// Type parsing
// ---------------------------------------------------------------------------
// C-friendly type name from a TypeExpr (named, tuple, pointer, …).
func parserTypeExprCName(te: *TypeExpr) -> String {
if te == null as *TypeExpr { return "int"; }
if te.kind == tekTuple {
if !String_Eq(te.typeName, "") { return te.typeName; }
return "Tuple_Empty";
}
if te.kind == tekPointer || te.kind == tekRef || te.kind == tekMutRef {
if te.pointerPointee != null as *TypeExpr {
return String_Concat(parserTypeExprCName(te.pointerPointee), "*");
}
return "void*";
}
if !String_Eq(te.typeName, "") {
if String_Eq(te.typeName, "String") || String_Eq(te.typeName, "str") {
return "const char*";
}
return te.typeName;
}
return "int";
}
func parserParseType(p: *Parser) -> *TypeExpr {
let line: uint32 = parserCurToken(p).line;
let col: uint32 = parserCurToken(p).column;
@@ -1953,14 +1975,14 @@ func parserParseEnumDecl(p: *Parser, isPublic: bool) -> *Decl {
v.fieldTypeName0 = "";
v.fieldTypeName1 = "";
// Optional (Type, Type) data
// Optional payload: (Type, Type) or (Tuple, ...) — full type expressions
if parserMatch(p, tkLParen) {
let t0: LexToken = parserExpect(p, tkIdent, "expected data type");
v.fieldTypeName0 = t0.text;
let te0: *TypeExpr = parserParseType(p);
v.fieldTypeName0 = parserTypeExprCName(te0);
v.fieldCount = 1;
if parserMatch(p, tkComma) {
let t1: LexToken = parserExpect(p, tkIdent, "expected data type");
v.fieldTypeName1 = t1.text;
let te1: *TypeExpr = parserParseType(p);
v.fieldTypeName1 = parserTypeExprCName(te1);
v.fieldCount = 2;
}
discard parserExpect(p, tkRParen, "expected ')'");