jolt/test/chez/cli-test.janet
Yogthos a23095b502 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
2026-06-20 12:14:08 -04:00

60 lines
2.6 KiB
Text

# Chez Phase 3 inc9b (jolt-9phg) — the pure-Chez runtime CLI (no Janet).
#
# bin/joltc execs `chez --script host/chez/cli.ss`, which loads the checked-in
# bootstrap seed (host/chez/seed/) + the zero-Janet spine and compiles+evals a
# Clojure -e expression entirely on Chez. This test drives bin/joltc and checks
# results: with only Chez installed, jolt runs end to end — no Janet at build or
# run time. (This harness is Janet only to spawn the process; the compile+eval is
# 100% Chez.)
#
# janet test/chez/cli-test.janet
(import ../../host/chez/driver :as d)
(var total 0) (var fails 0)
(defn ok [name pred &opt extra]
(++ total)
(if pred (printf "ok: %s" name)
(do (++ fails) (printf "FAIL: %s %s" name (or extra "")))))
(unless (d/chez-available?)
(print "chez not on PATH — skipping cli-test")
(os/exit 0))
(defn- joltc [expr]
(def proc (os/spawn ["bin/joltc" "-e" expr] :p {:out :pipe :err :pipe}))
(def out (string/trim (string (:read (proc :out) :all))))
(def err (string/trim (string (or (:read (proc :err) :all) ""))))
(def code (os/proc-wait proc))
[code out err])
(def cases
[["(+ 1 2)" "3"]
["(defn fib [n] (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2))))) (fib 15)" "610"]
["(->> (range 10) (filter even?) (map #(* % %)) (reduce +))" "120"]
["(let [{:keys [a b] :or {b 99}} {:a 1}] [a b])" "[1 99]"]
["(require '[clojure.string :as s]) (s/upper-case \"hello\")" "HELLO"]
["(case 3 1 :a 2 :b :other)" ":other"]
["(reduce + (vals (reduce (fn [m k] (assoc m k (* k k))) {} [1 2 3])))" "14"]
["(map inc [1 2 3])" "(2 3 4)"]
["nil" ""]
# jolt-r8ku: runtime eval / load-string / defmacro on the Chez spine.
["(eval (quote (+ 1 2)))" "3"]
["(eval (list (quote +) 1 2 3))" "6"]
["(eval (quote (let [a 2 b 3] (* a b))))" "6"]
["(load-string \"(+ 1 2)\")" "3"]
["(load-string \"(def y 5) (* y y)\")" "25"]
["(load-string \"\")" ""]
["(map eval [(quote (+ 1 1)) (quote (* 3 3))])" "(2 9)"]
["(defmacro add1 [x] (list (quote +) x 1)) (add1 10)" "11"]
["(defmacro twice [x] `(do ~x ~x)) (twice (+ 2 3))" "5"]
["(defmacro m [x] `(+ ~x 1)) (m (m (m 0)))" "3"]])
(each [src want] cases
(def [code out err] (joltc src))
(ok (string "joltc: " (if (> (length src) 48) (string (string/slice src 0 48) "...") src))
(and (= code 0) (= out want))
(string "[" code "] got " (string/format "%j" out) " want " (string/format "%j" want)
(if (= "" err) "" (string " err: " (string/slice err 0 (min 120 (length err))))))))
(printf "\ncli-test: %d/%d checks passed" (- total fails) total)
(os/exit (if (zero? fails) 0 1))