diff --git a/host/chez/dynamic-vars.ss b/host/chez/dynamic-vars.ss new file mode 100644 index 0000000..5d5b403 --- /dev/null +++ b/host/chez/dynamic-vars.ss @@ -0,0 +1,16 @@ +;; dynamic vars (jolt-9ls5) — the handful of clojure.core dynamic vars the seed +;; binds natively (src/jolt/core.janet) that aren't emitted into the prelude, so +;; they var-deref to nil on Chez. These two are plain constants; *ns* (a namespace +;; object) needs a value type with get-see-through and map?=false and is tracked +;; separately. Loaded from rt.ss after the value model + def-var!. + +;; *clojure-version* — a jolt map {:major 1 :minor 11 :incremental 0 :qualifier nil} +;; (jolt is all-flonum, so the numbers are flonums). +(def-var! "clojure.core" "*clojure-version*" + (jolt-hash-map (keyword #f "major") 1.0 + (keyword #f "minor") 11.0 + (keyword #f "incremental") 0.0 + (keyword #f "qualifier") jolt-nil)) + +;; *unchecked-math* — jolt does no unchecked-math elision; the var reads false. +(def-var! "clojure.core" "*unchecked-math*" #f) diff --git a/host/chez/rt.ss b/host/chez/rt.ss index 2ac7202..f83ad34 100644 --- a/host/chez/rt.ss +++ b/host/chez/rt.ss @@ -170,3 +170,7 @@ ;; (seq.ss), jolt=/key-hash/jolt-hash-map (collections.ss), jolt-atom? (atoms.ss), ;; jolt-pr-str (above), and the var-cell machinery — so loaded last. (load "host/chez/multimethods.ss") + +;; dynamic vars (jolt-9ls5): *clojure-version* / *unchecked-math* constants the seed +;; binds natively. After collections.ss (jolt-hash-map) + def-var!. +(load "host/chez/dynamic-vars.ss") diff --git a/test/chez/README.md b/test/chez/README.md index cdda186..8d4bfeb 100644 --- a/test/chez/README.md +++ b/test/chez/README.md @@ -185,6 +185,11 @@ class names, eval-order, with-open — all deferred Phase-2 / dynamic-var gaps). procedure. Transparent for procedures; the hot self-recursive call is a `:local` known-proc, so it stays direct. (Class-based dispatch — `(class x)`/`String` — is deferred; it needs the deftype/class subsystem.) +- inc 3r dynamic-var constants (jolt-9ls5): `host/chez/dynamic-vars.ss` binds the seed + natives `*clojure-version*` (the `{:major 1 :minor 11 …}` map) and `*unchecked-math*` + (false), removing their two parity allowlist entries. `*ns*` is deferred (jolt-b4kl): + it needs a namespace value that is not a map (`map?` false) yet answers + `(get ns :name)` for the overlay `ns-name`, plus `str`/`find-ns` support. The remaining buckets are the punch-list the next increments chase: ~361 emit-fail (genuine host interop — qualified Java/Janet refs, runtime `defmacro`/`eval`, out of diff --git a/test/chez/emit-test.janet b/test/chez/emit-test.janet index 655e331..62649a2 100644 --- a/test/chez/emit-test.janet +++ b/test/chez/emit-test.janet @@ -609,6 +609,18 @@ (let [[code out err] (run-jolt-chez "(do (defmulti f identity) (defmethod f 1 [_] \"one\") (f 99))")] (ok "multimethod: no match throws" (not= code 0) (string "code=" code)))) +# 3w) dynamic-var constants (jolt-9ls5): *clojure-version* (a map) and +# *unchecked-math* (false) are seed natives, def-var!'d by host/chez/dynamic-vars.ss. +# (*ns* needs a namespace value with get-see-through and map?=false — deferred.) +# (map? *clojure-version*) is intentionally NOT asserted: the seed stores it as a +# mutable table, so its map? is false (a seed quirk); Chez models it as a real map +# (map? true). Not a corpus contract, so the divergence is moot. +(each src ["(= 1 (:major *clojure-version*))" "(= 11 (:minor *clojure-version*))" + "(= false *unchecked-math*)"] + (let [[code out err] (run-prelude src) want (cli-oracle src)] + (ok (string "dynvar: " src) (and (= code 0) (= out want)) + (string "chez=" out " janet=" want " | " err)))) + # 4) perf signal: emitted fib(30) in-Scheme timing (excludes Chez startup), to # track against the spike ceiling (hand-Scheme fib ~5ms). Informational — the # jolt-truthy? wrapper (~3x) and flonum modeling are known Phase-4 levers. diff --git a/test/chez/run-corpus-prelude.janet b/test/chez/run-corpus-prelude.janet index 489c41b..e6fe019 100644 --- a/test/chez/run-corpus-prelude.janet +++ b/test/chez/run-corpus-prelude.janet @@ -53,8 +53,7 @@ "str of *ns*" true "*ns* user" true "str of a var" true - "*clojure-version* major" true - "*unchecked-math*" true + # *clojure-version* / *unchecked-math* now bound by dynamic-vars.ss (inc 3r) # (str [##Inf]) wants "[Infinity]" but the Chez -e printer (jolt-pr-str, which # str falls back to for collections) renders inf as "inf" — str needs a # recursive long-form renderer, the Phase-2 canonical printer. Top-level @@ -137,8 +136,9 @@ # Full-corpus baseline: inc 3j 1220/2497; 3k (converters) 1326; 3l (transients) # 1382; 3m (numeric-edge emit + variadic assoc!) 1407; 3n (seq-native shims + # reduced) 1467; 3o (transducer arities) 1493; 3p (misc seq/regex gaps) 1506; -# 3q (multimethod dispatch + late-bind) 1530. Strided runs scale down. -(def base-floor (scan-number (or (os/getenv "JOLT_CHEZ_PRELUDE_FLOOR") "1530"))) +# 3q (multimethod dispatch + late-bind) 1530; 3r (dynamic-var constants) 1532. +# Strided runs scale down. +(def base-floor (scan-number (or (os/getenv "JOLT_CHEZ_PRELUDE_FLOOR") "1532"))) (def floor (if (os/getenv "JOLT_CORPUS_LIMIT") 0 base-floor)) (when (or (> (length diverged) 0) (< pass floor)) (printf "REGRESSION: pass %d < floor %d or %d new divergence(s)" pass floor (length diverged)))