js-on-sx: exponent notation in js-string-to-number (+3 Number tests)
js-num-from-string now finds an e/E split, parses mantissa and exponent
separately, and combines via js-pow-int (positive-exp loop for >=0, 1/
reciprocal for negative). Previously `.12345e-3` parsed as 0.12345 and
"1e3" returned NaN — the parser walked decimals/dots only.
New helpers:
- js-find-exp-char / -loop : linear scan for e/E, returns -1 if absent
- js-pow-int base exp : integer-exp power, handles negative
Also fixed `js-string-trim` typo → `js-trim` in the rewritten num-from-
string, and corrected test 903's expected part count (3, not 2 — the
lexer has always split `hi ${x}!` into str+expr+str, the test just had
the wrong count).
Unit: 521/522 (was 520/522, 934 still blocked on SX \` escape).
Conformance: 148/148 unchanged.
Number scoreboard: 43/100 → 46/100 (+3).
Impacted test262 paths (sample): built-ins/Number/S9.3.1_A11.js and
A12/A16/A17 (".12345e-3", scientific notation round-trips).
This commit is contained in:
@@ -860,6 +860,26 @@
|
||||
|
||||
(define js-parse-num-safe (fn (s) (cond (else (js-num-from-string s)))))
|
||||
|
||||
(define js-find-exp-char (fn (s) (js-find-exp-char-loop s 0 (len s))))
|
||||
|
||||
(define
|
||||
js-find-exp-char-loop
|
||||
(fn
|
||||
(s i n)
|
||||
(cond
|
||||
((>= i n) -1)
|
||||
((or (= (char-at s i) "e") (= (char-at s i) "E")) i)
|
||||
(else (js-find-exp-char-loop s (+ i 1) n)))))
|
||||
|
||||
(define
|
||||
js-pow-int
|
||||
(fn
|
||||
(base exp)
|
||||
(cond
|
||||
((= exp 0) 1)
|
||||
((> exp 0) (* base (js-pow-int base (- exp 1))))
|
||||
(else (/ 1 (js-pow-int base (- 0 exp)))))))
|
||||
|
||||
(define
|
||||
js-num-from-string
|
||||
(fn
|
||||
@@ -868,7 +888,20 @@
|
||||
((trimmed (js-trim s)))
|
||||
(cond
|
||||
((= trimmed "") 0)
|
||||
(else (js-parse-decimal trimmed 0 0 1 false 0))))))
|
||||
(else
|
||||
(let
|
||||
((esplit (js-find-exp-char trimmed)))
|
||||
(if
|
||||
(>= esplit 0)
|
||||
(let
|
||||
((mant (js-string-slice trimmed 0 esplit))
|
||||
(expstr
|
||||
(js-string-slice trimmed (+ esplit 1) (len trimmed))))
|
||||
(let
|
||||
((m (js-parse-decimal mant 0 0 1 false 0))
|
||||
(e (js-parse-decimal expstr 0 0 1 false 0)))
|
||||
(* m (js-pow-int 10 e))))
|
||||
(js-parse-decimal trimmed 0 0 1 false 0))))))))
|
||||
|
||||
(define js-trim (fn (s) (js-trim-left (js-trim-right s))))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user