Phase 7g: the compiler builds its IR with interpolation, not +

Answering your readability point directly: the compiler's own string-building —
left uglier by the 7c `+` migration, e.g. `emit_bind(("load i32, ptr " + ip))` —
now reads as interpolation:

  emit_bind(("load i32, ptr " + ip))            -> emit_bind(`load i32, ptr {ip}`)
  emit_bind(("icmp eq i32 " + (kv + (", " + itoa(ak)))))
                                                -> emit_bind(`icmp eq i32 {kv}, {itoa(ak)}`)
  perr(("assign to unknown " + t.s))            -> perr(`assign to unknown {t.s}`)

164 concat chains across selfhost converted by a tool that flattens the `+` tree,
keeps call/index parens (only grouping parens are rewritten), and converts only
**brace-free** literals — LLVM IR structure strings full of `{`/`}` stay as `+`
rather than becoming awkward `{{`/`}}`. No new language surface; interpolation
already desugars to the same concat.

Reseeded (22565 lines); C-free fixpoint holds byte-for-byte (the strongest proof
the reconstruction is exact); goldens identical; 18/18.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-08-28 01:30:37 +03:00
parent 4faf91abdc
commit df6955e609
20 changed files with 566 additions and 566 deletions

View file

@ -77,7 +77,7 @@ entry {
# an unknown flag is ignored (with a note) rather than mistaken for the
# input file — '-' is ASCII 45
if peek8(a, 0) == 45 {
let m = ("ludicc: ignoring unknown flag " + (a + "\n"))
let m = `ludicc: ignoring unknown flag {a}\n`
file_write(file_stderr(), m, len(m))
} else { path = a }
} } } } } } }
@ -117,14 +117,14 @@ entry {
# a run with no explicit -o lands in a temp file
if run and (out == null) {
out = (("/tmp/ludic-run-") + strip_ludic(base_name(path)))
out = `/tmp/ludic-run-{strip_ludic(base_name(path))}`
}
# make the output directory if the user asked for e.g. bin/app
let odir = dir_of(out)
if len(odir) > 0 { os_system((("mkdir -p ") + odir)) }
if len(odir) > 0 { os_system(`mkdir -p {odir}`) }
let ll = (out + ".ll")
let ll = `{out}.ll`
if not ir_flush(ll) { die("ludicc: cannot write IR\n") }
let cc = getenv_or("LUDIC_CC", "clang")
@ -134,15 +134,15 @@ entry {
# platform layer and the Cocoa framework.
# -Wno-override-module: our IR carries an explicit target triple, which clang
# would otherwise warn about on every build.
var cmd = (cc + ((" -O2 -Wno-override-module ") + ll))
var cmd = `{cc} -O2 -Wno-override-module {ll}`
if g_windowed {
let cocoa = path_join(home, "runtime/native/cocoa.ll")
cmd = (cmd + (" " + (cocoa + (" -framework Cocoa -Wl,-rpath,@loader_path"))))
cmd = `{cmd} {cocoa} -framework Cocoa -Wl,-rpath,@loader_path`
}
cmd = (cmd + ((" -o ") + out))
cmd = `{cmd} -o {out}`
let rc = os_system(cmd)
if not save { os_system((("rm -f ") + ll)) }
if not save { os_system(`rm -f {ll}`) }
if rc != 0 { die("ludicc: link failed\n") }
# run mode: execute the binary we just built and forward its exit code