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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user