Skip to content

Commit 447ef2a

Browse files
committed
Add support for float_of_string
1 parent 5d8c561 commit 447ef2a

File tree

3 files changed

+49
-19
lines changed

3 files changed

+49
-19
lines changed

jscomp/core/js_number.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,11 @@ let is_hex_format (v : string) =
8686

8787
let caml_float_literal_to_js_string (v : string) : string =
8888
let len = String.length v in
89+
#if OCAML_VERSION =~ ">4.03.0" then
8990
if len >= 2 && is_hex_format v then
9091
to_string (float_of_string v)
9192
else
92-
93+
#end
9394
let rec aux buf i =
9495
if i >= len then buf
9596
else

jscomp/runtime/caml_format.ml

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,9 @@ let caml_format_float fmt x =
583583
FIXME: arity of float_of_string is not inferred correctly
584584
*)
585585

586-
let float_of_string : string -> exn -> float = fun%raw s exn -> {|
586+
let float_of_string : string -> exn -> float =
587+
#if OCAML_VERSION =~ ">4.3.0" then
588+
fun%raw s exn -> {|
587589
{
588590
var res = +s;
589591
if ((s.length > 0) && (res === res))
@@ -592,29 +594,42 @@ let float_of_string : string -> exn -> float = fun%raw s exn -> {|
592594
res = +s;
593595
if (((s.length > 0) && (res === res)) || /^[+-]?nan$/i.test(s)) {
594596
return res;
595-
}
596-
;
597-
if (/^ *0x[0-9a-f_]+p[+-]?[0-9_]+/i.test(s)) {
598-
var pidx = s.indexOf('p');
599-
pidx = (pidx == -1) ? s.indexOf('P') : pidx;
600-
var exp = +s.substring(pidx + 1);
601-
res = +s.substring(0, pidx);
602-
return res * Math.pow(2, exp);
597+
};
598+
var m = /^ *([+-]?)0x([0-9a-f]+)\.?([0-9a-f]*)p([+-]?[0-9]+)/i.exec(s);
599+
// 1 2 3 4
600+
if(m){
601+
var m3 = m[3].replace(/0+$/,'');
602+
var mantissa = parseInt(m[1] + m[2] + m3, 16);
603+
var exponent = (m[4]|0) - 4*m3.length;
604+
res = mantissa * Math.pow(2, exponent);
605+
return res;
603606
}
604607
if (/^\+?inf(inity)?$/i.test(s))
605608
return Infinity;
606609
if (/^-inf(inity)?$/i.test(s))
607610
return -Infinity;
608611
throw exn;
609612
}
610-
611613
|}
612-
613-
614-
(* let float_of_string (s : string) : float =
615-
let res : float = [%raw{|+s|}] in
616-
if String.length s > 0 && res = res then res
617-
else *)
614+
#else
615+
fun%raw s exn -> {|
616+
{
617+
var res = +s;
618+
if ((s.length > 0) && (res === res))
619+
return res;
620+
s = s.replace(/_/g, "");
621+
res = +s;
622+
if (((s.length > 0) && (res === res)) || /^[+-]?nan$/i.test(s)) {
623+
return res;
624+
};
625+
if (/^\+?inf(inity)?$/i.test(s))
626+
return Infinity;
627+
if (/^-inf(inity)?$/i.test(s))
628+
return -Infinity;
629+
throw exn;
630+
}
631+
|}
632+
#end
618633

619634
let caml_float_of_string s = float_of_string s (Failure "float_of_string")
620635

jscomp/test/format_test.ml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,27 @@ let () =
6868
;;
6969
#end
7070
(*TODO: add scanf example *)
71+
72+
let f loc ls =
73+
List.iter (fun (a,b) ->
74+
eq loc (float_of_string a) b ) ls
75+
76+
let () =
77+
f __LOC__ [
78+
"0x3.fp+1", 0x3.fp+1 ;
79+
" 0x3.fp2", 0x3.fp2;
80+
" 0x4.fp2", 0x4.fp2
81+
];
82+
83+
84+
;;
85+
7186
#if
7287
(* OCAML_VERSION =~ ">4.03.0" *) 0
7388
then
7489

7590

76-
let () =
77-
eq __LOC__ (float_of_string "0x3.fp+1") 0x3.fp+1;;
91+
7892

7993
let () = eq __LOC__ (Printf.sprintf "%h" 0x3.fp+1) "0x1.f8p+2"
8094
let () = eq __LOC__ (Printf.sprintf "%H" 0x3.fp+1) "0x1.F8P+2"

0 commit comments

Comments
 (0)