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>
29 lines
1.3 KiB
Text
29 lines
1.3 KiB
Text
# emit_math.ludic — the math builtins that lower to inline IR rather than a
|
|
# runtime call: min, max, abs, clamp. Everything else named like a builtin
|
|
# (clear, fill_rect, reg, ...) is resolved to its rt_ function by emit_call.
|
|
|
|
fn is_math_builtin(name: ptr) -> bool {
|
|
return (name == "min") or (name == "max") or (name == "abs") or (name == "clamp")
|
|
}
|
|
|
|
fn emit_math_builtin(name: ptr, e: Node) -> Val {
|
|
if (name == "abs") {
|
|
let a = emit_expr(e.kids[0])
|
|
let c = emit_bind(`icmp slt i32 {a.code}, 0`)
|
|
let n = emit_bind(`sub i32 0, {a.code}`)
|
|
return val(emit_bind(`select i1 {c}, i32 {n}, i32 {a.code}`), "int")
|
|
}
|
|
if (name == "min") or (name == "max") {
|
|
let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1])
|
|
var op = "slt"
|
|
if (name == "max") { op = "sgt" }
|
|
let c = emit_bind(`icmp {op} i32 {a.code}, {b.code}`)
|
|
return val(emit_bind(`select i1 {c}, i32 {a.code}, i32 {b.code}`), "int")
|
|
}
|
|
# clamp(v, lo, hi) = max(lo, min(v, hi))
|
|
let v = emit_expr(e.kids[0]); let lo = emit_expr(e.kids[1]); let hi = emit_expr(e.kids[2])
|
|
let c1 = emit_bind(`icmp slt i32 {v.code}, {hi.code}`)
|
|
let t = emit_bind(`select i1 {c1}, i32 {v.code}, i32 {hi.code}`)
|
|
let c2 = emit_bind(`icmp sgt i32 {lo.code}, {t}`)
|
|
return val(emit_bind(`select i1 {c2}, i32 {lo.code}, i32 {t}`), "int")
|
|
}
|