Chez inc 3m: numeric-edge literal emit + variadic assoc!
##Inf/##-Inf/##NaN were emitted to bare inf/-inf/nan, which are unbound symbols in
Chez. emit-const now lowers them to +inf.0/-inf.0/+nan.0. The -e/element printer
renders them inf/-inf/nan (Chez's number->string gives +inf.0), and str renders the
long Clojure forms Infinity/-Infinity/NaN. assoc! is now variadic ((assoc! t k v
& kvs)) like Clojure.
Prelude parity 1382 -> 1407/2497, 0 new divergences. str of inf INSIDE a collection
still wants the long form (needs the Phase-2 recursive str renderer), so
[inf inside coll] is allowlisted. Transducer arities and the cdr-on-()/\p{} regex
gaps are split out to jolt-kxsr/jolt-y1zq.
This commit is contained in:
parent
1826c8b3e9
commit
c28b5406ca
7 changed files with 65 additions and 16 deletions
|
|
@ -13,6 +13,11 @@
|
|||
((string? v) v)
|
||||
((char? v) (string v))
|
||||
((regex-t? v) (regex-t-source v))
|
||||
;; str/print render the infinities and NaN long-form (Clojure .toString),
|
||||
;; unlike the -e printer's inf/-inf/nan.
|
||||
((and (flonum? v) (fl= v +inf.0)) "Infinity")
|
||||
((and (flonum? v) (fl= v -inf.0)) "-Infinity")
|
||||
((and (flonum? v) (not (fl= v v))) "NaN")
|
||||
(else (jolt-pr-str v))))
|
||||
(define (jolt-str . xs)
|
||||
(let loop ((xs xs) (acc '()))
|
||||
|
|
|
|||
|
|
@ -122,10 +122,14 @@
|
|||
# jolt models every number as a double (no ratios/bignums; see reader.janet).
|
||||
# Emit flonums so arithmetic matches the Janet host and Chez doesn't fall into
|
||||
# exploding exact rationals (mandelbrot). Integer-valued -> append ".0".
|
||||
(number? v) (let [s (string v)]
|
||||
(if (or (string/find "." s) (string/find "e" s) (string/find "n" s))
|
||||
s
|
||||
(string s ".0")))
|
||||
# ##Inf/##-Inf/##NaN: Janet stringifies these as inf/-inf/nan, which are
|
||||
# unbound symbols in Chez — emit Chez's flonum literals instead.
|
||||
(number? v) (cond
|
||||
(= v math/inf) "+inf.0"
|
||||
(= v (- math/inf)) "-inf.0"
|
||||
(not= v v) "+nan.0"
|
||||
(let [s (string v)]
|
||||
(if (or (string/find "." s) (string/find "e" s)) s (string s ".0"))))
|
||||
(string? v) (string/format "%j" v) # quoted+escaped string literal
|
||||
# keyword literal -> (keyword ns name); ns is everything before the first "/"
|
||||
(keyword? v) (let [s (string v) idx (string/find "/" s)]
|
||||
|
|
|
|||
|
|
@ -98,9 +98,15 @@
|
|||
;; jolt models every number as a Clojure double: integer-valued values print
|
||||
;; without a ".0" (the Janet host prints (* 1.0 5) as "5", (/ 1 2) as "0.5").
|
||||
(define (jolt-num->string x)
|
||||
(if (and (rational? x) (integer? x))
|
||||
(number->string (exact x))
|
||||
(number->string x)))
|
||||
(cond
|
||||
;; the -e / element printer renders the infinities and NaN as inf/-inf/nan
|
||||
;; (Chez's number->string gives +inf.0 etc.); the str/print family uses the
|
||||
;; long "Infinity"/"NaN" forms (see jolt-str-render-one in converters.ss).
|
||||
((and (flonum? x) (fl= x +inf.0)) "inf")
|
||||
((and (flonum? x) (fl= x -inf.0)) "-inf")
|
||||
((and (flonum? x) (not (fl= x x))) "nan")
|
||||
((and (rational? x) (integer? x)) (number->string (exact x)))
|
||||
(else (number->string x))))
|
||||
|
||||
;; Program-final-value printer. jolt's `-e` prints in str-style: strings raw (no
|
||||
;; quotes), chars as `\c`/`\newline`, collections recursively. NOTE: maps/sets
|
||||
|
|
|
|||
|
|
@ -27,9 +27,10 @@
|
|||
(jolt-trans-check t "conj!")
|
||||
(jolt-transient-coll-set! t (apply jolt-conj (jolt-transient-coll t) xs))
|
||||
t)
|
||||
(define (jolt-assoc! t k v)
|
||||
;; (assoc! t k v & kvs): variadic like Clojure (jolt-assoc already folds pairs).
|
||||
(define (jolt-assoc! t . kvs)
|
||||
(jolt-trans-check t "assoc!")
|
||||
(jolt-transient-coll-set! t (jolt-assoc (jolt-transient-coll t) k v))
|
||||
(jolt-transient-coll-set! t (apply jolt-assoc (jolt-transient-coll t) kvs))
|
||||
t)
|
||||
(define (jolt-dissoc! t . ks)
|
||||
(jolt-trans-check t "dissoc!")
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ corpus case with all of core present, bucketing the result —
|
|||
JOLT_CORPUS_LIMIT=200 … (every-Nth stride, fast)
|
||||
|
||||
Parity baseline: inc 3j **1220/2497**; 3k (converters, jolt-t6cr) **1326**;
|
||||
3l (transients, jolt-kl2l) **1382/2497**, 0 NEW divergences (13 allowlisted:
|
||||
3l (transients, jolt-kl2l) **1382**; 3m (numeric-edge emit + variadic assoc!,
|
||||
jolt-q3w8) **1407/2497**, 0 NEW divergences (14 allowlisted:
|
||||
dynamic vars `*ns*`/`*clojure-version*`/`*unchecked-math*`, var/`*ns*` rendering,
|
||||
class names, eval-order, with-open — all deferred Phase-2 / dynamic-var gaps).
|
||||
- inc 3k `host/chez/converters.ss`: `str`/`subs`/`vec`/`keyword`/`symbol`/`compare`/
|
||||
|
|
@ -118,11 +119,17 @@ class names, eval-order, with-open — all deferred Phase-2 / dynamic-var gaps).
|
|||
are redefined to see THROUGH a transient (frequencies/group-by do `(get tm k)` on a
|
||||
transient map); `vector?` on a transient vector is false, which group-by relies on.
|
||||
|
||||
- inc 3m: `##Inf`/`##-Inf`/`##NaN` emitted to bare `inf`/`nan` (unbound in Chez);
|
||||
emit-const now lowers them to `+inf.0`/`-inf.0`/`+nan.0`, the `-e` printer renders
|
||||
`inf`/`-inf`/`nan` and `str` renders `Infinity`/`-Infinity`/`NaN` (Clojure). Plus
|
||||
variadic `assoc!`. (`str` of inf *inside a collection* still wants the long form —
|
||||
the Phase-2 recursive str renderer — so `[inf inside coll]` is allowlisted.)
|
||||
|
||||
The remaining buckets are the punch-list the next increments chase: ~360 emit-fail
|
||||
(genuine host interop — qualified Java/Janet refs, runtime `defmacro`/`eval`, out of
|
||||
the analyzer's subset) and ~740 runtime crashes, including `##Inf`/`##NaN` literals →
|
||||
unbound `inf`/`nan` and seq-prim transducer arities (inc 3m jolt-q3w8), multimethod
|
||||
dispatch (Phase 2 jolt-9ls5), and more host-coupled natives without a shim.
|
||||
the analyzer's subset) and ~715 runtime crashes — more host-coupled natives without a
|
||||
shim, transducer arities (jolt-kxsr), `cdr`-on-`()` and `\p{}` regex classes
|
||||
(jolt-y1zq), and multimethod dispatch (Phase 2 jolt-9ls5).
|
||||
|
||||
Two host shims landed with the prelude. `host/chez/atoms.ss`: atom/deref/swap!/
|
||||
reset! (+ compare-and-set!/swap-vals!/reset-vals!) — host-coupled mutable cells the
|
||||
|
|
|
|||
|
|
@ -467,6 +467,27 @@
|
|||
(ok (string "jolt-chez -e: " src) (and (= code 0) (= out want))
|
||||
(string "chez=" out " janet=" want " | " err)))))
|
||||
|
||||
# 3r) numeric-edge literals (jolt-q3w8): ##Inf/##-Inf/##NaN emitted to bare
|
||||
# inf/nan (unbound on Chez) — fix emit-const to +inf.0/-inf.0/+nan.0, the
|
||||
# -e printer to inf/-inf/nan, and str to Infinity/-Infinity/NaN (Clojure).
|
||||
# Value/print cases are pure literals -> subset path (d/run-on-chez).
|
||||
(each src ["(< 5 ##Inf)" "(> 5 ##-Inf)" "(= ##Inf ##Inf)"
|
||||
"##Inf" "##-Inf" "##NaN" "[##Inf]" "[##NaN ##-Inf]"]
|
||||
(let [[code out err] (d/run-on-chez ctx src) want (cli-oracle src)]
|
||||
(ok (string "numedge: " src) (and (= code 0) (= out want))
|
||||
(string "chez=" out " janet=" want " | " err))))
|
||||
# str of inf/nan needs the prelude (str is a converter shim).
|
||||
(each src ["(str ##Inf)" "(str ##-Inf)" "(str ##NaN)"]
|
||||
(let [[code out err] (run-prelude src) want (cli-oracle src)]
|
||||
(ok (string "numedge: " src) (and (= code 0) (= out want))
|
||||
(string "chez=" out " janet=" want " | " err))))
|
||||
# variadic assoc! (jolt-q3w8): (assoc! t k v & kvs).
|
||||
(each src ["(count (persistent! (assoc! (transient {}) :a 1 :b 2 :c 3)))"
|
||||
"(get (persistent! (assoc! (transient {}) :a 1 :b 2)) :b)"]
|
||||
(let [[code out err] (run-prelude src) want (cli-oracle src)]
|
||||
(ok (string "numedge: " src) (and (= code 0) (= out want))
|
||||
(string "chez=" out " janet=" want " | " err))))
|
||||
|
||||
# 4) perf signal: emitted fib(30) in-Scheme timing (excludes Chez startup), to
|
||||
# track against the spike ceiling (hand-Scheme fib ~5ms). Informational — the
|
||||
# jolt-truthy? wrapper (~3x) and flonum modeling are known Phase-4 levers.
|
||||
|
|
|
|||
|
|
@ -54,7 +54,12 @@
|
|||
"*ns* user" true
|
||||
"str of a var" true
|
||||
"*clojure-version* major" true
|
||||
"*unchecked-math*" true})
|
||||
"*unchecked-math*" true
|
||||
# (str [##Inf]) wants "[Infinity]" but the Chez -e printer (jolt-pr-str, which
|
||||
# str falls back to for collections) renders inf as "inf" — str needs a
|
||||
# recursive long-form renderer, the Phase-2 canonical printer. Top-level
|
||||
# (str ##Inf) -> "Infinity" already works (jolt-str-render-one).
|
||||
"inf inside coll" true})
|
||||
|
||||
(def ctx (d/make-ctx))
|
||||
|
||||
|
|
@ -130,8 +135,8 @@
|
|||
# reach-floor and the suite baseline. The gate fails if parity drops below it, or
|
||||
# on any NEW (un-allowlisted) divergence — a real Chez correctness regression.
|
||||
# Full-corpus baseline: inc 3j 1220/2497; 3k (converters) 1326; 3l (transients)
|
||||
# 1382. Strided runs scale the floor down.
|
||||
(def base-floor (scan-number (or (os/getenv "JOLT_CHEZ_PRELUDE_FLOOR") "1382")))
|
||||
# 1382; 3m (numeric-edge emit + variadic assoc!) 1407. Strided runs scale down.
|
||||
(def base-floor (scan-number (or (os/getenv "JOLT_CHEZ_PRELUDE_FLOOR") "1407")))
|
||||
(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