jolt/host/chez/atoms.ss
Yogthos 0c9c7931fe Chez Phase 1 (increment 3j): assemble the clojure.core prelude, -e-capable jolt-chez
Emit every non-macro clojure.core form through the live analyzer -> Chez emit
pipeline as a def-var! prelude (prelude mode, tier dependency order), load it
before a user expression, and you get an -e-capable jolt-chez: analysis on Janet,
execution on Chez. driver/emit-core-prelude assembles it (each form behind a
silent load guard so the Phase-2 multimethod forms don't break the rest);
bin/jolt-chez is the -e CLI, caching the prelude on disk keyed by source hash.

run-corpus-prelude.janet is the full parity gate this opens, the prelude-backed
sibling of run-corpus-chez. First baseline: 1220/2497 evaluated cases pass, 0 new
divergences (10 allowlisted: dynamic vars, class names, eval-order — deferred
Phase 2). The rest is the punch-list: ~360 emit-fail (real host interop, out of
the analyzer subset) and ~900 runtime crashes, mostly core fns calling
host-coupled seed natives with no Chez shim yet (str/format/vec, transients).
Follow-ups jolt-t6cr/kl2l/q3w8/9ls5.

Two shims landed to get the prelude to load and run. atoms.ss: atom/deref/swap!/
reset! (+ the compare/vals kernel) — needed at load time for
global-hierarchy = (atom (make-hierarchy)). predicates.ss: the type predicates +
name/namespace/boolean the overlay assumes are seed natives, matching the seed's
strict semantics. post-prelude.ss re-asserts char?/atom? after the prelude: the
overlay implements those by reading :jolt/type, which is false for Chez-native
chars/atoms, so its def-var! would clobber the correct native versions.

Per-case Scheme files are PID-unique so a foreground -e never reads a half-written
file while the gate runs.
2026-06-17 20:50:42 -04:00

57 lines
2.3 KiB
Scheme

;; atoms (jolt-9ziu) — host-coupled mutable reference cells for the Chez host.
;;
;; atom/deref/swap!/reset! stay in the Janet seed (not the clojure.core overlay),
;; so the Chez runtime needs native shims, def-var!'d into clojure.core. They
;; lower to var-deref in prelude mode. The hierarchy machinery
;; (global-hierarchy = (atom (make-hierarchy))) calls `atom` at the prelude's
;; LOAD time, so without this shim the whole prelude fails to load.
;;
;; compare-and-set!/swap-vals!/reset-vals! are overlay fns over the native kernel
;; in the live system; provided here natively too so the Chez host is
;; self-sufficient for atoms without the full prelude (the overlay versions, when
;; the full prelude loads, override these but compose the same native kernel).
(define-record-type jolt-atom (fields (mutable val)) (nongenerative jolt-atom-v1))
;; (atom init) — extra :meta/:validator opts are accepted and ignored for now
;; (watches/validators are overlay features layered via jolt.host/ref-put!).
(define (jolt-atom-new v . _opts) (make-jolt-atom v))
(define (jolt-deref x)
(if (jolt-atom? x)
(jolt-atom-val x)
(error #f "deref: unsupported reference type" x)))
;; (swap! a f arg*) -> (reset! a (f @a arg*)); f is invoked through jolt-invoke
;; (a jolt fn value, keyword, or invokable collection).
(define (jolt-swap! a f . args)
(let ((nv (apply jolt-invoke f (jolt-atom-val a) args)))
(jolt-atom-val-set! a nv)
nv))
(define (jolt-reset! a v) (jolt-atom-val-set! a v) v)
(define (jolt-compare-and-set! a oldv newv)
(if (jolt= (jolt-atom-val a) oldv)
(begin (jolt-atom-val-set! a newv) #t)
#f))
(define (jolt-swap-vals! a f . args)
(let* ((old (jolt-atom-val a))
(nv (apply jolt-invoke f old args)))
(jolt-atom-val-set! a nv)
(jolt-vector old nv)))
(define (jolt-reset-vals! a v)
(let ((old (jolt-atom-val a)))
(jolt-atom-val-set! a v)
(jolt-vector old v)))
(def-var! "clojure.core" "atom" jolt-atom-new)
(def-var! "clojure.core" "deref" jolt-deref)
(def-var! "clojure.core" "swap!" jolt-swap!)
(def-var! "clojure.core" "reset!" jolt-reset!)
(def-var! "clojure.core" "compare-and-set!" jolt-compare-and-set!)
(def-var! "clojure.core" "swap-vals!" jolt-swap-vals!)
(def-var! "clojure.core" "reset-vals!" jolt-reset-vals!)
(def-var! "clojure.core" "atom?" jolt-atom?)