diff --git a/lib/js/runtime.sx b/lib/js/runtime.sx index b8bbf7b8..48a647d7 100644 --- a/lib/js/runtime.sx +++ b/lib/js/runtime.sx @@ -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)))