Chez Phase 3 inc8: prelude fixpoint + fully-Chez-emitted system

Extends the fixpoint beyond the compiler image to the whole emitted system.
emit-image.ss now handles macros (defmacro -> bare expander fn + def-var! +
mark-macro!) and re-emits the clojure.core prelude (all tiers + stdlib) on Chez
via jolt-emit-prelude; driver's emit-image-on-chez takes an emit-fn arg.

The prelude converges at pstage3==pstage4 (one stage later than the compiler's
stage2==stage3) because macro expanders bake an auto-gensym id at emit time, so a
Janet-emitted macro carries a different id than a Chez-emitted one — only once
both stages load a Chez-emitted prelude does it stabilize.

fixpoint-test now proves: compiler stage2==stage3, prelude pstage3==pstage4, and
the fully Chez-emitted system (Chez prelude + Chez image, no Janet artifact in the
loop) compiles+runs real cases. 10/10.
This commit is contained in:
Yogthos 2026-06-20 05:21:23 -04:00
parent 509c23f06d
commit 81e587b2d7
3 changed files with 176 additions and 89 deletions

View file

@ -374,9 +374,11 @@
(defn program-emit-image
"A Chez program that loads the zero-Janet runtime + the compiler `image-path`,
then re-emits the compiler image ON CHEZ (jolt-emit-image) and writes it to
`out-path`. Running this with image = stageN produces stage(N+1)."
[prelude-path image-path out-path]
then re-emits the compiler image (or, with emit-fn \"jolt-emit-prelude\", the
clojure.core prelude) ON CHEZ and writes it to `out-path`. Running this with
image = stageN produces stage(N+1)."
[prelude-path image-path out-path &opt emit-fn]
(default emit-fn "jolt-emit-image")
(string
"(import (chezscheme))\n"
"(load \"host/chez/rt.ss\")\n"
@ -389,15 +391,16 @@
"(load \"host/chez/compile-eval.ss\")\n"
"(load \"host/chez/emit-image.ss\")\n"
"(let ((p (open-output-file " (string/format "%j" out-path) " 'replace)))\n"
" (put-string p (jolt-emit-image)) (close-port p))\n"))
" (put-string p (" emit-fn ")) (close-port p))\n"))
(defn emit-image-on-chez
"Re-emit the compiler image on Chez: load `image-path` (stageN) and write the
re-emitted image (stage N+1) to `out-path`. Each runs in a fresh chez process so
gensym/state start clean (essential for a byte-stable fixpoint). Returns
gensym/state start clean (essential for a byte-stable fixpoint). emit-fn selects
jolt-emit-image (the compiler) or jolt-emit-prelude (clojure.core). Returns
[code stderr]."
[prelude-path image-path out-path]
(def prog (program-emit-image prelude-path image-path out-path))
[prelude-path image-path out-path &opt emit-fn]
(def prog (program-emit-image prelude-path image-path out-path emit-fn))
(def path (string "/tmp/jolt-emit-image-" (os/getpid) "-" (hash out-path) ".ss"))
(spit path prog)
(def proc (os/spawn ["chez" "--script" path] :p {:out :pipe :err :pipe}))