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
+33
View File
@@ -188,6 +188,19 @@ proc emitExpr(be: var CBackend, node: HirNode): string =
return &"({callee})({argsStr})"
of hLoad:
# Optimize: load(field_ptr(base, field)) → base.field (avoids & on temporaries)
if node.loadPtr != nil and node.loadPtr.kind == hFieldPtr:
let base = be.emitExpr(node.loadPtr.fieldPtrBase)
return &"({base}.{node.loadPtr.fieldName})"
# Optimize: load(arrow_field(base, field)) → base->field
if node.loadPtr != nil and node.loadPtr.kind == hArrowField:
let base = be.emitExpr(node.loadPtr.arrowFieldBase)
return &"({base}->{node.loadPtr.arrowFieldName})"
# Optimize: load(index_ptr(base, idx)) → base[idx]
if node.loadPtr != nil and node.loadPtr.kind == hIndexPtr:
let base = be.emitExpr(node.loadPtr.indexPtrBase)
let idx = be.emitExpr(node.loadPtr.indexPtrIndex)
return &"({base}[{idx}])"
let ptrExpr = be.emitExpr(node.loadPtr)
return &"(*{ptrExpr})"
@@ -482,6 +495,26 @@ proc emitModule*(be: var CBackend, module: HirModule): string =
be.emitExternDecl(ef)
be.emitLine("")
# Const declarations as #define
if module.consts.len > 0:
be.emitLine("/* Constants */")
for c in module.consts:
let val = c.value
if val != nil and val.kind == hLit:
let tok = val.litToken
case tok.kind
of tkIntLiteral:
be.emitLine(&"#define {c.name} {tok.text}")
of tkStringLiteral:
be.emitLine(&"#define {c.name} \"{tok.text}\"")
of tkBoolLiteral:
be.emitLine(&"#define {c.name} {tok.text}")
else:
be.emitLine(&"/* const {c.name} (unsupported literal kind) */")
else:
be.emitLine(&"/* const {c.name} (complex expression) */")
be.emitLine("")
# Struct definitions
for s in module.structs:
be.emitStruct(s.name, s.fields)