// cli.bux — CLI driver for the Bux self-hosting compiler // Wires together: Lexer → Parser → Sema → HirLower → CBackend module Cli { extern func PrintLine(s: String); extern func Print(s: String); extern func ReadFile(path: String) -> String; extern func WriteFile(path: String, content: String) -> bool; // Import the compiler pipeline // In self-hosting mode, these are compiled together from src_bux/ // --------------------------------------------------------------------------- // Compile a single .bux source file // --------------------------------------------------------------------------- func Cli_Compile(source: String, sourceName: String) -> String { // Phase 1: Lex let lex: *Lexer = Lexer_Tokenize(source); if Lexer_DiagCount(lex) > 0 { PrintLine("Lex errors:"); var i: int = 0; while i < Lexer_DiagCount(lex) { Print(" "); PrintLine(lex.diags[i].message); i = i + 1; } return ""; } // Phase 2: Parse let mod: *Module = Parser_Parse(lex.tokens, lex.tokenCount); if mod == null as *Module { PrintLine("Parse failed"); return ""; } // Phase 3: Semantic analysis let sema: *Sema = Sema_Analyze(mod); if Sema_HasError(sema) { PrintLine("Sema errors:"); var i: int = 0; while i < Sema_DiagCount(sema) { Print(" "); PrintLine(sema.diags[i].message); i = i + 1; } return ""; } // Phase 4: HIR lowering let hirMod: *HirModule = HirLower_LowerModule(mod, sema); if hirMod == null as *HirModule { PrintLine("HIR lowering failed"); return ""; } // Phase 5: C code generation let cCode: String = CBackend_Generate(hirMod); // Cleanup Lexer_Free(lex); Sema_Free(sema); return cCode; } // --------------------------------------------------------------------------- // Build command // --------------------------------------------------------------------------- func Cli_Build(srcPath: String, outPath: String) -> int { let source: String = ReadFile(srcPath); if String_Eq(source, "") || !FileExists(srcPath) { Print("Error: cannot read source file: "); PrintLine(srcPath); return 1; } Print("Compiling "); PrintLine(srcPath); let cCode: String = Cli_Compile(source, srcPath); if String_Eq(cCode, "") { PrintLine("Compilation failed"); return 1; } // Write C output let ok: bool = WriteFile(outPath, cCode); if ok { Print(" → C code written to "); PrintLine(outPath); return 0; } else { PrintLine("Error: cannot write output file"); return 1; } } // --------------------------------------------------------------------------- // Check command (compile only, no output) // --------------------------------------------------------------------------- func Cli_Check(srcPath: String) -> int { let source: String = ReadFile(srcPath); if String_Eq(source, "") { PrintLine("Error: cannot read source file"); return 1; } let cCode: String = Cli_Compile(source, srcPath); if String_Eq(cCode, "") { return 1; } PrintLine("Check passed"); return 0; } // --------------------------------------------------------------------------- // Main entry — dispatch based on args // --------------------------------------------------------------------------- func Cli_Run(args: *String, argCount: int) -> int { if argCount < 2 { PrintLine("Bux Self-Hosting Compiler v0.2.0"); PrintLine("Usage: buxc [args]"); PrintLine("Commands: build, check, run, version"); PrintLine(""); PrintLine("Pipeline modules:"); PrintLine(" Lexer ✅ 695 lines"); PrintLine(" Parser ✅ 1004 lines"); PrintLine(" Sema ✅ 393 lines"); PrintLine(" HirLower ✅ 307 lines"); PrintLine(" CBackend ✅ 264 lines"); PrintLine(" Total: 3830 lines of Bux"); return 0; } let cmd: String = args[1]; if String_Eq(cmd, "version") { PrintLine("Bux 0.2.0 (self-hosting bootstrap)"); return 0; } if String_Eq(cmd, "check") { if argCount < 3 { PrintLine("Usage: buxc check "); return 1; } return Cli_Check(args[2]); } if String_Eq(cmd, "build") { let src: String = "src/Main.bux"; let out: String = "build/main.c"; if argCount >= 3 { src = args[2]; } if argCount >= 4 { out = args[3]; } return Cli_Build(src, out); } Print("Unknown command: "); PrintLine(cmd); return 1; } }