core: Stage 3 — leaf batch: complement/fnil/clojure-version/bigdec/numerator/denominator/supers/munge/test to the overlay
Nine more seed leaves move to 20-coll.clj (verified leaf-by-leaf: defn +
core-bindings entry only, no internal callers). fnil is upgraded to Clojure's
canonical 2/3/4-arity — it patches only the first 1-3 arguments; the old
kernel fn patched every position it had a default for, which Clojure does
not. The rest carry their kernel semantics over unchanged (bigdec is a
double, numerator/denominator throw, supers is #{}, munge rewrites dashes).
16 new spec rows incl. the fnil arity-contract cases. Gate green:
conformance 326x3, suite 4577, full jpm test (2:18 — first full run with the
ctx image cache on main).
This commit is contained in:
parent
ee6447adae
commit
3faee14271
4 changed files with 77 additions and 30 deletions
|
|
@ -592,3 +592,41 @@
|
|||
target (reduce (fn [t k] (nth t k)) arr (take (- n 2) idxs+val))]
|
||||
(jolt.host/ref-put! target (nth idxs+val (- n 2)) val)
|
||||
val))
|
||||
|
||||
;; --- Phase 2 leaf batch (jolt-ded): fn combinators + host-free stubs ---------
|
||||
|
||||
(defn complement
|
||||
"Takes a fn f and returns a fn that takes the same arguments as f, has the
|
||||
same effects, if any, and returns the opposite truth value."
|
||||
[f]
|
||||
(fn [& args] (not (apply f args))))
|
||||
|
||||
;; Canonical Clojure fnil: patches only the FIRST 1-3 arguments (the old Janet
|
||||
;; kernel patched every position it had a default for, which Clojure does not).
|
||||
(defn fnil
|
||||
([f x]
|
||||
(fn [a & args] (apply f (if (nil? a) x a) args)))
|
||||
([f x y]
|
||||
(fn [a b & args] (apply f (if (nil? a) x a) (if (nil? b) y b) args)))
|
||||
([f x y z]
|
||||
(fn [a b c & args]
|
||||
(apply f (if (nil? a) x a) (if (nil? b) y b) (if (nil? c) z c) args))))
|
||||
|
||||
(defn clojure-version [] "1.11.0-jolt")
|
||||
|
||||
;; Jolt numbers are doubles; no BigDecimal, no ratios.
|
||||
(defn bigdec [x] (* 1.0 x))
|
||||
(defn numerator [x] (throw (ex-info "numerator requires a ratio (Jolt has no ratios)" {})))
|
||||
(defn denominator [x] (throw (ex-info "denominator requires a ratio (Jolt has no ratios)" {})))
|
||||
|
||||
;; No class hierarchy on the Janet host.
|
||||
(defn supers [x] #{})
|
||||
|
||||
;; The kernel's munge only rewrote dashes; kept as-is for parity.
|
||||
(defn munge [s] (str-replace-all "-" "_" (str s)))
|
||||
|
||||
(defn test
|
||||
"Calls the :test fn from v's metadata; :ok if it runs, :no-test if absent."
|
||||
[v]
|
||||
(let [t (:test (meta v))]
|
||||
(if t (do (t) :ok) :no-test)))
|
||||
|
|
|
|||
|
|
@ -69,6 +69,17 @@ test, rather than preserving the bug.
|
|||
would recurse). GOTCHA for future attached-ops ports: inside the overlay,
|
||||
NEVER read your own wrapper's fields with `get`.
|
||||
|
||||
- **Leaf batch (jolt-ded)** — complement, fnil (canonical 2/3/4-arity: patch
|
||||
the first 1-3 args only, unlike the old patch-everything kernel fn),
|
||||
clojure-version, bigdec, numerator, denominator, supers, munge, test moved
|
||||
to 20-coll.clj.
|
||||
- ***in* reader family (jolt-0d9)** — *in*, read-line, read, with-in-str,
|
||||
line-seq in a new `50-io.clj` tier over two seed seams (__stdin-read-line,
|
||||
__parse-next). GOTCHAS: a map LITERAL with :jolt/type as a key parses as a
|
||||
tagged form (don't tag overlay value maps); a leftover seed stub holding the
|
||||
same name breaks direct-linked overlay self-recursion (line-seq bound to the
|
||||
stub's root and truncated after one element) — delete the stub first.
|
||||
|
||||
## MOVABLE candidates (Phase 2 worklist, 193)
|
||||
>Eduction NaN? abs aclone alength ancestors array-map array-seq assoc! associative? bean bigdec bigint biginteger boolean boolean? booleans byte bytes bytes? cat char char-escape-string char-name-string char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class clojure-version comparator compare-and-set! completing conj! counted? decimal? deliver denominator derive descendants destructure disj disj! dissoc! distinct? doall dorun double? doubles drop-last eduction empty ensure-reduced enumeration-seq ex-cause ex-data ex-info ex-info? ex-message find float? floats force halt-when hash-combine hash-map hash-ordered-coll hash-set hash-unordered-coll ident? ifn? indexed? infinite? inst-ms inst? integer? ints isa? iterator-seq key keyword keyword-identical? list* list? longs macrofy map-entry? memfn munge nat-int? neg-int? not-any? not-every? nthnext nthrest numerator numeric= object? parents persistent! pop pop! pos-int? pr prefers println-str prn-str promise qualified-ident? qualified-keyword? qualified-symbol? rand rand-nth random-sample ratio? rational? rationalize re-groups re-matcher record? reduce-kv reduced reduced? reductions replace replicate resolve reversible? rseq rsubseq run! seq-to-map-for-destructuring seque set set? short shorts shuffle simple-ident? simple-keyword? simple-symbol? some-search sort sort-by sorted-map sorted-map-by sorted-map? sorted-set sorted-set-by sorted-set? special-symbol? split-at split-with str-join str-replace-all str-replace-first str-split subseq supers symbol tagged-literal tagged-literal? take-last test transduce unchecked-add unchecked-byte unchecked-char unchecked-dec unchecked-divide-int unchecked-double unchecked-float unchecked-inc unchecked-int unchecked-multiply unchecked-negate unchecked-remainder-int unchecked-short unchecked-subtract undefined? underive uri? uuid? val vector volatile! volatile? xml-seq
|
||||
|
||||
|
|
|
|||
|
|
@ -1485,8 +1485,7 @@
|
|||
|
||||
(def core-constantly (fn [x] (fn [& _] x)))
|
||||
|
||||
(defn core-complement [f]
|
||||
(fn [& args] (not (apply f args))))
|
||||
# complement now lives in the Clojure collection tier (core/20-coll.clj).
|
||||
|
||||
# Jolt has no inst/uri/uuid host types, so these are always false; inst-ms has
|
||||
# nothing valid to read.
|
||||
|
|
@ -2034,7 +2033,7 @@
|
|||
# 64-bit integers (Janet int/s64 — C-backed)
|
||||
(defn core-bigint [x] (int/s64 x))
|
||||
(defn core-biginteger [x] (int/s64 x))
|
||||
(defn core-bigdec [x] (* 1.0 x)) # no BigDecimal; use a double
|
||||
# bigdec now lives in the Clojure collection tier (no BigDecimal: a double).
|
||||
|
||||
# Chunked seqs — Jolt does not chunk, so these are simple eager equivalents.
|
||||
(defn core-chunk-buffer [capacity] @[])
|
||||
|
|
@ -2060,19 +2059,15 @@
|
|||
# semantics) now live in the Clojure sorted tier (core/25-sorted.clj).
|
||||
(defn core-array-seq [arr & _] (core-seq arr))
|
||||
(defn core-seque [& args] (in args (- (length args) 1)))
|
||||
(defn core-supers [x] (make-phs))
|
||||
# supers now lives in the Clojure collection tier (no class hierarchy: #{}).
|
||||
(defn core-class [x]
|
||||
(cond
|
||||
(nil? x) nil (number? x) "java.lang.Number" (string? x) "java.lang.String"
|
||||
(boolean? x) "java.lang.Boolean" (keyword? x) "clojure.lang.Keyword"
|
||||
(function? x) "clojure.lang.IFn" (buffer? x) "[B"
|
||||
(string (type x))))
|
||||
(defn core-clojure-version [] "1.11.0-jolt")
|
||||
(defn core-munge [s]
|
||||
(string/replace-all "-" "_" (string s)))
|
||||
(defn core-test [v]
|
||||
(let [t (and (core-meta v) (get (core-meta v) :test))]
|
||||
(if t (do (t) :ok) :no-test)))
|
||||
# clojure-version / munge / test now live in the Clojure collection tier
|
||||
# (core/20-coll.clj).
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
|
@ -2375,15 +2370,8 @@
|
|||
(let [sub (core-get m k)]
|
||||
(core-assoc m k (apply core-update-in (if (nil? sub) {} sub) (ks-rest ks) f args))))))
|
||||
|
||||
(defn core-fnil [f & defaults]
|
||||
(fn [& args]
|
||||
(def new-args (array/slice args))
|
||||
(var i 0)
|
||||
(each d defaults
|
||||
(when (and (< i (length new-args)) (nil? (in new-args i)))
|
||||
(put new-args i d))
|
||||
(++ i))
|
||||
(apply f new-args)))
|
||||
# fnil now lives in the Clojure collection tier (core/20-coll.clj), with
|
||||
# Clojure's canonical 2/3/4-arity (patch the first 1-3 args only).
|
||||
|
||||
# copy-var stubs for sci.impl.copy-vars (used by sci.impl.namespaces)
|
||||
(defn core-copy-core-var [sym] nil)
|
||||
|
|
@ -2637,8 +2625,8 @@
|
|||
# ratio?/decimal?/rational? live in the Clojure collection tier (core/20-coll.clj).
|
||||
# Jolt has no ratio type, so numerator/denominator have no valid input (Clojure
|
||||
# requires a Ratio and throws otherwise).
|
||||
(defn core-numerator [x] (error "numerator requires a ratio (Jolt has no ratios)"))
|
||||
(defn core-denominator [x] (error "denominator requires a ratio (Jolt has no ratios)"))
|
||||
# numerator / denominator now live in the Clojure collection tier (Jolt has
|
||||
# no ratios; they throw, as on a non-ratio in Clojure).
|
||||
|
||||
(def- special-syms
|
||||
{"if" true "do" true "let*" true "fn*" true "quote" true "var" true "def" true
|
||||
|
|
@ -2914,8 +2902,6 @@
|
|||
"key" core-key
|
||||
"val" core-val
|
||||
"map-entry?" core-map-entry?
|
||||
"numerator" core-numerator
|
||||
"denominator" core-denominator
|
||||
"special-symbol?" core-special-symbol?
|
||||
"promise" core-promise
|
||||
"deliver" core-deliver
|
||||
|
|
@ -3005,7 +2991,6 @@
|
|||
"range" core-range
|
||||
"identity" core-identity
|
||||
"constantly" core-constantly
|
||||
"complement" core-complement
|
||||
"comp" core-comp
|
||||
"partial" core-partial
|
||||
"memoize" core-memoize
|
||||
|
|
@ -3085,7 +3070,6 @@
|
|||
"unchecked-double" core-unchecked-double
|
||||
"bigint" core-bigint
|
||||
"biginteger" core-biginteger
|
||||
"bigdec" core-bigdec
|
||||
"chunk-buffer" core-chunk-buffer
|
||||
"chunk-append" core-chunk-append
|
||||
"chunk" core-chunk
|
||||
|
|
@ -3099,11 +3083,7 @@
|
|||
"reader-conditional" core-reader-conditional
|
||||
"array-seq" core-array-seq
|
||||
"seque" core-seque
|
||||
"supers" core-supers
|
||||
"class" core-class
|
||||
"clojure-version" core-clojure-version
|
||||
"munge" core-munge
|
||||
"test" core-test
|
||||
"enumeration-seq" core-enumeration-seq
|
||||
"iterator-seq" core-iterator-seq
|
||||
"re-matcher" core-re-matcher
|
||||
|
|
@ -3173,7 +3153,6 @@
|
|||
"resolve" core-resolve
|
||||
"update-in" core-update-in
|
||||
"assoc-in" core-assoc-in
|
||||
"fnil" core-fnil
|
||||
"copy-core-var" core-copy-core-var
|
||||
"copy-var" core-copy-var
|
||||
"macrofy" core-macrofy
|
||||
|
|
|
|||
|
|
@ -35,3 +35,22 @@
|
|||
["some-fn" "true" "((some-fn even? neg?) 3 4)"]
|
||||
["memoize" "2" "(do (def c (atom 0)) (def f (memoize (fn [x] (swap! c inc) x))) (f 1) (f 1) (f 2) @c)"]
|
||||
["trampoline" "10" "(trampoline (fn f [n acc] (if (zero? n) acc (fn [] (f (dec n) (+ acc 2))))) 5 0)"])
|
||||
|
||||
# Phase 2 leaf batch (jolt-ded): moved from the Janet seed to 20-coll.clj.
|
||||
(defspec "clojure.core / leaf batch (complement fnil munge etc.)"
|
||||
["complement true" "true" "((complement pos?) -1)"]
|
||||
["complement false" "false" "((complement pos?) 1)"]
|
||||
["complement multi" "true" "((complement <) 3 2)"]
|
||||
["fnil patches nil" "1" "((fnil inc 0) nil)"]
|
||||
["fnil passes non-nil" "6" "((fnil inc 0) 5)"]
|
||||
["fnil two defaults" "8" "((fnil + 1 2) nil nil 5)"]
|
||||
["fnil only first 3" "[:a :b :c nil]" "((fnil vector :a :b :c) nil nil nil nil)"]
|
||||
["fnil in update" "{:k 1}" "(update {} :k (fnil inc 0))"]
|
||||
["clojure-version" "true" "(string? (clojure-version))"]
|
||||
["bigdec" "3" "(bigdec 3)"]
|
||||
["numerator throws" :throws "(numerator 1)"]
|
||||
["denominator throws" :throws "(denominator 1)"]
|
||||
["supers empty set" "#{}" "(supers 1)"]
|
||||
["munge dashes" "\"a_b\"" "(munge \"a-b\")"]
|
||||
["munge symbol" "\"x_y\"" "(munge (quote x-y))"]
|
||||
["test no-test" ":no-test" "(test (quote foo))"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue