core: start moving clojure.core to Clojure (overlay loaded at init)

Phase 4 kernel-shrink seam. jolt-core/clojure/core.clj holds the Clojure portion
of clojure.core; api/init loads it into the clojure.core namespace after
init-core! interns the Janet primitives, routed through eval-toplevel so it
compiles via the self-hosted pipeline (or interprets when :compile? is off).

First three fns moved off the Janet side: ffirst, fnext, nnext (leaf, no internal
callers). Same results compiled or interpreted; full suite green; battery holds
3913.
This commit is contained in:
Yogthos 2026-06-06 11:45:31 -04:00
parent 984af02532
commit 30a308f3ef
4 changed files with 43 additions and 6 deletions

View file

@ -0,0 +1,12 @@
;; The Clojure portion of clojure.core. Loaded into the clojure.core namespace at
;; init (api/init), AFTER the Janet primitives are interned by core/init-core!,
;; and compiled by the self-hosted pipeline (analyzer -> IR -> Janet back end).
;;
;; This is the Phase 4 kernel-shrink seam: fns expressible in plain Clojure on top
;; 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
;; already interned by init-core! (and on other overlay fns defined above it).
(defn ffirst [coll] (first (first coll)))
(defn fnext [coll] (first (next coll)))
(defn nnext [coll] (next (next coll)))

View file

@ -27,6 +27,21 @@
x)) x))
(defn- load-core-overlay!
"Load the Clojure portion of clojure.core (embedded jolt-core/clojure/core.clj)
into the clojure.core namespace, routed through eval-toplevel like any other
source (compiled when :compile?, interpreted otherwise)."
[ctx]
(when-let [src (get stdlib-embed/sources "clojure.core")]
(def saved (ctx-current-ns ctx))
(ctx-set-current-ns ctx "clojure.core")
(var s src)
(while (> (length (string/trim s)) 0)
(def [form rest] (parse-next s))
(set s rest)
(when (not (nil? form)) (eval-toplevel ctx form)))
(ctx-set-current-ns ctx saved)))
(defn init (defn init
"Create a new Jolt evaluation context. "Create a new Jolt evaluation context.
opts may contain: opts may contain:
@ -57,6 +72,11 @@
(install-async! ctx) (install-async! ctx)
# Host contract (ns jolt.host): the seam the portable jolt-core compiler calls. # Host contract (ns jolt.host): the seam the portable jolt-core compiler calls.
(host/install! ctx) (host/install! ctx)
# Clojure portion of clojure.core (jolt-core/clojure/core.clj): fns expressed
# in plain Clojure on top of the Janet primitives interned above. Loaded into
# clojure.core and compiled by the self-hosted pipeline (or interpreted when
# :compile? is off). Phase 4 kernel-shrink seam — see that file.
(load-core-overlay! ctx)
ctx)) ctx))
(defn eval-one (defn eval-one

View file

@ -940,10 +940,8 @@
(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)))
(defn core-ffirst [coll] (core-first (core-first coll)))
(defn core-nfirst [coll] (core-next (core-first coll))) (defn core-nfirst [coll] (core-next (core-first coll)))
(defn core-fnext [coll] (core-first (core-next coll))) # ffirst / fnext / nnext now live in the Clojure overlay (jolt-core/clojure/core.clj).
(defn core-nnext [coll] (core-next (core-next coll)))
(defn core-last [coll] (defn core-last [coll]
(let [c (realize-for-iteration coll)] (let [c (realize-for-iteration coll)]
@ -3809,10 +3807,7 @@
"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
"ffirst" core-ffirst
"nfirst" core-nfirst "nfirst" core-nfirst
"fnext" core-fnext
"nnext" core-nnext
"last" core-last "last" core-last
"drop-last" core-drop-last "drop-last" core-drop-last
"take-last" core-take-last "take-last" core-take-last

View file

@ -74,4 +74,14 @@
(eval-one ctx (parse-string "(+ 1 2)")) (eval-one ctx (parse-string "(+ 1 2)"))
(assert (zero? (length ((ctx-find-ns ctx "jolt.analyzer") :mappings))) "analyzer NOT loaded when interpreting")) (assert (zero? (length ((ctx-find-ns ctx "jolt.analyzer") :mappings))) "analyzer NOT loaded when interpreting"))
# clojure.core overlay: fns moved from core.janet to jolt-core/clojure/core.clj
# load into clojure.core at init and work the same compiled or interpreted.
(print "clojure.core overlay (Clojure-defined core fns)...")
(each opts [{:compile? true} {}]
(let [ctx (init opts)]
(defn ev [s] (normalize-pvecs (eval-one ctx (parse-string s))))
(assert (= 1 (ev "(ffirst [[1 2] [3 4]])")) "ffirst")
(assert (= 2 (ev "(fnext [1 2 3])")) "fnext")
(assert (= [3 4] (ev "(nnext [1 2 3 4])")) "nnext")))
(print "self-host pipeline passed!") (print "self-host pipeline passed!")