feat: keyword-as-identifier, hFieldPtr/hSizeOf handling, skip forward decl bodies
This commit is contained in:
@@ -259,6 +259,26 @@ func CBE_EmitExpr(cbe: *CEmitter, node: *HirNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Field access: obj.field — emit as obj->field (since most are pointers)
|
||||
if kind == hFieldPtr {
|
||||
CBE_EmitExpr(cbe, node.child1);
|
||||
StringBuilder_Append(&cbe.sb, "->");
|
||||
StringBuilder_Append(&cbe.sb, node.strValue);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sizeof: sizeof(Type) — emit as sizeof(Type)
|
||||
if kind == hSizeOf {
|
||||
StringBuilder_Append(&cbe.sb, "sizeof(");
|
||||
if !String_Eq(node.typeName, "") {
|
||||
StringBuilder_Append(&cbe.sb, node.typeName);
|
||||
} else {
|
||||
StringBuilder_Append(&cbe.sb, "int");
|
||||
}
|
||||
StringBuilder_Append(&cbe.sb, ")");
|
||||
return;
|
||||
}
|
||||
|
||||
// Index: arr[idx] — emit as arr[idx]
|
||||
if kind == hIndexPtr {
|
||||
CBE_EmitExpr(cbe, node.child1);
|
||||
@@ -512,12 +532,16 @@ func CBackend_Generate(mod: *HirModule) -> String {
|
||||
i = 0;
|
||||
while i < mod.funcCount {
|
||||
if String_Eq(mod.funcs[i].name, "Main") { hasMain = true; }
|
||||
// Skip forward declarations (functions without body)
|
||||
let body: *HirNode = mod.funcs[i].body;
|
||||
if body == null as *HirNode {
|
||||
i = i + 1;
|
||||
continue;
|
||||
}
|
||||
CBE_EmitFuncDecl(cbe, &mod.funcs[i]);
|
||||
StringBuilder_Append(&cbe.sb, " {\n");
|
||||
// Body
|
||||
var hasReturn: bool = false;
|
||||
let body: *HirNode = mod.funcs[i].body;
|
||||
if body != null as *HirNode {
|
||||
cbe.indent = 1;
|
||||
CBE_EmitExpr(cbe, body);
|
||||
cbe.indent = 0;
|
||||
@@ -527,7 +551,6 @@ func CBackend_Generate(mod: *HirModule) -> String {
|
||||
if stmt.kind == hReturn { hasReturn = true; }
|
||||
stmt = stmt.child3;
|
||||
}
|
||||
}
|
||||
// Add default return 0 only if function returns int and has no explicit return
|
||||
if String_Eq(mod.funcs[i].retTypeName, "int") && !hasReturn {
|
||||
StringBuilder_Append(&cbe.sb, " return 0;\n");
|
||||
|
||||
@@ -105,6 +105,15 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode {
|
||||
return n;
|
||||
}
|
||||
|
||||
// Sizeof
|
||||
if kind == ekSizeOf {
|
||||
n.kind = hSizeOf;
|
||||
if expr.refType != null as *TypeExpr {
|
||||
n.typeName = expr.refType.typeName;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// Field access
|
||||
if kind == ekField {
|
||||
n.kind = hFieldPtr;
|
||||
|
||||
+26
-3
@@ -259,6 +259,26 @@ func CBE_EmitExpr(cbe: *CEmitter, node: *HirNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Field access: obj.field — emit as obj->field (since most are pointers)
|
||||
if kind == hFieldPtr {
|
||||
CBE_EmitExpr(cbe, node.child1);
|
||||
StringBuilder_Append(&cbe.sb, "->");
|
||||
StringBuilder_Append(&cbe.sb, node.strValue);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sizeof: sizeof(Type) — emit as sizeof(Type)
|
||||
if kind == hSizeOf {
|
||||
StringBuilder_Append(&cbe.sb, "sizeof(");
|
||||
if !String_Eq(node.typeName, "") {
|
||||
StringBuilder_Append(&cbe.sb, node.typeName);
|
||||
} else {
|
||||
StringBuilder_Append(&cbe.sb, "int");
|
||||
}
|
||||
StringBuilder_Append(&cbe.sb, ")");
|
||||
return;
|
||||
}
|
||||
|
||||
// Index: arr[idx] — emit as arr[idx]
|
||||
if kind == hIndexPtr {
|
||||
CBE_EmitExpr(cbe, node.child1);
|
||||
@@ -512,12 +532,16 @@ func CBackend_Generate(mod: *HirModule) -> String {
|
||||
i = 0;
|
||||
while i < mod.funcCount {
|
||||
if String_Eq(mod.funcs[i].name, "Main") { hasMain = true; }
|
||||
// Skip forward declarations (functions without body)
|
||||
let body: *HirNode = mod.funcs[i].body;
|
||||
if body == null as *HirNode {
|
||||
i = i + 1;
|
||||
continue;
|
||||
}
|
||||
CBE_EmitFuncDecl(cbe, &mod.funcs[i]);
|
||||
StringBuilder_Append(&cbe.sb, " {\n");
|
||||
// Body
|
||||
var hasReturn: bool = false;
|
||||
let body: *HirNode = mod.funcs[i].body;
|
||||
if body != null as *HirNode {
|
||||
cbe.indent = 1;
|
||||
CBE_EmitExpr(cbe, body);
|
||||
cbe.indent = 0;
|
||||
@@ -527,7 +551,6 @@ func CBackend_Generate(mod: *HirModule) -> String {
|
||||
if stmt.kind == hReturn { hasReturn = true; }
|
||||
stmt = stmt.child3;
|
||||
}
|
||||
}
|
||||
// Add default return 0 only if function returns int and has no explicit return
|
||||
if String_Eq(mod.funcs[i].retTypeName, "int") && !hasReturn {
|
||||
StringBuilder_Append(&cbe.sb, " return 0;\n");
|
||||
|
||||
@@ -105,6 +105,15 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode {
|
||||
return n;
|
||||
}
|
||||
|
||||
// Sizeof
|
||||
if kind == ekSizeOf {
|
||||
n.kind = hSizeOf;
|
||||
if expr.refType != null as *TypeExpr {
|
||||
n.typeName = expr.refType.typeName;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// Field access
|
||||
if kind == ekField {
|
||||
n.kind = hFieldPtr;
|
||||
|
||||
Reference in New Issue
Block a user