diff --git a/PLAN.md b/PLAN.md index c54b96c..408d582 100644 --- a/PLAN.md +++ b/PLAN.md @@ -293,7 +293,32 @@ Phase 7.5 — Driver (depends on all): | `7.7` Port C backend | ✅ | `c_backend.bux` — C code generator | 266 | | `7.8` Port CLI | ✅ | `cli.bux` + `main.bux` — command dispatch | ~181 | | `7.9` Dogfooding | ✅ | `buxc` (Nim) compiles `buxc2` (Bux) — **WORKING BINARY** (88KB ELF x86-64) | — | -| `7.10` Fix bootstrap loop | ⏳ | Once `buxc2 == buxc3`, we are self-hosted. Freeze Nim version as reference. | — | +| `7.10` Bootstrap loop | 🔄 | `buxc2 check` works on `.bux` files. Full multi-file build needs sema/IR fixes. | 7.9 | + +### Phase 7.10 — Bootstrap Loop (In Progress) + +**Status:** `buxc2` can type-check (`check`) individual `.bux` files. Full self-compilation needs fixes in `buxc2`'s sema, HIR, and C backend. + +**What works:** +- ✅ `buxc2 version` — shows version from command-line args +- ✅ `buxc2 check ` — lexes, parses, type-checks, generates C (validates pipeline) +- ✅ `buxc2 build ` — writes generated C to file +- ✅ Command-line args — `bux_argc()`/`bux_argv()` in runtime, `int main(argc, argv)` wrapper + +**What needs fixing in `buxc2`:** +| Issue | Location | Description | +|-------|----------|-------------| +| `String` → `int` | `sema.bux` | `Sema_ResolveType("String")` returns `tyInt` instead of `tyStr` | +| Function calls not in body | `hir_lower.bux` | `Lcx_LowerExpr` doesn't emit call expressions into function body | +| No `int main()` wrapper | `c_backend.bux` | Missing `hasMain` detection and C main wrapper generation | +| Single-file only | `cli.bux` | Cannot merge multiple `.bux` files with imports | + +**Bootstrap loop goal:** +``` +buxc (Nim) → compile src_bux/*.bux → buxc2 (Bux binary) +buxc2 (Bux) → compile src_bux/*.bux → buxc3 (Bux binary) +compare buxc2 == buxc3 → SELF-HOSTED ✅ +``` ### Phase 7.9 — Completed 2026-05-31 🎉 diff --git a/_selfhost/src/Main.bux b/_selfhost/src/Main.bux index 181fe20..a58b83c 100644 --- a/_selfhost/src/Main.bux +++ b/_selfhost/src/Main.bux @@ -1,13 +1,22 @@ // main.bux — Entry point for the Bux self-hosting compiler module Main { +// C runtime for command-line args +extern func bux_argc() -> int; +extern func bux_argv(index: int) -> String; + // Forward declaration from Cli module func Cli_Run(args: *String, argCount: int) -> int; func Main() -> int { - // In a full implementation, parse command-line arguments - // For now, just show version info - var emptyArgs: *String = null as *String; - return Cli_Run(emptyArgs, 0); + let count: int = bux_argc(); + // Allocate array of String pointers + let args: *String = bux_alloc(count as uint * 8) as *String; + var i: int = 0; + while i < count { + args[i] = bux_argv(i); + i = i + 1; + } + return Cli_Run(args, count); } } diff --git a/src/c_backend.nim b/src/c_backend.nim index 33b864d..a48d48a 100644 --- a/src/c_backend.nim +++ b/src/c_backend.nim @@ -544,7 +544,11 @@ proc emitModule*(be: var CBackend, module: HirModule): string = # Generate C main wrapper if Bux Main exists if hasMain: be.emitLine("/* C entry point wrapper */") + be.emitLine("extern int g_argc;") + be.emitLine("extern char** g_argv;") be.emitLine("int main(int argc, char** argv) {") + be.emitLine(" g_argc = argc;") + be.emitLine(" g_argv = argv;") be.emitLine(" return Main();") be.emitLine("}") be.emitLine("") diff --git a/src_bux/main.bux b/src_bux/main.bux index 181fe20..a58b83c 100644 --- a/src_bux/main.bux +++ b/src_bux/main.bux @@ -1,13 +1,22 @@ // main.bux — Entry point for the Bux self-hosting compiler module Main { +// C runtime for command-line args +extern func bux_argc() -> int; +extern func bux_argv(index: int) -> String; + // Forward declaration from Cli module func Cli_Run(args: *String, argCount: int) -> int; func Main() -> int { - // In a full implementation, parse command-line arguments - // For now, just show version info - var emptyArgs: *String = null as *String; - return Cli_Run(emptyArgs, 0); + let count: int = bux_argc(); + // Allocate array of String pointers + let args: *String = bux_alloc(count as uint * 8) as *String; + var i: int = 0; + while i < count { + args[i] = bux_argv(i); + i = i + 1; + } + return Cli_Run(args, count); } } diff --git a/stdlib/runtime.c b/stdlib/runtime.c index 9f4d02f..51795d0 100644 --- a/stdlib/runtime.c +++ b/stdlib/runtime.c @@ -7,6 +7,16 @@ #include #include +/* Command-line argument storage */ +int g_argc = 0; +char** g_argv = NULL; + +int bux_argc(void) { return g_argc; } +char* bux_argv(int index) { + if (index < 0 || index >= g_argc) return ""; + return g_argv[index]; +} + /* Memory allocation */ void* bux_alloc(size_t size) { void* ptr = malloc(size);