From 1441f59f9b24d97932bf10b3be34a987c6d532f9 Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 8 Mar 2024 15:51:19 +0900 Subject: [PATCH 01/45] add primitive bigint --- jscomp/core/js_analyzer.ml | 2 + jscomp/core/js_dump.ml | 1 + jscomp/core/js_exp_make.ml | 14 + jscomp/core/js_exp_make.mli | 14 + jscomp/core/js_op.ml | 3 + jscomp/core/lam.ml | 2 +- jscomp/core/lam_analysis.ml | 6 +- jscomp/core/lam_compat.ml | 13 +- jscomp/core/lam_compat.mli | 4 +- jscomp/core/lam_compile_const.ml | 1 + jscomp/core/lam_compile_primitive.ml | 9 + jscomp/core/lam_constant_convert.ml | 2 +- jscomp/core/lam_convert.ml | 42 +-- jscomp/core/lam_primitive.ml | 13 + jscomp/core/lam_primitive.mli | 6 + jscomp/core/lam_print.ml | 7 + jscomp/ext/misc.ml | 1 - jscomp/ext/misc.mli | 1 - jscomp/frontend/ast_literal.ml | 11 + jscomp/frontend/ast_literal.mli | 4 + jscomp/frontend/bs_ast_invariant.ml | 2 - jscomp/frontend/bs_builtin_ppx.ml | 12 + jscomp/frontend/external_ffi_types.ml | 3 + jscomp/frontend/external_ffi_types.mli | 2 + jscomp/frontend/lam_constant.ml | 5 + jscomp/frontend/lam_constant.mli | 1 + jscomp/ml/asttypes.ml | 2 +- jscomp/ml/lambda.ml | 4 +- jscomp/ml/lambda.mli | 4 +- jscomp/ml/matching.ml | 4 +- jscomp/ml/parmatch.ml | 16 +- jscomp/ml/predef.ml | 6 +- jscomp/ml/predef.mli | 2 + jscomp/ml/primitive.ml | 2 +- jscomp/ml/primitive.mli | 4 +- jscomp/ml/printlambda.ml | 20 +- jscomp/ml/printtyped.ml | 2 +- jscomp/ml/translcore.ml | 14 +- jscomp/ml/typecore.ml | 10 +- jscomp/ml/typeopt.ml | 2 +- jscomp/ml/untypeast.ml | 2 +- jscomp/stdlib-406/pervasives.res | 10 + jscomp/stdlib-406/pervasives.resi | 43 +++ jscomp/stdlib-406/pervasivesU.res | 10 + jscomp/stdlib-406/pervasivesU.resi | 43 +++ jscomp/syntax/src/res_comments_table.ml | 3 +- jscomp/syntax/src/res_core.ml | 10 +- jscomp/syntax/src/res_parsetree_viewer.ml | 8 +- jscomp/syntax/src/res_printer.ml | 2 + jscomp/syntax/src/res_scanner.ml | 20 +- jscomp/syntax/src/res_token.ml | 14 +- .../errors/scanner/expected/nativeint.res.txt | 9 - .../parsing/grammar/expressions/binary.res | 1 + .../expressions/expected/binary.res.txt | 1 + .../expressions/expected/unary.res.txt | 4 + .../expected/unaryOrBinary.res.txt | 5 + .../parsing/grammar/expressions/unary.res | 4 + .../grammar/expressions/unaryOrBinary.res | 17 ++ jscomp/test/ocaml_re_test.js | 288 +++++++++--------- jscomp/test/test_per.res | 10 + 60 files changed, 531 insertions(+), 246 deletions(-) diff --git a/jscomp/core/js_analyzer.ml b/jscomp/core/js_analyzer.ml index 233050d0d9..b2f11354e9 100644 --- a/jscomp/core/js_analyzer.ml +++ b/jscomp/core/js_analyzer.ml @@ -158,6 +158,8 @@ let rec eq_expression ({ expression_desc = x0 } : J.expression) | Undefined x -> y0 = Undefined x | Number (Int { i }) -> ( match y0 with Number (Int { i = j }) -> i = j | _ -> false) + | Number (Bigint { i }) -> ( + match y0 with Number (Bigint { i = j }) -> i = j | _ -> false) | Number (Float _) -> false (* begin match y0 with | Number (Float j) -> diff --git a/jscomp/core/js_dump.ml b/jscomp/core/js_dump.ml index 09514211bc..b4b66d3dbc 100644 --- a/jscomp/core/js_dump.ml +++ b/jscomp/core/js_dump.ml @@ -664,6 +664,7 @@ and expression_desc cxt ~(level : int) f x : cxt = Int32.to_string i (* check , js convention with ocaml lexical convention *) | Uint i -> Format.asprintf "%lu" i + | Bigint { i } -> Format.asprintf "%sn" i in let need_paren = if s.[0] = '-' then level > 13 diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index 8ec00fbe58..57e7d4ae2c 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -312,6 +312,10 @@ let obj_int_tag_literal : t = let int ?comment ?c i : t = { expression_desc = Number (Int { i; c }); comment } +let bigint ?comment i : t = { expression_desc = Number (Bigint { i }); comment} + +let zero_bigint_literal : t = {expression_desc = Number (Bigint {i = "0"}); comment = None} + let small_int i : t = match i with | 0 -> zero_int_literal @@ -1253,6 +1257,16 @@ let rec int32_band ?comment (e1 : J.expression) (e2 : J.expression) : (* let int32_bin ?comment op e1 e2 : J.expression = *) (* {expression_desc = Int32_bin(op,e1, e2); comment} *) +let bigint_add ?comment (e1: t) (e2:t) = bin ?comment Plus e1 e2 + +let bigint_minus ?comment (e1: t) (e2: t) = bin ?comment Minus e1 e2 + +let bigint_mul ?comment (e1: t) (e2: t) = bin ?comment Mul e1 e2 + +let bigint_div ?comment (e1: t) (e2: t) = bin ?comment Div e1 e2 + +let bigint_mod ?comment (e1: t) (e2: t) = bin ?comment Mod e1 e2 + (* TODO -- alpha conversion remember to add parens.. *) diff --git a/jscomp/core/js_exp_make.mli b/jscomp/core/js_exp_make.mli index c16097ae10..d49055cd3d 100644 --- a/jscomp/core/js_exp_make.mli +++ b/jscomp/core/js_exp_make.mli @@ -111,6 +111,8 @@ val uint32 : ?comment:string -> int32 -> t val small_int : int -> t +val bigint : ?comment:string -> string -> t + val float : ?comment:string -> string -> t (* val empty_string_literal : t *) @@ -121,6 +123,8 @@ val zero_int_literal : t val zero_float_lit : t (* val obj_int_tag_literal : t *) +val zero_bigint_literal : t + val is_out : ?comment:string -> t -> t -> t (** [is_out e range] is equivalent to [e > range or e <0] @@ -272,6 +276,16 @@ val string_comp : Js_op.binop -> ?comment:string -> t -> t -> t val float_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t +val bigint_add : ?comment: string -> t -> t -> t + +val bigint_minus : ?comment: string -> t-> t -> t + +val bigint_mul : ?comment: string -> t -> t -> t + +val bigint_div : ?comment: string -> t -> t -> t + +val bigint_mod : ?comment: string -> t -> t -> t + val js_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t val not : t -> t diff --git a/jscomp/core/js_op.ml b/jscomp/core/js_op.ml index b01b3addc4..a2b7b07128 100644 --- a/jscomp/core/js_op.ml +++ b/jscomp/core/js_op.ml @@ -125,10 +125,13 @@ type 'a access = Getter | Setter (* literal char *) type float_lit = { f : string } [@@unboxed] +type bigint_lit = { i: string } [@@unboxed] + type number = | Float of float_lit | Int of { i : int32; c : int option } | Uint of int32 + | Bigint of bigint_lit (* becareful when constant folding +/-, since we treat it as js nativeint, bitwise operators: diff --git a/jscomp/core/lam.ml b/jscomp/core/lam.ml index 8aa5fe17bd..4f038257a8 100644 --- a/jscomp/core/lam.ml +++ b/jscomp/core/lam.ml @@ -641,7 +641,7 @@ let rec eval_const_as_bool (v : Lam_constant.t) : bool = | Const_int64 x -> x <> 0L | Const_js_false | Const_js_null | Const_module_alias | Const_js_undefined _ -> false - | Const_js_true | Const_string _ | Const_pointer _ | Const_float _ + | Const_js_true | Const_string _ | Const_pointer _ | Const_float _ | Const_bigint _ | Const_block _ | Const_float_array _ -> true | Const_some b -> eval_const_as_bool b diff --git a/jscomp/core/lam_analysis.ml b/jscomp/core/lam_analysis.ml index eacfe0a872..acae9aa749 100644 --- a/jscomp/core/lam_analysis.ml +++ b/jscomp/core/lam_analysis.ml @@ -27,6 +27,7 @@ let not_zero_constant (x : Lam_constant.t) = match x with | Const_int { i } -> i <> 0l | Const_int64 i -> i <> 0L + | Const_bigint i -> i <> "0" | _ -> false let rec no_side_effects (lam : Lam.t) : bool = @@ -53,7 +54,7 @@ let rec no_side_effects (lam : Lam.t) : bool = _ ) -> true | _, _ -> false) - | Pmodint | Pdivint | Pdivint64 | Pmodint64 -> ( + | Pmodint | Pdivint | Pdivint64 | Pmodint64 | Pdivbigint | Pmodbigint -> ( match args with | [ _; Lconst cst ] -> not_zero_constant cst | _ -> false) @@ -76,6 +77,7 @@ let rec no_side_effects (lam : Lam.t) : bool = | Pintoffloat | Pfloatofint | Pnegfloat (* | Pabsfloat *) | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pjscomp _ + | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu | Pbytesrefs | Pmakearray | Parraylength | Parrayrefu | Parrayrefs @@ -193,7 +195,7 @@ let rec size (lam : Lam.t) = and size_constant x = match x with - | Const_int _ | Const_char _ | Const_float _ | Const_int64 _ | Const_pointer _ + | Const_int _ | Const_char _ | Const_float _ | Const_int64 _ | Const_bigint _ | Const_pointer _ | Const_js_null | Const_js_undefined _ | Const_module_alias | Const_js_true | Const_js_false -> 1 diff --git a/jscomp/core/lam_compat.ml b/jscomp/core/lam_compat.ml index 9d36540241..83564523bc 100644 --- a/jscomp/core/lam_compat.ml +++ b/jscomp/core/lam_compat.ml @@ -22,11 +22,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -type boxed_integer = Lambda.boxed_integer = Pnativeint | Pint32 | Pint64 +type boxed_integer = Lambda.boxed_integer = Pbigint | Pint32 | Pint64 let eq_boxed_integer (p : boxed_integer) (p1 : boxed_integer) = match p with - | Pnativeint -> p1 = Pnativeint + | Pbigint -> p1 = Pbigint | Pint32 -> p1 = Pint32 | Pint64 -> p1 = Pint64 @@ -59,15 +59,6 @@ let cmp_int64 (cmp : comparison) (a : int64) b : bool = | Clt -> a < b | Cge -> a >= b -let cmp_nativeint (cmp : comparison) (a : nativeint) b : bool = - match cmp with - | Ceq -> a = b - | Cneq -> a <> b - | Cgt -> a > b - | Cle -> a <= b - | Clt -> a < b - | Cge -> a >= b - let cmp_float (cmp : comparison) (a : float) b : bool = match cmp with | Ceq -> a = b diff --git a/jscomp/core/lam_compat.mli b/jscomp/core/lam_compat.mli index b4e8ed41ac..de022543be 100644 --- a/jscomp/core/lam_compat.mli +++ b/jscomp/core/lam_compat.mli @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *) -type boxed_integer = Lambda.boxed_integer = Pnativeint | Pint32 | Pint64 +type boxed_integer = Lambda.boxed_integer = Pbigint | Pint32 | Pint64 type comparison = Lambda.comparison = Ceq | Cneq | Clt | Cgt | Cle | Cge @@ -59,8 +59,6 @@ val cmp_int32 : comparison -> int32 -> int32 -> bool val cmp_int64 : comparison -> int64 -> int64 -> bool -val cmp_nativeint : comparison -> nativeint -> nativeint -> bool - val cmp_float : comparison -> float -> float -> bool val cmp_int : comparison -> int -> int -> bool diff --git a/jscomp/core/lam_compile_const.ml b/jscomp/core/lam_compile_const.ml index 98acf07cb8..fe0884abd9 100644 --- a/jscomp/core/lam_compile_const.ml +++ b/jscomp/core/lam_compile_const.ml @@ -74,6 +74,7 @@ and translate (x : Lam_constant.t) : J.expression = (* E.float (Int64.to_string i) *) Js_long.of_const i (* https://github.com/google/closure-library/blob/master/closure%2Fgoog%2Fmath%2Flong.js *) + | Const_bigint i -> E.bigint i | Const_float f -> E.float f (* TODO: preserve float *) | Const_string { s; unicode = false } -> E.str s | Const_string { s; unicode = true } -> E.str ~delim:DStarJ s diff --git a/jscomp/core/lam_compile_primitive.ml b/jscomp/core/lam_compile_primitive.ml index 2afd22338e..a737be4389 100644 --- a/jscomp/core/lam_compile_primitive.ml +++ b/jscomp/core/lam_compile_primitive.ml @@ -183,6 +183,7 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) E.int32_minus E.zero_int_literal (Ext_list.singleton_exn args) | Pnegint64 -> Js_long.neg args | Pnegfloat -> E.float_minus E.zero_float_lit (Ext_list.singleton_exn args) + | Pnegbigint -> E.bigint_minus E.zero_bigint_literal (Ext_list.singleton_exn args) (* Negate boxed int end*) (* Int addition and subtraction *) | Paddint -> ( @@ -190,16 +191,22 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) | Paddint64 -> Js_long.add args | Paddfloat -> ( match args with [ e1; e2 ] -> E.float_add e1 e2 | _ -> assert false) + | Paddbigint -> ( + match args with [ e1; e2 ] -> E.bigint_add e1 e2 | _ -> assert false) | Psubint -> ( match args with [ e1; e2 ] -> E.int32_minus e1 e2 | _ -> assert false) | Psubint64 -> Js_long.sub args | Psubfloat -> ( match args with [ e1; e2 ] -> E.float_minus e1 e2 | _ -> assert false) + | Psubbigint -> ( + match args with [ e1; e2 ] -> E.bigint_minus e1 e2 | _ -> assert false) | Pmulint -> ( match args with [ e1; e2 ] -> E.int32_mul e1 e2 | _ -> assert false) | Pmulint64 -> Js_long.mul args | Pmulfloat -> ( match args with [ e1; e2 ] -> E.float_mul e1 e2 | _ -> assert false) + | Pmulbigint -> ( + match args with [ e1; e2 ] -> E.bigint_mul e1 e2 | _ -> assert false) | Pdivfloat -> ( match args with [ e1; e2 ] -> E.float_div e1 e2 | _ -> assert false) | Pdivint -> ( @@ -207,11 +214,13 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) | [ e1; e2 ] -> E.int32_div ~checked:!Js_config.check_div_by_zero e1 e2 | _ -> assert false) | Pdivint64 -> Js_long.div args + | Pdivbigint -> (match args with [ e1; e2 ] -> E.bigint_div e1 e2 | _ -> assert false) | Pmodint -> ( match args with | [ e1; e2 ] -> E.int32_mod ~checked:!Js_config.check_div_by_zero e1 e2 | _ -> assert false) | Pmodint64 -> Js_long.mod_ args + | Pmodbigint -> (match args with [ e1; e2 ] -> E.bigint_mod e1 e2 | _ -> assert false) | Plslint -> ( match args with [ e1; e2 ] -> E.int32_lsl e1 e2 | _ -> assert false) | Plslint64 -> Js_long.lsl_ args diff --git a/jscomp/core/lam_constant_convert.ml b/jscomp/core/lam_constant_convert.ml index 5e3fa49537..37c7a802de 100644 --- a/jscomp/core/lam_constant_convert.ml +++ b/jscomp/core/lam_constant_convert.ml @@ -36,7 +36,7 @@ let rec convert_constant (const : Lambda.structured_constant) : Lam_constant.t = | Const_base (Const_float i) -> Const_float i | Const_base (Const_int32 i) -> Const_int { i; comment = None } | Const_base (Const_int64 i) -> Const_int64 i - | Const_base (Const_nativeint _) -> assert false + | Const_base (Const_bigint i) -> Const_bigint i | Const_pointer (0, Pt_constructor { name = "()"; const = 1; non_const = 0 }) -> Const_js_undefined {isUnit = true} diff --git a/jscomp/core/lam_convert.ml b/jscomp/core/lam_convert.ml index dd376230a1..b77dfa5d47 100644 --- a/jscomp/core/lam_convert.ml +++ b/jscomp/core/lam_convert.ml @@ -254,6 +254,12 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t = | Psubfloat -> prim ~primitive:Psubfloat ~args loc | Pmulfloat -> prim ~primitive:Pmulfloat ~args loc | Pdivfloat -> prim ~primitive:Pdivfloat ~args loc + | Pnegbigint -> prim ~primitive:Pnegbigint ~args loc + | Paddbigint -> prim ~primitive:Paddbigint ~args loc + | Psubbigint -> prim ~primitive:Psubbigint ~args loc + | Pmulbigint -> prim ~primitive:Pmulbigint ~args loc + | Pdivbigint _is_safe (*FIXME*) -> prim ~primitive:Pdivbigint ~args loc + | Pmodbigint _is_safe (*FIXME*) -> prim ~primitive:Pmodbigint ~args loc | Pintcomp x -> prim ~primitive:(Pintcomp x) ~args loc | Poffsetint x -> prim ~primitive:(Poffsetint x) ~args loc | Poffsetref x -> prim ~primitive:(Poffsetref x) ~args loc @@ -266,59 +272,59 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t = | Parraysets -> prim ~primitive:Parraysets ~args loc | Pbintofint x -> ( match x with - | Pint32 | Pnativeint -> Ext_list.singleton_exn args + | Pint32 | Pbigint -> Ext_list.singleton_exn args | Pint64 -> prim ~primitive:Pint64ofint ~args loc) | Pintofbint x -> ( match x with - | Pint32 | Pnativeint -> Ext_list.singleton_exn args + | Pint32 | Pbigint -> Ext_list.singleton_exn args | Pint64 -> prim ~primitive:Pintofint64 ~args loc) | Pnegbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Pnegint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Pnegint ~args loc | Pint64 -> prim ~primitive:Pnegint64 ~args loc) | Paddbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Paddint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Paddint ~args loc | Pint64 -> prim ~primitive:Paddint64 ~args loc) | Psubbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Psubint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Psubint ~args loc | Pint64 -> prim ~primitive:Psubint64 ~args loc) | Pmulbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Pmulint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Pmulint ~args loc | Pint64 -> prim ~primitive:Pmulint64 ~args loc) | Pdivbint { size = x; is_safe = _ } (*FIXME*) -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Pdivint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Pdivint ~args loc | Pint64 -> prim ~primitive:Pdivint64 ~args loc) | Pmodbint { size = x; is_safe = _ } (*FIXME*) -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Pmodint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Pmodint ~args loc | Pint64 -> prim ~primitive:Pmodint64 ~args loc) | Pandbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Pandint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Pandint ~args loc | Pint64 -> prim ~primitive:Pandint64 ~args loc) | Porbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Porint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Porint ~args loc | Pint64 -> prim ~primitive:Porint64 ~args loc) | Pxorbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Pxorint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Pxorint ~args loc | Pint64 -> prim ~primitive:Pxorint64 ~args loc) | Plslbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Plslint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Plslint ~args loc | Pint64 -> prim ~primitive:Plslint64 ~args loc) | Plsrbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Plsrint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Plsrint ~args loc | Pint64 -> prim ~primitive:Plsrint64 ~args loc) | Pasrbint x -> ( match x with - | Pnativeint | Pint32 -> prim ~primitive:Pasrint ~args loc + | Pbigint | Pint32 -> prim ~primitive:Pasrint ~args loc | Pint64 -> prim ~primitive:Pasrint64 ~args loc) | Pctconst x -> ( match x with @@ -333,13 +339,13 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t = | Backend_type -> prim ~primitive:(Pctconst Backend_type) ~args loc) | Pcvtbint (a, b) -> ( match (a, b) with - | (Pnativeint | Pint32), (Pnativeint | Pint32) | Pint64, Pint64 -> + | (Pbigint | Pint32), (Pbigint | Pint32) | Pint64, Pint64 -> Ext_list.singleton_exn args - | Pint64, (Pnativeint | Pint32) -> prim ~primitive:Pintofint64 ~args loc - | (Pnativeint | Pint32), Pint64 -> prim ~primitive:Pint64ofint ~args loc) + | Pint64, (Pbigint | Pint32) -> prim ~primitive:Pintofint64 ~args loc + | (Pbigint | Pint32), Pint64 -> prim ~primitive:Pint64ofint ~args loc) | Pbintcomp (a, b) -> ( match a with - | Pnativeint | Pint32 -> prim ~primitive:(Pintcomp b) ~args loc + | Pbigint | Pint32 -> prim ~primitive:(Pintcomp b) ~args loc | Pint64 -> prim ~primitive:(Pint64comp b) ~args loc) | Popaque -> Ext_list.singleton_exn args diff --git a/jscomp/core/lam_primitive.ml b/jscomp/core/lam_primitive.ml index 552906858e..c79196b46f 100644 --- a/jscomp/core/lam_primitive.ml +++ b/jscomp/core/lam_primitive.ml @@ -80,6 +80,13 @@ type t = | Psubfloat | Pmulfloat | Pdivfloat + (* Bigint operations *) + | Pnegbigint + | Paddbigint + | Psubbigint + | Pmulbigint + | Pdivbigint + | Pmodbigint | Pintcomp of Lam_compat.comparison | Pfloatcomp of Lam_compat.comparison | Pjscomp of Lam_compat.comparison @@ -201,6 +208,12 @@ let eq_primitive_approx (lhs : t) (rhs : t) = | Psubfloat -> rhs = Psubfloat | Pmulfloat -> rhs = Pmulfloat | Pdivfloat -> rhs = Pdivfloat + | Pnegbigint -> rhs = Pnegbigint + | Paddbigint -> rhs = Paddbigint + | Psubbigint -> rhs = Psubbigint + | Pmulbigint -> rhs = Pmulbigint + | Pdivbigint -> rhs = Pdivbigint + | Pmodbigint -> rhs = Pmodbigint | Pjs_apply -> rhs = Pjs_apply | Pjs_runtime_apply -> rhs = Pjs_runtime_apply | Pstringlength -> rhs = Pstringlength diff --git a/jscomp/core/lam_primitive.mli b/jscomp/core/lam_primitive.mli index 4c05d7fe2d..2a6efc3d85 100644 --- a/jscomp/core/lam_primitive.mli +++ b/jscomp/core/lam_primitive.mli @@ -71,6 +71,12 @@ type t = | Psubfloat | Pmulfloat | Pdivfloat + | Pnegbigint + | Paddbigint + | Psubbigint + | Pmulbigint + | Pdivbigint + | Pmodbigint | Pintcomp of Lam_compat.comparison | Pfloatcomp of Lam_compat.comparison | Pjscomp of Lam_compat.comparison diff --git a/jscomp/core/lam_print.ml b/jscomp/core/lam_print.ml index f7390234c5..c74005e39c 100644 --- a/jscomp/core/lam_print.ml +++ b/jscomp/core/lam_print.ml @@ -25,6 +25,7 @@ let rec struct_const ppf (cst : Lam_constant.t) = | Const_string { s } -> fprintf ppf "%S" s | Const_float f -> fprintf ppf "%s" f | Const_int64 n -> fprintf ppf "%LiL" n + | Const_bigint i -> fprintf ppf "%sn" i | Const_pointer name -> fprintf ppf "`%s" name | Const_some n -> fprintf ppf "[some-c]%a" struct_const n | Const_block (tag, _, []) -> fprintf ppf "[%i]" tag @@ -133,6 +134,12 @@ let primitive ppf (prim : Lam_primitive.t) = | Pfloatcomp Cle -> fprintf ppf "<=." | Pfloatcomp Cgt -> fprintf ppf ">." | Pfloatcomp Cge -> fprintf ppf ">=." + | Pnegbigint -> fprintf ppf "~n" + | Paddbigint -> fprintf ppf "+n" + | Psubbigint -> fprintf ppf "-n" + | Pmulbigint -> fprintf ppf "*n" + | Pdivbigint -> fprintf ppf "/n" + | Pmodbigint -> fprintf ppf "modn" | Pjscomp Ceq -> fprintf ppf "#==" | Pjscomp Cneq -> fprintf ppf "#!=" | Pjscomp Clt -> fprintf ppf "#<" diff --git a/jscomp/ext/misc.ml b/jscomp/ext/misc.ml index eef6e4760f..33ca3eee56 100644 --- a/jscomp/ext/misc.ml +++ b/jscomp/ext/misc.ml @@ -330,7 +330,6 @@ module Int_literal_converter = struct let int s = cvt_int_aux s (~-) int_of_string let int32 s = cvt_int_aux s Int32.neg Int32.of_string let int64 s = cvt_int_aux s Int64.neg Int64.of_string - let nativeint s = cvt_int_aux s Nativeint.neg Nativeint.of_string end (* String operations *) diff --git a/jscomp/ext/misc.mli b/jscomp/ext/misc.mli index 61dfdf0a72..33878bb1d2 100644 --- a/jscomp/ext/misc.mli +++ b/jscomp/ext/misc.mli @@ -163,7 +163,6 @@ module Int_literal_converter : sig val int : string -> int val int32 : string -> int32 val int64 : string -> int64 - val nativeint : string -> nativeint end val chop_extensions: string -> string diff --git a/jscomp/frontend/ast_literal.ml b/jscomp/frontend/ast_literal.ml index a4453f646f..41a641ee8d 100644 --- a/jscomp/frontend/ast_literal.ml +++ b/jscomp/frontend/ast_literal.ml @@ -43,6 +43,8 @@ module Lid = struct let type_int : t = Lident "int" (* use *predef* *) + let type_bigint : t = Lident "bigint" (* use *predef* *) + let type_exn : t = Lident "exn" (* use *predef* *) let type_bool : t = Lident "bool" (* use *predef* *) @@ -85,6 +87,9 @@ module No_loc = struct let type_int = Ast_helper.Typ.mk (Ptyp_constr ({txt = Lid.type_int; loc}, [])) + let type_bigint = + Ast_helper.Typ.mk (Ptyp_constr ({txt = Lid.type_bigint; loc}, [])) + let type_string = Ast_helper.Typ.mk (Ptyp_constr ({txt = Lid.type_string; loc}, [])) @@ -147,6 +152,12 @@ let type_float = Ast_helper.Typ.mk (Ptyp_constr ({txt = Lident "float"; loc = Location.none}, [])) +let type_bigint ?loc () = + match loc with + | None -> No_loc.type_bigint + | Some loc -> + Ast_helper.Typ.mk ~loc (Ptyp_constr ({txt = Lid.type_bigint; loc}, [])) + let type_any ?loc () = match loc with | None -> No_loc.type_any diff --git a/jscomp/frontend/ast_literal.mli b/jscomp/frontend/ast_literal.mli index ca51dbc4f7..e77b0259f8 100644 --- a/jscomp/frontend/ast_literal.mli +++ b/jscomp/frontend/ast_literal.mli @@ -39,6 +39,8 @@ module Lid : sig val type_int : t + val type_bigint : t + val js_internal_full_apply : t val opaque : t @@ -84,6 +86,8 @@ val type_int64 : Parsetree.core_type val type_float : Parsetree.core_type +val type_bigint : core_type_lit + val type_any : core_type_lit val pat_unit : pattern_lit diff --git a/jscomp/frontend/bs_ast_invariant.ml b/jscomp/frontend/bs_ast_invariant.ml index 131b0f0526..b7abb886d7 100644 --- a/jscomp/frontend/bs_ast_invariant.ml +++ b/jscomp/frontend/bs_ast_invariant.ml @@ -83,8 +83,6 @@ let check_constant loc (const : Parsetree.constant) = *) try ignore @@ Int32.of_string s with _ -> Bs_warnings.warn_literal_overflow loc) - | Pconst_integer (_, Some 'n') -> - Location.raise_errorf ~loc "literal with `n` suffix is not supported" | _ -> () (* Note we only used Bs_ast_iterator here, we can reuse compiler-libs instead of diff --git a/jscomp/frontend/bs_builtin_ppx.ml b/jscomp/frontend/bs_builtin_ppx.ml index 7974fb7fad..bc0afb0f4c 100644 --- a/jscomp/frontend/bs_builtin_ppx.ml +++ b/jscomp/frontend/bs_builtin_ppx.ml @@ -341,6 +341,18 @@ let signature_item_mapper (self : mapper) (sigi : Parsetree.signature_item) : pval_attributes = []; }; } + | Pexp_constant (Pconst_integer (s, Some 'n')) -> + succeed attr pval_attributes; + { + sigi with + psig_desc = + Psig_value + { + value_desc with + pval_prim = External_ffi_types.inline_bigint_primitive s; + pval_attributes = []; + }; + } | Pexp_constant (Pconst_float (s, None)) -> succeed attr pval_attributes; { diff --git a/jscomp/frontend/external_ffi_types.ml b/jscomp/frontend/external_ffi_types.ml index cdbe19b970..152c0ef7ac 100644 --- a/jscomp/frontend/external_ffi_types.ml +++ b/jscomp/frontend/external_ffi_types.ml @@ -300,6 +300,9 @@ let inline_int_primitive (i : int32) : string list = let inline_int64_primitive (i : int64) : string list = [""; to_string (Ffi_inline_const (Const_int64 i))] +let inline_bigint_primitive (i : string) : string list = + [""; to_string (Ffi_inline_const (Const_bigint i))] + let inline_float_primitive (i : string) : string list = [""; to_string (Ffi_inline_const (Const_float i))] let rec ffi_bs_aux acc (params : External_arg_spec.params) = diff --git a/jscomp/frontend/external_ffi_types.mli b/jscomp/frontend/external_ffi_types.mli index 76d0a89f9e..a96c06cbe3 100644 --- a/jscomp/frontend/external_ffi_types.mli +++ b/jscomp/frontend/external_ffi_types.mli @@ -107,6 +107,8 @@ val inline_int64_primitive : int64 -> string list val inline_float_primitive : string -> string list +val inline_bigint_primitive : string -> string list + val ffi_bs : External_arg_spec.params -> return_wrapper -> external_spec -> t val ffi_bs_as_prims : diff --git a/jscomp/frontend/lam_constant.ml b/jscomp/frontend/lam_constant.ml index 346dc02368..4c24e0906c 100644 --- a/jscomp/frontend/lam_constant.ml +++ b/jscomp/frontend/lam_constant.ml @@ -50,6 +50,7 @@ type t = | Const_string of {s: string; unicode: bool} | Const_float of string | Const_int64 of int64 + | Const_bigint of string | Const_pointer of string | Const_block of int * Lambda.tag_info * t list | Const_float_array of string list @@ -86,6 +87,10 @@ let rec eq_approx (x : t) (y : t) = match y with | Const_int64 iy -> ix = iy | _ -> false) + | Const_bigint ix -> ( + match y with + | Const_bigint iy -> ix = iy + | _ -> false) | Const_pointer ix -> ( match y with | Const_pointer iy -> ix = iy diff --git a/jscomp/frontend/lam_constant.mli b/jscomp/frontend/lam_constant.mli index 3426b9a466..76c5bdad48 100644 --- a/jscomp/frontend/lam_constant.mli +++ b/jscomp/frontend/lam_constant.mli @@ -46,6 +46,7 @@ type t = | Const_string of {s: string; unicode: bool} | Const_float of string | Const_int64 of int64 + | Const_bigint of string | Const_pointer of string | Const_block of int * Lambda.tag_info * t list | Const_float_array of string list diff --git a/jscomp/ml/asttypes.ml b/jscomp/ml/asttypes.ml index 8fefc45283..59314145ea 100644 --- a/jscomp/ml/asttypes.ml +++ b/jscomp/ml/asttypes.ml @@ -22,7 +22,7 @@ type constant = | Const_float of string | Const_int32 of int32 | Const_int64 of int64 - | Const_nativeint of nativeint + | Const_bigint of string type rec_flag = Nonrecursive | Recursive diff --git a/jscomp/ml/lambda.ml b/jscomp/ml/lambda.ml index 337dd10e9e..69dc253850 100644 --- a/jscomp/ml/lambda.ml +++ b/jscomp/ml/lambda.ml @@ -229,6 +229,8 @@ type primitive = | Pnegfloat | Pabsfloat | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp of comparison + (* Bigint operations *) + | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu | Pbytessetu | Pbytesrefs | Pbytessets @@ -273,7 +275,7 @@ and value_kind = and boxed_integer = Primitive.boxed_integer = - Pnativeint | Pint32 | Pint64 + Pbigint | Pint32 | Pint64 and raise_kind = diff --git a/jscomp/ml/lambda.mli b/jscomp/ml/lambda.mli index 3a9b847c9c..5d4f771f33 100644 --- a/jscomp/ml/lambda.mli +++ b/jscomp/ml/lambda.mli @@ -195,6 +195,8 @@ type primitive = | Pnegfloat | Pabsfloat | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp of comparison + (* Bigint operations *) + | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu | Pbytessetu | Pbytesrefs | Pbytessets @@ -240,7 +242,7 @@ and value_kind = and boxed_integer = Primitive.boxed_integer = - Pnativeint | Pint32 | Pint64 + Pbigint | Pint32 | Pint64 and raise_kind = diff --git a/jscomp/ml/matching.ml b/jscomp/ml/matching.ml index 30fa8efb72..79adae5b21 100644 --- a/jscomp/ml/matching.ml +++ b/jscomp/ml/matching.ml @@ -2236,10 +2236,10 @@ let combine_constant names loc arg cst partial ctx def fail (Pbintcomp(Pint64, Cneq)) (Pbintcomp(Pint64, Clt)) arg const_lambda_list - | Const_nativeint _ -> + | Const_bigint _ -> make_test_sequence loc fail - (Pbintcomp(Pnativeint, Cneq)) (Pbintcomp(Pnativeint, Clt)) + (Pbintcomp(Pbigint, Cneq)) (Pbintcomp(Pbigint, Clt)) arg const_lambda_list in lambda1,jumps_union local_jumps total diff --git a/jscomp/ml/parmatch.ml b/jscomp/ml/parmatch.ml index d93f1a63df..46030055e7 100644 --- a/jscomp/ml/parmatch.ml +++ b/jscomp/ml/parmatch.ml @@ -150,14 +150,14 @@ let all_coherent column = | Const_int _, Const_int _ | Const_int32 _, Const_int32 _ | Const_int64 _, Const_int64 _ - | Const_nativeint _, Const_nativeint _ + | Const_bigint _, Const_bigint _ | Const_float _, Const_float _ | Const_string _, Const_string _ -> true | ( Const_char _ | Const_int _ | Const_int32 _ | Const_int64 _ - | Const_nativeint _ + | Const_bigint _ | Const_float _ | Const_string _), _ -> false end @@ -384,7 +384,7 @@ let pretty_const c = match c with | Const_float f -> Printf.sprintf "%s" f | Const_int32 i -> Printf.sprintf "%ldl" i | Const_int64 i -> Printf.sprintf "%LdL" i -| Const_nativeint i -> Printf.sprintf "%ndn" i +| Const_bigint i -> Printf.sprintf "%s" i let rec pretty_val ppf v = match v.pat_extra with @@ -1102,11 +1102,11 @@ let build_other ext env : Typedtree.pattern = match env with (function Tpat_constant(Const_int64 i) -> i | _ -> assert false) (function i -> Tpat_constant(Const_int64 i)) 0L Int64.succ p env -| ({pat_desc=(Tpat_constant (Const_nativeint _))} as p,_) :: _ -> +| ({pat_desc=(Tpat_constant (Const_bigint _))} as p,_) :: _ -> build_other_constant - (function Tpat_constant(Const_nativeint i) -> i | _ -> assert false) - (function i -> Tpat_constant(Const_nativeint i)) - 0n Nativeint.succ p env + (function Tpat_constant(Const_bigint i) -> String.length i | _ -> assert false) + (function i -> Tpat_constant(Const_bigint (String.make i '*'))) + 0 succ p env | ({pat_desc=(Tpat_constant (Const_string _))} as p,_) :: _ -> build_other_constant (function Tpat_constant(Const_string (s, _)) -> String.length s @@ -2293,7 +2293,7 @@ let inactive ~partial pat = match c with | Const_string _ -> true (*Config.safe_string*) | Const_int _ | Const_char _ | Const_float _ - | Const_int32 _ | Const_int64 _ | Const_nativeint _ -> true + | Const_int32 _ | Const_int64 _ | Const_bigint _ -> true end | Tpat_tuple ps | Tpat_construct (_, _, ps) -> List.for_all (fun p -> loop p) ps diff --git a/jscomp/ml/predef.ml b/jscomp/ml/predef.ml index ad241cdd23..f318d7e84d 100644 --- a/jscomp/ml/predef.ml +++ b/jscomp/ml/predef.ml @@ -43,6 +43,7 @@ and ident_result = ident_create "result" and ident_dict = ident_create "dict" and ident_int64 = ident_create "int64" +and ident_bigint = ident_create "bigint" and ident_lazy_t = ident_create "lazy_t" and ident_string = ident_create "string" and ident_extension_constructor = ident_create "extension_constructor" @@ -87,6 +88,7 @@ and path_dict = Pident ident_dict and path_int64 = Pident ident_int64 +and path_bigint = Pident ident_bigint and path_lazy_t = Pident ident_lazy_t and path_string = Pident ident_string @@ -111,6 +113,7 @@ and type_result t1 t2 = newgenty (Tconstr(path_result, [t1; t2], ref Mnil)) and type_dict t = newgenty (Tconstr(path_dict, [t], ref Mnil)) and type_int64 = newgenty (Tconstr(path_int64, [], ref Mnil)) +and type_bigint = newgenty (Tconstr(path_bigint, [], ref Mnil)) and type_lazy_t t = newgenty (Tconstr(path_lazy_t, [t], ref Mnil)) and type_string = newgenty (Tconstr(path_string, [], ref Mnil)) @@ -298,6 +301,7 @@ let common_initial_env add_type add_extension empty_env = add_extension ident_undefined_recursive_module [newgenty (Ttuple[type_string; type_int; type_int])] ( add_type ident_int64 decl_abstr ( + add_type ident_bigint decl_abstr ( add_type ident_lazy_t decl_lazy_t ( add_type ident_option decl_option ( @@ -316,7 +320,7 @@ let common_initial_env add_type add_extension empty_env = add_type ident_extension_constructor decl_abstr ( add_type ident_floatarray decl_abstr ( add_type ident_promise decl_promise ( - empty_env))))))))))))))))))))))))))) + empty_env)))))))))))))))))))))))))))) let build_initial_env add_type add_exception empty_env = let common = common_initial_env add_type add_exception empty_env in diff --git a/jscomp/ml/predef.mli b/jscomp/ml/predef.mli index c19bb68733..a8049b5325 100644 --- a/jscomp/ml/predef.mli +++ b/jscomp/ml/predef.mli @@ -32,6 +32,7 @@ val type_result: type_expr -> type_expr -> type_expr val type_dict: type_expr -> type_expr val type_int64: type_expr +val type_bigint: type_expr val type_lazy_t: type_expr -> type_expr val type_extension_constructor:type_expr val type_floatarray:type_expr @@ -51,6 +52,7 @@ val path_result: Path.t val path_dict: Path.t val path_int64: Path.t +val path_bigint: Path.t val path_lazy_t: Path.t val path_extension_constructor: Path.t val path_floatarray: Path.t diff --git a/jscomp/ml/primitive.ml b/jscomp/ml/primitive.ml index ad0504a096..0fff0ccc77 100644 --- a/jscomp/ml/primitive.ml +++ b/jscomp/ml/primitive.ml @@ -18,7 +18,7 @@ open Misc open Parsetree -type boxed_integer = Pnativeint | Pint32 | Pint64 +type boxed_integer = Pbigint | Pint32 | Pint64 type native_repr = | Same_as_ocaml_repr diff --git a/jscomp/ml/primitive.mli b/jscomp/ml/primitive.mli index ecc2245623..c364c4cc04 100644 --- a/jscomp/ml/primitive.mli +++ b/jscomp/ml/primitive.mli @@ -15,7 +15,7 @@ (* Description of primitive functions *) -type boxed_integer = Pnativeint | Pint32 | Pint64 +type boxed_integer = Pbigint | Pint32 | Pint64 (* Representation of arguments/result for the native code version of a primitive *) @@ -62,4 +62,4 @@ val byte_name: description -> string val coerce : - (description -> description -> bool ) ref \ No newline at end of file + (description -> description -> bool ) ref diff --git a/jscomp/ml/printlambda.ml b/jscomp/ml/printlambda.ml index 8542238594..856495421f 100644 --- a/jscomp/ml/printlambda.ml +++ b/jscomp/ml/printlambda.ml @@ -27,7 +27,7 @@ let rec struct_const ppf = function | Const_base(Const_float f) -> fprintf ppf "%s" f | Const_base(Const_int32 n) -> fprintf ppf "%lil" n | Const_base(Const_int64 n) -> fprintf ppf "%LiL" n - | Const_base(Const_nativeint n) -> fprintf ppf "%nin" n + | Const_base(Const_bigint n) -> fprintf ppf "%sn" n | Const_pointer (n,_) -> fprintf ppf "%ia" n | Const_block(tag_info, []) -> let tag = Lambda.tag_of_tag_info tag_info in @@ -47,7 +47,7 @@ let rec struct_const ppf = function | Const_false -> fprintf ppf "false" | Const_true -> fprintf ppf "true" let boxed_integer_name = function - | Pnativeint -> "nativeint" + | Pbigint -> "bigint" | Pint32 -> "int32" | Pint64 -> "int64" @@ -64,7 +64,7 @@ let print_boxed_integer_conversion ppf bi1 bi2 = fprintf ppf "%s_of_%s" (boxed_integer_name bi2) (boxed_integer_name bi1) let boxed_integer_mark name = function - | Pnativeint -> Printf.sprintf "Nativeint.%s" name + | Pbigint -> Printf.sprintf "Bigint.%s" name | Pint32 -> Printf.sprintf "Int32.%s" name | Pint64 -> Printf.sprintf "Int64.%s" name @@ -177,6 +177,14 @@ let primitive ppf = function | Pfloatcomp(Cle) -> fprintf ppf "<=." | Pfloatcomp(Cgt) -> fprintf ppf ">." | Pfloatcomp(Cge) -> fprintf ppf ">=." + | Pnegbigint -> fprintf ppf "~n" + | Paddbigint -> fprintf ppf "+n" + | Psubbigint -> fprintf ppf "-n" + | Pmulbigint -> fprintf ppf "*n" + | Pdivbigint Safe -> fprintf ppf "/n" + | Pdivbigint Unsafe -> fprintf ppf "/nu" + | Pmodbigint Safe -> fprintf ppf "mod" + | Pmodbigint Unsafe -> fprintf ppf "mod_unsafe" | Pstringlength -> fprintf ppf "string.length" | Pstringrefu -> fprintf ppf "string.unsafe_get" | Pstringrefs -> fprintf ppf "string.get" @@ -278,6 +286,12 @@ let name_of_primitive = function | Pmulfloat -> "Pmulfloat" | Pdivfloat -> "Pdivfloat" | Pfloatcomp _ -> "Pfloatcomp" + | Pnegbigint -> "Pnegbigint" + | Paddbigint -> "Paddbigint" + | Psubbigint -> "Psubbigint" + | Pmulbigint -> "Pmulbigint" + | Pdivbigint _ -> "Pdivbigint" + | Pmodbigint _ -> "Pmodbigint" | Pstringlength -> "Pstringlength" | Pstringrefu -> "Pstringrefu" | Pstringrefs -> "Pstringrefs" diff --git a/jscomp/ml/printtyped.ml b/jscomp/ml/printtyped.ml index f6243f6c6e..af0c093189 100644 --- a/jscomp/ml/printtyped.ml +++ b/jscomp/ml/printtyped.ml @@ -65,7 +65,7 @@ let fmt_constant f x = | Const_float (s) -> fprintf f "Const_float %s" s; | Const_int32 (i) -> fprintf f "Const_int32 %ld" i; | Const_int64 (i) -> fprintf f "Const_int64 %Ld" i; - | Const_nativeint (i) -> fprintf f "Const_nativeint %nd" i; + | Const_bigint (i) -> fprintf f "Const_bigint %s" i; ;; let fmt_mutable_flag f x = diff --git a/jscomp/ml/translcore.ml b/jscomp/ml/translcore.ml index 512940c72e..0102b5c556 100644 --- a/jscomp/ml/translcore.ml +++ b/jscomp/ml/translcore.ml @@ -350,6 +350,12 @@ let primitives_table = ("%lefloat", Pfloatcomp Cle); ("%gtfloat", Pfloatcomp Cgt); ("%gefloat", Pfloatcomp Cge); + ("%negbigint", Pnegbigint); + ("%addbigint", Paddbigint); + ("%subbigint", Psubbigint); + ("%mulbigint", Pmulbigint); + ("%divbigint", Pdivbigint Safe); + ("%modbigint", Pmodbigint Safe); ("%string_length", Pstringlength); ("%string_safe_get", Pstringrefs); ("%string_unsafe_get", Pstringrefu); @@ -383,12 +389,12 @@ let primitives_table = ("%int64_lsl", Plslbint Pint64); ("%int64_lsr", Plsrbint Pint64); ("%int64_asr", Pasrbint Pint64); - ("%nativeint_of_int32", Pcvtbint (Pint32, Pnativeint)); - ("%nativeint_to_int32", Pcvtbint (Pnativeint, Pint32)); + ("%bigint_of_int32", Pcvtbint (Pint32, Pbigint)); + ("%bigint_to_int32", Pcvtbint (Pbigint, Pint32)); ("%int64_of_int32", Pcvtbint (Pint32, Pint64)); ("%int64_to_int32", Pcvtbint (Pint64, Pint32)); - ("%int64_of_nativeint", Pcvtbint (Pnativeint, Pint64)); - ("%int64_to_nativeint", Pcvtbint (Pint64, Pnativeint)); + ("%int64_of_bigint", Pcvtbint (Pbigint, Pint64)); + ("%int64_to_bigint", Pcvtbint (Pint64, Pbigint)); ("%opaque", Popaque); ("%uncurried_apply", Puncurried_apply); ] diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index ae3ce1391e..61ba418e18 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -239,8 +239,8 @@ let type_constant = function | Const_string _ -> instance_def Predef.type_string | Const_float _ -> instance_def Predef.type_float | Const_int64 _ -> instance_def Predef.type_int64 - | Const_int32 _ - | Const_nativeint _ -> assert false + | Const_bigint _ -> instance_def Predef.type_bigint + | Const_int32 _ -> assert false let constant : Parsetree.constant -> (Asttypes.constant, error) result = function @@ -259,11 +259,7 @@ let constant : Parsetree.constant -> (Asttypes.constant, error) result = try Ok (Const_int64 (Misc.Int_literal_converter.int64 i)) with Failure _ -> Error (Literal_overflow "int64") end - | Pconst_integer (i,Some 'n') -> - begin - try Ok (Const_nativeint (Misc.Int_literal_converter.nativeint i)) - with Failure _ -> Error (Literal_overflow "nativeint") - end + | Pconst_integer (i,Some 'n') ->Ok (Const_bigint i) | Pconst_integer (i,Some c) -> Error (Unknown_literal (i, c)) | Pconst_char c -> Ok (Const_char c) | Pconst_string (s,d) -> Ok (Const_string (s,d)) diff --git a/jscomp/ml/typeopt.ml b/jscomp/ml/typeopt.ml index 4513f4fbf4..565cc3b799 100644 --- a/jscomp/ml/typeopt.ml +++ b/jscomp/ml/typeopt.ml @@ -186,7 +186,7 @@ let classify_lazy_argument : Typedtree.expression -> fun e -> match e.exp_desc with | Texp_constant ( Const_int _ | Const_char _ | Const_string _ - | Const_int32 _ | Const_int64 _ | Const_nativeint _ ) + | Const_int32 _ | Const_int64 _ | Const_bigint _ ) | Texp_function _ | Texp_construct (_, {cstr_arity = 0}, _) -> `Constant_or_function diff --git a/jscomp/ml/untypeast.ml b/jscomp/ml/untypeast.ml index 1372832e53..66996951e1 100644 --- a/jscomp/ml/untypeast.ml +++ b/jscomp/ml/untypeast.ml @@ -114,7 +114,7 @@ let constant = function | Const_int i -> Pconst_integer (string_of_int i, None) | Const_int32 i -> Pconst_integer (Int32.to_string i, Some 'l') | Const_int64 i -> Pconst_integer (Int64.to_string i, Some 'L') - | Const_nativeint i -> Pconst_integer (Nativeint.to_string i, Some 'n') + | Const_bigint i -> Pconst_integer (i, Some 'n') | Const_float f -> Pconst_float (f,None) let attribute sub (s, p) = (map_loc sub s, p) diff --git a/jscomp/stdlib-406/pervasives.res b/jscomp/stdlib-406/pervasives.res index 632d0b7228..d88f5cac0d 100644 --- a/jscomp/stdlib-406/pervasives.res +++ b/jscomp/stdlib-406/pervasives.res @@ -179,6 +179,16 @@ let classify_float = (x: float): fpclass => FP_infinite } +/* Bigint operations */ + +external \"~-,": bigint => bigint = "%negbigint" +external \"~+,": bigint => bigint = "%identity" +external \"+,": (bigint, bigint) => bigint = "%addbigint" +external \"-,": (bigint, bigint) => bigint = "%subbigint" +external \"*,": (bigint, bigint) => bigint = "%mulbigint" +external \"/,": (bigint, bigint) => bigint = "%divbigint" +external modn: (bigint, bigint) => bigint = "%modbigint" + /* String and byte sequence operations -- more in modules String and Bytes */ external string_length: string => int = "%string_length" diff --git a/jscomp/stdlib-406/pervasives.resi b/jscomp/stdlib-406/pervasives.resi index 43407ced92..795c137006 100644 --- a/jscomp/stdlib-406/pervasives.resi +++ b/jscomp/stdlib-406/pervasives.resi @@ -521,6 +521,49 @@ let infinity: float /** Negative infinity. */ let neg_infinity: float +/** Unary negation. You can also write [- e] instead of [~- e]. + Unary operator at precedence level 9/11 for [- e] + and 11/11 for [~- e]. */ +external \"~-,": bigint => bigint = "%negbigint" + +/** Unary addition. You can also write [+ e] instead of [~+ e]. + Unary operator at precedence level 9/11 for [+ e] + and 11/11 for [~+ e]. + @since 3.12.0 +*/ +external \"~+,": bigint => bigint = "%identity" + +/** Bigint addition. + Left-associative operator at precedence level 6/11. */ +external \"+,": (bigint, bigint) => bigint = "%addbigint" + +/** Bigint subtraction. + Left-associative operator at precedence level 6/11. */ +external \"-,": (bigint, bigint) => bigint = "%subbigint" + +/** Bigint multiplication. + Left-associative operator at precedence level 7/11. */ +external \"*,": (bigint, bigint) => bigint = "%mulbigint" + +/** Bigint division. + Raise [Division_by_zero] if the second argument is 0. + Bigint division rounds the real quotient of its arguments towards zero. + More precisely, if [x >= 0] and [y > 0], [x / y] is the greatest bigint + less than or equal to the real quotient of [x] by [y]. Moreover, + [(- x) / y = x / (- y) = - (x / y)]. + Left-associative operator at precedence level 7/11. */ +external \"/,": (bigint, bigint) => bigint = "%divbigint" + +/** Bigint remainder. If [y] is not zero, the result + of [x mod y] satisfies the following properties: + [x = (x / y) * y + x mod y] and + [abs(x mod y) <= abs(y) - 1]. + If [y = 0], [x mod y] raises [Division_by_zero]. + Note that [x mod y] is negative only if [x < 0]. + Raise [Division_by_zero] if [y] is zero. + Left-associative operator at precedence level 7/11. */ +external modn: (bigint, bigint) => bigint = "%modbigint" + @val @scope("Number") /** A special floating-point value denoting the result of an diff --git a/jscomp/stdlib-406/pervasivesU.res b/jscomp/stdlib-406/pervasivesU.res index c044504bb7..4f1378bcb2 100644 --- a/jscomp/stdlib-406/pervasivesU.res +++ b/jscomp/stdlib-406/pervasivesU.res @@ -180,6 +180,16 @@ let classify_float = (x: float): fpclass => FP_infinite } +/* Bigint operations */ + +external \"~-,": bigint => bigint = "%negbigint" +external \"~+,": bigint => bigint = "%identity" +external \"+,": (bigint, bigint) => bigint = "%addbigint" +external \"-,": (bigint, bigint) => bigint = "%subbigint" +external \"*,": (bigint, bigint) => bigint = "%mulbigint" +external \"/,": (bigint, bigint) => bigint = "%divbigint" +external modn: (bigint, bigint) => bigint = "%modbigint" + /* String and byte sequence operations -- more in modules String and Bytes */ external string_length: string => int = "%string_length" diff --git a/jscomp/stdlib-406/pervasivesU.resi b/jscomp/stdlib-406/pervasivesU.resi index 4b0f05928b..d3ed6f92ad 100644 --- a/jscomp/stdlib-406/pervasivesU.resi +++ b/jscomp/stdlib-406/pervasivesU.resi @@ -524,6 +524,49 @@ let infinity: float /** Negative infinity. */ let neg_infinity: float +/** Unary negation. You can also write [- e] instead of [~- e]. + Unary operator at precedence level 9/11 for [- e] + and 11/11 for [~- e]. */ +external \"~-,": bigint => bigint = "%negbigint" + +/** Unary addition. You can also write [+ e] instead of [~+ e]. + Unary operator at precedence level 9/11 for [+ e] + and 11/11 for [~+ e]. + @since 3.12.0 +*/ +external \"~+,": bigint => bigint = "%identity" + +/** Bigint addition. + Left-associative operator at precedence level 6/11. */ +external \"+,": (bigint, bigint) => bigint = "%addbigint" + +/** Bigint subtraction. + Left-associative operator at precedence level 6/11. */ +external \"-,": (bigint, bigint) => bigint = "%subbigint" + +/** Bigint multiplication. + Left-associative operator at precedence level 7/11. */ +external \"*,": (bigint, bigint) => bigint = "%mulbigint" + +/** Bigint division. + Raise [Division_by_zero] if the second argument is 0. + Bigint division rounds the real quotient of its arguments towards zero. + More precisely, if [x >= 0] and [y > 0], [x / y] is the greatest bigint + less than or equal to the real quotient of [x] by [y]. Moreover, + [(- x) / y = x / (- y) = - (x / y)]. + Left-associative operator at precedence level 7/11. */ +external \"/,": (bigint, bigint) => bigint = "%divbigint" + +/** Bigint remainder. If [y] is not zero, the result + of [x mod y] satisfies the following properties: + [x = (x / y) * y + x mod y] and + [abs(x mod y) <= abs(y) - 1]. + If [y = 0], [x mod y] raises [Division_by_zero]. + Note that [x mod y] is negative only if [x < 0]. + Raise [Division_by_zero] if [y] is zero. + Left-associative operator at precedence level 7/11. */ +external modn: (bigint, bigint) => bigint = "%modbigint" + @val @scope("Number") /** A special floating-point value denoting the result of an diff --git a/jscomp/syntax/src/res_comments_table.ml b/jscomp/syntax/src/res_comments_table.ml index d12ace5287..28a29b40a5 100644 --- a/jscomp/syntax/src/res_comments_table.ml +++ b/jscomp/syntax/src/res_comments_table.ml @@ -1269,7 +1269,8 @@ and walkExpression expr t comments = Pexp_ident { txt = - Longident.Lident ("~+" | "~+." | "~-" | "~-." | "not" | "!"); + Longident.Lident + ("~+" | "~+." | "~+," | "~-" | "~-." | "~-," | "not" | "!"); }; }, [(Nolabel, argExpr)] ) -> diff --git a/jscomp/syntax/src/res_core.ml b/jscomp/syntax/src/res_core.ml index 189f80de5d..7966ec74b5 100644 --- a/jscomp/syntax/src/res_core.ml +++ b/jscomp/syntax/src/res_core.ml @@ -410,16 +410,17 @@ let negateString s = let makeUnaryExpr startPos tokenEnd token operand = match (token, operand.Parsetree.pexp_desc) with - | (Token.Plus | PlusDot), Pexp_constant (Pconst_integer _ | Pconst_float _) -> + | ( (Token.Plus | PlusDot | PlusComma), + Pexp_constant (Pconst_integer _ | Pconst_float _) ) -> operand | Minus, Pexp_constant (Pconst_integer (n, m)) -> { operand with pexp_desc = Pexp_constant (Pconst_integer (negateString n, m)); } - | (Minus | MinusDot), Pexp_constant (Pconst_float (n, m)) -> + | (Minus | MinusDot | MinusComma), Pexp_constant (Pconst_float (n, m)) -> {operand with pexp_desc = Pexp_constant (Pconst_float (negateString n, m))} - | (Token.Plus | PlusDot | Minus | MinusDot), _ -> + | (Token.Plus | PlusDot | PlusComma | Minus | MinusDot | MinusComma), _ -> let tokenLoc = mkLoc startPos tokenEnd in let operator = "~" ^ Token.toString token in Ast_helper.Exp.apply @@ -2092,7 +2093,8 @@ and parsePrimaryExpr ~operand ?(noCall = false) p = and parseUnaryExpr p = let startPos = p.Parser.startPos in match p.Parser.token with - | (Minus | MinusDot | Plus | PlusDot | Bang) as token -> + | (Minus | MinusDot | MinusComma | Plus | PlusDot | PlusComma | Bang) as token + -> Parser.leaveBreadcrumb p Grammar.ExprUnary; let tokenEnd = p.endPos in Parser.next p; diff --git a/jscomp/syntax/src/res_parsetree_viewer.ml b/jscomp/syntax/src/res_parsetree_viewer.ml index a376b5b633..60fa5e7762 100644 --- a/jscomp/syntax/src/res_parsetree_viewer.ml +++ b/jscomp/syntax/src/res_parsetree_viewer.ml @@ -292,7 +292,7 @@ let operatorPrecedence operator = | "||" -> 2 | "&&" -> 3 | "=" | "==" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 4 - | "+" | "+." | "-" | "-." | "^" -> 5 + | "+" | "+." | "+," | "-" | "-." | "-," | "^" -> 5 | "*" | "*." | "/" | "/." -> 6 | "**" -> 7 | "#" | "##" | "|." | "|.u" -> 8 @@ -300,7 +300,7 @@ let operatorPrecedence operator = let isUnaryOperator operator = match operator with - | "~+" | "~+." | "~-" | "~-." | "not" -> true + | "~+" | "~+." | "~+," | "~-" | "~-." | "~-," | "not" -> true | _ -> false let isUnaryExpression expr = @@ -316,8 +316,8 @@ let isUnaryExpression expr = let isBinaryOperator operator = match operator with | ":=" | "||" | "&&" | "=" | "==" | "<" | ">" | "!=" | "!==" | "<=" | ">=" - | "|>" | "+" | "+." | "-" | "-." | "^" | "*" | "*." | "/" | "/." | "**" | "|." - | "|.u" | "<>" -> + | "|>" | "+" | "+." | "+," | "-" | "-." | "-," | "^" | "*" | "*." | "*," | "/" + | "/." | "/," | "**" | "|." | "|.u" | "<>" -> true | _ -> false diff --git a/jscomp/syntax/src/res_printer.ml b/jscomp/syntax/src/res_printer.ml index c7a715f8ce..98b3edc92f 100644 --- a/jscomp/syntax/src/res_printer.ml +++ b/jscomp/syntax/src/res_printer.ml @@ -3546,8 +3546,10 @@ and printUnaryExpression ~state expr cmtTbl = (match op with | "~+" -> "+" | "~+." -> "+." + | "~+," -> "+," | "~-" -> "-" | "~-." -> "-." + | "~-," -> "-," | "not" -> "!" | _ -> assert false) in diff --git a/jscomp/syntax/src/res_scanner.ml b/jscomp/syntax/src/res_scanner.ml index b169041034..82875e709e 100644 --- a/jscomp/syntax/src/res_scanner.ml +++ b/jscomp/syntax/src/res_scanner.ml @@ -274,14 +274,6 @@ let scanNumber scanner = (* suffix *) let suffix = match scanner.ch with - | 'n' -> - let msg = - "Unsupported number type (nativeint). Did you mean `" ^ literal ^ "`?" - in - let pos = position scanner in - scanner.err ~startPos:pos ~endPos:pos (Diagnostics.message msg); - next scanner; - Some 'n' | ('g' .. 'z' | 'G' .. 'Z') as ch -> next scanner; Some ch @@ -705,6 +697,9 @@ let rec scan scanner = | '.' -> next2 scanner; Token.AsteriskDot + | ',' -> + next2 scanner; + Token.AsteriskComma | _ -> next scanner; Token.Asterisk) @@ -766,6 +761,9 @@ let rec scan scanner = | '.' -> next2 scanner; Token.ForwardslashDot + | ',' -> + next2 scanner; + Token.ForwardslashComma | _ -> next scanner; Token.Forwardslash) @@ -774,6 +772,9 @@ let rec scan scanner = | '.' -> next2 scanner; Token.MinusDot + | ',' -> + next2 scanner; + Token.MinusComma | '>' -> next2 scanner; Token.MinusGreater @@ -785,6 +786,9 @@ let rec scan scanner = | '.' -> next2 scanner; Token.PlusDot + | ',' -> + next2 scanner; + Token.PlusComma | '+' -> next2 scanner; Token.PlusPlus diff --git a/jscomp/syntax/src/res_token.ml b/jscomp/syntax/src/res_token.ml index 5d12e0f141..a81249cdc7 100644 --- a/jscomp/syntax/src/res_token.ml +++ b/jscomp/syntax/src/res_token.ml @@ -39,13 +39,17 @@ type t = | Backslash [@live] | Forwardslash | ForwardslashDot + | ForwardslashComma | Asterisk | AsteriskDot + | AsteriskComma | Exponentiation | Minus | MinusDot + | MinusComma | Plus | PlusDot + | PlusComma | PlusPlus | PlusEqual | ColonGreaterThan @@ -104,8 +108,10 @@ let precedence = function | Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual | BangEqualEqual | LessEqual | GreaterEqual | BarGreater -> 4 - | Plus | PlusDot | Minus | MinusDot | PlusPlus -> 5 - | Asterisk | AsteriskDot | Forwardslash | ForwardslashDot -> 6 + | Plus | PlusDot | PlusComma | Minus | MinusDot | MinusComma | PlusPlus -> 5 + | Asterisk | AsteriskDot | AsteriskComma | Forwardslash | ForwardslashDot + | ForwardslashComma -> + 6 | Exponentiation -> 7 | MinusGreater -> 8 | Dot -> 9 @@ -149,13 +155,16 @@ let toString = function | Comma -> "," | Minus -> "-" | MinusDot -> "-." + | MinusComma -> "-," | Plus -> "+" | PlusDot -> "+." + | PlusComma -> "+," | PlusPlus -> "++" | PlusEqual -> "+=" | Backslash -> "\\" | Forwardslash -> "/" | ForwardslashDot -> "/." + | ForwardslashComma -> "/," | Exception -> "exception" | Hash -> "#" | HashEqual -> "#=" @@ -164,6 +173,7 @@ let toString = function | LessThanSlash -> " "*" | AsteriskDot -> "*." + | AsteriskComma -> "*," | Exponentiation -> "**" | Assert -> "assert" | Lazy -> "lazy" diff --git a/jscomp/syntax/tests/parsing/errors/scanner/expected/nativeint.res.txt b/jscomp/syntax/tests/parsing/errors/scanner/expected/nativeint.res.txt index 1b4441cc39..449385ccb8 100644 --- a/jscomp/syntax/tests/parsing/errors/scanner/expected/nativeint.res.txt +++ b/jscomp/syntax/tests/parsing/errors/scanner/expected/nativeint.res.txt @@ -1,10 +1 @@ - - Syntax error! - tests/parsing/errors/scanner/nativeint.res:1:18 - - 1 │ let nativeint = 3n - 2 │ - - Unsupported number type (nativeint). Did you mean `3`? - let nativeint = 3n \ No newline at end of file diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/binary.res b/jscomp/syntax/tests/parsing/grammar/expressions/binary.res index 32cc091ef4..61532c3b83 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/binary.res +++ b/jscomp/syntax/tests/parsing/grammar/expressions/binary.res @@ -33,6 +33,7 @@ let x = a + @attr -1 + @attr -2 // should be interpreted as binary expression not prefix op let x = a -b let x = a -.b +let x = a -,b // not binary expr Constructor(a, b) diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/binary.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/binary.res.txt index 81e51b8c75..ad06ad2c99 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/expected/binary.res.txt +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/binary.res.txt @@ -17,6 +17,7 @@ let x = (a + (-1)) + (-2) let x = (a + (((-1))[@attr ])) + (((-2))[@attr ]) let x = a - b let x = a -. b +let x = a -, b ;;Constructor (a, b) ;;`Constructor (a, b) let _ = ((Constructor (a, b); `Constructor (a, b))[@res.braces ]) diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/unary.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/unary.res.txt index b19a1a010b..2018c414ef 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/expected/unary.res.txt +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/unary.res.txt @@ -3,4 +3,8 @@ let m = (-1) let m = (-2.5) let x = 5 let x = 5.4 +let b = (-1n) +let b = 1n +let b = ~-, 1n +let b = 1n let sum = (- a) - (- b) \ No newline at end of file diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/unaryOrBinary.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/unaryOrBinary.res.txt index 517a93db88..51864b1634 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/expected/unaryOrBinary.res.txt +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/unaryOrBinary.res.txt @@ -2,8 +2,13 @@ let width = (((w -. innerLeft) -. imageWidth) -. imageRightGap) -. rowInnerRight let width = (((w - innerLeft) - imageWidth) - imageRightGap) - rowInnerRight +let width = + (((w -, innerLeft) -, imageWidth) -, imageRightGap) -, rowInnerRight let width = ((w; -. innerLeft; -. imageWidth; -. imageRightGap; -. rowInnerRight) [@res.braces ]) let width = ((w; - innerLeft; - imageWidth; - imageRightGap; - rowInnerRight) + [@res.braces ]) +let width = + (((((w -, innerLeft) -, imageWidth) -, imageRightGap) -, rowInnerRight) [@res.braces ]) \ No newline at end of file diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/unary.res b/jscomp/syntax/tests/parsing/grammar/expressions/unary.res index dea9604b5f..67985e87ca 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/unary.res +++ b/jscomp/syntax/tests/parsing/grammar/expressions/unary.res @@ -4,5 +4,9 @@ let m = -1 let m = -.2.5 let x = +5 let x = +.5.4 +let b = -1n +let b = +1n +let b = -,1n +let b = +,1n let sum = -a - -b diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/unaryOrBinary.res b/jscomp/syntax/tests/parsing/grammar/expressions/unaryOrBinary.res index 271ef9d193..bb03e4954f 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/unaryOrBinary.res +++ b/jscomp/syntax/tests/parsing/grammar/expressions/unaryOrBinary.res @@ -16,6 +16,14 @@ let width = - imageRightGap - rowInnerRight +// binary +let width = + w + -, innerLeft + -, imageWidth + -, imageRightGap + -, rowInnerRight + // unary let width = { w @@ -33,3 +41,12 @@ let width = { -imageRightGap -rowInnerRight } + +// unary +let width = { + w + -,innerLeft + -,imageWidth + -,imageRightGap + -,rowInnerRight +} diff --git a/jscomp/test/ocaml_re_test.js b/jscomp/test/ocaml_re_test.js index 041f35e63e..1f4ac1fc4b 100644 --- a/jscomp/test/ocaml_re_test.js +++ b/jscomp/test/ocaml_re_test.js @@ -3412,6 +3412,35 @@ function parse(multiline, dollar_endonly, dotall, ungreedy, s) { }; } }; + var branch$p = function (_left) { + while(true) { + var left = _left; + if (i.contents === l || test(/* '|' */124) || test(/* ')' */41)) { + return seq$2(List.rev(left)); + } + _left = { + hd: piece(), + tl: left + }; + continue ; + }; + }; + var regexp$p = function (_left) { + while(true) { + var left = _left; + if (!accept(/* '|' */124)) { + return left; + } + _left = alt$1({ + hd: left, + tl: { + hd: branch$p(/* [] */0), + tl: /* [] */0 + } + }); + continue ; + }; + }; var atom = function (param) { if (accept(/* '.' */46)) { if (dotall) { @@ -3704,6 +3733,121 @@ function parse(multiline, dollar_endonly, dotall, ungreedy, s) { }; } }; + var bracket = function (_s) { + while(true) { + var s = _s; + if (s !== /* [] */0 && accept(/* ']' */93)) { + return s; + } + var match = $$char(); + if (match.NAME === "Char") { + var c = match.VAL; + if (accept(/* '-' */45)) { + if (accept(/* ']' */93)) { + return { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '-' */45, + /* '-' */45 + ], + tl: /* [] */0 + } + }, + tl: s + } + }; + } + var match$1 = $$char(); + if (match$1.NAME !== "Char") { + return { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '-' */45, + /* '-' */45 + ], + tl: /* [] */0 + } + }, + tl: { + hd: match$1.VAL, + tl: s + } + } + }; + } + _s = { + hd: { + TAG: "Set", + _0: seq(c, match$1.VAL) + }, + tl: s + }; + continue ; + } + _s = { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: s + }; + continue ; + } + _s = { + hd: match.VAL, + tl: s + }; + continue ; + }; + }; + var piece = function (param) { + var r = atom(); + if (accept(/* '*' */42)) { + return greedy_mod(repn(r, 0, undefined)); + } + if (accept(/* '+' */43)) { + return greedy_mod(repn(r, 1, undefined)); + } + if (accept(/* '?' */63)) { + return greedy_mod(repn(r, 0, 1)); + } + if (!accept(/* '{' */123)) { + return r; + } + var i$1 = integer(); + if (i$1 !== undefined) { + var j = accept(/* ',' */44) ? integer() : i$1; + if (!accept(/* '}' */125)) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + if (j !== undefined && j < i$1) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + return greedy_mod(repn(r, i$1, j)); + } + i.contents = i.contents - 1 | 0; + return r; + }; var $$char = function (param) { if (i.contents === l) { throw { @@ -3999,150 +4143,6 @@ function parse(multiline, dollar_endonly, dotall, ungreedy, s) { }; } }; - var bracket = function (_s) { - while(true) { - var s = _s; - if (s !== /* [] */0 && accept(/* ']' */93)) { - return s; - } - var match = $$char(); - if (match.NAME === "Char") { - var c = match.VAL; - if (accept(/* '-' */45)) { - if (accept(/* ']' */93)) { - return { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '-' */45, - /* '-' */45 - ], - tl: /* [] */0 - } - }, - tl: s - } - }; - } - var match$1 = $$char(); - if (match$1.NAME !== "Char") { - return { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '-' */45, - /* '-' */45 - ], - tl: /* [] */0 - } - }, - tl: { - hd: match$1.VAL, - tl: s - } - } - }; - } - _s = { - hd: { - TAG: "Set", - _0: seq(c, match$1.VAL) - }, - tl: s - }; - continue ; - } - _s = { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: s - }; - continue ; - } - _s = { - hd: match.VAL, - tl: s - }; - continue ; - }; - }; - var piece = function (param) { - var r = atom(); - if (accept(/* '*' */42)) { - return greedy_mod(repn(r, 0, undefined)); - } - if (accept(/* '+' */43)) { - return greedy_mod(repn(r, 1, undefined)); - } - if (accept(/* '?' */63)) { - return greedy_mod(repn(r, 0, 1)); - } - if (!accept(/* '{' */123)) { - return r; - } - var i$1 = integer(); - if (i$1 !== undefined) { - var j = accept(/* ',' */44) ? integer() : i$1; - if (!accept(/* '}' */125)) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - if (j !== undefined && j < i$1) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - return greedy_mod(repn(r, i$1, j)); - } - i.contents = i.contents - 1 | 0; - return r; - }; - var branch$p = function (_left) { - while(true) { - var left = _left; - if (i.contents === l || test(/* '|' */124) || test(/* ')' */41)) { - return seq$2(List.rev(left)); - } - _left = { - hd: piece(), - tl: left - }; - continue ; - }; - }; - var regexp$p = function (_left) { - while(true) { - var left = _left; - if (!accept(/* '|' */124)) { - return left; - } - _left = alt$1({ - hd: left, - tl: { - hd: branch$p(/* [] */0), - tl: /* [] */0 - } - }); - continue ; - }; - }; var res = regexp$p(branch$p(/* [] */0)); if (i.contents !== l) { throw { diff --git a/jscomp/test/test_per.res b/jscomp/test/test_per.res index d27a252e68..c44e61d0dc 100644 --- a/jscomp/test/test_per.res +++ b/jscomp/test/test_per.res @@ -165,6 +165,16 @@ type fpclass = | FP_nan external classify_float: float => fpclass = "?classify_float" +/* Bigint operations */ + +external \"~-,": bigint => bigint = "%negbigint" +external \"~+,": bigint => bigint = "%identity" +external \"+,": (bigint, bigint) => bigint = "%addbigint" +external \"-,": (bigint, bigint) => bigint = "%subbigint" +external \"*,": (bigint, bigint) => bigint = "%mulbigint" +external \"/,": (bigint, bigint) => bigint = "%divbigint" +external modn: (bigint, bigint) => bigint = "%modbigint" + /* String and byte sequence operations -- more in modules String and Bytes */ external string_length: string => int = "%string_length" From db001fa423f61e733be03b203f0b91f7b60248dd Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 8 Mar 2024 19:35:26 +0900 Subject: [PATCH 02/45] Js_bigint adding operations --- jscomp/others/js_bigint.res | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/jscomp/others/js_bigint.res b/jscomp/others/js_bigint.res index a469ed9862..f7f3758b99 100644 --- a/jscomp/others/js_bigint.res +++ b/jscomp/others/js_bigint.res @@ -1,3 +1,11 @@ /*** JavaScript BigInt API */ -type t +type t = bigint + +external \"~-": t => t = "%negbigint" +external \"~+": t => t = "%identity" +external \"+": (t, t) => t = "%addbigint" +external \"-": (t, t) => t = "%subbigint" +external \"*": (t, t) => t = "%mulbigint" +external \"/": (t, t) => t = "%divbigint" +external mod: (t, t) => t = "%modbigint" From 20410daaee631d531457c6aa210f933a486cd81c Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 8 Mar 2024 21:13:31 +0900 Subject: [PATCH 03/45] Js_json adding support of bigint --- jscomp/core/js_exp_make.ml | 2 ++ jscomp/core/js_stmt_make.ml | 2 +- jscomp/ml/ast_payload.ml | 18 ++++++++++++++++-- jscomp/ml/ast_payload.mli | 2 ++ jscomp/ml/ast_untagged_variants.ml | 28 +++++++++++++++++++++++++--- jscomp/ml/parsetree.ml | 2 +- jscomp/ml/variant_coercion.ml | 1 + jscomp/others/js_json.res | 1 + jscomp/others/js_json.resi | 1 + 9 files changed, 50 insertions(+), 7 deletions(-) diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index 57e7d4ae2c..a930714fa7 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -807,11 +807,13 @@ let tag_type = function | Ast_untagged_variants.String s -> str s ~delim:DStarJ | Int i -> small_int i | Float f -> float f + | Bigint i -> bigint i | Bool b -> bool b | Null -> nil | Undefined -> undefined | Untagged IntType -> str "number" | Untagged FloatType -> str "number" + | Untagged BigintType -> str "bigint" | Untagged BooleanType -> str "boolean" | Untagged FunctionType -> str "function" | Untagged StringType -> str "string" diff --git a/jscomp/core/js_stmt_make.ml b/jscomp/core/js_stmt_make.ml index 82773ae80e..258ce2c19d 100644 --- a/jscomp/core/js_stmt_make.ml +++ b/jscomp/core/js_stmt_make.ml @@ -138,7 +138,7 @@ let string_switch ?(comment : string option) match switch_case with | String s -> if s = txt then Some x.switch_body else None - | Int _ | Float _| Bool _ | Null | Undefined | Untagged _ -> + | Int _ | Float _ | Bigint _ | Bool _ | Null | Undefined | Untagged _ -> None) with | Some case -> case diff --git a/jscomp/ml/ast_payload.ml b/jscomp/ml/ast_payload.ml index 0f973b9e19..4d4e6aba99 100644 --- a/jscomp/ml/ast_payload.ml +++ b/jscomp/ml/ast_payload.ml @@ -61,10 +61,10 @@ let is_single_int (x : t) : int option = { pstr_desc = Pstr_eval - ({pexp_desc = Pexp_constant (Pconst_integer (name, _)); _}, _); + ({pexp_desc = Pexp_constant (Pconst_integer (name, char)); _}, _); _; }; - ] -> + ] when (match char with Some n when n = 'n' -> false | _ -> true) -> Some (int_of_string name) | _ -> None @@ -82,6 +82,20 @@ let is_single_float (x : t) : string option = Some name | _ -> None +let is_single_bigint (x : t) : string option = + match x with + | PStr + [ + { + pstr_desc = + Pstr_eval + ({pexp_desc = Pexp_constant (Pconst_integer (name, Some n)); _}, _); + _; + }; + ] when n = 'n' -> + Some name + | _ -> None + let is_single_bool (x : t) : bool option = match x with | PStr diff --git a/jscomp/ml/ast_payload.mli b/jscomp/ml/ast_payload.mli index addd8f9116..dfd2426ba0 100644 --- a/jscomp/ml/ast_payload.mli +++ b/jscomp/ml/ast_payload.mli @@ -41,6 +41,8 @@ val is_single_int : t -> int option val is_single_float : t -> string option +val is_single_bigint : t -> string option + val is_single_bool : t -> bool option val is_single_ident : t -> Longident.t option diff --git a/jscomp/ml/ast_untagged_variants.ml b/jscomp/ml/ast_untagged_variants.ml index 440299cb32..97e4b9abab 100644 --- a/jscomp/ml/ast_untagged_variants.ml +++ b/jscomp/ml/ast_untagged_variants.ml @@ -22,6 +22,7 @@ type untaggedError = | AtMostOneFunction | AtMostOneString | AtMostOneNumber + | AtMostOneBigint | AtMostOneBoolean | DuplicateLiteral of string | ConstructorMoreThanOneArg of string @@ -54,6 +55,8 @@ let report_error ppf = | AtMostOneBoolean -> "At most one case can be a boolean type." | AtMostOneNumber -> "At most one case can be a number type (int or float)." + | AtMostOneBigint -> + "At most one case can be a bigint type." | DuplicateLiteral s -> "Duplicate literal " ^ s ^ "." | ConstructorMoreThanOneArg (name) -> "Constructor " ^ name ^ " has more than one argument.") @@ -62,6 +65,7 @@ type block_type = | IntType | StringType | FloatType + | BigintType | BooleanType | InstanceType of Instance.t | FunctionType @@ -77,6 +81,7 @@ type tag_type = | String of string | Int of int | Float of string + | Bigint of string | Bool of bool | Null | Undefined (* literal or tagged block *) @@ -119,6 +124,9 @@ let process_tag_type (attrs : Parsetree.attributes) = (match Ast_payload.is_single_float payload with | None -> () | Some f -> st := Some (Float f)); + (match Ast_payload.is_single_bigint payload with + | None -> () + | Some i -> st := Some (Bigint i)); (match Ast_payload.is_single_bool payload with | None -> () | Some b -> st := Some (Bool b)); @@ -172,6 +180,8 @@ let get_block_type_from_typ ~env (t: Types.type_expr) : block_type option = Some IntType | {desc = Tconstr (path, _, _)} when Path.same path Predef.path_float -> Some FloatType + | {desc = Tconstr (path, _, _)} when Path.same path Predef.path_bigint -> + Some BigintType | {desc = Tconstr (path, _, _)} when Path.same path Predef.path_bool -> Some BooleanType | ({desc = Tconstr _} as t) when Ast_uncurried_utils.typeIsUncurriedFun t -> @@ -240,6 +250,7 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list) let objectTypes = ref 0 in let stringTypes = ref 0 in let numberTypes = ref 0 in + let bigintTypes = ref 0 in let booleanTypes = ref 0 in let unknownTypes = ref 0 in let addStringLiteral ~loc s = @@ -267,6 +278,9 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list) raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneString)); if !numberTypes > 1 then raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneNumber)); + if !bigintTypes > 1 then + (* FIXME need to define another error for duplicated bigint *) + raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBigint)); if !booleanTypes > 1 then raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBoolean)); if !booleanTypes > 0 && (StringSet.mem "true" !nonstring_literals || StringSet.mem "false" !nonstring_literals) then @@ -278,6 +292,7 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list) | Some (String s) -> addStringLiteral ~loc s | Some (Int i) -> addNonstringLiteral ~loc (string_of_int i) | Some (Float f) -> addNonstringLiteral ~loc f + | Some (Bigint i) -> addNonstringLiteral ~loc i | Some Null -> addNonstringLiteral ~loc "null" | Some Undefined -> addNonstringLiteral ~loc "undefined" | Some (Bool b) -> addNonstringLiteral ~loc (if b then "true" else "false") @@ -295,6 +310,7 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list) Hashtbl.replace instanceTypes i (count + 1); | FunctionType -> incr functionTypes; | (IntType | FloatType) -> incr numberTypes; + | BigintType -> incr bigintTypes; | BooleanType -> incr booleanTypes; | StringType -> incr stringTypes; ); @@ -359,6 +375,9 @@ module DynamicChecks = struct let function_ = Untagged FunctionType |> tag_type let string = Untagged StringType |> tag_type let number = Untagged IntType |> tag_type + + let bigint = Untagged BigintType |> tag_type + let boolean = Untagged BooleanType |> tag_type let ( == ) x y = bin EqEqEq x y @@ -375,7 +394,7 @@ module DynamicChecks = struct in let literals_overlaps_with_number () = Ext_list.exists literal_cases (function - | Int _ | Float _ -> true + | Int _ | Float _ | Bigint _ -> true | _ -> false) in let literals_overlaps_with_boolean () = @@ -398,6 +417,8 @@ module DynamicChecks = struct typeof e != number | FloatType when literals_overlaps_with_number () = false -> typeof e != number + | BigintType when literals_overlaps_with_number () = false -> + typeof e != bigint | BooleanType when literals_overlaps_with_boolean () = false -> typeof e != boolean | InstanceType i -> not (is_instance i e) @@ -408,6 +429,7 @@ module DynamicChecks = struct | StringType (* overlap *) | IntType (* overlap *) | FloatType (* overlap *) + | BigintType (* overlap *) | BooleanType (* overlap *) | UnknownType -> ( (* We don't know the type of unknown, so we need to express: @@ -449,7 +471,7 @@ module DynamicChecks = struct let add_runtime_type_check ~tag_type ~(block_cases : block_type list) x y = let instances = Ext_list.filter_map block_cases (function InstanceType i -> Some i | _ -> None) in match tag_type with - | Untagged (IntType | StringType | FloatType | BooleanType | FunctionType) -> + | Untagged (IntType | StringType | FloatType | BigintType | BooleanType | FunctionType) -> typeof y == x | Untagged ObjectType -> if instances <> [] then @@ -462,5 +484,5 @@ module DynamicChecks = struct | Untagged UnknownType -> (* This should not happen because unknown must be the only non-literal case *) assert false - | Bool _ | Float _ | Int _ | String _ | Null | Undefined -> x + | Bool _ | Float _ | Int _ | Bigint _ | String _ | Null | Undefined -> x end diff --git a/jscomp/ml/parsetree.ml b/jscomp/ml/parsetree.ml index ebf1837755..159a832aa9 100644 --- a/jscomp/ml/parsetree.ml +++ b/jscomp/ml/parsetree.ml @@ -22,7 +22,7 @@ type constant = (* 3 3l 3L 3n Suffixes [g-z][G-Z] are accepted by the parser. - Suffixes except 'l', 'L' and 'n' are rejected by the typechecker + Suffixes except 'l', 'L' are rejected by the typechecker *) | Pconst_char of int (* 'c' *) diff --git a/jscomp/ml/variant_coercion.ml b/jscomp/ml/variant_coercion.ml index a178b4b5bd..5d0406b7a3 100644 --- a/jscomp/ml/variant_coercion.ml +++ b/jscomp/ml/variant_coercion.ml @@ -45,6 +45,7 @@ let variant_has_same_runtime_representation_as_target ~(targetPath : Path.t) | None | Some (String _) -> Path.same targetPath Predef.path_string | Some (Int _) -> Path.same targetPath Predef.path_int | Some (Float _) -> Path.same targetPath Predef.path_float + | Some (Bigint _) -> Path.same targetPath Predef.path_bigint | Some (Null | Undefined | Bool _ | Untagged _) -> false) | _ -> false in diff --git a/jscomp/others/js_json.res b/jscomp/others/js_json.res index ccfa6de9f7..0b3d09722e 100644 --- a/jscomp/others/js_json.res +++ b/jscomp/others/js_json.res @@ -30,6 +30,7 @@ type rec t = | @as(null) Null | String(string) | Number(float) + | Bigint(bigint) | Object(Js.Dict.t) | Array(array) diff --git a/jscomp/others/js_json.resi b/jscomp/others/js_json.resi index 218d5f5626..78d5b261bf 100644 --- a/jscomp/others/js_json.resi +++ b/jscomp/others/js_json.resi @@ -36,6 +36,7 @@ type rec t = | @as(null) Null | String(string) | Number(float) + | Bigint(bigint) | Object(Js.Dict.t) | Array(array) From 2f6217b8eea4d87813b0950b02d5113377baeaba Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 8 Mar 2024 21:21:28 +0900 Subject: [PATCH 04/45] rename test --- jscomp/syntax/tests/parsing/errors/scanner/bigint.res | 1 + .../syntax/tests/parsing/errors/scanner/expected/bigint.res.txt | 1 + .../tests/parsing/errors/scanner/expected/nativeint.res.txt | 1 - jscomp/syntax/tests/parsing/errors/scanner/nativeint.res | 1 - 4 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 jscomp/syntax/tests/parsing/errors/scanner/bigint.res create mode 100644 jscomp/syntax/tests/parsing/errors/scanner/expected/bigint.res.txt delete mode 100644 jscomp/syntax/tests/parsing/errors/scanner/expected/nativeint.res.txt delete mode 100644 jscomp/syntax/tests/parsing/errors/scanner/nativeint.res diff --git a/jscomp/syntax/tests/parsing/errors/scanner/bigint.res b/jscomp/syntax/tests/parsing/errors/scanner/bigint.res new file mode 100644 index 0000000000..2e8a02966f --- /dev/null +++ b/jscomp/syntax/tests/parsing/errors/scanner/bigint.res @@ -0,0 +1 @@ +let bigint = 3n diff --git a/jscomp/syntax/tests/parsing/errors/scanner/expected/bigint.res.txt b/jscomp/syntax/tests/parsing/errors/scanner/expected/bigint.res.txt new file mode 100644 index 0000000000..cf8eb47407 --- /dev/null +++ b/jscomp/syntax/tests/parsing/errors/scanner/expected/bigint.res.txt @@ -0,0 +1 @@ +let bigint = 3n \ No newline at end of file diff --git a/jscomp/syntax/tests/parsing/errors/scanner/expected/nativeint.res.txt b/jscomp/syntax/tests/parsing/errors/scanner/expected/nativeint.res.txt deleted file mode 100644 index 449385ccb8..0000000000 --- a/jscomp/syntax/tests/parsing/errors/scanner/expected/nativeint.res.txt +++ /dev/null @@ -1 +0,0 @@ -let nativeint = 3n \ No newline at end of file diff --git a/jscomp/syntax/tests/parsing/errors/scanner/nativeint.res b/jscomp/syntax/tests/parsing/errors/scanner/nativeint.res deleted file mode 100644 index 9e175b2078..0000000000 --- a/jscomp/syntax/tests/parsing/errors/scanner/nativeint.res +++ /dev/null @@ -1 +0,0 @@ -let nativeint = 3n From 0b14c33033a852abc3e4ce52c8fe9734dd62b795 Mon Sep 17 00:00:00 2001 From: mununki Date: Sat, 9 Mar 2024 02:41:53 +0900 Subject: [PATCH 05/45] remove bigint from Js_json --- jscomp/others/js_json.res | 1 - jscomp/others/js_json.resi | 1 - 2 files changed, 2 deletions(-) diff --git a/jscomp/others/js_json.res b/jscomp/others/js_json.res index 0b3d09722e..ccfa6de9f7 100644 --- a/jscomp/others/js_json.res +++ b/jscomp/others/js_json.res @@ -30,7 +30,6 @@ type rec t = | @as(null) Null | String(string) | Number(float) - | Bigint(bigint) | Object(Js.Dict.t) | Array(array) diff --git a/jscomp/others/js_json.resi b/jscomp/others/js_json.resi index 78d5b261bf..218d5f5626 100644 --- a/jscomp/others/js_json.resi +++ b/jscomp/others/js_json.resi @@ -36,7 +36,6 @@ type rec t = | @as(null) Null | String(string) | Number(float) - | Bigint(bigint) | Object(Js.Dict.t) | Array(array) From 4f4057556b501b727e6387e58da627dffff6d4ec Mon Sep 17 00:00:00 2001 From: mununki Date: Sat, 9 Mar 2024 02:52:29 +0900 Subject: [PATCH 06/45] stale comment --- jscomp/ml/ast_untagged_variants.ml | 1 - 1 file changed, 1 deletion(-) diff --git a/jscomp/ml/ast_untagged_variants.ml b/jscomp/ml/ast_untagged_variants.ml index 97e4b9abab..8f27806636 100644 --- a/jscomp/ml/ast_untagged_variants.ml +++ b/jscomp/ml/ast_untagged_variants.ml @@ -279,7 +279,6 @@ let checkInvariant ~isUntaggedDef ~(consts : (Location.t * tag) list) if !numberTypes > 1 then raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneNumber)); if !bigintTypes > 1 then - (* FIXME need to define another error for duplicated bigint *) raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBigint)); if !booleanTypes > 1 then raise (Error (loc, InvalidUntaggedVariantDefinition AtMostOneBoolean)); From 6020820b0f83cb2fae939e28e57ffa0145d443fb Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 11 Mar 2024 11:15:50 +0900 Subject: [PATCH 07/45] remove unnecessary guard in pattern matching --- jscomp/ml/ast_payload.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jscomp/ml/ast_payload.ml b/jscomp/ml/ast_payload.ml index 4d4e6aba99..f49ac59a4f 100644 --- a/jscomp/ml/ast_payload.ml +++ b/jscomp/ml/ast_payload.ml @@ -89,10 +89,10 @@ let is_single_bigint (x : t) : string option = { pstr_desc = Pstr_eval - ({pexp_desc = Pexp_constant (Pconst_integer (name, Some n)); _}, _); + ({pexp_desc = Pexp_constant (Pconst_integer (name, Some 'n')); _}, _); _; }; - ] when n = 'n' -> + ] -> Some name | _ -> None From 8d95ccd79dbbec37d9b20920f5ccb541357eb7d1 Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 11 Mar 2024 21:05:58 +0900 Subject: [PATCH 08/45] fix literal_overlaps --- jscomp/ml/ast_untagged_variants.ml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/jscomp/ml/ast_untagged_variants.ml b/jscomp/ml/ast_untagged_variants.ml index 8f27806636..a1fbacc8a6 100644 --- a/jscomp/ml/ast_untagged_variants.ml +++ b/jscomp/ml/ast_untagged_variants.ml @@ -393,7 +393,12 @@ module DynamicChecks = struct in let literals_overlaps_with_number () = Ext_list.exists literal_cases (function - | Int _ | Float _ | Bigint _ -> true + | Int _ | Float _ -> true + | _ -> false) + in + let literals_overlaps_with_bigint () = + Ext_list.exists literal_cases (function + | Bigint _ -> true | _ -> false) in let literals_overlaps_with_boolean () = @@ -416,7 +421,7 @@ module DynamicChecks = struct typeof e != number | FloatType when literals_overlaps_with_number () = false -> typeof e != number - | BigintType when literals_overlaps_with_number () = false -> + | BigintType when literals_overlaps_with_bigint () = false -> typeof e != bigint | BooleanType when literals_overlaps_with_boolean () = false -> typeof e != boolean From 83070a08f5d3c37e6ddc7354a761af4b715410cc Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 11 Mar 2024 21:06:30 +0900 Subject: [PATCH 09/45] primitive bigint instead of Js_bigint.t --- jscomp/others/js_bigint.res | 16 +++++++--------- jscomp/others/js_types.res | 2 +- jscomp/others/release.ninja | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/jscomp/others/js_bigint.res b/jscomp/others/js_bigint.res index f7f3758b99..397b4506eb 100644 --- a/jscomp/others/js_bigint.res +++ b/jscomp/others/js_bigint.res @@ -1,11 +1,9 @@ /*** JavaScript BigInt API */ -type t = bigint - -external \"~-": t => t = "%negbigint" -external \"~+": t => t = "%identity" -external \"+": (t, t) => t = "%addbigint" -external \"-": (t, t) => t = "%subbigint" -external \"*": (t, t) => t = "%mulbigint" -external \"/": (t, t) => t = "%divbigint" -external mod: (t, t) => t = "%modbigint" +external \"~-": bigint => bigint = "%negbigint" +external \"~+": bigint => bigint = "%identity" +external \"+": (bigint, bigint) => bigint = "%addbigint" +external \"-": (bigint, bigint) => bigint = "%subbigint" +external \"*": (bigint, bigint) => bigint = "%mulbigint" +external \"/": (bigint, bigint) => bigint = "%divbigint" +external mod: (bigint, bigint) => bigint = "%modbigint" diff --git a/jscomp/others/js_types.res b/jscomp/others/js_types.res index 09acbc8cab..9048765d8d 100644 --- a/jscomp/others/js_types.res +++ b/jscomp/others/js_types.res @@ -26,7 +26,7 @@ type symbol /** Js bigint type only available in ES2020 */ -type bigint_val = Js_bigint.t +type bigint_val = bigint type obj_val /** This type has only one value `undefined` */ diff --git a/jscomp/others/release.ninja b/jscomp/others/release.ninja index 116df80fef..21b03b82eb 100644 --- a/jscomp/others/release.ninja +++ b/jscomp/others/release.ninja @@ -57,7 +57,7 @@ o others/js_string.cmi others/js_string.cmj : cc others/js_string.res | others/b o others/js_string2.cmi others/js_string2.cmj : cc others/js_string2.res | others/belt_internals.cmi others/js.cmi others/js_array2.cmj others/js_re.cmj $bsc o others/js_typed_array.cmi others/js_typed_array.cmj : cc others/js_typed_array.res | others/belt_internals.cmi others/js.cmi others/js.cmj others/js_typed_array2.cmj $bsc o others/js_typed_array2.cmi others/js_typed_array2.cmj : cc others/js_typed_array2.res | others/belt_internals.cmi others/js.cmi others/js.cmj $bsc -o others/js_types.cmj : cc_cmi others/js_types.res | others/belt_internals.cmi others/js.cmi others/js.cmj others/js_bigint.cmj others/js_null.cmj others/js_types.cmi $bsc +o others/js_types.cmj : cc_cmi others/js_types.res | others/belt_internals.cmi others/js.cmi others/js.cmj others/js_null.cmj others/js_types.cmi $bsc o others/js_types.cmi : cc others/js_types.resi | others/belt_internals.cmi others/js.cmi $bsc o others/js_undefined.cmj : cc_cmi others/js_undefined.res | others/belt_internals.cmi others/js.cmi others/js.cmj others/js_exn.cmj others/js_undefined.cmi $bsc o others/js_undefined.cmi : cc others/js_undefined.resi | others/belt_internals.cmi others/js.cmi others/js.cmj $bsc From 128aa2045aaf0e2cbd245fc1cba95506aac38898 Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 11 Mar 2024 21:06:44 +0900 Subject: [PATCH 10/45] variant coercion for bigint --- jscomp/ml/variant_coercion.ml | 3 +++ jscomp/test/VariantCoercion.js | 20 ++++++++++++++++++-- jscomp/test/VariantCoercion.res | 12 ++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/jscomp/ml/variant_coercion.ml b/jscomp/ml/variant_coercion.ml index 5d0406b7a3..21f6c11e5a 100644 --- a/jscomp/ml/variant_coercion.ml +++ b/jscomp/ml/variant_coercion.ml @@ -5,6 +5,7 @@ let can_coerce_primitive (path : Path.t) = Path.same path Predef.path_string || Path.same path Predef.path_int || Path.same path Predef.path_float + || Path.same path Predef.path_bigint let check_paths_same p1 p2 target_path = Path.same p1 target_path && Path.same p2 target_path @@ -38,6 +39,8 @@ let variant_has_same_runtime_representation_as_target ~(targetPath : Path.t) path_same Predef.path_string || (* unboxed Number(float) :> float *) path_same Predef.path_float + || (* unboxed Bigint(bigint) :> bigint *) + path_same Predef.path_bigint | Cstr_tuple [] -> ( (* Check that @as payloads match with the target path to coerce to. No @as means the default encoding, which is string *) diff --git a/jscomp/test/VariantCoercion.js b/jscomp/test/VariantCoercion.js index 0918041039..556121501f 100644 --- a/jscomp/test/VariantCoercion.js +++ b/jscomp/test/VariantCoercion.js @@ -62,7 +62,22 @@ var CoerceFromFloatToVariant = { cc: 120 }; -var a$2 = "Three"; +var a$2 = 100n; + +var aa$1 = 1n; + +var c$2 = 120n; + +var CoerceFromBigintToVariant = { + a: a$2, + aa: aa$1, + b: a$2, + bb: aa$1, + c: c$2, + cc: c$2 +}; + +var a$3 = "Three"; var b = "Three"; @@ -74,7 +89,7 @@ var ii = 1.1; var dd = 1.1; -exports.a = a$2; +exports.a = a$3; exports.b = b; exports.i = i; exports.d = d; @@ -85,4 +100,5 @@ exports.CoerceWithPayload = CoerceWithPayload; exports.CoerceFromStringToVariant = CoerceFromStringToVariant; exports.CoerceFromIntToVariant = CoerceFromIntToVariant; exports.CoerceFromFloatToVariant = CoerceFromFloatToVariant; +exports.CoerceFromBigintToVariant = CoerceFromBigintToVariant; /* No side effect */ diff --git a/jscomp/test/VariantCoercion.res b/jscomp/test/VariantCoercion.res index 2c653f2a9d..9286ed8d78 100644 --- a/jscomp/test/VariantCoercion.res +++ b/jscomp/test/VariantCoercion.res @@ -80,3 +80,15 @@ module CoerceFromFloatToVariant = { let c = 120. let cc: mixed = (c :> mixed) } + +module CoerceFromBigintToVariant = { + @unboxed type bigints = Bigint(bigint) | @as(1n) First | @as(2n) Second | @as(3n) Third + let a = 100n + let aa = 1n + let b: bigints = (a :> bigints) + let bb: bigints = (aa :> bigints) + + @unboxed type mixed = Bigint(bigint) | @as(1n) One | @as(null) Null | Two + let c = 120n + let cc: mixed = (c :> mixed) +} From c1d39b2c7cc0bc2dc1fd6d35ded1afeeddc3aa77 Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 11 Mar 2024 21:33:49 +0900 Subject: [PATCH 11/45] add error test --- .../expected/variant_coercion_bigint.res.expected | 10 ++++++++++ .../expected/variant_coercion_bigint_as.res.expected | 10 ++++++++++ .../super_errors/fixtures/variant_coercion_bigint.res | 5 +++++ .../fixtures/variant_coercion_bigint_as.res | 5 +++++ 4 files changed, 30 insertions(+) create mode 100644 jscomp/build_tests/super_errors/expected/variant_coercion_bigint.res.expected create mode 100644 jscomp/build_tests/super_errors/expected/variant_coercion_bigint_as.res.expected create mode 100644 jscomp/build_tests/super_errors/fixtures/variant_coercion_bigint.res create mode 100644 jscomp/build_tests/super_errors/fixtures/variant_coercion_bigint_as.res diff --git a/jscomp/build_tests/super_errors/expected/variant_coercion_bigint.res.expected b/jscomp/build_tests/super_errors/expected/variant_coercion_bigint.res.expected new file mode 100644 index 0000000000..c179d49c12 --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/variant_coercion_bigint.res.expected @@ -0,0 +1,10 @@ + + We've found a bug for you! + /.../fixtures/variant_coercion_bigint.res:5:10-20 + + 3 │ let x = One(true) + 4 │ + 5 │ let y = (x :> bigint) + 6 │ + + Type x is not a subtype of bigint \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/variant_coercion_bigint_as.res.expected b/jscomp/build_tests/super_errors/expected/variant_coercion_bigint_as.res.expected new file mode 100644 index 0000000000..a05508050b --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/variant_coercion_bigint_as.res.expected @@ -0,0 +1,10 @@ + + We've found a bug for you! + /.../fixtures/variant_coercion_bigint_as.res:5:10-20 + + 3 │ let x = One + 4 │ + 5 │ let y = (x :> bigint) + 6 │ + + Type x is not a subtype of bigint \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/fixtures/variant_coercion_bigint.res b/jscomp/build_tests/super_errors/fixtures/variant_coercion_bigint.res new file mode 100644 index 0000000000..4f23f40a70 --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/variant_coercion_bigint.res @@ -0,0 +1,5 @@ +type x = | @as(1n) One(bool) | @as(2n) Two + +let x = One(true) + +let y = (x :> bigint) diff --git a/jscomp/build_tests/super_errors/fixtures/variant_coercion_bigint_as.res b/jscomp/build_tests/super_errors/fixtures/variant_coercion_bigint_as.res new file mode 100644 index 0000000000..d3a3cc1f24 --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/variant_coercion_bigint_as.res @@ -0,0 +1,5 @@ +type x = | @as(1n) One | Two + +let x = One + +let y = (x :> bigint) From 883527621ec0184dc0ef646adf44f7c8c59d7dd3 Mon Sep 17 00:00:00 2001 From: mununki Date: Wed, 13 Mar 2024 02:29:02 +0900 Subject: [PATCH 12/45] add optimization of comparisons --- jscomp/core/js_exp_make.ml | 11 +++++++++++ jscomp/core/js_exp_make.mli | 2 ++ jscomp/core/lam_analysis.ml | 2 +- jscomp/core/lam_compile_primitive.ml | 2 ++ jscomp/core/lam_convert.ml | 1 + jscomp/core/lam_dispatch_primitive.ml | 8 ++++++-- jscomp/core/lam_primitive.ml | 6 ++++++ jscomp/core/lam_primitive.mli | 1 + jscomp/core/lam_print.ml | 6 ++++++ jscomp/ml/lambda.ml | 4 +++- jscomp/ml/lambda.mli | 4 +++- jscomp/ml/printlambda.ml | 7 +++++++ jscomp/ml/translcore.ml | 24 +++++++++++++++++++++++- jscomp/runtime/caml.res | 15 +++++++++++++++ jscomp/runtime/caml.resi | 1 + lib/es6/caml.js | 15 +++++++++++++++ lib/js/caml.js | 15 +++++++++++++++ 17 files changed, 118 insertions(+), 6 deletions(-) diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index a930714fa7..98a660aa99 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -787,6 +787,7 @@ let rec float_equal ?comment (e0 : t) (e1 : t) : t = float_equal ?comment a e1 | Number (Float { f = f0; _ }), Number (Float { f = f1 }) when f0 = f1 -> true_ + | Number (Bigint { i = i0 }), Number (Bigint { i = i1 }) -> bool (i0 = i1) | _ -> { expression_desc = Bin (EqEqEq, e0, e1); comment } let int_equal = float_equal @@ -1269,6 +1270,16 @@ let bigint_div ?comment (e1: t) (e2: t) = bin ?comment Div e1 e2 let bigint_mod ?comment (e1: t) (e2: t) = bin ?comment Mod e1 e2 +let bigint_comp (cmp : Lam_compat.comparison) ?comment (e0: t) (e1: t) = + match (cmp, e0.expression_desc, e1.expression_desc) with + | Ceq, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 = i1) + | Cneq, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 <> i1) + | Cge, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 >= i1) + | Cgt, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 > i1) + | Cle, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 <= i1) + | Clt, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 < i1) + | _ -> bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1 + (* TODO -- alpha conversion remember to add parens.. *) diff --git a/jscomp/core/js_exp_make.mli b/jscomp/core/js_exp_make.mli index d49055cd3d..2981c77d84 100644 --- a/jscomp/core/js_exp_make.mli +++ b/jscomp/core/js_exp_make.mli @@ -286,6 +286,8 @@ val bigint_div : ?comment: string -> t -> t -> t val bigint_mod : ?comment: string -> t -> t -> t +val bigint_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t + val js_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t val not : t -> t diff --git a/jscomp/core/lam_analysis.ml b/jscomp/core/lam_analysis.ml index acae9aa749..b1afbf2463 100644 --- a/jscomp/core/lam_analysis.ml +++ b/jscomp/core/lam_analysis.ml @@ -76,7 +76,7 @@ let rec no_side_effects (lam : Lam.t) : bool = (* Float operations *) | Pintoffloat | Pfloatofint | Pnegfloat (* | Pabsfloat *) - | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pjscomp _ + | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pbigintcomp _ | Pjscomp _ | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu diff --git a/jscomp/core/lam_compile_primitive.ml b/jscomp/core/lam_compile_primitive.ml index a737be4389..88424f1771 100644 --- a/jscomp/core/lam_compile_primitive.ml +++ b/jscomp/core/lam_compile_primitive.ml @@ -251,6 +251,8 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) [Not_found] or [Invalid_argument] ? *) match args with [ e1; e2 ] -> E.int_comp cmp e1 e2 | _ -> assert false) + | Pbigintcomp cmp -> ( + match args with [ e1; e2 ] -> E.bigint_comp cmp e1 e2 | _ -> assert false) (* List --> stamp = 0 Assert_false --> stamp = 26 *) diff --git a/jscomp/core/lam_convert.ml b/jscomp/core/lam_convert.ml index b77dfa5d47..25aa8cd554 100644 --- a/jscomp/core/lam_convert.ml +++ b/jscomp/core/lam_convert.ml @@ -260,6 +260,7 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t = | Pmulbigint -> prim ~primitive:Pmulbigint ~args loc | Pdivbigint _is_safe (*FIXME*) -> prim ~primitive:Pdivbigint ~args loc | Pmodbigint _is_safe (*FIXME*) -> prim ~primitive:Pmodbigint ~args loc + | Pbigintcomp x -> prim ~primitive:(Pbigintcomp x) ~args loc | Pintcomp x -> prim ~primitive:(Pintcomp x) ~args loc | Poffsetint x -> prim ~primitive:(Poffsetint x) ~args loc | Poffsetref x -> prim ~primitive:(Poffsetref x) ~args loc diff --git a/jscomp/core/lam_dispatch_primitive.ml b/jscomp/core/lam_dispatch_primitive.ml index 5b7f55160b..a719e1ce2a 100644 --- a/jscomp/core/lam_dispatch_primitive.ml +++ b/jscomp/core/lam_dispatch_primitive.ml @@ -123,6 +123,9 @@ let translate loc (prim_name : string) (args : J.expression list) : J.expression | "caml_float_equal_null" | "caml_float_equal_nullable" | "caml_float_equal_undefined" -> ( match args with [ e0; e1 ] -> E.float_comp Ceq e0 e1 | _ -> assert false) + | "caml_bigint_equal_null" | "caml_bigint_equal_nullable" + | "caml_bigint_equal_undefined" -> ( + match args with [ e0; e1 ] -> E.bigint_comp Ceq e0 e1 | _ -> assert false) | "caml_string_equal_null" | "caml_string_equal_nullable" | "caml_string_equal_undefined" -> ( match args with @@ -137,8 +140,9 @@ let translate loc (prim_name : string) (args : J.expression list) : J.expression | "caml_int_compare" -> E.runtime_call Js_runtime_modules.caml_primitive "int_compare" args | "caml_float_compare" -> call Js_runtime_modules.caml_primitive + | "caml_bigint_compare" -> call Js_runtime_modules.caml_primitive | "caml_string_compare" -> call Js_runtime_modules.caml_primitive - | "caml_bool_min" | "caml_int_min" | "caml_float_min" | "caml_string_min" -> ( + | "caml_bool_min" | "caml_int_min" | "caml_float_min" | "caml_bigint_min" | "caml_string_min" -> ( match args with | [ a; b ] -> if @@ -147,7 +151,7 @@ let translate loc (prim_name : string) (args : J.expression list) : J.expression then E.econd (E.js_comp Clt a b) a b else call Js_runtime_modules.caml_primitive | _ -> assert false) - | "caml_bool_max" | "caml_int_max" | "caml_float_max" | "caml_string_max" -> ( + | "caml_bool_max" | "caml_int_max" | "caml_float_max" | "caml_bigint_max" | "caml_string_max" -> ( match args with | [ a; b ] -> if diff --git a/jscomp/core/lam_primitive.ml b/jscomp/core/lam_primitive.ml index c79196b46f..4b7eadea63 100644 --- a/jscomp/core/lam_primitive.ml +++ b/jscomp/core/lam_primitive.ml @@ -91,6 +91,7 @@ type t = | Pfloatcomp of Lam_compat.comparison | Pjscomp of Lam_compat.comparison | Pint64comp of Lam_compat.comparison + | Pbigintcomp of Lam_compat.comparison | Pjs_apply (*[f;arg0;arg1; arg2; ... argN]*) | Pjs_runtime_apply (* [f; [...]] *) (* String operations *) @@ -282,6 +283,11 @@ let eq_primitive_approx (lhs : t) (rhs : t) = | Pfloatcomp comparison1 -> Lam_compat.eq_comparison comparison comparison1 | _ -> false) + | Pbigintcomp comparison -> ( + match rhs with + | Pbigintcomp comparison1 -> + Lam_compat.eq_comparison comparison comparison1 + | _ -> false) | Pjscomp comparison -> ( match rhs with | Pjscomp comparison1 -> Lam_compat.eq_comparison comparison comparison1 diff --git a/jscomp/core/lam_primitive.mli b/jscomp/core/lam_primitive.mli index 2a6efc3d85..aef8bf983e 100644 --- a/jscomp/core/lam_primitive.mli +++ b/jscomp/core/lam_primitive.mli @@ -81,6 +81,7 @@ type t = | Pfloatcomp of Lam_compat.comparison | Pjscomp of Lam_compat.comparison | Pint64comp of Lam_compat.comparison + | Pbigintcomp of Lam_compat.comparison | Pjs_apply (*[f;arg0;arg1; arg2; ... argN]*) | Pjs_runtime_apply (* [f; [...]] *) | Pstringlength diff --git a/jscomp/core/lam_print.ml b/jscomp/core/lam_print.ml index c74005e39c..33475aed57 100644 --- a/jscomp/core/lam_print.ml +++ b/jscomp/core/lam_print.ml @@ -140,6 +140,12 @@ let primitive ppf (prim : Lam_primitive.t) = | Pmulbigint -> fprintf ppf "*n" | Pdivbigint -> fprintf ppf "/n" | Pmodbigint -> fprintf ppf "modn" + | Pbigintcomp Ceq -> fprintf ppf "==," + | Pbigintcomp Cneq -> fprintf ppf "!=," + | Pbigintcomp Clt -> fprintf ppf "<," + | Pbigintcomp Cle -> fprintf ppf "<=," + | Pbigintcomp Cgt -> fprintf ppf ">," + | Pbigintcomp Cge -> fprintf ppf ">=," | Pjscomp Ceq -> fprintf ppf "#==" | Pjscomp Cneq -> fprintf ppf "#!=" | Pjscomp Clt -> fprintf ppf "#<" diff --git a/jscomp/ml/lambda.ml b/jscomp/ml/lambda.ml index 69dc253850..977344fadf 100644 --- a/jscomp/ml/lambda.ml +++ b/jscomp/ml/lambda.ml @@ -230,7 +230,9 @@ type primitive = | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp of comparison (* Bigint operations *) - | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe + | Pnegbigint | Paddbigint | Psubbigint + | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe + | Pbigintcomp of comparison (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu | Pbytessetu | Pbytesrefs | Pbytessets diff --git a/jscomp/ml/lambda.mli b/jscomp/ml/lambda.mli index 5d4f771f33..c0b9e3036f 100644 --- a/jscomp/ml/lambda.mli +++ b/jscomp/ml/lambda.mli @@ -196,7 +196,9 @@ type primitive = | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp of comparison (* Bigint operations *) - | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe + | Pnegbigint | Paddbigint | Psubbigint + | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe + | Pbigintcomp of comparison (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu | Pbytessetu | Pbytesrefs | Pbytessets diff --git a/jscomp/ml/printlambda.ml b/jscomp/ml/printlambda.ml index 856495421f..40f2b8c1c1 100644 --- a/jscomp/ml/printlambda.ml +++ b/jscomp/ml/printlambda.ml @@ -185,6 +185,12 @@ let primitive ppf = function | Pdivbigint Unsafe -> fprintf ppf "/nu" | Pmodbigint Safe -> fprintf ppf "mod" | Pmodbigint Unsafe -> fprintf ppf "mod_unsafe" + | Pbigintcomp(Ceq) -> fprintf ppf "==," + | Pbigintcomp(Cneq) -> fprintf ppf "!=," + | Pbigintcomp(Clt) -> fprintf ppf "<," + | Pbigintcomp(Cle) -> fprintf ppf "<=," + | Pbigintcomp(Cgt) -> fprintf ppf ">," + | Pbigintcomp(Cge) -> fprintf ppf ">=," | Pstringlength -> fprintf ppf "string.length" | Pstringrefu -> fprintf ppf "string.unsafe_get" | Pstringrefs -> fprintf ppf "string.get" @@ -292,6 +298,7 @@ let name_of_primitive = function | Pmulbigint -> "Pmulbigint" | Pdivbigint _ -> "Pdivbigint" | Pmodbigint _ -> "Pmodbigint" + | Pbigintcomp _ -> "Pbigintcomp" | Pstringlength -> "Pstringlength" | Pstringrefu -> "Pstringrefu" | Pstringrefs -> "Pstringrefs" diff --git a/jscomp/ml/translcore.ml b/jscomp/ml/translcore.ml index 0102b5c556..72c41e56eb 100644 --- a/jscomp/ml/translcore.ml +++ b/jscomp/ml/translcore.ml @@ -57,6 +57,7 @@ type specialized = { stringcomp : Lambda.primitive; bytescomp : Lambda.primitive; int64comp : Lambda.primitive; + bigintcomp : Lambda.primitive; simplify_constant_constructor : bool; } @@ -82,6 +83,7 @@ let comparisons_table = Pccall (Primitive.simple ~name:"caml_bytes_equal" ~arity:2 ~alloc:false); int64comp = Pbintcomp (Pint64, Ceq); + bigintcomp = Pbigintcomp Ceq; simplify_constant_constructor = true; } ); ( "%notequal", @@ -102,6 +104,7 @@ let comparisons_table = (Primitive.simple ~name:"caml_bytes_notequal" ~arity:2 ~alloc:false); int64comp = Pbintcomp (Pint64, Cneq); + bigintcomp = Pbigintcomp Cneq; simplify_constant_constructor = true; } ); ( "%lessthan", @@ -122,6 +125,7 @@ let comparisons_table = (Primitive.simple ~name:"caml_bytes_lessthan" ~arity:2 ~alloc:false); int64comp = Pbintcomp (Pint64, Clt); + bigintcomp = Pbigintcomp Clt; simplify_constant_constructor = false; } ); ( "%greaterthan", @@ -144,6 +148,7 @@ let comparisons_table = (Primitive.simple ~name:"caml_bytes_greaterthan" ~arity:2 ~alloc:false); int64comp = Pbintcomp (Pint64, Cgt); + bigintcomp = Pbigintcomp Cgt; simplify_constant_constructor = false; } ); ( "%lessequal", @@ -166,6 +171,7 @@ let comparisons_table = (Primitive.simple ~name:"caml_bytes_lessequal" ~arity:2 ~alloc:false); int64comp = Pbintcomp (Pint64, Cle); + bigintcomp = Pbigintcomp Cle; simplify_constant_constructor = false; } ); ( "%greaterequal", @@ -188,6 +194,7 @@ let comparisons_table = (Primitive.simple ~name:"caml_bytes_greaterequal" ~arity:2 ~alloc:false); int64comp = Pbintcomp (Pint64, Cge); + bigintcomp = Pbigintcomp Cge; simplify_constant_constructor = false; } ); ( "%compare", @@ -214,6 +221,9 @@ let comparisons_table = int64comp = Pccall (Primitive.simple ~name:"caml_int64_compare" ~arity:2 ~alloc:false); + bigintcomp = + Pccall + (Primitive.simple ~name:"caml_bigint_compare" ~arity:2 ~alloc:false); simplify_constant_constructor = false; } ); ( "%bs_max", @@ -226,6 +236,7 @@ let comparisons_table = floatcomp = arity2 "caml_float_max"; stringcomp = arity2 "caml_string_max"; int64comp = arity2 "caml_int64_max"; + bigintcomp = arity2 "caml_bigint_max"; simplify_constant_constructor = false; } ); ( "%bs_min", @@ -237,6 +248,7 @@ let comparisons_table = floatcomp = arity2 "caml_float_min"; stringcomp = arity2 "caml_string_min"; int64comp = arity2 "caml_int64_min"; + bigintcomp = arity2 "caml_bigint_min"; simplify_constant_constructor = false; } ); ( "%bs_equal_null", @@ -249,6 +261,7 @@ let comparisons_table = floatcomp = arity2 "caml_float_equal_null"; stringcomp = arity2 "caml_string_equal_null"; int64comp = arity2 "caml_int64_equal_null"; + bigintcomp = arity2 "caml_bigint_equal_null"; simplify_constant_constructor = true; } ); ( "%bs_equal_undefined", @@ -261,6 +274,7 @@ let comparisons_table = floatcomp = arity2 "caml_float_equal_undefined"; stringcomp = arity2 "caml_string_equal_undefined"; int64comp = arity2 "caml_int64_equal_undefined"; + bigintcomp = arity2 "caml_bigint_equal_undefined"; simplify_constant_constructor = true; } ); ( "%bs_equal_nullable", @@ -273,6 +287,7 @@ let comparisons_table = floatcomp = arity2 "caml_float_equal_nullable"; stringcomp = arity2 "caml_string_equal_nullable"; int64comp = arity2 "caml_int64_equal_nullable"; + bigintcomp = arity2 "caml_bigint_equal_nullable"; simplify_constant_constructor = true; } ); ] @@ -356,6 +371,12 @@ let primitives_table = ("%mulbigint", Pmulbigint); ("%divbigint", Pdivbigint Safe); ("%modbigint", Pmodbigint Safe); + ("%eqbigint", Pbigintcomp Ceq); + ("%noteqbigint", Pbigintcomp Cneq); + ("%ltbigint", Pbigintcomp Clt); + ("%lebigint", Pbigintcomp Cle); + ("%gtbigint", Pbigintcomp Cgt); + ("%gebigint", Pbigintcomp Cge); ("%string_length", Pstringlength); ("%string_safe_get", Pstringrefs); ("%string_unsafe_get", Pstringrefu); @@ -402,7 +423,7 @@ let primitives_table = let find_primitive prim_name = Hashtbl.find primitives_table prim_name let specialize_comparison - ({ gencomp; intcomp; floatcomp; stringcomp; bytescomp; int64comp; boolcomp } : + ({ gencomp; intcomp; floatcomp; stringcomp; bytescomp; int64comp; bigintcomp; boolcomp } : specialized) env ty = match () with | () @@ -414,6 +435,7 @@ let specialize_comparison | () when is_base_type env ty Predef.path_string -> stringcomp | () when is_base_type env ty Predef.path_bytes -> bytescomp | () when is_base_type env ty Predef.path_int64 -> int64comp + | () when is_base_type env ty Predef.path_bigint -> bigintcomp | () when is_base_type env ty Predef.path_bool -> boolcomp | () -> gencomp diff --git a/jscomp/runtime/caml.res b/jscomp/runtime/caml.res index b4cee4ec20..9a2b74bd85 100644 --- a/jscomp/runtime/caml.res +++ b/jscomp/runtime/caml.res @@ -52,6 +52,21 @@ let float_compare = (x: float, y: float) => 0 } +let bigint_compare = (x: bigint, y: bigint) => + if x == y { + 0 + } else if x < y { + -1 + } else if x > y { + 1 + } else if x == x { + 1 + } else if y == y { + -1 + } else { + 0 + } + /* Lexical order */ let string_compare = (s1: string, s2: string): int => if s1 == s2 { diff --git a/jscomp/runtime/caml.resi b/jscomp/runtime/caml.resi index f300ae7dac..fe4d629b3c 100644 --- a/jscomp/runtime/caml.resi +++ b/jscomp/runtime/caml.resi @@ -27,6 +27,7 @@ type selector<'a> = ('a, 'a) => 'a let int_compare: (int, int) => int let bool_compare: (bool, bool) => int let float_compare: (float, float) => int +let bigint_compare: (bigint, bigint) => int let string_compare: (string, string) => int let bool_min: selector diff --git a/lib/es6/caml.js b/lib/es6/caml.js index 01db3ad725..cc14694d24 100644 --- a/lib/es6/caml.js +++ b/lib/es6/caml.js @@ -39,6 +39,20 @@ function float_compare(x, y) { } } +function bigint_compare(x, y) { + if (x === y) { + return 0; + } else if (x < y) { + return -1; + } else if (x > y || x === x) { + return 1; + } else if (y === y) { + return -1; + } else { + return 0; + } +} + function string_compare(s1, s2) { if (s1 === s2) { return 0; @@ -175,6 +189,7 @@ export { int_compare , bool_compare , float_compare , + bigint_compare , string_compare , bool_min , int_min , diff --git a/lib/js/caml.js b/lib/js/caml.js index 06384353ab..bfbcf46623 100644 --- a/lib/js/caml.js +++ b/lib/js/caml.js @@ -39,6 +39,20 @@ function float_compare(x, y) { } } +function bigint_compare(x, y) { + if (x === y) { + return 0; + } else if (x < y) { + return -1; + } else if (x > y || x === x) { + return 1; + } else if (y === y) { + return -1; + } else { + return 0; + } +} + function string_compare(s1, s2) { if (s1 === s2) { return 0; @@ -174,6 +188,7 @@ function i64_max(x, y) { exports.int_compare = int_compare; exports.bool_compare = bool_compare; exports.float_compare = float_compare; +exports.bigint_compare = bigint_compare; exports.string_compare = string_compare; exports.bool_min = bool_min; exports.int_min = int_min; From 51e2ab2ec4d18f13e81434ec2a1ee75c1ae47260 Mon Sep 17 00:00:00 2001 From: mununki Date: Wed, 13 Mar 2024 14:27:27 +0900 Subject: [PATCH 13/45] add bigint_test and binding bigint methods, NaN, etc --- jscomp/others/js_bigint.res | 94 ++++++++++++++++++++ jscomp/test/bigint_test.js | 170 ++++++++++++++++++++++++++++++++++++ jscomp/test/bigint_test.res | 63 +++++++++++++ jscomp/test/build.ninja | 1 + 4 files changed, 328 insertions(+) create mode 100644 jscomp/test/bigint_test.js create mode 100644 jscomp/test/bigint_test.res diff --git a/jscomp/others/js_bigint.res b/jscomp/others/js_bigint.res index 397b4506eb..e7e1bf8da3 100644 --- a/jscomp/others/js_bigint.res +++ b/jscomp/others/js_bigint.res @@ -1,5 +1,72 @@ /*** JavaScript BigInt API */ +@val +/** +The special value "Not a Number". See [`NaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) on MDN. +*/ +external _NaN: bigint = "NaN" + +@val +@scope("Number") +/** +Tests if the given value is `_NaN` + +Note that both `_NaN = _NaN` and `_NaN == _NaN` will return `false`. `isNaN` is +therefore necessary to test for `_NaN`. Return `true` if the given value is +`_NaN`, `false` otherwise. See [`isNaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) on MDN. +*/ +external isNaN: bigint => bool = "isNaN" + +/** +Tests if the given value is finite. Return `true` if the given value is a finite +number, `false` otherwise. See [`isFinite`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) on MDN. + +## Examples + +```rescript +/* returns [false] */ +Js.Bigint.isFinite(infinity) + +/* returns [false] */ +Js.Bigint.isFinite(neg_infinity) + +/* returns [false] */ +Js.Bigint.isFinite(Js.Bigint._NaN) + +/* returns [true] */ +Js.Bigint.isFinite(1234.) +``` +*/ +external isFinite: bigint => bool = "isFinite" + +@val +/** +Parses the given `string` into a `bigint` using JavaScript semantics. Return the +number as a `bigint` if successfully parsed, `null`, `undefined`, `_NaN` otherwise. + +## Examples + +```rescript +/* returns 123n */ +Js.Bigint.fromString("123") + +/* returns 0n */ +Js.Bigint.fromString("") + +/* returns 17n */ +Js.Bigint.fromString("0x11") + +/* returns 3n */ +Js.Bigint.fromString("0b11") + +/* returns 9n */ +Js.Bigint.fromString("0o11") +``` +*/ +external fromStringExn: string => bigint = "BigInt" + +// Operations + external \"~-": bigint => bigint = "%negbigint" external \"~+": bigint => bigint = "%identity" external \"+": (bigint, bigint) => bigint = "%addbigint" @@ -7,3 +74,30 @@ external \"-": (bigint, bigint) => bigint = "%subbigint" external \"*": (bigint, bigint) => bigint = "%mulbigint" external \"/": (bigint, bigint) => bigint = "%divbigint" external mod: (bigint, bigint) => bigint = "%modbigint" + +@send +/** +Formats a `bigint` as a string. Return a `string` representing the given value. +See [`toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString) on MDN. + +## Examples + +```rescript +/* prints "123" */ +Js.Bigint.toString(123n)->Js.log +``` +*/ +external toString: bigint => string = "toString" + +@send +/** +Returns a string with a language-sensitive representation of this Bigint value. + +## Examples + +```rescript +/* prints "123" */ +Js.Bigint.toString(123n)->Js.log +``` +*/ +external toLocaleString: bigint => string = "toLocaleString" diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js new file mode 100644 index 0000000000..6d7fb09feb --- /dev/null +++ b/jscomp/test/bigint_test.js @@ -0,0 +1,170 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE +'use strict'; + +var Caml = require("../../lib/js/caml.js"); +var Caml_obj = require("../../lib/js/caml_obj.js"); +var Mt_global = require("./mt_global.js"); + +var test_id = { + contents: 0 +}; + +var suites = { + contents: /* [] */0 +}; + +function eq(loc) { + return function (param, param$1) { + return Mt_global.collect_eq(test_id, suites, loc, param, param$1); + }; +} + +function approx(loc) { + return function (param, param$1) { + return Mt_global.collect_approx(test_id, suites, loc, param, param$1); + }; +} + +var bigint_compare = Caml.bigint_compare; + +var generic_compare = Caml_obj.compare; + +function bigint_equal(x, y) { + return x === y; +} + +var generic_equal = Caml_obj.equal; + +function bigint_notequal(x, y) { + return x !== y; +} + +var generic_notequal = Caml_obj.notequal; + +function bigint_lessthan(x, y) { + return x < y; +} + +var generic_lessthan = Caml_obj.lessthan; + +function bigint_greaterthan(x, y) { + return x > y; +} + +var generic_greaterthan = Caml_obj.greaterthan; + +function bigint_lessequal(x, y) { + return x <= y; +} + +var generic_lessequal = Caml_obj.lessequal; + +function bigint_greaterequal(x, y) { + return x >= y; +} + +var generic_greaterequal = Caml_obj.greaterequal; + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 21, characters 5-12", Caml.bigint_compare(NaN, NaN), 0); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 22, characters 5-12", Caml_obj.compare(NaN, NaN), 0); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 23, characters 5-12", Caml.bigint_compare(NaN, -1n), -1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 24, characters 5-12", Caml_obj.compare(NaN, -1n), -1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 25, characters 5-12", Caml.bigint_compare(-1n, NaN), 1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 26, characters 5-12", Caml_obj.compare(-1n, NaN), 1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 27, characters 5-12", NaN === NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 28, characters 5-12", Caml_obj.equal(NaN, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 29, characters 5-12", 1n === NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 30, characters 5-12", Caml_obj.equal(1n, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 31, characters 5-12", NaN === 1n, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 32, characters 5-12", Caml_obj.equal(NaN, 1n), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 33, characters 5-12", NaN !== NaN, true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 34, characters 5-12", Caml_obj.notequal(NaN, NaN), true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 35, characters 5-12", 1n !== NaN, true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 36, characters 5-12", Caml_obj.notequal(1n, NaN), true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 37, characters 5-12", NaN !== 1n, true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 38, characters 5-12", Caml_obj.notequal(NaN, 1n), true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 39, characters 5-12", NaN < NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 40, characters 5-12", Caml_obj.lessthan(NaN, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 41, characters 5-12", 1n < NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 42, characters 5-12", Caml_obj.lessthan(1n, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 43, characters 5-12", NaN < 1n, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 44, characters 5-12", Caml_obj.lessthan(NaN, 1n), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 45, characters 5-12", NaN > NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 46, characters 5-12", Caml_obj.greaterthan(NaN, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 47, characters 5-12", 1n > NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 48, characters 5-12", Caml_obj.greaterthan(1n, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 49, characters 5-12", NaN > 1n, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 50, characters 5-12", Caml_obj.greaterthan(NaN, 1n), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 51, characters 5-12", NaN <= NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 52, characters 5-12", Caml_obj.lessequal(NaN, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 53, characters 5-12", 1n <= NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 54, characters 5-12", Caml_obj.lessequal(1n, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 55, characters 5-12", NaN <= 1n, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 56, characters 5-12", Caml_obj.lessequal(NaN, 1n), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 57, characters 5-12", NaN >= NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 58, characters 5-12", Caml_obj.greaterequal(NaN, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 59, characters 5-12", 1n >= NaN, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 60, characters 5-12", Caml_obj.greaterequal(1n, NaN), false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 61, characters 5-12", NaN >= 1n, false); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 62, characters 5-12", Caml_obj.greaterequal(NaN, 1n), false); + +exports.test_id = test_id; +exports.suites = suites; +exports.eq = eq; +exports.approx = approx; +exports.bigint_compare = bigint_compare; +exports.generic_compare = generic_compare; +exports.bigint_equal = bigint_equal; +exports.generic_equal = generic_equal; +exports.bigint_notequal = bigint_notequal; +exports.generic_notequal = generic_notequal; +exports.bigint_lessthan = bigint_lessthan; +exports.generic_lessthan = generic_lessthan; +exports.bigint_greaterthan = bigint_greaterthan; +exports.generic_greaterthan = generic_greaterthan; +exports.bigint_lessequal = bigint_lessequal; +exports.generic_lessequal = generic_lessequal; +exports.bigint_greaterequal = bigint_greaterequal; +exports.generic_greaterequal = generic_greaterequal; +/* Not a pure module */ diff --git a/jscomp/test/bigint_test.res b/jscomp/test/bigint_test.res new file mode 100644 index 0000000000..28890ffea8 --- /dev/null +++ b/jscomp/test/bigint_test.res @@ -0,0 +1,63 @@ +let (test_id, suites) = (ref(0), ref(list{})) +let eq = loc => Mt_global.collect_eq(test_id, suites, loc) +let approx = loc => Mt_global.collect_approx(test_id, suites, loc) + +let bigint_compare = (x: bigint, y) => Pervasives.compare(x, y) +let generic_compare = Pervasives.compare +let bigint_equal = (x: bigint, y) => x == y +let generic_equal = \"=" +let bigint_notequal = (x: bigint, y) => x != y +let generic_notequal = \"<>" +let bigint_lessthan = (x: bigint, y) => x < y +let generic_lessthan = \"<" +let bigint_greaterthan = (x: bigint, y) => x > y +let generic_greaterthan = \">" +let bigint_lessequal = (x: bigint, y) => x <= y +let generic_lessequal = \"<=" +let bigint_greaterequal = (x: bigint, y) => x >= y +let generic_greaterequal = \">=" + +let () = { + eq(__LOC__, bigint_compare(Js.Bigint._NaN, Js.Bigint._NaN), 0) + eq(__LOC__, generic_compare(Js.Bigint._NaN, Js.Bigint._NaN), 0) + eq(__LOC__, bigint_compare(Js.Bigint._NaN, -1n), -1) + eq(__LOC__, generic_compare(Js.Bigint._NaN, -1n), -1) + eq(__LOC__, bigint_compare(-1n, Js.Bigint._NaN), 1) + eq(__LOC__, generic_compare(-1n, Js.Bigint._NaN), 1) + eq(__LOC__, bigint_equal(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, generic_equal(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, bigint_equal(1n, Js.Bigint._NaN), false) + eq(__LOC__, generic_equal(1n, Js.Bigint._NaN), false) + eq(__LOC__, bigint_equal(Js.Bigint._NaN, 1n), false) + eq(__LOC__, generic_equal(Js.Bigint._NaN, 1n), false) + eq(__LOC__, bigint_notequal(Js.Bigint._NaN, Js.Bigint._NaN), true) + eq(__LOC__, generic_notequal(Js.Bigint._NaN, Js.Bigint._NaN), true) + eq(__LOC__, bigint_notequal(1n, Js.Bigint._NaN), true) + eq(__LOC__, generic_notequal(1n, Js.Bigint._NaN), true) + eq(__LOC__, bigint_notequal(Js.Bigint._NaN, 1n), true) + eq(__LOC__, generic_notequal(Js.Bigint._NaN, 1n), true) + eq(__LOC__, bigint_lessthan(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, generic_lessthan(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, bigint_lessthan(1n, Js.Bigint._NaN), false) + eq(__LOC__, generic_lessthan(1n, Js.Bigint._NaN), false) + eq(__LOC__, bigint_lessthan(Js.Bigint._NaN, 1n), false) + eq(__LOC__, generic_lessthan(Js.Bigint._NaN, 1n), false) + eq(__LOC__, bigint_greaterthan(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, generic_greaterthan(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, bigint_greaterthan(1n, Js.Bigint._NaN), false) + eq(__LOC__, generic_greaterthan(1n, Js.Bigint._NaN), false) + eq(__LOC__, bigint_greaterthan(Js.Bigint._NaN, 1n), false) + eq(__LOC__, generic_greaterthan(Js.Bigint._NaN, 1n), false) + eq(__LOC__, bigint_lessequal(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, generic_lessequal(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, bigint_lessequal(1n, Js.Bigint._NaN), false) + eq(__LOC__, generic_lessequal(1n, Js.Bigint._NaN), false) + eq(__LOC__, bigint_lessequal(Js.Bigint._NaN, 1n), false) + eq(__LOC__, generic_lessequal(Js.Bigint._NaN, 1n), false) + eq(__LOC__, bigint_greaterequal(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, generic_greaterequal(Js.Bigint._NaN, Js.Bigint._NaN), false) + eq(__LOC__, bigint_greaterequal(1n, Js.Bigint._NaN), false) + eq(__LOC__, generic_greaterequal(1n, Js.Bigint._NaN), false) + eq(__LOC__, bigint_greaterequal(Js.Bigint._NaN, 1n), false) + eq(__LOC__, generic_greaterequal(Js.Bigint._NaN, 1n), false) +} diff --git a/jscomp/test/build.ninja b/jscomp/test/build.ninja index 26ddd84f68..aee68d4480 100644 --- a/jscomp/test/build.ninja +++ b/jscomp/test/build.ninja @@ -85,6 +85,7 @@ o test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj : cc test/belt o test/bench.cmi test/bench.cmj : cc test/bench.res | $bsc $stdlib runtime o test/big_enum.cmi test/big_enum.cmj : cc test/big_enum.res | $bsc $stdlib runtime o test/big_polyvar_test.cmi test/big_polyvar_test.cmj : cc test/big_polyvar_test.res | $bsc $stdlib runtime +o test/bigint_test.cmi test/bigint_test.cmj : cc test/bigint_test.res | test/mt_global.cmj $bsc $stdlib runtime o test/block_alias_test.cmi test/block_alias_test.cmj : cc test/block_alias_test.res | test/mt.cmj $bsc $stdlib runtime o test/boolean_test.cmi test/boolean_test.cmj : cc test/boolean_test.res | test/mt.cmj test/test_bool_equal.cmj $bsc $stdlib runtime o test/bs_MapInt_test.cmi test/bs_MapInt_test.cmj : cc test/bs_MapInt_test.res | $bsc $stdlib runtime From 84cf107ef28555d43976bc533add13cf3f869ee8 Mon Sep 17 00:00:00 2001 From: mununki Date: Wed, 13 Mar 2024 14:31:47 +0900 Subject: [PATCH 14/45] stale comment --- jscomp/others/js_bigint.res | 6 ------ 1 file changed, 6 deletions(-) diff --git a/jscomp/others/js_bigint.res b/jscomp/others/js_bigint.res index e7e1bf8da3..105b10580e 100644 --- a/jscomp/others/js_bigint.res +++ b/jscomp/others/js_bigint.res @@ -24,12 +24,6 @@ number, `false` otherwise. See [`isFinite`](https://developer.mozilla.org/en-US/ ## Examples ```rescript -/* returns [false] */ -Js.Bigint.isFinite(infinity) - -/* returns [false] */ -Js.Bigint.isFinite(neg_infinity) - /* returns [false] */ Js.Bigint.isFinite(Js.Bigint._NaN) From 0f21844a662cfe2bcb4b6ce01b30b7fd07bcecd3 Mon Sep 17 00:00:00 2001 From: mununki Date: Wed, 13 Mar 2024 20:58:09 +0900 Subject: [PATCH 15/45] add bigint pow operator --- jscomp/core/js_exp_make.ml | 2 + jscomp/core/js_exp_make.mli | 2 + jscomp/core/js_op.ml | 1 + jscomp/core/js_op_util.ml | 3 +- jscomp/core/lam_analysis.ml | 2 +- jscomp/core/lam_compile_primitive.ml | 1 + jscomp/core/lam_convert.ml | 1 + jscomp/core/lam_primitive.ml | 2 + jscomp/core/lam_primitive.mli | 1 + jscomp/core/lam_print.ml | 11 +- jscomp/ml/lambda.ml | 2 +- jscomp/ml/lambda.mli | 2 +- jscomp/ml/printlambda.ml | 10 +- jscomp/ml/translcore.ml | 1 + jscomp/others/js_bigint.res | 1 + jscomp/stdlib-406/pervasives.res | 1 + jscomp/stdlib-406/pervasives.resi | 4 + jscomp/stdlib-406/pervasivesU.res | 1 + jscomp/stdlib-406/pervasivesU.resi | 4 + jscomp/syntax/src/res_comments_table.ml | 3 +- jscomp/syntax/src/res_core.ml | 3 +- jscomp/syntax/src/res_parsetree_viewer.ml | 6 +- jscomp/syntax/src/res_scanner.ml | 11 +- jscomp/syntax/src/res_token.ml | 4 +- .../parsing/grammar/expressions/bigint.res | 9 + .../expressions/expected/bigint.res.txt | 5 + jscomp/syntax/tests/printer/other/case.res | 3 +- .../tests/printer/other/expected/case.res.txt | 3 +- jscomp/test/ocaml_re_test.js | 390 ++++++++++++++++++ 29 files changed, 465 insertions(+), 24 deletions(-) create mode 100644 jscomp/syntax/tests/parsing/grammar/expressions/bigint.res create mode 100644 jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index 98a660aa99..44d03a8852 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -1270,6 +1270,8 @@ let bigint_div ?comment (e1: t) (e2: t) = bin ?comment Div e1 e2 let bigint_mod ?comment (e1: t) (e2: t) = bin ?comment Mod e1 e2 +let bigint_pow ?comment (e1: t) (e2: t) = bin ?comment Pow e1 e2 + let bigint_comp (cmp : Lam_compat.comparison) ?comment (e0: t) (e1: t) = match (cmp, e0.expression_desc, e1.expression_desc) with | Ceq, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 = i1) diff --git a/jscomp/core/js_exp_make.mli b/jscomp/core/js_exp_make.mli index 2981c77d84..1931542384 100644 --- a/jscomp/core/js_exp_make.mli +++ b/jscomp/core/js_exp_make.mli @@ -286,6 +286,8 @@ val bigint_div : ?comment: string -> t -> t -> t val bigint_mod : ?comment: string -> t -> t -> t +val bigint_pow : ?comment: string -> t -> t -> t + val bigint_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t val js_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t diff --git a/jscomp/core/js_op.ml b/jscomp/core/js_op.ml index a2b7b07128..5054b3cee4 100644 --- a/jscomp/core/js_op.ml +++ b/jscomp/core/js_op.ml @@ -48,6 +48,7 @@ type binop = | Mul | Div | Mod + | Pow | InstanceOf (** diff --git a/jscomp/core/js_op_util.ml b/jscomp/core/js_op_util.ml index 6431b16fc8..87997f6792 100644 --- a/jscomp/core/js_op_util.ml +++ b/jscomp/core/js_op_util.ml @@ -40,7 +40,7 @@ let op_prec (op : Js_op.binop) = | Band -> (7, 7, 7) | Lsl | Lsr | Asr -> (10, 10, 11) | Plus | Minus -> (11, 11, 12) - | Mul | Div | Mod -> (12, 12, 13) + | Mul | Div | Mod | Pow -> (12, 12, 13) let op_int_prec (op : Js_op.int_op) = match op with @@ -64,6 +64,7 @@ let op_str (op : Js_op.binop) = | Mul -> "*" | Div -> "/" | Mod -> "%" + | Pow -> "**" | Eq -> "=" | Or -> "||" | And -> "&&" diff --git a/jscomp/core/lam_analysis.ml b/jscomp/core/lam_analysis.ml index b1afbf2463..cc65845a4b 100644 --- a/jscomp/core/lam_analysis.ml +++ b/jscomp/core/lam_analysis.ml @@ -77,7 +77,7 @@ let rec no_side_effects (lam : Lam.t) : bool = | Pintoffloat | Pfloatofint | Pnegfloat (* | Pabsfloat *) | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pbigintcomp _ | Pjscomp _ - | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint + | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Ppowbigint (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu | Pbytesrefs | Pmakearray | Parraylength | Parrayrefu | Parrayrefs diff --git a/jscomp/core/lam_compile_primitive.ml b/jscomp/core/lam_compile_primitive.ml index 88424f1771..0c6fd55ab1 100644 --- a/jscomp/core/lam_compile_primitive.ml +++ b/jscomp/core/lam_compile_primitive.ml @@ -221,6 +221,7 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) | _ -> assert false) | Pmodint64 -> Js_long.mod_ args | Pmodbigint -> (match args with [ e1; e2 ] -> E.bigint_mod e1 e2 | _ -> assert false) + | Ppowbigint -> (match args with [ e1; e2 ] -> E.bigint_pow e1 e2 | _ -> assert false) | Plslint -> ( match args with [ e1; e2 ] -> E.int32_lsl e1 e2 | _ -> assert false) | Plslint64 -> Js_long.lsl_ args diff --git a/jscomp/core/lam_convert.ml b/jscomp/core/lam_convert.ml index 25aa8cd554..0b2564166c 100644 --- a/jscomp/core/lam_convert.ml +++ b/jscomp/core/lam_convert.ml @@ -260,6 +260,7 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t = | Pmulbigint -> prim ~primitive:Pmulbigint ~args loc | Pdivbigint _is_safe (*FIXME*) -> prim ~primitive:Pdivbigint ~args loc | Pmodbigint _is_safe (*FIXME*) -> prim ~primitive:Pmodbigint ~args loc + | Ppowbigint -> prim ~primitive:Ppowbigint ~args loc | Pbigintcomp x -> prim ~primitive:(Pbigintcomp x) ~args loc | Pintcomp x -> prim ~primitive:(Pintcomp x) ~args loc | Poffsetint x -> prim ~primitive:(Poffsetint x) ~args loc diff --git a/jscomp/core/lam_primitive.ml b/jscomp/core/lam_primitive.ml index 4b7eadea63..0acfbb2022 100644 --- a/jscomp/core/lam_primitive.ml +++ b/jscomp/core/lam_primitive.ml @@ -87,6 +87,7 @@ type t = | Pmulbigint | Pdivbigint | Pmodbigint + | Ppowbigint | Pintcomp of Lam_compat.comparison | Pfloatcomp of Lam_compat.comparison | Pjscomp of Lam_compat.comparison @@ -215,6 +216,7 @@ let eq_primitive_approx (lhs : t) (rhs : t) = | Pmulbigint -> rhs = Pmulbigint | Pdivbigint -> rhs = Pdivbigint | Pmodbigint -> rhs = Pmodbigint + | Ppowbigint -> rhs = Ppowbigint | Pjs_apply -> rhs = Pjs_apply | Pjs_runtime_apply -> rhs = Pjs_runtime_apply | Pstringlength -> rhs = Pstringlength diff --git a/jscomp/core/lam_primitive.mli b/jscomp/core/lam_primitive.mli index aef8bf983e..8a2d2ab31b 100644 --- a/jscomp/core/lam_primitive.mli +++ b/jscomp/core/lam_primitive.mli @@ -77,6 +77,7 @@ type t = | Pmulbigint | Pdivbigint | Pmodbigint + | Ppowbigint | Pintcomp of Lam_compat.comparison | Pfloatcomp of Lam_compat.comparison | Pjscomp of Lam_compat.comparison diff --git a/jscomp/core/lam_print.ml b/jscomp/core/lam_print.ml index 33475aed57..cf02060472 100644 --- a/jscomp/core/lam_print.ml +++ b/jscomp/core/lam_print.ml @@ -134,12 +134,13 @@ let primitive ppf (prim : Lam_primitive.t) = | Pfloatcomp Cle -> fprintf ppf "<=." | Pfloatcomp Cgt -> fprintf ppf ">." | Pfloatcomp Cge -> fprintf ppf ">=." - | Pnegbigint -> fprintf ppf "~n" - | Paddbigint -> fprintf ppf "+n" - | Psubbigint -> fprintf ppf "-n" - | Pmulbigint -> fprintf ppf "*n" - | Pdivbigint -> fprintf ppf "/n" + | Pnegbigint -> fprintf ppf "~," + | Paddbigint -> fprintf ppf "+," + | Psubbigint -> fprintf ppf "-," + | Pmulbigint -> fprintf ppf "*," + | Pdivbigint -> fprintf ppf "/," | Pmodbigint -> fprintf ppf "modn" + | Ppowbigint -> fprintf ppf "**," | Pbigintcomp Ceq -> fprintf ppf "==," | Pbigintcomp Cneq -> fprintf ppf "!=," | Pbigintcomp Clt -> fprintf ppf "<," diff --git a/jscomp/ml/lambda.ml b/jscomp/ml/lambda.ml index 977344fadf..e0319ec4f9 100644 --- a/jscomp/ml/lambda.ml +++ b/jscomp/ml/lambda.ml @@ -230,7 +230,7 @@ type primitive = | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp of comparison (* Bigint operations *) - | Pnegbigint | Paddbigint | Psubbigint + | Pnegbigint | Paddbigint | Psubbigint | Ppowbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe | Pbigintcomp of comparison (* String operations *) diff --git a/jscomp/ml/lambda.mli b/jscomp/ml/lambda.mli index c0b9e3036f..2848c0f3f6 100644 --- a/jscomp/ml/lambda.mli +++ b/jscomp/ml/lambda.mli @@ -196,7 +196,7 @@ type primitive = | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp of comparison (* Bigint operations *) - | Pnegbigint | Paddbigint | Psubbigint + | Pnegbigint | Paddbigint | Psubbigint | Ppowbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe | Pbigintcomp of comparison (* String operations *) diff --git a/jscomp/ml/printlambda.ml b/jscomp/ml/printlambda.ml index 40f2b8c1c1..6014ea65d6 100644 --- a/jscomp/ml/printlambda.ml +++ b/jscomp/ml/printlambda.ml @@ -177,10 +177,11 @@ let primitive ppf = function | Pfloatcomp(Cle) -> fprintf ppf "<=." | Pfloatcomp(Cgt) -> fprintf ppf ">." | Pfloatcomp(Cge) -> fprintf ppf ">=." - | Pnegbigint -> fprintf ppf "~n" - | Paddbigint -> fprintf ppf "+n" - | Psubbigint -> fprintf ppf "-n" - | Pmulbigint -> fprintf ppf "*n" + | Pnegbigint -> fprintf ppf "~," + | Paddbigint -> fprintf ppf "+," + | Psubbigint -> fprintf ppf "-," + | Pmulbigint -> fprintf ppf "*," + | Ppowbigint -> fprintf ppf "**," | Pdivbigint Safe -> fprintf ppf "/n" | Pdivbigint Unsafe -> fprintf ppf "/nu" | Pmodbigint Safe -> fprintf ppf "mod" @@ -298,6 +299,7 @@ let name_of_primitive = function | Pmulbigint -> "Pmulbigint" | Pdivbigint _ -> "Pdivbigint" | Pmodbigint _ -> "Pmodbigint" + | Ppowbigint -> "Ppowbigint" | Pbigintcomp _ -> "Pbigintcomp" | Pstringlength -> "Pstringlength" | Pstringrefu -> "Pstringrefu" diff --git a/jscomp/ml/translcore.ml b/jscomp/ml/translcore.ml index 72c41e56eb..01ea01fc31 100644 --- a/jscomp/ml/translcore.ml +++ b/jscomp/ml/translcore.ml @@ -370,6 +370,7 @@ let primitives_table = ("%subbigint", Psubbigint); ("%mulbigint", Pmulbigint); ("%divbigint", Pdivbigint Safe); + ("%powbigint", Ppowbigint); ("%modbigint", Pmodbigint Safe); ("%eqbigint", Pbigintcomp Ceq); ("%noteqbigint", Pbigintcomp Cneq); diff --git a/jscomp/others/js_bigint.res b/jscomp/others/js_bigint.res index 105b10580e..857a7293ab 100644 --- a/jscomp/others/js_bigint.res +++ b/jscomp/others/js_bigint.res @@ -68,6 +68,7 @@ external \"-": (bigint, bigint) => bigint = "%subbigint" external \"*": (bigint, bigint) => bigint = "%mulbigint" external \"/": (bigint, bigint) => bigint = "%divbigint" external mod: (bigint, bigint) => bigint = "%modbigint" +external \"**": (bigint, bigint) => bigint = "%powbigint" @send /** diff --git a/jscomp/stdlib-406/pervasives.res b/jscomp/stdlib-406/pervasives.res index d88f5cac0d..027cddc1bd 100644 --- a/jscomp/stdlib-406/pervasives.res +++ b/jscomp/stdlib-406/pervasives.res @@ -188,6 +188,7 @@ external \"-,": (bigint, bigint) => bigint = "%subbigint" external \"*,": (bigint, bigint) => bigint = "%mulbigint" external \"/,": (bigint, bigint) => bigint = "%divbigint" external modn: (bigint, bigint) => bigint = "%modbigint" +external \"**,": (bigint, bigint) => bigint = "%powbigint" /* String and byte sequence operations -- more in modules String and Bytes */ diff --git a/jscomp/stdlib-406/pervasives.resi b/jscomp/stdlib-406/pervasives.resi index 795c137006..42db582871 100644 --- a/jscomp/stdlib-406/pervasives.resi +++ b/jscomp/stdlib-406/pervasives.resi @@ -564,6 +564,10 @@ external \"/,": (bigint, bigint) => bigint = "%divbigint" Left-associative operator at precedence level 7/11. */ external modn: (bigint, bigint) => bigint = "%modbigint" +/** Bigint Exponentiation. + Left-associative operator at precedence level 7/9. */ +external \"**,": (bigint, bigint) => bigint = "%powbigint" + @val @scope("Number") /** A special floating-point value denoting the result of an diff --git a/jscomp/stdlib-406/pervasivesU.res b/jscomp/stdlib-406/pervasivesU.res index 4f1378bcb2..76889ce38b 100644 --- a/jscomp/stdlib-406/pervasivesU.res +++ b/jscomp/stdlib-406/pervasivesU.res @@ -189,6 +189,7 @@ external \"-,": (bigint, bigint) => bigint = "%subbigint" external \"*,": (bigint, bigint) => bigint = "%mulbigint" external \"/,": (bigint, bigint) => bigint = "%divbigint" external modn: (bigint, bigint) => bigint = "%modbigint" +external \"**,": (bigint, bigint) => bigint = "%powbigint" /* String and byte sequence operations -- more in modules String and Bytes */ diff --git a/jscomp/stdlib-406/pervasivesU.resi b/jscomp/stdlib-406/pervasivesU.resi index d3ed6f92ad..e5132d7f16 100644 --- a/jscomp/stdlib-406/pervasivesU.resi +++ b/jscomp/stdlib-406/pervasivesU.resi @@ -567,6 +567,10 @@ external \"/,": (bigint, bigint) => bigint = "%divbigint" Left-associative operator at precedence level 7/11. */ external modn: (bigint, bigint) => bigint = "%modbigint" +/** Bigint Exponentiation. + Left-associative operator at precedence level 7/9. */ +external \"**,": (bigint, bigint) => bigint = "%powbigint" + @val @scope("Number") /** A special floating-point value denoting the result of an diff --git a/jscomp/syntax/src/res_comments_table.ml b/jscomp/syntax/src/res_comments_table.ml index 28a29b40a5..df9379b4e9 100644 --- a/jscomp/syntax/src/res_comments_table.ml +++ b/jscomp/syntax/src/res_comments_table.ml @@ -1288,7 +1288,8 @@ and walkExpression expr t comments = Longident.Lident ( ":=" | "||" | "&&" | "=" | "==" | "<" | ">" | "!=" | "!==" | "<=" | ">=" | "|>" | "+" | "+." | "-" | "-." | "++" | "^" - | "*" | "*." | "/" | "/." | "**" | "|." | "|.u" | "<>" ); + | "*" | "*." | "/" | "/." | "**" | "**," | "|." | "|.u" + | "<>" ); }; }, [(Nolabel, operand1); (Nolabel, operand2)] ) -> diff --git a/jscomp/syntax/src/res_core.ml b/jscomp/syntax/src/res_core.ml index 7966ec74b5..ce39f9eeda 100644 --- a/jscomp/syntax/src/res_core.ml +++ b/jscomp/syntax/src/res_core.ml @@ -2200,7 +2200,8 @@ and parseBinaryExpr ?(context = OrdinaryExpr) ?a p prec = let endPos = p.prevEndPos in let tokenPrec = (* exponentiation operator is right-associative *) - if token = Exponentiation then tokenPrec else tokenPrec + 1 + if token = Exponentiation || token = ExponentiationComma then tokenPrec + else tokenPrec + 1 in let b = parseBinaryExpr ~context p tokenPrec in let loc = mkLoc a.Parsetree.pexp_loc.loc_start b.pexp_loc.loc_end in diff --git a/jscomp/syntax/src/res_parsetree_viewer.ml b/jscomp/syntax/src/res_parsetree_viewer.ml index 60fa5e7762..0f7f85e5d3 100644 --- a/jscomp/syntax/src/res_parsetree_viewer.ml +++ b/jscomp/syntax/src/res_parsetree_viewer.ml @@ -294,7 +294,7 @@ let operatorPrecedence operator = | "=" | "==" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 4 | "+" | "+." | "+," | "-" | "-." | "-," | "^" -> 5 | "*" | "*." | "/" | "/." -> 6 - | "**" -> 7 + | "**" | "**," -> 7 | "#" | "##" | "|." | "|.u" -> 8 | _ -> 0 @@ -317,7 +317,7 @@ let isBinaryOperator operator = match operator with | ":=" | "||" | "&&" | "=" | "==" | "<" | ">" | "!=" | "!==" | "<=" | ">=" | "|>" | "+" | "+." | "+," | "-" | "-." | "-," | "^" | "*" | "*." | "*," | "/" - | "/." | "/," | "**" | "|." | "|.u" | "<>" -> + | "/." | "/," | "**" | "**," | "|." | "|.u" | "<>" -> true | _ -> false @@ -342,7 +342,7 @@ let isEqualityOperator operator = let isRhsBinaryOperator operator = match operator with - | "**" -> true + | "**" | "**," -> true | _ -> false let flattenableOperators parentOperator childOperator = diff --git a/jscomp/syntax/src/res_scanner.ml b/jscomp/syntax/src/res_scanner.ml index 82875e709e..37767697f7 100644 --- a/jscomp/syntax/src/res_scanner.ml +++ b/jscomp/syntax/src/res_scanner.ml @@ -691,9 +691,14 @@ let rec scan scanner = Token.Hash) | '*' -> ( match peek scanner with - | '*' -> - next2 scanner; - Token.Exponentiation + | '*' -> ( + match peek2 scanner with + | ',' -> + next3 scanner; + Token.ExponentiationComma + | _ -> + next2 scanner; + Token.Exponentiation) | '.' -> next2 scanner; Token.AsteriskDot diff --git a/jscomp/syntax/src/res_token.ml b/jscomp/syntax/src/res_token.ml index a81249cdc7..3ec3d60687 100644 --- a/jscomp/syntax/src/res_token.ml +++ b/jscomp/syntax/src/res_token.ml @@ -44,6 +44,7 @@ type t = | AsteriskDot | AsteriskComma | Exponentiation + | ExponentiationComma | Minus | MinusDot | MinusComma @@ -112,7 +113,7 @@ let precedence = function | Asterisk | AsteriskDot | AsteriskComma | Forwardslash | ForwardslashDot | ForwardslashComma -> 6 - | Exponentiation -> 7 + | Exponentiation | ExponentiationComma -> 7 | MinusGreater -> 8 | Dot -> 9 | _ -> 0 @@ -175,6 +176,7 @@ let toString = function | AsteriskDot -> "*." | AsteriskComma -> "*," | Exponentiation -> "**" + | ExponentiationComma -> "**," | Assert -> "assert" | Lazy -> "lazy" | Tilde -> "tilde" diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res b/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res new file mode 100644 index 0000000000..da9e998e63 --- /dev/null +++ b/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res @@ -0,0 +1,9 @@ +1n /, 2n + +3n *, 4n + +2n **, 2n + +10n +, 54 + +289n -, 138n diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt new file mode 100644 index 0000000000..88b6519ac1 --- /dev/null +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt @@ -0,0 +1,5 @@ +;;1n /, 2n +;;3n *, 4n +;;2n **, 2n +;;10n +, 54 +;;289n -, 138n \ No newline at end of file diff --git a/jscomp/syntax/tests/printer/other/case.res b/jscomp/syntax/tests/printer/other/case.res index c72cc2f8a7..ab84f19d11 100644 --- a/jscomp/syntax/tests/printer/other/case.res +++ b/jscomp/syntax/tests/printer/other/case.res @@ -93,7 +93,8 @@ let precedence = x => switch x { | AsteriskDot | Forwardslash | ForwardslashDot => 6 - | Exponentiation => 7 + | Exponentiation + | ExponentiationComma => 7 | Hash | HashHash | MinusGreater => 8 diff --git a/jscomp/syntax/tests/printer/other/expected/case.res.txt b/jscomp/syntax/tests/printer/other/expected/case.res.txt index 38931fc1d1..52acaf7bee 100644 --- a/jscomp/syntax/tests/printer/other/expected/case.res.txt +++ b/jscomp/syntax/tests/printer/other/expected/case.res.txt @@ -83,7 +83,8 @@ let precedence = x => | AsteriskDot | Forwardslash | ForwardslashDot => 6 - | Exponentiation => 7 + | Exponentiation + | ExponentiationComma => 7 | Hash | HashHash | MinusGreater => 8 diff --git a/jscomp/test/ocaml_re_test.js b/jscomp/test/ocaml_re_test.js index 1f4ac1fc4b..19d1e1e186 100644 --- a/jscomp/test/ocaml_re_test.js +++ b/jscomp/test/ocaml_re_test.js @@ -4143,6 +4143,396 @@ function parse(multiline, dollar_endonly, dotall, ungreedy, s) { }; } }; + var bracket = function (_s) { + while(true) { + var s = _s; + if (s !== /* [] */0 && accept(/* ']' */93)) { + return s; + } + var match = $$char(); + if (match.NAME === "Char") { + var c = match.VAL; + if (accept(/* '-' */45)) { + if (accept(/* ']' */93)) { + return { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '-' */45, + /* '-' */45 + ], + tl: /* [] */0 + } + }, + tl: s + } + }; + } + var match$1 = $$char(); + if (match$1.NAME !== "Char") { + return { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '-' */45, + /* '-' */45 + ], + tl: /* [] */0 + } + }, + tl: { + hd: match$1.VAL, + tl: s + } + } + }; + } + _s = { + hd: { + TAG: "Set", + _0: seq(c, match$1.VAL) + }, + tl: s + }; + continue ; + } + _s = { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: s + }; + continue ; + } + _s = { + hd: match.VAL, + tl: s + }; + continue ; + }; + }; + var atom = function (param) { + if (accept(/* '.' */46)) { + if (dotall) { + return any; + } else { + return notnl; + } + } + if (accept(/* '(' */40)) { + if (accept(/* '?' */63)) { + if (accept(/* ':' */58)) { + var r = regexp$p(branch$p(/* [] */0)); + if (!accept(/* ')' */41)) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + return r; + } + if (accept(/* '#' */35)) { + var _param; + while(true) { + if (accept(/* ')' */41)) { + return epsilon; + } + i.contents = i.contents + 1 | 0; + _param = undefined; + continue ; + }; + } + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + var r$1 = regexp$p(branch$p(/* [] */0)); + if (!accept(/* ')' */41)) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + return { + TAG: "Group", + _0: r$1 + }; + } + if (accept(/* '^' */94)) { + if (multiline) { + return "Beg_of_line"; + } else { + return "Beg_of_str"; + } + } + if (accept(/* '$' */36)) { + if (multiline) { + return "End_of_line"; + } else if (dollar_endonly) { + return "Last_end_of_line"; + } else { + return "End_of_str"; + } + } + if (accept(/* '[' */91)) { + if (accept(/* '^' */94)) { + return compl(bracket(/* [] */0)); + } else { + return alt$1(bracket(/* [] */0)); + } + } + if (accept(/* '\\' */92)) { + if (i.contents === l) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + var c = get(); + switch (c) { + case 48 : + case 49 : + case 50 : + case 51 : + case 52 : + case 53 : + case 54 : + case 55 : + case 56 : + case 57 : + throw { + RE_EXN_ID: Not_supported, + Error: new Error() + }; + case 65 : + return "Beg_of_str"; + case 66 : + return "Not_bound"; + case 68 : + return compl({ + hd: digit, + tl: /* [] */0 + }); + case 71 : + return "Start"; + case 83 : + return compl({ + hd: space, + tl: /* [] */0 + }); + case 87 : + return compl({ + hd: alnum, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '_' */95, + /* '_' */95 + ], + tl: /* [] */0 + } + }, + tl: /* [] */0 + } + }); + case 90 : + return "Last_end_of_line"; + case 58 : + case 59 : + case 60 : + case 61 : + case 62 : + case 63 : + case 64 : + case 91 : + case 92 : + case 93 : + case 94 : + case 95 : + case 96 : + return { + TAG: "Set", + _0: single(c) + }; + case 98 : + return alt$1({ + hd: "Beg_of_word", + tl: { + hd: "End_of_word", + tl: /* [] */0 + } + }); + case 100 : + return digit; + case 115 : + return space; + case 119 : + return alt$1({ + hd: alnum, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '_' */95, + /* '_' */95 + ], + tl: /* [] */0 + } + }, + tl: /* [] */0 + } + }); + case 67 : + case 69 : + case 70 : + case 72 : + case 73 : + case 74 : + case 75 : + case 76 : + case 77 : + case 78 : + case 79 : + case 80 : + case 81 : + case 82 : + case 84 : + case 85 : + case 86 : + case 88 : + case 89 : + case 97 : + case 99 : + case 101 : + case 102 : + case 103 : + case 104 : + case 105 : + case 106 : + case 107 : + case 108 : + case 109 : + case 110 : + case 111 : + case 112 : + case 113 : + case 114 : + case 116 : + case 117 : + case 118 : + case 120 : + case 121 : + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + case 122 : + return "End_of_str"; + default: + return { + TAG: "Set", + _0: single(c) + }; + } + } else { + if (i.contents === l) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + var c$1 = get(); + if (c$1 >= 64) { + if (c$1 !== 92) { + if (c$1 !== 123) { + return { + TAG: "Set", + _0: single(c$1) + }; + } + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + if (c$1 >= 44) { + if (c$1 >= 63) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + return { + TAG: "Set", + _0: single(c$1) + }; + } + if (c$1 >= 42) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + return { + TAG: "Set", + _0: single(c$1) + }; + } + }; + var integer = function (param) { + if (i.contents === l) { + return ; + } + var d = get(); + if (d > 57 || d < 48) { + i.contents = i.contents - 1 | 0; + return ; + } else { + var _i = d - /* '0' */48 | 0; + while(true) { + var i$1 = _i; + if (i.contents === l) { + return i$1; + } + var d$1 = get(); + if (d$1 > 57 || d$1 < 48) { + i.contents = i.contents - 1 | 0; + return i$1; + } + var i$p = Math.imul(10, i$1) + (d$1 - /* '0' */48 | 0) | 0; + if (i$p < i$1) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + _i = i$p; + continue ; + }; + } + }; var res = regexp$p(branch$p(/* [] */0)); if (i.contents !== l) { throw { From 6b01997847f655db585c49d03edf0a6bfa1e09f8 Mon Sep 17 00:00:00 2001 From: mununki Date: Wed, 13 Mar 2024 20:59:38 +0900 Subject: [PATCH 16/45] clean up Js_exp for bigint operations --- jscomp/core/js_exp_make.ml | 12 +----------- jscomp/core/js_exp_make.mli | 12 +----------- jscomp/core/lam_compile_primitive.ml | 14 +++++++------- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index 44d03a8852..17ca3b9f40 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -1260,17 +1260,7 @@ let rec int32_band ?comment (e1 : J.expression) (e2 : J.expression) : (* let int32_bin ?comment op e1 e2 : J.expression = *) (* {expression_desc = Int32_bin(op,e1, e2); comment} *) -let bigint_add ?comment (e1: t) (e2:t) = bin ?comment Plus e1 e2 - -let bigint_minus ?comment (e1: t) (e2: t) = bin ?comment Minus e1 e2 - -let bigint_mul ?comment (e1: t) (e2: t) = bin ?comment Mul e1 e2 - -let bigint_div ?comment (e1: t) (e2: t) = bin ?comment Div e1 e2 - -let bigint_mod ?comment (e1: t) (e2: t) = bin ?comment Mod e1 e2 - -let bigint_pow ?comment (e1: t) (e2: t) = bin ?comment Pow e1 e2 +let bigint_op ?comment op (e1: t) (e2: t) = bin ?comment op e1 e2 let bigint_comp (cmp : Lam_compat.comparison) ?comment (e0: t) (e1: t) = match (cmp, e0.expression_desc, e1.expression_desc) with diff --git a/jscomp/core/js_exp_make.mli b/jscomp/core/js_exp_make.mli index 1931542384..0c071f1dc8 100644 --- a/jscomp/core/js_exp_make.mli +++ b/jscomp/core/js_exp_make.mli @@ -276,17 +276,7 @@ val string_comp : Js_op.binop -> ?comment:string -> t -> t -> t val float_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t -val bigint_add : ?comment: string -> t -> t -> t - -val bigint_minus : ?comment: string -> t-> t -> t - -val bigint_mul : ?comment: string -> t -> t -> t - -val bigint_div : ?comment: string -> t -> t -> t - -val bigint_mod : ?comment: string -> t -> t -> t - -val bigint_pow : ?comment: string -> t -> t -> t +val bigint_op : ?comment: string -> Js_op.binop -> t -> t -> t val bigint_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t diff --git a/jscomp/core/lam_compile_primitive.ml b/jscomp/core/lam_compile_primitive.ml index 0c6fd55ab1..ca1b7d52fd 100644 --- a/jscomp/core/lam_compile_primitive.ml +++ b/jscomp/core/lam_compile_primitive.ml @@ -183,7 +183,7 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) E.int32_minus E.zero_int_literal (Ext_list.singleton_exn args) | Pnegint64 -> Js_long.neg args | Pnegfloat -> E.float_minus E.zero_float_lit (Ext_list.singleton_exn args) - | Pnegbigint -> E.bigint_minus E.zero_bigint_literal (Ext_list.singleton_exn args) + | Pnegbigint -> E.bigint_op Minus E.zero_bigint_literal (Ext_list.singleton_exn args) (* Negate boxed int end*) (* Int addition and subtraction *) | Paddint -> ( @@ -192,21 +192,21 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) | Paddfloat -> ( match args with [ e1; e2 ] -> E.float_add e1 e2 | _ -> assert false) | Paddbigint -> ( - match args with [ e1; e2 ] -> E.bigint_add e1 e2 | _ -> assert false) + match args with [ e1; e2 ] -> E.bigint_op Plus e1 e2 | _ -> assert false) | Psubint -> ( match args with [ e1; e2 ] -> E.int32_minus e1 e2 | _ -> assert false) | Psubint64 -> Js_long.sub args | Psubfloat -> ( match args with [ e1; e2 ] -> E.float_minus e1 e2 | _ -> assert false) | Psubbigint -> ( - match args with [ e1; e2 ] -> E.bigint_minus e1 e2 | _ -> assert false) + match args with [ e1; e2 ] -> E.bigint_op Minus e1 e2 | _ -> assert false) | Pmulint -> ( match args with [ e1; e2 ] -> E.int32_mul e1 e2 | _ -> assert false) | Pmulint64 -> Js_long.mul args | Pmulfloat -> ( match args with [ e1; e2 ] -> E.float_mul e1 e2 | _ -> assert false) | Pmulbigint -> ( - match args with [ e1; e2 ] -> E.bigint_mul e1 e2 | _ -> assert false) + match args with [ e1; e2 ] -> E.bigint_op Mul e1 e2 | _ -> assert false) | Pdivfloat -> ( match args with [ e1; e2 ] -> E.float_div e1 e2 | _ -> assert false) | Pdivint -> ( @@ -214,14 +214,14 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) | [ e1; e2 ] -> E.int32_div ~checked:!Js_config.check_div_by_zero e1 e2 | _ -> assert false) | Pdivint64 -> Js_long.div args - | Pdivbigint -> (match args with [ e1; e2 ] -> E.bigint_div e1 e2 | _ -> assert false) + | Pdivbigint -> (match args with [ e1; e2 ] -> E.bigint_op Div e1 e2 | _ -> assert false) | Pmodint -> ( match args with | [ e1; e2 ] -> E.int32_mod ~checked:!Js_config.check_div_by_zero e1 e2 | _ -> assert false) | Pmodint64 -> Js_long.mod_ args - | Pmodbigint -> (match args with [ e1; e2 ] -> E.bigint_mod e1 e2 | _ -> assert false) - | Ppowbigint -> (match args with [ e1; e2 ] -> E.bigint_pow e1 e2 | _ -> assert false) + | Pmodbigint -> (match args with [ e1; e2 ] -> E.bigint_op Mod e1 e2 | _ -> assert false) + | Ppowbigint -> (match args with [ e1; e2 ] -> E.bigint_op Pow e1 e2 | _ -> assert false) | Plslint -> ( match args with [ e1; e2 ] -> E.int32_lsl e1 e2 | _ -> assert false) | Plslint64 -> Js_long.lsl_ args From d386c4af38748b67f1decebad9f5d046e6003526 Mon Sep 17 00:00:00 2001 From: mununki Date: Sat, 16 Mar 2024 02:22:51 +0900 Subject: [PATCH 17/45] remove isNaN, isInfinite --- jscomp/others/js_bigint.res | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/jscomp/others/js_bigint.res b/jscomp/others/js_bigint.res index 857a7293ab..3ed8dd3d91 100644 --- a/jscomp/others/js_bigint.res +++ b/jscomp/others/js_bigint.res @@ -6,33 +6,6 @@ The special value "Not a Number". See [`NaN`](https://developer.mozilla.org/en-U */ external _NaN: bigint = "NaN" -@val -@scope("Number") -/** -Tests if the given value is `_NaN` - -Note that both `_NaN = _NaN` and `_NaN == _NaN` will return `false`. `isNaN` is -therefore necessary to test for `_NaN`. Return `true` if the given value is -`_NaN`, `false` otherwise. See [`isNaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) on MDN. -*/ -external isNaN: bigint => bool = "isNaN" - -/** -Tests if the given value is finite. Return `true` if the given value is a finite -number, `false` otherwise. See [`isFinite`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) on MDN. - -## Examples - -```rescript -/* returns [false] */ -Js.Bigint.isFinite(Js.Bigint._NaN) - -/* returns [true] */ -Js.Bigint.isFinite(1234.) -``` -*/ -external isFinite: bigint => bool = "isFinite" - @val /** Parses the given `string` into a `bigint` using JavaScript semantics. Return the From bc222616eefaa20cb9d5e863b23cfca2aabfa6e0 Mon Sep 17 00:00:00 2001 From: mununki Date: Sat, 16 Mar 2024 03:22:55 +0900 Subject: [PATCH 18/45] remove NaN from BigInt --- jscomp/others/js_bigint.res | 6 ------ 1 file changed, 6 deletions(-) diff --git a/jscomp/others/js_bigint.res b/jscomp/others/js_bigint.res index 3ed8dd3d91..e8cc4a7567 100644 --- a/jscomp/others/js_bigint.res +++ b/jscomp/others/js_bigint.res @@ -1,11 +1,5 @@ /*** JavaScript BigInt API */ -@val -/** -The special value "Not a Number". See [`NaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) on MDN. -*/ -external _NaN: bigint = "NaN" - @val /** Parses the given `string` into a `bigint` using JavaScript semantics. Return the From 3b34a01bc34f68e8a287874271d4a74d5ac4894c Mon Sep 17 00:00:00 2001 From: mununki Date: Sat, 16 Mar 2024 03:23:29 +0900 Subject: [PATCH 19/45] fix compare function --- jscomp/runtime/caml.res | 14 ++++---------- lib/es6/caml.js | 12 ++++-------- lib/js/caml.js | 12 ++++-------- 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/jscomp/runtime/caml.res b/jscomp/runtime/caml.res index 9a2b74bd85..15a70573b7 100644 --- a/jscomp/runtime/caml.res +++ b/jscomp/runtime/caml.res @@ -53,18 +53,12 @@ let float_compare = (x: float, y: float) => } let bigint_compare = (x: bigint, y: bigint) => - if x == y { - 0 - } else if x < y { - -1 - } else if x > y { - 1 - } else if x == x { - 1 - } else if y == y { + if x < y { -1 - } else { + } else if x == y { 0 + } else { + 1 } /* Lexical order */ diff --git a/lib/es6/caml.js b/lib/es6/caml.js index cc14694d24..1ed401152b 100644 --- a/lib/es6/caml.js +++ b/lib/es6/caml.js @@ -40,16 +40,12 @@ function float_compare(x, y) { } function bigint_compare(x, y) { - if (x === y) { - return 0; - } else if (x < y) { - return -1; - } else if (x > y || x === x) { - return 1; - } else if (y === y) { + if (x < y) { return -1; - } else { + } else if (x === y) { return 0; + } else { + return 1; } } diff --git a/lib/js/caml.js b/lib/js/caml.js index bfbcf46623..0675534391 100644 --- a/lib/js/caml.js +++ b/lib/js/caml.js @@ -40,16 +40,12 @@ function float_compare(x, y) { } function bigint_compare(x, y) { - if (x === y) { - return 0; - } else if (x < y) { - return -1; - } else if (x > y || x === x) { - return 1; - } else if (y === y) { + if (x < y) { return -1; - } else { + } else if (x === y) { return 0; + } else { + return 1; } } From d3032e1854801e983b55f8d8c9e0acda67373551 Mon Sep 17 00:00:00 2001 From: mununki Date: Sat, 16 Mar 2024 03:23:35 +0900 Subject: [PATCH 20/45] fix test --- jscomp/test/bigint_test.js | 85 +++++++------------------------------ jscomp/test/bigint_test.res | 58 +++++++------------------ jscomp/test/build.ninja | 2 +- 3 files changed, 33 insertions(+), 112 deletions(-) diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js index 6d7fb09feb..610d01ee7e 100644 --- a/jscomp/test/bigint_test.js +++ b/jscomp/test/bigint_test.js @@ -1,6 +1,7 @@ // Generated by ReScript, PLEASE EDIT WITH CARE 'use strict'; +var Mt = require("./mt.js"); var Caml = require("../../lib/js/caml.js"); var Caml_obj = require("../../lib/js/caml_obj.js"); var Mt_global = require("./mt_global.js"); @@ -65,89 +66,35 @@ function bigint_greaterequal(x, y) { var generic_greaterequal = Caml_obj.greaterequal; -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 21, characters 5-12", Caml.bigint_compare(NaN, NaN), 0); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 21, characters 5-12", Caml.bigint_compare(1n, 1n), 0); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 22, characters 5-12", Caml_obj.compare(NaN, NaN), 0); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 22, characters 5-12", Caml_obj.compare(1n, 1n), 0); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 23, characters 5-12", Caml.bigint_compare(NaN, -1n), -1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 23, characters 5-12", Caml.bigint_compare(-0n, -1n), 1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 24, characters 5-12", Caml_obj.compare(NaN, -1n), -1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 24, characters 5-12", Caml_obj.compare(-0n, -1n), 1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 25, characters 5-12", Caml.bigint_compare(-1n, NaN), 1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 25, characters 5-12", Caml.bigint_compare(0n, -1n), 1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 26, characters 5-12", Caml_obj.compare(-1n, NaN), 1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 26, characters 5-12", Caml_obj.compare(0n, -1n), 1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 27, characters 5-12", NaN === NaN, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 27, characters 5-12", Caml.bigint_compare(1n, 2n), -1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 28, characters 5-12", Caml_obj.equal(NaN, NaN), false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 28, characters 5-12", Caml_obj.compare(1n, 2n), -1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 29, characters 5-12", 1n === NaN, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 29, characters 5-12", true, true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 30, characters 5-12", Caml_obj.equal(1n, NaN), false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 30, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 31, characters 5-12", NaN === 1n, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 31, characters 5-12", false, false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 32, characters 5-12", Caml_obj.equal(NaN, 1n), false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 32, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 33, characters 5-12", NaN !== NaN, true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 33, characters 5-12", false, false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 34, characters 5-12", Caml_obj.notequal(NaN, NaN), true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 34, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 35, characters 5-12", 1n !== NaN, true); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 36, characters 5-12", Caml_obj.notequal(1n, NaN), true); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 37, characters 5-12", NaN !== 1n, true); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 38, characters 5-12", Caml_obj.notequal(NaN, 1n), true); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 39, characters 5-12", NaN < NaN, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 40, characters 5-12", Caml_obj.lessthan(NaN, NaN), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 41, characters 5-12", 1n < NaN, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 42, characters 5-12", Caml_obj.lessthan(1n, NaN), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 43, characters 5-12", NaN < 1n, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 44, characters 5-12", Caml_obj.lessthan(NaN, 1n), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 45, characters 5-12", NaN > NaN, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 46, characters 5-12", Caml_obj.greaterthan(NaN, NaN), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 47, characters 5-12", 1n > NaN, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 48, characters 5-12", Caml_obj.greaterthan(1n, NaN), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 49, characters 5-12", NaN > 1n, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 50, characters 5-12", Caml_obj.greaterthan(NaN, 1n), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 51, characters 5-12", NaN <= NaN, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 52, characters 5-12", Caml_obj.lessequal(NaN, NaN), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 53, characters 5-12", 1n <= NaN, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 54, characters 5-12", Caml_obj.lessequal(1n, NaN), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 55, characters 5-12", NaN <= 1n, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 56, characters 5-12", Caml_obj.lessequal(NaN, 1n), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 57, characters 5-12", NaN >= NaN, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 58, characters 5-12", Caml_obj.greaterequal(NaN, NaN), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 59, characters 5-12", 1n >= NaN, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 60, characters 5-12", Caml_obj.greaterequal(1n, NaN), false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 61, characters 5-12", NaN >= 1n, false); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 62, characters 5-12", Caml_obj.greaterequal(NaN, 1n), false); +Mt.from_pair_suites("Bigint_test", suites.contents); exports.test_id = test_id; exports.suites = suites; diff --git a/jscomp/test/bigint_test.res b/jscomp/test/bigint_test.res index 28890ffea8..3412882162 100644 --- a/jscomp/test/bigint_test.res +++ b/jscomp/test/bigint_test.res @@ -18,46 +18,20 @@ let bigint_greaterequal = (x: bigint, y) => x >= y let generic_greaterequal = \">=" let () = { - eq(__LOC__, bigint_compare(Js.Bigint._NaN, Js.Bigint._NaN), 0) - eq(__LOC__, generic_compare(Js.Bigint._NaN, Js.Bigint._NaN), 0) - eq(__LOC__, bigint_compare(Js.Bigint._NaN, -1n), -1) - eq(__LOC__, generic_compare(Js.Bigint._NaN, -1n), -1) - eq(__LOC__, bigint_compare(-1n, Js.Bigint._NaN), 1) - eq(__LOC__, generic_compare(-1n, Js.Bigint._NaN), 1) - eq(__LOC__, bigint_equal(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, generic_equal(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, bigint_equal(1n, Js.Bigint._NaN), false) - eq(__LOC__, generic_equal(1n, Js.Bigint._NaN), false) - eq(__LOC__, bigint_equal(Js.Bigint._NaN, 1n), false) - eq(__LOC__, generic_equal(Js.Bigint._NaN, 1n), false) - eq(__LOC__, bigint_notequal(Js.Bigint._NaN, Js.Bigint._NaN), true) - eq(__LOC__, generic_notequal(Js.Bigint._NaN, Js.Bigint._NaN), true) - eq(__LOC__, bigint_notequal(1n, Js.Bigint._NaN), true) - eq(__LOC__, generic_notequal(1n, Js.Bigint._NaN), true) - eq(__LOC__, bigint_notequal(Js.Bigint._NaN, 1n), true) - eq(__LOC__, generic_notequal(Js.Bigint._NaN, 1n), true) - eq(__LOC__, bigint_lessthan(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, generic_lessthan(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, bigint_lessthan(1n, Js.Bigint._NaN), false) - eq(__LOC__, generic_lessthan(1n, Js.Bigint._NaN), false) - eq(__LOC__, bigint_lessthan(Js.Bigint._NaN, 1n), false) - eq(__LOC__, generic_lessthan(Js.Bigint._NaN, 1n), false) - eq(__LOC__, bigint_greaterthan(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, generic_greaterthan(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, bigint_greaterthan(1n, Js.Bigint._NaN), false) - eq(__LOC__, generic_greaterthan(1n, Js.Bigint._NaN), false) - eq(__LOC__, bigint_greaterthan(Js.Bigint._NaN, 1n), false) - eq(__LOC__, generic_greaterthan(Js.Bigint._NaN, 1n), false) - eq(__LOC__, bigint_lessequal(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, generic_lessequal(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, bigint_lessequal(1n, Js.Bigint._NaN), false) - eq(__LOC__, generic_lessequal(1n, Js.Bigint._NaN), false) - eq(__LOC__, bigint_lessequal(Js.Bigint._NaN, 1n), false) - eq(__LOC__, generic_lessequal(Js.Bigint._NaN, 1n), false) - eq(__LOC__, bigint_greaterequal(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, generic_greaterequal(Js.Bigint._NaN, Js.Bigint._NaN), false) - eq(__LOC__, bigint_greaterequal(1n, Js.Bigint._NaN), false) - eq(__LOC__, generic_greaterequal(1n, Js.Bigint._NaN), false) - eq(__LOC__, bigint_greaterequal(Js.Bigint._NaN, 1n), false) - eq(__LOC__, generic_greaterequal(Js.Bigint._NaN, 1n), false) + eq(__LOC__, bigint_compare(1n, 1n), 0) + eq(__LOC__, generic_compare(1n, 1n), 0) + eq(__LOC__, bigint_compare(-0n, -1n), 1) + eq(__LOC__, generic_compare(-0n, -1n), 1) + eq(__LOC__, bigint_compare(+0n, -1n), 1) + eq(__LOC__, generic_compare(+0n, -1n), 1) + eq(__LOC__, bigint_compare(1n, 2n), -1) + eq(__LOC__, generic_compare(1n, 2n), -1) + eq(__LOC__, bigint_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true) + eq(__LOC__, generic_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true) + eq(__LOC__, bigint_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false) + eq(__LOC__, generic_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false) + eq(__LOC__, bigint_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false) + eq(__LOC__, generic_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false) } + +let () = Mt.from_pair_suites(__MODULE__, suites.contents) diff --git a/jscomp/test/build.ninja b/jscomp/test/build.ninja index aee68d4480..7c8864c2d6 100644 --- a/jscomp/test/build.ninja +++ b/jscomp/test/build.ninja @@ -85,7 +85,7 @@ o test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj : cc test/belt o test/bench.cmi test/bench.cmj : cc test/bench.res | $bsc $stdlib runtime o test/big_enum.cmi test/big_enum.cmj : cc test/big_enum.res | $bsc $stdlib runtime o test/big_polyvar_test.cmi test/big_polyvar_test.cmj : cc test/big_polyvar_test.res | $bsc $stdlib runtime -o test/bigint_test.cmi test/bigint_test.cmj : cc test/bigint_test.res | test/mt_global.cmj $bsc $stdlib runtime +o test/bigint_test.cmi test/bigint_test.cmj : cc test/bigint_test.res | test/mt.cmj test/mt_global.cmj $bsc $stdlib runtime o test/block_alias_test.cmi test/block_alias_test.cmj : cc test/block_alias_test.res | test/mt.cmj $bsc $stdlib runtime o test/boolean_test.cmi test/boolean_test.cmj : cc test/boolean_test.res | test/mt.cmj test/test_bool_equal.cmj $bsc $stdlib runtime o test/bs_MapInt_test.cmi test/bs_MapInt_test.cmj : cc test/bs_MapInt_test.res | $bsc $stdlib runtime From d3090ff60bb9519a0c6e7d2de4a9b04e9c9375eb Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 18 Mar 2024 21:39:31 +0900 Subject: [PATCH 21/45] add bitwise operations --- jscomp/core/lam_analysis.ml | 4 +- jscomp/core/lam_compile_primitive.ml | 10 + jscomp/core/lam_convert.ml | 5 + jscomp/core/lam_primitive.ml | 10 + jscomp/core/lam_primitive.mli | 5 + jscomp/core/lam_print.ml | 5 + jscomp/ml/lambda.ml | 2 + jscomp/ml/lambda.mli | 2 + jscomp/ml/printlambda.ml | 10 + jscomp/ml/translcore.ml | 5 + jscomp/stdlib-406/pervasives.res | 9 + jscomp/stdlib-406/pervasives.resi | 27 ++ jscomp/stdlib-406/pervasivesU.res | 9 + jscomp/stdlib-406/pervasivesU.resi | 27 ++ jscomp/test/ocaml_re_test.js | 439 +++++++++++++++++++++++++++ jscomp/test/test_per.js | 5 + jscomp/test/test_per.res | 9 + jscomp/test/test_pervasive.js | 1 + jscomp/test/test_pervasives2.js | 2 + jscomp/test/test_pervasives3.js | 1 + lib/es6/pervasives.js | 5 + lib/es6/pervasivesU.js | 5 + lib/js/pervasives.js | 5 + lib/js/pervasivesU.js | 5 + 24 files changed, 606 insertions(+), 1 deletion(-) diff --git a/jscomp/core/lam_analysis.ml b/jscomp/core/lam_analysis.ml index cc65845a4b..9a521897c3 100644 --- a/jscomp/core/lam_analysis.ml +++ b/jscomp/core/lam_analysis.ml @@ -76,8 +76,10 @@ let rec no_side_effects (lam : Lam.t) : bool = (* Float operations *) | Pintoffloat | Pfloatofint | Pnegfloat (* | Pabsfloat *) - | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pbigintcomp _ | Pjscomp _ + | Paddfloat | Psubfloat | Pmulfloat | Pdivfloat | Pfloatcomp _ | Pjscomp _ | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Ppowbigint + | Pandbigint | Porbigint | Pxorbigint | Plslbigint | Pasrbigint + | Pbigintcomp _ (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs | Pbyteslength | Pbytesrefu | Pbytesrefs | Pmakearray | Parraylength | Parrayrefu | Parrayrefs diff --git a/jscomp/core/lam_compile_primitive.ml b/jscomp/core/lam_compile_primitive.ml index ca1b7d52fd..e7752b8fa9 100644 --- a/jscomp/core/lam_compile_primitive.ml +++ b/jscomp/core/lam_compile_primitive.ml @@ -225,6 +225,8 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) | Plslint -> ( match args with [ e1; e2 ] -> E.int32_lsl e1 e2 | _ -> assert false) | Plslint64 -> Js_long.lsl_ args + | Plslbigint -> ( + match args with [ e1; e2 ] -> E.bigint_op Lsl e1 e2 | _ -> assert false) | Plsrint -> ( match args with | [ e1; { J.expression_desc = Number (Int { i = 0l; _ } | Uint 0l); _ } ] @@ -236,15 +238,23 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) | Pasrint -> ( match args with [ e1; e2 ] -> E.int32_asr e1 e2 | _ -> assert false) | Pasrint64 -> Js_long.asr_ args + | Pasrbigint -> ( + match args with [ e1; e2 ] -> E.bigint_op Asr e1 e2 | _ -> assert false) | Pandint -> ( match args with [ e1; e2 ] -> E.int32_band e1 e2 | _ -> assert false) | Pandint64 -> Js_long.and_ args + | Pandbigint -> ( + match args with [ e1; e2 ] -> E.bigint_op Band e1 e2 | _ -> assert false) | Porint -> ( match args with [ e1; e2 ] -> E.int32_bor e1 e2 | _ -> assert false) | Porint64 -> Js_long.or_ args + | Porbigint -> ( + match args with [ e1; e2 ] -> E.bigint_op Bor e1 e2 | _ -> assert false) | Pxorint -> ( match args with [ e1; e2 ] -> E.int32_bxor e1 e2 | _ -> assert false) | Pxorint64 -> Js_long.xor args + | Pxorbigint -> ( + match args with [ e1; e2 ] -> E.bigint_op Bxor e1 e2 | _ -> assert false) | Pjscomp cmp -> ( match args with [ l; r ] -> E.js_comp cmp l r | _ -> assert false) | Pfloatcomp cmp | Pintcomp cmp -> ( diff --git a/jscomp/core/lam_convert.ml b/jscomp/core/lam_convert.ml index 0b2564166c..41caa4f7ae 100644 --- a/jscomp/core/lam_convert.ml +++ b/jscomp/core/lam_convert.ml @@ -261,6 +261,11 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t = | Pdivbigint _is_safe (*FIXME*) -> prim ~primitive:Pdivbigint ~args loc | Pmodbigint _is_safe (*FIXME*) -> prim ~primitive:Pmodbigint ~args loc | Ppowbigint -> prim ~primitive:Ppowbigint ~args loc + | Pandbigint -> prim ~primitive:Pandbigint ~args loc + | Porbigint -> prim ~primitive:Porbigint ~args loc + | Pxorbigint -> prim ~primitive:Pxorbigint ~args loc + | Plslbigint -> prim ~primitive:Plslbigint ~args loc + | Pasrbigint -> prim ~primitive:Pasrbigint ~args loc | Pbigintcomp x -> prim ~primitive:(Pbigintcomp x) ~args loc | Pintcomp x -> prim ~primitive:(Pintcomp x) ~args loc | Poffsetint x -> prim ~primitive:(Poffsetint x) ~args loc diff --git a/jscomp/core/lam_primitive.ml b/jscomp/core/lam_primitive.ml index 0acfbb2022..1ccc636de1 100644 --- a/jscomp/core/lam_primitive.ml +++ b/jscomp/core/lam_primitive.ml @@ -88,6 +88,11 @@ type t = | Pdivbigint | Pmodbigint | Ppowbigint + | Pandbigint + | Porbigint + | Pxorbigint + | Plslbigint + | Pasrbigint | Pintcomp of Lam_compat.comparison | Pfloatcomp of Lam_compat.comparison | Pjscomp of Lam_compat.comparison @@ -217,6 +222,11 @@ let eq_primitive_approx (lhs : t) (rhs : t) = | Pdivbigint -> rhs = Pdivbigint | Pmodbigint -> rhs = Pmodbigint | Ppowbigint -> rhs = Ppowbigint + | Pandbigint -> rhs = Pandbigint + | Porbigint -> rhs = Porbigint + | Pxorbigint -> rhs = Pxorbigint + | Plslbigint -> rhs = Plslbigint + | Pasrbigint -> rhs = Pasrbigint | Pjs_apply -> rhs = Pjs_apply | Pjs_runtime_apply -> rhs = Pjs_runtime_apply | Pstringlength -> rhs = Pstringlength diff --git a/jscomp/core/lam_primitive.mli b/jscomp/core/lam_primitive.mli index 8a2d2ab31b..31ba475096 100644 --- a/jscomp/core/lam_primitive.mli +++ b/jscomp/core/lam_primitive.mli @@ -78,6 +78,11 @@ type t = | Pdivbigint | Pmodbigint | Ppowbigint + | Pandbigint + | Porbigint + | Pxorbigint + | Plslbigint + | Pasrbigint | Pintcomp of Lam_compat.comparison | Pfloatcomp of Lam_compat.comparison | Pjscomp of Lam_compat.comparison diff --git a/jscomp/core/lam_print.ml b/jscomp/core/lam_print.ml index cf02060472..7ecd43171e 100644 --- a/jscomp/core/lam_print.ml +++ b/jscomp/core/lam_print.ml @@ -141,6 +141,11 @@ let primitive ppf (prim : Lam_primitive.t) = | Pdivbigint -> fprintf ppf "/," | Pmodbigint -> fprintf ppf "modn" | Ppowbigint -> fprintf ppf "**," + | Pandbigint -> fprintf ppf "and," + | Porbigint -> fprintf ppf "or," + | Pxorbigint -> fprintf ppf "xor," + | Plslbigint -> fprintf ppf "lsl," + | Pasrbigint -> fprintf ppf "asr," | Pbigintcomp Ceq -> fprintf ppf "==," | Pbigintcomp Cneq -> fprintf ppf "!=," | Pbigintcomp Clt -> fprintf ppf "<," diff --git a/jscomp/ml/lambda.ml b/jscomp/ml/lambda.ml index e0319ec4f9..0a9810e572 100644 --- a/jscomp/ml/lambda.ml +++ b/jscomp/ml/lambda.ml @@ -232,6 +232,8 @@ type primitive = (* Bigint operations *) | Pnegbigint | Paddbigint | Psubbigint | Ppowbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe + | Pandbigint | Porbigint | Pxorbigint + | Plslbigint | Pasrbigint | Pbigintcomp of comparison (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs diff --git a/jscomp/ml/lambda.mli b/jscomp/ml/lambda.mli index 2848c0f3f6..4fce136ac2 100644 --- a/jscomp/ml/lambda.mli +++ b/jscomp/ml/lambda.mli @@ -198,6 +198,8 @@ type primitive = (* Bigint operations *) | Pnegbigint | Paddbigint | Psubbigint | Ppowbigint | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe + | Pandbigint | Porbigint | Pxorbigint + | Plslbigint | Pasrbigint | Pbigintcomp of comparison (* String operations *) | Pstringlength | Pstringrefu | Pstringrefs diff --git a/jscomp/ml/printlambda.ml b/jscomp/ml/printlambda.ml index 6014ea65d6..e337bdc3c8 100644 --- a/jscomp/ml/printlambda.ml +++ b/jscomp/ml/printlambda.ml @@ -182,6 +182,11 @@ let primitive ppf = function | Psubbigint -> fprintf ppf "-," | Pmulbigint -> fprintf ppf "*," | Ppowbigint -> fprintf ppf "**," + | Pandbigint -> fprintf ppf "and," + | Porbigint -> fprintf ppf "or," + | Pxorbigint -> fprintf ppf "xor," + | Plslbigint -> fprintf ppf "lsl," + | Pasrbigint -> fprintf ppf "asr," | Pdivbigint Safe -> fprintf ppf "/n" | Pdivbigint Unsafe -> fprintf ppf "/nu" | Pmodbigint Safe -> fprintf ppf "mod" @@ -300,6 +305,11 @@ let name_of_primitive = function | Pdivbigint _ -> "Pdivbigint" | Pmodbigint _ -> "Pmodbigint" | Ppowbigint -> "Ppowbigint" + | Pandbigint -> "Pandbigint" + | Porbigint -> "Porbigint" + | Pxorbigint -> "Pxorbigint" + | Plslbigint -> "Plslbigint" + | Pasrbigint -> "Pasrbigint" | Pbigintcomp _ -> "Pbigintcomp" | Pstringlength -> "Pstringlength" | Pstringrefu -> "Pstringrefu" diff --git a/jscomp/ml/translcore.ml b/jscomp/ml/translcore.ml index 01ea01fc31..8c09dba446 100644 --- a/jscomp/ml/translcore.ml +++ b/jscomp/ml/translcore.ml @@ -345,6 +345,11 @@ let primitives_table = ("%lslint", Plslint); ("%lsrint", Plsrint); ("%asrint", Pasrint); + ("%andbigint", Pandbigint); + ("%orbigint", Porbigint); + ("%xorbigint", Pxorbigint); + ("%lslbigint", Plslbigint); + ("%asrbigint", Pasrbigint); ("%eq", Pintcomp Ceq); ("%noteq", Pintcomp Cneq); ("%ltint", Pintcomp Clt); diff --git a/jscomp/stdlib-406/pervasives.res b/jscomp/stdlib-406/pervasives.res index 027cddc1bd..143507f37d 100644 --- a/jscomp/stdlib-406/pervasives.res +++ b/jscomp/stdlib-406/pervasives.res @@ -190,6 +190,15 @@ external \"/,": (bigint, bigint) => bigint = "%divbigint" external modn: (bigint, bigint) => bigint = "%modbigint" external \"**,": (bigint, bigint) => bigint = "%powbigint" +external landn: (bigint, bigint) => bigint = "%andbigint" +external lorn: (bigint, bigint) => bigint = "%orbigint" +external lxorn: (bigint, bigint) => bigint = "%xorbigint" + +let lnotn = x => lxorn(x, -1n) + +external lsln: (bigint, bigint) => bigint = "%lslbigint" +external asrn: (bigint, bigint) => bigint = "%asrbigint" + /* String and byte sequence operations -- more in modules String and Bytes */ external string_length: string => int = "%string_length" diff --git a/jscomp/stdlib-406/pervasives.resi b/jscomp/stdlib-406/pervasives.resi index 42db582871..52a50087d9 100644 --- a/jscomp/stdlib-406/pervasives.resi +++ b/jscomp/stdlib-406/pervasives.resi @@ -568,6 +568,33 @@ external modn: (bigint, bigint) => bigint = "%modbigint" Left-associative operator at precedence level 7/9. */ external \"**,": (bigint, bigint) => bigint = "%powbigint" +/** Bigint Bitwise logical and. + Left-associative operator at precedence level 7/11. */ +external landn: (bigint, bigint) => bigint = "%andbigint" + +/** Bigint Bitwise logical or. + Left-associative operator at precedence level 7/11. */ +external lorn: (bigint, bigint) => bigint = "%orbigint" + +/** Bigint Bitwise logical exclusive or. + Left-associative operator at precedence level 7/11. */ +external lxorn: (bigint, bigint) => bigint = "%xorbigint" + +/** Bigint Bitwise logical negation. */ +let lnotn: bigint => bigint + +/** [n lsln m] shifts [n] to the left by [m] bits. + The result is unspecified if [m < 0n] or [m >= bitsize], + where the both operands are bigints. + Right-associative operator at precedence level 8/11. */ +external lsln: (bigint, bigint) => bigint = "%lslbigint" + +/** [n asrn m] shifts [n] to the right by [m] bits. + This is an arithmetic shift: the sign bit of [n] is replicated. + The result is unspecified if [m < 0n] or [m >= bitsize]. + Right-associative operator at precedence level 8/11. */ +external asrn: (bigint, bigint) => bigint = "%asrbigint" + @val @scope("Number") /** A special floating-point value denoting the result of an diff --git a/jscomp/stdlib-406/pervasivesU.res b/jscomp/stdlib-406/pervasivesU.res index 76889ce38b..bd6a1badba 100644 --- a/jscomp/stdlib-406/pervasivesU.res +++ b/jscomp/stdlib-406/pervasivesU.res @@ -191,6 +191,15 @@ external \"/,": (bigint, bigint) => bigint = "%divbigint" external modn: (bigint, bigint) => bigint = "%modbigint" external \"**,": (bigint, bigint) => bigint = "%powbigint" +external landn: (bigint, bigint) => bigint = "%andbigint" +external lorn: (bigint, bigint) => bigint = "%orbigint" +external lxorn: (bigint, bigint) => bigint = "%xorbigint" + +let lnotn = x => lxorn(x, -1n) + +external lsln: (bigint, bigint) => bigint = "%lslbigint" +external asrn: (bigint, bigint) => bigint = "%asrbigint" + /* String and byte sequence operations -- more in modules String and Bytes */ external string_length: string => int = "%string_length" diff --git a/jscomp/stdlib-406/pervasivesU.resi b/jscomp/stdlib-406/pervasivesU.resi index e5132d7f16..d6d4dc6456 100644 --- a/jscomp/stdlib-406/pervasivesU.resi +++ b/jscomp/stdlib-406/pervasivesU.resi @@ -571,6 +571,33 @@ external modn: (bigint, bigint) => bigint = "%modbigint" Left-associative operator at precedence level 7/9. */ external \"**,": (bigint, bigint) => bigint = "%powbigint" +/** Bigint Bitwise logical and. + Left-associative operator at precedence level 7/11. */ +external landn: (bigint, bigint) => bigint = "%andbigint" + +/** Bigint Bitwise logical or. + Left-associative operator at precedence level 7/11. */ +external lorn: (bigint, bigint) => bigint = "%orbigint" + +/** Bigint Bitwise logical exclusive or. + Left-associative operator at precedence level 7/11. */ +external lxorn: (bigint, bigint) => bigint = "%xorbigint" + +/** Bigint Bitwise logical negation. */ +let lnotn: bigint => bigint + +/** [n lsln m] shifts [n] to the left by [m] bits. + The result is unspecified if [m < 0n] or [m >= bitsize], + where the both operands are bigints. + Right-associative operator at precedence level 8/11. */ +external lsln: (bigint, bigint) => bigint = "%lslbigint" + +/** [n asrn m] shifts [n] to the right by [m] bits. + This is an arithmetic shift: the sign bit of [n] is replicated. + The result is unspecified if [m < 0n] or [m >= bitsize]. + Right-associative operator at precedence level 8/11. */ +external asrn: (bigint, bigint) => bigint = "%asrbigint" + @val @scope("Number") /** A special floating-point value denoting the result of an diff --git a/jscomp/test/ocaml_re_test.js b/jscomp/test/ocaml_re_test.js index 19d1e1e186..098a77d7e8 100644 --- a/jscomp/test/ocaml_re_test.js +++ b/jscomp/test/ocaml_re_test.js @@ -4533,6 +4533,445 @@ function parse(multiline, dollar_endonly, dotall, ungreedy, s) { }; } }; + var branch$p = function (_left) { + while(true) { + var left = _left; + if (i.contents === l || test(/* '|' */124) || test(/* ')' */41)) { + return seq$2(List.rev(left)); + } + _left = { + hd: piece(), + tl: left + }; + continue ; + }; + }; + var regexp$p = function (_left) { + while(true) { + var left = _left; + if (!accept(/* '|' */124)) { + return left; + } + _left = alt$1({ + hd: left, + tl: { + hd: branch$p(/* [] */0), + tl: /* [] */0 + } + }); + continue ; + }; + }; + var piece = function (param) { + var r = atom(); + if (accept(/* '*' */42)) { + return greedy_mod(repn(r, 0, undefined)); + } + if (accept(/* '+' */43)) { + return greedy_mod(repn(r, 1, undefined)); + } + if (accept(/* '?' */63)) { + return greedy_mod(repn(r, 0, 1)); + } + if (!accept(/* '{' */123)) { + return r; + } + var i$1 = integer(); + if (i$1 !== undefined) { + var j = accept(/* ',' */44) ? integer() : i$1; + if (!accept(/* '}' */125)) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + if (j !== undefined && j < i$1) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + return greedy_mod(repn(r, i$1, j)); + } + i.contents = i.contents - 1 | 0; + return r; + }; + var bracket = function (_s) { + while(true) { + var s = _s; + if (s !== /* [] */0 && accept(/* ']' */93)) { + return s; + } + var match = $$char(); + if (match.NAME === "Char") { + var c = match.VAL; + if (accept(/* '-' */45)) { + if (accept(/* ']' */93)) { + return { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '-' */45, + /* '-' */45 + ], + tl: /* [] */0 + } + }, + tl: s + } + }; + } + var match$1 = $$char(); + if (match$1.NAME !== "Char") { + return { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '-' */45, + /* '-' */45 + ], + tl: /* [] */0 + } + }, + tl: { + hd: match$1.VAL, + tl: s + } + } + }; + } + _s = { + hd: { + TAG: "Set", + _0: seq(c, match$1.VAL) + }, + tl: s + }; + continue ; + } + _s = { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: s + }; + continue ; + } + _s = { + hd: match.VAL, + tl: s + }; + continue ; + }; + }; + var $$char = function (param) { + if (i.contents === l) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + var c = get(); + if (c === /* '[' */91) { + if (accept(/* '=' */61)) { + throw { + RE_EXN_ID: Not_supported, + Error: new Error() + }; + } + if (accept(/* ':' */58)) { + var compl$1 = accept(/* '^' */94); + var cls; + try { + cls = List.find(accept_s, { + hd: "alnum", + tl: { + hd: "ascii", + tl: { + hd: "blank", + tl: { + hd: "cntrl", + tl: { + hd: "digit", + tl: { + hd: "lower", + tl: { + hd: "print", + tl: { + hd: "space", + tl: { + hd: "upper", + tl: { + hd: "word", + tl: { + hd: "punct", + tl: { + hd: "graph", + tl: { + hd: "xdigit", + tl: /* [] */0 + } + } + } + } + } + } + } + } + } + } + } + } + }); + } + catch (raw_exn){ + var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); + if (exn.RE_EXN_ID === "Not_found") { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + throw exn; + } + if (!accept_s(":]")) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + var posix_class = posix_class_of_string(cls); + var re = compl$1 ? compl({ + hd: posix_class, + tl: /* [] */0 + }) : posix_class; + return { + NAME: "Set", + VAL: re + }; + } + if (!accept(/* '.' */46)) { + return { + NAME: "Char", + VAL: c + }; + } + if (i.contents === l) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + var c$1 = get(); + if (!accept(/* '.' */46)) { + throw { + RE_EXN_ID: Not_supported, + Error: new Error() + }; + } + if (!accept(/* ']' */93)) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + return { + NAME: "Char", + VAL: c$1 + }; + } + if (c !== /* '\\' */92) { + return { + NAME: "Char", + VAL: c + }; + } + var c$2 = get(); + if (c$2 >= 58) { + if (c$2 >= 123) { + return { + NAME: "Char", + VAL: c$2 + }; + } + switch (c$2) { + case 68 : + return { + NAME: "Set", + VAL: compl({ + hd: digit, + tl: /* [] */0 + }) + }; + case 83 : + return { + NAME: "Set", + VAL: compl({ + hd: space, + tl: /* [] */0 + }) + }; + case 87 : + return { + NAME: "Set", + VAL: compl({ + hd: alnum, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '_' */95, + /* '_' */95 + ], + tl: /* [] */0 + } + }, + tl: /* [] */0 + } + }) + }; + case 58 : + case 59 : + case 60 : + case 61 : + case 62 : + case 63 : + case 64 : + case 91 : + case 92 : + case 93 : + case 94 : + case 95 : + case 96 : + return { + NAME: "Char", + VAL: c$2 + }; + case 98 : + return { + NAME: "Char", + VAL: /* '\b' */8 + }; + case 100 : + return { + NAME: "Set", + VAL: digit + }; + case 110 : + return { + NAME: "Char", + VAL: /* '\n' */10 + }; + case 114 : + return { + NAME: "Char", + VAL: /* '\r' */13 + }; + case 115 : + return { + NAME: "Set", + VAL: space + }; + case 116 : + return { + NAME: "Char", + VAL: /* '\t' */9 + }; + case 119 : + return { + NAME: "Set", + VAL: alt$1({ + hd: alnum, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '_' */95, + /* '_' */95 + ], + tl: /* [] */0 + } + }, + tl: /* [] */0 + } + }) + }; + case 65 : + case 66 : + case 67 : + case 69 : + case 70 : + case 71 : + case 72 : + case 73 : + case 74 : + case 75 : + case 76 : + case 77 : + case 78 : + case 79 : + case 80 : + case 81 : + case 82 : + case 84 : + case 85 : + case 86 : + case 88 : + case 89 : + case 90 : + case 97 : + case 99 : + case 101 : + case 102 : + case 103 : + case 104 : + case 105 : + case 106 : + case 107 : + case 108 : + case 109 : + case 111 : + case 112 : + case 113 : + case 117 : + case 118 : + case 120 : + case 121 : + case 122 : + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + + } + } else { + if (c$2 >= 48) { + throw { + RE_EXN_ID: Not_supported, + Error: new Error() + }; + } + return { + NAME: "Char", + VAL: c$2 + }; + } + }; var res = regexp$p(branch$p(/* [] */0)); if (i.contents !== l) { throw { diff --git a/jscomp/test/test_per.js b/jscomp/test/test_per.js index 27edfb87f7..a053488828 100644 --- a/jscomp/test/test_per.js +++ b/jscomp/test/test_per.js @@ -94,6 +94,10 @@ var epsilon_float = Caml_int64.float_of_bits([ 0 ]); +function lnotn(x) { + return x ^ -1n; +} + function $caret(s1, s2) { var l1 = s1.length; var l2 = s2.length; @@ -466,6 +470,7 @@ exports.nan = nan; exports.max_float = max_float; exports.min_float = min_float; exports.epsilon_float = epsilon_float; +exports.lnotn = lnotn; exports.$caret = $caret; exports.char_of_int = char_of_int; exports.string_of_bool = string_of_bool; diff --git a/jscomp/test/test_per.res b/jscomp/test/test_per.res index c44e61d0dc..289b0059e3 100644 --- a/jscomp/test/test_per.res +++ b/jscomp/test/test_per.res @@ -175,6 +175,15 @@ external \"*,": (bigint, bigint) => bigint = "%mulbigint" external \"/,": (bigint, bigint) => bigint = "%divbigint" external modn: (bigint, bigint) => bigint = "%modbigint" +external landn: (bigint, bigint) => bigint = "%andbigint" +external lorn: (bigint, bigint) => bigint = "%orbigint" +external lxorn: (bigint, bigint) => bigint = "%xorbigint" + +let lnotn = x => lxorn(x, -1n) + +external lsln: (bigint, bigint) => bigint = "%lslbigint" +external asrn: (bigint, bigint) => bigint = "%asrbigint" + /* String and byte sequence operations -- more in modules String and Bytes */ external string_length: string => int = "%string_length" diff --git a/jscomp/test/test_pervasive.js b/jscomp/test/test_pervasive.js index 128440f3db..6587feab94 100644 --- a/jscomp/test/test_pervasive.js +++ b/jscomp/test/test_pervasive.js @@ -71,6 +71,7 @@ var Pervasives$1 = { lnot: Pervasives.lnot, infinity: Pervasives.infinity, neg_infinity: Pervasives.neg_infinity, + lnotn: Pervasives.lnotn, max_float: Pervasives.max_float, min_float: Pervasives.min_float, epsilon_float: Pervasives.epsilon_float, diff --git a/jscomp/test/test_pervasives2.js b/jscomp/test/test_pervasives2.js index f12c45a171..3cd8629835 100644 --- a/jscomp/test/test_pervasives2.js +++ b/jscomp/test/test_pervasives2.js @@ -72,6 +72,7 @@ var List$1 = { lnot: Pervasives.lnot, infinity: Pervasives.infinity, neg_infinity: Pervasives.neg_infinity, + lnotn: Pervasives.lnotn, max_float: Pervasives.max_float, min_float: Pervasives.min_float, epsilon_float: Pervasives.epsilon_float, @@ -120,6 +121,7 @@ var U = { lnot: Pervasives.lnot, infinity: Pervasives.infinity, neg_infinity: Pervasives.neg_infinity, + lnotn: Pervasives.lnotn, max_float: Pervasives.max_float, min_float: Pervasives.min_float, epsilon_float: Pervasives.epsilon_float, diff --git a/jscomp/test/test_pervasives3.js b/jscomp/test/test_pervasives3.js index c85f0668ad..cd12bb69d0 100644 --- a/jscomp/test/test_pervasives3.js +++ b/jscomp/test/test_pervasives3.js @@ -19,6 +19,7 @@ var Pervasives$1 = { lnot: Pervasives.lnot, infinity: Pervasives.infinity, neg_infinity: Pervasives.neg_infinity, + lnotn: Pervasives.lnotn, max_float: Pervasives.max_float, min_float: Pervasives.min_float, epsilon_float: Pervasives.epsilon_float, diff --git a/lib/es6/pervasives.js b/lib/es6/pervasives.js index 8d9f304b4f..2391612faf 100644 --- a/lib/es6/pervasives.js +++ b/lib/es6/pervasives.js @@ -61,6 +61,10 @@ function classify_float(x) { } } +function lnotn(x) { + return x ^ -1n; +} + function char_of_int(n) { if (n < 0 || n > 255) { throw { @@ -245,6 +249,7 @@ export { lnot , infinity , neg_infinity , + lnotn , max_float , min_float , epsilon_float , diff --git a/lib/es6/pervasivesU.js b/lib/es6/pervasivesU.js index 66770b5ddb..1a3cd4d4c8 100644 --- a/lib/es6/pervasivesU.js +++ b/lib/es6/pervasivesU.js @@ -60,6 +60,10 @@ function classify_float(x) { } } +function lnotn(x) { + return x ^ -1n; +} + function char_of_int(n) { if (n < 0 || n > 255) { throw { @@ -244,6 +248,7 @@ export { lnot , infinity , neg_infinity , + lnotn , max_float , min_float , epsilon_float , diff --git a/lib/js/pervasives.js b/lib/js/pervasives.js index efcf4fb70d..6fcc1ac898 100644 --- a/lib/js/pervasives.js +++ b/lib/js/pervasives.js @@ -61,6 +61,10 @@ function classify_float(x) { } } +function lnotn(x) { + return x ^ -1n; +} + function char_of_int(n) { if (n < 0 || n > 255) { throw { @@ -244,6 +248,7 @@ exports.min_int = min_int; exports.lnot = lnot; exports.infinity = infinity; exports.neg_infinity = neg_infinity; +exports.lnotn = lnotn; exports.max_float = max_float; exports.min_float = min_float; exports.epsilon_float = epsilon_float; diff --git a/lib/js/pervasivesU.js b/lib/js/pervasivesU.js index 31c6560d8a..766d39ff35 100644 --- a/lib/js/pervasivesU.js +++ b/lib/js/pervasivesU.js @@ -60,6 +60,10 @@ function classify_float(x) { } } +function lnotn(x) { + return x ^ -1n; +} + function char_of_int(n) { if (n < 0 || n > 255) { throw { @@ -243,6 +247,7 @@ exports.min_int = min_int; exports.lnot = lnot; exports.infinity = infinity; exports.neg_infinity = neg_infinity; +exports.lnotn = lnotn; exports.max_float = max_float; exports.min_float = min_float; exports.epsilon_float = epsilon_float; From 5683ca2174c8a5244913b69d1e54020034b90426 Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 18 Mar 2024 21:40:10 +0900 Subject: [PATCH 22/45] eta conversion for bigint --- jscomp/core/lam_eta_conversion.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jscomp/core/lam_eta_conversion.ml b/jscomp/core/lam_eta_conversion.ml index a92639f1f2..6ae495e7f8 100644 --- a/jscomp/core/lam_eta_conversion.ml +++ b/jscomp/core/lam_eta_conversion.ml @@ -42,7 +42,7 @@ let transform_under_supply n ap_info fn args = match lam with | Lvar _ | Lconst - ( Const_int _ | Const_char _ | Const_string _ | Const_float _ + ( Const_int _ | Const_char _ | Const_string _ | Const_float _ | Const_bigint _ | Const_int64 _ | Const_pointer _ | Const_js_true | Const_js_false | Const_js_undefined _ ) | Lprim { primitive = Pfield (_, Fld_module _); _ } From da60074da68b1e3a93034cd3a19f246c851b110e Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 18 Mar 2024 22:14:54 +0900 Subject: [PATCH 23/45] optimization --- jscomp/core/lam.ml | 3 +++ jscomp/core/lam_compat.ml | 9 +++++++++ jscomp/core/lam_compat.mli | 2 ++ jscomp/core/lam_pass_lets_dce.ml | 2 +- jscomp/ml/matching.ml | 2 +- jscomp/ml/parmatch.ml | 2 ++ jscomp/test/VariantCoercion.js | 22 ++++++++-------------- 7 files changed, 26 insertions(+), 16 deletions(-) diff --git a/jscomp/core/lam.ml b/jscomp/core/lam.ml index 4f038257a8..06c28db4ea 100644 --- a/jscomp/core/lam.ml +++ b/jscomp/core/lam.ml @@ -506,6 +506,9 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t = (* FIXME: could raise? *) Lift.bool (Lam_compat.cmp_float cmp (float_of_string a) (float_of_string b)) + | Pbigintcomp cmp, Const_bigint a, Const_bigint b -> + Lift.bool + (Lam_compat.cmp_bigint cmp (a) (b)) | Pintcomp ((Ceq | Cneq) as op), Const_pointer a, Const_pointer b -> Lift.bool (match op with diff --git a/jscomp/core/lam_compat.ml b/jscomp/core/lam_compat.ml index 83564523bc..0ade662f21 100644 --- a/jscomp/core/lam_compat.ml +++ b/jscomp/core/lam_compat.ml @@ -68,6 +68,15 @@ let cmp_float (cmp : comparison) (a : float) b : bool = | Clt -> a < b | Cge -> a >= b +let cmp_bigint (cmp : comparison) (a : string) b : bool = + match cmp with + | Ceq -> a = b + | Cneq -> a <> b + | Cgt -> a > b + | Cle -> a <= b + | Clt -> a < b + | Cge -> a >= b + let cmp_int (cmp : comparison) (a : int) b : bool = match cmp with | Ceq -> a = b diff --git a/jscomp/core/lam_compat.mli b/jscomp/core/lam_compat.mli index de022543be..5181fc3243 100644 --- a/jscomp/core/lam_compat.mli +++ b/jscomp/core/lam_compat.mli @@ -61,6 +61,8 @@ val cmp_int64 : comparison -> int64 -> int64 -> bool val cmp_float : comparison -> float -> float -> bool +val cmp_bigint : comparison -> string -> string -> bool + val cmp_int : comparison -> int -> int -> bool val eq_comparison : comparison -> comparison -> bool diff --git a/jscomp/core/lam_pass_lets_dce.ml b/jscomp/core/lam_pass_lets_dce.ml index b9459eb168..dad1786fa2 100644 --- a/jscomp/core/lam_pass_lets_dce.ml +++ b/jscomp/core/lam_pass_lets_dce.ml @@ -51,7 +51,7 @@ let lets_helper (count_var : Ident.t -> Lam_pass_count.used_info) lam : Lam.t = | {times = 1; captured = true }, (Lconst _ | Lvar _) | _, (Lconst (( - Const_int _ | Const_char _ | Const_float _ + Const_int _ | Const_char _ | Const_float _ | Const_bigint _ ) | Const_pointer _ |Const_js_true | Const_js_false | Const_js_undefined _) (* could be poly-variant [`A] -> [65a]*) | Lprim {primitive = Pfield (_); diff --git a/jscomp/ml/matching.ml b/jscomp/ml/matching.ml index 79adae5b21..ff213fac65 100644 --- a/jscomp/ml/matching.ml +++ b/jscomp/ml/matching.ml @@ -2239,7 +2239,7 @@ let combine_constant names loc arg cst partial ctx def | Const_bigint _ -> make_test_sequence loc fail - (Pbintcomp(Pbigint, Cneq)) (Pbintcomp(Pbigint, Clt)) + (Pbigintcomp Cneq) (Pbigintcomp Clt) arg const_lambda_list in lambda1,jumps_union local_jumps total diff --git a/jscomp/ml/parmatch.ml b/jscomp/ml/parmatch.ml index 46030055e7..3f49819a12 100644 --- a/jscomp/ml/parmatch.ml +++ b/jscomp/ml/parmatch.ml @@ -264,6 +264,8 @@ let const_compare x y = match x,y with | Const_float f1, Const_float f2 -> compare (float_of_string f1) (float_of_string f2) + | Const_bigint b1, Const_bigint b2 -> + String.compare b1 b2 | Const_string (s1, _), Const_string (s2, _) -> String.compare s1 s2 | _, _ -> compare x y diff --git a/jscomp/test/VariantCoercion.js b/jscomp/test/VariantCoercion.js index 556121501f..325b780648 100644 --- a/jscomp/test/VariantCoercion.js +++ b/jscomp/test/VariantCoercion.js @@ -62,22 +62,16 @@ var CoerceFromFloatToVariant = { cc: 120 }; -var a$2 = 100n; - -var aa$1 = 1n; - -var c$2 = 120n; - var CoerceFromBigintToVariant = { - a: a$2, - aa: aa$1, - b: a$2, - bb: aa$1, - c: c$2, - cc: c$2 + a: 100n, + aa: 1n, + b: 100n, + bb: 1n, + c: 120n, + cc: 120n }; -var a$3 = "Three"; +var a$2 = "Three"; var b = "Three"; @@ -89,7 +83,7 @@ var ii = 1.1; var dd = 1.1; -exports.a = a$3; +exports.a = a$2; exports.b = b; exports.i = i; exports.d = d; From 41ba70b8c2a8efcdaf5288b11ccada97091f184a Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 18 Mar 2024 22:26:10 +0900 Subject: [PATCH 24/45] bitwise operators in Js_bigint --- jscomp/others/js_bigint.res | 9 +++++++++ lib/es6/js_bigint.js | 12 +++++++++++- lib/js/js_bigint.js | 10 +++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/jscomp/others/js_bigint.res b/jscomp/others/js_bigint.res index e8cc4a7567..687f6700cb 100644 --- a/jscomp/others/js_bigint.res +++ b/jscomp/others/js_bigint.res @@ -37,6 +37,15 @@ external \"/": (bigint, bigint) => bigint = "%divbigint" external mod: (bigint, bigint) => bigint = "%modbigint" external \"**": (bigint, bigint) => bigint = "%powbigint" +external land: (bigint, bigint) => bigint = "%andbigint" +external lor: (bigint, bigint) => bigint = "%orbigint" +external lxor: (bigint, bigint) => bigint = "%xorbigint" + +let lnot = x => lxor(x, -1n) + +external lsl: (bigint, bigint) => bigint = "%lslbigint" +external asr: (bigint, bigint) => bigint = "%asrbigint" + @send /** Formats a `bigint` as a string. Return a `string` representing the given value. diff --git a/lib/es6/js_bigint.js b/lib/es6/js_bigint.js index ae1b9f17e6..7255018701 100644 --- a/lib/es6/js_bigint.js +++ b/lib/es6/js_bigint.js @@ -1 +1,11 @@ -/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ + + + +function lnot(x) { + return x ^ -1n; +} + +export { + lnot , +} +/* No side effect */ diff --git a/lib/js/js_bigint.js b/lib/js/js_bigint.js index ae1b9f17e6..f66be3837c 100644 --- a/lib/js/js_bigint.js +++ b/lib/js/js_bigint.js @@ -1 +1,9 @@ -/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ +'use strict'; + + +function lnot(x) { + return x ^ -1n; +} + +exports.lnot = lnot; +/* No side effect */ From 3e9a47124ab6985cfe2391417d3d77c9950e6bf2 Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 19 Mar 2024 13:24:52 +0900 Subject: [PATCH 25/45] add test for bitwise operations --- jscomp/test/bigint_test.js | 71 +++++++++++++++++++++++++++++-------- jscomp/test/bigint_test.res | 14 ++++++++ 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js index 610d01ee7e..e00eb3b175 100644 --- a/jscomp/test/bigint_test.js +++ b/jscomp/test/bigint_test.js @@ -66,33 +66,71 @@ function bigint_greaterequal(x, y) { var generic_greaterequal = Caml_obj.greaterequal; -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 21, characters 5-12", Caml.bigint_compare(1n, 1n), 0); +function bigint_land(prim0, prim1) { + return prim0 & prim1; +} + +function bigint_lor(prim0, prim1) { + return prim0 | prim1; +} + +function bigint_lxor(prim0, prim1) { + return prim0 ^ prim1; +} + +function bigint_lsl(prim0, prim1) { + return (prim0 << prim1); +} + +function bigint_asr(prim0, prim1) { + return (prim0 >> prim1); +} + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 26, characters 5-12", Caml.bigint_compare(1n, 1n), 0); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 27, characters 5-12", Caml_obj.compare(1n, 1n), 0); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 28, characters 5-12", Caml.bigint_compare(-0n, -1n), 1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 29, characters 5-12", Caml_obj.compare(-0n, -1n), 1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 30, characters 5-12", Caml.bigint_compare(0n, -1n), 1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 31, characters 5-12", Caml_obj.compare(0n, -1n), 1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 32, characters 5-12", Caml.bigint_compare(1n, 2n), -1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 33, characters 5-12", Caml_obj.compare(1n, 2n), -1); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 34, characters 5-12", true, true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 35, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 22, characters 5-12", Caml_obj.compare(1n, 1n), 0); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 36, characters 5-12", false, false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 23, characters 5-12", Caml.bigint_compare(-0n, -1n), 1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 37, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 24, characters 5-12", Caml_obj.compare(-0n, -1n), 1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 38, characters 5-12", false, false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 25, characters 5-12", Caml.bigint_compare(0n, -1n), 1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 39, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 26, characters 5-12", Caml_obj.compare(0n, -1n), 1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 40, characters 5-12", 9n & 1n, 1n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 27, characters 5-12", Caml.bigint_compare(1n, 2n), -1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 41, characters 5-12", 9n | 1n, 9n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 28, characters 5-12", Caml_obj.compare(1n, 2n), -1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 42, characters 5-12", 9n ^ 1n, 8n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 29, characters 5-12", true, true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 43, characters 5-12", (9n << 1n), 18n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 30, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 44, characters 5-12", (9n << -1n), 4n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 31, characters 5-12", false, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 45, characters 5-12", (9n >> 1n), 4n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 32, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 46, characters 5-12", (9n >> -1n), 18n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 33, characters 5-12", false, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 47, characters 5-12", (-9n >> 1n), -5n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 34, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 48, characters 5-12", (-9n >> -1n), -18n); Mt.from_pair_suites("Bigint_test", suites.contents); @@ -114,4 +152,9 @@ exports.bigint_lessequal = bigint_lessequal; exports.generic_lessequal = generic_lessequal; exports.bigint_greaterequal = bigint_greaterequal; exports.generic_greaterequal = generic_greaterequal; +exports.bigint_land = bigint_land; +exports.bigint_lor = bigint_lor; +exports.bigint_lxor = bigint_lxor; +exports.bigint_lsl = bigint_lsl; +exports.bigint_asr = bigint_asr; /* Not a pure module */ diff --git a/jscomp/test/bigint_test.res b/jscomp/test/bigint_test.res index 3412882162..f418c8a476 100644 --- a/jscomp/test/bigint_test.res +++ b/jscomp/test/bigint_test.res @@ -16,6 +16,11 @@ let bigint_lessequal = (x: bigint, y) => x <= y let generic_lessequal = \"<=" let bigint_greaterequal = (x: bigint, y) => x >= y let generic_greaterequal = \">=" +let bigint_land = Pervasives.landn +let bigint_lor = Pervasives.lorn +let bigint_lxor = Pervasives.lxorn +let bigint_lsl = Pervasives.lsln +let bigint_asr = Pervasives.asrn let () = { eq(__LOC__, bigint_compare(1n, 1n), 0) @@ -32,6 +37,15 @@ let () = { eq(__LOC__, generic_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false) eq(__LOC__, bigint_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false) eq(__LOC__, generic_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false) + eq(__LOC__, bigint_land(9n, 1n), 1n) + eq(__LOC__, bigint_lor(9n, 1n), 9n) + eq(__LOC__, bigint_lxor(9n, 1n), 8n) + eq(__LOC__, bigint_lsl(9n, 1n), 18n) + eq(__LOC__, bigint_lsl(9n, -1n), 4n) + eq(__LOC__, bigint_asr(9n, 1n), 4n) + eq(__LOC__, bigint_asr(9n, -1n), 18n) + eq(__LOC__, bigint_asr(-9n, 1n), -5n) + eq(__LOC__, bigint_asr(-9n, -1n), -18n) } let () = Mt.from_pair_suites(__MODULE__, suites.contents) From fee14cca57a9a20665d4b1264936885f538e1d99 Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 22 Mar 2024 01:54:01 +0900 Subject: [PATCH 26/45] remove bigint operators from parser and pervasives --- jscomp/core/lam_print.ml | 36 +-- jscomp/ml/printlambda.ml | 20 +- jscomp/stdlib-406/pervasives.res | 20 -- jscomp/stdlib-406/pervasives.resi | 74 ----- jscomp/stdlib-406/pervasivesU.res | 20 -- jscomp/stdlib-406/pervasivesU.resi | 74 ----- jscomp/syntax/src/res_comments_table.ml | 6 +- jscomp/syntax/src/res_core.ml | 13 +- jscomp/syntax/src/res_parsetree_viewer.ml | 12 +- jscomp/syntax/src/res_printer.ml | 2 - jscomp/syntax/src/res_scanner.ml | 23 +- jscomp/syntax/src/res_token.ml | 18 +- .../parsing/grammar/expressions/bigint.res | 10 +- .../parsing/grammar/expressions/binary.res | 1 - .../expressions/expected/bigint.res.txt | 10 +- .../expressions/expected/binary.res.txt | 1 - .../expressions/expected/unary.res.txt | 2 - .../expected/unaryOrBinary.res.txt | 5 - .../parsing/grammar/expressions/unary.res | 2 - .../grammar/expressions/unaryOrBinary.res | 17 -- jscomp/test/bigint_test.res | 10 +- jscomp/test/ocaml_re_test.js | 288 +++++++++--------- jscomp/test/test_per.js | 5 - jscomp/test/test_per.res | 19 -- jscomp/test/test_pervasive.js | 1 - jscomp/test/test_pervasives2.js | 2 - jscomp/test/test_pervasives3.js | 1 - lib/es6/pervasives.js | 5 - lib/es6/pervasivesU.js | 5 - lib/js/pervasives.js | 5 - lib/js/pervasivesU.js | 5 - 31 files changed, 206 insertions(+), 506 deletions(-) diff --git a/jscomp/core/lam_print.ml b/jscomp/core/lam_print.ml index 7ecd43171e..36c902be98 100644 --- a/jscomp/core/lam_print.ml +++ b/jscomp/core/lam_print.ml @@ -134,24 +134,24 @@ let primitive ppf (prim : Lam_primitive.t) = | Pfloatcomp Cle -> fprintf ppf "<=." | Pfloatcomp Cgt -> fprintf ppf ">." | Pfloatcomp Cge -> fprintf ppf ">=." - | Pnegbigint -> fprintf ppf "~," - | Paddbigint -> fprintf ppf "+," - | Psubbigint -> fprintf ppf "-," - | Pmulbigint -> fprintf ppf "*," - | Pdivbigint -> fprintf ppf "/," - | Pmodbigint -> fprintf ppf "modn" - | Ppowbigint -> fprintf ppf "**," - | Pandbigint -> fprintf ppf "and," - | Porbigint -> fprintf ppf "or," - | Pxorbigint -> fprintf ppf "xor," - | Plslbigint -> fprintf ppf "lsl," - | Pasrbigint -> fprintf ppf "asr," - | Pbigintcomp Ceq -> fprintf ppf "==," - | Pbigintcomp Cneq -> fprintf ppf "!=," - | Pbigintcomp Clt -> fprintf ppf "<," - | Pbigintcomp Cle -> fprintf ppf "<=," - | Pbigintcomp Cgt -> fprintf ppf ">," - | Pbigintcomp Cge -> fprintf ppf ">=," + | Pnegbigint -> fprintf ppf "~" + | Paddbigint -> fprintf ppf "+" + | Psubbigint -> fprintf ppf "-" + | Pmulbigint -> fprintf ppf "*" + | Pdivbigint -> fprintf ppf "/" + | Pmodbigint -> fprintf ppf "mod" + | Ppowbigint -> fprintf ppf "**" + | Pandbigint -> fprintf ppf "and" + | Porbigint -> fprintf ppf "or" + | Pxorbigint -> fprintf ppf "xor" + | Plslbigint -> fprintf ppf "lsl" + | Pasrbigint -> fprintf ppf "asr" + | Pbigintcomp Ceq -> fprintf ppf "==" + | Pbigintcomp Cneq -> fprintf ppf "!=" + | Pbigintcomp Clt -> fprintf ppf "<" + | Pbigintcomp Cle -> fprintf ppf "<=" + | Pbigintcomp Cgt -> fprintf ppf ">" + | Pbigintcomp Cge -> fprintf ppf ">=" | Pjscomp Ceq -> fprintf ppf "#==" | Pjscomp Cneq -> fprintf ppf "#!=" | Pjscomp Clt -> fprintf ppf "#<" diff --git a/jscomp/ml/printlambda.ml b/jscomp/ml/printlambda.ml index e337bdc3c8..ded3c57226 100644 --- a/jscomp/ml/printlambda.ml +++ b/jscomp/ml/printlambda.ml @@ -177,16 +177,16 @@ let primitive ppf = function | Pfloatcomp(Cle) -> fprintf ppf "<=." | Pfloatcomp(Cgt) -> fprintf ppf ">." | Pfloatcomp(Cge) -> fprintf ppf ">=." - | Pnegbigint -> fprintf ppf "~," - | Paddbigint -> fprintf ppf "+," - | Psubbigint -> fprintf ppf "-," - | Pmulbigint -> fprintf ppf "*," - | Ppowbigint -> fprintf ppf "**," - | Pandbigint -> fprintf ppf "and," - | Porbigint -> fprintf ppf "or," - | Pxorbigint -> fprintf ppf "xor," - | Plslbigint -> fprintf ppf "lsl," - | Pasrbigint -> fprintf ppf "asr," + | Pnegbigint -> fprintf ppf "~" + | Paddbigint -> fprintf ppf "+" + | Psubbigint -> fprintf ppf "-" + | Pmulbigint -> fprintf ppf "*" + | Ppowbigint -> fprintf ppf "**" + | Pandbigint -> fprintf ppf "and" + | Porbigint -> fprintf ppf "or" + | Pxorbigint -> fprintf ppf "xor" + | Plslbigint -> fprintf ppf "lsl" + | Pasrbigint -> fprintf ppf "asr" | Pdivbigint Safe -> fprintf ppf "/n" | Pdivbigint Unsafe -> fprintf ppf "/nu" | Pmodbigint Safe -> fprintf ppf "mod" diff --git a/jscomp/stdlib-406/pervasives.res b/jscomp/stdlib-406/pervasives.res index 143507f37d..632d0b7228 100644 --- a/jscomp/stdlib-406/pervasives.res +++ b/jscomp/stdlib-406/pervasives.res @@ -179,26 +179,6 @@ let classify_float = (x: float): fpclass => FP_infinite } -/* Bigint operations */ - -external \"~-,": bigint => bigint = "%negbigint" -external \"~+,": bigint => bigint = "%identity" -external \"+,": (bigint, bigint) => bigint = "%addbigint" -external \"-,": (bigint, bigint) => bigint = "%subbigint" -external \"*,": (bigint, bigint) => bigint = "%mulbigint" -external \"/,": (bigint, bigint) => bigint = "%divbigint" -external modn: (bigint, bigint) => bigint = "%modbigint" -external \"**,": (bigint, bigint) => bigint = "%powbigint" - -external landn: (bigint, bigint) => bigint = "%andbigint" -external lorn: (bigint, bigint) => bigint = "%orbigint" -external lxorn: (bigint, bigint) => bigint = "%xorbigint" - -let lnotn = x => lxorn(x, -1n) - -external lsln: (bigint, bigint) => bigint = "%lslbigint" -external asrn: (bigint, bigint) => bigint = "%asrbigint" - /* String and byte sequence operations -- more in modules String and Bytes */ external string_length: string => int = "%string_length" diff --git a/jscomp/stdlib-406/pervasives.resi b/jscomp/stdlib-406/pervasives.resi index 52a50087d9..43407ced92 100644 --- a/jscomp/stdlib-406/pervasives.resi +++ b/jscomp/stdlib-406/pervasives.resi @@ -521,80 +521,6 @@ let infinity: float /** Negative infinity. */ let neg_infinity: float -/** Unary negation. You can also write [- e] instead of [~- e]. - Unary operator at precedence level 9/11 for [- e] - and 11/11 for [~- e]. */ -external \"~-,": bigint => bigint = "%negbigint" - -/** Unary addition. You can also write [+ e] instead of [~+ e]. - Unary operator at precedence level 9/11 for [+ e] - and 11/11 for [~+ e]. - @since 3.12.0 -*/ -external \"~+,": bigint => bigint = "%identity" - -/** Bigint addition. - Left-associative operator at precedence level 6/11. */ -external \"+,": (bigint, bigint) => bigint = "%addbigint" - -/** Bigint subtraction. - Left-associative operator at precedence level 6/11. */ -external \"-,": (bigint, bigint) => bigint = "%subbigint" - -/** Bigint multiplication. - Left-associative operator at precedence level 7/11. */ -external \"*,": (bigint, bigint) => bigint = "%mulbigint" - -/** Bigint division. - Raise [Division_by_zero] if the second argument is 0. - Bigint division rounds the real quotient of its arguments towards zero. - More precisely, if [x >= 0] and [y > 0], [x / y] is the greatest bigint - less than or equal to the real quotient of [x] by [y]. Moreover, - [(- x) / y = x / (- y) = - (x / y)]. - Left-associative operator at precedence level 7/11. */ -external \"/,": (bigint, bigint) => bigint = "%divbigint" - -/** Bigint remainder. If [y] is not zero, the result - of [x mod y] satisfies the following properties: - [x = (x / y) * y + x mod y] and - [abs(x mod y) <= abs(y) - 1]. - If [y = 0], [x mod y] raises [Division_by_zero]. - Note that [x mod y] is negative only if [x < 0]. - Raise [Division_by_zero] if [y] is zero. - Left-associative operator at precedence level 7/11. */ -external modn: (bigint, bigint) => bigint = "%modbigint" - -/** Bigint Exponentiation. - Left-associative operator at precedence level 7/9. */ -external \"**,": (bigint, bigint) => bigint = "%powbigint" - -/** Bigint Bitwise logical and. - Left-associative operator at precedence level 7/11. */ -external landn: (bigint, bigint) => bigint = "%andbigint" - -/** Bigint Bitwise logical or. - Left-associative operator at precedence level 7/11. */ -external lorn: (bigint, bigint) => bigint = "%orbigint" - -/** Bigint Bitwise logical exclusive or. - Left-associative operator at precedence level 7/11. */ -external lxorn: (bigint, bigint) => bigint = "%xorbigint" - -/** Bigint Bitwise logical negation. */ -let lnotn: bigint => bigint - -/** [n lsln m] shifts [n] to the left by [m] bits. - The result is unspecified if [m < 0n] or [m >= bitsize], - where the both operands are bigints. - Right-associative operator at precedence level 8/11. */ -external lsln: (bigint, bigint) => bigint = "%lslbigint" - -/** [n asrn m] shifts [n] to the right by [m] bits. - This is an arithmetic shift: the sign bit of [n] is replicated. - The result is unspecified if [m < 0n] or [m >= bitsize]. - Right-associative operator at precedence level 8/11. */ -external asrn: (bigint, bigint) => bigint = "%asrbigint" - @val @scope("Number") /** A special floating-point value denoting the result of an diff --git a/jscomp/stdlib-406/pervasivesU.res b/jscomp/stdlib-406/pervasivesU.res index bd6a1badba..c044504bb7 100644 --- a/jscomp/stdlib-406/pervasivesU.res +++ b/jscomp/stdlib-406/pervasivesU.res @@ -180,26 +180,6 @@ let classify_float = (x: float): fpclass => FP_infinite } -/* Bigint operations */ - -external \"~-,": bigint => bigint = "%negbigint" -external \"~+,": bigint => bigint = "%identity" -external \"+,": (bigint, bigint) => bigint = "%addbigint" -external \"-,": (bigint, bigint) => bigint = "%subbigint" -external \"*,": (bigint, bigint) => bigint = "%mulbigint" -external \"/,": (bigint, bigint) => bigint = "%divbigint" -external modn: (bigint, bigint) => bigint = "%modbigint" -external \"**,": (bigint, bigint) => bigint = "%powbigint" - -external landn: (bigint, bigint) => bigint = "%andbigint" -external lorn: (bigint, bigint) => bigint = "%orbigint" -external lxorn: (bigint, bigint) => bigint = "%xorbigint" - -let lnotn = x => lxorn(x, -1n) - -external lsln: (bigint, bigint) => bigint = "%lslbigint" -external asrn: (bigint, bigint) => bigint = "%asrbigint" - /* String and byte sequence operations -- more in modules String and Bytes */ external string_length: string => int = "%string_length" diff --git a/jscomp/stdlib-406/pervasivesU.resi b/jscomp/stdlib-406/pervasivesU.resi index d6d4dc6456..4b0f05928b 100644 --- a/jscomp/stdlib-406/pervasivesU.resi +++ b/jscomp/stdlib-406/pervasivesU.resi @@ -524,80 +524,6 @@ let infinity: float /** Negative infinity. */ let neg_infinity: float -/** Unary negation. You can also write [- e] instead of [~- e]. - Unary operator at precedence level 9/11 for [- e] - and 11/11 for [~- e]. */ -external \"~-,": bigint => bigint = "%negbigint" - -/** Unary addition. You can also write [+ e] instead of [~+ e]. - Unary operator at precedence level 9/11 for [+ e] - and 11/11 for [~+ e]. - @since 3.12.0 -*/ -external \"~+,": bigint => bigint = "%identity" - -/** Bigint addition. - Left-associative operator at precedence level 6/11. */ -external \"+,": (bigint, bigint) => bigint = "%addbigint" - -/** Bigint subtraction. - Left-associative operator at precedence level 6/11. */ -external \"-,": (bigint, bigint) => bigint = "%subbigint" - -/** Bigint multiplication. - Left-associative operator at precedence level 7/11. */ -external \"*,": (bigint, bigint) => bigint = "%mulbigint" - -/** Bigint division. - Raise [Division_by_zero] if the second argument is 0. - Bigint division rounds the real quotient of its arguments towards zero. - More precisely, if [x >= 0] and [y > 0], [x / y] is the greatest bigint - less than or equal to the real quotient of [x] by [y]. Moreover, - [(- x) / y = x / (- y) = - (x / y)]. - Left-associative operator at precedence level 7/11. */ -external \"/,": (bigint, bigint) => bigint = "%divbigint" - -/** Bigint remainder. If [y] is not zero, the result - of [x mod y] satisfies the following properties: - [x = (x / y) * y + x mod y] and - [abs(x mod y) <= abs(y) - 1]. - If [y = 0], [x mod y] raises [Division_by_zero]. - Note that [x mod y] is negative only if [x < 0]. - Raise [Division_by_zero] if [y] is zero. - Left-associative operator at precedence level 7/11. */ -external modn: (bigint, bigint) => bigint = "%modbigint" - -/** Bigint Exponentiation. - Left-associative operator at precedence level 7/9. */ -external \"**,": (bigint, bigint) => bigint = "%powbigint" - -/** Bigint Bitwise logical and. - Left-associative operator at precedence level 7/11. */ -external landn: (bigint, bigint) => bigint = "%andbigint" - -/** Bigint Bitwise logical or. - Left-associative operator at precedence level 7/11. */ -external lorn: (bigint, bigint) => bigint = "%orbigint" - -/** Bigint Bitwise logical exclusive or. - Left-associative operator at precedence level 7/11. */ -external lxorn: (bigint, bigint) => bigint = "%xorbigint" - -/** Bigint Bitwise logical negation. */ -let lnotn: bigint => bigint - -/** [n lsln m] shifts [n] to the left by [m] bits. - The result is unspecified if [m < 0n] or [m >= bitsize], - where the both operands are bigints. - Right-associative operator at precedence level 8/11. */ -external lsln: (bigint, bigint) => bigint = "%lslbigint" - -/** [n asrn m] shifts [n] to the right by [m] bits. - This is an arithmetic shift: the sign bit of [n] is replicated. - The result is unspecified if [m < 0n] or [m >= bitsize]. - Right-associative operator at precedence level 8/11. */ -external asrn: (bigint, bigint) => bigint = "%asrbigint" - @val @scope("Number") /** A special floating-point value denoting the result of an diff --git a/jscomp/syntax/src/res_comments_table.ml b/jscomp/syntax/src/res_comments_table.ml index df9379b4e9..d12ace5287 100644 --- a/jscomp/syntax/src/res_comments_table.ml +++ b/jscomp/syntax/src/res_comments_table.ml @@ -1269,8 +1269,7 @@ and walkExpression expr t comments = Pexp_ident { txt = - Longident.Lident - ("~+" | "~+." | "~+," | "~-" | "~-." | "~-," | "not" | "!"); + Longident.Lident ("~+" | "~+." | "~-" | "~-." | "not" | "!"); }; }, [(Nolabel, argExpr)] ) -> @@ -1288,8 +1287,7 @@ and walkExpression expr t comments = Longident.Lident ( ":=" | "||" | "&&" | "=" | "==" | "<" | ">" | "!=" | "!==" | "<=" | ">=" | "|>" | "+" | "+." | "-" | "-." | "++" | "^" - | "*" | "*." | "/" | "/." | "**" | "**," | "|." | "|.u" - | "<>" ); + | "*" | "*." | "/" | "/." | "**" | "|." | "|.u" | "<>" ); }; }, [(Nolabel, operand1); (Nolabel, operand2)] ) -> diff --git a/jscomp/syntax/src/res_core.ml b/jscomp/syntax/src/res_core.ml index ce39f9eeda..189f80de5d 100644 --- a/jscomp/syntax/src/res_core.ml +++ b/jscomp/syntax/src/res_core.ml @@ -410,17 +410,16 @@ let negateString s = let makeUnaryExpr startPos tokenEnd token operand = match (token, operand.Parsetree.pexp_desc) with - | ( (Token.Plus | PlusDot | PlusComma), - Pexp_constant (Pconst_integer _ | Pconst_float _) ) -> + | (Token.Plus | PlusDot), Pexp_constant (Pconst_integer _ | Pconst_float _) -> operand | Minus, Pexp_constant (Pconst_integer (n, m)) -> { operand with pexp_desc = Pexp_constant (Pconst_integer (negateString n, m)); } - | (Minus | MinusDot | MinusComma), Pexp_constant (Pconst_float (n, m)) -> + | (Minus | MinusDot), Pexp_constant (Pconst_float (n, m)) -> {operand with pexp_desc = Pexp_constant (Pconst_float (negateString n, m))} - | (Token.Plus | PlusDot | PlusComma | Minus | MinusDot | MinusComma), _ -> + | (Token.Plus | PlusDot | Minus | MinusDot), _ -> let tokenLoc = mkLoc startPos tokenEnd in let operator = "~" ^ Token.toString token in Ast_helper.Exp.apply @@ -2093,8 +2092,7 @@ and parsePrimaryExpr ~operand ?(noCall = false) p = and parseUnaryExpr p = let startPos = p.Parser.startPos in match p.Parser.token with - | (Minus | MinusDot | MinusComma | Plus | PlusDot | PlusComma | Bang) as token - -> + | (Minus | MinusDot | Plus | PlusDot | Bang) as token -> Parser.leaveBreadcrumb p Grammar.ExprUnary; let tokenEnd = p.endPos in Parser.next p; @@ -2200,8 +2198,7 @@ and parseBinaryExpr ?(context = OrdinaryExpr) ?a p prec = let endPos = p.prevEndPos in let tokenPrec = (* exponentiation operator is right-associative *) - if token = Exponentiation || token = ExponentiationComma then tokenPrec - else tokenPrec + 1 + if token = Exponentiation then tokenPrec else tokenPrec + 1 in let b = parseBinaryExpr ~context p tokenPrec in let loc = mkLoc a.Parsetree.pexp_loc.loc_start b.pexp_loc.loc_end in diff --git a/jscomp/syntax/src/res_parsetree_viewer.ml b/jscomp/syntax/src/res_parsetree_viewer.ml index 0f7f85e5d3..a376b5b633 100644 --- a/jscomp/syntax/src/res_parsetree_viewer.ml +++ b/jscomp/syntax/src/res_parsetree_viewer.ml @@ -292,15 +292,15 @@ let operatorPrecedence operator = | "||" -> 2 | "&&" -> 3 | "=" | "==" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 4 - | "+" | "+." | "+," | "-" | "-." | "-," | "^" -> 5 + | "+" | "+." | "-" | "-." | "^" -> 5 | "*" | "*." | "/" | "/." -> 6 - | "**" | "**," -> 7 + | "**" -> 7 | "#" | "##" | "|." | "|.u" -> 8 | _ -> 0 let isUnaryOperator operator = match operator with - | "~+" | "~+." | "~+," | "~-" | "~-." | "~-," | "not" -> true + | "~+" | "~+." | "~-" | "~-." | "not" -> true | _ -> false let isUnaryExpression expr = @@ -316,8 +316,8 @@ let isUnaryExpression expr = let isBinaryOperator operator = match operator with | ":=" | "||" | "&&" | "=" | "==" | "<" | ">" | "!=" | "!==" | "<=" | ">=" - | "|>" | "+" | "+." | "+," | "-" | "-." | "-," | "^" | "*" | "*." | "*," | "/" - | "/." | "/," | "**" | "**," | "|." | "|.u" | "<>" -> + | "|>" | "+" | "+." | "-" | "-." | "^" | "*" | "*." | "/" | "/." | "**" | "|." + | "|.u" | "<>" -> true | _ -> false @@ -342,7 +342,7 @@ let isEqualityOperator operator = let isRhsBinaryOperator operator = match operator with - | "**" | "**," -> true + | "**" -> true | _ -> false let flattenableOperators parentOperator childOperator = diff --git a/jscomp/syntax/src/res_printer.ml b/jscomp/syntax/src/res_printer.ml index 98b3edc92f..c7a715f8ce 100644 --- a/jscomp/syntax/src/res_printer.ml +++ b/jscomp/syntax/src/res_printer.ml @@ -3546,10 +3546,8 @@ and printUnaryExpression ~state expr cmtTbl = (match op with | "~+" -> "+" | "~+." -> "+." - | "~+," -> "+," | "~-" -> "-" | "~-." -> "-." - | "~-," -> "-," | "not" -> "!" | _ -> assert false) in diff --git a/jscomp/syntax/src/res_scanner.ml b/jscomp/syntax/src/res_scanner.ml index 37767697f7..40d759004a 100644 --- a/jscomp/syntax/src/res_scanner.ml +++ b/jscomp/syntax/src/res_scanner.ml @@ -691,20 +691,12 @@ let rec scan scanner = Token.Hash) | '*' -> ( match peek scanner with - | '*' -> ( - match peek2 scanner with - | ',' -> - next3 scanner; - Token.ExponentiationComma - | _ -> - next2 scanner; - Token.Exponentiation) + | '*' -> + next2 scanner; + Token.Exponentiation | '.' -> next2 scanner; Token.AsteriskDot - | ',' -> - next2 scanner; - Token.AsteriskComma | _ -> next scanner; Token.Asterisk) @@ -766,9 +758,6 @@ let rec scan scanner = | '.' -> next2 scanner; Token.ForwardslashDot - | ',' -> - next2 scanner; - Token.ForwardslashComma | _ -> next scanner; Token.Forwardslash) @@ -777,9 +766,6 @@ let rec scan scanner = | '.' -> next2 scanner; Token.MinusDot - | ',' -> - next2 scanner; - Token.MinusComma | '>' -> next2 scanner; Token.MinusGreater @@ -791,9 +777,6 @@ let rec scan scanner = | '.' -> next2 scanner; Token.PlusDot - | ',' -> - next2 scanner; - Token.PlusComma | '+' -> next2 scanner; Token.PlusPlus diff --git a/jscomp/syntax/src/res_token.ml b/jscomp/syntax/src/res_token.ml index 3ec3d60687..5d12e0f141 100644 --- a/jscomp/syntax/src/res_token.ml +++ b/jscomp/syntax/src/res_token.ml @@ -39,18 +39,13 @@ type t = | Backslash [@live] | Forwardslash | ForwardslashDot - | ForwardslashComma | Asterisk | AsteriskDot - | AsteriskComma | Exponentiation - | ExponentiationComma | Minus | MinusDot - | MinusComma | Plus | PlusDot - | PlusComma | PlusPlus | PlusEqual | ColonGreaterThan @@ -109,11 +104,9 @@ let precedence = function | Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual | BangEqualEqual | LessEqual | GreaterEqual | BarGreater -> 4 - | Plus | PlusDot | PlusComma | Minus | MinusDot | MinusComma | PlusPlus -> 5 - | Asterisk | AsteriskDot | AsteriskComma | Forwardslash | ForwardslashDot - | ForwardslashComma -> - 6 - | Exponentiation | ExponentiationComma -> 7 + | Plus | PlusDot | Minus | MinusDot | PlusPlus -> 5 + | Asterisk | AsteriskDot | Forwardslash | ForwardslashDot -> 6 + | Exponentiation -> 7 | MinusGreater -> 8 | Dot -> 9 | _ -> 0 @@ -156,16 +149,13 @@ let toString = function | Comma -> "," | Minus -> "-" | MinusDot -> "-." - | MinusComma -> "-," | Plus -> "+" | PlusDot -> "+." - | PlusComma -> "+," | PlusPlus -> "++" | PlusEqual -> "+=" | Backslash -> "\\" | Forwardslash -> "/" | ForwardslashDot -> "/." - | ForwardslashComma -> "/," | Exception -> "exception" | Hash -> "#" | HashEqual -> "#=" @@ -174,9 +164,7 @@ let toString = function | LessThanSlash -> " "*" | AsteriskDot -> "*." - | AsteriskComma -> "*," | Exponentiation -> "**" - | ExponentiationComma -> "**," | Assert -> "assert" | Lazy -> "lazy" | Tilde -> "tilde" diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res b/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res index da9e998e63..60a5497495 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res +++ b/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res @@ -1,9 +1,9 @@ -1n /, 2n +1n / 2n -3n *, 4n +3n * 4n -2n **, 2n +2n ** 2n -10n +, 54 +10n + 54 -289n -, 138n +289n - 138n diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/binary.res b/jscomp/syntax/tests/parsing/grammar/expressions/binary.res index 61532c3b83..32cc091ef4 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/binary.res +++ b/jscomp/syntax/tests/parsing/grammar/expressions/binary.res @@ -33,7 +33,6 @@ let x = a + @attr -1 + @attr -2 // should be interpreted as binary expression not prefix op let x = a -b let x = a -.b -let x = a -,b // not binary expr Constructor(a, b) diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt index 88b6519ac1..aeadd59947 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt @@ -1,5 +1,5 @@ -;;1n /, 2n -;;3n *, 4n -;;2n **, 2n -;;10n +, 54 -;;289n -, 138n \ No newline at end of file +;;1n / 2n +;;3n * 4n +;;2n ** 2n +;;10n + 54 +;;289n - 138n \ No newline at end of file diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/binary.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/binary.res.txt index ad06ad2c99..81e51b8c75 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/expected/binary.res.txt +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/binary.res.txt @@ -17,7 +17,6 @@ let x = (a + (-1)) + (-2) let x = (a + (((-1))[@attr ])) + (((-2))[@attr ]) let x = a - b let x = a -. b -let x = a -, b ;;Constructor (a, b) ;;`Constructor (a, b) let _ = ((Constructor (a, b); `Constructor (a, b))[@res.braces ]) diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/unary.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/unary.res.txt index 2018c414ef..c919555529 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/expected/unary.res.txt +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/unary.res.txt @@ -5,6 +5,4 @@ let x = 5 let x = 5.4 let b = (-1n) let b = 1n -let b = ~-, 1n -let b = 1n let sum = (- a) - (- b) \ No newline at end of file diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/unaryOrBinary.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/unaryOrBinary.res.txt index 51864b1634..517a93db88 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/expected/unaryOrBinary.res.txt +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/unaryOrBinary.res.txt @@ -2,13 +2,8 @@ let width = (((w -. innerLeft) -. imageWidth) -. imageRightGap) -. rowInnerRight let width = (((w - innerLeft) - imageWidth) - imageRightGap) - rowInnerRight -let width = - (((w -, innerLeft) -, imageWidth) -, imageRightGap) -, rowInnerRight let width = ((w; -. innerLeft; -. imageWidth; -. imageRightGap; -. rowInnerRight) [@res.braces ]) let width = ((w; - innerLeft; - imageWidth; - imageRightGap; - rowInnerRight) - [@res.braces ]) -let width = - (((((w -, innerLeft) -, imageWidth) -, imageRightGap) -, rowInnerRight) [@res.braces ]) \ No newline at end of file diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/unary.res b/jscomp/syntax/tests/parsing/grammar/expressions/unary.res index 67985e87ca..b675fba28f 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/unary.res +++ b/jscomp/syntax/tests/parsing/grammar/expressions/unary.res @@ -6,7 +6,5 @@ let x = +5 let x = +.5.4 let b = -1n let b = +1n -let b = -,1n -let b = +,1n let sum = -a - -b diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/unaryOrBinary.res b/jscomp/syntax/tests/parsing/grammar/expressions/unaryOrBinary.res index bb03e4954f..271ef9d193 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/unaryOrBinary.res +++ b/jscomp/syntax/tests/parsing/grammar/expressions/unaryOrBinary.res @@ -16,14 +16,6 @@ let width = - imageRightGap - rowInnerRight -// binary -let width = - w - -, innerLeft - -, imageWidth - -, imageRightGap - -, rowInnerRight - // unary let width = { w @@ -41,12 +33,3 @@ let width = { -imageRightGap -rowInnerRight } - -// unary -let width = { - w - -,innerLeft - -,imageWidth - -,imageRightGap - -,rowInnerRight -} diff --git a/jscomp/test/bigint_test.res b/jscomp/test/bigint_test.res index f418c8a476..7b70bf88c7 100644 --- a/jscomp/test/bigint_test.res +++ b/jscomp/test/bigint_test.res @@ -16,11 +16,11 @@ let bigint_lessequal = (x: bigint, y) => x <= y let generic_lessequal = \"<=" let bigint_greaterequal = (x: bigint, y) => x >= y let generic_greaterequal = \">=" -let bigint_land = Pervasives.landn -let bigint_lor = Pervasives.lorn -let bigint_lxor = Pervasives.lxorn -let bigint_lsl = Pervasives.lsln -let bigint_asr = Pervasives.asrn +let bigint_land = Js.Bigint.land +let bigint_lor = Js.Bigint.lor +let bigint_lxor = Js.Bigint.lxor +let bigint_lsl = Js.Bigint.lsl +let bigint_asr = Js.Bigint.asr let () = { eq(__LOC__, bigint_compare(1n, 1n), 0) diff --git a/jscomp/test/ocaml_re_test.js b/jscomp/test/ocaml_re_test.js index 098a77d7e8..4cd42b894c 100644 --- a/jscomp/test/ocaml_re_test.js +++ b/jscomp/test/ocaml_re_test.js @@ -4533,150 +4533,6 @@ function parse(multiline, dollar_endonly, dotall, ungreedy, s) { }; } }; - var branch$p = function (_left) { - while(true) { - var left = _left; - if (i.contents === l || test(/* '|' */124) || test(/* ')' */41)) { - return seq$2(List.rev(left)); - } - _left = { - hd: piece(), - tl: left - }; - continue ; - }; - }; - var regexp$p = function (_left) { - while(true) { - var left = _left; - if (!accept(/* '|' */124)) { - return left; - } - _left = alt$1({ - hd: left, - tl: { - hd: branch$p(/* [] */0), - tl: /* [] */0 - } - }); - continue ; - }; - }; - var piece = function (param) { - var r = atom(); - if (accept(/* '*' */42)) { - return greedy_mod(repn(r, 0, undefined)); - } - if (accept(/* '+' */43)) { - return greedy_mod(repn(r, 1, undefined)); - } - if (accept(/* '?' */63)) { - return greedy_mod(repn(r, 0, 1)); - } - if (!accept(/* '{' */123)) { - return r; - } - var i$1 = integer(); - if (i$1 !== undefined) { - var j = accept(/* ',' */44) ? integer() : i$1; - if (!accept(/* '}' */125)) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - if (j !== undefined && j < i$1) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - return greedy_mod(repn(r, i$1, j)); - } - i.contents = i.contents - 1 | 0; - return r; - }; - var bracket = function (_s) { - while(true) { - var s = _s; - if (s !== /* [] */0 && accept(/* ']' */93)) { - return s; - } - var match = $$char(); - if (match.NAME === "Char") { - var c = match.VAL; - if (accept(/* '-' */45)) { - if (accept(/* ']' */93)) { - return { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '-' */45, - /* '-' */45 - ], - tl: /* [] */0 - } - }, - tl: s - } - }; - } - var match$1 = $$char(); - if (match$1.NAME !== "Char") { - return { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '-' */45, - /* '-' */45 - ], - tl: /* [] */0 - } - }, - tl: { - hd: match$1.VAL, - tl: s - } - } - }; - } - _s = { - hd: { - TAG: "Set", - _0: seq(c, match$1.VAL) - }, - tl: s - }; - continue ; - } - _s = { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: s - }; - continue ; - } - _s = { - hd: match.VAL, - tl: s - }; - continue ; - }; - }; var $$char = function (param) { if (i.contents === l) { throw { @@ -4972,6 +4828,150 @@ function parse(multiline, dollar_endonly, dotall, ungreedy, s) { }; } }; + var bracket = function (_s) { + while(true) { + var s = _s; + if (s !== /* [] */0 && accept(/* ']' */93)) { + return s; + } + var match = $$char(); + if (match.NAME === "Char") { + var c = match.VAL; + if (accept(/* '-' */45)) { + if (accept(/* ']' */93)) { + return { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '-' */45, + /* '-' */45 + ], + tl: /* [] */0 + } + }, + tl: s + } + }; + } + var match$1 = $$char(); + if (match$1.NAME !== "Char") { + return { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: { + hd: { + TAG: "Set", + _0: { + hd: [ + /* '-' */45, + /* '-' */45 + ], + tl: /* [] */0 + } + }, + tl: { + hd: match$1.VAL, + tl: s + } + } + }; + } + _s = { + hd: { + TAG: "Set", + _0: seq(c, match$1.VAL) + }, + tl: s + }; + continue ; + } + _s = { + hd: { + TAG: "Set", + _0: single(c) + }, + tl: s + }; + continue ; + } + _s = { + hd: match.VAL, + tl: s + }; + continue ; + }; + }; + var piece = function (param) { + var r = atom(); + if (accept(/* '*' */42)) { + return greedy_mod(repn(r, 0, undefined)); + } + if (accept(/* '+' */43)) { + return greedy_mod(repn(r, 1, undefined)); + } + if (accept(/* '?' */63)) { + return greedy_mod(repn(r, 0, 1)); + } + if (!accept(/* '{' */123)) { + return r; + } + var i$1 = integer(); + if (i$1 !== undefined) { + var j = accept(/* ',' */44) ? integer() : i$1; + if (!accept(/* '}' */125)) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + if (j !== undefined && j < i$1) { + throw { + RE_EXN_ID: Parse_error, + Error: new Error() + }; + } + return greedy_mod(repn(r, i$1, j)); + } + i.contents = i.contents - 1 | 0; + return r; + }; + var branch$p = function (_left) { + while(true) { + var left = _left; + if (i.contents === l || test(/* '|' */124) || test(/* ')' */41)) { + return seq$2(List.rev(left)); + } + _left = { + hd: piece(), + tl: left + }; + continue ; + }; + }; + var regexp$p = function (_left) { + while(true) { + var left = _left; + if (!accept(/* '|' */124)) { + return left; + } + _left = alt$1({ + hd: left, + tl: { + hd: branch$p(/* [] */0), + tl: /* [] */0 + } + }); + continue ; + }; + }; var res = regexp$p(branch$p(/* [] */0)); if (i.contents !== l) { throw { diff --git a/jscomp/test/test_per.js b/jscomp/test/test_per.js index a053488828..27edfb87f7 100644 --- a/jscomp/test/test_per.js +++ b/jscomp/test/test_per.js @@ -94,10 +94,6 @@ var epsilon_float = Caml_int64.float_of_bits([ 0 ]); -function lnotn(x) { - return x ^ -1n; -} - function $caret(s1, s2) { var l1 = s1.length; var l2 = s2.length; @@ -470,7 +466,6 @@ exports.nan = nan; exports.max_float = max_float; exports.min_float = min_float; exports.epsilon_float = epsilon_float; -exports.lnotn = lnotn; exports.$caret = $caret; exports.char_of_int = char_of_int; exports.string_of_bool = string_of_bool; diff --git a/jscomp/test/test_per.res b/jscomp/test/test_per.res index 289b0059e3..d27a252e68 100644 --- a/jscomp/test/test_per.res +++ b/jscomp/test/test_per.res @@ -165,25 +165,6 @@ type fpclass = | FP_nan external classify_float: float => fpclass = "?classify_float" -/* Bigint operations */ - -external \"~-,": bigint => bigint = "%negbigint" -external \"~+,": bigint => bigint = "%identity" -external \"+,": (bigint, bigint) => bigint = "%addbigint" -external \"-,": (bigint, bigint) => bigint = "%subbigint" -external \"*,": (bigint, bigint) => bigint = "%mulbigint" -external \"/,": (bigint, bigint) => bigint = "%divbigint" -external modn: (bigint, bigint) => bigint = "%modbigint" - -external landn: (bigint, bigint) => bigint = "%andbigint" -external lorn: (bigint, bigint) => bigint = "%orbigint" -external lxorn: (bigint, bigint) => bigint = "%xorbigint" - -let lnotn = x => lxorn(x, -1n) - -external lsln: (bigint, bigint) => bigint = "%lslbigint" -external asrn: (bigint, bigint) => bigint = "%asrbigint" - /* String and byte sequence operations -- more in modules String and Bytes */ external string_length: string => int = "%string_length" diff --git a/jscomp/test/test_pervasive.js b/jscomp/test/test_pervasive.js index 6587feab94..128440f3db 100644 --- a/jscomp/test/test_pervasive.js +++ b/jscomp/test/test_pervasive.js @@ -71,7 +71,6 @@ var Pervasives$1 = { lnot: Pervasives.lnot, infinity: Pervasives.infinity, neg_infinity: Pervasives.neg_infinity, - lnotn: Pervasives.lnotn, max_float: Pervasives.max_float, min_float: Pervasives.min_float, epsilon_float: Pervasives.epsilon_float, diff --git a/jscomp/test/test_pervasives2.js b/jscomp/test/test_pervasives2.js index 3cd8629835..f12c45a171 100644 --- a/jscomp/test/test_pervasives2.js +++ b/jscomp/test/test_pervasives2.js @@ -72,7 +72,6 @@ var List$1 = { lnot: Pervasives.lnot, infinity: Pervasives.infinity, neg_infinity: Pervasives.neg_infinity, - lnotn: Pervasives.lnotn, max_float: Pervasives.max_float, min_float: Pervasives.min_float, epsilon_float: Pervasives.epsilon_float, @@ -121,7 +120,6 @@ var U = { lnot: Pervasives.lnot, infinity: Pervasives.infinity, neg_infinity: Pervasives.neg_infinity, - lnotn: Pervasives.lnotn, max_float: Pervasives.max_float, min_float: Pervasives.min_float, epsilon_float: Pervasives.epsilon_float, diff --git a/jscomp/test/test_pervasives3.js b/jscomp/test/test_pervasives3.js index cd12bb69d0..c85f0668ad 100644 --- a/jscomp/test/test_pervasives3.js +++ b/jscomp/test/test_pervasives3.js @@ -19,7 +19,6 @@ var Pervasives$1 = { lnot: Pervasives.lnot, infinity: Pervasives.infinity, neg_infinity: Pervasives.neg_infinity, - lnotn: Pervasives.lnotn, max_float: Pervasives.max_float, min_float: Pervasives.min_float, epsilon_float: Pervasives.epsilon_float, diff --git a/lib/es6/pervasives.js b/lib/es6/pervasives.js index 2391612faf..8d9f304b4f 100644 --- a/lib/es6/pervasives.js +++ b/lib/es6/pervasives.js @@ -61,10 +61,6 @@ function classify_float(x) { } } -function lnotn(x) { - return x ^ -1n; -} - function char_of_int(n) { if (n < 0 || n > 255) { throw { @@ -249,7 +245,6 @@ export { lnot , infinity , neg_infinity , - lnotn , max_float , min_float , epsilon_float , diff --git a/lib/es6/pervasivesU.js b/lib/es6/pervasivesU.js index 1a3cd4d4c8..66770b5ddb 100644 --- a/lib/es6/pervasivesU.js +++ b/lib/es6/pervasivesU.js @@ -60,10 +60,6 @@ function classify_float(x) { } } -function lnotn(x) { - return x ^ -1n; -} - function char_of_int(n) { if (n < 0 || n > 255) { throw { @@ -248,7 +244,6 @@ export { lnot , infinity , neg_infinity , - lnotn , max_float , min_float , epsilon_float , diff --git a/lib/js/pervasives.js b/lib/js/pervasives.js index 6fcc1ac898..efcf4fb70d 100644 --- a/lib/js/pervasives.js +++ b/lib/js/pervasives.js @@ -61,10 +61,6 @@ function classify_float(x) { } } -function lnotn(x) { - return x ^ -1n; -} - function char_of_int(n) { if (n < 0 || n > 255) { throw { @@ -248,7 +244,6 @@ exports.min_int = min_int; exports.lnot = lnot; exports.infinity = infinity; exports.neg_infinity = neg_infinity; -exports.lnotn = lnotn; exports.max_float = max_float; exports.min_float = min_float; exports.epsilon_float = epsilon_float; diff --git a/lib/js/pervasivesU.js b/lib/js/pervasivesU.js index 766d39ff35..31c6560d8a 100644 --- a/lib/js/pervasivesU.js +++ b/lib/js/pervasivesU.js @@ -60,10 +60,6 @@ function classify_float(x) { } } -function lnotn(x) { - return x ^ -1n; -} - function char_of_int(n) { if (n < 0 || n > 255) { throw { @@ -247,7 +243,6 @@ exports.min_int = min_int; exports.lnot = lnot; exports.infinity = infinity; exports.neg_infinity = neg_infinity; -exports.lnotn = lnotn; exports.max_float = max_float; exports.min_float = min_float; exports.epsilon_float = epsilon_float; From fc1ea04b3390783f647d8dd99f748de29fc4a6ca Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 22 Mar 2024 03:13:22 +0900 Subject: [PATCH 27/45] rebase clean up --- jscomp/test/build.ninja | 2 +- jscomp/test/ocaml_re_test.js | 829 ----------------------------------- 2 files changed, 1 insertion(+), 830 deletions(-) diff --git a/jscomp/test/build.ninja b/jscomp/test/build.ninja index 7c8864c2d6..ac3f839fe2 100644 --- a/jscomp/test/build.ninja +++ b/jscomp/test/build.ninja @@ -725,4 +725,4 @@ o test/update_record_test.cmi test/update_record_test.cmj : cc test/update_recor o test/variant.cmi test/variant.cmj : cc test/variant.res | $bsc $stdlib runtime o test/variantsMatching.cmi test/variantsMatching.cmj : cc test/variantsMatching.res | $bsc $stdlib runtime o test/webpack_config.cmi test/webpack_config.cmj : cc test/webpack_config.res | $bsc $stdlib runtime -o test : phony test/406_primitive_test.cmi test/406_primitive_test.cmj test/AsInUncurriedExternals.cmi test/AsInUncurriedExternals.cmj test/Coercion.cmi test/Coercion.cmj test/DerivingAccessorsCurried.cmi test/DerivingAccessorsCurried.cmj test/DerivingAccessorsUncurried.cmi test/DerivingAccessorsUncurried.cmj test/DotDotDot.cmi test/DotDotDot.cmj test/EmptyRecord.cmi test/EmptyRecord.cmj test/FFI.cmi test/FFI.cmj test/Import.cmi test/Import.cmj test/ImportAttributes.cmi test/ImportAttributes.cmj test/RecordCoercion.cmi test/RecordCoercion.cmj test/RecordOrObject.cmi test/RecordOrObject.cmj test/SafePromises.cmi test/SafePromises.cmj test/UncurriedAlways.cmi test/UncurriedAlways.cmj test/UncurriedExternals.cmi test/UncurriedExternals.cmj test/UncurriedPervasives.cmi test/UncurriedPervasives.cmj test/UntaggedVariants.cmi test/UntaggedVariants.cmj test/VariantCoercion.cmi test/VariantCoercion.cmj test/VariantSpreads.cmi test/VariantSpreads.cmj test/a.cmi test/a.cmj test/a_filename_test.cmi test/a_filename_test.cmj test/a_list_test.cmi test/a_list_test.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/a_string_test.cmi test/a_string_test.cmj test/abstract_type.cmi test/abstract_type.cmj test/adt_optimize_test.cmi test/adt_optimize_test.cmj test/alias_default_value_test.cmi test/alias_default_value_test.cmj test/alias_test.cmi test/alias_test.cmj test/and_or_tailcall_test.cmi test/and_or_tailcall_test.cmj test/argv_test.cmi test/argv_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_lexer.cmi test/arith_lexer.cmj test/arith_parser.cmi test/arith_parser.cmj test/arith_syntax.cmi test/arith_syntax.cmj test/arity.cmi test/arity.cmj test/arity_deopt.cmi test/arity_deopt.cmj test/arity_infer.cmi test/arity_infer.cmj test/array_data_util.cmi test/array_data_util.cmj test/array_safe_get.cmi test/array_safe_get.cmj test/array_subtle_test.cmi test/array_subtle_test.cmj test/array_test.cmi test/array_test.cmj test/as_inline_record_test.cmi test/as_inline_record_test.cmj test/ast_abstract_test.cmi test/ast_abstract_test.cmj test/ast_mapper_unused_warning_test.cmi test/ast_mapper_unused_warning_test.cmj test/async_await.cmi test/async_await.cmj test/async_ideas.cmi test/async_ideas.cmj test/async_inline.cmi test/async_inline.cmj test/async_inside_loop.cmi test/async_inside_loop.cmj test/attr_test.cmi test/attr_test.cmj test/b.cmi test/b.cmj test/bal_set_mini.cmi test/bal_set_mini.cmj test/bang_primitive.cmi test/bang_primitive.cmj test/basic_module_test.cmi test/basic_module_test.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj test/bench.cmi test/bench.cmj test/big_enum.cmi test/big_enum.cmj test/big_polyvar_test.cmi test/big_polyvar_test.cmj test/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_MapInt_test.cmi test/bs_MapInt_test.cmj test/bs_abstract_test.cmi test/bs_abstract_test.cmj test/bs_array_test.cmi test/bs_array_test.cmj test/bs_auto_uncurry.cmi test/bs_auto_uncurry.cmj test/bs_auto_uncurry_test.cmi test/bs_auto_uncurry_test.cmj test/bs_float_test.cmi test/bs_float_test.cmj test/bs_hashmap_test.cmi test/bs_hashmap_test.cmj test/bs_hashset_int_test.cmi test/bs_hashset_int_test.cmj test/bs_hashtbl_string_test.cmi test/bs_hashtbl_string_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_int_test.cmi test/bs_int_test.cmj test/bs_list_test.cmi test/bs_list_test.cmj test/bs_map_set_dict_test.cmi test/bs_map_set_dict_test.cmj test/bs_map_test.cmi test/bs_map_test.cmj test/bs_min_max_test.cmi test/bs_min_max_test.cmj test/bs_mutable_set_test.cmi test/bs_mutable_set_test.cmj test/bs_poly_map_test.cmi test/bs_poly_map_test.cmj test/bs_poly_mutable_map_test.cmi test/bs_poly_mutable_map_test.cmj test/bs_poly_mutable_set_test.cmi test/bs_poly_mutable_set_test.cmj test/bs_poly_set_test.cmi test/bs_poly_set_test.cmj test/bs_qualified.cmi test/bs_qualified.cmj test/bs_queue_test.cmi test/bs_queue_test.cmj test/bs_rbset_int_bench.cmi test/bs_rbset_int_bench.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_bench.cmi test/bs_set_bench.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_sort_test.cmi test/bs_sort_test.cmj test/bs_splice_partial.cmi test/bs_splice_partial.cmj test/bs_stack_test.cmi test/bs_stack_test.cmj test/bs_string_test.cmi test/bs_string_test.cmj test/bs_unwrap_test.cmi test/bs_unwrap_test.cmj test/buffer_test.cmi test/buffer_test.cmj test/bytes_split_gpr_743_test.cmi test/bytes_split_gpr_743_test.cmj test/caml_compare_bigint_test.cmi test/caml_compare_bigint_test.cmj test/caml_compare_test.cmi test/caml_compare_test.cmj test/caml_format_test.cmi test/caml_format_test.cmj test/chain_code_test.cmi test/chain_code_test.cmj test/chn_test.cmi test/chn_test.cmj test/class_type_ffi_test.cmi test/class_type_ffi_test.cmj test/coercion_module_alias_test.cmi test/coercion_module_alias_test.cmj test/compare_test.cmi test/compare_test.cmj test/complete_parmatch_test.cmi test/complete_parmatch_test.cmj test/complex_if_test.cmi test/complex_if_test.cmj test/complex_test.cmi test/complex_test.cmj test/complex_while_loop.cmi test/complex_while_loop.cmj test/condition_compilation_test.cmi test/condition_compilation_test.cmj test/config1_test.cmi test/config1_test.cmj test/console_log_test.cmi test/console_log_test.cmj test/const_block_test.cmi test/const_block_test.cmj test/const_defs.cmi test/const_defs.cmj test/const_defs_test.cmi test/const_defs_test.cmj test/const_test.cmi test/const_test.cmj test/cont_int_fold_test.cmi test/cont_int_fold_test.cmj test/cps_test.cmi test/cps_test.cmj test/cross_module_inline_test.cmi test/cross_module_inline_test.cmj test/custom_error_test.cmi test/custom_error_test.cmj test/debug_keep_test.cmi test/debug_keep_test.cmj test/debug_mode_value.cmi test/debug_mode_value.cmj test/debug_tmp.cmi test/debug_tmp.cmj test/debugger_test.cmi test/debugger_test.cmj test/default_export_test.cmi test/default_export_test.cmj test/defunctor_make_test.cmi test/defunctor_make_test.cmj test/demo_int_map.cmi test/demo_int_map.cmj test/demo_page.cmi test/demo_page.cmj test/demo_pipe.cmi test/demo_pipe.cmj test/derive_dyntype.cmi test/derive_dyntype.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/derive_type_test.cmi test/derive_type_test.cmj test/digest_test.cmi test/digest_test.cmj test/directives.cmi test/directives.cmj test/div_by_zero_test.cmi test/div_by_zero_test.cmj test/dollar_escape_test.cmi test/dollar_escape_test.cmj test/earger_curry_test.cmi test/earger_curry_test.cmj test/effect.cmi test/effect.cmj test/epsilon_test.cmi test/epsilon_test.cmj test/equal_box_test.cmi test/equal_box_test.cmj test/equal_exception_test.cmi test/equal_exception_test.cmj test/equal_test.cmi test/equal_test.cmj test/es6_export.cmi test/es6_export.cmj test/es6_import.cmi test/es6_import.cmj test/es6_module_test.cmi test/es6_module_test.cmj test/escape_esmodule.cmi test/escape_esmodule.cmj test/esmodule_ref.cmi test/esmodule_ref.cmj test/event_ffi.cmi test/event_ffi.cmj test/exception_alias.cmi test/exception_alias.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebound_err_test.cmi test/exception_rebound_err_test.cmj test/exception_value_test.cmi test/exception_value_test.cmj test/exponentiation_precedence_test.cmi test/exponentiation_precedence_test.cmj test/export_keyword.cmi test/export_keyword.cmj test/ext_array_test.cmi test/ext_array_test.cmj test/ext_bytes_test.cmi test/ext_bytes_test.cmj test/ext_filename_test.cmi test/ext_filename_test.cmj test/ext_list_test.cmi test/ext_list_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/ext_string_test.cmi test/ext_string_test.cmj test/ext_sys_test.cmi test/ext_sys_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_polyfill_test.cmi test/external_polyfill_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/fail_comp.cmi test/fail_comp.cmj test/ffi_arity_test.cmi test/ffi_arity_test.cmj test/ffi_array_test.cmi test/ffi_array_test.cmj test/ffi_js_test.cmi test/ffi_js_test.cmj test/ffi_splice_test.cmi test/ffi_splice_test.cmj test/ffi_test.cmi test/ffi_test.cmj test/fib.cmi test/fib.cmj test/flattern_order_test.cmi test/flattern_order_test.cmj test/flexible_array_test.cmi test/flexible_array_test.cmj test/float_array.cmi test/float_array.cmj test/float_of_bits_test.cmi test/float_of_bits_test.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/floatarray_test.cmi test/floatarray_test.cmj test/for_loop_test.cmi test/for_loop_test.cmj test/for_side_effect_test.cmi test/for_side_effect_test.cmj test/format_regression.cmi test/format_regression.cmj test/format_test.cmi test/format_test.cmj test/fun_pattern_match.cmi test/fun_pattern_match.cmj test/functor_app_test.cmi test/functor_app_test.cmj test/functor_def.cmi test/functor_def.cmj test/functor_ffi.cmi test/functor_ffi.cmj test/functor_inst.cmi test/functor_inst.cmj test/functors.cmi test/functors.cmj test/gbk.cmi test/gbk.cmj test/genlex_test.cmi test/genlex_test.cmj test/gentTypeReTest.cmi test/gentTypeReTest.cmj test/global_exception_regression_test.cmi test/global_exception_regression_test.cmj test/global_mangles.cmi test/global_mangles.cmj test/global_module_alias_test.cmi test/global_module_alias_test.cmj test/google_closure_test.cmi test/google_closure_test.cmj test/gpr496_test.cmi test/gpr496_test.cmj test/gpr_1072.cmi test/gpr_1072.cmj test/gpr_1072_reg.cmi test/gpr_1072_reg.cmj test/gpr_1150.cmi test/gpr_1150.cmj test/gpr_1154_test.cmi test/gpr_1154_test.cmj test/gpr_1170.cmi test/gpr_1170.cmj test/gpr_1240_missing_unbox.cmi test/gpr_1240_missing_unbox.cmj test/gpr_1245_test.cmi test/gpr_1245_test.cmj test/gpr_1268.cmi test/gpr_1268.cmj test/gpr_1409_test.cmi test/gpr_1409_test.cmj test/gpr_1423_app_test.cmi test/gpr_1423_app_test.cmj test/gpr_1423_nav.cmi test/gpr_1423_nav.cmj test/gpr_1438.cmi test/gpr_1438.cmj test/gpr_1481.cmi test/gpr_1481.cmj test/gpr_1484.cmi test/gpr_1484.cmj test/gpr_1503_test.cmi test/gpr_1503_test.cmj test/gpr_1539_test.cmi test/gpr_1539_test.cmj test/gpr_1658_test.cmi test/gpr_1658_test.cmj test/gpr_1667_test.cmi test/gpr_1667_test.cmj test/gpr_1692_test.cmi test/gpr_1692_test.cmj test/gpr_1698_test.cmi test/gpr_1698_test.cmj test/gpr_1701_test.cmi test/gpr_1701_test.cmj test/gpr_1716_test.cmi test/gpr_1716_test.cmj test/gpr_1717_test.cmi test/gpr_1717_test.cmj test/gpr_1728_test.cmi test/gpr_1728_test.cmj test/gpr_1749_test.cmi test/gpr_1749_test.cmj test/gpr_1759_test.cmi test/gpr_1759_test.cmj test/gpr_1760_test.cmi test/gpr_1760_test.cmj test/gpr_1762_test.cmi test/gpr_1762_test.cmj test/gpr_1817_test.cmi test/gpr_1817_test.cmj test/gpr_1822_test.cmi test/gpr_1822_test.cmj test/gpr_1891_test.cmi test/gpr_1891_test.cmj test/gpr_1943_test.cmi test/gpr_1943_test.cmj test/gpr_1946_test.cmi test/gpr_1946_test.cmj test/gpr_2316_test.cmi test/gpr_2316_test.cmj test/gpr_2352_test.cmi test/gpr_2352_test.cmj test/gpr_2413_test.cmi test/gpr_2413_test.cmj test/gpr_2474.cmi test/gpr_2474.cmj test/gpr_2487.cmi test/gpr_2487.cmj test/gpr_2503_test.cmi test/gpr_2503_test.cmj test/gpr_2608_test.cmi test/gpr_2608_test.cmj test/gpr_2614_test.cmi test/gpr_2614_test.cmj test/gpr_2633_test.cmi test/gpr_2633_test.cmj test/gpr_2642_test.cmi test/gpr_2642_test.cmj test/gpr_2682_test.cmi test/gpr_2682_test.cmj test/gpr_2700_test.cmi test/gpr_2700_test.cmj test/gpr_2731_test.cmi test/gpr_2731_test.cmj test/gpr_2789_test.cmi test/gpr_2789_test.cmj test/gpr_2931_test.cmi test/gpr_2931_test.cmj test/gpr_3142_test.cmi test/gpr_3142_test.cmj test/gpr_3154_test.cmi test/gpr_3154_test.cmj test/gpr_3209_test.cmi test/gpr_3209_test.cmj test/gpr_3492_test.cmi test/gpr_3492_test.cmj test/gpr_3519_jsx_test.cmi test/gpr_3519_jsx_test.cmj test/gpr_3519_test.cmi test/gpr_3519_test.cmj test/gpr_3536_test.cmi test/gpr_3536_test.cmj test/gpr_3546_test.cmi test/gpr_3546_test.cmj test/gpr_3548_test.cmi test/gpr_3548_test.cmj test/gpr_3549_test.cmi test/gpr_3549_test.cmj test/gpr_3566_drive_test.cmi test/gpr_3566_drive_test.cmj test/gpr_3566_test.cmi test/gpr_3566_test.cmj test/gpr_3595_test.cmi test/gpr_3595_test.cmj test/gpr_3609_test.cmi test/gpr_3609_test.cmj test/gpr_3697_test.cmi test/gpr_3697_test.cmj test/gpr_373_test.cmi test/gpr_373_test.cmj test/gpr_3770_test.cmi test/gpr_3770_test.cmj test/gpr_3852_alias.cmi test/gpr_3852_alias.cmj test/gpr_3852_alias_reify.cmi test/gpr_3852_alias_reify.cmj test/gpr_3852_effect.cmi test/gpr_3852_effect.cmj test/gpr_3865.cmi test/gpr_3865.cmj test/gpr_3865_bar.cmi test/gpr_3865_bar.cmj test/gpr_3865_foo.cmi test/gpr_3865_foo.cmj test/gpr_3875_test.cmi test/gpr_3875_test.cmj test/gpr_3877_test.cmi test/gpr_3877_test.cmj test/gpr_3895_test.cmi test/gpr_3895_test.cmj test/gpr_3897_test.cmi test/gpr_3897_test.cmj test/gpr_3931_test.cmi test/gpr_3931_test.cmj test/gpr_3980_test.cmi test/gpr_3980_test.cmj test/gpr_4025_test.cmi test/gpr_4025_test.cmj test/gpr_405_test.cmi test/gpr_405_test.cmj test/gpr_4069_test.cmi test/gpr_4069_test.cmj test/gpr_4265_test.cmi test/gpr_4265_test.cmj test/gpr_4274_test.cmi test/gpr_4274_test.cmj test/gpr_4280_test.cmi test/gpr_4280_test.cmj test/gpr_4407_test.cmi test/gpr_4407_test.cmj test/gpr_441.cmi test/gpr_441.cmj test/gpr_4442_test.cmi test/gpr_4442_test.cmj test/gpr_4491_test.cmi test/gpr_4491_test.cmj test/gpr_4494_test.cmi test/gpr_4494_test.cmj test/gpr_4519_test.cmi test/gpr_4519_test.cmj test/gpr_459_test.cmi test/gpr_459_test.cmj test/gpr_4632.cmi test/gpr_4632.cmj test/gpr_4639_test.cmi test/gpr_4639_test.cmj test/gpr_4900_test.cmi test/gpr_4900_test.cmj test/gpr_4924_test.cmi test/gpr_4924_test.cmj test/gpr_4931.cmi test/gpr_4931.cmj test/gpr_4931_allow.cmi test/gpr_4931_allow.cmj test/gpr_5071_test.cmi test/gpr_5071_test.cmj test/gpr_5169_test.cmi test/gpr_5169_test.cmj test/gpr_5218_test.cmi test/gpr_5218_test.cmj test/gpr_5280_optimize_test.cmi test/gpr_5280_optimize_test.cmj test/gpr_5312.cmi test/gpr_5312.cmj test/gpr_5557.cmi test/gpr_5557.cmj test/gpr_5753.cmi test/gpr_5753.cmj test/gpr_658.cmi test/gpr_658.cmj test/gpr_858_test.cmi test/gpr_858_test.cmj test/gpr_858_unit2_test.cmi test/gpr_858_unit2_test.cmj test/gpr_904_test.cmi test/gpr_904_test.cmj test/gpr_974_test.cmi test/gpr_974_test.cmj test/gpr_977_test.cmi test/gpr_977_test.cmj test/gpr_return_type_unused_attribute.cmi test/gpr_return_type_unused_attribute.cmj test/gray_code_test.cmi test/gray_code_test.cmj test/guide_for_ext.cmi test/guide_for_ext.cmj test/hamming_test.cmi test/hamming_test.cmj test/hash_collision_test.cmi test/hash_collision_test.cmj test/hash_sugar_desugar.cmi test/hash_sugar_desugar.cmj test/hash_test.cmi test/hash_test.cmj test/hashtbl_test.cmi test/hashtbl_test.cmj test/hello.foo.cmi test/hello.foo.cmj test/hello_res.cmi test/hello_res.cmj test/ignore_test.cmi test/ignore_test.cmj test/imm_map_bench.cmi test/imm_map_bench.cmj test/import2.cmi test/import2.cmj test/import_external.cmi test/import_external.cmj test/import_side_effect.cmi test/import_side_effect.cmj test/import_side_effect_free.cmi test/import_side_effect_free.cmj test/include_side_effect.cmi test/include_side_effect.cmj test/include_side_effect_free.cmi test/include_side_effect_free.cmj test/incomplete_toplevel_test.cmi test/incomplete_toplevel_test.cmj test/infer_type_test.cmi test/infer_type_test.cmj test/inline_condition_with_pattern_matching.cmi test/inline_condition_with_pattern_matching.cmj test/inline_const.cmi test/inline_const.cmj test/inline_const_test.cmi test/inline_const_test.cmj test/inline_edge_cases.cmi test/inline_edge_cases.cmj test/inline_map2_test.cmi test/inline_map2_test.cmj test/inline_map_demo.cmi test/inline_map_demo.cmj test/inline_map_test.cmi test/inline_map_test.cmj test/inline_record_test.cmi test/inline_record_test.cmj test/inline_regression_test.cmi test/inline_regression_test.cmj test/inline_string_test.cmi test/inline_string_test.cmj test/inner_call.cmi test/inner_call.cmj test/inner_define.cmi test/inner_define.cmj test/inner_unused.cmi test/inner_unused.cmj test/installation_test.cmi test/installation_test.cmj test/int32_test.cmi test/int32_test.cmj test/int64_mul_div_test.cmi test/int64_mul_div_test.cmj test/int64_string_bench.cmi test/int64_string_bench.cmj test/int64_string_test.cmi test/int64_string_test.cmj test/int64_test.cmi test/int64_test.cmj test/int_hashtbl_test.cmi test/int_hashtbl_test.cmj test/int_map.cmi test/int_map.cmj test/int_overflow_test.cmi test/int_overflow_test.cmj test/int_poly_var.cmi test/int_poly_var.cmj test/int_switch_test.cmi test/int_switch_test.cmj test/internal_unused_test.cmi test/internal_unused_test.cmj test/io_test.cmi test/io_test.cmj test/js_array_test.cmi test/js_array_test.cmj test/js_bool_test.cmi test/js_bool_test.cmj test/js_cast_test.cmi test/js_cast_test.cmj test/js_date_test.cmi test/js_date_test.cmj test/js_dict_test.cmi test/js_dict_test.cmj test/js_exception_catch_test.cmi test/js_exception_catch_test.cmj test/js_float_test.cmi test/js_float_test.cmj test/js_global_test.cmi test/js_global_test.cmj test/js_int_test.cmi test/js_int_test.cmj test/js_json_test.cmi test/js_json_test.cmj test/js_list_test.cmi test/js_list_test.cmj test/js_math_test.cmi test/js_math_test.cmj test/js_null_test.cmi test/js_null_test.cmj test/js_null_undefined_test.cmi test/js_null_undefined_test.cmj test/js_nullable_test.cmi test/js_nullable_test.cmj test/js_obj_test.cmi test/js_obj_test.cmj test/js_option_test.cmi test/js_option_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_typed_array_test.cmi test/js_typed_array_test.cmj test/js_undefined_test.cmi test/js_undefined_test.cmj test/js_val.cmi test/js_val.cmj test/jsoo_400_test.cmi test/jsoo_400_test.cmj test/jsoo_485_test.cmi test/jsoo_485_test.cmj test/jsxv4_newtype.cmi test/jsxv4_newtype.cmj test/key_word_property.cmi test/key_word_property.cmj test/key_word_property2.cmi test/key_word_property2.cmj test/key_word_property_plus_test.cmi test/key_word_property_plus_test.cmj test/label_uncurry.cmi test/label_uncurry.cmj test/large_integer_pat.cmi test/large_integer_pat.cmj test/large_record_duplication_test.cmi test/large_record_duplication_test.cmj test/largest_int_flow.cmi test/largest_int_flow.cmj test/lazy_demo.cmi test/lazy_demo.cmj test/lazy_test.cmi test/lazy_test.cmj test/lib_js_test.cmi test/lib_js_test.cmj test/libarg_test.cmi test/libarg_test.cmj test/libqueue_test.cmi test/libqueue_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_stack.cmi test/list_stack.cmj test/list_test.cmi test/list_test.cmj test/local_exception_test.cmi test/local_exception_test.cmj test/loop_regression_test.cmi test/loop_regression_test.cmj test/loop_suites_test.cmi test/loop_suites_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/map_test.cmi test/map_test.cmj test/mario_game.cmi test/mario_game.cmj test/marshal.cmi test/marshal.cmj test/meth_annotation.cmi test/meth_annotation.cmj test/method_name_test.cmi test/method_name_test.cmj test/method_string_name.cmi test/method_string_name.cmj test/minimal_test.cmi test/minimal_test.cmj test/miss_colon_test.cmi test/miss_colon_test.cmj test/mock_mt.cmi test/mock_mt.cmj test/module_alias_test.cmi test/module_alias_test.cmj test/module_as_class_ffi.cmi test/module_as_class_ffi.cmj test/module_as_function.cmi test/module_as_function.cmj test/module_missing_conversion.cmi test/module_missing_conversion.cmj test/module_parameter_test.cmi test/module_parameter_test.cmj test/module_splice_test.cmi test/module_splice_test.cmj test/more_poly_variant_test.cmi test/more_poly_variant_test.cmj test/more_uncurry.cmi test/more_uncurry.cmj test/mpr_6033_test.cmi test/mpr_6033_test.cmj test/mt.cmi test/mt.cmj test/mt_global.cmi test/mt_global.cmj test/mutable_obj_test.cmi test/mutable_obj_test.cmj test/mutable_uncurry_test.cmi test/mutable_uncurry_test.cmj test/mutual_non_recursive_type.cmi test/mutual_non_recursive_type.cmj test/name_mangle_test.cmi test/name_mangle_test.cmj test/nested_include.cmi test/nested_include.cmj test/nested_module_alias.cmi test/nested_module_alias.cmj test/nested_obj_literal.cmi test/nested_obj_literal.cmj test/nested_obj_test.cmi test/nested_obj_test.cmj test/nested_pattern_match_test.cmi test/nested_pattern_match_test.cmj test/noassert.cmi test/noassert.cmj test/node_path_test.cmi test/node_path_test.cmj test/null_list_test.cmi test/null_list_test.cmj test/number_lexer.cmi test/number_lexer.cmj test/obj_literal_ppx.cmi test/obj_literal_ppx.cmj test/obj_literal_ppx_test.cmi test/obj_literal_ppx_test.cmj test/obj_magic_test.cmi test/obj_magic_test.cmj test/obj_type_test.cmi test/obj_type_test.cmj test/ocaml_re_test.cmi test/ocaml_re_test.cmj test/of_string_test.cmi test/of_string_test.cmj test/offset.cmi test/offset.cmj test/omit_trailing_undefined_in_external_calls.cmi test/omit_trailing_undefined_in_external_calls.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_record_none_test.cmi test/option_record_none_test.cmj test/option_repr_test.cmi test/option_repr_test.cmj test/optional_ffi_test.cmi test/optional_ffi_test.cmj test/optional_regression_test.cmi test/optional_regression_test.cmj test/pipe_send_readline.cmi test/pipe_send_readline.cmj test/pipe_syntax.cmi test/pipe_syntax.cmj test/poly_empty_array.cmi test/poly_empty_array.cmj test/poly_variant_test.cmi test/poly_variant_test.cmj test/polymorphic_raw_test.cmi test/polymorphic_raw_test.cmj test/polymorphism_test.cmi test/polymorphism_test.cmj test/polyvar_convert.cmi test/polyvar_convert.cmj test/polyvar_test.cmi test/polyvar_test.cmj test/ppx_apply_test.cmi test/ppx_apply_test.cmj test/pq_test.cmi test/pq_test.cmj test/pr6726.cmi test/pr6726.cmj test/pr_regression_test.cmi test/pr_regression_test.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/primitive_reg_test.cmi test/primitive_reg_test.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/queue_402.cmi test/queue_402.cmj test/queue_test.cmi test/queue_test.cmj test/random_test.cmi test/random_test.cmj test/raw_hash_tbl_bench.cmi test/raw_hash_tbl_bench.cmj test/raw_output_test.cmi test/raw_output_test.cmj test/raw_pure_test.cmi test/raw_pure_test.cmj test/rbset.cmi test/rbset.cmj test/react.cmi test/react.cmj test/reactDOMRe.cmi test/reactDOMRe.cmj test/reactDOMServerRe.cmi test/reactDOMServerRe.cmj test/reactEvent.cmi test/reactEvent.cmj test/reactTestUtils.cmi test/reactTestUtils.cmj test/reasonReact.cmi test/reasonReact.cmj test/reasonReactCompat.cmi test/reasonReactCompat.cmj test/reasonReactOptimizedCreateClass.cmi test/reasonReactOptimizedCreateClass.cmj test/reasonReactRouter.cmi test/reasonReactRouter.cmj test/rebind_module.cmi test/rebind_module.cmj test/rebind_module_test.cmi test/rebind_module_test.cmj test/rec_array_test.cmi test/rec_array_test.cmj test/rec_fun_test.cmi test/rec_fun_test.cmj test/rec_module_opt.cmi test/rec_module_opt.cmj test/rec_module_test.cmi test/rec_module_test.cmj test/recmodule.cmi test/recmodule.cmj test/record_debug_test.cmi test/record_debug_test.cmj test/record_extension_test.cmi test/record_extension_test.cmj test/record_name_test.cmi test/record_name_test.cmj test/record_regression.cmi test/record_regression.cmj test/record_type_spread.cmi test/record_type_spread.cmj test/record_with_test.cmi test/record_with_test.cmj test/recursive_module.cmi test/recursive_module.cmj test/recursive_module_test.cmi test/recursive_module_test.cmj test/recursive_react_component.cmi test/recursive_react_component.cmj test/recursive_records_test.cmi test/recursive_records_test.cmj test/recursive_unbound_module_test.cmi test/recursive_unbound_module_test.cmj test/regression_print.cmi test/regression_print.cmj test/relative_path.cmi test/relative_path.cmj test/res_debug.cmi test/res_debug.cmj test/return_check.cmi test/return_check.cmj test/runtime_encoding_test.cmi test/runtime_encoding_test.cmj test/set_annotation.cmi test/set_annotation.cmj test/set_gen.cmi test/set_gen.cmj test/sexp.cmi test/sexp.cmj test/sexpm.cmi test/sexpm.cmj test/sexpm_test.cmi test/sexpm_test.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect2.cmi test/side_effect2.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simple_derive_test.cmi test/simple_derive_test.cmj test/simple_derive_use.cmi test/simple_derive_use.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/single_module_alias.cmi test/single_module_alias.cmj test/singular_unit_test.cmi test/singular_unit_test.cmj test/small_inline_test.cmi test/small_inline_test.cmj test/splice_test.cmi test/splice_test.cmj test/stack_comp_test.cmi test/stack_comp_test.cmj test/stack_test.cmi test/stack_test.cmj test/stream_parser_test.cmi test/stream_parser_test.cmj test/string_bound_get_test.cmi test/string_bound_get_test.cmj test/string_constant_compare.cmi test/string_constant_compare.cmj test/string_get_set_test.cmi test/string_get_set_test.cmj test/string_runtime_test.cmi test/string_runtime_test.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_test.cmi test/string_test.cmj test/string_unicode_test.cmi test/string_unicode_test.cmj test/stringmatch_test.cmi test/stringmatch_test.cmj test/submodule.cmi test/submodule.cmj test/submodule_call.cmi test/submodule_call.cmj test/switch_case_test.cmi test/switch_case_test.cmj test/switch_string.cmi test/switch_string.cmj test/tagged_template_test.cmi test/tagged_template_test.cmj test/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test.cmi test/test.cmj test/test2.cmi test/test2.cmj test/test_alias.cmi test/test_alias.cmj test/test_ari.cmi test/test_ari.cmj test/test_array.cmi test/test_array.cmj test/test_array_append.cmi test/test_array_append.cmj test/test_array_primitive.cmi test/test_array_primitive.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_bug.cmi test/test_bug.cmj test/test_bytes.cmi test/test_bytes.cmj test/test_case_opt_collision.cmi test/test_case_opt_collision.cmj test/test_case_set.cmi test/test_case_set.cmj test/test_char.cmi test/test_char.cmj test/test_closure.cmi test/test_closure.cmj test/test_common.cmi test/test_common.cmj test/test_const_elim.cmi test/test_const_elim.cmj test/test_const_propogate.cmi test/test_const_propogate.cmj test/test_cpp.cmi test/test_cpp.cmj test/test_cps.cmi test/test_cps.cmj test/test_demo.cmi test/test_demo.cmj test/test_dup_param.cmi test/test_dup_param.cmj test/test_eq.cmi test/test_eq.cmj test/test_exception.cmi test/test_exception.cmj test/test_exception_escape.cmi test/test_exception_escape.cmj test/test_export2.cmi test/test_export2.cmj test/test_external.cmi test/test_external.cmj test/test_external_unit.cmi test/test_external_unit.cmj test/test_ffi.cmi test/test_ffi.cmj test/test_fib.cmi test/test_fib.cmj test/test_filename.cmi test/test_filename.cmj test/test_for_loop.cmi test/test_for_loop.cmj test/test_for_map.cmi test/test_for_map.cmj test/test_for_map2.cmi test/test_for_map2.cmj test/test_format.cmi test/test_format.cmj test/test_formatter.cmi test/test_formatter.cmj test/test_functor_dead_code.cmi test/test_functor_dead_code.cmj test/test_generative_module.cmi test/test_generative_module.cmj test/test_global_print.cmi test/test_global_print.cmj test/test_google_closure.cmi test/test_google_closure.cmj test/test_include.cmi test/test_include.cmj test/test_incomplete.cmi test/test_incomplete.cmj test/test_incr_ref.cmi test/test_incr_ref.cmj test/test_int_map_find.cmi test/test_int_map_find.cmj test/test_internalOO.cmi test/test_internalOO.cmj test/test_is_js.cmi test/test_is_js.cmj test/test_js_ffi.cmi test/test_js_ffi.cmj test/test_let.cmi test/test_let.cmj test/test_list.cmi test/test_list.cmj test/test_literal.cmi test/test_literal.cmj test/test_literals.cmi test/test_literals.cmj test/test_match_exception.cmi test/test_match_exception.cmj test/test_mutliple.cmi test/test_mutliple.cmj test/test_nat64.cmi test/test_nat64.cmj test/test_nested_let.cmi test/test_nested_let.cmj test/test_nested_print.cmi test/test_nested_print.cmj test/test_non_export.cmi test/test_non_export.cmj test/test_nullary.cmi test/test_nullary.cmj test/test_obj.cmi test/test_obj.cmj test/test_order.cmi test/test_order.cmj test/test_order_tailcall.cmi test/test_order_tailcall.cmj test/test_other_exn.cmi test/test_other_exn.cmj test/test_pack.cmi test/test_pack.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives2.cmi test/test_pervasives2.cmj test/test_pervasives3.cmi test/test_pervasives3.cmj test/test_primitive.cmi test/test_primitive.cmj test/test_ramification.cmi test/test_ramification.cmj test/test_react.cmi test/test_react.cmj test/test_react_case.cmi test/test_react_case.cmj test/test_regex.cmi test/test_regex.cmj test/test_runtime_encoding.cmi test/test_runtime_encoding.cmj test/test_scope.cmi test/test_scope.cmj test/test_seq.cmi test/test_seq.cmj test/test_set.cmi test/test_set.cmj test/test_side_effect_functor.cmi test/test_side_effect_functor.cmj test/test_simple_include.cmi test/test_simple_include.cmj test/test_simple_pattern_match.cmi test/test_simple_pattern_match.cmj test/test_simple_ref.cmi test/test_simple_ref.cmj test/test_simple_tailcall.cmi test/test_simple_tailcall.cmj test/test_small.cmi test/test_small.cmj test/test_sprintf.cmi test/test_sprintf.cmj test/test_stack.cmi test/test_stack.cmj test/test_static_catch_ident.cmi test/test_static_catch_ident.cmj test/test_string.cmi test/test_string.cmj test/test_string_case.cmi test/test_string_case.cmj test/test_string_const.cmi test/test_string_const.cmj test/test_string_map.cmi test/test_string_map.cmj test/test_string_switch.cmi test/test_string_switch.cmj test/test_switch.cmi test/test_switch.cmj test/test_trywith.cmi test/test_trywith.cmj test/test_tuple.cmi test/test_tuple.cmj test/test_tuple_destructring.cmi test/test_tuple_destructring.cmj test/test_type_based_arity.cmi test/test_type_based_arity.cmj test/test_u.cmi test/test_u.cmj test/test_unknown.cmi test/test_unknown.cmj test/test_unsafe_cmp.cmi test/test_unsafe_cmp.cmj test/test_unsafe_obj_ffi.cmi test/test_unsafe_obj_ffi.cmj test/test_unsafe_obj_ffi_ppx.cmi test/test_unsafe_obj_ffi_ppx.cmj test/test_unsupported_primitive.cmi test/test_unsupported_primitive.cmj test/test_while_closure.cmi test/test_while_closure.cmj test/test_while_side_effect.cmi test/test_while_side_effect.cmj test/test_zero_nullable.cmi test/test_zero_nullable.cmj test/then_mangle_test.cmi test/then_mangle_test.cmj test/ticker.cmi test/ticker.cmj test/to_string_test.cmi test/to_string_test.cmj test/topsort_test.cmi test/topsort_test.cmj test/tramp_fib.cmi test/tramp_fib.cmj test/tuple_alloc.cmi test/tuple_alloc.cmj test/type_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/unboxed_attribute.cmi test/unboxed_attribute.cmj test/unboxed_attribute_test.cmi test/unboxed_attribute_test.cmj test/unboxed_crash.cmi test/unboxed_crash.cmj test/unboxed_use_case.cmi test/unboxed_use_case.cmj test/uncurried_cast.cmi test/uncurried_cast.cmj test/uncurried_default.args.cmi test/uncurried_default.args.cmj test/uncurried_pipe.cmi test/uncurried_pipe.cmj test/uncurry_external_test.cmi test/uncurry_external_test.cmj test/uncurry_glob_test.cmi test/uncurry_glob_test.cmj test/uncurry_test.cmi test/uncurry_test.cmj test/undef_regression2_test.cmi test/undef_regression2_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/undefine_conditional.cmi test/undefine_conditional.cmj test/unicode_type_error.cmi test/unicode_type_error.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unitest_string.cmi test/unitest_string.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/update_record_test.cmi test/update_record_test.cmj test/variant.cmi test/variant.cmj test/variantsMatching.cmi test/variantsMatching.cmj test/webpack_config.cmi test/webpack_config.cmj +o test : phony test/406_primitive_test.cmi test/406_primitive_test.cmj test/AsInUncurriedExternals.cmi test/AsInUncurriedExternals.cmj test/Coercion.cmi test/Coercion.cmj test/DerivingAccessorsCurried.cmi test/DerivingAccessorsCurried.cmj test/DerivingAccessorsUncurried.cmi test/DerivingAccessorsUncurried.cmj test/DotDotDot.cmi test/DotDotDot.cmj test/EmptyRecord.cmi test/EmptyRecord.cmj test/FFI.cmi test/FFI.cmj test/Import.cmi test/Import.cmj test/ImportAttributes.cmi test/ImportAttributes.cmj test/RecordCoercion.cmi test/RecordCoercion.cmj test/RecordOrObject.cmi test/RecordOrObject.cmj test/SafePromises.cmi test/SafePromises.cmj test/UncurriedAlways.cmi test/UncurriedAlways.cmj test/UncurriedExternals.cmi test/UncurriedExternals.cmj test/UncurriedPervasives.cmi test/UncurriedPervasives.cmj test/UntaggedVariants.cmi test/UntaggedVariants.cmj test/VariantCoercion.cmi test/VariantCoercion.cmj test/VariantSpreads.cmi test/VariantSpreads.cmj test/a.cmi test/a.cmj test/a_filename_test.cmi test/a_filename_test.cmj test/a_list_test.cmi test/a_list_test.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/a_string_test.cmi test/a_string_test.cmj test/abstract_type.cmi test/abstract_type.cmj test/adt_optimize_test.cmi test/adt_optimize_test.cmj test/alias_default_value_test.cmi test/alias_default_value_test.cmj test/alias_test.cmi test/alias_test.cmj test/and_or_tailcall_test.cmi test/and_or_tailcall_test.cmj test/argv_test.cmi test/argv_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_lexer.cmi test/arith_lexer.cmj test/arith_parser.cmi test/arith_parser.cmj test/arith_syntax.cmi test/arith_syntax.cmj test/arity.cmi test/arity.cmj test/arity_deopt.cmi test/arity_deopt.cmj test/arity_infer.cmi test/arity_infer.cmj test/array_data_util.cmi test/array_data_util.cmj test/array_safe_get.cmi test/array_safe_get.cmj test/array_subtle_test.cmi test/array_subtle_test.cmj test/array_test.cmi test/array_test.cmj test/as_inline_record_test.cmi test/as_inline_record_test.cmj test/ast_abstract_test.cmi test/ast_abstract_test.cmj test/ast_mapper_unused_warning_test.cmi test/ast_mapper_unused_warning_test.cmj test/async_await.cmi test/async_await.cmj test/async_ideas.cmi test/async_ideas.cmj test/async_inline.cmi test/async_inline.cmj test/async_inside_loop.cmi test/async_inside_loop.cmj test/attr_test.cmi test/attr_test.cmj test/b.cmi test/b.cmj test/bal_set_mini.cmi test/bal_set_mini.cmj test/bang_primitive.cmi test/bang_primitive.cmj test/basic_module_test.cmi test/basic_module_test.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj test/bench.cmi test/bench.cmj test/big_enum.cmi test/big_enum.cmj test/big_polyvar_test.cmi test/big_polyvar_test.cmj test/bigint_test.cmi test/bigint_test.cmj test/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_MapInt_test.cmi test/bs_MapInt_test.cmj test/bs_abstract_test.cmi test/bs_abstract_test.cmj test/bs_array_test.cmi test/bs_array_test.cmj test/bs_auto_uncurry.cmi test/bs_auto_uncurry.cmj test/bs_auto_uncurry_test.cmi test/bs_auto_uncurry_test.cmj test/bs_float_test.cmi test/bs_float_test.cmj test/bs_hashmap_test.cmi test/bs_hashmap_test.cmj test/bs_hashset_int_test.cmi test/bs_hashset_int_test.cmj test/bs_hashtbl_string_test.cmi test/bs_hashtbl_string_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_int_test.cmi test/bs_int_test.cmj test/bs_list_test.cmi test/bs_list_test.cmj test/bs_map_set_dict_test.cmi test/bs_map_set_dict_test.cmj test/bs_map_test.cmi test/bs_map_test.cmj test/bs_min_max_test.cmi test/bs_min_max_test.cmj test/bs_mutable_set_test.cmi test/bs_mutable_set_test.cmj test/bs_poly_map_test.cmi test/bs_poly_map_test.cmj test/bs_poly_mutable_map_test.cmi test/bs_poly_mutable_map_test.cmj test/bs_poly_mutable_set_test.cmi test/bs_poly_mutable_set_test.cmj test/bs_poly_set_test.cmi test/bs_poly_set_test.cmj test/bs_qualified.cmi test/bs_qualified.cmj test/bs_queue_test.cmi test/bs_queue_test.cmj test/bs_rbset_int_bench.cmi test/bs_rbset_int_bench.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_bench.cmi test/bs_set_bench.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_sort_test.cmi test/bs_sort_test.cmj test/bs_splice_partial.cmi test/bs_splice_partial.cmj test/bs_stack_test.cmi test/bs_stack_test.cmj test/bs_string_test.cmi test/bs_string_test.cmj test/bs_unwrap_test.cmi test/bs_unwrap_test.cmj test/buffer_test.cmi test/buffer_test.cmj test/bytes_split_gpr_743_test.cmi test/bytes_split_gpr_743_test.cmj test/caml_compare_bigint_test.cmi test/caml_compare_bigint_test.cmj test/caml_compare_test.cmi test/caml_compare_test.cmj test/caml_format_test.cmi test/caml_format_test.cmj test/chain_code_test.cmi test/chain_code_test.cmj test/chn_test.cmi test/chn_test.cmj test/class_type_ffi_test.cmi test/class_type_ffi_test.cmj test/coercion_module_alias_test.cmi test/coercion_module_alias_test.cmj test/compare_test.cmi test/compare_test.cmj test/complete_parmatch_test.cmi test/complete_parmatch_test.cmj test/complex_if_test.cmi test/complex_if_test.cmj test/complex_test.cmi test/complex_test.cmj test/complex_while_loop.cmi test/complex_while_loop.cmj test/condition_compilation_test.cmi test/condition_compilation_test.cmj test/config1_test.cmi test/config1_test.cmj test/console_log_test.cmi test/console_log_test.cmj test/const_block_test.cmi test/const_block_test.cmj test/const_defs.cmi test/const_defs.cmj test/const_defs_test.cmi test/const_defs_test.cmj test/const_test.cmi test/const_test.cmj test/cont_int_fold_test.cmi test/cont_int_fold_test.cmj test/cps_test.cmi test/cps_test.cmj test/cross_module_inline_test.cmi test/cross_module_inline_test.cmj test/custom_error_test.cmi test/custom_error_test.cmj test/debug_keep_test.cmi test/debug_keep_test.cmj test/debug_mode_value.cmi test/debug_mode_value.cmj test/debug_tmp.cmi test/debug_tmp.cmj test/debugger_test.cmi test/debugger_test.cmj test/default_export_test.cmi test/default_export_test.cmj test/defunctor_make_test.cmi test/defunctor_make_test.cmj test/demo_int_map.cmi test/demo_int_map.cmj test/demo_page.cmi test/demo_page.cmj test/demo_pipe.cmi test/demo_pipe.cmj test/derive_dyntype.cmi test/derive_dyntype.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/derive_type_test.cmi test/derive_type_test.cmj test/digest_test.cmi test/digest_test.cmj test/directives.cmi test/directives.cmj test/div_by_zero_test.cmi test/div_by_zero_test.cmj test/dollar_escape_test.cmi test/dollar_escape_test.cmj test/earger_curry_test.cmi test/earger_curry_test.cmj test/effect.cmi test/effect.cmj test/epsilon_test.cmi test/epsilon_test.cmj test/equal_box_test.cmi test/equal_box_test.cmj test/equal_exception_test.cmi test/equal_exception_test.cmj test/equal_test.cmi test/equal_test.cmj test/es6_export.cmi test/es6_export.cmj test/es6_import.cmi test/es6_import.cmj test/es6_module_test.cmi test/es6_module_test.cmj test/escape_esmodule.cmi test/escape_esmodule.cmj test/esmodule_ref.cmi test/esmodule_ref.cmj test/event_ffi.cmi test/event_ffi.cmj test/exception_alias.cmi test/exception_alias.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebound_err_test.cmi test/exception_rebound_err_test.cmj test/exception_value_test.cmi test/exception_value_test.cmj test/exponentiation_precedence_test.cmi test/exponentiation_precedence_test.cmj test/export_keyword.cmi test/export_keyword.cmj test/ext_array_test.cmi test/ext_array_test.cmj test/ext_bytes_test.cmi test/ext_bytes_test.cmj test/ext_filename_test.cmi test/ext_filename_test.cmj test/ext_list_test.cmi test/ext_list_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/ext_string_test.cmi test/ext_string_test.cmj test/ext_sys_test.cmi test/ext_sys_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_polyfill_test.cmi test/external_polyfill_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/fail_comp.cmi test/fail_comp.cmj test/ffi_arity_test.cmi test/ffi_arity_test.cmj test/ffi_array_test.cmi test/ffi_array_test.cmj test/ffi_js_test.cmi test/ffi_js_test.cmj test/ffi_splice_test.cmi test/ffi_splice_test.cmj test/ffi_test.cmi test/ffi_test.cmj test/fib.cmi test/fib.cmj test/flattern_order_test.cmi test/flattern_order_test.cmj test/flexible_array_test.cmi test/flexible_array_test.cmj test/float_array.cmi test/float_array.cmj test/float_of_bits_test.cmi test/float_of_bits_test.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/floatarray_test.cmi test/floatarray_test.cmj test/for_loop_test.cmi test/for_loop_test.cmj test/for_side_effect_test.cmi test/for_side_effect_test.cmj test/format_regression.cmi test/format_regression.cmj test/format_test.cmi test/format_test.cmj test/fun_pattern_match.cmi test/fun_pattern_match.cmj test/functor_app_test.cmi test/functor_app_test.cmj test/functor_def.cmi test/functor_def.cmj test/functor_ffi.cmi test/functor_ffi.cmj test/functor_inst.cmi test/functor_inst.cmj test/functors.cmi test/functors.cmj test/gbk.cmi test/gbk.cmj test/genlex_test.cmi test/genlex_test.cmj test/gentTypeReTest.cmi test/gentTypeReTest.cmj test/global_exception_regression_test.cmi test/global_exception_regression_test.cmj test/global_mangles.cmi test/global_mangles.cmj test/global_module_alias_test.cmi test/global_module_alias_test.cmj test/google_closure_test.cmi test/google_closure_test.cmj test/gpr496_test.cmi test/gpr496_test.cmj test/gpr_1072.cmi test/gpr_1072.cmj test/gpr_1072_reg.cmi test/gpr_1072_reg.cmj test/gpr_1150.cmi test/gpr_1150.cmj test/gpr_1154_test.cmi test/gpr_1154_test.cmj test/gpr_1170.cmi test/gpr_1170.cmj test/gpr_1240_missing_unbox.cmi test/gpr_1240_missing_unbox.cmj test/gpr_1245_test.cmi test/gpr_1245_test.cmj test/gpr_1268.cmi test/gpr_1268.cmj test/gpr_1409_test.cmi test/gpr_1409_test.cmj test/gpr_1423_app_test.cmi test/gpr_1423_app_test.cmj test/gpr_1423_nav.cmi test/gpr_1423_nav.cmj test/gpr_1438.cmi test/gpr_1438.cmj test/gpr_1481.cmi test/gpr_1481.cmj test/gpr_1484.cmi test/gpr_1484.cmj test/gpr_1503_test.cmi test/gpr_1503_test.cmj test/gpr_1539_test.cmi test/gpr_1539_test.cmj test/gpr_1658_test.cmi test/gpr_1658_test.cmj test/gpr_1667_test.cmi test/gpr_1667_test.cmj test/gpr_1692_test.cmi test/gpr_1692_test.cmj test/gpr_1698_test.cmi test/gpr_1698_test.cmj test/gpr_1701_test.cmi test/gpr_1701_test.cmj test/gpr_1716_test.cmi test/gpr_1716_test.cmj test/gpr_1717_test.cmi test/gpr_1717_test.cmj test/gpr_1728_test.cmi test/gpr_1728_test.cmj test/gpr_1749_test.cmi test/gpr_1749_test.cmj test/gpr_1759_test.cmi test/gpr_1759_test.cmj test/gpr_1760_test.cmi test/gpr_1760_test.cmj test/gpr_1762_test.cmi test/gpr_1762_test.cmj test/gpr_1817_test.cmi test/gpr_1817_test.cmj test/gpr_1822_test.cmi test/gpr_1822_test.cmj test/gpr_1891_test.cmi test/gpr_1891_test.cmj test/gpr_1943_test.cmi test/gpr_1943_test.cmj test/gpr_1946_test.cmi test/gpr_1946_test.cmj test/gpr_2316_test.cmi test/gpr_2316_test.cmj test/gpr_2352_test.cmi test/gpr_2352_test.cmj test/gpr_2413_test.cmi test/gpr_2413_test.cmj test/gpr_2474.cmi test/gpr_2474.cmj test/gpr_2487.cmi test/gpr_2487.cmj test/gpr_2503_test.cmi test/gpr_2503_test.cmj test/gpr_2608_test.cmi test/gpr_2608_test.cmj test/gpr_2614_test.cmi test/gpr_2614_test.cmj test/gpr_2633_test.cmi test/gpr_2633_test.cmj test/gpr_2642_test.cmi test/gpr_2642_test.cmj test/gpr_2682_test.cmi test/gpr_2682_test.cmj test/gpr_2700_test.cmi test/gpr_2700_test.cmj test/gpr_2731_test.cmi test/gpr_2731_test.cmj test/gpr_2789_test.cmi test/gpr_2789_test.cmj test/gpr_2931_test.cmi test/gpr_2931_test.cmj test/gpr_3142_test.cmi test/gpr_3142_test.cmj test/gpr_3154_test.cmi test/gpr_3154_test.cmj test/gpr_3209_test.cmi test/gpr_3209_test.cmj test/gpr_3492_test.cmi test/gpr_3492_test.cmj test/gpr_3519_jsx_test.cmi test/gpr_3519_jsx_test.cmj test/gpr_3519_test.cmi test/gpr_3519_test.cmj test/gpr_3536_test.cmi test/gpr_3536_test.cmj test/gpr_3546_test.cmi test/gpr_3546_test.cmj test/gpr_3548_test.cmi test/gpr_3548_test.cmj test/gpr_3549_test.cmi test/gpr_3549_test.cmj test/gpr_3566_drive_test.cmi test/gpr_3566_drive_test.cmj test/gpr_3566_test.cmi test/gpr_3566_test.cmj test/gpr_3595_test.cmi test/gpr_3595_test.cmj test/gpr_3609_test.cmi test/gpr_3609_test.cmj test/gpr_3697_test.cmi test/gpr_3697_test.cmj test/gpr_373_test.cmi test/gpr_373_test.cmj test/gpr_3770_test.cmi test/gpr_3770_test.cmj test/gpr_3852_alias.cmi test/gpr_3852_alias.cmj test/gpr_3852_alias_reify.cmi test/gpr_3852_alias_reify.cmj test/gpr_3852_effect.cmi test/gpr_3852_effect.cmj test/gpr_3865.cmi test/gpr_3865.cmj test/gpr_3865_bar.cmi test/gpr_3865_bar.cmj test/gpr_3865_foo.cmi test/gpr_3865_foo.cmj test/gpr_3875_test.cmi test/gpr_3875_test.cmj test/gpr_3877_test.cmi test/gpr_3877_test.cmj test/gpr_3895_test.cmi test/gpr_3895_test.cmj test/gpr_3897_test.cmi test/gpr_3897_test.cmj test/gpr_3931_test.cmi test/gpr_3931_test.cmj test/gpr_3980_test.cmi test/gpr_3980_test.cmj test/gpr_4025_test.cmi test/gpr_4025_test.cmj test/gpr_405_test.cmi test/gpr_405_test.cmj test/gpr_4069_test.cmi test/gpr_4069_test.cmj test/gpr_4265_test.cmi test/gpr_4265_test.cmj test/gpr_4274_test.cmi test/gpr_4274_test.cmj test/gpr_4280_test.cmi test/gpr_4280_test.cmj test/gpr_4407_test.cmi test/gpr_4407_test.cmj test/gpr_441.cmi test/gpr_441.cmj test/gpr_4442_test.cmi test/gpr_4442_test.cmj test/gpr_4491_test.cmi test/gpr_4491_test.cmj test/gpr_4494_test.cmi test/gpr_4494_test.cmj test/gpr_4519_test.cmi test/gpr_4519_test.cmj test/gpr_459_test.cmi test/gpr_459_test.cmj test/gpr_4632.cmi test/gpr_4632.cmj test/gpr_4639_test.cmi test/gpr_4639_test.cmj test/gpr_4900_test.cmi test/gpr_4900_test.cmj test/gpr_4924_test.cmi test/gpr_4924_test.cmj test/gpr_4931.cmi test/gpr_4931.cmj test/gpr_4931_allow.cmi test/gpr_4931_allow.cmj test/gpr_5071_test.cmi test/gpr_5071_test.cmj test/gpr_5169_test.cmi test/gpr_5169_test.cmj test/gpr_5218_test.cmi test/gpr_5218_test.cmj test/gpr_5280_optimize_test.cmi test/gpr_5280_optimize_test.cmj test/gpr_5312.cmi test/gpr_5312.cmj test/gpr_5557.cmi test/gpr_5557.cmj test/gpr_5753.cmi test/gpr_5753.cmj test/gpr_658.cmi test/gpr_658.cmj test/gpr_858_test.cmi test/gpr_858_test.cmj test/gpr_858_unit2_test.cmi test/gpr_858_unit2_test.cmj test/gpr_904_test.cmi test/gpr_904_test.cmj test/gpr_974_test.cmi test/gpr_974_test.cmj test/gpr_977_test.cmi test/gpr_977_test.cmj test/gpr_return_type_unused_attribute.cmi test/gpr_return_type_unused_attribute.cmj test/gray_code_test.cmi test/gray_code_test.cmj test/guide_for_ext.cmi test/guide_for_ext.cmj test/hamming_test.cmi test/hamming_test.cmj test/hash_collision_test.cmi test/hash_collision_test.cmj test/hash_sugar_desugar.cmi test/hash_sugar_desugar.cmj test/hash_test.cmi test/hash_test.cmj test/hashtbl_test.cmi test/hashtbl_test.cmj test/hello.foo.cmi test/hello.foo.cmj test/hello_res.cmi test/hello_res.cmj test/ignore_test.cmi test/ignore_test.cmj test/imm_map_bench.cmi test/imm_map_bench.cmj test/import2.cmi test/import2.cmj test/import_external.cmi test/import_external.cmj test/import_side_effect.cmi test/import_side_effect.cmj test/import_side_effect_free.cmi test/import_side_effect_free.cmj test/include_side_effect.cmi test/include_side_effect.cmj test/include_side_effect_free.cmi test/include_side_effect_free.cmj test/incomplete_toplevel_test.cmi test/incomplete_toplevel_test.cmj test/infer_type_test.cmi test/infer_type_test.cmj test/inline_condition_with_pattern_matching.cmi test/inline_condition_with_pattern_matching.cmj test/inline_const.cmi test/inline_const.cmj test/inline_const_test.cmi test/inline_const_test.cmj test/inline_edge_cases.cmi test/inline_edge_cases.cmj test/inline_map2_test.cmi test/inline_map2_test.cmj test/inline_map_demo.cmi test/inline_map_demo.cmj test/inline_map_test.cmi test/inline_map_test.cmj test/inline_record_test.cmi test/inline_record_test.cmj test/inline_regression_test.cmi test/inline_regression_test.cmj test/inline_string_test.cmi test/inline_string_test.cmj test/inner_call.cmi test/inner_call.cmj test/inner_define.cmi test/inner_define.cmj test/inner_unused.cmi test/inner_unused.cmj test/installation_test.cmi test/installation_test.cmj test/int32_test.cmi test/int32_test.cmj test/int64_mul_div_test.cmi test/int64_mul_div_test.cmj test/int64_string_bench.cmi test/int64_string_bench.cmj test/int64_string_test.cmi test/int64_string_test.cmj test/int64_test.cmi test/int64_test.cmj test/int_hashtbl_test.cmi test/int_hashtbl_test.cmj test/int_map.cmi test/int_map.cmj test/int_overflow_test.cmi test/int_overflow_test.cmj test/int_poly_var.cmi test/int_poly_var.cmj test/int_switch_test.cmi test/int_switch_test.cmj test/internal_unused_test.cmi test/internal_unused_test.cmj test/io_test.cmi test/io_test.cmj test/js_array_test.cmi test/js_array_test.cmj test/js_bool_test.cmi test/js_bool_test.cmj test/js_cast_test.cmi test/js_cast_test.cmj test/js_date_test.cmi test/js_date_test.cmj test/js_dict_test.cmi test/js_dict_test.cmj test/js_exception_catch_test.cmi test/js_exception_catch_test.cmj test/js_float_test.cmi test/js_float_test.cmj test/js_global_test.cmi test/js_global_test.cmj test/js_int_test.cmi test/js_int_test.cmj test/js_json_test.cmi test/js_json_test.cmj test/js_list_test.cmi test/js_list_test.cmj test/js_math_test.cmi test/js_math_test.cmj test/js_null_test.cmi test/js_null_test.cmj test/js_null_undefined_test.cmi test/js_null_undefined_test.cmj test/js_nullable_test.cmi test/js_nullable_test.cmj test/js_obj_test.cmi test/js_obj_test.cmj test/js_option_test.cmi test/js_option_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_typed_array_test.cmi test/js_typed_array_test.cmj test/js_undefined_test.cmi test/js_undefined_test.cmj test/js_val.cmi test/js_val.cmj test/jsoo_400_test.cmi test/jsoo_400_test.cmj test/jsoo_485_test.cmi test/jsoo_485_test.cmj test/jsxv4_newtype.cmi test/jsxv4_newtype.cmj test/key_word_property.cmi test/key_word_property.cmj test/key_word_property2.cmi test/key_word_property2.cmj test/key_word_property_plus_test.cmi test/key_word_property_plus_test.cmj test/label_uncurry.cmi test/label_uncurry.cmj test/large_integer_pat.cmi test/large_integer_pat.cmj test/large_record_duplication_test.cmi test/large_record_duplication_test.cmj test/largest_int_flow.cmi test/largest_int_flow.cmj test/lazy_demo.cmi test/lazy_demo.cmj test/lazy_test.cmi test/lazy_test.cmj test/lib_js_test.cmi test/lib_js_test.cmj test/libarg_test.cmi test/libarg_test.cmj test/libqueue_test.cmi test/libqueue_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_stack.cmi test/list_stack.cmj test/list_test.cmi test/list_test.cmj test/local_exception_test.cmi test/local_exception_test.cmj test/loop_regression_test.cmi test/loop_regression_test.cmj test/loop_suites_test.cmi test/loop_suites_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/map_test.cmi test/map_test.cmj test/mario_game.cmi test/mario_game.cmj test/marshal.cmi test/marshal.cmj test/meth_annotation.cmi test/meth_annotation.cmj test/method_name_test.cmi test/method_name_test.cmj test/method_string_name.cmi test/method_string_name.cmj test/minimal_test.cmi test/minimal_test.cmj test/miss_colon_test.cmi test/miss_colon_test.cmj test/mock_mt.cmi test/mock_mt.cmj test/module_alias_test.cmi test/module_alias_test.cmj test/module_as_class_ffi.cmi test/module_as_class_ffi.cmj test/module_as_function.cmi test/module_as_function.cmj test/module_missing_conversion.cmi test/module_missing_conversion.cmj test/module_parameter_test.cmi test/module_parameter_test.cmj test/module_splice_test.cmi test/module_splice_test.cmj test/more_poly_variant_test.cmi test/more_poly_variant_test.cmj test/more_uncurry.cmi test/more_uncurry.cmj test/mpr_6033_test.cmi test/mpr_6033_test.cmj test/mt.cmi test/mt.cmj test/mt_global.cmi test/mt_global.cmj test/mutable_obj_test.cmi test/mutable_obj_test.cmj test/mutable_uncurry_test.cmi test/mutable_uncurry_test.cmj test/mutual_non_recursive_type.cmi test/mutual_non_recursive_type.cmj test/name_mangle_test.cmi test/name_mangle_test.cmj test/nested_include.cmi test/nested_include.cmj test/nested_module_alias.cmi test/nested_module_alias.cmj test/nested_obj_literal.cmi test/nested_obj_literal.cmj test/nested_obj_test.cmi test/nested_obj_test.cmj test/nested_pattern_match_test.cmi test/nested_pattern_match_test.cmj test/noassert.cmi test/noassert.cmj test/node_path_test.cmi test/node_path_test.cmj test/null_list_test.cmi test/null_list_test.cmj test/number_lexer.cmi test/number_lexer.cmj test/obj_literal_ppx.cmi test/obj_literal_ppx.cmj test/obj_literal_ppx_test.cmi test/obj_literal_ppx_test.cmj test/obj_magic_test.cmi test/obj_magic_test.cmj test/obj_type_test.cmi test/obj_type_test.cmj test/ocaml_re_test.cmi test/ocaml_re_test.cmj test/of_string_test.cmi test/of_string_test.cmj test/offset.cmi test/offset.cmj test/omit_trailing_undefined_in_external_calls.cmi test/omit_trailing_undefined_in_external_calls.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_record_none_test.cmi test/option_record_none_test.cmj test/option_repr_test.cmi test/option_repr_test.cmj test/optional_ffi_test.cmi test/optional_ffi_test.cmj test/optional_regression_test.cmi test/optional_regression_test.cmj test/pipe_send_readline.cmi test/pipe_send_readline.cmj test/pipe_syntax.cmi test/pipe_syntax.cmj test/poly_empty_array.cmi test/poly_empty_array.cmj test/poly_variant_test.cmi test/poly_variant_test.cmj test/polymorphic_raw_test.cmi test/polymorphic_raw_test.cmj test/polymorphism_test.cmi test/polymorphism_test.cmj test/polyvar_convert.cmi test/polyvar_convert.cmj test/polyvar_test.cmi test/polyvar_test.cmj test/ppx_apply_test.cmi test/ppx_apply_test.cmj test/pq_test.cmi test/pq_test.cmj test/pr6726.cmi test/pr6726.cmj test/pr_regression_test.cmi test/pr_regression_test.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/primitive_reg_test.cmi test/primitive_reg_test.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/queue_402.cmi test/queue_402.cmj test/queue_test.cmi test/queue_test.cmj test/random_test.cmi test/random_test.cmj test/raw_hash_tbl_bench.cmi test/raw_hash_tbl_bench.cmj test/raw_output_test.cmi test/raw_output_test.cmj test/raw_pure_test.cmi test/raw_pure_test.cmj test/rbset.cmi test/rbset.cmj test/react.cmi test/react.cmj test/reactDOMRe.cmi test/reactDOMRe.cmj test/reactDOMServerRe.cmi test/reactDOMServerRe.cmj test/reactEvent.cmi test/reactEvent.cmj test/reactTestUtils.cmi test/reactTestUtils.cmj test/reasonReact.cmi test/reasonReact.cmj test/reasonReactCompat.cmi test/reasonReactCompat.cmj test/reasonReactOptimizedCreateClass.cmi test/reasonReactOptimizedCreateClass.cmj test/reasonReactRouter.cmi test/reasonReactRouter.cmj test/rebind_module.cmi test/rebind_module.cmj test/rebind_module_test.cmi test/rebind_module_test.cmj test/rec_array_test.cmi test/rec_array_test.cmj test/rec_fun_test.cmi test/rec_fun_test.cmj test/rec_module_opt.cmi test/rec_module_opt.cmj test/rec_module_test.cmi test/rec_module_test.cmj test/recmodule.cmi test/recmodule.cmj test/record_debug_test.cmi test/record_debug_test.cmj test/record_extension_test.cmi test/record_extension_test.cmj test/record_name_test.cmi test/record_name_test.cmj test/record_regression.cmi test/record_regression.cmj test/record_type_spread.cmi test/record_type_spread.cmj test/record_with_test.cmi test/record_with_test.cmj test/recursive_module.cmi test/recursive_module.cmj test/recursive_module_test.cmi test/recursive_module_test.cmj test/recursive_react_component.cmi test/recursive_react_component.cmj test/recursive_records_test.cmi test/recursive_records_test.cmj test/recursive_unbound_module_test.cmi test/recursive_unbound_module_test.cmj test/regression_print.cmi test/regression_print.cmj test/relative_path.cmi test/relative_path.cmj test/res_debug.cmi test/res_debug.cmj test/return_check.cmi test/return_check.cmj test/runtime_encoding_test.cmi test/runtime_encoding_test.cmj test/set_annotation.cmi test/set_annotation.cmj test/set_gen.cmi test/set_gen.cmj test/sexp.cmi test/sexp.cmj test/sexpm.cmi test/sexpm.cmj test/sexpm_test.cmi test/sexpm_test.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect2.cmi test/side_effect2.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simple_derive_test.cmi test/simple_derive_test.cmj test/simple_derive_use.cmi test/simple_derive_use.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/single_module_alias.cmi test/single_module_alias.cmj test/singular_unit_test.cmi test/singular_unit_test.cmj test/small_inline_test.cmi test/small_inline_test.cmj test/splice_test.cmi test/splice_test.cmj test/stack_comp_test.cmi test/stack_comp_test.cmj test/stack_test.cmi test/stack_test.cmj test/stream_parser_test.cmi test/stream_parser_test.cmj test/string_bound_get_test.cmi test/string_bound_get_test.cmj test/string_constant_compare.cmi test/string_constant_compare.cmj test/string_get_set_test.cmi test/string_get_set_test.cmj test/string_runtime_test.cmi test/string_runtime_test.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_test.cmi test/string_test.cmj test/string_unicode_test.cmi test/string_unicode_test.cmj test/stringmatch_test.cmi test/stringmatch_test.cmj test/submodule.cmi test/submodule.cmj test/submodule_call.cmi test/submodule_call.cmj test/switch_case_test.cmi test/switch_case_test.cmj test/switch_string.cmi test/switch_string.cmj test/tagged_template_test.cmi test/tagged_template_test.cmj test/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test.cmi test/test.cmj test/test2.cmi test/test2.cmj test/test_alias.cmi test/test_alias.cmj test/test_ari.cmi test/test_ari.cmj test/test_array.cmi test/test_array.cmj test/test_array_append.cmi test/test_array_append.cmj test/test_array_primitive.cmi test/test_array_primitive.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_bug.cmi test/test_bug.cmj test/test_bytes.cmi test/test_bytes.cmj test/test_case_opt_collision.cmi test/test_case_opt_collision.cmj test/test_case_set.cmi test/test_case_set.cmj test/test_char.cmi test/test_char.cmj test/test_closure.cmi test/test_closure.cmj test/test_common.cmi test/test_common.cmj test/test_const_elim.cmi test/test_const_elim.cmj test/test_const_propogate.cmi test/test_const_propogate.cmj test/test_cpp.cmi test/test_cpp.cmj test/test_cps.cmi test/test_cps.cmj test/test_demo.cmi test/test_demo.cmj test/test_dup_param.cmi test/test_dup_param.cmj test/test_eq.cmi test/test_eq.cmj test/test_exception.cmi test/test_exception.cmj test/test_exception_escape.cmi test/test_exception_escape.cmj test/test_export2.cmi test/test_export2.cmj test/test_external.cmi test/test_external.cmj test/test_external_unit.cmi test/test_external_unit.cmj test/test_ffi.cmi test/test_ffi.cmj test/test_fib.cmi test/test_fib.cmj test/test_filename.cmi test/test_filename.cmj test/test_for_loop.cmi test/test_for_loop.cmj test/test_for_map.cmi test/test_for_map.cmj test/test_for_map2.cmi test/test_for_map2.cmj test/test_format.cmi test/test_format.cmj test/test_formatter.cmi test/test_formatter.cmj test/test_functor_dead_code.cmi test/test_functor_dead_code.cmj test/test_generative_module.cmi test/test_generative_module.cmj test/test_global_print.cmi test/test_global_print.cmj test/test_google_closure.cmi test/test_google_closure.cmj test/test_include.cmi test/test_include.cmj test/test_incomplete.cmi test/test_incomplete.cmj test/test_incr_ref.cmi test/test_incr_ref.cmj test/test_int_map_find.cmi test/test_int_map_find.cmj test/test_internalOO.cmi test/test_internalOO.cmj test/test_is_js.cmi test/test_is_js.cmj test/test_js_ffi.cmi test/test_js_ffi.cmj test/test_let.cmi test/test_let.cmj test/test_list.cmi test/test_list.cmj test/test_literal.cmi test/test_literal.cmj test/test_literals.cmi test/test_literals.cmj test/test_match_exception.cmi test/test_match_exception.cmj test/test_mutliple.cmi test/test_mutliple.cmj test/test_nat64.cmi test/test_nat64.cmj test/test_nested_let.cmi test/test_nested_let.cmj test/test_nested_print.cmi test/test_nested_print.cmj test/test_non_export.cmi test/test_non_export.cmj test/test_nullary.cmi test/test_nullary.cmj test/test_obj.cmi test/test_obj.cmj test/test_order.cmi test/test_order.cmj test/test_order_tailcall.cmi test/test_order_tailcall.cmj test/test_other_exn.cmi test/test_other_exn.cmj test/test_pack.cmi test/test_pack.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives2.cmi test/test_pervasives2.cmj test/test_pervasives3.cmi test/test_pervasives3.cmj test/test_primitive.cmi test/test_primitive.cmj test/test_ramification.cmi test/test_ramification.cmj test/test_react.cmi test/test_react.cmj test/test_react_case.cmi test/test_react_case.cmj test/test_regex.cmi test/test_regex.cmj test/test_runtime_encoding.cmi test/test_runtime_encoding.cmj test/test_scope.cmi test/test_scope.cmj test/test_seq.cmi test/test_seq.cmj test/test_set.cmi test/test_set.cmj test/test_side_effect_functor.cmi test/test_side_effect_functor.cmj test/test_simple_include.cmi test/test_simple_include.cmj test/test_simple_pattern_match.cmi test/test_simple_pattern_match.cmj test/test_simple_ref.cmi test/test_simple_ref.cmj test/test_simple_tailcall.cmi test/test_simple_tailcall.cmj test/test_small.cmi test/test_small.cmj test/test_sprintf.cmi test/test_sprintf.cmj test/test_stack.cmi test/test_stack.cmj test/test_static_catch_ident.cmi test/test_static_catch_ident.cmj test/test_string.cmi test/test_string.cmj test/test_string_case.cmi test/test_string_case.cmj test/test_string_const.cmi test/test_string_const.cmj test/test_string_map.cmi test/test_string_map.cmj test/test_string_switch.cmi test/test_string_switch.cmj test/test_switch.cmi test/test_switch.cmj test/test_trywith.cmi test/test_trywith.cmj test/test_tuple.cmi test/test_tuple.cmj test/test_tuple_destructring.cmi test/test_tuple_destructring.cmj test/test_type_based_arity.cmi test/test_type_based_arity.cmj test/test_u.cmi test/test_u.cmj test/test_unknown.cmi test/test_unknown.cmj test/test_unsafe_cmp.cmi test/test_unsafe_cmp.cmj test/test_unsafe_obj_ffi.cmi test/test_unsafe_obj_ffi.cmj test/test_unsafe_obj_ffi_ppx.cmi test/test_unsafe_obj_ffi_ppx.cmj test/test_unsupported_primitive.cmi test/test_unsupported_primitive.cmj test/test_while_closure.cmi test/test_while_closure.cmj test/test_while_side_effect.cmi test/test_while_side_effect.cmj test/test_zero_nullable.cmi test/test_zero_nullable.cmj test/then_mangle_test.cmi test/then_mangle_test.cmj test/ticker.cmi test/ticker.cmj test/to_string_test.cmi test/to_string_test.cmj test/topsort_test.cmi test/topsort_test.cmj test/tramp_fib.cmi test/tramp_fib.cmj test/tuple_alloc.cmi test/tuple_alloc.cmj test/type_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/unboxed_attribute.cmi test/unboxed_attribute.cmj test/unboxed_attribute_test.cmi test/unboxed_attribute_test.cmj test/unboxed_crash.cmi test/unboxed_crash.cmj test/unboxed_use_case.cmi test/unboxed_use_case.cmj test/uncurried_cast.cmi test/uncurried_cast.cmj test/uncurried_default.args.cmi test/uncurried_default.args.cmj test/uncurried_pipe.cmi test/uncurried_pipe.cmj test/uncurry_external_test.cmi test/uncurry_external_test.cmj test/uncurry_glob_test.cmi test/uncurry_glob_test.cmj test/uncurry_test.cmi test/uncurry_test.cmj test/undef_regression2_test.cmi test/undef_regression2_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/undefine_conditional.cmi test/undefine_conditional.cmj test/unicode_type_error.cmi test/unicode_type_error.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unitest_string.cmi test/unitest_string.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/update_record_test.cmi test/update_record_test.cmj test/variant.cmi test/variant.cmj test/variantsMatching.cmi test/variantsMatching.cmj test/webpack_config.cmi test/webpack_config.cmj diff --git a/jscomp/test/ocaml_re_test.js b/jscomp/test/ocaml_re_test.js index 4cd42b894c..041f35e63e 100644 --- a/jscomp/test/ocaml_re_test.js +++ b/jscomp/test/ocaml_re_test.js @@ -3412,818 +3412,6 @@ function parse(multiline, dollar_endonly, dotall, ungreedy, s) { }; } }; - var branch$p = function (_left) { - while(true) { - var left = _left; - if (i.contents === l || test(/* '|' */124) || test(/* ')' */41)) { - return seq$2(List.rev(left)); - } - _left = { - hd: piece(), - tl: left - }; - continue ; - }; - }; - var regexp$p = function (_left) { - while(true) { - var left = _left; - if (!accept(/* '|' */124)) { - return left; - } - _left = alt$1({ - hd: left, - tl: { - hd: branch$p(/* [] */0), - tl: /* [] */0 - } - }); - continue ; - }; - }; - var atom = function (param) { - if (accept(/* '.' */46)) { - if (dotall) { - return any; - } else { - return notnl; - } - } - if (accept(/* '(' */40)) { - if (accept(/* '?' */63)) { - if (accept(/* ':' */58)) { - var r = regexp$p(branch$p(/* [] */0)); - if (!accept(/* ')' */41)) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - return r; - } - if (accept(/* '#' */35)) { - var _param; - while(true) { - if (accept(/* ')' */41)) { - return epsilon; - } - i.contents = i.contents + 1 | 0; - _param = undefined; - continue ; - }; - } - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - var r$1 = regexp$p(branch$p(/* [] */0)); - if (!accept(/* ')' */41)) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - return { - TAG: "Group", - _0: r$1 - }; - } - if (accept(/* '^' */94)) { - if (multiline) { - return "Beg_of_line"; - } else { - return "Beg_of_str"; - } - } - if (accept(/* '$' */36)) { - if (multiline) { - return "End_of_line"; - } else if (dollar_endonly) { - return "Last_end_of_line"; - } else { - return "End_of_str"; - } - } - if (accept(/* '[' */91)) { - if (accept(/* '^' */94)) { - return compl(bracket(/* [] */0)); - } else { - return alt$1(bracket(/* [] */0)); - } - } - if (accept(/* '\\' */92)) { - if (i.contents === l) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - var c = get(); - switch (c) { - case 48 : - case 49 : - case 50 : - case 51 : - case 52 : - case 53 : - case 54 : - case 55 : - case 56 : - case 57 : - throw { - RE_EXN_ID: Not_supported, - Error: new Error() - }; - case 65 : - return "Beg_of_str"; - case 66 : - return "Not_bound"; - case 68 : - return compl({ - hd: digit, - tl: /* [] */0 - }); - case 71 : - return "Start"; - case 83 : - return compl({ - hd: space, - tl: /* [] */0 - }); - case 87 : - return compl({ - hd: alnum, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '_' */95, - /* '_' */95 - ], - tl: /* [] */0 - } - }, - tl: /* [] */0 - } - }); - case 90 : - return "Last_end_of_line"; - case 98 : - return alt$1({ - hd: "Beg_of_word", - tl: { - hd: "End_of_word", - tl: /* [] */0 - } - }); - case 100 : - return digit; - case 115 : - return space; - case 119 : - return alt$1({ - hd: alnum, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '_' */95, - /* '_' */95 - ], - tl: /* [] */0 - } - }, - tl: /* [] */0 - } - }); - case 67 : - case 69 : - case 70 : - case 72 : - case 73 : - case 74 : - case 75 : - case 76 : - case 77 : - case 78 : - case 79 : - case 80 : - case 81 : - case 82 : - case 84 : - case 85 : - case 86 : - case 88 : - case 89 : - case 97 : - case 99 : - case 101 : - case 102 : - case 103 : - case 104 : - case 105 : - case 106 : - case 107 : - case 108 : - case 109 : - case 110 : - case 111 : - case 112 : - case 113 : - case 114 : - case 116 : - case 117 : - case 118 : - case 120 : - case 121 : - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - case 122 : - return "End_of_str"; - default: - return { - TAG: "Set", - _0: single(c) - }; - } - } else { - if (i.contents === l) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - var c$1 = get(); - if (c$1 >= 64) { - if (c$1 !== 92) { - if (c$1 !== 123) { - return { - TAG: "Set", - _0: single(c$1) - }; - } - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - if (c$1 >= 44) { - if (c$1 >= 63) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - return { - TAG: "Set", - _0: single(c$1) - }; - } - if (c$1 >= 42) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - return { - TAG: "Set", - _0: single(c$1) - }; - } - }; - var integer = function (param) { - if (i.contents === l) { - return ; - } - var d = get(); - if (d > 57 || d < 48) { - i.contents = i.contents - 1 | 0; - return ; - } else { - var _i = d - /* '0' */48 | 0; - while(true) { - var i$1 = _i; - if (i.contents === l) { - return i$1; - } - var d$1 = get(); - if (d$1 > 57 || d$1 < 48) { - i.contents = i.contents - 1 | 0; - return i$1; - } - var i$p = Math.imul(10, i$1) + (d$1 - /* '0' */48 | 0) | 0; - if (i$p < i$1) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - _i = i$p; - continue ; - }; - } - }; - var bracket = function (_s) { - while(true) { - var s = _s; - if (s !== /* [] */0 && accept(/* ']' */93)) { - return s; - } - var match = $$char(); - if (match.NAME === "Char") { - var c = match.VAL; - if (accept(/* '-' */45)) { - if (accept(/* ']' */93)) { - return { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '-' */45, - /* '-' */45 - ], - tl: /* [] */0 - } - }, - tl: s - } - }; - } - var match$1 = $$char(); - if (match$1.NAME !== "Char") { - return { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '-' */45, - /* '-' */45 - ], - tl: /* [] */0 - } - }, - tl: { - hd: match$1.VAL, - tl: s - } - } - }; - } - _s = { - hd: { - TAG: "Set", - _0: seq(c, match$1.VAL) - }, - tl: s - }; - continue ; - } - _s = { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: s - }; - continue ; - } - _s = { - hd: match.VAL, - tl: s - }; - continue ; - }; - }; - var piece = function (param) { - var r = atom(); - if (accept(/* '*' */42)) { - return greedy_mod(repn(r, 0, undefined)); - } - if (accept(/* '+' */43)) { - return greedy_mod(repn(r, 1, undefined)); - } - if (accept(/* '?' */63)) { - return greedy_mod(repn(r, 0, 1)); - } - if (!accept(/* '{' */123)) { - return r; - } - var i$1 = integer(); - if (i$1 !== undefined) { - var j = accept(/* ',' */44) ? integer() : i$1; - if (!accept(/* '}' */125)) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - if (j !== undefined && j < i$1) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - return greedy_mod(repn(r, i$1, j)); - } - i.contents = i.contents - 1 | 0; - return r; - }; - var $$char = function (param) { - if (i.contents === l) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - var c = get(); - if (c === /* '[' */91) { - if (accept(/* '=' */61)) { - throw { - RE_EXN_ID: Not_supported, - Error: new Error() - }; - } - if (accept(/* ':' */58)) { - var compl$1 = accept(/* '^' */94); - var cls; - try { - cls = List.find(accept_s, { - hd: "alnum", - tl: { - hd: "ascii", - tl: { - hd: "blank", - tl: { - hd: "cntrl", - tl: { - hd: "digit", - tl: { - hd: "lower", - tl: { - hd: "print", - tl: { - hd: "space", - tl: { - hd: "upper", - tl: { - hd: "word", - tl: { - hd: "punct", - tl: { - hd: "graph", - tl: { - hd: "xdigit", - tl: /* [] */0 - } - } - } - } - } - } - } - } - } - } - } - } - }); - } - catch (raw_exn){ - var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); - if (exn.RE_EXN_ID === "Not_found") { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - throw exn; - } - if (!accept_s(":]")) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - var posix_class = posix_class_of_string(cls); - var re = compl$1 ? compl({ - hd: posix_class, - tl: /* [] */0 - }) : posix_class; - return { - NAME: "Set", - VAL: re - }; - } - if (!accept(/* '.' */46)) { - return { - NAME: "Char", - VAL: c - }; - } - if (i.contents === l) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - var c$1 = get(); - if (!accept(/* '.' */46)) { - throw { - RE_EXN_ID: Not_supported, - Error: new Error() - }; - } - if (!accept(/* ']' */93)) { - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - } - return { - NAME: "Char", - VAL: c$1 - }; - } - if (c !== /* '\\' */92) { - return { - NAME: "Char", - VAL: c - }; - } - var c$2 = get(); - if (c$2 >= 58) { - if (c$2 >= 123) { - return { - NAME: "Char", - VAL: c$2 - }; - } - switch (c$2) { - case 68 : - return { - NAME: "Set", - VAL: compl({ - hd: digit, - tl: /* [] */0 - }) - }; - case 83 : - return { - NAME: "Set", - VAL: compl({ - hd: space, - tl: /* [] */0 - }) - }; - case 87 : - return { - NAME: "Set", - VAL: compl({ - hd: alnum, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '_' */95, - /* '_' */95 - ], - tl: /* [] */0 - } - }, - tl: /* [] */0 - } - }) - }; - case 58 : - case 59 : - case 60 : - case 61 : - case 62 : - case 63 : - case 64 : - case 91 : - case 92 : - case 93 : - case 94 : - case 95 : - case 96 : - return { - NAME: "Char", - VAL: c$2 - }; - case 98 : - return { - NAME: "Char", - VAL: /* '\b' */8 - }; - case 100 : - return { - NAME: "Set", - VAL: digit - }; - case 110 : - return { - NAME: "Char", - VAL: /* '\n' */10 - }; - case 114 : - return { - NAME: "Char", - VAL: /* '\r' */13 - }; - case 115 : - return { - NAME: "Set", - VAL: space - }; - case 116 : - return { - NAME: "Char", - VAL: /* '\t' */9 - }; - case 119 : - return { - NAME: "Set", - VAL: alt$1({ - hd: alnum, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '_' */95, - /* '_' */95 - ], - tl: /* [] */0 - } - }, - tl: /* [] */0 - } - }) - }; - case 65 : - case 66 : - case 67 : - case 69 : - case 70 : - case 71 : - case 72 : - case 73 : - case 74 : - case 75 : - case 76 : - case 77 : - case 78 : - case 79 : - case 80 : - case 81 : - case 82 : - case 84 : - case 85 : - case 86 : - case 88 : - case 89 : - case 90 : - case 97 : - case 99 : - case 101 : - case 102 : - case 103 : - case 104 : - case 105 : - case 106 : - case 107 : - case 108 : - case 109 : - case 111 : - case 112 : - case 113 : - case 117 : - case 118 : - case 120 : - case 121 : - case 122 : - throw { - RE_EXN_ID: Parse_error, - Error: new Error() - }; - - } - } else { - if (c$2 >= 48) { - throw { - RE_EXN_ID: Not_supported, - Error: new Error() - }; - } - return { - NAME: "Char", - VAL: c$2 - }; - } - }; - var bracket = function (_s) { - while(true) { - var s = _s; - if (s !== /* [] */0 && accept(/* ']' */93)) { - return s; - } - var match = $$char(); - if (match.NAME === "Char") { - var c = match.VAL; - if (accept(/* '-' */45)) { - if (accept(/* ']' */93)) { - return { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '-' */45, - /* '-' */45 - ], - tl: /* [] */0 - } - }, - tl: s - } - }; - } - var match$1 = $$char(); - if (match$1.NAME !== "Char") { - return { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: { - hd: { - TAG: "Set", - _0: { - hd: [ - /* '-' */45, - /* '-' */45 - ], - tl: /* [] */0 - } - }, - tl: { - hd: match$1.VAL, - tl: s - } - } - }; - } - _s = { - hd: { - TAG: "Set", - _0: seq(c, match$1.VAL) - }, - tl: s - }; - continue ; - } - _s = { - hd: { - TAG: "Set", - _0: single(c) - }, - tl: s - }; - continue ; - } - _s = { - hd: match.VAL, - tl: s - }; - continue ; - }; - }; var atom = function (param) { if (accept(/* '.' */46)) { if (dotall) { @@ -4353,23 +3541,6 @@ function parse(multiline, dollar_endonly, dotall, ungreedy, s) { }); case 90 : return "Last_end_of_line"; - case 58 : - case 59 : - case 60 : - case 61 : - case 62 : - case 63 : - case 64 : - case 91 : - case 92 : - case 93 : - case 94 : - case 95 : - case 96 : - return { - TAG: "Set", - _0: single(c) - }; case 98 : return alt$1({ hd: "Beg_of_word", From ec900783169d52363e4d4aa1ebea1788574af2e6 Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 22 Mar 2024 03:18:59 +0900 Subject: [PATCH 28/45] update change log --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad4b5c1987..a85891b622 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ # 11.1.0-rc.6 (Unreleased) +#### :rocket: New Feature + +- Add the primitive bigint type https://github.com/rescript-lang/rescript-compiler/pull/6670 + #### :bug: Bug Fix - Fix mishandling of uncurried functions in super errors. https://github.com/rescript-lang/rescript-compiler/pull/6694 From b8a5efd78c385fc660ea63f2b350c1fd320aae04 Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 22 Mar 2024 04:07:48 +0900 Subject: [PATCH 29/45] fix incorrect compare bigint values --- jscomp/core/js_exp_make.ml | 4 ---- jscomp/core/lam.ml | 8 ++++++-- jscomp/core/lam_compat.ml | 9 --------- jscomp/core/lam_compat.mli | 2 -- 4 files changed, 6 insertions(+), 17 deletions(-) diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index 17ca3b9f40..b780803e69 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -1266,10 +1266,6 @@ let bigint_comp (cmp : Lam_compat.comparison) ?comment (e0: t) (e1: t) = match (cmp, e0.expression_desc, e1.expression_desc) with | Ceq, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 = i1) | Cneq, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 <> i1) - | Cge, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 >= i1) - | Cgt, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 > i1) - | Cle, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 <= i1) - | Clt, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 < i1) | _ -> bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1 (* TODO -- alpha conversion diff --git a/jscomp/core/lam.ml b/jscomp/core/lam.ml index 06c28db4ea..8b8d11a83b 100644 --- a/jscomp/core/lam.ml +++ b/jscomp/core/lam.ml @@ -507,8 +507,12 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t = Lift.bool (Lam_compat.cmp_float cmp (float_of_string a) (float_of_string b)) | Pbigintcomp cmp, Const_bigint a, Const_bigint b -> - Lift.bool - (Lam_compat.cmp_bigint cmp (a) (b)) + (match cmp with + | Ceq -> + Lift.bool (a = b) + | Cneq -> + Lift.bool (a <> b) + |_ -> default ()) | Pintcomp ((Ceq | Cneq) as op), Const_pointer a, Const_pointer b -> Lift.bool (match op with diff --git a/jscomp/core/lam_compat.ml b/jscomp/core/lam_compat.ml index 0ade662f21..3fb76f455c 100644 --- a/jscomp/core/lam_compat.ml +++ b/jscomp/core/lam_compat.ml @@ -67,15 +67,6 @@ let cmp_float (cmp : comparison) (a : float) b : bool = | Cle -> a <= b | Clt -> a < b | Cge -> a >= b - -let cmp_bigint (cmp : comparison) (a : string) b : bool = - match cmp with - | Ceq -> a = b - | Cneq -> a <> b - | Cgt -> a > b - | Cle -> a <= b - | Clt -> a < b - | Cge -> a >= b let cmp_int (cmp : comparison) (a : int) b : bool = match cmp with diff --git a/jscomp/core/lam_compat.mli b/jscomp/core/lam_compat.mli index 5181fc3243..de022543be 100644 --- a/jscomp/core/lam_compat.mli +++ b/jscomp/core/lam_compat.mli @@ -61,8 +61,6 @@ val cmp_int64 : comparison -> int64 -> int64 -> bool val cmp_float : comparison -> float -> float -> bool -val cmp_bigint : comparison -> string -> string -> bool - val cmp_int : comparison -> int -> int -> bool val eq_comparison : comparison -> comparison -> bool From 79df62c844348afe2fd77f2e0619b52dad3a4695 Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 22 Mar 2024 04:14:35 +0900 Subject: [PATCH 30/45] remove leftover --- jscomp/syntax/tests/printer/other/case.res | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jscomp/syntax/tests/printer/other/case.res b/jscomp/syntax/tests/printer/other/case.res index ab84f19d11..c72cc2f8a7 100644 --- a/jscomp/syntax/tests/printer/other/case.res +++ b/jscomp/syntax/tests/printer/other/case.res @@ -93,8 +93,7 @@ let precedence = x => switch x { | AsteriskDot | Forwardslash | ForwardslashDot => 6 - | Exponentiation - | ExponentiationComma => 7 + | Exponentiation => 7 | Hash | HashHash | MinusGreater => 8 From dd6b0cf32802c3d0a78cd9e6e7c90447d665f307 Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 22 Mar 2024 13:16:22 +0900 Subject: [PATCH 31/45] removed leftover --- jscomp/syntax/tests/printer/other/expected/case.res.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jscomp/syntax/tests/printer/other/expected/case.res.txt b/jscomp/syntax/tests/printer/other/expected/case.res.txt index 52acaf7bee..38931fc1d1 100644 --- a/jscomp/syntax/tests/printer/other/expected/case.res.txt +++ b/jscomp/syntax/tests/printer/other/expected/case.res.txt @@ -83,8 +83,7 @@ let precedence = x => | AsteriskDot | Forwardslash | ForwardslashDot => 6 - | Exponentiation - | ExponentiationComma => 7 + | Exponentiation => 7 | Hash | HashHash | MinusGreater => 8 From 9852ad098b70af8144c1a4174f47ff637d1d3858 Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 22 Mar 2024 21:11:32 +0900 Subject: [PATCH 32/45] handling and testing bigint values with leading zeros and minus --- jscomp/ext/ext_string.ml | 41 ++++++++++++++++- jscomp/ext/ext_string.mli | 4 +- jscomp/ml/typecore.ml | 2 +- .../parsing/grammar/expressions/bigint.res | 7 +++ .../expressions/expected/bigint.res.txt | 8 +++- jscomp/test/bigint_test.js | 46 +++++++++++++------ jscomp/test/bigint_test.res | 8 ++++ 7 files changed, 97 insertions(+), 19 deletions(-) diff --git a/jscomp/ext/ext_string.ml b/jscomp/ext/ext_string.ml index 617f416d84..ae2b0e5694 100644 --- a/jscomp/ext/ext_string.ml +++ b/jscomp/ext/ext_string.ml @@ -528,4 +528,43 @@ let hash_number_as_i32_exn let first_marshal_char (x : string) = x <> "" && ( String.unsafe_get x 0 = '\132') - \ No newline at end of file + +(* + Removes leading zeros from the string only if the first non-zero character + encountered is a digit. Unlike int and float, bigint cannot be of_string, so + This function removes only leading 0s. Instead, values like 00x1 are not converted + and are intended to be syntax errors. + + 000n -> 0n + 001n -> 1n + 01_000_000n -> 1000000n + 0x1 -> 0x1n + 0x001n -> 0x001n + -00100n -> -100n + + The following values are syntax errors + + 00o1n -> 00o1n + 00x1_000_000n -> 00x1000000n +*) +let remove_leading_zeros str = + let aux str = + let len = String.length str in + if len = 0 then "" + else + let is_digit c = c >= '0' && c <= '9' in + let idx = ref 0 in + while !idx < len && str.[!idx] = '0' do + incr idx + done; + if !idx >= len then "0" (* If the string contains only '0's, return '0'. *) + else if (is_digit str.[!idx]) then String.sub str !idx (len - !idx) (* Remove leading zeros and return the rest of the string. *) + else str + in + (* Replace the delimiters '_' inside number *) + let str = String.concat "" (String.split_on_char '_' str) in + (* Check if negative *) + let starts_with_minus = str <> "" && str.[0] = '-' in + let str = if starts_with_minus then String.sub str 1 (String.length str - 1) else str in + let processed_str = aux str in + if starts_with_minus then "-" ^ processed_str else processed_str diff --git a/jscomp/ext/ext_string.mli b/jscomp/ext/ext_string.mli index a1c6a66e91..354c9c221e 100644 --- a/jscomp/ext/ext_string.mli +++ b/jscomp/ext/ext_string.mli @@ -223,4 +223,6 @@ val hash_number_as_i32_exn: val first_marshal_char: string -> - bool \ No newline at end of file + bool + +val remove_leading_zeros: string -> string diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index 61ba418e18..c069ec87a5 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -259,7 +259,7 @@ let constant : Parsetree.constant -> (Asttypes.constant, error) result = try Ok (Const_int64 (Misc.Int_literal_converter.int64 i)) with Failure _ -> Error (Literal_overflow "int64") end - | Pconst_integer (i,Some 'n') ->Ok (Const_bigint i) + | Pconst_integer (i,Some 'n') ->Ok (Const_bigint (Ext_string.remove_leading_zeros i)) | Pconst_integer (i,Some c) -> Error (Unknown_literal (i, c)) | Pconst_char c -> Ok (Const_char c) | Pconst_string (s,d) -> Ok (Const_string (s,d)) diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res b/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res index 60a5497495..9789195cf8 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res +++ b/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res @@ -7,3 +7,10 @@ 10n + 54 289n - 138n + +0x1n +0b1n +0o1n +0100n +001_000_000n +-000100n diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt index aeadd59947..c7ebbf3fc1 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt @@ -2,4 +2,10 @@ ;;3n * 4n ;;2n ** 2n ;;10n + 54 -;;289n - 138n \ No newline at end of file +;;289n - 138n +;;0x1n +;;0b1n +;;0o1n +;;0100n +;;001_000_000n +;;(-000100n) \ No newline at end of file diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js index e00eb3b175..7ae3429f81 100644 --- a/jscomp/test/bigint_test.js +++ b/jscomp/test/bigint_test.js @@ -102,35 +102,51 @@ Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 32, charac Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 33, characters 5-12", Caml_obj.compare(1n, 2n), -1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 34, characters 5-12", true, true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 34, characters 5-12", Caml.bigint_compare(1n, 2n), -1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 35, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 35, characters 5-12", Caml_obj.compare(1n, 2n), -1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 36, characters 5-12", false, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 36, characters 5-12", Caml.bigint_compare(1n, 1n), 0); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 37, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 37, characters 5-12", Caml_obj.compare(1n, 1n), 0); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 38, characters 5-12", false, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 38, characters 5-12", Caml.bigint_compare(0x1n, 0x001n), 0); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 39, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 39, characters 5-12", Caml_obj.compare(0x1n, 0x001n), 0); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 40, characters 5-12", 9n & 1n, 1n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 40, characters 5-12", Caml.bigint_compare(-0x1n, 0x001n), -1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 41, characters 5-12", 9n | 1n, 9n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 41, characters 5-12", Caml_obj.compare(-0x1n, 0x001n), -1); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 42, characters 5-12", 9n ^ 1n, 8n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 42, characters 5-12", true, true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 43, characters 5-12", (9n << 1n), 18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 43, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 44, characters 5-12", (9n << -1n), 4n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 44, characters 5-12", false, false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 45, characters 5-12", (9n >> 1n), 4n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 45, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 46, characters 5-12", (9n >> -1n), 18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 46, characters 5-12", false, false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 47, characters 5-12", (-9n >> 1n), -5n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 47, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 48, characters 5-12", (-9n >> -1n), -18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 48, characters 5-12", 9n & 1n, 1n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 49, characters 5-12", 9n | 1n, 9n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 50, characters 5-12", 9n ^ 1n, 8n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 51, characters 5-12", (9n << 1n), 18n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 52, characters 5-12", (9n << -1n), 4n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 53, characters 5-12", (9n >> 1n), 4n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 54, characters 5-12", (9n >> -1n), 18n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 55, characters 5-12", (-9n >> 1n), -5n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 56, characters 5-12", (-9n >> -1n), -18n); Mt.from_pair_suites("Bigint_test", suites.contents); diff --git a/jscomp/test/bigint_test.res b/jscomp/test/bigint_test.res index 7b70bf88c7..ab989d2983 100644 --- a/jscomp/test/bigint_test.res +++ b/jscomp/test/bigint_test.res @@ -31,6 +31,14 @@ let () = { eq(__LOC__, generic_compare(+0n, -1n), 1) eq(__LOC__, bigint_compare(1n, 2n), -1) eq(__LOC__, generic_compare(1n, 2n), -1) + eq(__LOC__, bigint_compare(1n, 02n), -1) + eq(__LOC__, generic_compare(1n, 02n), -1) + eq(__LOC__, bigint_compare(1n, 001n), 0) + eq(__LOC__, generic_compare(1n, 001n), 0) + eq(__LOC__, bigint_compare(0x1n, 0x001n), 0) + eq(__LOC__, generic_compare(0x1n, 0x001n), 0) + eq(__LOC__, bigint_compare(-0x1n, 0x001n), -1) + eq(__LOC__, generic_compare(-0x1n, 0x001n), -1) eq(__LOC__, bigint_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true) eq(__LOC__, generic_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true) eq(__LOC__, bigint_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false) From 00d741a206cd698b2f13dfbd92f418cffd37ab48 Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 22 Mar 2024 21:54:53 +0900 Subject: [PATCH 33/45] remove optimization const_compare from parmatch and add test --- jscomp/ml/parmatch.ml | 2 -- jscomp/test/bigint_test.js | 22 +++++++++++++--------- jscomp/test/bigint_test.res | 10 ++++++++++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/jscomp/ml/parmatch.ml b/jscomp/ml/parmatch.ml index 3f49819a12..46030055e7 100644 --- a/jscomp/ml/parmatch.ml +++ b/jscomp/ml/parmatch.ml @@ -264,8 +264,6 @@ let const_compare x y = match x,y with | Const_float f1, Const_float f2 -> compare (float_of_string f1) (float_of_string f2) - | Const_bigint b1, Const_bigint b2 -> - String.compare b1 b2 | Const_string (s1, _), Const_string (s2, _) -> String.compare s1 s2 | _, _ -> compare x y diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js index 7ae3429f81..78babb1e2c 100644 --- a/jscomp/test/bigint_test.js +++ b/jscomp/test/bigint_test.js @@ -130,23 +130,27 @@ Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 46, charac Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 47, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 48, characters 5-12", 9n & 1n, 1n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 48, characters 5-12", true, true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 49, characters 5-12", 9n | 1n, 9n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 53, characters 5-12", Caml_obj.equal(3n, 3n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 50, characters 5-12", 9n ^ 1n, 8n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 58, characters 5-12", 9n & 1n, 1n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 51, characters 5-12", (9n << 1n), 18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 59, characters 5-12", 9n | 1n, 9n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 52, characters 5-12", (9n << -1n), 4n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 60, characters 5-12", 9n ^ 1n, 8n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 53, characters 5-12", (9n >> 1n), 4n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 61, characters 5-12", (9n << 1n), 18n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 54, characters 5-12", (9n >> -1n), 18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 62, characters 5-12", (9n << -1n), 4n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 55, characters 5-12", (-9n >> 1n), -5n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 63, characters 5-12", (9n >> 1n), 4n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 56, characters 5-12", (-9n >> -1n), -18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 64, characters 5-12", (9n >> -1n), 18n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 65, characters 5-12", (-9n >> 1n), -5n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 66, characters 5-12", (-9n >> -1n), -18n); Mt.from_pair_suites("Bigint_test", suites.contents); diff --git a/jscomp/test/bigint_test.res b/jscomp/test/bigint_test.res index ab989d2983..12c5ebc86e 100644 --- a/jscomp/test/bigint_test.res +++ b/jscomp/test/bigint_test.res @@ -45,6 +45,16 @@ let () = { eq(__LOC__, generic_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false) eq(__LOC__, bigint_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false) eq(__LOC__, generic_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false) + eq(__LOC__, bigint_equal(switch 1n { + |1n => 3n + |2n => 4n + |_ => 0n + }, 3n), true) + eq(__LOC__, generic_equal(switch 1n { + |1n => 3n + |2n => 4n + |_ => 0n + }, 3n), true) eq(__LOC__, bigint_land(9n, 1n), 1n) eq(__LOC__, bigint_lor(9n, 1n), 9n) eq(__LOC__, bigint_lxor(9n, 1n), 8n) From 379dc318138380121970bc8cc5241f52f22a706c Mon Sep 17 00:00:00 2001 From: mununki Date: Fri, 22 Mar 2024 22:03:54 +0900 Subject: [PATCH 34/45] add tests for pattern matching bigint liternal --- jscomp/test/bigint_test.js | 26 +++++++++++++++++--------- jscomp/test/bigint_test.res | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js index 78babb1e2c..14bd8d5674 100644 --- a/jscomp/test/bigint_test.js +++ b/jscomp/test/bigint_test.js @@ -134,23 +134,31 @@ Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 48, charac Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 53, characters 5-12", Caml_obj.equal(3n, 3n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 58, characters 5-12", 9n & 1n, 1n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 58, characters 5-12", true, true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 59, characters 5-12", 9n | 1n, 9n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 63, characters 5-12", Caml_obj.equal(3n, 3n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 60, characters 5-12", 9n ^ 1n, 8n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 68, characters 5-12", true, true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 61, characters 5-12", (9n << 1n), 18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 73, characters 5-12", Caml_obj.equal(3n, 3n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 62, characters 5-12", (9n << -1n), 4n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 78, characters 5-12", 9n & 1n, 1n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 63, characters 5-12", (9n >> 1n), 4n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 79, characters 5-12", 9n | 1n, 9n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 64, characters 5-12", (9n >> -1n), 18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 80, characters 5-12", 9n ^ 1n, 8n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 65, characters 5-12", (-9n >> 1n), -5n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 81, characters 5-12", (9n << 1n), 18n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 66, characters 5-12", (-9n >> -1n), -18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 82, characters 5-12", (9n << -1n), 4n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 83, characters 5-12", (9n >> 1n), 4n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 84, characters 5-12", (9n >> -1n), 18n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 85, characters 5-12", (-9n >> 1n), -5n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 86, characters 5-12", (-9n >> -1n), -18n); Mt.from_pair_suites("Bigint_test", suites.contents); diff --git a/jscomp/test/bigint_test.res b/jscomp/test/bigint_test.res index 12c5ebc86e..135b0acbb1 100644 --- a/jscomp/test/bigint_test.res +++ b/jscomp/test/bigint_test.res @@ -55,6 +55,26 @@ let () = { |2n => 4n |_ => 0n }, 3n), true) + eq(__LOC__, bigint_equal(switch -1n { + |-00001n => 3n + |-2n => 4n + |_ => 0n + }, 3n), true) + eq(__LOC__, generic_equal(switch -1n { + |-00001n => 3n + |2n => 4n + |_ => 0n + }, 3n), true) + eq(__LOC__, bigint_equal(switch 0x1n { + |0x1n => 3n + |0b1n => 4n + |_ => 0n + }, 3n), true) + eq(__LOC__, generic_equal(switch 0x1n { + |0x1n => 3n + |0b1n => 4n + |_ => 0n + }, 3n), true) eq(__LOC__, bigint_land(9n, 1n), 1n) eq(__LOC__, bigint_lor(9n, 1n), 9n) eq(__LOC__, bigint_lxor(9n, 1n), 8n) From 990e5ac3b3f4ca45cb80d42d05b49084865d1a92 Mon Sep 17 00:00:00 2001 From: mununki Date: Sat, 23 Mar 2024 15:07:38 +0900 Subject: [PATCH 35/45] support only decimal bigint literal and pattern matching --- .../bigint_match_literal.res.expected | 11 +++ .../expected/warnings4.res.expected | 2 +- .../expected/warnings5.res.expected | 2 +- .../fixtures/bigint_match_literal.res | 6 ++ jscomp/ext/ext_string.ml | 40 ----------- jscomp/ext/ext_string.mli | 2 - jscomp/ml/bigint_utils.ml | 71 +++++++++++++++++++ jscomp/ml/bigint_utils.mli | 3 + jscomp/ml/parmatch.ml | 2 + jscomp/ml/typecore.ml | 9 ++- jscomp/ml/typecore.mli | 1 + .../parsing/grammar/expressions/bigint.res | 3 - jscomp/test/bigint_test.js | 50 +++++-------- jscomp/test/bigint_test.res | 14 ---- 14 files changed, 123 insertions(+), 93 deletions(-) create mode 100644 jscomp/build_tests/super_errors/expected/bigint_match_literal.res.expected create mode 100644 jscomp/build_tests/super_errors/fixtures/bigint_match_literal.res create mode 100644 jscomp/ml/bigint_utils.ml create mode 100644 jscomp/ml/bigint_utils.mli diff --git a/jscomp/build_tests/super_errors/expected/bigint_match_literal.res.expected b/jscomp/build_tests/super_errors/expected/bigint_match_literal.res.expected new file mode 100644 index 0000000000..2093c55797 --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/bigint_match_literal.res.expected @@ -0,0 +1,11 @@ + + Warning number 11 + /.../fixtures/bigint_match_literal.res:3:3-4 + + 1 │ let m1 = switch 1n { + 2 │ | 0001n => 1 + 3 │ | 1n => 1 + 4 │ | -0001n => -1 + 5 │ | _ => 0 + + this match case is unused. \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/warnings4.res.expected b/jscomp/build_tests/super_errors/expected/warnings4.res.expected index 8591875997..f294e441b1 100644 --- a/jscomp/build_tests/super_errors/expected/warnings4.res.expected +++ b/jscomp/build_tests/super_errors/expected/warnings4.res.expected @@ -10,4 +10,4 @@ 14 │ You forgot to handle a possible case here, for example: - | #second(_) | #fourth | #third + | #second(_) | #fourth | #third \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/warnings5.res.expected b/jscomp/build_tests/super_errors/expected/warnings5.res.expected index 1cb0e9757d..204f9f1608 100644 --- a/jscomp/build_tests/super_errors/expected/warnings5.res.expected +++ b/jscomp/build_tests/super_errors/expected/warnings5.res.expected @@ -187,4 +187,4 @@ Either bind these labels explicitly or add ', _' to the pattern. 60 │ You forgot to handle a possible case here, for example: - | (_, true) + | (_, true) \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/fixtures/bigint_match_literal.res b/jscomp/build_tests/super_errors/fixtures/bigint_match_literal.res new file mode 100644 index 0000000000..ee0e07ffb8 --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/bigint_match_literal.res @@ -0,0 +1,6 @@ +let m1 = switch 1n { +| 0001n => 1 +| 1n => 1 +| -0001n => -1 +| _ => 0 +} diff --git a/jscomp/ext/ext_string.ml b/jscomp/ext/ext_string.ml index ae2b0e5694..dcc7ab00e4 100644 --- a/jscomp/ext/ext_string.ml +++ b/jscomp/ext/ext_string.ml @@ -528,43 +528,3 @@ let hash_number_as_i32_exn let first_marshal_char (x : string) = x <> "" && ( String.unsafe_get x 0 = '\132') - -(* - Removes leading zeros from the string only if the first non-zero character - encountered is a digit. Unlike int and float, bigint cannot be of_string, so - This function removes only leading 0s. Instead, values like 00x1 are not converted - and are intended to be syntax errors. - - 000n -> 0n - 001n -> 1n - 01_000_000n -> 1000000n - 0x1 -> 0x1n - 0x001n -> 0x001n - -00100n -> -100n - - The following values are syntax errors - - 00o1n -> 00o1n - 00x1_000_000n -> 00x1000000n -*) -let remove_leading_zeros str = - let aux str = - let len = String.length str in - if len = 0 then "" - else - let is_digit c = c >= '0' && c <= '9' in - let idx = ref 0 in - while !idx < len && str.[!idx] = '0' do - incr idx - done; - if !idx >= len then "0" (* If the string contains only '0's, return '0'. *) - else if (is_digit str.[!idx]) then String.sub str !idx (len - !idx) (* Remove leading zeros and return the rest of the string. *) - else str - in - (* Replace the delimiters '_' inside number *) - let str = String.concat "" (String.split_on_char '_' str) in - (* Check if negative *) - let starts_with_minus = str <> "" && str.[0] = '-' in - let str = if starts_with_minus then String.sub str 1 (String.length str - 1) else str in - let processed_str = aux str in - if starts_with_minus then "-" ^ processed_str else processed_str diff --git a/jscomp/ext/ext_string.mli b/jscomp/ext/ext_string.mli index 354c9c221e..7099464a23 100644 --- a/jscomp/ext/ext_string.mli +++ b/jscomp/ext/ext_string.mli @@ -224,5 +224,3 @@ val hash_number_as_i32_exn: val first_marshal_char: string -> bool - -val remove_leading_zeros: string -> string diff --git a/jscomp/ml/bigint_utils.ml b/jscomp/ml/bigint_utils.ml new file mode 100644 index 0000000000..a243f9fb6f --- /dev/null +++ b/jscomp/ml/bigint_utils.ml @@ -0,0 +1,71 @@ +(* + Removes leading zeros from the string only if the first non-zero character + encountered is a digit. Unlike int and float, bigint cannot be of_string, so + This function removes only leading 0s. Instead, values like 00x1 are not converted + and are intended to be syntax errors. + + 000n -> 0n + 001n -> 1n + 01_000_000n -> 1000000n + 0x1 -> 0x1n + 0x001n -> 0x001n + -00100n -> -100n + + The following values are syntax errors + + 00o1n -> 00o1n + 00x1_000_000n -> 00x1000000n +*) +let remove_leading_zeros str = + let aux str = + let len = String.length str in + if len = 0 then "" + else + let is_digit c = c >= '0' && c <= '9' in + let idx = ref 0 in + while !idx < len && str.[!idx] = '0' do + incr idx + done; + if !idx >= len then "0" (* If the string contains only '0's, return '0'. *) + else if (is_digit str.[!idx]) then String.sub str !idx (len - !idx) (* Remove leading zeros and return the rest of the string. *) + else str + in + (* Replace the delimiters '_' inside number *) + let str = String.concat "" (String.split_on_char '_' str) in + (* Check if negative *) + let starts_with_minus = str <> "" && str.[0] = '-' in + let str = if starts_with_minus then String.sub str 1 (String.length str - 1) else str in + let processed_str = aux str in + if starts_with_minus then "-" ^ processed_str else processed_str + +let is_numeric s = + let len = String.length s in + if len = 0 then false + else + let is_digit c = c >= '0' && c <= '9' in + let first_char = s.[0] in + if first_char <> '-' && not (is_digit first_char) then false + else + let rec check idx = + if idx >= len then true + else + let c = s.[idx] in + if is_digit c then check (idx + 1) + else false + in + check 1 + +let compare s0 s1 = + (* check if negative *) + let is_neg s = String.length s > 0 && s.[0] = '-' in + match (is_neg s0, is_neg s1) with + | (true, false) -> -1 (* If only s0 is negative, it's smaller. *) + | (false, true) -> 1 (* If only s1 is negative, s0 is larger. *) + | _ -> + (* If both numbers are either negative or positive, compare their lengths. *) + let len0, len1 = (String.length s0, String.length s1) in + if len0 = len1 then String.compare s0 s1 (* If lengths are equal, compare the strings directly. *) + else if len0 > len1 then + if is_neg s0 then -1 else 1 (* A longer s0 means it's larger unless it's negative. *) + else (* len0 < len1 *) + if is_neg s1 then 1 else -1 (* A longer s1 means s0 is smaller unless s1 is negative. *) diff --git a/jscomp/ml/bigint_utils.mli b/jscomp/ml/bigint_utils.mli new file mode 100644 index 0000000000..cb8f9bbb29 --- /dev/null +++ b/jscomp/ml/bigint_utils.mli @@ -0,0 +1,3 @@ +val remove_leading_zeros : string -> string +val is_numeric : string -> bool +val compare : string -> string -> int diff --git a/jscomp/ml/parmatch.ml b/jscomp/ml/parmatch.ml index 46030055e7..5e96ccae3d 100644 --- a/jscomp/ml/parmatch.ml +++ b/jscomp/ml/parmatch.ml @@ -264,6 +264,8 @@ let const_compare x y = match x,y with | Const_float f1, Const_float f2 -> compare (float_of_string f1) (float_of_string f2) + | Const_bigint b1, Const_bigint b2 -> + Bigint_utils.compare b1 b2 | Const_string (s1, _), Const_string (s2, _) -> String.compare s1 s2 | _, _ -> compare x y diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index c069ec87a5..e3fa7b22e9 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -76,6 +76,7 @@ type error = | Empty_record_literal | Uncurried_arity_mismatch of type_expr * int * int | Field_not_optional of string * type_expr + | Invalid_decimal of string exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -259,7 +260,10 @@ let constant : Parsetree.constant -> (Asttypes.constant, error) result = try Ok (Const_int64 (Misc.Int_literal_converter.int64 i)) with Failure _ -> Error (Literal_overflow "int64") end - | Pconst_integer (i,Some 'n') ->Ok (Const_bigint (Ext_string.remove_leading_zeros i)) + | Pconst_integer (i,Some 'n') -> + if Bigint_utils.is_numeric i then + Ok (Const_bigint (Bigint_utils.remove_leading_zeros i)) + else Error (Invalid_decimal i) | Pconst_integer (i,Some c) -> Error (Unknown_literal (i, c)) | Pconst_char c -> Ok (Const_char c) | Pconst_string (s,d) -> Ok (Const_string (s,d)) @@ -4075,6 +4079,9 @@ let report_error env ppf = function fprintf ppf "Field @{%s@} is not optional in type %a. Use without ?" name type_expr typ + | Invalid_decimal s -> + fprintf ppf + "Invalid decimal literal '%sn'. Only decimal literal is allowed for bigint" s let super_report_error_no_wrap_printing_env = report_error diff --git a/jscomp/ml/typecore.mli b/jscomp/ml/typecore.mli index 650bae0d5f..861c52fac6 100644 --- a/jscomp/ml/typecore.mli +++ b/jscomp/ml/typecore.mli @@ -111,6 +111,7 @@ type error = | Empty_record_literal | Uncurried_arity_mismatch of type_expr * int * int | Field_not_optional of string * type_expr + | Invalid_decimal of string exception Error of Location.t * Env.t * error exception Error_forward of Location.error diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res b/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res index 9789195cf8..e1fbc64bd9 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res +++ b/jscomp/syntax/tests/parsing/grammar/expressions/bigint.res @@ -8,9 +8,6 @@ 289n - 138n -0x1n -0b1n -0o1n 0100n 001_000_000n -000100n diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js index 14bd8d5674..dbb3aedc1a 100644 --- a/jscomp/test/bigint_test.js +++ b/jscomp/test/bigint_test.js @@ -110,55 +110,43 @@ Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 36, charac Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 37, characters 5-12", Caml_obj.compare(1n, 1n), 0); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 38, characters 5-12", Caml.bigint_compare(0x1n, 0x001n), 0); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 38, characters 5-12", true, true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 39, characters 5-12", Caml_obj.compare(0x1n, 0x001n), 0); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 39, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 40, characters 5-12", Caml.bigint_compare(-0x1n, 0x001n), -1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 40, characters 5-12", false, false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 41, characters 5-12", Caml_obj.compare(-0x1n, 0x001n), -1); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 41, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 42, characters 5-12", true, true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 42, characters 5-12", false, false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 43, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 43, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 44, characters 5-12", false, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 44, characters 5-12", true, true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 45, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 49, characters 5-12", Caml_obj.equal(3n, 3n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 46, characters 5-12", false, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 54, characters 5-12", true, true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 47, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 59, characters 5-12", Caml_obj.equal(3n, 3n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 48, characters 5-12", true, true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 64, characters 5-12", 9n & 1n, 1n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 53, characters 5-12", Caml_obj.equal(3n, 3n), true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 65, characters 5-12", 9n | 1n, 9n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 58, characters 5-12", true, true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 66, characters 5-12", 9n ^ 1n, 8n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 63, characters 5-12", Caml_obj.equal(3n, 3n), true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 67, characters 5-12", (9n << 1n), 18n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 68, characters 5-12", true, true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 68, characters 5-12", (9n << -1n), 4n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 73, characters 5-12", Caml_obj.equal(3n, 3n), true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 69, characters 5-12", (9n >> 1n), 4n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 78, characters 5-12", 9n & 1n, 1n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 70, characters 5-12", (9n >> -1n), 18n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 79, characters 5-12", 9n | 1n, 9n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 71, characters 5-12", (-9n >> 1n), -5n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 80, characters 5-12", 9n ^ 1n, 8n); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 81, characters 5-12", (9n << 1n), 18n); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 82, characters 5-12", (9n << -1n), 4n); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 83, characters 5-12", (9n >> 1n), 4n); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 84, characters 5-12", (9n >> -1n), 18n); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 85, characters 5-12", (-9n >> 1n), -5n); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 86, characters 5-12", (-9n >> -1n), -18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 72, characters 5-12", (-9n >> -1n), -18n); Mt.from_pair_suites("Bigint_test", suites.contents); diff --git a/jscomp/test/bigint_test.res b/jscomp/test/bigint_test.res index 135b0acbb1..f5410889dc 100644 --- a/jscomp/test/bigint_test.res +++ b/jscomp/test/bigint_test.res @@ -35,10 +35,6 @@ let () = { eq(__LOC__, generic_compare(1n, 02n), -1) eq(__LOC__, bigint_compare(1n, 001n), 0) eq(__LOC__, generic_compare(1n, 001n), 0) - eq(__LOC__, bigint_compare(0x1n, 0x001n), 0) - eq(__LOC__, generic_compare(0x1n, 0x001n), 0) - eq(__LOC__, bigint_compare(-0x1n, 0x001n), -1) - eq(__LOC__, generic_compare(-0x1n, 0x001n), -1) eq(__LOC__, bigint_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true) eq(__LOC__, generic_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true) eq(__LOC__, bigint_equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false) @@ -65,16 +61,6 @@ let () = { |2n => 4n |_ => 0n }, 3n), true) - eq(__LOC__, bigint_equal(switch 0x1n { - |0x1n => 3n - |0b1n => 4n - |_ => 0n - }, 3n), true) - eq(__LOC__, generic_equal(switch 0x1n { - |0x1n => 3n - |0b1n => 4n - |_ => 0n - }, 3n), true) eq(__LOC__, bigint_land(9n, 1n), 1n) eq(__LOC__, bigint_lor(9n, 1n), 9n) eq(__LOC__, bigint_lxor(9n, 1n), 8n) From 0d40dd9f74ce300f33f5a137b0e32e836c847fd3 Mon Sep 17 00:00:00 2001 From: mununki Date: Sat, 23 Mar 2024 15:15:00 +0900 Subject: [PATCH 36/45] fix test --- .../tests/parsing/grammar/expressions/expected/bigint.res.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt b/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt index c7ebbf3fc1..eea35a4f9c 100644 --- a/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt +++ b/jscomp/syntax/tests/parsing/grammar/expressions/expected/bigint.res.txt @@ -3,9 +3,6 @@ ;;2n ** 2n ;;10n + 54 ;;289n - 138n -;;0x1n -;;0b1n -;;0o1n ;;0100n ;;001_000_000n ;;(-000100n) \ No newline at end of file From 79c7013a4df3f005470491c3b2b40cf4fe7d5da5 Mon Sep 17 00:00:00 2001 From: mununki Date: Sat, 23 Mar 2024 20:57:39 +0900 Subject: [PATCH 37/45] handle delimiter '_' --- jscomp/ml/bigint_utils.ml | 2 +- jscomp/test/bigint_test.js | 22 +++++++++++++--------- jscomp/test/bigint_test.res | 10 ++++++++++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/jscomp/ml/bigint_utils.ml b/jscomp/ml/bigint_utils.ml index a243f9fb6f..4a8ce4f626 100644 --- a/jscomp/ml/bigint_utils.ml +++ b/jscomp/ml/bigint_utils.ml @@ -42,7 +42,7 @@ let is_numeric s = let len = String.length s in if len = 0 then false else - let is_digit c = c >= '0' && c <= '9' in + let is_digit c = (c >= '0' && c <= '9') || c = '_' in let first_char = s.[0] in if first_char <> '-' && not (is_digit first_char) then false else diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js index dbb3aedc1a..6fb98e750c 100644 --- a/jscomp/test/bigint_test.js +++ b/jscomp/test/bigint_test.js @@ -130,23 +130,27 @@ Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 54, charac Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 59, characters 5-12", Caml_obj.equal(3n, 3n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 64, characters 5-12", 9n & 1n, 1n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 64, characters 5-12", true, true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 65, characters 5-12", 9n | 1n, 9n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 69, characters 5-12", Caml_obj.equal(3n, 3n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 66, characters 5-12", 9n ^ 1n, 8n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 74, characters 5-12", 9n & 1n, 1n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 67, characters 5-12", (9n << 1n), 18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 75, characters 5-12", 9n | 1n, 9n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 68, characters 5-12", (9n << -1n), 4n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 76, characters 5-12", 9n ^ 1n, 8n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 69, characters 5-12", (9n >> 1n), 4n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 77, characters 5-12", (9n << 1n), 18n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 70, characters 5-12", (9n >> -1n), 18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 78, characters 5-12", (9n << -1n), 4n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 71, characters 5-12", (-9n >> 1n), -5n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 79, characters 5-12", (9n >> 1n), 4n); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 72, characters 5-12", (-9n >> -1n), -18n); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 80, characters 5-12", (9n >> -1n), 18n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 81, characters 5-12", (-9n >> 1n), -5n); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 82, characters 5-12", (-9n >> -1n), -18n); Mt.from_pair_suites("Bigint_test", suites.contents); diff --git a/jscomp/test/bigint_test.res b/jscomp/test/bigint_test.res index f5410889dc..e2439c7798 100644 --- a/jscomp/test/bigint_test.res +++ b/jscomp/test/bigint_test.res @@ -61,6 +61,16 @@ let () = { |2n => 4n |_ => 0n }, 3n), true) + eq(__LOC__, bigint_equal(switch -0001_000n { + |-00001000n => 3n + |-0002n => 4n + |_ => 0n + }, 3n), true) + eq(__LOC__, generic_equal(switch -0001_000n { + |-00001000n => 3n + |-0002n => 4n + |_ => 0n + }, 3n), true) eq(__LOC__, bigint_land(9n, 1n), 1n) eq(__LOC__, bigint_lor(9n, 1n), 9n) eq(__LOC__, bigint_lxor(9n, 1n), 8n) From 5748e83d91b26b11d23a0ead6756823324c5023a Mon Sep 17 00:00:00 2001 From: mununki Date: Sun, 24 Mar 2024 04:25:59 +0900 Subject: [PATCH 38/45] throw Division_by_zero in bigint div, mod --- jscomp/core/js_exp_make.ml | 18 ++++++++--- jscomp/core/js_exp_make.mli | 4 +++ jscomp/core/lam.ml | 8 +---- jscomp/core/lam_compile_primitive.ml | 10 ++++-- jscomp/core/lam_dispatch_primitive.ml | 8 +++++ jscomp/ext/js_runtime_modules.ml | 2 ++ jscomp/ml/printlambda.ml | 4 +-- jscomp/runtime/caml_bigint.res | 37 +++++++++++++++++++++ jscomp/runtime/caml_bigint.resi | 27 ++++++++++++++++ jscomp/runtime/caml_bigint_extern.res | 2 ++ jscomp/runtime/release.ninja | 5 ++- jscomp/test/bigint_test.js | 46 +++++++++++++++++++-------- lib/es6/caml_bigint.js | 28 ++++++++++++++++ lib/es6/caml_bigint_extern.js | 1 + lib/js/caml_bigint.js | 26 +++++++++++++++ lib/js/caml_bigint_extern.js | 1 + packages/artifacts.txt | 4 +++ 17 files changed, 200 insertions(+), 31 deletions(-) create mode 100644 jscomp/runtime/caml_bigint.res create mode 100644 jscomp/runtime/caml_bigint.resi create mode 100644 jscomp/runtime/caml_bigint_extern.res create mode 100644 lib/es6/caml_bigint.js create mode 100644 lib/es6/caml_bigint_extern.js create mode 100644 lib/js/caml_bigint.js create mode 100644 lib/js/caml_bigint_extern.js diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index b780803e69..7bf97299f3 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -787,7 +787,6 @@ let rec float_equal ?comment (e0 : t) (e1 : t) : t = float_equal ?comment a e1 | Number (Float { f = f0; _ }), Number (Float { f = f1 }) when f0 = f1 -> true_ - | Number (Bigint { i = i0 }), Number (Bigint { i = i1 }) -> bool (i0 = i1) | _ -> { expression_desc = Bin (EqEqEq, e0, e1); comment } let int_equal = float_equal @@ -1263,10 +1262,19 @@ let rec int32_band ?comment (e1 : J.expression) (e2 : J.expression) : let bigint_op ?comment op (e1: t) (e2: t) = bin ?comment op e1 e2 let bigint_comp (cmp : Lam_compat.comparison) ?comment (e0: t) (e1: t) = - match (cmp, e0.expression_desc, e1.expression_desc) with - | Ceq, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 = i1) - | Cneq, Number (Bigint {i = i0; _}), Number (Bigint {i = i1; _}) -> bool (i0 <> i1) - | _ -> bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1 + bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1 + +let bigint_div ~checked ?comment (e0: t) (e1: t) = + if checked then + runtime_call Js_runtime_modules.bigint "div" [e0; e1] + else + bigint_op ?comment Div e0 e1 + +let bigint_mod ~checked ?comment (e0: t) (e1: t) = + if checked then + runtime_call Js_runtime_modules.bigint "mod_" [e0; e1] + else + bigint_op ?comment Mod e0 e1 (* TODO -- alpha conversion remember to add parens.. diff --git a/jscomp/core/js_exp_make.mli b/jscomp/core/js_exp_make.mli index 0c071f1dc8..7bd05f8835 100644 --- a/jscomp/core/js_exp_make.mli +++ b/jscomp/core/js_exp_make.mli @@ -280,6 +280,10 @@ val bigint_op : ?comment: string -> Js_op.binop -> t -> t -> t val bigint_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t +val bigint_div : checked:bool -> ?comment:string -> t -> t -> t + +val bigint_mod : checked:bool -> ?comment:string -> t -> t -> t + val js_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t val not : t -> t diff --git a/jscomp/core/lam.ml b/jscomp/core/lam.ml index 8b8d11a83b..b01536943e 100644 --- a/jscomp/core/lam.ml +++ b/jscomp/core/lam.ml @@ -506,13 +506,7 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t = (* FIXME: could raise? *) Lift.bool (Lam_compat.cmp_float cmp (float_of_string a) (float_of_string b)) - | Pbigintcomp cmp, Const_bigint a, Const_bigint b -> - (match cmp with - | Ceq -> - Lift.bool (a = b) - | Cneq -> - Lift.bool (a <> b) - |_ -> default ()) + | Pbigintcomp cmp, Const_bigint a, Const_bigint b -> default () | Pintcomp ((Ceq | Cneq) as op), Const_pointer a, Const_pointer b -> Lift.bool (match op with diff --git a/jscomp/core/lam_compile_primitive.ml b/jscomp/core/lam_compile_primitive.ml index e7752b8fa9..33e7db0e6d 100644 --- a/jscomp/core/lam_compile_primitive.ml +++ b/jscomp/core/lam_compile_primitive.ml @@ -214,13 +214,19 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) | [ e1; e2 ] -> E.int32_div ~checked:!Js_config.check_div_by_zero e1 e2 | _ -> assert false) | Pdivint64 -> Js_long.div args - | Pdivbigint -> (match args with [ e1; e2 ] -> E.bigint_op Div e1 e2 | _ -> assert false) + | Pdivbigint -> ( + match args with + | [ e1; e2 ] -> E.bigint_div ~checked:!Js_config.check_div_by_zero e1 e2 + | _ -> assert false) | Pmodint -> ( match args with | [ e1; e2 ] -> E.int32_mod ~checked:!Js_config.check_div_by_zero e1 e2 | _ -> assert false) | Pmodint64 -> Js_long.mod_ args - | Pmodbigint -> (match args with [ e1; e2 ] -> E.bigint_op Mod e1 e2 | _ -> assert false) + | Pmodbigint -> ( + match args with + | [ e1; e2 ] -> E.bigint_mod ~checked:!Js_config.check_div_by_zero e1 e2 + | _ -> assert false) | Ppowbigint -> (match args with [ e1; e2 ] -> E.bigint_op Pow e1 e2 | _ -> assert false) | Plslint -> ( match args with [ e1; e2 ] -> E.int32_lsl e1 e2 | _ -> assert false) diff --git a/jscomp/core/lam_dispatch_primitive.ml b/jscomp/core/lam_dispatch_primitive.ml index a719e1ce2a..8f7823720e 100644 --- a/jscomp/core/lam_dispatch_primitive.ml +++ b/jscomp/core/lam_dispatch_primitive.ml @@ -252,6 +252,14 @@ let translate loc (prim_name : string) (args : J.expression list) : J.expression match args with | [ e1; e2 ] -> E.unchecked_int32_mul e1 e2 | _ -> assert false) + | "?bigint_div" -> ( + match args with + | [ e1; e2 ] -> E.bigint_div e1 e2 ~checked:false + | _ -> assert false) + | "?bigint_mod" -> ( + match args with + | [ e1; e2 ] -> E.bigint_mod e1 e2 ~checked:false + | _ -> assert false) | "?await" -> ( match args with | [e] -> {e with expression_desc = Await e} diff --git a/jscomp/ext/js_runtime_modules.ml b/jscomp/ext/js_runtime_modules.ml index a962e15003..9c2b3b9eac 100644 --- a/jscomp/ext/js_runtime_modules.ml +++ b/jscomp/ext/js_runtime_modules.ml @@ -59,6 +59,8 @@ let md5 = "Caml_md5" let int32 = "Caml_int32" +let bigint = "Caml_bigint" + let option = "Caml_option" let module_ = "Caml_module" diff --git a/jscomp/ml/printlambda.ml b/jscomp/ml/printlambda.ml index ded3c57226..fb63e2ce35 100644 --- a/jscomp/ml/printlambda.ml +++ b/jscomp/ml/printlambda.ml @@ -187,8 +187,8 @@ let primitive ppf = function | Pxorbigint -> fprintf ppf "xor" | Plslbigint -> fprintf ppf "lsl" | Pasrbigint -> fprintf ppf "asr" - | Pdivbigint Safe -> fprintf ppf "/n" - | Pdivbigint Unsafe -> fprintf ppf "/nu" + | Pdivbigint Safe -> fprintf ppf "/" + | Pdivbigint Unsafe -> fprintf ppf "/u" | Pmodbigint Safe -> fprintf ppf "mod" | Pmodbigint Unsafe -> fprintf ppf "mod_unsafe" | Pbigintcomp(Ceq) -> fprintf ppf "==," diff --git a/jscomp/runtime/caml_bigint.res b/jscomp/runtime/caml_bigint.res new file mode 100644 index 0000000000..bf78dcef84 --- /dev/null +++ b/jscomp/runtime/caml_bigint.res @@ -0,0 +1,37 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +let div = (x: bigint, y: bigint) => + if y == 0n { + raise(Division_by_zero) + } else { + Caml_bigint_extern.div(x, y) + } + +let mod_ = (x: bigint, y: bigint) => + if y == 0n { + raise(Division_by_zero) + } else { + Caml_bigint_extern.rem(x, y) + } diff --git a/jscomp/runtime/caml_bigint.resi b/jscomp/runtime/caml_bigint.resi new file mode 100644 index 0000000000..386a1ab992 --- /dev/null +++ b/jscomp/runtime/caml_bigint.resi @@ -0,0 +1,27 @@ +/* Copyright (C) 2015-2016 Bloomberg Finance L.P. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * In addition to the permissions granted to you by the LGPL, you may combine + * or link a "work that uses the Library" with a publicly distributed version + * of this file to produce a combined library or application, then distribute + * that combined work under the terms of your choosing, with no requirement + * to comply with the obligations normally placed on you by section 4 of the + * LGPL version 3 (or the corresponding section of a later version of the LGPL + * should you choose to use a later version). + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +let div: (bigint, bigint) => bigint + +let mod_: (bigint, bigint) => bigint diff --git a/jscomp/runtime/caml_bigint_extern.res b/jscomp/runtime/caml_bigint_extern.res new file mode 100644 index 0000000000..33f0c432d2 --- /dev/null +++ b/jscomp/runtime/caml_bigint_extern.res @@ -0,0 +1,2 @@ +external div: (bigint, bigint) => bigint = "?bigint_div" +external rem: (bigint, bigint) => bigint = "?bigint_mod" diff --git a/jscomp/runtime/release.ninja b/jscomp/runtime/release.ninja index 864f9c5a77..d21ca55b4d 100644 --- a/jscomp/runtime/release.ninja +++ b/jscomp/runtime/release.ninja @@ -17,6 +17,8 @@ o runtime/caml.cmj : cc_cmi runtime/caml.res | runtime/caml.cmi runtime/caml_int o runtime/caml.cmi : cc runtime/caml.resi | runtime/bs_stdlib_mini.cmi runtime/caml_int64_extern.cmj runtime/js.cmi runtime/js.cmj o runtime/caml_array.cmj : cc_cmi runtime/caml_array.res | runtime/caml_array.cmi runtime/caml_array_extern.cmj o runtime/caml_array.cmi : cc runtime/caml_array.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj +o runtime/caml_bigint.cmj : cc_cmi runtime/caml_bigint.res | runtime/caml_bigint.cmi runtime/caml_bigint_extern.cmj +o runtime/caml_bigint.cmi : cc runtime/caml_bigint.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_bytes.cmj : cc_cmi runtime/caml_bytes.res | runtime/caml_bytes.cmi o runtime/caml_bytes.cmi : cc runtime/caml_bytes.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_exceptions.cmj : cc_cmi runtime/caml_exceptions.res | runtime/caml_exceptions.cmi runtime/js.cmj @@ -52,6 +54,7 @@ o runtime/caml_string.cmi : cc runtime/caml_string.resi | runtime/bs_stdlib_mini o runtime/caml_sys.cmj : cc_cmi runtime/caml_sys.res | runtime/caml_array_extern.cmj runtime/caml_sys.cmi runtime/caml_undefined_extern.cmj runtime/js.cmj o runtime/caml_sys.cmi : cc runtime/caml_sys.resi | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_array_extern.cmi runtime/caml_array_extern.cmj : cc runtime/caml_array_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj +o runtime/caml_bigint_extern.cmi runtime/caml_bigint_extern.cmj : cc runtime/caml_bigint_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_external_polyfill.cmi runtime/caml_external_polyfill.cmj : cc runtime/caml_external_polyfill.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_float_extern.cmi runtime/caml_float_extern.cmj : cc runtime/caml_float_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_int64_extern.cmi runtime/caml_int64_extern.cmj : cc runtime/caml_int64_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj @@ -60,4 +63,4 @@ o runtime/caml_nativeint_extern.cmi runtime/caml_nativeint_extern.cmj : cc runti o runtime/caml_string_extern.cmi runtime/caml_string_extern.cmj : cc runtime/caml_string_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/caml_undefined_extern.cmi runtime/caml_undefined_extern.cmj : cc runtime/caml_undefined_extern.res | runtime/bs_stdlib_mini.cmi runtime/js.cmi runtime/js.cmj o runtime/curry.cmi runtime/curry.cmj : cc runtime/curry.res | runtime/bs_stdlib_mini.cmi runtime/caml_array.cmj runtime/caml_array_extern.cmj runtime/js.cmi runtime/js.cmj -o runtime : phony runtime/bs_stdlib_mini.cmi runtime/js.cmj runtime/js.cmi runtime/caml.cmi runtime/caml.cmj runtime/caml_array.cmi runtime/caml_array.cmj runtime/caml_bytes.cmi runtime/caml_bytes.cmj runtime/caml_exceptions.cmi runtime/caml_exceptions.cmj runtime/caml_float.cmi runtime/caml_float.cmj runtime/caml_format.cmi runtime/caml_format.cmj runtime/caml_hash.cmi runtime/caml_hash.cmj runtime/caml_hash_primitive.cmi runtime/caml_hash_primitive.cmj runtime/caml_int32.cmi runtime/caml_int32.cmj runtime/caml_int64.cmi runtime/caml_int64.cmj runtime/caml_lexer.cmi runtime/caml_lexer.cmj runtime/caml_md5.cmi runtime/caml_md5.cmj runtime/caml_module.cmi runtime/caml_module.cmj runtime/caml_obj.cmi runtime/caml_obj.cmj runtime/caml_option.cmi runtime/caml_option.cmj runtime/caml_parser.cmi runtime/caml_parser.cmj runtime/caml_splice_call.cmi runtime/caml_splice_call.cmj runtime/caml_string.cmi runtime/caml_string.cmj runtime/caml_sys.cmi runtime/caml_sys.cmj runtime/caml_array_extern.cmi runtime/caml_array_extern.cmj runtime/caml_external_polyfill.cmi runtime/caml_external_polyfill.cmj runtime/caml_float_extern.cmi runtime/caml_float_extern.cmj runtime/caml_int64_extern.cmi runtime/caml_int64_extern.cmj runtime/caml_js_exceptions.cmi runtime/caml_js_exceptions.cmj runtime/caml_nativeint_extern.cmi runtime/caml_nativeint_extern.cmj runtime/caml_string_extern.cmi runtime/caml_string_extern.cmj runtime/caml_undefined_extern.cmi runtime/caml_undefined_extern.cmj runtime/curry.cmi runtime/curry.cmj +o runtime : phony runtime/bs_stdlib_mini.cmi runtime/js.cmj runtime/js.cmi runtime/caml.cmi runtime/caml.cmj runtime/caml_array.cmi runtime/caml_array.cmj runtime/caml_bigint.cmi runtime/caml_bigint.cmj runtime/caml_bytes.cmi runtime/caml_bytes.cmj runtime/caml_exceptions.cmi runtime/caml_exceptions.cmj runtime/caml_float.cmi runtime/caml_float.cmj runtime/caml_format.cmi runtime/caml_format.cmj runtime/caml_hash.cmi runtime/caml_hash.cmj runtime/caml_hash_primitive.cmi runtime/caml_hash_primitive.cmj runtime/caml_int32.cmi runtime/caml_int32.cmj runtime/caml_int64.cmi runtime/caml_int64.cmj runtime/caml_lexer.cmi runtime/caml_lexer.cmj runtime/caml_md5.cmi runtime/caml_md5.cmj runtime/caml_module.cmi runtime/caml_module.cmj runtime/caml_obj.cmi runtime/caml_obj.cmj runtime/caml_option.cmi runtime/caml_option.cmj runtime/caml_parser.cmi runtime/caml_parser.cmj runtime/caml_splice_call.cmi runtime/caml_splice_call.cmj runtime/caml_string.cmi runtime/caml_string.cmj runtime/caml_sys.cmi runtime/caml_sys.cmj runtime/caml_array_extern.cmi runtime/caml_array_extern.cmj runtime/caml_bigint_extern.cmi runtime/caml_bigint_extern.cmj runtime/caml_external_polyfill.cmi runtime/caml_external_polyfill.cmj runtime/caml_float_extern.cmi runtime/caml_float_extern.cmj runtime/caml_int64_extern.cmi runtime/caml_int64_extern.cmj runtime/caml_js_exceptions.cmi runtime/caml_js_exceptions.cmj runtime/caml_nativeint_extern.cmi runtime/caml_nativeint_extern.cmj runtime/caml_string_extern.cmi runtime/caml_string_extern.cmj runtime/caml_undefined_extern.cmi runtime/caml_undefined_extern.cmj runtime/curry.cmi runtime/curry.cmj diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js index 6fb98e750c..83a1da1a8c 100644 --- a/jscomp/test/bigint_test.js +++ b/jscomp/test/bigint_test.js @@ -110,29 +110,47 @@ Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 36, charac Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 37, characters 5-12", Caml_obj.compare(1n, 1n), 0); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 38, characters 5-12", true, true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 38, characters 5-12", 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n === 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, true); Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 39, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), true); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 40, characters 5-12", false, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 40, characters 5-12", 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n === 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n, false); Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 41, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, 1000000000000000000000000000000000000000000000000000000000000000000000000000000000001n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 42, characters 5-12", false, false); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 42, characters 5-12", 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n === -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, false); Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 43, characters 5-12", Caml_obj.equal(1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n, -1000000000000000000000000000000000000000000000000000000000000000000000000000000000000n), false); -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 44, characters 5-12", true, true); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 49, characters 5-12", Caml_obj.equal(3n, 3n), true); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 54, characters 5-12", true, true); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 59, characters 5-12", Caml_obj.equal(3n, 3n), true); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 64, characters 5-12", true, true); - -Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 69, characters 5-12", Caml_obj.equal(3n, 3n), true); +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 44, characters 5-12", ( + 1n !== 1n ? ( + 1n !== 2n ? 0n : 4n + ) : 3n + ) === 3n, true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 49, characters 5-12", Caml_obj.equal(1n !== 1n ? ( + 1n !== 2n ? 0n : 4n + ) : 3n, 3n), true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 54, characters 5-12", ( + -1n !== -1n ? ( + -1n !== -2n ? 0n : 4n + ) : 3n + ) === 3n, true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 59, characters 5-12", Caml_obj.equal(-1n !== -1n ? ( + -1n !== 2n ? 0n : 4n + ) : 3n, 3n), true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 64, characters 5-12", ( + -1000n !== -1000n ? ( + -1000n !== -2n ? 0n : 4n + ) : 3n + ) === 3n, true); + +Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 69, characters 5-12", Caml_obj.equal(-1000n !== -1000n ? ( + -1000n !== -2n ? 0n : 4n + ) : 3n, 3n), true); Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 74, characters 5-12", 9n & 1n, 1n); diff --git a/lib/es6/caml_bigint.js b/lib/es6/caml_bigint.js new file mode 100644 index 0000000000..fa5d6c8c88 --- /dev/null +++ b/lib/es6/caml_bigint.js @@ -0,0 +1,28 @@ + + + +function div(x, y) { + if (y === 0n) { + throw { + RE_EXN_ID: "Division_by_zero", + Error: new Error() + }; + } + return x / y; +} + +function mod_(x, y) { + if (y === 0n) { + throw { + RE_EXN_ID: "Division_by_zero", + Error: new Error() + }; + } + return x % y; +} + +export { + div , + mod_ , +} +/* No side effect */ diff --git a/lib/es6/caml_bigint_extern.js b/lib/es6/caml_bigint_extern.js new file mode 100644 index 0000000000..ae1b9f17e6 --- /dev/null +++ b/lib/es6/caml_bigint_extern.js @@ -0,0 +1 @@ +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/lib/js/caml_bigint.js b/lib/js/caml_bigint.js new file mode 100644 index 0000000000..c3ecb2a28e --- /dev/null +++ b/lib/js/caml_bigint.js @@ -0,0 +1,26 @@ +'use strict'; + + +function div(x, y) { + if (y === 0n) { + throw { + RE_EXN_ID: "Division_by_zero", + Error: new Error() + }; + } + return x / y; +} + +function mod_(x, y) { + if (y === 0n) { + throw { + RE_EXN_ID: "Division_by_zero", + Error: new Error() + }; + } + return x % y; +} + +exports.div = div; +exports.mod_ = mod_; +/* No side effect */ diff --git a/lib/js/caml_bigint_extern.js b/lib/js/caml_bigint_extern.js new file mode 100644 index 0000000000..ae1b9f17e6 --- /dev/null +++ b/lib/js/caml_bigint_extern.js @@ -0,0 +1 @@ +/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/packages/artifacts.txt b/packages/artifacts.txt index 0fbc2e7676..88bf15a9b7 100644 --- a/packages/artifacts.txt +++ b/packages/artifacts.txt @@ -68,6 +68,8 @@ lib/es6/callback.js lib/es6/caml.js lib/es6/caml_array.js lib/es6/caml_array_extern.js +lib/es6/caml_bigint.js +lib/es6/caml_bigint_extern.js lib/es6/caml_bytes.js lib/es6/caml_exceptions.js lib/es6/caml_external_polyfill.js @@ -231,6 +233,8 @@ lib/js/callback.js lib/js/caml.js lib/js/caml_array.js lib/js/caml_array_extern.js +lib/js/caml_bigint.js +lib/js/caml_bigint_extern.js lib/js/caml_bytes.js lib/js/caml_exceptions.js lib/js/caml_external_polyfill.js From 4a43e396b908d50c938b0f421f174d40cb0ae966 Mon Sep 17 00:00:00 2001 From: mununki Date: Sun, 24 Mar 2024 04:45:32 +0900 Subject: [PATCH 39/45] call runtime only when dividing by zero --- jscomp/core/js_exp_make.ml | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index 7bf97299f3..6555068bc5 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -1265,16 +1265,22 @@ let bigint_comp (cmp : Lam_compat.comparison) ?comment (e0: t) (e1: t) = bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1 let bigint_div ~checked ?comment (e0: t) (e1: t) = - if checked then - runtime_call Js_runtime_modules.bigint "div" [e0; e1] - else - bigint_op ?comment Div e0 e1 + match e1.expression_desc with + | Number (Bigint { i = i1 }) when i1 = "0" || i1 = "-0" -> + if checked then + runtime_call Js_runtime_modules.bigint "div" [e0; e1] + else + bigint_op ?comment Div e0 e1 + | _ -> bigint_op ?comment Div e0 e1 let bigint_mod ~checked ?comment (e0: t) (e1: t) = - if checked then - runtime_call Js_runtime_modules.bigint "mod_" [e0; e1] - else - bigint_op ?comment Mod e0 e1 + match e1.expression_desc with + | Number (Bigint { i = i1 }) when i1 = "0" || i1 = "-0" -> + if checked then + runtime_call Js_runtime_modules.bigint "mod_" [e0; e1] + else + bigint_op ?comment Mod e0 e1 + | _ -> bigint_op ?comment Mod e0 e1 (* TODO -- alpha conversion remember to add parens.. From e7e41c492146ea31106448158598f59437cb8a91 Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 25 Mar 2024 17:58:45 +0900 Subject: [PATCH 40/45] fix incorrect dividing by zero with non constant --- jscomp/core/js_exp_make.ml | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index 6555068bc5..7bf97299f3 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -1265,22 +1265,16 @@ let bigint_comp (cmp : Lam_compat.comparison) ?comment (e0: t) (e1: t) = bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1 let bigint_div ~checked ?comment (e0: t) (e1: t) = - match e1.expression_desc with - | Number (Bigint { i = i1 }) when i1 = "0" || i1 = "-0" -> - if checked then - runtime_call Js_runtime_modules.bigint "div" [e0; e1] - else - bigint_op ?comment Div e0 e1 - | _ -> bigint_op ?comment Div e0 e1 + if checked then + runtime_call Js_runtime_modules.bigint "div" [e0; e1] + else + bigint_op ?comment Div e0 e1 let bigint_mod ~checked ?comment (e0: t) (e1: t) = - match e1.expression_desc with - | Number (Bigint { i = i1 }) when i1 = "0" || i1 = "-0" -> - if checked then - runtime_call Js_runtime_modules.bigint "mod_" [e0; e1] - else - bigint_op ?comment Mod e0 e1 - | _ -> bigint_op ?comment Mod e0 e1 + if checked then + runtime_call Js_runtime_modules.bigint "mod_" [e0; e1] + else + bigint_op ?comment Mod e0 e1 (* TODO -- alpha conversion remember to add parens.. From e8e80508fb66889061deec546ebb89a02b6fe288 Mon Sep 17 00:00:00 2001 From: mununki Date: Mon, 25 Mar 2024 18:08:10 +0900 Subject: [PATCH 41/45] remove is_safe from Pdivbigint, Pmodbigint --- jscomp/core/lam_convert.ml | 4 ++-- jscomp/ml/lambda.ml | 2 +- jscomp/ml/lambda.mli | 2 +- jscomp/ml/printlambda.ml | 10 ++++------ jscomp/ml/translcore.ml | 4 ++-- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/jscomp/core/lam_convert.ml b/jscomp/core/lam_convert.ml index 41caa4f7ae..8264a60310 100644 --- a/jscomp/core/lam_convert.ml +++ b/jscomp/core/lam_convert.ml @@ -258,8 +258,8 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t = | Paddbigint -> prim ~primitive:Paddbigint ~args loc | Psubbigint -> prim ~primitive:Psubbigint ~args loc | Pmulbigint -> prim ~primitive:Pmulbigint ~args loc - | Pdivbigint _is_safe (*FIXME*) -> prim ~primitive:Pdivbigint ~args loc - | Pmodbigint _is_safe (*FIXME*) -> prim ~primitive:Pmodbigint ~args loc + | Pdivbigint -> prim ~primitive:Pdivbigint ~args loc + | Pmodbigint -> prim ~primitive:Pmodbigint ~args loc | Ppowbigint -> prim ~primitive:Ppowbigint ~args loc | Pandbigint -> prim ~primitive:Pandbigint ~args loc | Porbigint -> prim ~primitive:Porbigint ~args loc diff --git a/jscomp/ml/lambda.ml b/jscomp/ml/lambda.ml index 0a9810e572..a73c8504d4 100644 --- a/jscomp/ml/lambda.ml +++ b/jscomp/ml/lambda.ml @@ -231,7 +231,7 @@ type primitive = | Pfloatcomp of comparison (* Bigint operations *) | Pnegbigint | Paddbigint | Psubbigint | Ppowbigint - | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe + | Pmulbigint | Pdivbigint | Pmodbigint | Pandbigint | Porbigint | Pxorbigint | Plslbigint | Pasrbigint | Pbigintcomp of comparison diff --git a/jscomp/ml/lambda.mli b/jscomp/ml/lambda.mli index 4fce136ac2..902bc4aa3e 100644 --- a/jscomp/ml/lambda.mli +++ b/jscomp/ml/lambda.mli @@ -197,7 +197,7 @@ type primitive = | Pfloatcomp of comparison (* Bigint operations *) | Pnegbigint | Paddbigint | Psubbigint | Ppowbigint - | Pmulbigint | Pdivbigint of is_safe | Pmodbigint of is_safe + | Pmulbigint | Pdivbigint | Pmodbigint | Pandbigint | Porbigint | Pxorbigint | Plslbigint | Pasrbigint | Pbigintcomp of comparison diff --git a/jscomp/ml/printlambda.ml b/jscomp/ml/printlambda.ml index fb63e2ce35..d967a30b8b 100644 --- a/jscomp/ml/printlambda.ml +++ b/jscomp/ml/printlambda.ml @@ -187,10 +187,8 @@ let primitive ppf = function | Pxorbigint -> fprintf ppf "xor" | Plslbigint -> fprintf ppf "lsl" | Pasrbigint -> fprintf ppf "asr" - | Pdivbigint Safe -> fprintf ppf "/" - | Pdivbigint Unsafe -> fprintf ppf "/u" - | Pmodbigint Safe -> fprintf ppf "mod" - | Pmodbigint Unsafe -> fprintf ppf "mod_unsafe" + | Pdivbigint -> fprintf ppf "/" + | Pmodbigint -> fprintf ppf "mod" | Pbigintcomp(Ceq) -> fprintf ppf "==," | Pbigintcomp(Cneq) -> fprintf ppf "!=," | Pbigintcomp(Clt) -> fprintf ppf "<," @@ -302,8 +300,8 @@ let name_of_primitive = function | Paddbigint -> "Paddbigint" | Psubbigint -> "Psubbigint" | Pmulbigint -> "Pmulbigint" - | Pdivbigint _ -> "Pdivbigint" - | Pmodbigint _ -> "Pmodbigint" + | Pdivbigint -> "Pdivbigint" + | Pmodbigint -> "Pmodbigint" | Ppowbigint -> "Ppowbigint" | Pandbigint -> "Pandbigint" | Porbigint -> "Porbigint" diff --git a/jscomp/ml/translcore.ml b/jscomp/ml/translcore.ml index 8c09dba446..9cf09f8134 100644 --- a/jscomp/ml/translcore.ml +++ b/jscomp/ml/translcore.ml @@ -374,9 +374,9 @@ let primitives_table = ("%addbigint", Paddbigint); ("%subbigint", Psubbigint); ("%mulbigint", Pmulbigint); - ("%divbigint", Pdivbigint Safe); + ("%divbigint", Pdivbigint); ("%powbigint", Ppowbigint); - ("%modbigint", Pmodbigint Safe); + ("%modbigint", Pmodbigint); ("%eqbigint", Pbigintcomp Ceq); ("%noteqbigint", Pbigintcomp Cneq); ("%ltbigint", Pbigintcomp Clt); From 5e963cd74fe6408ec29b5f2d9411b6ca19c462fe Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 26 Mar 2024 19:56:03 +0900 Subject: [PATCH 42/45] stale comments --- jscomp/ml/bigint_utils.ml | 2 -- jscomp/others/js_bigint.res | 19 +++++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/jscomp/ml/bigint_utils.ml b/jscomp/ml/bigint_utils.ml index 4a8ce4f626..ae3c4cb6a6 100644 --- a/jscomp/ml/bigint_utils.ml +++ b/jscomp/ml/bigint_utils.ml @@ -7,8 +7,6 @@ 000n -> 0n 001n -> 1n 01_000_000n -> 1000000n - 0x1 -> 0x1n - 0x001n -> 0x001n -00100n -> -100n The following values are syntax errors diff --git a/jscomp/others/js_bigint.res b/jscomp/others/js_bigint.res index 687f6700cb..66f83d9ba1 100644 --- a/jscomp/others/js_bigint.res +++ b/jscomp/others/js_bigint.res @@ -3,25 +3,32 @@ @val /** Parses the given `string` into a `bigint` using JavaScript semantics. Return the -number as a `bigint` if successfully parsed, `null`, `undefined`, `_NaN` otherwise. +number as a `bigint` if successfully parsed. Uncaught syntax exception otherwise. ## Examples ```rescript /* returns 123n */ -Js.Bigint.fromString("123") +Js.Bigint.fromStringExn("123") /* returns 0n */ -Js.Bigint.fromString("") +Js.Bigint.fromStringExn("") /* returns 17n */ -Js.Bigint.fromString("0x11") +Js.Bigint.fromStringExn("0x11") /* returns 3n */ -Js.Bigint.fromString("0b11") +Js.Bigint.fromStringExn("0b11") /* returns 9n */ -Js.Bigint.fromString("0o11") +Js.Bigint.fromStringExn("0o11") + +/* catch exception */ +try { + Js.Bigint.fromStringExn("a") +} catch { +| _ => ... +} ``` */ external fromStringExn: string => bigint = "BigInt" From 84eecd7d365e5b0c119c9883ede8eb9611140b7e Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 26 Mar 2024 20:17:50 +0900 Subject: [PATCH 43/45] fix bigint_utils.compare --- jscomp/ml/bigint_utils.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jscomp/ml/bigint_utils.ml b/jscomp/ml/bigint_utils.ml index ae3c4cb6a6..74908a8664 100644 --- a/jscomp/ml/bigint_utils.ml +++ b/jscomp/ml/bigint_utils.ml @@ -62,7 +62,8 @@ let compare s0 s1 = | _ -> (* If both numbers are either negative or positive, compare their lengths. *) let len0, len1 = (String.length s0, String.length s1) in - if len0 = len1 then String.compare s0 s1 (* If lengths are equal, compare the strings directly. *) + if len0 = len1 then + if is_neg s0 then String.compare s1 s0 else String.compare s0 s1 (* If lengths are equal, compare the strings directly. *) else if len0 > len1 then if is_neg s0 then -1 else 1 (* A longer s0 means it's larger unless it's negative. *) else (* len0 < len1 *) From 96521151bf649f64a41463e5d9696f680fd5f350 Mon Sep 17 00:00:00 2001 From: mununki Date: Tue, 26 Mar 2024 23:53:05 +0900 Subject: [PATCH 44/45] change bigint model to sign * string --- jscomp/core/js_analyzer.ml | 4 ++-- jscomp/core/js_dump.ml | 2 +- jscomp/core/js_exp_make.ml | 10 ++++++--- jscomp/core/js_exp_make.mli | 2 +- jscomp/core/js_op.ml | 4 +--- jscomp/core/lam.ml | 2 +- jscomp/core/lam_analysis.ml | 2 +- jscomp/core/lam_compile_const.ml | 2 +- jscomp/core/lam_constant_convert.ml | 2 +- jscomp/core/lam_print.ml | 2 +- jscomp/frontend/external_ffi_types.ml | 4 +++- jscomp/frontend/lam_constant.ml | 6 ++--- jscomp/frontend/lam_constant.mli | 2 +- jscomp/ml/asttypes.ml | 2 +- jscomp/ml/bigint_utils.ml | 32 ++++++++++++++++++--------- jscomp/ml/bigint_utils.mli | 6 ++++- jscomp/ml/parmatch.ml | 10 ++++----- jscomp/ml/printlambda.ml | 2 +- jscomp/ml/printtyped.ml | 2 +- jscomp/ml/typecore.ml | 10 +++------ jscomp/ml/typecore.mli | 1 - jscomp/ml/untypeast.ml | 3 ++- jscomp/syntax/src/res_core.ml | 6 +++++ jscomp/test/bigint_test.js | 6 ++--- 24 files changed, 72 insertions(+), 52 deletions(-) diff --git a/jscomp/core/js_analyzer.ml b/jscomp/core/js_analyzer.ml index b2f11354e9..4dd8dd05b4 100644 --- a/jscomp/core/js_analyzer.ml +++ b/jscomp/core/js_analyzer.ml @@ -158,8 +158,8 @@ let rec eq_expression ({ expression_desc = x0 } : J.expression) | Undefined x -> y0 = Undefined x | Number (Int { i }) -> ( match y0 with Number (Int { i = j }) -> i = j | _ -> false) - | Number (Bigint { i }) -> ( - match y0 with Number (Bigint { i = j }) -> i = j | _ -> false) + | Number (Bigint (s0, i )) -> ( + match y0 with Number (Bigint (s1, j)) -> s0 = s1 && i = j | _ -> false) | Number (Float _) -> false (* begin match y0 with | Number (Float j) -> diff --git a/jscomp/core/js_dump.ml b/jscomp/core/js_dump.ml index b4b66d3dbc..079cf90208 100644 --- a/jscomp/core/js_dump.ml +++ b/jscomp/core/js_dump.ml @@ -664,7 +664,7 @@ and expression_desc cxt ~(level : int) f x : cxt = Int32.to_string i (* check , js convention with ocaml lexical convention *) | Uint i -> Format.asprintf "%lu" i - | Bigint { i } -> Format.asprintf "%sn" i + | Bigint (sign, i) -> Format.asprintf "%sn" (Bigint_utils.to_string sign i) in let need_paren = if s.[0] = '-' then level > 13 diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index 7bf97299f3..fc41247260 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -312,9 +312,9 @@ let obj_int_tag_literal : t = let int ?comment ?c i : t = { expression_desc = Number (Int { i; c }); comment } -let bigint ?comment i : t = { expression_desc = Number (Bigint { i }); comment} +let bigint ?comment sign i : t = { expression_desc = Number (Bigint (sign, i)); comment} -let zero_bigint_literal : t = {expression_desc = Number (Bigint {i = "0"}); comment = None} +let zero_bigint_literal : t = {expression_desc = Number (Bigint (true, "0")); comment = None} let small_int i : t = match i with @@ -807,7 +807,11 @@ let tag_type = function | Ast_untagged_variants.String s -> str s ~delim:DStarJ | Int i -> small_int i | Float f -> float f - | Bigint i -> bigint i + | Bigint i -> + let open Bigint_utils in + let sign, i = i |> remove_leading_sign in + let i = remove_leading_zeros i in + bigint sign i | Bool b -> bool b | Null -> nil | Undefined -> undefined diff --git a/jscomp/core/js_exp_make.mli b/jscomp/core/js_exp_make.mli index 7bd05f8835..a1034bf915 100644 --- a/jscomp/core/js_exp_make.mli +++ b/jscomp/core/js_exp_make.mli @@ -111,7 +111,7 @@ val uint32 : ?comment:string -> int32 -> t val small_int : int -> t -val bigint : ?comment:string -> string -> t +val bigint : ?comment:string -> bool -> string -> t val float : ?comment:string -> string -> t diff --git a/jscomp/core/js_op.ml b/jscomp/core/js_op.ml index 5054b3cee4..addef1ce2b 100644 --- a/jscomp/core/js_op.ml +++ b/jscomp/core/js_op.ml @@ -126,13 +126,11 @@ type 'a access = Getter | Setter (* literal char *) type float_lit = { f : string } [@@unboxed] -type bigint_lit = { i: string } [@@unboxed] - type number = | Float of float_lit | Int of { i : int32; c : int option } | Uint of int32 - | Bigint of bigint_lit + | Bigint of bool * string (* becareful when constant folding +/-, since we treat it as js nativeint, bitwise operators: diff --git a/jscomp/core/lam.ml b/jscomp/core/lam.ml index b01536943e..305f336d37 100644 --- a/jscomp/core/lam.ml +++ b/jscomp/core/lam.ml @@ -506,7 +506,7 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t = (* FIXME: could raise? *) Lift.bool (Lam_compat.cmp_float cmp (float_of_string a) (float_of_string b)) - | Pbigintcomp cmp, Const_bigint a, Const_bigint b -> default () + | Pbigintcomp cmp, Const_bigint (_, a), Const_bigint (_, b) -> default () | Pintcomp ((Ceq | Cneq) as op), Const_pointer a, Const_pointer b -> Lift.bool (match op with diff --git a/jscomp/core/lam_analysis.ml b/jscomp/core/lam_analysis.ml index 9a521897c3..329352a5b9 100644 --- a/jscomp/core/lam_analysis.ml +++ b/jscomp/core/lam_analysis.ml @@ -27,7 +27,7 @@ let not_zero_constant (x : Lam_constant.t) = match x with | Const_int { i } -> i <> 0l | Const_int64 i -> i <> 0L - | Const_bigint i -> i <> "0" + | Const_bigint (_, i) -> i <> "0" | _ -> false let rec no_side_effects (lam : Lam.t) : bool = diff --git a/jscomp/core/lam_compile_const.ml b/jscomp/core/lam_compile_const.ml index fe0884abd9..7c56808160 100644 --- a/jscomp/core/lam_compile_const.ml +++ b/jscomp/core/lam_compile_const.ml @@ -74,7 +74,7 @@ and translate (x : Lam_constant.t) : J.expression = (* E.float (Int64.to_string i) *) Js_long.of_const i (* https://github.com/google/closure-library/blob/master/closure%2Fgoog%2Fmath%2Flong.js *) - | Const_bigint i -> E.bigint i + | Const_bigint (sign, i) -> E.bigint sign i | Const_float f -> E.float f (* TODO: preserve float *) | Const_string { s; unicode = false } -> E.str s | Const_string { s; unicode = true } -> E.str ~delim:DStarJ s diff --git a/jscomp/core/lam_constant_convert.ml b/jscomp/core/lam_constant_convert.ml index 37c7a802de..360eb55db3 100644 --- a/jscomp/core/lam_constant_convert.ml +++ b/jscomp/core/lam_constant_convert.ml @@ -36,7 +36,7 @@ let rec convert_constant (const : Lambda.structured_constant) : Lam_constant.t = | Const_base (Const_float i) -> Const_float i | Const_base (Const_int32 i) -> Const_int { i; comment = None } | Const_base (Const_int64 i) -> Const_int64 i - | Const_base (Const_bigint i) -> Const_bigint i + | Const_base (Const_bigint (sign, i)) -> Const_bigint (sign, i) | Const_pointer (0, Pt_constructor { name = "()"; const = 1; non_const = 0 }) -> Const_js_undefined {isUnit = true} diff --git a/jscomp/core/lam_print.ml b/jscomp/core/lam_print.ml index 36c902be98..47496d04ed 100644 --- a/jscomp/core/lam_print.ml +++ b/jscomp/core/lam_print.ml @@ -25,7 +25,7 @@ let rec struct_const ppf (cst : Lam_constant.t) = | Const_string { s } -> fprintf ppf "%S" s | Const_float f -> fprintf ppf "%s" f | Const_int64 n -> fprintf ppf "%LiL" n - | Const_bigint i -> fprintf ppf "%sn" i + | Const_bigint (sign, i) -> fprintf ppf "%sn" (Bigint_utils.to_string sign i) | Const_pointer name -> fprintf ppf "`%s" name | Const_some n -> fprintf ppf "[some-c]%a" struct_const n | Const_block (tag, _, []) -> fprintf ppf "[%i]" tag diff --git a/jscomp/frontend/external_ffi_types.ml b/jscomp/frontend/external_ffi_types.ml index 152c0ef7ac..2fee111f5f 100644 --- a/jscomp/frontend/external_ffi_types.ml +++ b/jscomp/frontend/external_ffi_types.ml @@ -301,7 +301,9 @@ let inline_int64_primitive (i : int64) : string list = [""; to_string (Ffi_inline_const (Const_int64 i))] let inline_bigint_primitive (i : string) : string list = - [""; to_string (Ffi_inline_const (Const_bigint i))] + let sign, i = i |> Bigint_utils.remove_leading_sign in + let i = Bigint_utils.remove_leading_zeros i in + [""; to_string (Ffi_inline_const (Const_bigint (sign, i)))] let inline_float_primitive (i : string) : string list = [""; to_string (Ffi_inline_const (Const_float i))] diff --git a/jscomp/frontend/lam_constant.ml b/jscomp/frontend/lam_constant.ml index 4c24e0906c..7985af2c83 100644 --- a/jscomp/frontend/lam_constant.ml +++ b/jscomp/frontend/lam_constant.ml @@ -50,7 +50,7 @@ type t = | Const_string of {s: string; unicode: bool} | Const_float of string | Const_int64 of int64 - | Const_bigint of string + | Const_bigint of bool * string | Const_pointer of string | Const_block of int * Lambda.tag_info * t list | Const_float_array of string list @@ -87,9 +87,9 @@ let rec eq_approx (x : t) (y : t) = match y with | Const_int64 iy -> ix = iy | _ -> false) - | Const_bigint ix -> ( + | Const_bigint (sx, ix) -> ( match y with - | Const_bigint iy -> ix = iy + | Const_bigint (sy, iy) -> sx = sy && ix = iy | _ -> false) | Const_pointer ix -> ( match y with diff --git a/jscomp/frontend/lam_constant.mli b/jscomp/frontend/lam_constant.mli index 76c5bdad48..2514b1dea7 100644 --- a/jscomp/frontend/lam_constant.mli +++ b/jscomp/frontend/lam_constant.mli @@ -46,7 +46,7 @@ type t = | Const_string of {s: string; unicode: bool} | Const_float of string | Const_int64 of int64 - | Const_bigint of string + | Const_bigint of bool * string | Const_pointer of string | Const_block of int * Lambda.tag_info * t list | Const_float_array of string list diff --git a/jscomp/ml/asttypes.ml b/jscomp/ml/asttypes.ml index 59314145ea..5abbdaa0a6 100644 --- a/jscomp/ml/asttypes.ml +++ b/jscomp/ml/asttypes.ml @@ -22,7 +22,7 @@ type constant = | Const_float of string | Const_int32 of int32 | Const_int64 of int64 - | Const_bigint of string + | Const_bigint of bool * string type rec_flag = Nonrecursive | Recursive diff --git a/jscomp/ml/bigint_utils.ml b/jscomp/ml/bigint_utils.ml index 74908a8664..ac034e447f 100644 --- a/jscomp/ml/bigint_utils.ml +++ b/jscomp/ml/bigint_utils.ml @@ -1,3 +1,15 @@ +let is_neg s = String.length s > 0 && s.[0] = '-' +let is_pos s = String.length s > 0 && s.[0] = '+' + +let to_string sign s = (if sign then "" else "-") ^ s + +let remove_leading_sign str : bool * string = + let len = String.length str in + if len = 0 then (false, str) + else + if is_neg str || is_pos str then (not (is_neg str), String.sub str 1 (len -1)) + else (not (is_neg str), str) + (* Removes leading zeros from the string only if the first non-zero character encountered is a digit. Unlike int and float, bigint cannot be of_string, so @@ -32,7 +44,7 @@ let remove_leading_zeros str = let str = String.concat "" (String.split_on_char '_' str) in (* Check if negative *) let starts_with_minus = str <> "" && str.[0] = '-' in - let str = if starts_with_minus then String.sub str 1 (String.length str - 1) else str in + let str = if is_neg str || is_pos str then String.sub str 1 (String.length str - 1) else str in let processed_str = aux str in if starts_with_minus then "-" ^ processed_str else processed_str @@ -42,7 +54,7 @@ let is_numeric s = else let is_digit c = (c >= '0' && c <= '9') || c = '_' in let first_char = s.[0] in - if first_char <> '-' && not (is_digit first_char) then false + if first_char <> '-' && first_char <> '+' && not (is_digit first_char) then false else let rec check idx = if idx >= len then true @@ -53,18 +65,16 @@ let is_numeric s = in check 1 -let compare s0 s1 = - (* check if negative *) - let is_neg s = String.length s > 0 && s.[0] = '-' in - match (is_neg s0, is_neg s1) with - | (true, false) -> -1 (* If only s0 is negative, it's smaller. *) - | (false, true) -> 1 (* If only s1 is negative, s0 is larger. *) +let compare (p0, s0) (p1, s1) = + match (p0, p1) with + | (false, true) -> -1 (* If only s1 is positive, s0 is smaller. *) + | (true, false) -> 1 (* If only s0 is positive, s0 is larger. *) | _ -> (* If both numbers are either negative or positive, compare their lengths. *) let len0, len1 = (String.length s0, String.length s1) in if len0 = len1 then - if is_neg s0 then String.compare s1 s0 else String.compare s0 s1 (* If lengths are equal, compare the strings directly. *) + if p0 then String.compare s0 s1 else String.compare s1 s0 (* If lengths are equal, compare the strings directly. *) else if len0 > len1 then - if is_neg s0 then -1 else 1 (* A longer s0 means it's larger unless it's negative. *) + if p0 then 1 else -1 (* A longer s0 means it's larger unless it's negative. *) else (* len0 < len1 *) - if is_neg s1 then 1 else -1 (* A longer s1 means s0 is smaller unless s1 is negative. *) + if p0 then -1 else 1 (* A longer s1 means s0 is smaller unless s1 is negative. *) diff --git a/jscomp/ml/bigint_utils.mli b/jscomp/ml/bigint_utils.mli index cb8f9bbb29..dd4cc2b77b 100644 --- a/jscomp/ml/bigint_utils.mli +++ b/jscomp/ml/bigint_utils.mli @@ -1,3 +1,7 @@ +val is_neg: string -> bool +val is_pos: string -> bool +val to_string: bool -> string -> string +val remove_leading_sign : string -> bool * string val remove_leading_zeros : string -> string val is_numeric : string -> bool -val compare : string -> string -> int +val compare : bool * string -> bool * string -> int diff --git a/jscomp/ml/parmatch.ml b/jscomp/ml/parmatch.ml index 5e96ccae3d..67c6d25909 100644 --- a/jscomp/ml/parmatch.ml +++ b/jscomp/ml/parmatch.ml @@ -264,8 +264,8 @@ let const_compare x y = match x,y with | Const_float f1, Const_float f2 -> compare (float_of_string f1) (float_of_string f2) - | Const_bigint b1, Const_bigint b2 -> - Bigint_utils.compare b1 b2 + | Const_bigint (s1, b1), Const_bigint (s2, b2) -> + Bigint_utils.compare (s1, b1) (s2, b2) | Const_string (s1, _), Const_string (s2, _) -> String.compare s1 s2 | _, _ -> compare x y @@ -386,7 +386,7 @@ let pretty_const c = match c with | Const_float f -> Printf.sprintf "%s" f | Const_int32 i -> Printf.sprintf "%ldl" i | Const_int64 i -> Printf.sprintf "%LdL" i -| Const_bigint i -> Printf.sprintf "%s" i +| Const_bigint (sign, i) -> Printf.sprintf "%s" (Bigint_utils.to_string sign i) let rec pretty_val ppf v = match v.pat_extra with @@ -1106,8 +1106,8 @@ let build_other ext env : Typedtree.pattern = match env with 0L Int64.succ p env | ({pat_desc=(Tpat_constant (Const_bigint _))} as p,_) :: _ -> build_other_constant - (function Tpat_constant(Const_bigint i) -> String.length i | _ -> assert false) - (function i -> Tpat_constant(Const_bigint (String.make i '*'))) + (function Tpat_constant(Const_bigint (sign, i)) -> String.length (Bigint_utils.to_string sign i) | _ -> assert false) + (function i -> Tpat_constant(Const_bigint (true, (String.make i '*')))) 0 succ p env | ({pat_desc=(Tpat_constant (Const_string _))} as p,_) :: _ -> build_other_constant diff --git a/jscomp/ml/printlambda.ml b/jscomp/ml/printlambda.ml index d967a30b8b..98e0ab2e9e 100644 --- a/jscomp/ml/printlambda.ml +++ b/jscomp/ml/printlambda.ml @@ -27,7 +27,7 @@ let rec struct_const ppf = function | Const_base(Const_float f) -> fprintf ppf "%s" f | Const_base(Const_int32 n) -> fprintf ppf "%lil" n | Const_base(Const_int64 n) -> fprintf ppf "%LiL" n - | Const_base(Const_bigint n) -> fprintf ppf "%sn" n + | Const_base(Const_bigint (sign, n)) -> fprintf ppf "%sn" (Bigint_utils.to_string sign n) | Const_pointer (n,_) -> fprintf ppf "%ia" n | Const_block(tag_info, []) -> let tag = Lambda.tag_of_tag_info tag_info in diff --git a/jscomp/ml/printtyped.ml b/jscomp/ml/printtyped.ml index af0c093189..e38d17d2df 100644 --- a/jscomp/ml/printtyped.ml +++ b/jscomp/ml/printtyped.ml @@ -65,7 +65,7 @@ let fmt_constant f x = | Const_float (s) -> fprintf f "Const_float %s" s; | Const_int32 (i) -> fprintf f "Const_int32 %ld" i; | Const_int64 (i) -> fprintf f "Const_int64 %Ld" i; - | Const_bigint (i) -> fprintf f "Const_bigint %s" i; + | Const_bigint (sign, i) -> fprintf f "Const_bigint %s" (Bigint_utils.to_string sign i); ;; let fmt_mutable_flag f x = diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index e3fa7b22e9..ef87bc99e4 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -76,7 +76,6 @@ type error = | Empty_record_literal | Uncurried_arity_mismatch of type_expr * int * int | Field_not_optional of string * type_expr - | Invalid_decimal of string exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -261,9 +260,9 @@ let constant : Parsetree.constant -> (Asttypes.constant, error) result = with Failure _ -> Error (Literal_overflow "int64") end | Pconst_integer (i,Some 'n') -> - if Bigint_utils.is_numeric i then - Ok (Const_bigint (Bigint_utils.remove_leading_zeros i)) - else Error (Invalid_decimal i) + let sign, i = i |> Bigint_utils.remove_leading_sign in + let i = Bigint_utils.remove_leading_zeros i in + Ok (Const_bigint (sign, i)) | Pconst_integer (i,Some c) -> Error (Unknown_literal (i, c)) | Pconst_char c -> Ok (Const_char c) | Pconst_string (s,d) -> Ok (Const_string (s,d)) @@ -4079,9 +4078,6 @@ let report_error env ppf = function fprintf ppf "Field @{%s@} is not optional in type %a. Use without ?" name type_expr typ - | Invalid_decimal s -> - fprintf ppf - "Invalid decimal literal '%sn'. Only decimal literal is allowed for bigint" s let super_report_error_no_wrap_printing_env = report_error diff --git a/jscomp/ml/typecore.mli b/jscomp/ml/typecore.mli index 861c52fac6..650bae0d5f 100644 --- a/jscomp/ml/typecore.mli +++ b/jscomp/ml/typecore.mli @@ -111,7 +111,6 @@ type error = | Empty_record_literal | Uncurried_arity_mismatch of type_expr * int * int | Field_not_optional of string * type_expr - | Invalid_decimal of string exception Error of Location.t * Env.t * error exception Error_forward of Location.error diff --git a/jscomp/ml/untypeast.ml b/jscomp/ml/untypeast.ml index 66996951e1..17203b03dd 100644 --- a/jscomp/ml/untypeast.ml +++ b/jscomp/ml/untypeast.ml @@ -114,7 +114,8 @@ let constant = function | Const_int i -> Pconst_integer (string_of_int i, None) | Const_int32 i -> Pconst_integer (Int32.to_string i, Some 'l') | Const_int64 i -> Pconst_integer (Int64.to_string i, Some 'L') - | Const_bigint i -> Pconst_integer (i, Some 'n') + | Const_bigint (sign, i) -> + Pconst_integer (Bigint_utils.to_string sign i, Some 'n') | Const_float f -> Pconst_float (f,None) let attribute sub (s, p) = (map_loc sub s, p) diff --git a/jscomp/syntax/src/res_core.ml b/jscomp/syntax/src/res_core.ml index 189f80de5d..704a68c409 100644 --- a/jscomp/syntax/src/res_core.ml +++ b/jscomp/syntax/src/res_core.ml @@ -812,6 +812,12 @@ let parseConstant p = let constant = match p.Parser.token with | Int {i; suffix} -> + (* Only decimal literal is allowed for bigint *) + if suffix = Some 'n' && not (Bigint_utils.is_numeric i) then + Parser.err p + (Diagnostics.message + "Invalid decimal literal. Only decimal literal is allowed for \ + bigint."); let intTxt = if isNegative then "-" ^ i else i in Parsetree.Pconst_integer (intTxt, suffix) | Float {f; suffix} -> diff --git a/jscomp/test/bigint_test.js b/jscomp/test/bigint_test.js index 83a1da1a8c..7cc08970f0 100644 --- a/jscomp/test/bigint_test.js +++ b/jscomp/test/bigint_test.js @@ -133,9 +133,9 @@ Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 49, charac ) : 3n, 3n), true); Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 54, characters 5-12", ( - -1n !== -1n ? ( - -1n !== -2n ? 0n : 4n - ) : 3n + -1n !== -2n ? ( + -1n !== -1n ? 0n : 3n + ) : 4n ) === 3n, true); Mt_global.collect_eq(test_id, suites, "File \"bigint_test.res\", line 59, characters 5-12", Caml_obj.equal(-1n !== -1n ? ( From d82b4bc4d2045dc5e8e616c88ef6c83278abdbda Mon Sep 17 00:00:00 2001 From: mununki Date: Wed, 27 Mar 2024 18:16:40 +0900 Subject: [PATCH 45/45] clean up --- jscomp/core/js_analyzer.ml | 4 ++-- jscomp/core/js_dump.ml | 2 +- jscomp/core/js_exp_make.ml | 8 +++----- jscomp/core/js_op.ml | 4 +++- jscomp/core/lam.ml | 2 +- jscomp/frontend/external_ffi_types.ml | 3 +-- jscomp/ml/bigint_utils.ml | 8 ++++++-- jscomp/ml/bigint_utils.mli | 3 ++- jscomp/ml/parmatch.ml | 2 +- jscomp/ml/typecore.ml | 3 +-- jscomp/syntax/src/res_core.ml | 4 ++-- 11 files changed, 23 insertions(+), 20 deletions(-) diff --git a/jscomp/core/js_analyzer.ml b/jscomp/core/js_analyzer.ml index 4dd8dd05b4..f56c8b98d3 100644 --- a/jscomp/core/js_analyzer.ml +++ b/jscomp/core/js_analyzer.ml @@ -158,8 +158,8 @@ let rec eq_expression ({ expression_desc = x0 } : J.expression) | Undefined x -> y0 = Undefined x | Number (Int { i }) -> ( match y0 with Number (Int { i = j }) -> i = j | _ -> false) - | Number (Bigint (s0, i )) -> ( - match y0 with Number (Bigint (s1, j)) -> s0 = s1 && i = j | _ -> false) + | Number (Bigint {positive = p0; value = v0}) -> ( + match y0 with Number (Bigint {positive = p1; value = v1}) -> p0 = p1 && v0 = v1 | _ -> false) | Number (Float _) -> false (* begin match y0 with | Number (Float j) -> diff --git a/jscomp/core/js_dump.ml b/jscomp/core/js_dump.ml index 079cf90208..412d8baaf0 100644 --- a/jscomp/core/js_dump.ml +++ b/jscomp/core/js_dump.ml @@ -664,7 +664,7 @@ and expression_desc cxt ~(level : int) f x : cxt = Int32.to_string i (* check , js convention with ocaml lexical convention *) | Uint i -> Format.asprintf "%lu" i - | Bigint (sign, i) -> Format.asprintf "%sn" (Bigint_utils.to_string sign i) + | Bigint {positive; value} -> Format.asprintf "%sn" (Bigint_utils.to_string positive value) in let need_paren = if s.[0] = '-' then level > 13 diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index fc41247260..a40f7ad0d5 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -312,9 +312,9 @@ let obj_int_tag_literal : t = let int ?comment ?c i : t = { expression_desc = Number (Int { i; c }); comment } -let bigint ?comment sign i : t = { expression_desc = Number (Bigint (sign, i)); comment} +let bigint ?comment sign i : t = { expression_desc = Number (Bigint {positive=sign; value=i}); comment} -let zero_bigint_literal : t = {expression_desc = Number (Bigint (true, "0")); comment = None} +let zero_bigint_literal : t = {expression_desc = Number (Bigint {positive=true; value="0"}); comment = None} let small_int i : t = match i with @@ -808,9 +808,7 @@ let tag_type = function | Int i -> small_int i | Float f -> float f | Bigint i -> - let open Bigint_utils in - let sign, i = i |> remove_leading_sign in - let i = remove_leading_zeros i in + let sign, i = Bigint_utils.parse_bigint i in bigint sign i | Bool b -> bool b | Null -> nil diff --git a/jscomp/core/js_op.ml b/jscomp/core/js_op.ml index addef1ce2b..04575cb4b4 100644 --- a/jscomp/core/js_op.ml +++ b/jscomp/core/js_op.ml @@ -126,11 +126,13 @@ type 'a access = Getter | Setter (* literal char *) type float_lit = { f : string } [@@unboxed] +type bigint_lit = { positive: bool; value: string } + type number = | Float of float_lit | Int of { i : int32; c : int option } | Uint of int32 - | Bigint of bool * string + | Bigint of bigint_lit (* becareful when constant folding +/-, since we treat it as js nativeint, bitwise operators: diff --git a/jscomp/core/lam.ml b/jscomp/core/lam.ml index 305f336d37..383817194a 100644 --- a/jscomp/core/lam.ml +++ b/jscomp/core/lam.ml @@ -506,7 +506,7 @@ let prim ~primitive:(prim : Lam_primitive.t) ~args loc : t = (* FIXME: could raise? *) Lift.bool (Lam_compat.cmp_float cmp (float_of_string a) (float_of_string b)) - | Pbigintcomp cmp, Const_bigint (_, a), Const_bigint (_, b) -> default () + | Pbigintcomp cmp, Const_bigint _, Const_bigint _ -> default () | Pintcomp ((Ceq | Cneq) as op), Const_pointer a, Const_pointer b -> Lift.bool (match op with diff --git a/jscomp/frontend/external_ffi_types.ml b/jscomp/frontend/external_ffi_types.ml index 2fee111f5f..1acc82d5c0 100644 --- a/jscomp/frontend/external_ffi_types.ml +++ b/jscomp/frontend/external_ffi_types.ml @@ -301,8 +301,7 @@ let inline_int64_primitive (i : int64) : string list = [""; to_string (Ffi_inline_const (Const_int64 i))] let inline_bigint_primitive (i : string) : string list = - let sign, i = i |> Bigint_utils.remove_leading_sign in - let i = Bigint_utils.remove_leading_zeros i in + let sign, i = Bigint_utils.parse_bigint i in [""; to_string (Ffi_inline_const (Const_bigint (sign, i)))] let inline_float_primitive (i : string) : string list = diff --git a/jscomp/ml/bigint_utils.ml b/jscomp/ml/bigint_utils.ml index ac034e447f..e0f3fe9ac1 100644 --- a/jscomp/ml/bigint_utils.ml +++ b/jscomp/ml/bigint_utils.ml @@ -8,7 +8,7 @@ let remove_leading_sign str : bool * string = if len = 0 then (false, str) else if is_neg str || is_pos str then (not (is_neg str), String.sub str 1 (len -1)) - else (not (is_neg str), str) + else (true, str) (* Removes leading zeros from the string only if the first non-zero character @@ -48,7 +48,11 @@ let remove_leading_zeros str = let processed_str = aux str in if starts_with_minus then "-" ^ processed_str else processed_str -let is_numeric s = +let parse_bigint s = + let sign, i = remove_leading_sign s in + (sign, remove_leading_zeros i) + +let is_valid s = let len = String.length s in if len = 0 then false else diff --git a/jscomp/ml/bigint_utils.mli b/jscomp/ml/bigint_utils.mli index dd4cc2b77b..34f9dfb628 100644 --- a/jscomp/ml/bigint_utils.mli +++ b/jscomp/ml/bigint_utils.mli @@ -3,5 +3,6 @@ val is_pos: string -> bool val to_string: bool -> string -> string val remove_leading_sign : string -> bool * string val remove_leading_zeros : string -> string -val is_numeric : string -> bool +val parse_bigint: string -> bool * string +val is_valid : string -> bool val compare : bool * string -> bool * string -> int diff --git a/jscomp/ml/parmatch.ml b/jscomp/ml/parmatch.ml index 67c6d25909..7c9888377c 100644 --- a/jscomp/ml/parmatch.ml +++ b/jscomp/ml/parmatch.ml @@ -1107,7 +1107,7 @@ let build_other ext env : Typedtree.pattern = match env with | ({pat_desc=(Tpat_constant (Const_bigint _))} as p,_) :: _ -> build_other_constant (function Tpat_constant(Const_bigint (sign, i)) -> String.length (Bigint_utils.to_string sign i) | _ -> assert false) - (function i -> Tpat_constant(Const_bigint (true, (String.make i '*')))) + (function i -> Tpat_constant(Const_bigint (true, (string_of_int i)))) 0 succ p env | ({pat_desc=(Tpat_constant (Const_string _))} as p,_) :: _ -> build_other_constant diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index ef87bc99e4..568a3695be 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -260,8 +260,7 @@ let constant : Parsetree.constant -> (Asttypes.constant, error) result = with Failure _ -> Error (Literal_overflow "int64") end | Pconst_integer (i,Some 'n') -> - let sign, i = i |> Bigint_utils.remove_leading_sign in - let i = Bigint_utils.remove_leading_zeros i in + let sign, i = Bigint_utils.parse_bigint i in Ok (Const_bigint (sign, i)) | Pconst_integer (i,Some c) -> Error (Unknown_literal (i, c)) | Pconst_char c -> Ok (Const_char c) diff --git a/jscomp/syntax/src/res_core.ml b/jscomp/syntax/src/res_core.ml index 704a68c409..40b972c10f 100644 --- a/jscomp/syntax/src/res_core.ml +++ b/jscomp/syntax/src/res_core.ml @@ -813,10 +813,10 @@ let parseConstant p = match p.Parser.token with | Int {i; suffix} -> (* Only decimal literal is allowed for bigint *) - if suffix = Some 'n' && not (Bigint_utils.is_numeric i) then + if suffix = Some 'n' && not (Bigint_utils.is_valid i) then Parser.err p (Diagnostics.message - "Invalid decimal literal. Only decimal literal is allowed for \ + "Invalid bigint literal. Only decimal literal is allowed for \ bigint."); let intTxt = if isNegative then "-" ^ i else i in Parsetree.Pconst_integer (intTxt, suffix)