feat: add algebraic enums (tagged unions) support

- Generate tagged unions in C backend for enums with data
- Add HirEnumVariant type with fields and namedFields
- Support _Tag and _Data field access in sema
- Support enum variant constants (Result_Ok, Result_Err)
- Support _Data union field access (Ok_0, Err_0, etc.)
- Add algebraic_enums.bux example

Example:
  enum Result {
      Ok(int),
      Err(String)
  }

  let r: Result = Result { tag: Result_Ok };
  r.data.Ok_0 = 42;
This commit is contained in:
2026-05-30 23:50:33 +03:00
parent b59e852330
commit cf074bec89
5 changed files with 181 additions and 22 deletions
+31 -3
View File
@@ -433,7 +433,7 @@ proc lowerModule*(module: Module, sema: Sema): HirModule =
var funcs: seq[HirFunc] = @[]
var externFuncs: seq[HirFunc] = @[]
var structs: seq[tuple[name: string, fields: seq[tuple[name: string, typ: Type]]]] = @[]
var enums: seq[tuple[name: string, variants: seq[string]]] = @[]
var enums: seq[tuple[name: string, variants: seq[HirEnumVariant]]] = @[]
var consts: seq[tuple[name: string, typ: Type, value: HirNode]] = @[]
for decl in module.items:
@@ -463,9 +463,37 @@ proc lowerModule*(module: Module, sema: Sema): HirModule =
fields.add((f.name, fType))
structs.add((decl.declStructName, fields))
of dkEnum:
var variants: seq[string] = @[]
var variants: seq[HirEnumVariant] = @[]
for v in decl.declEnumVariants:
variants.add(v.name)
var fields: seq[Type] = @[]
for f in v.fields:
var fType = makeUnknown()
if f != nil and f.kind == tekNamed:
case f.typeName
of "int", "int32": fType = makeInt()
of "int64": fType = makeInt64()
of "float64": fType = makeFloat64()
of "float32": fType = makeFloat32()
of "bool": fType = makeBool()
of "String", "str": fType = makeStr()
else: fType = makeNamed(f.typeName)
fields.add(fType)
var namedFields: seq[tuple[name: string, typ: Type]] = @[]
for nf in v.namedFields:
var fType = makeUnknown()
if nf.ftype != nil and nf.ftype.kind == tekNamed:
case nf.ftype.typeName
of "int", "int32": fType = makeInt()
of "int64": fType = makeInt64()
of "float64": fType = makeFloat64()
of "float32": fType = makeFloat32()
of "bool": fType = makeBool()
of "String", "str": fType = makeStr()
else: fType = makeNamed(nf.ftype.typeName)
namedFields.add((nf.name, fType))
variants.add(HirEnumVariant(name: v.name, fields: fields, namedFields: namedFields))
enums.add((decl.declEnumName, variants))
of dkConst:
let value = ctx.lowerExpr(decl.declConstValue)