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