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") ((= v false) "false")
((= (type-of v) "string") v) ((= (type-of v) "string") v)
((= (type-of v) "number") (js-number-to-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 (define
js-template-concat js-template-concat
@@ -1187,6 +1194,32 @@
(+ i 1) (+ i 1)
(str acc (js-to-string (nth parts i))))))) (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 (define
js-number-to-string js-number-to-string
(fn (fn
@@ -1195,7 +1228,16 @@
((js-number-is-nan n) "NaN") ((js-number-is-nan n) "NaN")
((= n (js-infinity-value)) "Infinity") ((= n (js-infinity-value)) "Infinity")
((= n (- 0 (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 (define
js-normalize-num-str js-normalize-num-str
@@ -1296,6 +1338,10 @@
(= (js-to-number a) b)) (= (js-to-number a) b))
((= (type-of a) "boolean") (js-loose-eq (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))) ((= (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)))) (else false))))
(define js-loose-neq (fn (a b) (not (js-loose-eq a b)))) (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 "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))))}) (define Boolean {:__callable__ (fn (&rest args) (if (= (len args) 0) false (js-to-boolean (nth args 0))))})
(dict-set! (dict-set!

View File

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

View File

@@ -1,44 +1,32 @@
# test262 scoreboard # test262 scoreboard
Pinned commit: `d5e73fc8d2c663554fb72e2380a8c2bc1a318a33` 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 ## Top failure modes
- **78x** Test262Error (assertion failed) - **28x** Test262Error (assertion failed)
- **13x** Timeout - **9x** Timeout
- **3x** TypeError: not a function - **1x** Unhandled: Not callable: \\\
- **1x** ReferenceError (undefined symbol) - **1x** ReferenceError (undefined symbol)
- **1x** SyntaxError (parse/unsupported syntax) - **1x** SyntaxError (parse/unsupported syntax)
- **1x** Unhandled: Not callable: \\\ - **1x** TypeError: not a function
- **1x** Unhandled: js-transpile-binop: unsupported op: >>>\ - **1x** Unhandled: js-transpile-binop: unsupported op: >>>\
## Categories (worst pass-rate first, min 10 runnable) ## Categories (worst pass-rate first, min 10 runnable)
| Category | Pass | Fail | Skip | Timeout | Total | Pass % | | Category | Pass | Fail | Skip | Timeout | Total | Pass % |
|---|---:|---:|---:|---:|---:|---:| |---|---:|---:|---:|---:|---:|---:|
| built-ins/String | 43 | 49 | 1123 | 8 | 1223 | 43.0% | | built-ins/String | 58 | 33 | 1123 | 9 | 1223 | 58.0% |
| built-ins/Number | 77 | 19 | 240 | 4 | 340 | 77.0% |
| built-ins/Math | 82 | 17 | 227 | 1 | 327 | 82.0% |
## Per-category top failures (min 10 runnable, worst first) ## 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) - **28x** Test262Error (assertion failed)
- **8x** Timeout - **9x** Timeout
- **3x** TypeError: not a function - **1x** Unhandled: Not callable: \\\
- **1x** ReferenceError (undefined symbol) - **1x** ReferenceError (undefined symbol)
- **1x** SyntaxError (parse/unsupported syntax) - **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