Baseline: Ludic compiler + toolchain, Phase 1 syntax fixes complete
Self-hosted compiler (selfhost/*.ludic), runtime, examples, editor tooling, and docs. Phase 1 of the syntax-redesign cohesion pass has landed: edge-system fix, signature-query, when-alias, and the documentation truth-pass. Suite green (14/14), C-free bootstrap fixpoint holds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
commit
985f9ad8f2
418 changed files with 39065 additions and 0 deletions
61
selfhost/emit_save.ludic
Normal file
61
selfhost/emit_save.ludic
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# emit_save.ludic — save() / load() snapshot of the whole ECS world. The
|
||||
# compiler writes the entity/component half itself (it knows the shape) and
|
||||
# hands the open file to rt_save_state/rt_load_state for the runtime's own
|
||||
# state. Mirrors compiler/back/ir_save.c. save()->@L_save, load()->@L_load.
|
||||
|
||||
var g_iok: int = 0
|
||||
|
||||
fn emit_io(fn2: ptr, p: ptr, bytes: ptr) -> void {
|
||||
let r = sconcat("%io", itoa(g_iok)) g_iok = g_iok + 1
|
||||
emit(" ") emit(r) emit(" = call i64 @") emit(fn2) emit("(ptr ") emit(p) emit(", i64 1, i64 ") emit(bytes) emit(", ptr %f)\n")
|
||||
}
|
||||
|
||||
fn emit_snapshot_blocks(fn2: ptr) -> void {
|
||||
g_iok = 0
|
||||
let me = itoa(MAX_ENT)
|
||||
emit_io(fn2, "@L_entc", "4")
|
||||
emit_io(fn2, "@L_freen", "4")
|
||||
emit(" %nalive = mul i64 ") emit(me) emit(", 4\n")
|
||||
emit_io(fn2, "@L_alive", "%nalive")
|
||||
emit_io(fn2, "@L_freelist", "%nalive")
|
||||
emit_io(fn2, "@L_kind", "%nalive")
|
||||
let i = 0
|
||||
while i < len(prog) { if prog[i].kind == N_VAR { emit_io(fn2, sconcat("@g_", prog[i].s), "4") } i = i + 1 }
|
||||
let ci = 0
|
||||
i = 0
|
||||
while i < len(prog) {
|
||||
if prog[i].kind == N_COMP {
|
||||
let c = prog[i].s
|
||||
let csz = sconcat("%csz", itoa(ci))
|
||||
emit(" ") emit(csz) emit(" = ptrtoint ptr getelementptr (%Cmp_") emit(c) emit(", ptr null, i32 ") emit(me) emit(") to i64\n")
|
||||
emit_io(fn2, sconcat("@S_", c), csz)
|
||||
emit_io(fn2, sconcat("@H_", c), me)
|
||||
ci = ci + 1
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_snapshot() -> void {
|
||||
emith("@.sav_path = private unnamed_addr constant [10 x i8] c\"ludic.sav\\00\"\n")
|
||||
emith("@.sav_wb = private unnamed_addr constant [3 x i8] c\"wb\\00\"\n")
|
||||
emith("@.sav_rb = private unnamed_addr constant [3 x i8] c\"rb\\00\"\n")
|
||||
let has_save = not ptr_is_null(find_fn("rt_save_state"))
|
||||
let has_load = not ptr_is_null(find_fn("rt_load_state"))
|
||||
|
||||
emit("define void @L_save() {\nentry:\n")
|
||||
emit(" %f = call ptr @fopen(ptr @.sav_path, ptr @.sav_wb)\n")
|
||||
emit(" %bad = icmp eq ptr %f, null\n")
|
||||
emit(" br i1 %bad, label %out, label %go\ngo:\n")
|
||||
emit_snapshot_blocks("fwrite")
|
||||
if has_save { emit(" call void @fn_rt_save_state(ptr %f)\n") }
|
||||
emit(" %c = call i32 @fclose(ptr %f)\n br label %out\nout:\n ret void\n}\n\n")
|
||||
|
||||
emit("define i32 @L_load() {\nentry:\n")
|
||||
emit(" %f = call ptr @fopen(ptr @.sav_path, ptr @.sav_rb)\n")
|
||||
emit(" %bad = icmp eq ptr %f, null\n")
|
||||
emit(" br i1 %bad, label %miss, label %go\nmiss:\n ret i32 0\ngo:\n")
|
||||
emit_snapshot_blocks("fread")
|
||||
if has_load { emit(" call void @fn_rt_load_state(ptr %f)\n") }
|
||||
emit(" %c = call i32 @fclose(ptr %f)\n ret i32 1\n}\n\n")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue