core: move last/butlast to the Clojure overlay
Continue the kernel shrink. last/butlast become canonical Clojure defs (pure first/next/loop/recur) in the core.clj overlay, dropping two realize-for-iteration uses from the Janet kernel. second was the obvious next candidate but can't move: the self-hosted compiler front-end (analyzer.clj) calls it, and the compiler has to compile the overlay, so anything it uses must already exist as a Janet primitive. Documented that as a third clause of the safe-to-move rule. Suite green, clojure-test-suite battery holds 3913 pass / 58 clean, binary builds and runs the embedded overlay.
This commit is contained in:
parent
c8810ee4aa
commit
a6f0f8a6fe
2 changed files with 22 additions and 11 deletions
|
|
@ -6,8 +6,26 @@
|
||||||
;; of the remaining Janet primitives move here from core.janet, one at a time,
|
;; of the remaining Janet primitives move here from core.janet, one at a time,
|
||||||
;; each compiled by the prior stage. Anything here must depend only on core vars
|
;; each compiled by the prior stage. Anything here must depend only on core vars
|
||||||
;; already interned by init-core! (and on other overlay fns defined above it).
|
;; already interned by init-core! (and on other overlay fns defined above it).
|
||||||
|
;;
|
||||||
|
;; Safe-to-move rule: a fn can move here only if it is (1) NOT in
|
||||||
|
;; compiler/core-renames (that map emits core-X Janet symbols directly), (2) has
|
||||||
|
;; no internal Janet callers of its core-X binding, and (3) is NOT used by the
|
||||||
|
;; self-hosted compiler itself (jolt-core/jolt/*.clj) — the compiler has to
|
||||||
|
;; compile this overlay, so anything it calls must already exist as a Janet
|
||||||
|
;; primitive. (That last rule is why `second`, used by analyzer.clj, stays in
|
||||||
|
;; Janet even though it has no Janet callers.)
|
||||||
|
|
||||||
(defn ffirst [coll] (first (first coll)))
|
(defn ffirst [coll] (first (first coll)))
|
||||||
(defn nfirst [coll] (next (first coll)))
|
(defn nfirst [coll] (next (first coll)))
|
||||||
(defn fnext [coll] (first (next coll)))
|
(defn fnext [coll] (first (next coll)))
|
||||||
(defn nnext [coll] (next (next coll)))
|
(defn nnext [coll] (next (next coll)))
|
||||||
|
|
||||||
|
;; Canonical Clojure defs: pure first/next/loop/recur, no Janet realize-for-iteration.
|
||||||
|
(defn last [s]
|
||||||
|
(if (next s) (recur (next s)) (first s)))
|
||||||
|
|
||||||
|
(defn butlast [s]
|
||||||
|
(loop [ret [] s s]
|
||||||
|
(if (next s)
|
||||||
|
(recur (conj ret (first s)) (next s))
|
||||||
|
(seq ret))))
|
||||||
|
|
|
||||||
|
|
@ -940,11 +940,10 @@
|
||||||
(if (jvec? coll) (make-vec dropped) dropped))))))
|
(if (jvec? coll) (make-vec dropped) dropped))))))
|
||||||
|
|
||||||
(defn core-second [coll] (core-first (core-rest coll)))
|
(defn core-second [coll] (core-first (core-rest coll)))
|
||||||
# ffirst / nfirst / fnext / nnext now live in the Clojure overlay (jolt-core/clojure/core.clj).
|
# ffirst / nfirst / fnext / nnext / last / butlast now live in the Clojure overlay
|
||||||
|
# (jolt-core/clojure/core.clj). second stays here — the self-hosted compiler
|
||||||
(defn core-last [coll]
|
# (analyzer.clj) calls it, so it must exist as a Janet primitive before the
|
||||||
(let [c (realize-for-iteration coll)]
|
# overlay (which the compiler compiles) loads.
|
||||||
(if (= 0 (length c)) nil (in c (- (length c) 1)))))
|
|
||||||
|
|
||||||
(defn core-drop-last [a & rest]
|
(defn core-drop-last [a & rest]
|
||||||
(let [n (if (= 0 (length rest)) 1 a)
|
(let [n (if (= 0 (length rest)) 1 a)
|
||||||
|
|
@ -3098,10 +3097,6 @@
|
||||||
(when (not (number? n)) (error "nthnext requires a numeric count"))
|
(when (not (number? n)) (error "nthnext requires a numeric count"))
|
||||||
(let [r (core-nthrest coll n)] (if (or (nil? r) (= 0 (length r))) nil r)))
|
(let [r (core-nthrest coll n)] (if (or (nil? r) (= 0 (length r))) nil r)))
|
||||||
|
|
||||||
(defn core-butlast [coll]
|
|
||||||
(let [c (realize-for-iteration coll)]
|
|
||||||
(if (<= (length c) 1) nil (tuple/slice (tuple ;(array/slice c 0 (- (length c) 1)))))))
|
|
||||||
|
|
||||||
(defn core-filterv [pred coll]
|
(defn core-filterv [pred coll]
|
||||||
(def pred (as-fn pred))
|
(def pred (as-fn pred))
|
||||||
(let [r @[]] (each x (realize-for-iteration coll) (when (truthy? (pred x)) (array/push r x)))
|
(let [r @[]] (each x (realize-for-iteration coll) (when (truthy? (pred x)) (array/push r x)))
|
||||||
|
|
@ -3806,7 +3801,6 @@
|
||||||
"ex-cause" core-ex-cause
|
"ex-cause" core-ex-cause
|
||||||
"prefers" core-prefers
|
"prefers" core-prefers
|
||||||
"random-uuid" core-random-uuid
|
"random-uuid" core-random-uuid
|
||||||
"last" core-last
|
|
||||||
"drop-last" core-drop-last
|
"drop-last" core-drop-last
|
||||||
"take-last" core-take-last
|
"take-last" core-take-last
|
||||||
"interpose" core-interpose
|
"interpose" core-interpose
|
||||||
|
|
@ -3834,7 +3828,6 @@
|
||||||
"take-nth" core-take-nth
|
"take-nth" core-take-nth
|
||||||
"nthrest" core-nthrest
|
"nthrest" core-nthrest
|
||||||
"nthnext" core-nthnext
|
"nthnext" core-nthnext
|
||||||
"butlast" core-butlast
|
|
||||||
"filterv" core-filterv
|
"filterv" core-filterv
|
||||||
"mapv" core-mapv
|
"mapv" core-mapv
|
||||||
"empty" core-empty
|
"empty" core-empty
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue