core: spec 35-var batch A — 1.11 parsers, map/partition variants, with-redefs, ns fns

Fifteen vars from the spec coverage gap (docs/spec/coverage.md):
parse-long/parse-double/parse-boolean (strict validation; scan-number alone
accepts 0x10), newline, current-time-ms (host clock for time), update-keys/
update-vals (PHM base, collisions last-wins), partitionv/partitionv-all/
splitv-at (lazy seqs of vectors; splitv-at's tail stays a seq, matching the
reference), with-redefs/with-redefs-fn (roots restored on throw), time,
macroexpand (expand-1 to fixpoint), alias/ns-unalias (write BOTH alias stores
— require :as uses string-keyed :imports while ns-aliases reads :aliases;
split filed), ns-publics (symbol-keyed map; publics == interns, no privacy).

Three pre-existing bugs fixed along the way:
- (partition n step pad coll) misparsed pad as the coll and returned ()
- (require 'bare.symbol) rejected — only vector specs were accepted
- analyze-form leaked the interpreted analyzer's ns on a punt: a throw out of
  the analyzer left current-ns=jolt.analyzer and :compile-ns set, so the
  fallback interpretation resolved user vars against the wrong namespace
  (bit (var user-sym) under compile mode)

And one overlay-authoring landmine documented in-code: a 20-coll fn must not
use 30-macros macros (with-redefs-fn's dotimes compiled as a forward ref that
resolved to the macro fn at runtime) — loop/recur instead.

Gate: conformance 316x3 (+14 rows), suite 4324 pass / 78 clean (was 4081/72;
parse_*/update_* files now contribute), baselines raised, all specs+unit,
fixpoint, self-host, sci, staged. Coverage: missing-portable 35 -> 20.
This commit is contained in:
Yogthos 2026-06-10 11:16:54 -04:00
parent 894af34b4c
commit eb7a9f1b20
13 changed files with 277 additions and 44 deletions

View file

@ -134,3 +134,26 @@
["rand n in [0,n)" "true" "(let [r (rand 10)] (and (>= r 0) (< r 10)))"]
["rand-nth member" "true" "(contains? #{:a :b :c} (rand-nth [:a :b :c]))"]
["rand-nth single" ":x" "(rand-nth [:x])"])
# Clojure 1.11 string->scalar parsers: nil on malformed, throw on non-string.
(defspec "numbers / parse fns (1.11)"
["parse-long" "42" "(parse-long \"42\")"]
["parse-long negative" "-7" "(parse-long \"-7\")"]
["parse-long plus" "7" "(parse-long \"+7\")"]
["parse-long float nil" "nil" "(parse-long \"1.5\")"]
["parse-long hex nil" "nil" "(parse-long \"0x10\")"]
["parse-long empty nil" "nil" "(parse-long \"\")"]
["parse-long junk nil" "nil" "(parse-long \"12ab\")"]
["parse-long throws" :throws "(parse-long 42)"]
["parse-double" "1.5" "(parse-double \"1.5\")"]
["parse-double int" "4.0" "(parse-double \"4\")"]
["parse-double sci" "1500.0" "(parse-double \"1.5e3\")"]
["parse-double neg" "-0.5" "(parse-double \"-0.5\")"]
["parse-double junk" "nil" "(parse-double \"abc\")"]
["parse-double trail" "nil" "(parse-double \"1.5x\")"]
["parse-double throws" :throws "(parse-double :k)"]
["parse-boolean true" "true" "(parse-boolean \"true\")"]
["parse-boolean false" "false" "(parse-boolean \"false\")"]
["parse-boolean case" "nil" "(parse-boolean \"True\")"]
["parse-boolean junk" "nil" "(parse-boolean \"yes\")"]
["parse-boolean throws" :throws "(parse-boolean true)"])