js-on-sx: js-loose-eq honours NaN inequality across numeric/string paths
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 22s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 22s
This commit is contained in:
@@ -2134,9 +2134,15 @@
|
||||
((and (= a nil) (js-undefined? b)) true)
|
||||
((and (js-undefined? a) (= b nil)) true)
|
||||
((and (js-numeric-type? a) (= (type-of b) "string"))
|
||||
(= (js-numeric-norm a) (js-to-number b)))
|
||||
(let ((an (js-numeric-norm a)) (bn (js-to-number b)))
|
||||
(cond
|
||||
((or (js-number-is-nan an) (js-number-is-nan bn)) false)
|
||||
(else (= an bn)))))
|
||||
((and (= (type-of a) "string") (js-numeric-type? b))
|
||||
(= (js-to-number a) (js-numeric-norm b)))
|
||||
(let ((an (js-to-number a)) (bn (js-numeric-norm b)))
|
||||
(cond
|
||||
((or (js-number-is-nan an) (js-number-is-nan bn)) false)
|
||||
(else (= an bn)))))
|
||||
((= (type-of a) "boolean") (js-loose-eq (js-to-number a) b))
|
||||
((= (type-of b) "boolean") (js-loose-eq a (js-to-number b)))
|
||||
((and (dict? a) (contains? (keys a) "__js_string_value__"))
|
||||
|
||||
@@ -158,6 +158,8 @@ Each item: implement → tests → update progress. Mark `[x]` when tests green.
|
||||
|
||||
Append-only record of completed iterations. Loop writes one line per iteration: date, what was done, test count delta.
|
||||
|
||||
- 2026-05-09 — **`==` returns false when either side is NaN, even across the numeric/string paths.** `js-loose-eq` was converting both sides to numbers (`Number.NaN == "string"` → `NaN == NaN`) and using SX `(=)`, which apparently returns true when both NaN values are the same reference. Per JS, NaN compares unequal to everything including itself. Wrapped both cross-type numeric/string branches in `(or (js-number-is-nan an) (js-number-is-nan bn))` short-circuits to false. Result: language/expressions/equals 20/30 → 23/30. strict-equals/Number/Object unchanged. conformance.sh: 148/148.
|
||||
|
||||
- 2026-05-09 — **Lexer: `}` ends the regex context, like `)` and `]`.** Was treating `/` after `}` as the start of a regex literal, so `({}) / function(){return 1}` lexed `} / function(){...})` as `}` + regex `/ function(){return 1}/`. Per JS, after `}` of an object literal we're in expression-end position and `/` is division. The "block vs object" distinction is context-sensitive, but in practice expression-position `}` is the common case and there is no statement/block hazard for our parser since blocks at expression position don't typically have a following `/`. Single-char addition to the no-regex-context check. Result: language/expressions/division 25/30 → 26/30. asi/Map/Object unchanged. conformance.sh: 148/148.
|
||||
|
||||
- 2026-05-09 — **`js-to-number` of functions/lists returns NaN / sensible coercion (was 0).** `js-to-number` had no clauses for `lambda`/`function`/`component`/`list` types, so they fell into the `(else 0)` arm. Per spec: ToNumber of any function is NaN, and ToNumber of an Array goes through ToPrimitive which calls `Array.prototype.toString` (the comma-join), so `[]` → "" → 0, `[5]` → "5" → 5, and `[1,2]` → "1,2" → NaN. Added explicit lambda/function/component clauses (return NaN) and a list clause (length 0 → 0, length 1 → recurse, else NaN). Now `function(){return 1} - function(){return 1}` is NaN instead of 0. Result: language/expressions/subtraction 25/30 → 26/30; multiplication 90%, division 83% confirmed unchanged-or-better. Object/Array/Number unchanged. conformance.sh: 148/148.
|
||||
|
||||
Reference in New Issue
Block a user