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
|
|
@ -90,28 +90,31 @@
|
|||
(string-append (if (string? p) p (jolt-str-render-one p))
|
||||
(number->string jolt-gensym-counter)))))
|
||||
|
||||
(define (jolt-int x) (if (char? x) (exact->inexact (char->integer x)) (truncate x)))
|
||||
;; int/long: truncate toward zero to an EXACT integer (= JVM long). char -> code
|
||||
;; point (exact). double: always a flonum (= JVM double).
|
||||
(define (jolt-int x) (if (char? x) (char->integer x) (exact (truncate x))))
|
||||
(define (jolt-double x) (if (char? x) (exact->inexact (char->integer x)) (exact->inexact x)))
|
||||
|
||||
;; compare: 3-way, ported from core_io.janet core-compare.
|
||||
(define (jolt-cmp3 x y) (cond ((< x y) -1.0) ((> x y) 1.0) (else 0.0)))
|
||||
(define (jolt-strcmp a b) (cond ((string<? a b) -1.0) ((string>? a b) 1.0) (else 0.0)))
|
||||
;; compare: 3-way, returns an EXACT integer (= JVM compare -> int).
|
||||
(define (jolt-cmp3 x y) (cond ((< x y) -1) ((> x y) 1) (else 0)))
|
||||
(define (jolt-strcmp a b) (cond ((string<? a b) -1) ((string>? a b) 1) (else 0)))
|
||||
(define (jolt-kw->string k)
|
||||
(let ((ns (keyword-t-ns k))) (if ns (string-append ns "/" (keyword-t-name k)) (keyword-t-name k))))
|
||||
(define (jolt-sym-ns-string s)
|
||||
(let ((n (symbol-t-ns s))) (if (or (jolt-nil? n) (not n) (eq? n '())) "" n)))
|
||||
;; compare returns an EXACT integer -1/0/1 (= JVM compare -> int).
|
||||
(define (jolt-compare a b)
|
||||
(cond
|
||||
((and (jolt-nil? a) (jolt-nil? b)) 0.0)
|
||||
((jolt-nil? a) -1.0)
|
||||
((jolt-nil? b) 1.0)
|
||||
((and (jolt-nil? a) (jolt-nil? b)) 0)
|
||||
((jolt-nil? a) -1)
|
||||
((jolt-nil? b) 1)
|
||||
((and (number? a) (number? b)) (jolt-cmp3 a b))
|
||||
((and (string? a) (string? b)) (jolt-strcmp a b))
|
||||
((and (keyword? a) (keyword? b)) (jolt-strcmp (jolt-kw->string a) (jolt-kw->string b)))
|
||||
((and (jolt-symbol? a) (jolt-symbol? b))
|
||||
(let ((r (jolt-strcmp (jolt-sym-ns-string a) (jolt-sym-ns-string b))))
|
||||
(if (= r 0.0) (jolt-strcmp (symbol-t-name a) (symbol-t-name b)) r)))
|
||||
((and (boolean? a) (boolean? b)) (cond ((eq? a b) 0.0) ((eq? a #f) -1.0) (else 1.0)))
|
||||
(if (= r 0) (jolt-strcmp (symbol-t-name a) (symbol-t-name b)) r)))
|
||||
((and (boolean? a) (boolean? b)) (cond ((eq? a b) 0) ((eq? a #f) -1) (else 1)))
|
||||
((and (char? a) (char? b)) (jolt-cmp3 (char->integer a) (char->integer b)))
|
||||
((and (pvec? a) (pvec? b))
|
||||
(let ((la (pvec-count a)) (lb (pvec-count b)))
|
||||
|
|
@ -119,9 +122,9 @@
|
|||
(jolt-cmp3 la lb)
|
||||
(let loop ((i 0))
|
||||
(if (>= i la)
|
||||
0.0
|
||||
0
|
||||
(let ((r (jolt-compare (pvec-nth-d a i jolt-nil) (pvec-nth-d b i jolt-nil))))
|
||||
(if (= r 0.0) (loop (+ i 1)) r)))))))
|
||||
(if (= r 0) (loop (+ i 1)) r)))))))
|
||||
(else (error #f "compare: cannot compare these types" a b))))
|
||||
|
||||
(def-var! "clojure.core" "str" jolt-str)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue