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
+25 -25
View File
@@ -7,29 +7,29 @@ module CBackend {
// ---------------------------------------------------------------------------
func CBackend_TypeToC(kind: int) -> String {
if kind == tkVoid { return "void"; }
if kind == tkBool { return "bool"; }
if kind == tkBool8 { return "bool"; }
if kind == tkBool16 { return "bool"; }
if kind == tkBool32 { return "bool"; }
if kind == tkChar8 { return "char"; }
if kind == tkChar16 { return "uint16_t"; }
if kind == tkChar32 { return "uint32_t"; }
if kind == tkStr { return "const char*"; }
if kind == tkInt8 { return "int8_t"; }
if kind == tkInt16 { return "int16_t"; }
if kind == tkInt32 { return "int32_t"; }
if kind == tkInt64 { return "int64_t"; }
if kind == tkInt { return "int"; }
if kind == tkUInt8 { return "uint8_t"; }
if kind == tkUInt16 { return "uint16_t"; }
if kind == tkUInt32 { return "uint32_t"; }
if kind == tkUInt64 { return "uint64_t"; }
if kind == tkUInt { return "unsigned int"; }
if kind == tkFloat32 { return "float"; }
if kind == tkFloat64 { return "double"; }
if kind == tkPointer { return "void*"; }
if kind == tkNamed { return "void*"; }
if kind == tyVoid { return "void"; }
if kind == tyBool { return "bool"; }
if kind == tyBool8 { return "bool"; }
if kind == tyBool16 { return "bool"; }
if kind == tyBool32 { return "bool"; }
if kind == tyChar8 { return "char"; }
if kind == tyChar16 { return "uint16_t"; }
if kind == tyChar32 { return "uint32_t"; }
if kind == tyStr { return "const char*"; }
if kind == tyInt8 { return "int8_t"; }
if kind == tyInt16 { return "int16_t"; }
if kind == tyInt32 { return "int32_t"; }
if kind == tyInt64 { return "int64_t"; }
if kind == tyInt{ return "int"; }
if kind == tyUInt8 { return "uint8_t"; }
if kind == tyUInt16 { return "uint16_t"; }
if kind == tyUInt32 { return "uint32_t"; }
if kind == tyUInt64 { return "uint64_t"; }
if kind == tyUInt { return "unsigned int"; }
if kind == tyFloat32 { return "float"; }
if kind == tyFloat64 { return "double"; }
if kind == tyPointer { return "void*"; }
if kind == tyNamed { return "void*"; }
return "int";
}
@@ -153,7 +153,7 @@ func CBE_EmitExpr(cbe: *CEmitter, node: *HirNode) {
// Alloca
if kind == hAlloca {
StringBuilder_Append(&cbe.sb, CBackend_TypeToC(tkInt)); // simplified type
StringBuilder_Append(&cbe.sb, CBackend_TypeToC(tyInt)); // simplified type
StringBuilder_Append(&cbe.sb, " ");
StringBuilder_Append(&cbe.sb, node.strValue);
StringBuilder_Append(&cbe.sb, ";\n");
@@ -171,7 +171,7 @@ func CBE_EmitExpr(cbe: *CEmitter, node: *HirNode) {
// Cast
if kind == hCast {
StringBuilder_Append(&cbe.sb, "((");
StringBuilder_Append(&cbe.sb, CBackend_TypeToC(tkPointer));
StringBuilder_Append(&cbe.sb, CBackend_TypeToC(tyPointer));
StringBuilder_Append(&cbe.sb, ")");
CBE_EmitExpr(cbe, node.child1);
StringBuilder_Append(&cbe.sb, ")");