fix: algebraic enum C backend and sema field type resolution
- Fix sema.nim: use objType.name instead of obj.name for algebraic enum tag/data field types (was generating _Tag instead of EnumName_Tag) - Fix c_backend.nim: emit enum definitions before struct definitions to allow structs to reference algebraic enum types
This commit is contained in:
@@ -616,14 +616,22 @@ proc emitModule*(be: var CBackend, module: HirModule): string =
|
|||||||
be.emitLine(&"/* const {c.name} (complex expression) */")
|
be.emitLine(&"/* const {c.name} (complex expression) */")
|
||||||
be.emitLine("")
|
be.emitLine("")
|
||||||
|
|
||||||
|
# Forward declarations for all structs
|
||||||
|
for s in module.structs:
|
||||||
|
be.emitLine(&"typedef struct {s.name} {s.name};")
|
||||||
|
if module.structs.len > 0:
|
||||||
|
be.emitLine("")
|
||||||
|
|
||||||
|
# Enum definitions (must come before structs that reference them)
|
||||||
|
for e in module.enums:
|
||||||
|
be.emitEnum(e.name, e.variants)
|
||||||
|
if module.enums.len > 0:
|
||||||
|
be.emitLine("")
|
||||||
|
|
||||||
# Struct definitions
|
# Struct definitions
|
||||||
for s in module.structs:
|
for s in module.structs:
|
||||||
be.emitStruct(s.name, s.fields)
|
be.emitStruct(s.name, s.fields)
|
||||||
|
|
||||||
# Enum definitions
|
|
||||||
for e in module.enums:
|
|
||||||
be.emitEnum(e.name, e.variants)
|
|
||||||
|
|
||||||
# Slice fat-pointer typedefs
|
# Slice fat-pointer typedefs
|
||||||
if sliceTypes.len > 0:
|
if sliceTypes.len > 0:
|
||||||
be.emitLine("/* Slice types */")
|
be.emitLine("/* Slice types */")
|
||||||
|
|||||||
@@ -1086,11 +1086,11 @@ proc checkExpr(sema: var Sema, expr: Expr, scope: Scope): Type =
|
|||||||
elif sym.decl.kind == dkEnum:
|
elif sym.decl.kind == dkEnum:
|
||||||
# Algebraic enum fields
|
# Algebraic enum fields
|
||||||
if expr.exprFieldName == "tag":
|
if expr.exprFieldName == "tag":
|
||||||
return makeNamed(obj.name & "_Tag")
|
return makeNamed(objType.name & "_Tag")
|
||||||
elif expr.exprFieldName == "data":
|
elif expr.exprFieldName == "data":
|
||||||
return makeNamed(obj.name & "_Data")
|
return makeNamed(objType.name & "_Data")
|
||||||
else:
|
else:
|
||||||
sema.emitError(expr.loc, &"enum '{obj.name}' has no field '{expr.exprFieldName}'")
|
sema.emitError(expr.loc, &"enum '{objType.name}' has no field '{expr.exprFieldName}'")
|
||||||
elif sym.decl.kind == dkUnion:
|
elif sym.decl.kind == dkUnion:
|
||||||
# Union fields
|
# Union fields
|
||||||
for f in sym.decl.declUnionFields:
|
for f in sym.decl.declUnionFields:
|
||||||
|
|||||||
Reference in New Issue
Block a user