Chez Phase 2 (inc Y): runtime data reader + clojure.edn (jolt-r8ku)
Chez-side recursive-descent Clojure reader (host/chez/reader.ss) producing the
same jolt forms the Janet reader yields, behind the read-string / __parse-next /
__read-tagged seams the seed registers in eval_runtime.janet. That lights up the
whole *in* read family — read, read+string, with-in-str (read) — plus read-string
and read-string metadata, none of which needed an analyzer change (read-string is
a clojure.core seam, jolt-nil on the prelude until now).
Reader output is pinned to the Janet reader's shapes: numbers coerce to flonum
(the all-double model emit-const uses, else a read int isn't = a source int),
sets read as the {:jolt/type :jolt/set :value [...]} FORM, #tag/#inst/#uuid/#regex
as tagged forms (no data reader applied — read-string never evaluates), ^meta on
a symbol, and the ' ` ~ ~@ @ reader macros. clojure.edn is added to the prelude
tier; its edn->value builds the real set/tagged values and __read-tagged reuses
the inc X #inst/#uuid constructors. The reader-arity edn/read stays a lazy gap
(drain-reader is Janet-coupled) — read-string is the live path.
eval / load-string / runtime defmacro are still out: they need the compiler at
runtime, which is Phase 3 (self-host). Chez-only change, no Janet gate.
Parity 2238 -> 2259, 0 new divergences. _reader 47/47; all chez unit tests green;
emit-test 331/331.
This commit is contained in:
parent
c70f3bae34
commit
6df60229b0
6 changed files with 484 additions and 4 deletions
95
test/chez/_reader.janet
Normal file
95
test/chez/_reader.janet
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
# jolt-r8ku (inc Y) — Chez-side Clojure data reader: read-string / read /
|
||||
# read+string / with-in-str / clojure.edn. The reader (host/chez/reader.ss)
|
||||
# produces the same jolt forms the Janet reader yields; the *in* family and
|
||||
# clojure.edn are Clojure over the read-string / __parse-next seams.
|
||||
#
|
||||
# Outputs are kept order-stable (equality checks, scalars) so set/map iteration
|
||||
# order — which legitimately differs from build/jolt — doesn't masquerade as a
|
||||
# divergence. Oracle = build/jolt.
|
||||
#
|
||||
# janet test/chez/_reader.janet
|
||||
(def jolt-bin (or (os/getenv "JOLT_BIN") "bin/jolt-chez"))
|
||||
|
||||
(def cases
|
||||
[# --- scalars + collections (value equality, order-independent) ---
|
||||
["(= 42 (read-string \"42\"))" "true"]
|
||||
["(= 42 (read-string \"0x2A\"))" "true"]
|
||||
["(= 0.5 (read-string \"1/2\"))" "true"]
|
||||
["(= -3.5 (read-string \"-3.5\"))" "true"]
|
||||
["(= 1000.0 (read-string \"1e3\"))" "true"]
|
||||
["(= 1 (read-string \"1N\"))" "true"]
|
||||
["(integer? (read-string \"7\"))" "true"]
|
||||
["(= :foo (read-string \":foo\"))" "true"]
|
||||
["(= :a/b (read-string \":a/b\"))" "true"]
|
||||
["(= :foo (read-string \"::foo\"))" "true"]
|
||||
["(= (quote sym) (read-string \"sym\"))" "true"]
|
||||
["(= (quote ns/sym) (read-string \"ns/sym\"))" "true"]
|
||||
["(nil? (read-string \"nil\"))" "true"]
|
||||
["(true? (read-string \"true\"))" "true"]
|
||||
["(false? (read-string \"false\"))" "true"]
|
||||
["(= \\a (read-string \"\\\\a\"))" "true"]
|
||||
["(= \\newline (read-string \"\\\\newline\"))" "true"]
|
||||
["(= \\space (read-string \"\\\\space\"))" "true"]
|
||||
["(= \"a\\nb\" (read-string \"\\\"a\\\\nb\\\"\"))" "true"]
|
||||
["(= [1 2 3] (read-string \"[1 2 3]\"))" "true"]
|
||||
["(= (quote (+ 1 2)) (read-string \"(+ 1 2)\"))" "true"]
|
||||
["(= {:a 1 :b 2} (read-string \"{:a 1 :b 2}\"))" "true"]
|
||||
# core read-string returns the raw set FORM (edn->value builds the real set)
|
||||
["(:value (read-string \"#{1 2 3}\"))" "[1 2 3]"]
|
||||
["(= :jolt/set (:jolt/type (read-string \"#{1 2 3}\")))" "true"]
|
||||
["(= [1 [2 3] {:k :v}] (read-string \"[1 [2 3] {:k :v}]\"))" "true"]
|
||||
# --- reader macros ---
|
||||
["(= (quote (quote x)) (read-string \"'x\"))" "true"]
|
||||
["(= (quote (clojure.core/deref a)) (read-string \"@a\"))" "true"]
|
||||
["(= (quote (syntax-quote (a (unquote b)))) (read-string \"`(a ~b)\"))" "true"]
|
||||
["(= (quote (unquote-splicing xs)) (read-string \"~@xs\"))" "true"]
|
||||
# --- whitespace / comments / discard ---
|
||||
["(= 42 (read-string \"; comment\\n42\"))" "true"]
|
||||
["(= [1 2] (read-string \"[1 #_ 9 2]\"))" "true"]
|
||||
["(nil? (read-string \"\"))" "true"]
|
||||
["(nil? (read-string \" , ,\"))" "true"]
|
||||
# --- metadata ^ on a symbol ---
|
||||
["(:tag (meta (read-string \"^String x\")))" "String"]
|
||||
["(:foo (meta (read-string \"^:foo x\")))" "true"]
|
||||
# --- *in* reader family: read / read+string / with-in-str ---
|
||||
["(= 42 (with-in-str \"42\" (read)))" "true"]
|
||||
["(= (quote (+ 1 2)) (with-in-str \"(+ 1 2)\" (read)))" "true"]
|
||||
["(with-in-str \"1 2\" [(read) (read)])" "[1 2]"]
|
||||
["(= :done (with-in-str \"\" (read *in* false :done)))" "true"]
|
||||
["(let [[v s] (with-in-str \"42 rest\" (read+string))] (and (= v 42) (string? s)))" "true"]
|
||||
["(= [1 2] (with-in-str \"1 2\" [(first (read+string)) (first (read+string))]))" "true"]
|
||||
# --- clojure.edn (set/tagged forms built into real values) ---
|
||||
["(do (require (quote [clojure.edn :as e0])) (= #{1 2} (e0/read-string \"#{1 2}\")))" "true"]
|
||||
["(do (require (quote [clojure.edn :as e0])) (uuid? (e0/read-string \"#uuid \\\"550e8400-e29b-41d4-a716-446655440000\\\"\")))" "true"]
|
||||
["(do (require (quote [clojure.edn :as e0])) (inst? (e0/read-string \"#inst \\\"2020-01-01T00:00:00Z\\\"\")))" "true"]
|
||||
["(do (require (quote [clojure.edn :as e0])) (= :end (e0/read-string {:eof :end} \"\")))" "true"]
|
||||
["(do (require (quote [clojure.edn :as e0])) (= [:custom 5] (e0/read-string {:readers {(quote custom) (fn [v] [:custom v])}} \"#custom 5\")))" "true"]
|
||||
["(do (require (quote clojure.edn)) (= {:a 1 :b 2} (clojure.edn/read-string \"{:a 1\\n :b 2}\")))" "true"]])
|
||||
|
||||
(defn run-capture [bin expr]
|
||||
(def proc (os/spawn [bin "-e" expr] :p {:out :pipe :err :pipe}))
|
||||
(def out (ev/read (proc :out) 0x100000))
|
||||
(def err (ev/read (proc :err) 0x100000))
|
||||
(def code (os/proc-wait proc))
|
||||
(def lines (filter (fn [l] (not (empty? l)))
|
||||
(string/split "\n" (string/trim (if out (string out) "")))))
|
||||
[code (if (empty? lines) "" (last lines)) (string/trim (if err (string err) ""))])
|
||||
|
||||
(var pass 0)
|
||||
(def fails @[])
|
||||
(each [expr expected] cases
|
||||
(def [ocode oracle _] (run-capture "build/jolt" expr))
|
||||
(def [code got err] (run-capture jolt-bin expr))
|
||||
(cond
|
||||
(not= ocode 0) (array/push fails [expr (string "ORACLE FAILED exit " ocode)])
|
||||
(not= oracle expected) (array/push fails [expr (string "ORACLE MISMATCH want `" expected "` got `" oracle "`")])
|
||||
(not= code 0) (array/push fails [expr (string "exit " code "; err: " err)])
|
||||
(= got expected) (++ pass)
|
||||
(array/push fails [expr (string "want `" expected "`, got `" got "`")])))
|
||||
|
||||
(printf "\n_reader parity [%s]: %d/%d passed" jolt-bin pass (length cases))
|
||||
(when (> (length fails) 0)
|
||||
(printf "%d FAIL(s):" (length fails))
|
||||
(each [e m] fails (printf " FAIL %s\n %s" e m)))
|
||||
(flush)
|
||||
(os/exit (if (empty? fails) 0 1))
|
||||
|
|
@ -269,8 +269,14 @@
|
|||
# offsets, = / hash / pr-str / get-as-overlay-seam) plus the DateTimeFormatter
|
||||
# pattern engine + Instant/ZoneId/LocalDateTime/FormatStyle/Locale/Date shims.
|
||||
# This cleared the whole "unsupported form" emit-fail bucket) 2238.
|
||||
# jolt-r8ku inc Y (Chez data reader — host/chez/reader.ss, a recursive-descent
|
||||
# Clojure reader producing the same forms as the Janet reader, behind the
|
||||
# read-string / __parse-next / __read-tagged seams) + clojure.edn loaded into the
|
||||
# prelude. Lights up read / read+string / with-in-str (read) / read-string and
|
||||
# clojure.edn/read-string. (eval / load-string / runtime defmacro stay Phase-3 —
|
||||
# they need the compiler at runtime.) 2259.
|
||||
# Strided runs scale down.
|
||||
(def base-floor (scan-number (or (os/getenv "JOLT_CHEZ_PRELUDE_FLOOR") "2238")))
|
||||
(def base-floor (scan-number (or (os/getenv "JOLT_CHEZ_PRELUDE_FLOOR") "2259")))
|
||||
(def floor (if (os/getenv "JOLT_CORPUS_LIMIT") 0 base-floor))
|
||||
(when (or (> (length diverged) 0) (< pass floor))
|
||||
(printf "REGRESSION: pass %d < floor %d or %d new divergence(s)" pass floor (length diverged)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue