From 456febf21b1bbcf808c4b41c418567d8a1acd7d7 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sat, 9 Nov 2024 09:17:05 +0900 Subject: [PATCH 01/11] Upgrade exponentiation to unified operator Also make its output to use ES7 exponentiation (`**`) operator. `**` is more concise, faster than `Math.pow()`, works well with all numeric types include bigint. We were already using it for bigint, now for int and float too. --- compiler/core/js_exp_make.ml | 7 +++++++ compiler/core/js_exp_make.mli | 4 ++++ compiler/core/js_op.ml | 3 ++- compiler/core/js_op_util.ml | 5 ++++- compiler/core/lam_analysis.ml | 9 +++++---- compiler/core/lam_compile_primitive.ml | 8 ++++++++ compiler/core/lam_convert.ml | 2 ++ compiler/core/lam_primitive.ml | 10 ++++++---- compiler/core/lam_primitive.mli | 2 ++ compiler/core/lam_print.ml | 2 ++ compiler/ext/ext_int.ml | 8 ++++++++ compiler/ext/ext_int.mli | 2 ++ compiler/ml/lambda.ml | 2 ++ compiler/ml/lambda.mli | 2 ++ compiler/ml/printlambda.ml | 2 ++ compiler/ml/unified_ops.ml | 13 +++++++++++++ compiler/syntax/src/res_parens.ml | 10 +++++----- compiler/syntax/src/res_parsetree_viewer.mli | 1 + runtime/Pervasives.res | 4 +--- runtime/Pervasives_mini.res | 1 + tests/tests/src/b.mjs | 2 +- tests/tests/src/exponentiation_precedence_test.mjs | 10 +++++----- tests/tests/src/test_pervasive.mjs | 2 +- tests/tests/src/unified_ops_test.mjs | 9 +++++++++ tests/tests/src/unified_ops_test.res | 4 ++++ tests/tests/src/variantsMatching.mjs | 4 ++-- 26 files changed, 101 insertions(+), 27 deletions(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index 4879bedf52..44c309dcaf 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -1549,6 +1549,7 @@ let unchecked_int32_minus ?comment e1 e2 : J.expression = float_minus ?comment e1 e2 let float_div ?comment e1 e2 = bin ?comment Div e1 e2 +let float_pow ?comment e1 e2 = bin ?comment Pow e1 e2 let float_notequal ?comment e1 e2 = bin ?comment NotEqEq e1 e2 let int32_asr ?comment e1 e2 : J.expression = @@ -1618,6 +1619,12 @@ let int32_mul ?comment (e1 : J.expression) (e2 : J.expression) : J.expression = let unchecked_int32_mul ?comment e1 e2 : J.expression = {comment; expression_desc = Bin (Mul, e1, e2)} +let int32_pow ?comment (e1 : t) (e2 : t) : J.expression = + match (e1.expression_desc, e2.expression_desc) with + | Number (Int {i = i1}), Number (Int {i = i2}) -> + int ?comment (Ext_int.int32_pow i1 i2) + | _ -> {comment; expression_desc = Bin (Pow, e1, e2)} + let rec int32_bxor ?comment (e1 : t) (e2 : t) : J.expression = match (e1.expression_desc, e2.expression_desc) with | Number (Int {i = i1}), Number (Int {i = i2}) -> diff --git a/compiler/core/js_exp_make.mli b/compiler/core/js_exp_make.mli index 14865e1769..778845bdba 100644 --- a/compiler/core/js_exp_make.mli +++ b/compiler/core/js_exp_make.mli @@ -254,6 +254,8 @@ val int32_div : checked:bool -> ?comment:string -> t -> t -> t val int32_mod : checked:bool -> ?comment:string -> t -> t -> t +val int32_pow : ?comment:string -> t -> t -> t + val int32_lsl : ?comment:string -> t -> t -> t val int32_lsr : ?comment:string -> t -> t -> t @@ -278,6 +280,8 @@ val float_notequal : ?comment:string -> t -> t -> t val float_mod : ?comment:string -> t -> t -> t +val float_pow : ?comment:string -> t -> t -> t + val int_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t val bool_comp : Lam_compat.comparison -> ?comment:string -> t -> t -> t diff --git a/compiler/core/js_op.ml b/compiler/core/js_op.ml index 15f9944b27..0d7558e7ad 100644 --- a/compiler/core/js_op.ml +++ b/compiler/core/js_op.ml @@ -105,7 +105,8 @@ type int_op = | Div (* x / y | 0 *) | Mod -(* x % y *) + (* x % y *) + | Pow (* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators {[ diff --git a/compiler/core/js_op_util.ml b/compiler/core/js_op_util.ml index af6f3c5dcb..439c4463cf 100644 --- a/compiler/core/js_op_util.ml +++ b/compiler/core/js_op_util.ml @@ -40,7 +40,8 @@ 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 | Pow -> (12, 12, 13) + | Mul | Div | Mod -> (12, 12, 13) + | Pow -> (12, 14, 12) let op_int_prec (op : Js_op.int_op) = match op with @@ -50,6 +51,7 @@ let op_int_prec (op : Js_op.int_op) = | Lsl | Lsr | Asr -> (10, 10, 11) | Plus | Minus -> (11, 11, 12) | Mul | Div | Mod -> (12, 12, 13) + | Pow -> (12, 14, 12) let op_str (op : Js_op.binop) = match op with @@ -89,6 +91,7 @@ let op_int_str (op : Js_op.int_op) = | Mul -> "*" | Div -> "/" | Mod -> "%" + | Pow -> "**" let str_of_used_stats x = match (x : Js_op.used_stats) with diff --git a/compiler/core/lam_analysis.ml b/compiler/core/lam_analysis.ml index 9bd4581ef4..93bcd496ee 100644 --- a/compiler/core/lam_analysis.ml +++ b/compiler/core/lam_analysis.ml @@ -59,12 +59,13 @@ let rec no_side_effects (lam : Lam.t) : bool = (* bool primitives *) | Psequand | Psequor | Pnot | Pboolcomp _ | Pboolorder | Pboolmin | Pboolmax (* int primitives *) - | Pnegint | Paddint | Psubint | Pmulint | Pandint | Porint | Pxorint - | Plslint | Plsrint | Pasrint | Pintcomp _ | Pintorder | Pintmin | Pintmax + | Pnegint | Paddint | Psubint | Pmulint | Ppowint | Pandint | Porint + | Pxorint | Plslint | Plsrint | Pasrint | Pintcomp _ | Pintorder | Pintmin + | Pintmax (* float primitives *) | Pintoffloat | Pfloatofint | Pnegfloat | Paddfloat | Psubfloat | Pmulfloat - | Pdivfloat | Pmodfloat | Pfloatcomp _ | Pjscomp _ | Pfloatorder | Pfloatmin - | Pfloatmax + | Ppowfloat | Pdivfloat | Pmodfloat | Pfloatcomp _ | Pjscomp _ | Pfloatorder + | Pfloatmin | Pfloatmax (* bigint primitives *) | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Ppowbigint | Pandbigint | Porbigint | Pxorbigint | Plslbigint | Pasrbigint diff --git a/compiler/core/lam_compile_primitive.ml b/compiler/core/lam_compile_primitive.ml index 6f3f16686a..ca99989f2b 100644 --- a/compiler/core/lam_compile_primitive.ml +++ b/compiler/core/lam_compile_primitive.ml @@ -250,6 +250,14 @@ let translate output_prefix loc (cxt : Lam_compile_context.t) match args with | [e1; e2] -> E.bigint_mod ~checked:!Js_config.check_div_by_zero e1 e2 | _ -> assert false) + | Ppowint -> ( + match args with + | [e1; e2] -> E.int32_pow e1 e2 + | _ -> assert false) + | Ppowfloat -> ( + match args with + | [e1; e2] -> E.float_pow e1 e2 + | _ -> assert false) | Ppowbigint -> ( match args with | [e1; e2] -> E.bigint_op Pow e1 e2 diff --git a/compiler/core/lam_convert.ml b/compiler/core/lam_convert.ml index dae5b351d9..8694474e37 100644 --- a/compiler/core/lam_convert.ml +++ b/compiler/core/lam_convert.ml @@ -249,6 +249,7 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t = | Pmulint -> prim ~primitive:Pmulint ~args loc | Pdivint -> prim ~primitive:Pdivint ~args loc | Pmodint -> prim ~primitive:Pmodint ~args loc + | Ppowint -> prim ~primitive:Ppowint ~args loc | Pandint -> prim ~primitive:Pandint ~args loc | Porint -> prim ~primitive:Porint ~args loc | Pxorint -> prim ~primitive:Pxorint ~args loc @@ -281,6 +282,7 @@ let lam_prim ~primitive:(p : Lambda.primitive) ~args loc : Lam.t = | Pmulfloat -> prim ~primitive:Pmulfloat ~args loc | Pdivfloat -> prim ~primitive:Pdivfloat ~args loc | Pmodfloat -> prim ~primitive:Pmodfloat ~args loc + | Ppowfloat -> prim ~primitive:Ppowfloat ~args loc | Pfloatorder -> prim ~primitive:Pfloatorder ~args loc | Pfloatmin -> prim ~primitive:Pfloatmin ~args loc | Pfloatmax -> prim ~primitive:Pfloatmax ~args loc diff --git a/compiler/core/lam_primitive.ml b/compiler/core/lam_primitive.ml index 9bd68d2975..d3759d9c6c 100644 --- a/compiler/core/lam_primitive.ml +++ b/compiler/core/lam_primitive.ml @@ -73,6 +73,7 @@ type t = | Pmulint | Pdivint | Pmodint + | Ppowint | Pandint | Porint | Pxorint @@ -94,6 +95,7 @@ type t = | Pmulfloat | Pdivfloat | Pmodfloat + | Ppowfloat | Pfloatcomp of Lam_compat.comparison | Pfloatorder | Pfloatmin @@ -197,12 +199,12 @@ let eq_primitive_approx (lhs : t) (rhs : t) = (* bool primitives *) | Psequand | Psequor | Pnot | Pboolcomp _ | Pboolorder | Pboolmin | Pboolmax (* int primitives *) - | Pisint | Pnegint | Paddint | Psubint | Pmulint | Pdivint | Pmodint | Pandint - | Porint | Pxorint | Plslint | Plsrint | Pasrint | Pintorder | Pintmin - | Pintmax + | Pisint | Pnegint | Paddint | Psubint | Pmulint | Pdivint | Pmodint | Ppowint + | Pandint | Porint | Pxorint | Plslint | Plsrint | Pasrint | Pintorder + | Pintmin | Pintmax (* float primitives *) | Pintoffloat | Pfloatofint | Pnegfloat | Paddfloat | Psubfloat | Pmulfloat - | Pdivfloat | Pmodfloat | Pfloatorder | Pfloatmin | Pfloatmax + | Pdivfloat | Pmodfloat | Ppowfloat | Pfloatorder | Pfloatmin | Pfloatmax (* bigint primitives *) | Pnegbigint | Paddbigint | Psubbigint | Pmulbigint | Pdivbigint | Pmodbigint | Ppowbigint | Pandbigint | Porbigint | Pxorbigint | Plslbigint | Pasrbigint diff --git a/compiler/core/lam_primitive.mli b/compiler/core/lam_primitive.mli index 164f66a5be..f130334732 100644 --- a/compiler/core/lam_primitive.mli +++ b/compiler/core/lam_primitive.mli @@ -68,6 +68,7 @@ type t = | Pmulint | Pdivint | Pmodint + | Ppowint | Pandint | Porint | Pxorint @@ -89,6 +90,7 @@ type t = | Pmulfloat | Pdivfloat | Pmodfloat + | Ppowfloat | Pfloatcomp of Lam_compat.comparison | Pfloatorder | Pfloatmin diff --git a/compiler/core/lam_print.ml b/compiler/core/lam_print.ml index 43c99edc88..a9efe966fe 100644 --- a/compiler/core/lam_print.ml +++ b/compiler/core/lam_print.ml @@ -115,6 +115,7 @@ let primitive ppf (prim : Lam_primitive.t) = | Pmulint -> fprintf ppf "*" | Pdivint -> fprintf ppf "/" | Pmodint -> fprintf ppf "mod" + | Ppowint -> fprintf ppf "**" | Pandint -> fprintf ppf "and" | Porint -> fprintf ppf "or" | Pxorint -> fprintf ppf "xor" @@ -140,6 +141,7 @@ let primitive ppf (prim : Lam_primitive.t) = | Pmulfloat -> fprintf ppf "*." | Pdivfloat -> fprintf ppf "/." | Pmodfloat -> fprintf ppf "mod" + | Ppowfloat -> fprintf ppf "**" | Pfloatcomp Ceq -> fprintf ppf "==." | Pfloatcomp Cneq -> fprintf ppf "!=." | Pfloatcomp Clt -> fprintf ppf "<." diff --git a/compiler/ext/ext_int.ml b/compiler/ext/ext_int.ml index f31d4251de..92d292508f 100644 --- a/compiler/ext/ext_int.ml +++ b/compiler/ext/ext_int.ml @@ -34,3 +34,11 @@ let move = 0x1_0000_0000 let int32_unsigned_to_int (n : int32) : int = let i = Int32.to_int n in if i < 0 then i + move else i + +let rec int32_pow (a : int32) = function + | 0l -> 1l + | 1l -> a + | n -> + let b = int32_pow a (Int32.div n 2l) in + let b = Int32.mul b b in + Int32.mul b (if Int32.rem n 2l = 0l then 1l else a) diff --git a/compiler/ext/ext_int.mli b/compiler/ext/ext_int.mli index acfc7af2ed..0c61810009 100644 --- a/compiler/ext/ext_int.mli +++ b/compiler/ext/ext_int.mli @@ -33,3 +33,5 @@ val int32_unsigned_to_int : int32 -> int works on 64 bit platform only given input as an uint32 and convert it io int64 *) + +val int32_pow : int32 -> int32 -> int32 diff --git a/compiler/ml/lambda.ml b/compiler/ml/lambda.ml index 809c1164a7..d2f02f9a91 100644 --- a/compiler/ml/lambda.ml +++ b/compiler/ml/lambda.ml @@ -206,6 +206,7 @@ type primitive = | Pmulint | Pdivint | Pmodint + | Ppowint | Pandint | Porint | Pxorint @@ -228,6 +229,7 @@ type primitive = | Psubfloat | Pmulfloat | Pdivfloat + | Ppowfloat | Pfloatcomp of comparison | Pfloatorder | Pfloatmin diff --git a/compiler/ml/lambda.mli b/compiler/ml/lambda.mli index aecdec146f..49035249df 100644 --- a/compiler/ml/lambda.mli +++ b/compiler/ml/lambda.mli @@ -173,6 +173,7 @@ type primitive = | Pmulint | Pdivint | Pmodint + | Ppowint | Pandint | Porint | Pxorint @@ -195,6 +196,7 @@ type primitive = | Psubfloat | Pmulfloat | Pdivfloat + | Ppowfloat | Pfloatcomp of comparison | Pfloatorder | Pfloatmin diff --git a/compiler/ml/printlambda.ml b/compiler/ml/printlambda.ml index 682e05660a..68967026fd 100644 --- a/compiler/ml/printlambda.ml +++ b/compiler/ml/printlambda.ml @@ -148,6 +148,7 @@ let primitive ppf = function | Pmulint -> fprintf ppf "*" | Pdivint -> fprintf ppf "/" | Pmodint -> fprintf ppf "mod" + | Ppowint -> fprintf ppf "**" | Pandint -> fprintf ppf "and" | Porint -> fprintf ppf "or" | Pxorint -> fprintf ppf "xor" @@ -174,6 +175,7 @@ let primitive ppf = function | Pmulfloat -> fprintf ppf "*." | Pdivfloat -> fprintf ppf "/." | Pmodfloat -> fprintf ppf "mod" + | Ppowfloat -> fprintf ppf "**" | Pfloatcomp Ceq -> fprintf ppf "==." | Pfloatcomp Cneq -> fprintf ppf "!=." | Pfloatcomp Clt -> fprintf ppf "<." diff --git a/compiler/ml/unified_ops.ml b/compiler/ml/unified_ops.ml index 980f7bd1f3..79d8d3b24f 100644 --- a/compiler/ml/unified_ops.ml +++ b/compiler/ml/unified_ops.ml @@ -161,6 +161,19 @@ let entries = string = None; }; }; + { + path = builtin "**"; + name = "%pow"; + form = Binary; + specialization = + { + int = Ppowint; + bool = None; + float = Some Ppowfloat; + bigint = Some Ppowbigint; + string = None; + }; + }; |] let index_by_path = diff --git a/compiler/syntax/src/res_parens.ml b/compiler/syntax/src/res_parens.ml index 550c375df9..b44f95bbf7 100644 --- a/compiler/syntax/src/res_parens.ml +++ b/compiler/syntax/src/res_parens.ml @@ -140,12 +140,12 @@ let binary_expr_operand ~is_lhs expr = else Nothing) let sub_binary_expr_operand parent_operator child_operator = - let prec_parent = ParsetreeViewer.operator_precedence parent_operator in - let prec_child = ParsetreeViewer.operator_precedence child_operator in + let open ParsetreeViewer in + let prec_parent = operator_precedence parent_operator in + let prec_child = operator_precedence child_operator in prec_parent > prec_child - || prec_parent == prec_child - && not - (ParsetreeViewer.flattenable_operators parent_operator child_operator) + || is_equality_operator parent_operator + && is_equality_operator child_operator || (* a && b || c, add parens to (a && b) for readability, who knows the difference by heart… *) (parent_operator = "||" && child_operator = "&&") diff --git a/compiler/syntax/src/res_parsetree_viewer.mli b/compiler/syntax/src/res_parsetree_viewer.mli index 1774563491..efb42df276 100644 --- a/compiler/syntax/src/res_parsetree_viewer.mli +++ b/compiler/syntax/src/res_parsetree_viewer.mli @@ -69,6 +69,7 @@ val is_unary_expression : Parsetree.expression -> bool val is_binary_operator : string -> bool val is_binary_expression : Parsetree.expression -> bool val is_rhs_binary_operator : string -> bool +val is_equality_operator : string -> bool val flattenable_operators : string -> string -> bool diff --git a/runtime/Pervasives.res b/runtime/Pervasives.res index d657dd782f..12c46bab4a 100644 --- a/runtime/Pervasives.res +++ b/runtime/Pervasives.res @@ -51,6 +51,7 @@ external \"*": ('a, 'a) => 'a = "%mul" external \"/": ('a, 'a) => 'a = "%div" external \"%": ('a, 'a) => 'a = "%mod" external mod: ('a, 'a) => 'a = "%mod" +external \"**": ('a, 'a) => 'a = "%pow" /* Comparisons */ /* Note: Later comparisons will be converted to unified operations too */ @@ -114,9 +115,6 @@ external \"-.": (float, float) => float = "%subfloat" external \"*.": (float, float) => float = "%mulfloat" external \"/.": (float, float) => float = "%divfloat" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") -external \"**": (float, float) => float = "pow" - @deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") external exp: float => float = "exp" diff --git a/runtime/Pervasives_mini.res b/runtime/Pervasives_mini.res index 7049284417..483420adb1 100644 --- a/runtime/Pervasives_mini.res +++ b/runtime/Pervasives_mini.res @@ -30,6 +30,7 @@ external \"*": (int, int) => int = "%mulint" external \"/": (int, int) => int = "%divint" external \"%": (int, int) => int = "%modint" external mod: (int, int) => int = "%modint" +external \"**": (int, int) => int = "%powint" /* Comparisons */ /* Note: Later comparisons will be converted to unified operations too */ diff --git a/tests/tests/src/b.mjs b/tests/tests/src/b.mjs index 1738e2ec25..2d888ec7ee 100644 --- a/tests/tests/src/b.mjs +++ b/tests/tests/src/b.mjs @@ -4,7 +4,7 @@ function f(point) { let y = point.y; let x = point.x; - return Math.pow(x * x + y * y, 2); + return (x * x + y * y) ** 2; } export { diff --git a/tests/tests/src/exponentiation_precedence_test.mjs b/tests/tests/src/exponentiation_precedence_test.mjs index 1f84a4ec3c..4d88b12de0 100644 --- a/tests/tests/src/exponentiation_precedence_test.mjs +++ b/tests/tests/src/exponentiation_precedence_test.mjs @@ -1,13 +1,13 @@ // Generated by ReScript, PLEASE EDIT WITH CARE -let a = Math.pow(2, Math.pow(3, 2)); +let a = 2 ** 3 ** 2; -let b = Math.pow(2, Math.pow(-3, 2)); +let b = 2 ** (-3) ** 2; -let c = Math.pow(Math.pow(2, 3), 2); +let c = (2 ** 3) ** 2; -let d = Math.pow(-2, 2); +let d = (-2) ** 2; export { a, @@ -15,4 +15,4 @@ export { c, d, } -/* a Not a pure module */ +/* No side effect */ diff --git a/tests/tests/src/test_pervasive.mjs b/tests/tests/src/test_pervasive.mjs index 5892a7ca6d..fb453f420f 100644 --- a/tests/tests/src/test_pervasive.mjs +++ b/tests/tests/src/test_pervasive.mjs @@ -186,7 +186,7 @@ function a17(prim) { } function a18(prim0, prim1) { - return Math.pow(prim0, prim1); + return prim0 ** prim1; } let f = Pervasives.$at; diff --git a/tests/tests/src/unified_ops_test.mjs b/tests/tests/src/unified_ops_test.mjs index c9635201cc..bb6cdd7683 100644 --- a/tests/tests/src/unified_ops_test.mjs +++ b/tests/tests/src/unified_ops_test.mjs @@ -59,6 +59,12 @@ function odd(n) { return n % 2 === 1; } +let pow1 = 4; + +let pow2 = 2 ** 2; + +let pow3 = 2n ** 2n; + let int = 3; export { @@ -79,5 +85,8 @@ export { case2, even, odd, + pow1, + pow2, + pow3, } /* No side effect */ diff --git a/tests/tests/src/unified_ops_test.res b/tests/tests/src/unified_ops_test.res index c35588167f..434f8e0651 100644 --- a/tests/tests/src/unified_ops_test.res +++ b/tests/tests/src/unified_ops_test.res @@ -20,3 +20,7 @@ let case2 = (a, b) => a + "test" + b let even = n => n % 2 == 0 let odd = n => n % 2 == 1 + +let pow1 = 2 ** 2 +let pow2 = 2. ** 2. +let pow3 = 2n ** 2n diff --git a/tests/tests/src/variantsMatching.mjs b/tests/tests/src/variantsMatching.mjs index 0ee83a8320..d380be8163 100644 --- a/tests/tests/src/variantsMatching.mjs +++ b/tests/tests/src/variantsMatching.mjs @@ -337,9 +337,9 @@ let MyNullableExtended = { function area(shape) { switch (shape.kind) { case 1 : - return Math.PI * Math.pow(shape.radius, 2); + return Math.PI * (shape.radius ** 2); case "square" : - return Math.pow(shape.sideLength, 2); + return shape.sideLength ** 2; case "rectangle" : return shape.width * shape.height; } From 230d46086cfbb9978387c84ffe6846eb5d2d85c8 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sat, 9 Nov 2024 09:48:15 +0900 Subject: [PATCH 02/11] adjust parens --- compiler/core/js_op_util.ml | 4 ++-- tests/tests/src/variantsMatching.mjs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/core/js_op_util.ml b/compiler/core/js_op_util.ml index 439c4463cf..373657adfb 100644 --- a/compiler/core/js_op_util.ml +++ b/compiler/core/js_op_util.ml @@ -41,7 +41,7 @@ let op_prec (op : Js_op.binop) = | Lsl | Lsr | Asr -> (10, 10, 11) | Plus | Minus -> (11, 11, 12) | Mul | Div | Mod -> (12, 12, 13) - | Pow -> (12, 14, 12) + | Pow -> (13, 14, 12) let op_int_prec (op : Js_op.int_op) = match op with @@ -51,7 +51,7 @@ let op_int_prec (op : Js_op.int_op) = | Lsl | Lsr | Asr -> (10, 10, 11) | Plus | Minus -> (11, 11, 12) | Mul | Div | Mod -> (12, 12, 13) - | Pow -> (12, 14, 12) + | Pow -> (13, 14, 12) let op_str (op : Js_op.binop) = match op with diff --git a/tests/tests/src/variantsMatching.mjs b/tests/tests/src/variantsMatching.mjs index d380be8163..a23fbd46a8 100644 --- a/tests/tests/src/variantsMatching.mjs +++ b/tests/tests/src/variantsMatching.mjs @@ -337,7 +337,7 @@ let MyNullableExtended = { function area(shape) { switch (shape.kind) { case 1 : - return Math.PI * (shape.radius ** 2); + return Math.PI * shape.radius ** 2; case "square" : return shape.sideLength ** 2; case "rectangle" : From 63c03a9ad79a64d0e899679981b08df9445e16de Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sun, 10 Nov 2024 03:43:47 +0900 Subject: [PATCH 03/11] result into int32 --- compiler/core/js_exp_make.ml | 2 +- compiler/core/js_op.ml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index 44c309dcaf..491a638e4b 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -1622,7 +1622,7 @@ let unchecked_int32_mul ?comment e1 e2 : J.expression = let int32_pow ?comment (e1 : t) (e2 : t) : J.expression = match (e1.expression_desc, e2.expression_desc) with | Number (Int {i = i1}), Number (Int {i = i2}) -> - int ?comment (Ext_int.int32_pow i1 i2) + to_int32 (int ?comment (Ext_int.int32_pow i1 i2)) | _ -> {comment; expression_desc = Bin (Pow, e1, e2)} let rec int32_bxor ?comment (e1 : t) (e2 : t) : J.expression = diff --git a/compiler/core/js_op.ml b/compiler/core/js_op.ml index 0d7558e7ad..9bbe3b50a2 100644 --- a/compiler/core/js_op.ml +++ b/compiler/core/js_op.ml @@ -106,7 +106,7 @@ type int_op = (* x / y | 0 *) | Mod (* x % y *) - | Pow + | Pow (* x ** y | 0 *) (* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators {[ From 445a780ff717b4912ad3bd4c02c30e85f7ca1417 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sun, 10 Nov 2024 03:45:03 +0900 Subject: [PATCH 04/11] more exponentiation tests --- .../src/exponentiation_precedence_test.mjs | 18 -------- .../src/exponentiation_precedence_test.res | 4 -- tests/tests/src/exponentiation_test.mjs | 45 +++++++++++++++++++ tests/tests/src/exponentiation_test.res | 22 +++++++++ 4 files changed, 67 insertions(+), 22 deletions(-) delete mode 100644 tests/tests/src/exponentiation_precedence_test.mjs delete mode 100644 tests/tests/src/exponentiation_precedence_test.res create mode 100644 tests/tests/src/exponentiation_test.mjs create mode 100644 tests/tests/src/exponentiation_test.res diff --git a/tests/tests/src/exponentiation_precedence_test.mjs b/tests/tests/src/exponentiation_precedence_test.mjs deleted file mode 100644 index 4d88b12de0..0000000000 --- a/tests/tests/src/exponentiation_precedence_test.mjs +++ /dev/null @@ -1,18 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - - -let a = 2 ** 3 ** 2; - -let b = 2 ** (-3) ** 2; - -let c = (2 ** 3) ** 2; - -let d = (-2) ** 2; - -export { - a, - b, - c, - d, -} -/* No side effect */ diff --git a/tests/tests/src/exponentiation_precedence_test.res b/tests/tests/src/exponentiation_precedence_test.res deleted file mode 100644 index 97c300005a..0000000000 --- a/tests/tests/src/exponentiation_precedence_test.res +++ /dev/null @@ -1,4 +0,0 @@ -let a = 2. ** 3. ** 2. -let b = 2. ** -3. ** 2. -let c = (2. ** 3.) ** 2. -let d = -2. ** 2. diff --git a/tests/tests/src/exponentiation_test.mjs b/tests/tests/src/exponentiation_test.mjs new file mode 100644 index 0000000000..a3c9bb71de --- /dev/null +++ b/tests/tests/src/exponentiation_test.mjs @@ -0,0 +1,45 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Mt from "./mt.mjs"; + +let suites = { + contents: /* [] */0 +}; + +let test_id = { + contents: 0 +}; + +function eq(loc, x, y) { + Mt.eq_suites(test_id, suites, loc, x, y); +} + +let intPow = ((a, b) => Math.pow(a, b) | 0); + +eq("File \"exponentiation_test.res\", line 10, characters 5-12", 2 ** 3 ** 2, Math.pow(2, Math.pow(3, 2))); + +eq("File \"exponentiation_test.res\", line 11, characters 5-12", 2 ** (-3) ** 2, Math.pow(2, Math.pow(-3, 2))); + +eq("File \"exponentiation_test.res\", line 12, characters 5-12", (2 ** 3) ** 2, Math.pow(Math.pow(2, 3), 2)); + +eq("File \"exponentiation_test.res\", line 13, characters 5-12", (-2) ** 2, Math.pow(-2, 2)); + +eq("File \"exponentiation_test.res\", line 15, characters 5-12", 512, intPow(2, intPow(3, 2))); + +eq("File \"exponentiation_test.res\", line 16, characters 5-12", 512, intPow(2, intPow(-3, 2))); + +eq("File \"exponentiation_test.res\", line 17, characters 5-12", 64, intPow(intPow(2, 3), 2)); + +eq("File \"exponentiation_test.res\", line 18, characters 5-12", -2147483648, intPow(-2, 31)); + +eq("File \"exponentiation_test.res\", line 19, characters 5-12", 0, intPow(2, 32)); + +Mt.from_pair_suites("Exponentiation_test", suites.contents); + +export { + suites, + test_id, + eq, + intPow, +} +/* Not a pure module */ diff --git a/tests/tests/src/exponentiation_test.res b/tests/tests/src/exponentiation_test.res new file mode 100644 index 0000000000..cb4a54aef2 --- /dev/null +++ b/tests/tests/src/exponentiation_test.res @@ -0,0 +1,22 @@ +let suites: ref = ref(list{}) +let test_id = ref(0) +let eq = (loc, x, y) => Mt.eq_suites(~test_id, ~suites, loc, x, y) + +external jsPow: (float, float) => float = "Math.pow" + +let intPow: (int, int) => int = %raw(`(a, b) => Math.pow(a, b) | 0`) + +let () = { + eq(__LOC__, 2. ** 3. ** 2., jsPow(2., jsPow(3., 2.))) + eq(__LOC__, 2. ** -3. ** 2., jsPow(2., jsPow(-3., 2.))) + eq(__LOC__, (2. ** 3.) ** 2., jsPow(jsPow(2., 3.), 2.)) + eq(__LOC__, -2. ** 2., jsPow(-2., 2.)) + + eq(__LOC__, 2 ** 3 ** 2, intPow(2, intPow(3, 2))) + eq(__LOC__, 2 ** -3 ** 2, intPow(2, intPow(-3, 2))) + eq(__LOC__, (2 ** 3) ** 2, intPow(intPow(2, 3), 2)) + eq(__LOC__, -2 ** 31, intPow(-2, 31)) + eq(__LOC__, 2 ** 32, intPow(2, 32)) +} + +let () = Mt.from_pair_suites(__MODULE__, suites.contents) From f125fddaa64e1c7c730a09110ac1bd475d70ca51 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sun, 10 Nov 2024 04:03:33 +0900 Subject: [PATCH 05/11] make sure it is int32 --- compiler/core/js_exp_make.ml | 2 +- tests/tests/src/test_pervasive.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index 491a638e4b..19bf43b2c4 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -1623,7 +1623,7 @@ let int32_pow ?comment (e1 : t) (e2 : t) : J.expression = match (e1.expression_desc, e2.expression_desc) with | Number (Int {i = i1}), Number (Int {i = i2}) -> to_int32 (int ?comment (Ext_int.int32_pow i1 i2)) - | _ -> {comment; expression_desc = Bin (Pow, e1, e2)} + | _ -> to_int32 (float_pow ?comment e1 e2) let rec int32_bxor ?comment (e1 : t) (e2 : t) : J.expression = match (e1.expression_desc, e2.expression_desc) with diff --git a/tests/tests/src/test_pervasive.mjs b/tests/tests/src/test_pervasive.mjs index fb453f420f..98fbe62c03 100644 --- a/tests/tests/src/test_pervasive.mjs +++ b/tests/tests/src/test_pervasive.mjs @@ -186,7 +186,7 @@ function a17(prim) { } function a18(prim0, prim1) { - return prim0 ** prim1; + return prim0 ** prim1 | 0; } let f = Pervasives.$at; From c9dedb6fa47672cc5b074a0b9558b0463ab20939 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sun, 10 Nov 2024 04:05:33 +0900 Subject: [PATCH 06/11] remove unnecessary guard for constants --- compiler/core/js_exp_make.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/core/js_exp_make.ml b/compiler/core/js_exp_make.ml index 19bf43b2c4..1fa740e16c 100644 --- a/compiler/core/js_exp_make.ml +++ b/compiler/core/js_exp_make.ml @@ -1622,7 +1622,7 @@ let unchecked_int32_mul ?comment e1 e2 : J.expression = let int32_pow ?comment (e1 : t) (e2 : t) : J.expression = match (e1.expression_desc, e2.expression_desc) with | Number (Int {i = i1}), Number (Int {i = i2}) -> - to_int32 (int ?comment (Ext_int.int32_pow i1 i2)) + int ?comment (Ext_int.int32_pow i1 i2) | _ -> to_int32 (float_pow ?comment e1 e2) let rec int32_bxor ?comment (e1 : t) (e2 : t) : J.expression = From 9ba6840b929716748e93b7fdf5baecba64dd9248 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sun, 10 Nov 2024 09:53:15 +0900 Subject: [PATCH 07/11] add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb08220768..114c79bbc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -161,6 +161,7 @@ - Introduce "Unified operators" for arithmetic operators (`+`, `-`, `*`, `/`, `mod`). https://github.com/rescript-lang/rescript-compiler/pull/7057 - Add remainder (`%`, aka modulus) operator. https://github.com/rescript-lang/rescript-compiler/pull/7152 +- Allow exponentiation (`**`) operator for `int` and `float`, using ES7 `**`. https://github.com/rescript-lang/rescript-compiler/pull/7153 #### :bug: Bug fix From 0ef247a5a064325aa72575209e70a63cc56f03cc Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sun, 10 Nov 2024 09:58:42 +0900 Subject: [PATCH 08/11] add a test --- tests/tests/src/exponentiation_test.mjs | 23 ++++++++++++++--------- tests/tests/src/exponentiation_test.res | 3 +++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/tests/tests/src/exponentiation_test.mjs b/tests/tests/src/exponentiation_test.mjs index a3c9bb71de..cd1b851151 100644 --- a/tests/tests/src/exponentiation_test.mjs +++ b/tests/tests/src/exponentiation_test.mjs @@ -16,23 +16,27 @@ function eq(loc, x, y) { let intPow = ((a, b) => Math.pow(a, b) | 0); -eq("File \"exponentiation_test.res\", line 10, characters 5-12", 2 ** 3 ** 2, Math.pow(2, Math.pow(3, 2))); +let four = 4; -eq("File \"exponentiation_test.res\", line 11, characters 5-12", 2 ** (-3) ** 2, Math.pow(2, Math.pow(-3, 2))); +eq("File \"exponentiation_test.res\", line 11, characters 5-12", 2 ** 3 ** 2, Math.pow(2, Math.pow(3, 2))); -eq("File \"exponentiation_test.res\", line 12, characters 5-12", (2 ** 3) ** 2, Math.pow(Math.pow(2, 3), 2)); +eq("File \"exponentiation_test.res\", line 12, characters 5-12", 2 ** (-3) ** 2, Math.pow(2, Math.pow(-3, 2))); -eq("File \"exponentiation_test.res\", line 13, characters 5-12", (-2) ** 2, Math.pow(-2, 2)); +eq("File \"exponentiation_test.res\", line 13, characters 5-12", (2 ** 3) ** 2, Math.pow(Math.pow(2, 3), 2)); -eq("File \"exponentiation_test.res\", line 15, characters 5-12", 512, intPow(2, intPow(3, 2))); +eq("File \"exponentiation_test.res\", line 14, characters 5-12", (-2) ** 2, Math.pow(-2, 2)); -eq("File \"exponentiation_test.res\", line 16, characters 5-12", 512, intPow(2, intPow(-3, 2))); +eq("File \"exponentiation_test.res\", line 16, characters 5-12", 512, intPow(2, intPow(3, 2))); -eq("File \"exponentiation_test.res\", line 17, characters 5-12", 64, intPow(intPow(2, 3), 2)); +eq("File \"exponentiation_test.res\", line 17, characters 5-12", 512, intPow(2, intPow(-3, 2))); -eq("File \"exponentiation_test.res\", line 18, characters 5-12", -2147483648, intPow(-2, 31)); +eq("File \"exponentiation_test.res\", line 18, characters 5-12", 64, intPow(intPow(2, 3), 2)); -eq("File \"exponentiation_test.res\", line 19, characters 5-12", 0, intPow(2, 32)); +eq("File \"exponentiation_test.res\", line 19, characters 5-12", -2147483648, intPow(-2, 31)); + +eq("File \"exponentiation_test.res\", line 20, characters 5-12", 0, intPow(2, 32)); + +eq("File \"exponentiation_test.res\", line 22, characters 5-12", 256, four ** four | 0); Mt.from_pair_suites("Exponentiation_test", suites.contents); @@ -41,5 +45,6 @@ export { test_id, eq, intPow, + four, } /* Not a pure module */ diff --git a/tests/tests/src/exponentiation_test.res b/tests/tests/src/exponentiation_test.res index cb4a54aef2..0d0caa7b21 100644 --- a/tests/tests/src/exponentiation_test.res +++ b/tests/tests/src/exponentiation_test.res @@ -5,6 +5,7 @@ let eq = (loc, x, y) => Mt.eq_suites(~test_id, ~suites, loc, x, y) external jsPow: (float, float) => float = "Math.pow" let intPow: (int, int) => int = %raw(`(a, b) => Math.pow(a, b) | 0`) +let four: int = %raw(`4`) let () = { eq(__LOC__, 2. ** 3. ** 2., jsPow(2., jsPow(3., 2.))) @@ -17,6 +18,8 @@ let () = { eq(__LOC__, (2 ** 3) ** 2, intPow(intPow(2, 3), 2)) eq(__LOC__, -2 ** 31, intPow(-2, 31)) eq(__LOC__, 2 ** 32, intPow(2, 32)) + + eq(__LOC__, 4 ** 4, four ** four) } let () = Mt.from_pair_suites(__MODULE__, suites.contents) From 75fdc411dd7f4e6fe381dc5f106d5ec4895c4d1b Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sun, 23 Mar 2025 01:01:31 +0900 Subject: [PATCH 09/11] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 114c79bbc1..e243ae7868 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Make reanalyze exception tracking work with the new stdlib. https://github.com/rescript-lang/rescript/pull/7328 - Fix Pervasive.max using boolean comparison for floats. https://github.com/rescript-lang/rescript/pull/7333 - Experimental: Support nested/inline record types - records defined inside of other records, without needing explicit separate type definitions. https://github.com/rescript-lang/rescript/pull/7241 +- Add unified exponentiation (`**`) operator for numeric types using ES7 `**`. https://github.com/rescript-lang/rescript-compiler/pull/7153 #### :boom: Breaking Change @@ -161,7 +162,6 @@ - Introduce "Unified operators" for arithmetic operators (`+`, `-`, `*`, `/`, `mod`). https://github.com/rescript-lang/rescript-compiler/pull/7057 - Add remainder (`%`, aka modulus) operator. https://github.com/rescript-lang/rescript-compiler/pull/7152 -- Allow exponentiation (`**`) operator for `int` and `float`, using ES7 `**`. https://github.com/rescript-lang/rescript-compiler/pull/7153 #### :bug: Bug fix From db66fd00f7968127ca94f4a83086ff5d01bb9fd2 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sun, 23 Mar 2025 01:14:58 +0900 Subject: [PATCH 10/11] add a failing case --- tests/tests/src/exponentiation_test.mjs | 4 +++- tests/tests/src/exponentiation_test.res | 1 + tests/tests/src/unified_ops_test.mjs | 3 +++ tests/tests/src/unified_ops_test.res | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/tests/src/exponentiation_test.mjs b/tests/tests/src/exponentiation_test.mjs index cd1b851151..e03bf1c344 100644 --- a/tests/tests/src/exponentiation_test.mjs +++ b/tests/tests/src/exponentiation_test.mjs @@ -36,7 +36,9 @@ eq("File \"exponentiation_test.res\", line 19, characters 5-12", -2147483648, in eq("File \"exponentiation_test.res\", line 20, characters 5-12", 0, intPow(2, 32)); -eq("File \"exponentiation_test.res\", line 22, characters 5-12", 256, four ** four | 0); +eq("File \"exponentiation_test.res\", line 21, characters 5-12", 1, intPow(2147483647, 2)); + +eq("File \"exponentiation_test.res\", line 23, characters 5-12", 256, four ** four | 0); Mt.from_pair_suites("Exponentiation_test", suites.contents); diff --git a/tests/tests/src/exponentiation_test.res b/tests/tests/src/exponentiation_test.res index 0d0caa7b21..f879431de7 100644 --- a/tests/tests/src/exponentiation_test.res +++ b/tests/tests/src/exponentiation_test.res @@ -18,6 +18,7 @@ let () = { eq(__LOC__, (2 ** 3) ** 2, intPow(intPow(2, 3), 2)) eq(__LOC__, -2 ** 31, intPow(-2, 31)) eq(__LOC__, 2 ** 32, intPow(2, 32)) + eq(__LOC__, 2147483647 ** 2, intPow(2147483647, 2)) eq(__LOC__, 4 ** 4, four ** four) } diff --git a/tests/tests/src/unified_ops_test.mjs b/tests/tests/src/unified_ops_test.mjs index bb6cdd7683..56cc580d89 100644 --- a/tests/tests/src/unified_ops_test.mjs +++ b/tests/tests/src/unified_ops_test.mjs @@ -65,6 +65,8 @@ let pow2 = 2 ** 2; let pow3 = 2n ** 2n; +let pow_overflow = 1; + let int = 3; export { @@ -88,5 +90,6 @@ export { pow1, pow2, pow3, + pow_overflow, } /* No side effect */ diff --git a/tests/tests/src/unified_ops_test.res b/tests/tests/src/unified_ops_test.res index 434f8e0651..26137c1c77 100644 --- a/tests/tests/src/unified_ops_test.res +++ b/tests/tests/src/unified_ops_test.res @@ -24,3 +24,5 @@ let odd = n => n % 2 == 1 let pow1 = 2 ** 2 let pow2 = 2. ** 2. let pow3 = 2n ** 2n + +let pow_overflow = 2147483647 ** 2 From b1ae4ec4eefe0eee085c175ea7c7a9e7763ed135 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sun, 23 Mar 2025 01:45:09 +0900 Subject: [PATCH 11/11] fix `Ext_int.int32_pow` to behave like JavaScript --- compiler/ext/ext_int.ml | 18 +++++++++++------- tests/tests/src/exponentiation_test.mjs | 6 ++++-- tests/tests/src/exponentiation_test.res | 1 + tests/tests/src/unified_ops_test.mjs | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/compiler/ext/ext_int.ml b/compiler/ext/ext_int.ml index 92d292508f..3c71537cab 100644 --- a/compiler/ext/ext_int.ml +++ b/compiler/ext/ext_int.ml @@ -35,10 +35,14 @@ let int32_unsigned_to_int (n : int32) : int = let i = Int32.to_int n in if i < 0 then i + move else i -let rec int32_pow (a : int32) = function - | 0l -> 1l - | 1l -> a - | n -> - let b = int32_pow a (Int32.div n 2l) in - let b = Int32.mul b b in - Int32.mul b (if Int32.rem n 2l = 0l then 1l else a) +let int32_pow (x : int32) (y : int32) = + let x_float = Int32.to_float x in + let y_float = Int32.to_float y in + let result = x_float ** y_float in + let truncated = + if result > 2147483647.0 || result < -2147483648.0 then + let i = int_of_float result in + i land 0xFFFFFFFF + else int_of_float result + in + Int32.of_int truncated diff --git a/tests/tests/src/exponentiation_test.mjs b/tests/tests/src/exponentiation_test.mjs index e03bf1c344..c1322508f5 100644 --- a/tests/tests/src/exponentiation_test.mjs +++ b/tests/tests/src/exponentiation_test.mjs @@ -36,9 +36,11 @@ eq("File \"exponentiation_test.res\", line 19, characters 5-12", -2147483648, in eq("File \"exponentiation_test.res\", line 20, characters 5-12", 0, intPow(2, 32)); -eq("File \"exponentiation_test.res\", line 21, characters 5-12", 1, intPow(2147483647, 2)); +eq("File \"exponentiation_test.res\", line 21, characters 5-12", 0, intPow(2147483647, 2)); -eq("File \"exponentiation_test.res\", line 23, characters 5-12", 256, four ** four | 0); +eq("File \"exponentiation_test.res\", line 22, characters 5-12", 0, intPow(-2147483648, 2)); + +eq("File \"exponentiation_test.res\", line 24, characters 5-12", 256, four ** four | 0); Mt.from_pair_suites("Exponentiation_test", suites.contents); diff --git a/tests/tests/src/exponentiation_test.res b/tests/tests/src/exponentiation_test.res index f879431de7..fe860d5c5e 100644 --- a/tests/tests/src/exponentiation_test.res +++ b/tests/tests/src/exponentiation_test.res @@ -19,6 +19,7 @@ let () = { eq(__LOC__, -2 ** 31, intPow(-2, 31)) eq(__LOC__, 2 ** 32, intPow(2, 32)) eq(__LOC__, 2147483647 ** 2, intPow(2147483647, 2)) + eq(__LOC__, -2147483648 ** 2, intPow(-2147483648, 2)) eq(__LOC__, 4 ** 4, four ** four) } diff --git a/tests/tests/src/unified_ops_test.mjs b/tests/tests/src/unified_ops_test.mjs index 56cc580d89..5ca55fc808 100644 --- a/tests/tests/src/unified_ops_test.mjs +++ b/tests/tests/src/unified_ops_test.mjs @@ -65,7 +65,7 @@ let pow2 = 2 ** 2; let pow3 = 2n ** 2n; -let pow_overflow = 1; +let pow_overflow = 0; let int = 3;