js-on-sx: String wrapper objects + number-to-string sci notation expansion
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

- js-to-string: return __js_string_value__ for String wrapper dicts
- js-loose-eq: coerce String wrapper objects to primitive before compare
- String.__callable__: set __js_string_value__ + length on 'this' when called as constructor
- js-expand-sci-notation: new helper converts mantissa+exp to decimal or integer form
- js-number-to-string: expand 1e-06→0.000001, 1e+06→1000000; fix 1e+21 (was 1e21)
- String test262 subset: 45→58/100

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 14:27:13 +00:00
parent 80c21cbabb
commit 4d00250233
3 changed files with 98 additions and 85 deletions

View File

@@ -1169,7 +1169,14 @@
((= v false) "false")
((= (type-of v) "string") v)
((= (type-of v) "number") (js-number-to-string v))
(else (if (= (type-of v) "dict") "[object Object]" (str v))))))
(else
(if
(= (type-of v) "dict")
(if
(contains? (keys v) "__js_string_value__")
(get v "__js_string_value__")
"[object Object]")
(str v))))))
(define
js-template-concat
@@ -1187,6 +1194,32 @@
(+ i 1)
(str acc (js-to-string (nth parts i)))))))
(define
js-expand-sci-notation
(fn
(mant exp-n)
(let
((di (js-string-index-of mant "." 0)))
(let
((int-part (if (< di 0) mant (js-string-slice mant 0 di)))
(frac-part
(if (< di 0) "" (js-string-slice mant (+ di 1) (len mant)))))
(let
((all-digits (str int-part frac-part))
(frac-len (if (< di 0) 0 (- (- (len mant) di) 1))))
(if
(>= exp-n 0)
(if
(>= exp-n frac-len)
(str all-digits (js-string-repeat "0" (- exp-n frac-len)))
(let
((dot-pos (+ (len int-part) exp-n)))
(str
(js-string-slice all-digits 0 dot-pos)
"."
(js-string-slice all-digits dot-pos (len all-digits)))))
(str "0." (js-string-repeat "0" (- (- 0 exp-n) 1)) all-digits)))))))
(define
js-number-to-string
(fn
@@ -1195,7 +1228,16 @@
((js-number-is-nan n) "NaN")
((= n (js-infinity-value)) "Infinity")
((= n (- 0 (js-infinity-value))) "-Infinity")
(else (js-normalize-num-str (str n))))))
(else
(let
((pos-n (if (< n 0) (- 0 n) n)))
(let
((s0 (js-normalize-num-str (str pos-n))))
(let
((ei (js-string-index-of s0 "e" 0)))
(let
((precise (if (< ei 0) s0 (let ((exp-n (js-to-number (js-string-slice s0 (+ ei 1) (len s0))))) (if (and (>= exp-n -6) (<= exp-n 20)) (js-expand-sci-notation (js-string-slice s0 0 ei) exp-n) (if (>= exp-n 0) (str (js-string-slice s0 0 (+ ei 1)) "+" (str exp-n)) s0))))))
(if (< n 0) (str "-" precise) precise)))))))))
(define
js-normalize-num-str
@@ -1296,6 +1338,10 @@
(= (js-to-number a) b))
((= (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__"))
(js-loose-eq (get a "__js_string_value__") b))
((and (dict? b) (contains? (keys b) "__js_string_value__"))
(js-loose-eq a (get b "__js_string_value__")))
(else false))))
(define js-loose-neq (fn (a b) (not (js-loose-eq a b))))
@@ -3139,6 +3185,23 @@
(dict-set! String "fromCodePoint" js-string-from-code-point)
(dict-set!
String
"__callable__"
(fn
(&rest args)
(let
((raw (if (= (len args) 0) "" (js-to-string (nth args 0)))))
(let
((this-val (js-this)))
(if
(dict? this-val)
(begin
(dict-set! this-val "__js_string_value__" raw)
(dict-set! this-val "length" (len raw))
this-val)
raw)))))
(define Boolean {:__callable__ (fn (&rest args) (if (= (len args) 0) false (js-to-boolean (nth args 0))))})
(dict-set!

View File

@@ -1,72 +1,34 @@
{
"totals": {
"pass": 202,
"fail": 85,
"skip": 1597,
"timeout": 13,
"total": 1897,
"runnable": 300,
"pass_rate": 67.3
"pass": 58,
"fail": 33,
"skip": 1130,
"timeout": 9,
"total": 1230,
"runnable": 100,
"pass_rate": 58.0
},
"categories": [
{
"category": "built-ins/Math",
"total": 327,
"pass": 82,
"fail": 17,
"skip": 227,
"timeout": 1,
"pass_rate": 82.0,
"top_failures": [
[
"Test262Error (assertion failed)",
17
],
[
"Timeout",
1
]
]
},
{
"category": "built-ins/Number",
"total": 340,
"pass": 77,
"fail": 19,
"skip": 240,
"timeout": 4,
"pass_rate": 77.0,
"top_failures": [
[
"Test262Error (assertion failed)",
19
],
[
"Timeout",
4
]
]
},
{
"category": "built-ins/String",
"total": 1223,
"pass": 43,
"fail": 49,
"pass": 58,
"fail": 33,
"skip": 1123,
"timeout": 8,
"pass_rate": 43.0,
"timeout": 9,
"pass_rate": 58.0,
"top_failures": [
[
"Test262Error (assertion failed)",
42
28
],
[
"Timeout",
8
9
],
[
"TypeError: not a function",
3
"Unhandled: Not callable: \\\\\\",
1
],
[
"ReferenceError (undefined symbol)",
@@ -92,15 +54,15 @@
"top_failure_modes": [
[
"Test262Error (assertion failed)",
78
28
],
[
"Timeout",
13
9
],
[
"TypeError: not a function",
3
"Unhandled: Not callable: \\\\\\",
1
],
[
"ReferenceError (undefined symbol)",
@@ -111,7 +73,7 @@
1
],
[
"Unhandled: Not callable: \\\\\\",
"TypeError: not a function",
1
],
[
@@ -120,6 +82,6 @@
]
],
"pinned_commit": "d5e73fc8d2c663554fb72e2380a8c2bc1a318a33",
"elapsed_seconds": 102.4,
"workers": 2
"elapsed_seconds": 37.7,
"workers": 7
}

View File

@@ -1,44 +1,32 @@
# test262 scoreboard
Pinned commit: `d5e73fc8d2c663554fb72e2380a8c2bc1a318a33`
Wall time: 102.4s
Wall time: 37.7s
**Total:** 202/300 runnable passed (67.3%). Raw: pass=202 fail=85 skip=1597 timeout=13 total=1897.
**Total:** 58/100 runnable passed (58.0%). Raw: pass=58 fail=33 skip=1130 timeout=9 total=1230.
## Top failure modes
- **78x** Test262Error (assertion failed)
- **13x** Timeout
- **3x** TypeError: not a function
- **28x** Test262Error (assertion failed)
- **9x** Timeout
- **1x** Unhandled: Not callable: \\\
- **1x** ReferenceError (undefined symbol)
- **1x** SyntaxError (parse/unsupported syntax)
- **1x** Unhandled: Not callable: \\\
- **1x** TypeError: not a function
- **1x** Unhandled: js-transpile-binop: unsupported op: >>>\
## Categories (worst pass-rate first, min 10 runnable)
| Category | Pass | Fail | Skip | Timeout | Total | Pass % |
|---|---:|---:|---:|---:|---:|---:|
| built-ins/String | 43 | 49 | 1123 | 8 | 1223 | 43.0% |
| built-ins/Number | 77 | 19 | 240 | 4 | 340 | 77.0% |
| built-ins/Math | 82 | 17 | 227 | 1 | 327 | 82.0% |
| built-ins/String | 58 | 33 | 1123 | 9 | 1223 | 58.0% |
## Per-category top failures (min 10 runnable, worst first)
### built-ins/String (43/100 — 43.0%)
### built-ins/String (58/100 — 58.0%)
- **42x** Test262Error (assertion failed)
- **8x** Timeout
- **3x** TypeError: not a function
- **28x** Test262Error (assertion failed)
- **9x** Timeout
- **1x** Unhandled: Not callable: \\\
- **1x** ReferenceError (undefined symbol)
- **1x** SyntaxError (parse/unsupported syntax)
### built-ins/Number (77/100 — 77.0%)
- **19x** Test262Error (assertion failed)
- **4x** Timeout
### built-ins/Math (82/100 — 82.0%)
- **17x** Test262Error (assertion failed)
- **1x** Timeout