feat: HTTP registry, app/bench harnesses, and DWARF #line maps

Ship QUALITY_PLAN sessions 31–33: fetchable package index URLs, showcase
app and micro/nexus benchmarks, and debugger-friendly C codegen.

- Registry: BUX_REGISTRY accepts http(s) URLs (curl/wget → ~/.bux/cache)
- E.2: make test-apps smoke for nexus/boko/simpledb/jwt-pitbul
- E.5: benches/micro + C/Nim/Zig twins; make bench-nexus (wrk)
- E.4: HIR locs → #line .bux; default -O0 -g; --release -O2; make test-dwarf
This commit is contained in:
2026-07-19 22:46:45 +03:00
parent 53b43b0f79
commit eb81856565
26 changed files with 983 additions and 52 deletions
+34 -1
View File
@@ -10,11 +10,17 @@ type
output*: string
indent*: int
tempTypes*: Table[string, string] ## Track C types of temp variables
emitDebugLines*: bool ## Emit #line → .bux for DWARF (E.4)
lastDebugLine*: int
lastDebugFile*: string
proc initLirCBackend*(): LirCBackend =
proc initLirCBackend*(emitDebugLines: bool = true): LirCBackend =
result = LirCBackend(
indent: 0,
tempTypes: initTable[string, string](),
emitDebugLines: emitDebugLines,
lastDebugLine: 0,
lastDebugFile: "",
)
proc emitIndent(be: var LirCBackend) =
@@ -26,6 +32,22 @@ proc emitLine(be: var LirCBackend, s: string) =
be.output.add(s)
be.output.add("\n")
proc emitDebugLine(be: var LirCBackend, instr: LirInstr) =
## Map generated C back to Bux source for gdb/DWARF via #line.
if not be.emitDebugLines: return
if instr.locLine <= 0: return
if instr.locLine == be.lastDebugLine and instr.locFile == be.lastDebugFile:
return
be.lastDebugLine = instr.locLine
be.lastDebugFile = instr.locFile
var path = instr.locFile
if path.len == 0:
path = "<bux>"
# Escape for C string literal
path = path.replace("\\", "\\\\").replace("\"", "\\\"")
# #line must start at column 0
be.output.add(&"#line {instr.locLine} \"{path}\"\n")
proc valToC(be: var LirCBackend, v: LirValue): string =
## Convert a LirValue to its C representation.
case v.kind
@@ -50,6 +72,7 @@ proc cParamDecl(cType, name: string): string =
# ── Per-instruction emission ──
proc emitInstr(be: var LirCBackend, instr: LirInstr) =
be.emitDebugLine(instr)
template v(x: LirValue): string = valToC(be, x)
case instr.kind
@@ -246,6 +269,16 @@ proc emitFunc(be: var LirCBackend, f: LirFunc, funcRetTypes: Table[string, strin
if f.params.len == 0:
paramsStr = "void"
# Point the function entry at the first Bux location so gdb `list Main` works
# (otherwise leftover #line from the previous function pollutes the prologue).
if be.emitDebugLines:
for instr in f.instrs:
if instr.locLine > 0:
be.lastDebugLine = 0
be.lastDebugFile = ""
be.emitDebugLine(instr)
break
be.emitLine(&"{f.retType} {f.name}({paramsStr}) {{")
be.indent += 1