core: Phase 4 — move atom peripheral ops to the overlay over a host primitive
First host-primitive batch. Adds jolt.host/ref-put! — the minimal mutation kernel (set/remove a key on a mutable reference cell) the overlay can't express over core fns — and moves seven atom ops out of the seed: swap-vals!/reset-vals!/compare-and-set! compose the native swap!/reset!/deref (which already validate and notify watches); get-validator is a slot read; add-watch/remove-watch/set-validator! mutate the atom (or its watches table) via ref-put!. atom/swap!/reset!/deref and atom-validate/atom-notify-watches stay native — the compiler depends on them and they're hot. compare-and-set! keeps value-equality semantics, matching the prior Janet behavior. Covered by the existing state spec.
This commit is contained in:
parent
f410bec2ec
commit
4d5aa8c903
3 changed files with 32 additions and 47 deletions
|
|
@ -265,3 +265,24 @@
|
|||
(defn record? [x] (some? (get x :jolt/deftype)))
|
||||
;; Jolt has no chunked seqs (Phase 5 territory), so this is always false.
|
||||
(defn chunked-seq? [x] false)
|
||||
|
||||
;; Atom peripheral operations. atom/swap!/reset!/deref stay native — the compiler
|
||||
;; depends on them and they're hot. swap-vals!/reset-vals!/compare-and-set! compose
|
||||
;; the native ops (which already validate and notify watches); get-validator reads a
|
||||
;; slot; add-watch/remove-watch/set-validator! mutate the atom (or its watches
|
||||
;; sub-table) through the one host primitive jolt.host/ref-put! — the minimal
|
||||
;; mutation kernel the overlay can't express over core fns (a nil value removes the
|
||||
;; key). compare-and-set! compares by value, matching the prior Janet behavior.
|
||||
(defn swap-vals! [a f & args]
|
||||
(let [old (deref a)] [old (apply swap! a f args)]))
|
||||
(defn reset-vals! [a newval]
|
||||
(let [old (deref a)] (reset! a newval) [old newval]))
|
||||
(defn compare-and-set! [a oldval newval]
|
||||
(if (= oldval (deref a)) (do (reset! a newval) true) false))
|
||||
(defn get-validator [a] (get a :validator))
|
||||
(defn add-watch [a key f]
|
||||
(jolt.host/ref-put! (get a :watches) key f) a)
|
||||
(defn remove-watch [a key]
|
||||
(jolt.host/ref-put! (get a :watches) key nil) a)
|
||||
(defn set-validator! [a f]
|
||||
(jolt.host/ref-put! a :validator f) nil)
|
||||
|
|
|
|||
|
|
@ -1975,46 +1975,10 @@
|
|||
(atom-notify-watches atm old-val new-val)
|
||||
new-val)
|
||||
|
||||
(defn core-reset-vals! [atm val]
|
||||
(let [old-val (atm :value)]
|
||||
(atom-validate atm val)
|
||||
(put atm :value val)
|
||||
(atom-notify-watches atm old-val val)
|
||||
[old-val val]))
|
||||
|
||||
(defn core-swap-vals! [atm f & args]
|
||||
(var old-val (atm :value))
|
||||
(var new-val (apply f old-val args))
|
||||
(atom-validate atm new-val)
|
||||
(put atm :value new-val)
|
||||
(atom-notify-watches atm old-val new-val)
|
||||
[old-val new-val])
|
||||
|
||||
(defn core-compare-and-set! [atm old-val new-val]
|
||||
(if (= old-val (atm :value))
|
||||
(do
|
||||
(atom-validate atm new-val)
|
||||
(put atm :value new-val)
|
||||
(atom-notify-watches atm old-val new-val)
|
||||
true)
|
||||
false))
|
||||
|
||||
(defn core-set-validator! [atm validator-fn]
|
||||
(put atm :validator validator-fn)
|
||||
nil)
|
||||
|
||||
(defn core-get-validator [atm]
|
||||
(atm :validator))
|
||||
|
||||
(defn core-add-watch [atm key watch-fn]
|
||||
(let [watches (atm :watches)]
|
||||
(put watches key watch-fn)
|
||||
atm))
|
||||
|
||||
(defn core-remove-watch [atm key]
|
||||
(let [watches (atm :watches)]
|
||||
(put watches key nil)
|
||||
atm))
|
||||
# Atom peripheral ops (swap-vals!/reset-vals!/compare-and-set!/get-validator/
|
||||
# add-watch/remove-watch/set-validator!) now live in the Clojure collection tier —
|
||||
# composed over the native atom ops + jolt.host/ref-put!. atom/swap!/reset!/deref
|
||||
# and the atom-validate/atom-notify-watches helpers stay native (compiler-critical).
|
||||
|
||||
# ============================================================
|
||||
# Threading macros (as regular functions? No, as macros in Clojure)
|
||||
|
|
@ -3038,13 +3002,6 @@
|
|||
"deref" core-deref
|
||||
"reset!" core-reset!
|
||||
"swap!" core-swap!
|
||||
"swap-vals!" core-swap-vals!
|
||||
"reset-vals!" core-reset-vals!
|
||||
"compare-and-set!" core-compare-and-set!
|
||||
"set-validator!" core-set-validator!
|
||||
"get-validator" core-get-validator
|
||||
"add-watch" core-add-watch
|
||||
"remove-watch" core-remove-watch
|
||||
"not" core-not
|
||||
"derive" core-derive
|
||||
"isa?" core-isa?
|
||||
|
|
|
|||
|
|
@ -148,8 +148,15 @@
|
|||
(defn h-syntax-quote-lower [ctx inner]
|
||||
(syntax-quote-lower ctx inner))
|
||||
|
||||
# Runtime host primitive: set a key on a mutable reference cell (an atom, the
|
||||
# watches sub-table, ...). The minimal mutation kernel the overlay can't express
|
||||
# over core fns — putting nil removes the key (Janet table semantics). Returns the
|
||||
# table so callers can thread; overlay wrappers return the Clojure-meaningful value.
|
||||
(defn h-ref-put! [tab key val] (put tab key val) tab)
|
||||
|
||||
(def- exports
|
||||
{"form-sym?" h-sym? "form-sym-name" h-sym-name "form-sym-ns" h-sym-ns
|
||||
"ref-put!" h-ref-put!
|
||||
"form-sym-meta" h-sym-meta
|
||||
"form-list?" h-list? "form-vec?" h-vector? "form-map?" h-map?
|
||||
"form-set?" h-set? "form-char?" h-char? "form-literal?" h-literal?
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue