js-on-sx: hex-literal string→number coercion (+15 Number)
ES spec: ToNumber("0x0") == 0, ToNumber("0xFF") == 255. Our parser
returned NaN for anything with a 0x/0X prefix, failing S9.3.1_A16..A32
(every hex-literal assertion test case).
Added:
- js-hex-prefix? — is this an 0x/0X prefix?
- js-is-hex-body? — all remaining chars are [0-9a-fA-F]?
- js-parse-hex — walk chars, accumulate in base 16, NaN on bad char
- js-hex-digit-value — char → 0..15 (or -1)
js-is-numeric-string? short-circuits to the hex-body check on 0x*
prefix; js-num-from-string dispatches to js-parse-hex on same.
Unit 521/522, slice 148/148 unchanged.
Number scoreboard: 58/100 → 73/100 (+15).
Sample flipped: S9.3.1_A16 (0x0/0X0), A17..A31 (0x0..0xF and 0x10..0x1F
range coverage). Many of the remaining 22 fails are (new Number()).x
style prototype-chain introspection and MAX_VALUE precision.
This commit is contained in:
@@ -833,7 +833,22 @@
|
||||
|
||||
(define
|
||||
js-is-numeric-string?
|
||||
(fn (s) (js-is-numeric-loop s 0 false false false)))
|
||||
(fn
|
||||
(s)
|
||||
(if
|
||||
(js-hex-prefix? s)
|
||||
(js-is-hex-body? s 2 (len s))
|
||||
(js-is-numeric-loop s 0 false false false))))
|
||||
|
||||
(define
|
||||
js-is-hex-body?
|
||||
(fn
|
||||
(s i n)
|
||||
(cond
|
||||
((>= i n) (> n 2))
|
||||
((>= (js-hex-digit-value (char-at s i)) 0)
|
||||
(js-is-hex-body? s (+ i 1) n))
|
||||
(else false))))
|
||||
|
||||
(define
|
||||
js-is-numeric-loop
|
||||
@@ -886,6 +901,51 @@
|
||||
((> exp 0) (* base (js-pow-int base (- exp 1))))
|
||||
(else (/ 1 (js-pow-int base (- 0 exp)))))))
|
||||
|
||||
(define
|
||||
js-hex-prefix?
|
||||
(fn
|
||||
(s)
|
||||
(and
|
||||
(>= (len s) 2)
|
||||
(= (char-at s 0) "0")
|
||||
(or (= (char-at s 1) "x") (= (char-at s 1) "X")))))
|
||||
|
||||
(define
|
||||
js-parse-hex
|
||||
(fn
|
||||
(s i acc)
|
||||
(cond
|
||||
((>= i (len s)) acc)
|
||||
(else
|
||||
(let
|
||||
((c (char-at s i)) (d (js-hex-digit-value (char-at s i))))
|
||||
(cond
|
||||
((< d 0) (js-nan-value))
|
||||
(else (js-parse-hex s (+ i 1) (+ (* acc 16) d)))))))))
|
||||
|
||||
(define
|
||||
js-hex-digit-value
|
||||
(fn
|
||||
(c)
|
||||
(cond
|
||||
((= c "0") 0)
|
||||
((= c "1") 1)
|
||||
((= c "2") 2)
|
||||
((= c "3") 3)
|
||||
((= c "4") 4)
|
||||
((= c "5") 5)
|
||||
((= c "6") 6)
|
||||
((= c "7") 7)
|
||||
((= c "8") 8)
|
||||
((= c "9") 9)
|
||||
((or (= c "a") (= c "A")) 10)
|
||||
((or (= c "b") (= c "B")) 11)
|
||||
((or (= c "c") (= c "C")) 12)
|
||||
((or (= c "d") (= c "D")) 13)
|
||||
((or (= c "e") (= c "E")) 14)
|
||||
((or (= c "f") (= c "F")) 15)
|
||||
(else -1))))
|
||||
|
||||
(define
|
||||
js-num-from-string
|
||||
(fn
|
||||
@@ -894,6 +954,7 @@
|
||||
((trimmed (js-trim s)))
|
||||
(cond
|
||||
((= trimmed "") 0)
|
||||
((js-hex-prefix? trimmed) (js-parse-hex trimmed 2 0))
|
||||
(else
|
||||
(let
|
||||
((esplit (js-find-exp-char trimmed)))
|
||||
|
||||
Reference in New Issue
Block a user