ludic/selfhost/emit_machine.ludic
Orkuncakilkaya cc701013f5 Phase 6e: unify builtin naming (loaders domain-first, set_reg)
Fixed the naming inconsistencies the cohesion audit flagged, converging on the
domain-first style the bulk of the surface already uses (ui_*, text_*, rng_*,
font_load, image_load):

  - load_png    -> png_load       (asset loaders were split: font_load/image_load
  - load_sprites -> sprites_load   were domain-first, load_* were verb-first)
  - setreg      -> set_reg        (missing underscore vs ui_set_int/ui_set_text)

Game builtins resolve to their `rt_` runtime function, so the renames are in
runtime/native (rt_png_load, rt_sprites_load, rt_set_reg) plus the ~100 example
call sites; `become` lowering in emit_machine now emits @fn_rt_set_reg. Purely a
surface rename — every renamed call maps to the same runtime symbol, so behavior
and golden renders are byte-identical.

Vocabulary + docs updated (ludic_syntax.h, grammar, LudicTokens.kt, LANGUAGE.md,
README, SYNTAX-REDESIGN). Reseeded; C-free fixpoint holds; goldens identical;
17/17; vocab clean.

Left as-is: os_argc/os_arg (compiler-internal intrinsics, already namespaced and
consistent with each other; renaming would need a bootstrap dance for little
gain). reg/set_reg keep the getter-bare/setter-set_ shape ui_focused/ui_set_int
already use.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-27 23:38:10 +03:00

39 lines
1.6 KiB
Text

# emit_machine.ludic — `machine <reg> { state Name = v { .. } }` dispatches on a
# register's value; `become Name` stores the target state's value back. Both are
# reg()/set_reg() calls, resolved to the runtime like any other builtin.
fn emit_machine(st: Node) -> void {
let regv = emit_expr(st.a)
let s = emit_bind(sconcat("call i32 @fn_rt_reg(i32 ", sconcat(regv.code, ")")))
if nmach < len(mach_stk) { mach_stk[nmach] = st } else { push(mach_stk, st) }
nmach = nmach + 1
let endl = lbl("smend")
let i = 0
while i < len(st.kids) {
let state = st.kids[i]
let v = emit_expr(state.b)
let c = emit_bind(sconcat("icmp eq i32 ", sconcat(s, sconcat(", ", v.code))))
let body = lbl("sbody"); let nxt = lbl("sarm")
emit(" br i1 "); emit(c); emit(", label %"); emit(body); emit(", label %"); emit(nxt); emit("\n")
emit(body); emit(":\n"); g_term = false
emit_block(state.a)
if not g_term { emit(" br label %"); emit(endl); emit("\n") }
emit(nxt); emit(":\n"); g_term = false
i = i + 1
}
if not g_term { emit(" br label %"); emit(endl); emit("\n") }
emit(endl); emit(":\n"); g_term = false
nmach = nmach - 1
}
fn emit_become(st: Node) -> void {
if nmach == 0 { perr("'become' outside a machine") }
let m = mach_stk[nmach - 1]
let target: Node = ptr_null()
let i = 0
while i < len(m.kids) { if streq(m.kids[i].s, st.s) { target = m.kids[i] }; i = i + 1 }
if ptr_is_null(target) { perr(sconcat("become: no state ", st.s)) }
let regv = emit_expr(m.a)
let sv = emit_expr(target.b)
emit(" call void @fn_rt_set_reg(i32 "); emit(regv.code); emit(", i32 "); emit(sv.code); emit(")\n")
}