Phase 7.9: Self-hosted compiler buxc2 builds and runs! 🎉

buxc (Nim bootstrap) successfully compiles buxc2 (Bux self-hosted compiler)
into a working 88KB ELF x86-64 binary.

Compiler fixes (Nim):
- duplicate symbol: user funcs shadow stdlib funcs via mergeDecls()
- forward declarations: func without body + definition (both orderings)
- extern func dedup: same extern in multiple files
- discard keyword: new language keyword, lowered to expr stmt or no-op
- parser: keywords as field names + advance-on-error safeguard
- parser: var without initializer (zero-init)
- parser: multi-line || && continuation expressions
- parser: else-if chain newline handling
- C backend: const declarations emitted as #define
- C backend: load(field_ptr) → base.field optimization (fixes lvalue errors)

Source fixes (src_bux/*.bux):
- types.bux: tk* → ty* prefix for type kind constants (avoid token conflict)
- sema.bux: remaining tk* → ty* references, StringMap → *void workaround
- hir_lower.bux: ekReturn removed, Lcx_LowerParam helper, *f dereference
- c_backend.bux: &mod.funcs[i] for pointer passing
- cli.bux: ReadFile/WriteFile → bux_read_file/bux_write_file wrappers
- parser.bux: pathStr.len → String_Len(pathStr)
- types.bux: "*" + x → String_Concat("*", x)

Build system:
- Makefile: added 4 missing examples + selfhost target
- PLAN.md: updated with actual project state, Phase 7.9 marked complete

All 18 examples pass, all unit tests pass.
This commit is contained in:
2026-05-31 16:34:36 +03:00
parent 166954204c
commit cb256397bd
31 changed files with 4603 additions and 284 deletions
+23 -15
View File
@@ -106,13 +106,6 @@ func Lcx_LowerExpr(ctx: *LowerCtx, expr: *Expr) -> *HirNode {
return n;
}
// Return
if kind == ekReturn {
n.kind = hReturn;
n.child1 = Lcx_LowerExpr(ctx, expr.child1);
return n;
}
// Cast
if kind == ekCast {
n.kind = hCast;
@@ -222,6 +215,21 @@ func Lcx_LowerBlock(ctx: *LowerCtx, block: *Block, retTypeKind: int) -> *HirNode
return n;
}
// ---------------------------------------------------------------------------
// Param → HirParam conversion
// ---------------------------------------------------------------------------
func Lcx_LowerParam(out: *HirParam, p: *Param) {
out.name = p.name;
if p.refParamType != null as *TypeExpr {
out.typeKind = p.refParamType.kind;
out.typeName = p.refParamType.typeName;
} else {
out.typeKind = 0;
out.typeName = "";
}
}
// ---------------------------------------------------------------------------
// Function lowering
// ---------------------------------------------------------------------------
@@ -231,12 +239,12 @@ func Lcx_LowerFunc(ctx: *LowerCtx, decl: *Decl) -> *HirFunc {
f.name = decl.strValue;
f.isPublic = decl.isPublic;
f.paramCount = decl.paramCount;
f.param0 = decl.param0;
f.param1 = decl.param1;
f.param2 = decl.param2;
f.param3 = decl.param3;
f.param4 = decl.param4;
f.param5 = decl.param5;
Lcx_LowerParam(&f.param0, &decl.param0);
Lcx_LowerParam(&f.param1, &decl.param1);
Lcx_LowerParam(&f.param2, &decl.param2);
Lcx_LowerParam(&f.param3, &decl.param3);
Lcx_LowerParam(&f.param4, &decl.param4);
Lcx_LowerParam(&f.param5, &decl.param5);
if decl.retType != null as *TypeExpr {
f.retTypeName = decl.retType.typeName;
@@ -276,12 +284,12 @@ func HirLower_LowerModule(mod: *Module, sema: *Sema) -> *HirModule {
while decl != null as *Decl {
if decl.kind == dkFunc {
let f: *HirFunc = Lcx_LowerFunc(ctx, decl);
ctx.funcs[ctx.funcCount] = f;
ctx.funcs[ctx.funcCount] = *f;
ctx.funcCount = ctx.funcCount + 1;
}
if decl.kind == dkExternFunc {
let f: *HirFunc = Lcx_LowerFunc(ctx, decl);
ctx.externFuncs[ctx.externCount] = f;
ctx.externFuncs[ctx.externCount] = *f;
ctx.externCount = ctx.externCount + 1;
}
if decl.kind == dkStruct {