real BigDecimal type (bigdec, M literals)

bigdec / 1.5M / 0.0M silently produced doubles. Add a jbigdec value type
{unscaled, scale} over Chez exact integers (host/chez/bigdec.ss): value =
unscaled * 10^-scale. An M-suffix literal reads to a :bigdec form that the back
end lowers to jolt-bigdec-from-string (same IR-leaf path as #inst/#uuid); bigdec
coerces a number/string. Equality is by value (1.0M = 1.00M true, 3M = 3 false),
str drops the M and pr keeps it, class is java.math.BigDecimal, decimal? is true.
Arithmetic contagion isn't modelled (out of scope). The old corpus cases passed
spuriously as doubles; they now exercise a genuine BigDecimal.
This commit is contained in:
Yogthos 2026-06-22 00:01:01 -04:00
parent 7db5fabc8d
commit ab96650fbb
10 changed files with 288 additions and 191 deletions

View file

@ -134,10 +134,12 @@
((and (> blen 1) (char=? (string-ref body (- blen 1)) #\N))
(let ((n (string->number (substring body 0 (- blen 1)))))
(and n (integer? n) (* sign n))))
;; bigdecimal suffix M -> double
;; bigdecimal suffix M -> a :bigdec form carrying the numeric text; the back
;; end lowers it to a runtime jbigdec (jolt-i2jm).
((and (> blen 1) (char=? (string-ref body (- blen 1)) #\M))
(let ((n (string->number (substring body 0 (- blen 1)))))
(and n (exact->inexact (* sign n)))))
(and n (real? n)
(rdr-make-tagged (keyword #f "bigdec") (substring tok 0 (- len 1))))))
(else
(let ((n (string->number tok))) ; tok carries its own sign
;; keep exactness: "42" -> exact int, "3.14"/"1e3" -> flonum.