feat: ##Inf/##-Inf/##NaN literals, infinite?/NaN?, fix intval? for infinity

The reader now reads the symbolic float values ##Inf, ##-Inf and ##NaN. Added
infinite? and NaN? predicates. Fixed intval? to exclude infinity (floor(inf)=inf
but inf isn't integer-valued), so float?/double? are true for ##Inf and
int?/pos-int?/nat-int?/neg-int? are false for it.

This unblocked many number-test files whose  forms previously failed to
READ (##Inf/##NaN literals), so clojure-test-suite jumped from 2241 to 2539
assertions and pass 1719 -> 1955. Baseline raised to 1900. NaN_qmark now runs.

float?/double? on integer-valued doubles (1.0) remain false: Janet represents
an integer and an integer-valued double identically, so they're inherently
indistinguishable — documented in the README Numbers section.

spec: numbers/floats-&-symbolic-values (15 cases). jpm test green.
Closes jolt-fy8 (fixable parts; int-vs-float ambiguity is a documented divergence).
This commit is contained in:
Yogthos 2026-06-05 09:35:44 -04:00
parent 09532dac05
commit 03652dce5d
6 changed files with 41 additions and 5 deletions

View file

@ -3009,7 +3009,10 @@
# Additional clojure.core functions
# ============================================================
(defn- intval? [x] (and (number? x) (= x (math/floor x))))
# Integer-valued: a finite number equal to its floor. Infinity floors to itself
# but is NOT integer-valued (so float?/double? are true for ##Inf, and int?/
# pos-int?/… are false), and NaN is excluded by the equality check.
(defn- intval? [x] (and (number? x) (< (math/abs x) math/inf) (= x (math/floor x))))
# Forcing lazy seqs
(defn core-doall [a & rest]
@ -3061,6 +3064,8 @@
(defn core-ratio? [x] false)
(defn core-decimal? [x] false)
(defn core-rational? [x] (intval? x))
(defn core-infinite? [x] (and (number? x) (= (math/abs x) math/inf)))
(defn core-NaN? [x] (and (number? x) (not= x x)))
(defn core-numerator [x] x)
(defn core-denominator [x] 1)
@ -3339,6 +3344,8 @@
"ratio?" core-ratio?
"decimal?" core-decimal?
"rational?" core-rational?
"infinite?" core-infinite?
"NaN?" core-NaN?
"numerator" core-numerator
"denominator" core-denominator
"list*" core-list*

View file

@ -385,6 +385,14 @@
[{:jolt/type :jolt/skip} new-pos])
(= c 39) (read-var-quote s pos) # #'
(= c 34) (read-regex s pos) # #"regex
(= c 35) # ## symbolic value: ##Inf ##-Inf ##NaN
(let [end (read-symbol-name s (+ pos 2) (+ pos 2))
name (string/slice s (+ pos 2) end)]
(cond
(= name "Inf") [math/inf end]
(= name "-Inf") [(- math/inf) end]
(= name "NaN") [math/nan end]
(error (string "Invalid symbolic value: ##" name))))
# unknown dispatch — tagged literal
(let [end (read-symbol-name s pos pos)
tag (string/slice s pos end)