js-on-sx: NaN / Infinity resolve at transpile; strict-eq returns false for NaN

Previously NaN / Infinity were SX symbols that couldn't be (define)'d
because the SX tokenizer parses 'NaN' and 'Infinity' as numeric literals.

js-transpile-ident now rewrites NaN -> (js-nan-value), Infinity ->
(js-infinity-value), each a zero-arg function returning the appropriate
IEEE value ((/ 0.0 0.0) and (/ 1.0 0.0)).

Also fixes js-number-is-nan: in this SX, (= nan nan) returns true, so the
classic 'v !== v' trick doesn't work. Now checks (inspect v) against
'nan'/'-nan' strings.

Extends js-strict-eq: NaN === NaN returns false per ES spec.

8 new unit tests, 497/499 total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 07:43:09 +00:00
parent fd73c43eba
commit db7a3d10dd
3 changed files with 97 additions and 58 deletions

View File

@@ -1213,6 +1213,24 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 3709)
(eval "(js-eval \"var a=[1,2,3]; a.keys().join(',')\")")
;; ── Phase 11.globals: NaN / Infinity / strict-eq ─────────────
(epoch 3750)
(eval "(js-eval \"typeof NaN\")")
(epoch 3751)
(eval "(js-eval \"isNaN(NaN)\")")
(epoch 3752)
(eval "(js-eval \"isNaN(5)\")")
(epoch 3753)
(eval "(js-eval \"NaN === NaN\")")
(epoch 3754)
(eval "(js-eval \"Infinity > 100\")")
(epoch 3755)
(eval "(js-eval \"-Infinity < 0\")")
(epoch 3756)
(eval "(js-eval \"isFinite(1)\")")
(epoch 3757)
(eval "(js-eval \"isFinite(Infinity)\")")
;; ── Phase 11.strmore: more String.prototype methods ─────────
(epoch 3800)
(eval "(js-eval \"'hello'.at(0)\")")
@@ -1909,6 +1927,16 @@ check 3707 "arr.toReversed" '"2,1,3"'
check 3708 "arr.toSorted" '"1,1,3,4,5"'
check 3709 "arr.keys" '"0,1,2"'
# ── Phase 11.globals: NaN / Infinity / strict-eq ─────────────
check 3750 "typeof NaN" '"number"'
check 3751 "isNaN(NaN)" 'true'
check 3752 "isNaN(5)" 'false'
check 3753 "NaN === NaN" 'false'
check 3754 "Infinity > 100" 'true'
check 3755 "-Infinity < 0" 'true'
check 3756 "isFinite(1)" 'true'
check 3757 "isFinite(Infinity)" 'false'
# ── Phase 11.strmore: more String.prototype methods ───────────
check 3800 "'hello'.at(0)" '"h"'
check 3801 "'hello'.at(-1)" '"o"'