refactor(x): per-process scratch dirs, Ludic ports of the LSP test and Forgejo release
- every scratch file lives in `$TMPDIR/x_<pid>/` (tmp_dir/tmp_path in prelude.ludic), removed by main's new dispatch() → tmp_cleanup(); X_KEEP_TMP=1 keeps it. `x test` and `x check-*` may now run together. - `x test-lsp` (tools/x/lsp_test.ludic) replaces tools/test-lsp.py: the whole request stream is framed into one stdin file, the server runs to `exit`, and the response stream is parsed back by request id; adds a check that ludicc's own error is published on save - tools/x/forgejo.ludic replaces tools/ci/forgejo_release.py (curl with a 0600 header file; the token is no longer on the command line; LUDIC_FORGEJO_API for forks) - `x docs-palette --check` regenerates into scratch and compares, so the drift guard judges the working tree rather than git HEAD; the generator no longer emits a trailing blank line the formatter rejects - `x test-tools`: exit 2 from test-lsp / test-grammar.js is a visible skip, never a pass; the widget-prop test uses the `id: Root` syntax - tools/test-grammar.js: current vocabulary (property/model/handler/ prefab/scene/event/become/@Queries), LUDIC_NODE_MODULES, exit 2 on skip - tools/atlas.ludic rewritten in the current language (it did not compile) - operators.ludic / os.ludic registered in the suite - json.ludic: j_quote() writer helper Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
647dfec334
commit
8fed9add66
19 changed files with 1154 additions and 614 deletions
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
# compile selfhost/tests/<name>.ludic with bin/ludicc, assemble, run, compare
|
||||
function sh_case(name: pointer, exp: pointer) -> void {
|
||||
let ll = `/tmp/x_sh_{name}.ll`
|
||||
let er = `/tmp/x_sh_{name}.err`
|
||||
let bn = `/tmp/x_sh_{name}`
|
||||
let ll = `{tmp_dir()}/sh_{name}.ll`
|
||||
let er = `{tmp_dir()}/sh_{name}.err`
|
||||
let bn = `{tmp_dir()}/sh_{name}`
|
||||
if not shq(`bin/ludicc selfhost/tests/{name}.ludic > {ll} 2>{er}`) {
|
||||
bad2(`{name}: self-host errored`, capture_line(`head -1 {er}`)); return
|
||||
}
|
||||
|
|
@ -22,9 +22,9 @@ function sh_case(name: pointer, exp: pointer) -> void {
|
|||
# `bin/x golden` (see cmd_golden below).
|
||||
function game_case(path: pointer, keys: pointer) -> void {
|
||||
let nm = flat(path)
|
||||
if not game_build_ok("bin/ludicc", `examples/{path}.ludic`, `/tmp/x_g_{nm}`) { bad(`{path}: build`); return }
|
||||
if not game_build_ok("bin/ludicc", `examples/{path}.ludic`, `{tmp_dir()}/g_{nm}`) { bad(`{path}: build`); return }
|
||||
run("mkdir -p build")
|
||||
run(`printf '%s' '{keys}' | /tmp/x_g_{nm} >/dev/null 2>&1`)
|
||||
run(`printf '%s' '{keys}' | {tmp_dir()}/g_{nm} >/dev/null 2>&1`)
|
||||
# The build + headless run above guard against a compile or runtime break on
|
||||
# every host. The pixel-exact golden comparison, though, is against a render
|
||||
# blessed on macOS; text rasterization differs by a hair on other hosts, so
|
||||
|
|
@ -41,11 +41,11 @@ function game_case(path: pointer, keys: pointer) -> void {
|
|||
# string on build failure). Shared by `bin/x golden` and nothing else.
|
||||
function bless_render(path: pointer, keys: pointer) -> pointer {
|
||||
let nm = flat(path)
|
||||
if not game_build_ok("bin/ludicc", `examples/{path}.ludic`, `/tmp/x_bg_{nm}`) {
|
||||
if not game_build_ok("bin/ludicc", `examples/{path}.ludic`, `{tmp_dir()}/bg_{nm}`) {
|
||||
err(`golden: {path} failed to build\n`); return ""
|
||||
}
|
||||
run("mkdir -p build")
|
||||
run(`printf '%s' '{keys}' | /tmp/x_bg_{nm} >/dev/null 2>&1`)
|
||||
run(`printf '%s' '{keys}' | {tmp_dir()}/bg_{nm} >/dev/null 2>&1`)
|
||||
let h = capture_line("shasum -a 256 build/out.ppm | cut -d' ' -f1")
|
||||
return `{path} {h}\n`
|
||||
}
|
||||
|
|
@ -58,10 +58,10 @@ function cmd_golden() -> int {
|
|||
ensure_ludicc()
|
||||
if not is_exec("bin/ludicc") { err("golden: bin/ludicc unavailable\n"); return 1 }
|
||||
var manifest = ""
|
||||
manifest = manifest + bless_render("games/snake", "ddssaawwddss")
|
||||
manifest = manifest + bless_render("games/menu", "ssss")
|
||||
manifest = manifest + bless_render("games/chronorift", "ddddwwwwaassK")
|
||||
manifest = manifest + bless_render("rendering/draw_prims", "")
|
||||
manifest += bless_render("games/snake", "ddssaawwddss")
|
||||
manifest += bless_render("games/menu", "ssss")
|
||||
manifest += bless_render("games/chronorift", "ddddwwwwaassK")
|
||||
manifest += bless_render("rendering/draw_prims", "")
|
||||
if not write_file("selfhost/golden/renders.sha256", manifest) {
|
||||
err("golden: could not write selfhost/golden/renders.sha256\n"); return 1
|
||||
}
|
||||
|
|
@ -117,12 +117,12 @@ function cmd_selfhost_test() -> int {
|
|||
game_case("rendering/draw_prims", "")
|
||||
|
||||
print("== the bootstrap fixpoint (seeded from bin/ludicc) ==")
|
||||
if shq("bin/x bootstrap > /tmp/x_boot.out 2>&1") { ok("gen2.ll == gen3.ll (compiler reproduces itself)") }
|
||||
else { bad("fixpoint not reached"); out(capture("cat /tmp/x_boot.out")) }
|
||||
if shq(`bin/x bootstrap > {tmp_dir()}/boot.out 2>&1`) { ok("gen2.ll == gen3.ll (compiler reproduces itself)") }
|
||||
else { bad("fixpoint not reached"); out(capture(`cat {tmp_dir()}/boot.out`)) }
|
||||
|
||||
print("== the C-free bootstrap (from the checked-in IR seed, no C compiler) ==")
|
||||
if shq("bin/x bootstrap-cfree > /tmp/x_cfree.out 2>&1") { ok("seed.ll rebuilds the compiler and is its own fixed point") }
|
||||
else { bad("C-free bootstrap failed (seed stale? run: x reseed)"); out(capture("cat /tmp/x_cfree.out")) }
|
||||
if shq(`bin/x bootstrap-cfree > {tmp_dir()}/cfree.out 2>&1`) { ok("seed.ll rebuilds the compiler and is its own fixed point") }
|
||||
else { bad("C-free bootstrap failed (seed stale? run: x reseed)"); out(capture(`cat {tmp_dir()}/cfree.out`)) }
|
||||
|
||||
return report()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue