diff --git a/_selfhost/src/c_backend.bux b/_selfhost/src/c_backend.bux index bd30a4c..eddb3ff 100644 --- a/_selfhost/src/c_backend.bux +++ b/_selfhost/src/c_backend.bux @@ -223,6 +223,67 @@ func CBE_EmitExpr(cbe: *CEmitter, node: *HirNode) { return; } + // While + if kind == hWhile { + StringBuilder_Append(&cbe.sb, "while ("); + CBE_EmitExpr(cbe, node.child1); + StringBuilder_Append(&cbe.sb, ") {\n"); + if node.child2 != null as *HirNode { + cbe.indent = cbe.indent + 1; + CBE_EmitExpr(cbe, node.child2); + cbe.indent = cbe.indent - 1; + } + var sp: int = 0; + while sp < cbe.indent { + StringBuilder_Append(&cbe.sb, " "); + sp = sp + 1; + } + StringBuilder_Append(&cbe.sb, "}"); + return; + } + + // Loop (infinite) + if kind == hLoop { + StringBuilder_Append(&cbe.sb, "while (1) {\n"); + if node.child1 != null as *HirNode { + cbe.indent = cbe.indent + 1; + CBE_EmitExpr(cbe, node.child1); + cbe.indent = cbe.indent - 1; + } + var sp: int = 0; + while sp < cbe.indent { + StringBuilder_Append(&cbe.sb, " "); + sp = sp + 1; + } + StringBuilder_Append(&cbe.sb, "}"); + return; + } + + // Index: arr[idx] — emit as arr[idx] + if kind == hIndexPtr { + CBE_EmitExpr(cbe, node.child1); + StringBuilder_Append(&cbe.sb, "["); + CBE_EmitExpr(cbe, node.child2); + StringBuilder_Append(&cbe.sb, "]"); + return; + } + + // Load: *ptr — emit as *ptr (dereference) + if kind == hLoad { + StringBuilder_Append(&cbe.sb, "(*"); + CBE_EmitExpr(cbe, node.child1); + StringBuilder_Append(&cbe.sb, ")"); + return; + } + + // Assign: target = value + if kind == hAssign { + CBE_EmitExpr(cbe, node.child1); + StringBuilder_Append(&cbe.sb, " = "); + CBE_EmitExpr(cbe, node.child2); + return; + } + // Cast if kind == hCast { StringBuilder_Append(&cbe.sb, "(("); diff --git a/_selfhost/src/hir_lower.bux b/_selfhost/src/hir_lower.bux index 20fbd16..e52fba2 100644 --- a/_selfhost/src/hir_lower.bux +++ b/_selfhost/src/hir_lower.bux @@ -66,6 +66,13 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode { // Binary if kind == ekBinary { + // Assignment operator → use hAssign + if expr.intValue == tkAssign { + n.kind = hAssign; + n.child1 = Lcx_LowerExpr(ctx, expr.child1); + n.child2 = Lcx_LowerExpr(ctx, expr.child2); + return n; + } n.kind = hBinary; n.intValue = expr.intValue; // operator n.child1 = Lcx_LowerExpr(ctx, expr.child1); @@ -106,6 +113,22 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode { return n; } + // Index: arr[idx] + if kind == ekIndex { + n.kind = hIndexPtr; + n.child1 = Lcx_LowerExpr(ctx, expr.child1); + n.child2 = Lcx_LowerExpr(ctx, expr.child2); + return n; + } + + // Assign: target = value + if kind == ekAssign { + n.kind = hAssign; + n.child1 = Lcx_LowerExpr(ctx, expr.child1); // target + n.child2 = Lcx_LowerExpr(ctx, expr.child2); // value + return n; + } + // Cast if kind == ekCast { n.kind = hCast; diff --git a/src_bux/c_backend.bux b/src_bux/c_backend.bux index bd30a4c..eddb3ff 100644 --- a/src_bux/c_backend.bux +++ b/src_bux/c_backend.bux @@ -223,6 +223,67 @@ func CBE_EmitExpr(cbe: *CEmitter, node: *HirNode) { return; } + // While + if kind == hWhile { + StringBuilder_Append(&cbe.sb, "while ("); + CBE_EmitExpr(cbe, node.child1); + StringBuilder_Append(&cbe.sb, ") {\n"); + if node.child2 != null as *HirNode { + cbe.indent = cbe.indent + 1; + CBE_EmitExpr(cbe, node.child2); + cbe.indent = cbe.indent - 1; + } + var sp: int = 0; + while sp < cbe.indent { + StringBuilder_Append(&cbe.sb, " "); + sp = sp + 1; + } + StringBuilder_Append(&cbe.sb, "}"); + return; + } + + // Loop (infinite) + if kind == hLoop { + StringBuilder_Append(&cbe.sb, "while (1) {\n"); + if node.child1 != null as *HirNode { + cbe.indent = cbe.indent + 1; + CBE_EmitExpr(cbe, node.child1); + cbe.indent = cbe.indent - 1; + } + var sp: int = 0; + while sp < cbe.indent { + StringBuilder_Append(&cbe.sb, " "); + sp = sp + 1; + } + StringBuilder_Append(&cbe.sb, "}"); + return; + } + + // Index: arr[idx] — emit as arr[idx] + if kind == hIndexPtr { + CBE_EmitExpr(cbe, node.child1); + StringBuilder_Append(&cbe.sb, "["); + CBE_EmitExpr(cbe, node.child2); + StringBuilder_Append(&cbe.sb, "]"); + return; + } + + // Load: *ptr — emit as *ptr (dereference) + if kind == hLoad { + StringBuilder_Append(&cbe.sb, "(*"); + CBE_EmitExpr(cbe, node.child1); + StringBuilder_Append(&cbe.sb, ")"); + return; + } + + // Assign: target = value + if kind == hAssign { + CBE_EmitExpr(cbe, node.child1); + StringBuilder_Append(&cbe.sb, " = "); + CBE_EmitExpr(cbe, node.child2); + return; + } + // Cast if kind == hCast { StringBuilder_Append(&cbe.sb, "(("); diff --git a/src_bux/hir_lower.bux b/src_bux/hir_lower.bux index 20fbd16..e52fba2 100644 --- a/src_bux/hir_lower.bux +++ b/src_bux/hir_lower.bux @@ -66,6 +66,13 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode { // Binary if kind == ekBinary { + // Assignment operator → use hAssign + if expr.intValue == tkAssign { + n.kind = hAssign; + n.child1 = Lcx_LowerExpr(ctx, expr.child1); + n.child2 = Lcx_LowerExpr(ctx, expr.child2); + return n; + } n.kind = hBinary; n.intValue = expr.intValue; // operator n.child1 = Lcx_LowerExpr(ctx, expr.child1); @@ -106,6 +113,22 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode { return n; } + // Index: arr[idx] + if kind == ekIndex { + n.kind = hIndexPtr; + n.child1 = Lcx_LowerExpr(ctx, expr.child1); + n.child2 = Lcx_LowerExpr(ctx, expr.child2); + return n; + } + + // Assign: target = value + if kind == ekAssign { + n.kind = hAssign; + n.child1 = Lcx_LowerExpr(ctx, expr.child1); // target + n.child2 = Lcx_LowerExpr(ctx, expr.child2); // value + return n; + } + // Cast if kind == ekCast { n.kind = hCast;