Chez numeric tower: exact ints / Ratio / double for JVM parity (jolt-n6al)
jolt was all-flonum (one :number type, inherited from Janet whose only number type is a double). The Chez runtime has a full numeric tower, so the zero-Janet path now carries it = JVM Clojure semantics: (/ 1 2) => 1/2 (exact Ratio, was 0.5) (integer? 3) => true (integer? 3.0) => false (float? 3.0) => true (ratio? (/ 1 2)) => true (= 3 3.0) => false (== 3 3.0) => true (+ 1 2) => 3 (exact) (/ 1.0 2) => 0.5 (double) jolt= was already exactness-aware (values.ss) and == is value-equality, so =/== match the JVM split. The reader preserves exactness (integer literals exact, a/b ratios exact rationals, decimals/exponents flonums); backend_scheme emit-const renders exact ints/ratios and flonums faithfully; the value-position arithmetic, count, int, compare, bit ops, parseLong, string .length/.indexOf, range, timestamps, and array bytes return exact integers (= JVM int/long) instead of coercing to flonum. double/parseDouble/clojure.math floor|ceil|signum stay double. Only the zero-Janet path carries the tower (the Janet reader loses exactness into a double before emit). The prelude/all-flonum path is unaffected for compiled code; the runtime reader is shared, so a couple of all-flonum reader assertions become value (==) assertions. ~16 numeric corpus cases now give the JVM tower value vs the Janet-era :expected and are allowlisted as tower divergences (Chez == reference JVM) pending the corpus flip to JVM (jolt-ecz0). No BigDecimal type (1M). Re-minted. zero-janet 2682 (floor 2698->2682, the reclassified tower cases), 0 new divergences; fixpoint 10/10, bootstrap 6/6, spine 35/35, cli 49/49; Janet gate 155 files 0 failed.
This commit is contained in:
parent
eb1c3298a4
commit
467ad75ff7
20 changed files with 291 additions and 210 deletions
|
|
@ -133,16 +133,18 @@
|
|||
(cond
|
||||
(nil? v) "jolt-nil"
|
||||
(boolean? v) (if v "#t" "#f")
|
||||
;; jolt models every number as a double. Emit flonums so arithmetic matches
|
||||
;; the Janet host and Chez doesn't fall into exploding exact rationals.
|
||||
;; ##Inf/##-Inf/##NaN -> Chez's flonum literals (Janet stringifies them as
|
||||
;; inf/-inf/nan, unbound symbols in Chez).
|
||||
;; Numeric tower (jolt-n6al): emit a literal Chez re-reads as the SAME number.
|
||||
;; Exact integers -> "42", exact ratios -> "1/2" (str renders both faithfully);
|
||||
;; a flonum must carry a decimal point/exponent or Chez reads it back as exact,
|
||||
;; so a whole flonum (str drops its .0) gets ".0" appended. ##Inf/##-Inf/##NaN
|
||||
;; -> Chez's flonum literals.
|
||||
(number? v) (cond
|
||||
(= v ##Inf) "+inf.0"
|
||||
(= v ##-Inf) "-inf.0"
|
||||
(not= v v) "+nan.0"
|
||||
:else (let [s (str v)]
|
||||
(if (or (str/includes? s ".") (str/includes? s "e")) s (str s ".0"))))
|
||||
(float? v) (let [s (str v)]
|
||||
(if (or (str/includes? s ".") (str/includes? s "e")) s (str s ".0")))
|
||||
:else (str v))
|
||||
(string? v) (chez-str-lit v)
|
||||
;; keyword literal -> (keyword ns name)
|
||||
(keyword? v) (if-let [kns (namespace v)]
|
||||
|
|
@ -310,9 +312,9 @@
|
|||
kind (ifn-kind fnode)
|
||||
default (if (> (count args) 1) (str " " (nth args 1)) "")]
|
||||
(cond
|
||||
;; zero-arg + / * : flonum identity to keep the all-double model.
|
||||
(and nop (empty? args) (= nop "+")) "0.0"
|
||||
(and nop (empty? args) (= nop "*")) "1.0"
|
||||
;; zero-arg + / * : exact integer identity (= JVM long: (+) -> 0, (*) -> 1).
|
||||
(and nop (empty? args) (= nop "+")) "0"
|
||||
(and nop (empty? args) (= nop "*")) "1"
|
||||
(and nop (= 1 (count args)) (cmp1-ops nop)) (str "(begin " (first args) " #t)")
|
||||
nop (str "(" nop " " (str/join " " args) ")")
|
||||
;; (:k coll [default]) -> (jolt-get coll :k [default])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue