core: the last seven missing-portable vars — coverage gap closed (jolt-brh)

The dashboard's missing-portable category is now EMPTY (was 35 when the issue
was filed; this session's io/leaf work had already landed most of them).
The final seven:

- extenders — ctx-capturing clojure.core fn over the protocol type-registry:
  the type-tags implementing a protocol, as symbols; nil when none
- find-keyword — keyword: jolt keywords have no intern table, so it always
  finds (babashka makes the same call)
- inst-ms* — the raw Inst method; one inst representation, so = inst-ms
- read+string — over the 50-io readers, which now expose :buf and :fill-fn;
  returns [form exact-text-consumed], EOF throws or yields [eof-value ""]
  with the 3-arity, works for string AND stdin readers
- with-local-vars — fresh free-standing var cells (__local-var seam) bound as
  locals; var-get/var-set work on any cell
- with-open — canonical recursive expansion closing through the __close seam:
  a map-like value's :close fn or a host file (no .close interop here);
  nested closes run inner-first, finally runs on throw
- with-precision — body evaluates with precision/:rounding accepted and
  ignored (doubles, no BigDecimal context) — documented divergence

30 new spec rows (test/spec/missing-vars-spec.janet); coverage.md
regenerated: implemented+tested 426 -> 433, missing-portable 7 -> 0.
Gate: jpm exit 0, all tests passed.
This commit is contained in:
Yogthos 2026-06-10 17:22:28 -04:00
parent 3051f4264a
commit 6445f461bb
7 changed files with 167 additions and 26 deletions

View file

@ -809,3 +809,15 @@
(assoc m k (up (get m k) ks f args))
(assoc m k (apply f (get m k) args)))))]
(up m ks f args)))
;; --- jolt-brh: the last missing-portable vars --------------------------------
;; jolt keywords have no intern table (any keyword "exists"), so find-keyword
;; always finds — babashka makes the same call.
(defn find-keyword
([nm] (keyword nm))
([ns nm] (keyword ns nm)))
;; The raw Inst protocol method; jolt insts have one representation, so it is
;; inst-ms itself.
(defn inst-ms* [i] (inst-ms i))

View file

@ -73,6 +73,29 @@
[] (partition 2 bindings))]
`(with-redefs-fn (hash-map ~@pairs) (fn [] ~@body))))
;; Fresh free-standing var cells bound as locals; read/write with
;; var-get/var-set. The cells come from the host seam __local-var.
(defmacro with-local-vars [bindings & body]
(let [binds (reduce (fn [acc p] (conj (conj acc (first p)) `(__local-var ~(second p))))
[] (partition 2 bindings))]
`(let [~@binds] ~@body)))
;; Canonical recursive expansion; closing goes through the host seam __close
;; (a map-like value's :close fn or a host file — no .close interop here).
(defmacro with-open [bindings & body]
(if (zero? (count bindings))
`(do ~@body)
`(let [~(first bindings) ~(second bindings)]
(try
(with-open ~(vec (drop 2 bindings)) ~@body)
(finally (__close ~(first bindings)))))))
;; jolt numbers are doubles — there is no BigDecimal math context, so the
;; precision (and optional :rounding mode) is accepted and ignored.
(defmacro with-precision [precision & exprs]
(let [body (if (= :rounding (first exprs)) (drop 2 exprs) exprs)]
`(do ~@body)))
(defmacro with-bindings [binding-map & body]
`(with-bindings* ~binding-map (fn [] ~@body)))

View file

@ -19,7 +19,9 @@
"A reader over string s (the with-in-str expansion calls this)."
[s]
(let [buf (atom s)]
{:read-line-fn
{:buf buf
:fill-fn nil
:read-line-fn
(fn []
(let [cur @buf]
(when (pos? (count cur))
@ -40,7 +42,13 @@
(def ^:private stdin-buf (atom ""))
(def ^:dynamic *in*
{:read-line-fn
{:buf stdin-buf
:fill-fn (fn []
(let [line (__stdin-read-line)]
(if (nil? line)
false
(do (swap! stdin-buf (fn [b] (str b line "\n"))) true))))
:read-line-fn
(fn []
(let [cur @stdin-buf]
(if (pos? (count cur))
@ -87,6 +95,27 @@
`(binding [*in* (__string-reader ~s)]
~@body))
;; Like read, and also returns the exact text consumed for the form (leading
;; whitespace included). On EOF: throws, or returns [eof-value ""] when
;; eof-error? is false.
(defn read+string
([] (read+string *in*))
([stream] (read+string stream true nil))
([stream eof-error? eof-value]
(let [buf (get stream :buf)
fill (get stream :fill-fn)]
(loop []
(let [s (deref buf)
r (__parse-next s)]
(if (nil? r)
(if (and fill (fill))
(recur)
(if eof-error?
(throw (ex-info "EOF while reading" {}))
[eof-value ""]))
(do (reset! buf (nth r 1))
[(nth r 0) (subs s 0 (- (count s) (count (nth r 1))))])))))))
(defn line-seq
"Returns the lines of text from rdr as a lazy sequence of strings, as by
read-line. (Jolt extension kept from the old kernel stub: a plain string