Chez: runtime eval / load-string / defmacro on the zero-Janet spine

The compiler image is already resident at runtime on the Chez spine, so eval
and load-string are just wiring: make them clojure.core functions instead of
analyzer special forms.

- eval / load-string are now functions, not special forms. Dropped "eval" from
  the host-contract special-symbol lists so it resolves as an ordinary var, and
  def-var! both in compile-eval.ss. eval takes an already-read form (e.g. from
  quote/list) and compiles+evals it in the current ns; load-string reads every
  form from a source string and evals each, returning the last.
- Runtime defmacro: jolt-compile-eval-form intercepts a (defmacro ...) form
  before analysis, defs the expander fn + mark-macro!s the var, exactly as
  emit-image.ss does at build time. The two helpers (macro-form? / defmacro->fn)
  move to compile-eval.ss and emit-image.ss reuses them.
- Top-level (do ...) is now unrolled form-by-form, like Clojure, so a defmacro
  or def in an earlier subform is visible (macro flag set / var interned) before
  a later subform is analyzed. This is what makes multi-form -e with a macro work.

Seed is byte-identical (no source references eval), so no re-mint; bootstrap-test
still passes. Zero-Janet corpus 2534 -> 2544 (eval/load-string cases now run),
0 new divergences; floor raised. Prelude corpus, JVM cert, full Janet gate green.

jolt-r8ku
This commit is contained in:
Yogthos 2026-06-20 12:14:08 -04:00
parent a8b61283b3
commit a23095b502
5 changed files with 112 additions and 41 deletions

View file

@ -105,9 +105,12 @@
;; --- special forms ----------------------------------------------------------
;; Mirrors host_iface special-names + interop-head? — forms the analyzer marks
;; uncompilable (the handled specials are dispatched in analyze-list BEFORE this).
;; `eval` is NOT here: it is a clojure.core FUNCTION on the spine (compile-eval.ss
;; def-var!s it), so it must resolve as an ordinary var, not punt (jolt-r8ku).
;; `defmacro` stays special — the spine intercepts it before analysis.
(define hc-special-names
'("quote" "syntax-quote" "unquote" "unquote-splicing" "do" "if" "def"
"defmacro" "fn*" "let*" "loop*" "recur" "throw" "try" "set!" "eval" "new"
"defmacro" "fn*" "let*" "loop*" "recur" "throw" "try" "set!" "new"
"." "gen-class" "monitor-enter" "monitor-exit" "letfn"))
(define (hc-interop-head? name)
(let ((n (string-length name)))
@ -180,7 +183,7 @@
;; clojure.core / the compile ns; a foo# auto-gensym is stable within one `.
(define hc-special-symbols
'("quote" "syntax-quote" "unquote" "unquote-splicing" "do" "if" "def"
"defmacro" "fn*" "let*" "loop*" "recur" "throw" "try" "set!" "var" "eval"
"defmacro" "fn*" "let*" "loop*" "recur" "throw" "try" "set!" "var"
"new" "."))
(define (hc-special-symbol? nm) (and (member nm hc-special-symbols) #t))