From a4d9d5f70bc2bd021dc9d6d9b89b28cf0c566584 Mon Sep 17 00:00:00 2001 From: Yogthos Date: Fri, 5 Jun 2026 10:23:57 -0400 Subject: [PATCH] fix: print Infinity/-Infinity/NaN like Clojure (str and pr-str) Numbers printed via Janet's (string v) rendered infinities/NaN as inf/-inf/nan. Add fmt-number so str/pr-str (and collection rendering) emit Infinity/-Infinity/ NaN. str.cljc 3->32 pass. Remaining str fails are the integer-valued-double divergence ((str 0.0) is "0" not "0.0" since 0.0 == 0 in Janet). spec: numbers/printing-of-inf-&-nan (5). jpm test green. --- src/jolt/core.janet | 14 ++++++++++++-- test/integration/clojure-test-suite-test.janet | 2 +- test/spec/numbers-spec.janet | 7 +++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/jolt/core.janet b/src/jolt/core.janet index 5dd65e1..86e6028 100644 --- a/src/jolt/core.janet +++ b/src/jolt/core.janet @@ -1424,6 +1424,16 @@ # syntax. Used by both pr-str (readable) and str (collection elements). (var pr-render nil) +# Format a number the way Clojure prints it: infinity and NaN have named forms +# (Janet renders them "inf"/"-inf"/"nan"). +(defn- fmt-number [v] + (cond + (not (number? v)) (string v) + (= v math/inf) "Infinity" + (= v (- math/inf)) "-Infinity" + (not= v v) "NaN" + (string v))) + (defn- pr-render-seq [buf items open close] (buffer/push-string buf open) (var first true) @@ -1458,7 +1468,7 @@ 12 "formfeed" 8 "backspace" 0 "nul" (char->string v)))) (regex? v) (do (buffer/push-string buf "#\"") (buffer/push-string buf (v :source)) (buffer/push-string buf "\"")) - (number? v) (buffer/push-string buf (string v)) + (number? v) (buffer/push-string buf (fmt-number v)) (and (struct? v) (= :symbol (v :jolt/type))) (buffer/push-string buf (if (v :ns) (string (v :ns) "/" (v :name)) (v :name))) (core-sorted-map? v) (pr-render-pairs buf (sorted-map-entries v)) @@ -1489,7 +1499,7 @@ (keyword? v) (string ":" (string v)) (and (struct? v) (= :symbol (v :jolt/type))) (if (v :ns) (string (v :ns) "/" (v :name)) (v :name)) - (number? v) (string v) + (number? v) (fmt-number v) (= true v) "true" (= false v) "false" (let [buf @""] (pr-render buf v) (string buf)))) diff --git a/test/integration/clojure-test-suite-test.janet b/test/integration/clojure-test-suite-test.janet index e7f39fb..498a70c 100644 --- a/test/integration/clojure-test-suite-test.janet +++ b/test/integration/clojure-test-suite-test.janet @@ -18,7 +18,7 @@ # Baseline: assertions Jolt currently passes across the suite. Raise as Jolt # improves so a regression (previously-passing assertion breaking) is caught. -(def baseline-pass 3660) +(def baseline-pass 3680) # A file is "clean" when it ran with zero failures AND zero errors. (def baseline-clean-files 45) # Per-file wall-clock budget (seconds). Normal files finish in well under 1s; diff --git a/test/spec/numbers-spec.janet b/test/spec/numbers-spec.janet index bb9cdbb..d79eb7d 100644 --- a/test/spec/numbers-spec.janet +++ b/test/spec/numbers-spec.janet @@ -90,6 +90,13 @@ ["exponent" "1000.0" "1e3"] ["exponent neg" "0.015" "1.5e-2"]) +(defspec "numbers / printing of inf & nan" + ["str Infinity" "\"Infinity\"" "(str ##Inf)"] + ["str -Infinity" "\"-Infinity\"" "(str ##-Inf)"] + ["str NaN" "\"NaN\"" "(str ##NaN)"] + ["pr-str Infinity" "\"Infinity\"" "(pr-str ##Inf)"] + ["inf inside coll" "\"[Infinity]\"" "(str [##Inf])"]) + (defspec "numbers / bit-ops & math" ["bit-and" "4" "(bit-and 12 6)"] ["bit-or" "14" "(bit-or 12 6)"]