From 88b81b72df83a25967e13491c8aeaf90983ddace Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sat, 30 Nov 2024 16:32:47 +0000 Subject: [PATCH 01/16] add left shift(`<<`) operator --- compiler/ml/unified_ops.ml | 12 ++++++++++++ compiler/syntax/src/res_core.ml | 2 +- compiler/syntax/src/res_parsetree_viewer.ml | 4 ++-- compiler/syntax/src/res_token.ml | 4 +++- runtime/Pervasives.res | 1 + 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/compiler/ml/unified_ops.ml b/compiler/ml/unified_ops.ml index 997606135e..d0732f146c 100644 --- a/compiler/ml/unified_ops.ml +++ b/compiler/ml/unified_ops.ml @@ -148,6 +148,18 @@ let entries = string = None; }; }; + { + path = builtin "<<"; + name = "%lsl"; + form = Binary; + specialization = { + int = Plslint; + bool = None; + float = None; + bigint = Some Plslbigint; + string = None; + }; + }; { path = builtin "mod"; name = "%mod"; diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 03ed02f450..cb919b95cb 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -2166,7 +2166,7 @@ and parse_binary_expr ?(context = OrdinaryExpr) ?a p prec = * * First case is unary, second is a binary operator. * See Scanner.isBinaryOp *) - | (Minus | MinusDot | LessThan | Percent) + | (Minus | MinusDot | LessThan | Percent | LessThanLessThan) when (not (Scanner.is_binary_op p.scanner.src p.start_pos.pos_cnum p.end_pos.pos_cnum)) diff --git a/compiler/syntax/src/res_parsetree_viewer.ml b/compiler/syntax/src/res_parsetree_viewer.ml index 5305bd3fc2..6692d7de99 100644 --- a/compiler/syntax/src/res_parsetree_viewer.ml +++ b/compiler/syntax/src/res_parsetree_viewer.ml @@ -274,7 +274,7 @@ let operator_precedence operator = | "&&" -> 3 | "^" -> 4 | "==" | "===" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 5 - | "+" | "+." | "-" | "-." | "++" -> 6 + | "+" | "+." | "-" | "-." | "++" | "<<" -> 6 | "*" | "*." | "/" | "/." | "%" -> 7 | "**" -> 8 | "#" | "##" | "->" -> 9 @@ -300,7 +300,7 @@ let is_binary_operator operator = match operator with | ":=" | "||" | "&&" | "==" | "===" | "<" | ">" | "!=" | "!==" | "<=" | ">=" | "|>" | "+" | "+." | "-" | "-." | "++" | "*" | "*." | "/" | "/." | "**" - | "->" | "<>" | "%" | "^" -> + | "->" | "<>" | "%" | "^" | "<<" -> true | _ -> false diff --git a/compiler/syntax/src/res_token.ml b/compiler/syntax/src/res_token.ml index 29d2b503d4..1fc6a71321 100644 --- a/compiler/syntax/src/res_token.ml +++ b/compiler/syntax/src/res_token.ml @@ -52,6 +52,7 @@ type t = | ColonGreaterThan | GreaterThan | LessThan + | LessThanLessThan | LessThanSlash | Hash | HashEqual @@ -107,7 +108,7 @@ let precedence = function | Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual | BangEqualEqual | LessEqual | GreaterEqual | BarGreater -> 5 - | Plus | PlusDot | Minus | MinusDot | PlusPlus -> 6 + | Plus | PlusDot | Minus | MinusDot | PlusPlus | LessThanLessThan -> 6 | Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 7 | Exponentiation -> 8 | MinusGreater -> 9 @@ -165,6 +166,7 @@ let to_string = function | HashEqual -> "#=" | GreaterThan -> ">" | LessThan -> "<" + | LessThanLessThan -> "<<" | LessThanSlash -> " "*" | AsteriskDot -> "*." diff --git a/runtime/Pervasives.res b/runtime/Pervasives.res index 6d997a603f..65e813ebe0 100644 --- a/runtime/Pervasives.res +++ b/runtime/Pervasives.res @@ -65,6 +65,7 @@ external \"-": ('a, 'a) => 'a = "%sub" external \"*": ('a, 'a) => 'a = "%mul" external \"/": ('a, 'a) => 'a = "%div" external \"%": ('a, 'a) => 'a = "%mod" +external \"<<": ('a, 'a) => 'a = "%lsl" external mod: ('a, 'a) => 'a = "%mod" external \"**": ('a, 'a) => 'a = "%pow" external \"^": ('a, 'a) => 'a = "%bitxor" From a24b3d76415247bf54aeac676c72018d5035feef Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sun, 8 Dec 2024 16:34:28 +0000 Subject: [PATCH 02/16] update operator precedence for shift operators --- compiler/syntax/src/res_parsetree_viewer.ml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/syntax/src/res_parsetree_viewer.ml b/compiler/syntax/src/res_parsetree_viewer.ml index 6692d7de99..9f1682d495 100644 --- a/compiler/syntax/src/res_parsetree_viewer.ml +++ b/compiler/syntax/src/res_parsetree_viewer.ml @@ -274,10 +274,11 @@ let operator_precedence operator = | "&&" -> 3 | "^" -> 4 | "==" | "===" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 5 - | "+" | "+." | "-" | "-." | "++" | "<<" -> 6 - | "*" | "*." | "/" | "/." | "%" -> 7 - | "**" -> 8 - | "#" | "##" | "->" -> 9 + | "<<" | ">>" | ">>>" -> 6 + | "+" | "+." | "-" | "-." | "++" -> 7 + | "*" | "*." | "/" | "/." | "%" -> 8 + | "**" -> 9 + | "#" | "##" | "->" -> 10 | _ -> 0 let is_unary_operator operator = From 852dacffd0a0454014f3a73f85a3f9ea66c88bd2 Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sun, 8 Dec 2024 16:34:49 +0000 Subject: [PATCH 03/16] remove LessThanLessThan from binary operator parsing --- compiler/syntax/src/res_core.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index cb919b95cb..03ed02f450 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -2166,7 +2166,7 @@ and parse_binary_expr ?(context = OrdinaryExpr) ?a p prec = * * First case is unary, second is a binary operator. * See Scanner.isBinaryOp *) - | (Minus | MinusDot | LessThan | Percent | LessThanLessThan) + | (Minus | MinusDot | LessThan | Percent) when (not (Scanner.is_binary_op p.scanner.src p.start_pos.pos_cnum p.end_pos.pos_cnum)) From 086887c0647141b8fcda38b86cea6f28b4fb42ff Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sun, 30 Mar 2025 06:27:52 +0000 Subject: [PATCH 04/16] chore: update --- compiler/ml/unified_ops.ml | 41 +++++++++++++++---- compiler/syntax/src/res_scanner.ml | 11 +++++ compiler/syntax/src/res_token.ml | 6 ++- runtime/Pervasives.res | 2 + .../parsing/grammar/expressions/binary.res | 11 +++++ .../syntax_tests/data/printer/expr/binary.res | 23 +++++++++++ tests/tests/src/unified_ops_test.res | 10 +++++ 7 files changed, 96 insertions(+), 8 deletions(-) diff --git a/compiler/ml/unified_ops.ml b/compiler/ml/unified_ops.ml index d0732f146c..c8ee90fa28 100644 --- a/compiler/ml/unified_ops.ml +++ b/compiler/ml/unified_ops.ml @@ -152,13 +152,40 @@ let entries = path = builtin "<<"; name = "%lsl"; form = Binary; - specialization = { - int = Plslint; - bool = None; - float = None; - bigint = Some Plslbigint; - string = None; - }; + specialization = + { + int = Plslint; + bool = None; + float = None; + bigint = Some Plslbigint; + string = None; + }; + }; + { + path = builtin ">>"; + name = "%asr"; + form = Binary; + specialization = + { + int = Pasrint; + bool = None; + float = None; + bigint = Some Pasrbigint; + string = None; + }; + }; + { + path = builtin ">>>"; + name = "%lsr"; + form = Binary; + specialization = + { + int = Plsrint; + bool = None; + float = None; + bigint = Some Pasrbigint; + string = None; + }; }; { path = builtin "mod"; diff --git a/compiler/syntax/src/res_scanner.ml b/compiler/syntax/src/res_scanner.ml index c581a52abc..0000c5e11f 100644 --- a/compiler/syntax/src/res_scanner.ml +++ b/compiler/syntax/src/res_scanner.ml @@ -888,6 +888,14 @@ let rec scan scanner = Token.Plus) | '>' -> ( match peek scanner with + | '>' -> ( + match peek2 scanner with + | '>' -> + next3 scanner; + Token.GreaterThanGreaterThanGreaterThan + | _ -> + next2 scanner; + Token.GreaterThanGreaterThan) | '=' when not (in_diamond_mode scanner) -> next2 scanner; Token.GreaterEqual @@ -896,6 +904,9 @@ let rec scan scanner = Token.GreaterThan) | '<' when not (in_jsx_mode scanner) -> ( match peek scanner with + | '<' -> + next2 scanner; + Token.LessThanLessThan | '=' -> next2 scanner; Token.LessEqual diff --git a/compiler/syntax/src/res_token.ml b/compiler/syntax/src/res_token.ml index 1fc6a71321..8ac875824b 100644 --- a/compiler/syntax/src/res_token.ml +++ b/compiler/syntax/src/res_token.ml @@ -54,6 +54,8 @@ type t = | LessThan | LessThanLessThan | LessThanSlash + | GreaterThanGreaterThan + | GreaterThanGreaterThanGreaterThan | Hash | HashEqual | Assert @@ -108,7 +110,7 @@ let precedence = function | Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual | BangEqualEqual | LessEqual | GreaterEqual | BarGreater -> 5 - | Plus | PlusDot | Minus | MinusDot | PlusPlus | LessThanLessThan -> 6 + | Plus | PlusDot | Minus | MinusDot | PlusPlus | LessThanLessThan | GreaterThanGreaterThan | GreaterThanGreaterThanGreaterThan -> 6 | Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 7 | Exponentiation -> 8 | MinusGreater -> 9 @@ -168,6 +170,8 @@ let to_string = function | LessThan -> "<" | LessThanLessThan -> "<<" | LessThanSlash -> " ">>" + | GreaterThanGreaterThanGreaterThan -> ">>>" | Asterisk -> "*" | AsteriskDot -> "*." | Exponentiation -> "**" diff --git a/runtime/Pervasives.res b/runtime/Pervasives.res index 65e813ebe0..1edd2cc01c 100644 --- a/runtime/Pervasives.res +++ b/runtime/Pervasives.res @@ -69,6 +69,8 @@ external \"<<": ('a, 'a) => 'a = "%lsl" external mod: ('a, 'a) => 'a = "%mod" external \"**": ('a, 'a) => 'a = "%pow" external \"^": ('a, 'a) => 'a = "%bitxor" +external \">>": ('a, 'a) => 'a = "%asr" +external \">>>": ('a, 'a) => 'a = "%lsr" /* Comparisons */ /* Note: Later comparisons will be converted to unified operations too */ diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/binary.res b/tests/syntax_tests/data/parsing/grammar/expressions/binary.res index 224eb2da39..b20330bcbc 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/binary.res +++ b/tests/syntax_tests/data/parsing/grammar/expressions/binary.res @@ -34,6 +34,17 @@ let x = a ^ a == 0 let x = a -b let x = a -.b +// shift operators +let x = a << b +let x = a >> b +let x = a >>> b +let x = a << b + c +let x = a >> b + c +let x = a >>> b + c +let x = a + b << c +let x = a + b >> c +let x = a + b >>> c + // not binary expr Constructor(a, b) #Constructor(a, b) diff --git a/tests/syntax_tests/data/printer/expr/binary.res b/tests/syntax_tests/data/printer/expr/binary.res index 6f43115a00..b8b025326e 100644 --- a/tests/syntax_tests/data/printer/expr/binary.res +++ b/tests/syntax_tests/data/printer/expr/binary.res @@ -409,3 +409,26 @@ let make = (~keycap) => (@doesNotRaise [])->Belt.Array.getExn(0) @doesNotRaise []->Belt.Array.getExn(0) + +// shift operators +let x = a << b +let x = a >> b +let x = a >>> b +let x = a << b << c +let x = a >> b >> c +let x = a >>> b >>> c +let x = (a << b) << c +let x = (a >> b) >> c +let x = (a >>> b) >>> c +let x = a << (b << c) +let x = a >> (b >> c) +let x = a >>> (b >>> c) +let x = a << b + c +let x = a >> b + c +let x = a >>> b + c +let x = (a << b) + c +let x = (a >> b) + c +let x = (a >>> b) + c +let x = a << (b + c) +let x = a >> (b + c) +let x = a >>> (b + c) diff --git a/tests/tests/src/unified_ops_test.res b/tests/tests/src/unified_ops_test.res index d98d453837..abf3619f06 100644 --- a/tests/tests/src/unified_ops_test.res +++ b/tests/tests/src/unified_ops_test.res @@ -29,3 +29,13 @@ let pow_overflow = 2147483647 ** 2 let bxor_int = (a, b) => a ^ b let bxor_bigint = (a: bigint, b) => a ^ b + +let shl = 1 << 2 +let shr = 8 >> 2 +let ushr = -1 >>> 1 + +let lhs_shift = (a: int, b) => a << b +let rhs_shift = (a, b: int) => a << b +let unknown_shift = (a, b) => a << b + +let bigint_shift = 1n << 2n From 5c3f3dbde6a19097aba5528f1216082e776928e7 Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sun, 30 Mar 2025 06:51:01 +0000 Subject: [PATCH 05/16] tests: update --- .../parsing/grammar/expressions/binary.res | 4 ++-- .../syntax_tests/data/printer/expr/binary.res | 18 +++--------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/binary.res b/tests/syntax_tests/data/parsing/grammar/expressions/binary.res index b20330bcbc..b32329636e 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/binary.res +++ b/tests/syntax_tests/data/parsing/grammar/expressions/binary.res @@ -39,10 +39,10 @@ let x = a << b let x = a >> b let x = a >>> b let x = a << b + c -let x = a >> b + c -let x = a >>> b + c let x = a + b << c +let x = a >> b + c let x = a + b >> c +let x = a >>> b + c let x = a + b >>> c // not binary expr diff --git a/tests/syntax_tests/data/printer/expr/binary.res b/tests/syntax_tests/data/printer/expr/binary.res index b8b025326e..98a3f5a6c5 100644 --- a/tests/syntax_tests/data/printer/expr/binary.res +++ b/tests/syntax_tests/data/printer/expr/binary.res @@ -414,21 +414,9 @@ let make = (~keycap) => let x = a << b let x = a >> b let x = a >>> b -let x = a << b << c -let x = a >> b >> c -let x = a >>> b >>> c -let x = (a << b) << c -let x = (a >> b) >> c -let x = (a >>> b) >>> c -let x = a << (b << c) -let x = a >> (b >> c) -let x = a >>> (b >>> c) let x = a << b + c +let x = a + b << c let x = a >> b + c +let x = a + b >> c let x = a >>> b + c -let x = (a << b) + c -let x = (a >> b) + c -let x = (a >>> b) + c -let x = a << (b + c) -let x = a >> (b + c) -let x = a >>> (b + c) +let x = a + b >>> c From 211f103e87ef857a4a350d70936e5ab2df889fae Mon Sep 17 00:00:00 2001 From: gwansikk Date: Wed, 2 Apr 2025 15:56:01 +0900 Subject: [PATCH 06/16] tests: update --- tests/tests/src/unified_ops_test.res | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/tests/src/unified_ops_test.res b/tests/tests/src/unified_ops_test.res index abf3619f06..d8f2396ee6 100644 --- a/tests/tests/src/unified_ops_test.res +++ b/tests/tests/src/unified_ops_test.res @@ -30,12 +30,13 @@ let pow_overflow = 2147483647 ** 2 let bxor_int = (a, b) => a ^ b let bxor_bigint = (a: bigint, b) => a ^ b -let shl = 1 << 2 -let shr = 8 >> 2 -let ushr = -1 >>> 1 +let shl_int = 1 << 2 +let shr_int = 8 >> 2 +let ushr_int = -1 >>> 1 let lhs_shift = (a: int, b) => a << b let rhs_shift = (a, b: int) => a << b let unknown_shift = (a, b) => a << b -let bigint_shift = 1n << 2n +let shl_bigint = 1n << 2n +let shr_bigint = 8n >> 2n From 8402475e22c17af20c2f475ee9ca06ad9ef3b7d6 Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sun, 6 Apr 2025 19:08:58 +0900 Subject: [PATCH 07/16] fix: remove bigint from lsr --- compiler/ml/unified_ops.ml | 2 +- tests/tests/src/unified_ops_test.res | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/ml/unified_ops.ml b/compiler/ml/unified_ops.ml index c8ee90fa28..90aeb37e38 100644 --- a/compiler/ml/unified_ops.ml +++ b/compiler/ml/unified_ops.ml @@ -183,7 +183,7 @@ let entries = int = Plsrint; bool = None; float = None; - bigint = Some Pasrbigint; + bigint = None; string = None; }; }; diff --git a/tests/tests/src/unified_ops_test.res b/tests/tests/src/unified_ops_test.res index d8f2396ee6..c7988e5e13 100644 --- a/tests/tests/src/unified_ops_test.res +++ b/tests/tests/src/unified_ops_test.res @@ -39,4 +39,3 @@ let rhs_shift = (a, b: int) => a << b let unknown_shift = (a, b) => a << b let shl_bigint = 1n << 2n -let shr_bigint = 8n >> 2n From 46fa472bf4793364252b46c0a22a1bd2f16ffb8e Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sun, 6 Apr 2025 10:45:52 +0000 Subject: [PATCH 08/16] test: update --- .../data/parsing/grammar/expressions/binary.res | 14 +++----------- tests/syntax_tests/data/printer/expr/binary.res | 13 ++----------- tests/tests/src/belt_int_test.res | 2 ++ tests/tests/src/unified_ops_test.res | 2 +- 4 files changed, 8 insertions(+), 23 deletions(-) diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/binary.res b/tests/syntax_tests/data/parsing/grammar/expressions/binary.res index b32329636e..dff2876351 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/binary.res +++ b/tests/syntax_tests/data/parsing/grammar/expressions/binary.res @@ -29,22 +29,14 @@ let x = a + -1 + -2 let x = a + @attr -1 + @attr -2 let x = a % a == 0 let x = a ^ a == 0 +let x = a << a == 0 +let x = a >> a == 0 + // should be interpreted as binary expression not prefix op let x = a -b let x = a -.b -// shift operators -let x = a << b -let x = a >> b -let x = a >>> b -let x = a << b + c -let x = a + b << c -let x = a >> b + c -let x = a + b >> c -let x = a >>> b + c -let x = a + b >>> c - // not binary expr Constructor(a, b) #Constructor(a, b) diff --git a/tests/syntax_tests/data/printer/expr/binary.res b/tests/syntax_tests/data/printer/expr/binary.res index 98a3f5a6c5..d12bd96f88 100644 --- a/tests/syntax_tests/data/printer/expr/binary.res +++ b/tests/syntax_tests/data/printer/expr/binary.res @@ -55,6 +55,8 @@ x + y / z x / y + z x % y * z x ^ y + z +x << y + z +x >> y + z 100 * x / total 2 / 3 * 10 / 2 + 2 let rotateX = ((range / rect.height) * refY - range / 2) * getXMultiplication(rect.width) @@ -409,14 +411,3 @@ let make = (~keycap) => (@doesNotRaise [])->Belt.Array.getExn(0) @doesNotRaise []->Belt.Array.getExn(0) - -// shift operators -let x = a << b -let x = a >> b -let x = a >>> b -let x = a << b + c -let x = a + b << c -let x = a >> b + c -let x = a + b >> c -let x = a >>> b + c -let x = a + b >>> c diff --git a/tests/tests/src/belt_int_test.res b/tests/tests/src/belt_int_test.res index 0c77875493..d00ddae5bf 100644 --- a/tests/tests/src/belt_int_test.res +++ b/tests/tests/src/belt_int_test.res @@ -42,5 +42,7 @@ describe(__MODULE__, () => { eq(__LOC__, 2 / 3, 0) eq(__LOC__, 2 % 2, 0) eq(__LOC__, 2 ^ 3, 1) + eq(__LOC__, 2 << 3, 16) + eq(__LOC__, 16 >> 3, 2) }) }) diff --git a/tests/tests/src/unified_ops_test.res b/tests/tests/src/unified_ops_test.res index c7988e5e13..89b844e760 100644 --- a/tests/tests/src/unified_ops_test.res +++ b/tests/tests/src/unified_ops_test.res @@ -32,10 +32,10 @@ let bxor_bigint = (a: bigint, b) => a ^ b let shl_int = 1 << 2 let shr_int = 8 >> 2 -let ushr_int = -1 >>> 1 let lhs_shift = (a: int, b) => a << b let rhs_shift = (a, b: int) => a << b let unknown_shift = (a, b) => a << b let shl_bigint = 1n << 2n +let shr_bigint = 8n >> 2n \ No newline at end of file From aa909a5e60aa46b852f7168281a4214c7e0bb4b9 Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sun, 6 Apr 2025 11:04:53 +0000 Subject: [PATCH 09/16] feat: >>> --- compiler/ml/unified_ops.ml | 8 +------- compiler/syntax/src/res_scanner.ml | 21 +++++++++++---------- compiler/syntax/src/res_token.ml | 4 +++- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/compiler/ml/unified_ops.ml b/compiler/ml/unified_ops.ml index 90aeb37e38..25f19c1ade 100644 --- a/compiler/ml/unified_ops.ml +++ b/compiler/ml/unified_ops.ml @@ -179,13 +179,7 @@ let entries = name = "%lsr"; form = Binary; specialization = - { - int = Plsrint; - bool = None; - float = None; - bigint = None; - string = None; - }; + {int = Plsrint; bool = None; float = None; bigint = None; string = None}; }; { path = builtin "mod"; diff --git a/compiler/syntax/src/res_scanner.ml b/compiler/syntax/src/res_scanner.ml index 0000c5e11f..d116622662 100644 --- a/compiler/syntax/src/res_scanner.ml +++ b/compiler/syntax/src/res_scanner.ml @@ -887,16 +887,14 @@ let rec scan scanner = next scanner; Token.Plus) | '>' -> ( - match peek scanner with - | '>' -> ( - match peek2 scanner with - | '>' -> - next3 scanner; - Token.GreaterThanGreaterThanGreaterThan - | _ -> - next2 scanner; - Token.GreaterThanGreaterThan) - | '=' when not (in_diamond_mode scanner) -> + match (peek scanner, peek2 scanner) with + | '>', '>' when not (in_diamond_mode scanner) -> + next3 scanner; + Token.GreaterThanGreaterThanGreaterThan + | '>', _ when not (in_diamond_mode scanner) -> + next2 scanner; + Token.GreaterThanGreaterThan + | '=', _ when not (in_diamond_mode scanner) -> next2 scanner; Token.GreaterEqual | _ -> @@ -1039,6 +1037,9 @@ let reconsider_less_than scanner = if scanner.ch == '/' then let () = next scanner in Token.LessThanSlash + else if scanner.ch == '<' then ( + next scanner; + Token.LessThanLessThan) else Token.LessThan (* If an operator has whitespace around both sides, it's a binary operator *) diff --git a/compiler/syntax/src/res_token.ml b/compiler/syntax/src/res_token.ml index 8ac875824b..30aa21d88b 100644 --- a/compiler/syntax/src/res_token.ml +++ b/compiler/syntax/src/res_token.ml @@ -110,7 +110,9 @@ let precedence = function | Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual | BangEqualEqual | LessEqual | GreaterEqual | BarGreater -> 5 - | Plus | PlusDot | Minus | MinusDot | PlusPlus | LessThanLessThan | GreaterThanGreaterThan | GreaterThanGreaterThanGreaterThan -> 6 + | Plus | PlusDot | Minus | MinusDot | PlusPlus | LessThanLessThan | GreaterThanGreaterThan + | GreaterThanGreaterThanGreaterThan -> + 6 | Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 7 | Exponentiation -> 8 | MinusGreater -> 9 From aba80d2df023fbbde81ef1bdb238e5267aa6aa61 Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sun, 6 Apr 2025 11:12:59 +0000 Subject: [PATCH 10/16] chore: update --- compiler/syntax/src/res_token.ml | 4 ++-- .../syntax_tests/data/parsing/grammar/expressions/binary.res | 2 +- tests/syntax_tests/data/printer/expr/binary.res | 1 + tests/tests/src/belt_int_test.res | 1 + tests/tests/src/unified_ops_test.res | 3 ++- 5 files changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/syntax/src/res_token.ml b/compiler/syntax/src/res_token.ml index 30aa21d88b..542debf58f 100644 --- a/compiler/syntax/src/res_token.ml +++ b/compiler/syntax/src/res_token.ml @@ -110,8 +110,8 @@ let precedence = function | Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual | BangEqualEqual | LessEqual | GreaterEqual | BarGreater -> 5 - | Plus | PlusDot | Minus | MinusDot | PlusPlus | LessThanLessThan | GreaterThanGreaterThan - | GreaterThanGreaterThanGreaterThan -> + | Plus | PlusDot | Minus | MinusDot | PlusPlus | LessThanLessThan + | GreaterThanGreaterThan | GreaterThanGreaterThanGreaterThan -> 6 | Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 7 | Exponentiation -> 8 diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/binary.res b/tests/syntax_tests/data/parsing/grammar/expressions/binary.res index dff2876351..92eae96eb8 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/binary.res +++ b/tests/syntax_tests/data/parsing/grammar/expressions/binary.res @@ -31,7 +31,7 @@ let x = a % a == 0 let x = a ^ a == 0 let x = a << a == 0 let x = a >> a == 0 - +let x = a >>> a == 0 // should be interpreted as binary expression not prefix op let x = a -b diff --git a/tests/syntax_tests/data/printer/expr/binary.res b/tests/syntax_tests/data/printer/expr/binary.res index d12bd96f88..b36e4a70fc 100644 --- a/tests/syntax_tests/data/printer/expr/binary.res +++ b/tests/syntax_tests/data/printer/expr/binary.res @@ -57,6 +57,7 @@ x % y * z x ^ y + z x << y + z x >> y + z +x >>> y + z 100 * x / total 2 / 3 * 10 / 2 + 2 let rotateX = ((range / rect.height) * refY - range / 2) * getXMultiplication(rect.width) diff --git a/tests/tests/src/belt_int_test.res b/tests/tests/src/belt_int_test.res index d00ddae5bf..8a2ee86238 100644 --- a/tests/tests/src/belt_int_test.res +++ b/tests/tests/src/belt_int_test.res @@ -44,5 +44,6 @@ describe(__MODULE__, () => { eq(__LOC__, 2 ^ 3, 1) eq(__LOC__, 2 << 3, 16) eq(__LOC__, 16 >> 3, 2) + eq(__LOC__, 16 >>> 3, 2) }) }) diff --git a/tests/tests/src/unified_ops_test.res b/tests/tests/src/unified_ops_test.res index 89b844e760..e26c8def82 100644 --- a/tests/tests/src/unified_ops_test.res +++ b/tests/tests/src/unified_ops_test.res @@ -32,10 +32,11 @@ let bxor_bigint = (a: bigint, b) => a ^ b let shl_int = 1 << 2 let shr_int = 8 >> 2 +let lsr_int = -1 >>> 1 let lhs_shift = (a: int, b) => a << b let rhs_shift = (a, b: int) => a << b let unknown_shift = (a, b) => a << b let shl_bigint = 1n << 2n -let shr_bigint = 8n >> 2n \ No newline at end of file +let shr_bigint = 8n >> 2n From 861ea7f55f6493f4c1c507ede50497228d64e1d8 Mon Sep 17 00:00:00 2001 From: gwansikk Date: Sun, 6 Apr 2025 17:16:27 +0000 Subject: [PATCH 11/16] feat: update Co-authored-by: Hyeseong Kim --- compiler/syntax/src/res_core.ml | 31 +++++++++++++++++++ compiler/syntax/src/res_scanner.ml | 47 ++++++++++++++++++++--------- compiler/syntax/src/res_scanner.mli | 4 +++ compiler/syntax/src/res_token.ml | 25 ++++++++------- 4 files changed, 80 insertions(+), 27 deletions(-) diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 03ed02f450..6be3e34b28 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -2138,6 +2138,27 @@ and parse_operand_expr ~context p = (* pexp_loc = mkLoc startPos endPos *) } +and parse_shift_operator (p : Parser.t) = + let start_pos = p.start_pos in + let end_pos = p.end_pos in + if p.token = LessThan && Scanner.is_left_shift p.scanner start_pos.pos_cnum + then ( + Parser.next p; + {p with token = LeftShift; start_pos; prev_end_pos = end_pos}) + else if + p.token = GreaterThan + && Scanner.is_right_shift_unsigned p.scanner start_pos.pos_cnum + then ( + Parser.next p; + Parser.next p; + {p with token = RightShiftUnsigned; start_pos; prev_end_pos = end_pos}) + else if + p.token = GreaterThan && Scanner.is_right_shift p.scanner start_pos.pos_cnum + then ( + Parser.next p; + {p with token = RightShift; start_pos; prev_end_pos = end_pos}) + else p + (* a binary expression is an expression that combines two expressions with an * operator. Examples: * a + b @@ -2150,6 +2171,11 @@ and parse_binary_expr ?(context = OrdinaryExpr) ?a p prec = | None -> parse_operand_expr ~context p in let rec loop a = + let p = + match p.token with + | LessThan | GreaterThan -> parse_shift_operator p + | _ -> p + in let token = p.Parser.token in let token_prec = match token with @@ -2179,6 +2205,11 @@ and parse_binary_expr ?(context = OrdinaryExpr) ?a p prec = Parser.leave_breadcrumb p (Grammar.ExprBinaryAfterOp token); let start_pos = p.start_pos in Parser.next p; + (* let p = + match p.token with + | LessThan | GreaterThan -> parse_shift_operator p + | _ -> p + in *) let end_pos = p.prev_end_pos in let token_prec = (* exponentiation operator is right-associative *) diff --git a/compiler/syntax/src/res_scanner.ml b/compiler/syntax/src/res_scanner.ml index d116622662..18b8a3fd60 100644 --- a/compiler/syntax/src/res_scanner.ml +++ b/compiler/syntax/src/res_scanner.ml @@ -887,24 +887,23 @@ let rec scan scanner = next scanner; Token.Plus) | '>' -> ( - match (peek scanner, peek2 scanner) with - | '>', '>' when not (in_diamond_mode scanner) -> - next3 scanner; - Token.GreaterThanGreaterThanGreaterThan - | '>', _ when not (in_diamond_mode scanner) -> - next2 scanner; - Token.GreaterThanGreaterThan - | '=', _ when not (in_diamond_mode scanner) -> + match peek scanner with + | '=' when not (in_diamond_mode scanner) -> next2 scanner; Token.GreaterEqual | _ -> next scanner; Token.GreaterThan) - | '<' when not (in_jsx_mode scanner) -> ( + | '<' when not (in_diamond_mode scanner) -> ( match peek scanner with - | '<' -> + | '=' -> next2 scanner; - Token.LessThanLessThan + Token.LessEqual + | _ -> + next scanner; + Token.LessThan) + | '<' when not (in_jsx_mode scanner) -> ( + match peek scanner with | '=' -> next2 scanner; Token.LessEqual @@ -1037,9 +1036,6 @@ let reconsider_less_than scanner = if scanner.ch == '/' then let () = next scanner in Token.LessThanSlash - else if scanner.ch == '<' then ( - next scanner; - Token.LessThanLessThan) else Token.LessThan (* If an operator has whitespace around both sides, it's a binary operator *) @@ -1058,3 +1054,26 @@ let is_binary_op src start_cnum end_cnum = || is_whitespace (String.unsafe_get src end_cnum) in left_ok && right_ok) + +let is_left_shift scanner _start_cnum = + (* print_endline ("@@@@@ is_left_shift ch: " ^ (Char.escaped scanner.ch)); *) + (* print_endline ("@@@@@ is_left_shift cnum: " ^ (string_of_int _start_cnum)); *) + (* print_endline ("@@@@@ is_left_shift peek: " ^ (Char.escaped (peek scanner))); *) + match scanner.ch with + | '<' -> true + | _ -> false + +let is_right_shift scanner _start_cnum = + (* print_endline ("@@@@@ is_right_shift ch: " ^ (Char.escaped scanner.ch)); *) + (* print_endline ("@@@@@ is_right_shift cnum: " ^ (string_of_int _start_cnum)); *) + (* print_endline ("@@@@@ is_right_shift peek: " ^ (Char.escaped (peek scanner))); *) + match scanner.ch with + | '>' -> true + | _ -> false + +let is_right_shift_unsigned scanner _start_cnum = + (* print_endline ("@@@@@ is_right_shift_unsigned ch: " ^ (Char.escaped scanner.ch)); *) + (* print_endline ("@@@@@ is_right_shift_unsigned peek: " ^ (Char.escaped (peek scanner))); *) + match (scanner.ch, peek scanner) with + | '>', '>' -> true + | _ -> false diff --git a/compiler/syntax/src/res_scanner.mli b/compiler/syntax/src/res_scanner.mli index a5b9c122ba..730b11be7e 100644 --- a/compiler/syntax/src/res_scanner.mli +++ b/compiler/syntax/src/res_scanner.mli @@ -26,6 +26,10 @@ val scan : t -> Lexing.position * Lexing.position * Res_token.t val is_binary_op : string -> int -> int -> bool +val is_left_shift : t -> int -> bool +val is_right_shift : t -> int -> bool +val is_right_shift_unsigned : t -> int -> bool + val set_jsx_mode : t -> unit val set_diamond_mode : t -> unit val pop_mode : t -> mode -> unit diff --git a/compiler/syntax/src/res_token.ml b/compiler/syntax/src/res_token.ml index 542debf58f..f3e8ad1cbc 100644 --- a/compiler/syntax/src/res_token.ml +++ b/compiler/syntax/src/res_token.ml @@ -52,10 +52,7 @@ type t = | ColonGreaterThan | GreaterThan | LessThan - | LessThanLessThan | LessThanSlash - | GreaterThanGreaterThan - | GreaterThanGreaterThanGreaterThan | Hash | HashEqual | Assert @@ -101,6 +98,9 @@ type t = | Try | DocComment of Location.t * string | ModuleComment of Location.t * string + | LeftShift + | RightShift + | RightShiftUnsigned let precedence = function | HashEqual | ColonEqual -> 1 @@ -110,13 +110,12 @@ let precedence = function | Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual | BangEqualEqual | LessEqual | GreaterEqual | BarGreater -> 5 - | Plus | PlusDot | Minus | MinusDot | PlusPlus | LessThanLessThan - | GreaterThanGreaterThan | GreaterThanGreaterThanGreaterThan -> - 6 - | Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 7 - | Exponentiation -> 8 - | MinusGreater -> 9 - | Dot -> 10 + | LeftShift | RightShift | RightShiftUnsigned -> 6 + | Plus | PlusDot | Minus | MinusDot | PlusPlus -> 7 + | Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 8 + | Exponentiation -> 9 + | MinusGreater -> 10 + | Dot -> 11 | _ -> 0 let to_string = function @@ -170,10 +169,7 @@ let to_string = function | HashEqual -> "#=" | GreaterThan -> ">" | LessThan -> "<" - | LessThanLessThan -> "<<" | LessThanSlash -> " ">>" - | GreaterThanGreaterThanGreaterThan -> ">>>" | Asterisk -> "*" | AsteriskDot -> "*." | Exponentiation -> "**" @@ -220,6 +216,9 @@ let to_string = function | Try -> "try" | DocComment (_loc, s) -> "DocComment " ^ s | ModuleComment (_loc, s) -> "ModuleComment " ^ s + | LeftShift -> "<<" + | RightShift -> ">>" + | RightShiftUnsigned -> ">>>" let keyword_table = function | "and" -> And From 763803d7b75d50b4267ff62f7a0d7751294cf0cb Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sat, 12 Apr 2025 00:59:48 +0900 Subject: [PATCH 12/16] Complete implementation of shift operators I looked back at the last session with Gwansik and realized that, I had misguided him by simply misunderstanding a particular syntx error. Gwansik's initial approach was almost close. Co-authored-by: gwansikk --- compiler/syntax/src/res_core.ml | 31 ------------ compiler/syntax/src/res_scanner.ml | 49 ++++++------------- compiler/syntax/src/res_scanner.mli | 4 -- .../expected/typeConstructorArgs.res.txt | 8 +-- .../expressions/expected/binary.res.txt | 3 ++ .../data/printer/expr/expected/binary.res.txt | 3 ++ tests/tests/src/belt_int_test.mjs | 3 ++ tests/tests/src/unified_ops_test.mjs | 15 ++++++ 8 files changed, 45 insertions(+), 71 deletions(-) diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 6be3e34b28..03ed02f450 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -2138,27 +2138,6 @@ and parse_operand_expr ~context p = (* pexp_loc = mkLoc startPos endPos *) } -and parse_shift_operator (p : Parser.t) = - let start_pos = p.start_pos in - let end_pos = p.end_pos in - if p.token = LessThan && Scanner.is_left_shift p.scanner start_pos.pos_cnum - then ( - Parser.next p; - {p with token = LeftShift; start_pos; prev_end_pos = end_pos}) - else if - p.token = GreaterThan - && Scanner.is_right_shift_unsigned p.scanner start_pos.pos_cnum - then ( - Parser.next p; - Parser.next p; - {p with token = RightShiftUnsigned; start_pos; prev_end_pos = end_pos}) - else if - p.token = GreaterThan && Scanner.is_right_shift p.scanner start_pos.pos_cnum - then ( - Parser.next p; - {p with token = RightShift; start_pos; prev_end_pos = end_pos}) - else p - (* a binary expression is an expression that combines two expressions with an * operator. Examples: * a + b @@ -2171,11 +2150,6 @@ and parse_binary_expr ?(context = OrdinaryExpr) ?a p prec = | None -> parse_operand_expr ~context p in let rec loop a = - let p = - match p.token with - | LessThan | GreaterThan -> parse_shift_operator p - | _ -> p - in let token = p.Parser.token in let token_prec = match token with @@ -2205,11 +2179,6 @@ and parse_binary_expr ?(context = OrdinaryExpr) ?a p prec = Parser.leave_breadcrumb p (Grammar.ExprBinaryAfterOp token); let start_pos = p.start_pos in Parser.next p; - (* let p = - match p.token with - | LessThan | GreaterThan -> parse_shift_operator p - | _ -> p - in *) let end_pos = p.prev_end_pos in let token_prec = (* exponentiation operator is right-associative *) diff --git a/compiler/syntax/src/res_scanner.ml b/compiler/syntax/src/res_scanner.ml index 18b8a3fd60..6ce390a68d 100644 --- a/compiler/syntax/src/res_scanner.ml +++ b/compiler/syntax/src/res_scanner.ml @@ -886,24 +886,30 @@ let rec scan scanner = | _ -> next scanner; Token.Plus) - | '>' -> ( + | '>' when not (in_diamond_mode scanner) -> ( match peek scanner with - | '=' when not (in_diamond_mode scanner) -> + | '=' -> next2 scanner; Token.GreaterEqual + | '>' -> ( + match peek2 scanner with + | '>' -> + next3 scanner; + Token.RightShiftUnsigned + | _ -> + next2 scanner; + Token.RightShift) | _ -> next scanner; Token.GreaterThan) - | '<' when not (in_diamond_mode scanner) -> ( - match peek scanner with - | '=' -> - next2 scanner; - Token.LessEqual - | _ -> - next scanner; - Token.LessThan) + | '>' -> + next scanner; + Token.GreaterThan | '<' when not (in_jsx_mode scanner) -> ( match peek scanner with + | '<' when not (in_diamond_mode scanner) -> + next2 scanner; + Token.LeftShift | '=' -> next2 scanner; Token.LessEqual @@ -1054,26 +1060,3 @@ let is_binary_op src start_cnum end_cnum = || is_whitespace (String.unsafe_get src end_cnum) in left_ok && right_ok) - -let is_left_shift scanner _start_cnum = - (* print_endline ("@@@@@ is_left_shift ch: " ^ (Char.escaped scanner.ch)); *) - (* print_endline ("@@@@@ is_left_shift cnum: " ^ (string_of_int _start_cnum)); *) - (* print_endline ("@@@@@ is_left_shift peek: " ^ (Char.escaped (peek scanner))); *) - match scanner.ch with - | '<' -> true - | _ -> false - -let is_right_shift scanner _start_cnum = - (* print_endline ("@@@@@ is_right_shift ch: " ^ (Char.escaped scanner.ch)); *) - (* print_endline ("@@@@@ is_right_shift cnum: " ^ (string_of_int _start_cnum)); *) - (* print_endline ("@@@@@ is_right_shift peek: " ^ (Char.escaped (peek scanner))); *) - match scanner.ch with - | '>' -> true - | _ -> false - -let is_right_shift_unsigned scanner _start_cnum = - (* print_endline ("@@@@@ is_right_shift_unsigned ch: " ^ (Char.escaped scanner.ch)); *) - (* print_endline ("@@@@@ is_right_shift_unsigned peek: " ^ (Char.escaped (peek scanner))); *) - match (scanner.ch, peek scanner) with - | '>', '>' -> true - | _ -> false diff --git a/compiler/syntax/src/res_scanner.mli b/compiler/syntax/src/res_scanner.mli index 730b11be7e..a5b9c122ba 100644 --- a/compiler/syntax/src/res_scanner.mli +++ b/compiler/syntax/src/res_scanner.mli @@ -26,10 +26,6 @@ val scan : t -> Lexing.position * Lexing.position * Res_token.t val is_binary_op : string -> int -> int -> bool -val is_left_shift : t -> int -> bool -val is_right_shift : t -> int -> bool -val is_right_shift_unsigned : t -> int -> bool - val set_jsx_mode : t -> unit val set_diamond_mode : t -> unit val pop_mode : t -> mode -> unit diff --git a/tests/syntax_tests/data/parsing/errors/typexpr/expected/typeConstructorArgs.res.txt b/tests/syntax_tests/data/parsing/errors/typexpr/expected/typeConstructorArgs.res.txt index 4aced9f2c8..7e6bbff333 100644 --- a/tests/syntax_tests/data/parsing/errors/typexpr/expected/typeConstructorArgs.res.txt +++ b/tests/syntax_tests/data/parsing/errors/typexpr/expected/typeConstructorArgs.res.txt @@ -38,18 +38,20 @@ Syntax error! - syntax_tests/data/parsing/errors/typexpr/typeConstructorArgs.res:9:28 + syntax_tests/data/parsing/errors/typexpr/typeConstructorArgs.res:8:16-17 + 6 │ type t<'a> = private Belt.Map.t('a) 7 │ 8 │ type t = option<> 9 │ type t = option(>) 10 │ - I'm not sure what to parse here when looking at ")". + I'm not sure what to parse here when looking at "<<". type nonrec 'a node = { _value: 'a Js.Nullable.value } type nonrec 'a t = 'a Belt.Map.t type nonrec 'a t = private 'a Belt.Map.t -type nonrec t = int node option +type nonrec t = option +;;node < (int >> ([%rescript.exprhole ])) type nonrec t = int node option \ No newline at end of file diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/expected/binary.res.txt b/tests/syntax_tests/data/parsing/grammar/expressions/expected/binary.res.txt index 14d06adaa4..7f85025c99 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/expected/binary.res.txt +++ b/tests/syntax_tests/data/parsing/grammar/expressions/expected/binary.res.txt @@ -15,6 +15,9 @@ let x = (a + (-1)) + (-2) let x = (a + (((-1))[@attr ])) + (((-2))[@attr ]) let x = (a % a) == 0 let x = a ^ (a == 0) +let x = (a << a) == 0 +let x = (a >> a) == 0 +let x = (a >>> a) == 0 let x = a - b let x = a -. b ;;Constructor (a, b) diff --git a/tests/syntax_tests/data/printer/expr/expected/binary.res.txt b/tests/syntax_tests/data/printer/expr/expected/binary.res.txt index 8717665e87..e1918cd184 100644 --- a/tests/syntax_tests/data/printer/expr/expected/binary.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/binary.res.txt @@ -86,6 +86,9 @@ x + y / z x / y + z x % y * z x ^ y + z +x << y + z +x >> y + z +x >>> y + z 100 * x / total 2 / 3 * 10 / 2 + 2 let rotateX = (range / rect.height * refY - range / 2) * getXMultiplication(rect.width) diff --git a/tests/tests/src/belt_int_test.mjs b/tests/tests/src/belt_int_test.mjs index 1c659da1e9..fe660cd9a1 100644 --- a/tests/tests/src/belt_int_test.mjs +++ b/tests/tests/src/belt_int_test.mjs @@ -37,6 +37,9 @@ Mocha.describe("Belt_int_test", () => { Test_utils.eq("File \"belt_int_test.res\", line 42, characters 7-14", 0, 0); Test_utils.eq("File \"belt_int_test.res\", line 43, characters 7-14", 0, 0); Test_utils.eq("File \"belt_int_test.res\", line 44, characters 7-14", 1, 1); + Test_utils.eq("File \"belt_int_test.res\", line 45, characters 7-14", 16, 16); + Test_utils.eq("File \"belt_int_test.res\", line 46, characters 7-14", 2, 2); + Test_utils.eq("File \"belt_int_test.res\", line 47, characters 7-14", 2, 2); }); }); diff --git a/tests/tests/src/unified_ops_test.mjs b/tests/tests/src/unified_ops_test.mjs index 9d1b858078..a849e5e12f 100644 --- a/tests/tests/src/unified_ops_test.mjs +++ b/tests/tests/src/unified_ops_test.mjs @@ -75,8 +75,18 @@ function bxor_bigint(a, b) { return a ^ b; } +let shl_bigint = (1n << 2n); + +let shr_bigint = (8n >> 2n); + let int = 3; +let shl_int = 4; + +let shr_int = 2; + +let lsr_int = 2147483647; + export { int, float, @@ -101,5 +111,10 @@ export { pow_overflow, bxor_int, bxor_bigint, + shl_int, + shr_int, + lsr_int, + shl_bigint, + shr_bigint, } /* No side effect */ From 5bc2981040ea46a4f64bd08ec401ef5aa880f1ad Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Sat, 12 Apr 2025 01:23:32 +0900 Subject: [PATCH 13/16] unparen shift ops --- compiler/core/js_dump.ml | 16 ++-------------- lib/es6/Belt_HashMap.js | 4 ++-- lib/es6/Belt_HashMapInt.js | 4 ++-- lib/es6/Belt_HashMapString.js | 4 ++-- lib/es6/Belt_HashSet.js | 4 ++-- lib/es6/Belt_HashSetInt.js | 4 ++-- lib/es6/Belt_HashSetString.js | 4 ++-- lib/es6/Belt_internalBucketsType.js | 4 ++-- lib/es6/Primitive_hash.js | 20 ++++++++++---------- lib/js/Belt_HashMap.js | 4 ++-- lib/js/Belt_HashMapInt.js | 4 ++-- lib/js/Belt_HashMapString.js | 4 ++-- lib/js/Belt_HashSet.js | 4 ++-- lib/js/Belt_HashSetInt.js | 4 ++-- lib/js/Belt_HashSetString.js | 4 ++-- lib/js/Belt_internalBucketsType.js | 4 ++-- lib/js/Primitive_hash.js | 20 ++++++++++---------- tests/tests/src/alias_default_value_test.mjs | 2 +- tests/tests/src/belt_list_test.mjs | 8 ++++---- tests/tests/src/belt_sortarray_test.mjs | 2 +- tests/tests/src/bigint_test.mjs | 16 ++++++++-------- tests/tests/src/bs_mutable_set_test.mjs | 6 +++--- tests/tests/src/bs_poly_set_test.mjs | 2 +- tests/tests/src/core/Core_TempTests.mjs | 2 +- tests/tests/src/for_loop_test.mjs | 10 +++++----- tests/tests/src/gray_code_test.mjs | 16 ++++++++-------- tests/tests/src/js_array_test.mjs | 4 ++-- tests/tests/src/js_null_test.mjs | 2 +- tests/tests/src/js_null_undefined_test.mjs | 2 +- tests/tests/src/js_undefined_test.mjs | 2 +- tests/tests/src/mario_game.mjs | 2 +- tests/tests/src/ocaml_compat/Ocaml_List.mjs | 8 ++++---- tests/tests/src/record_name_test.mjs | 4 ++-- tests/tests/src/test_for_loop.mjs | 8 ++++---- tests/tests/src/test_list.mjs | 8 ++++---- tests/tests/src/test_tuple.mjs | 2 +- tests/tests/src/unified_ops_test.mjs | 4 ++-- 37 files changed, 105 insertions(+), 117 deletions(-) diff --git a/compiler/core/js_dump.ml b/compiler/core/js_dump.ml index bc174e7dd5..e1acf79258 100644 --- a/compiler/core/js_dump.ml +++ b/compiler/core/js_dump.ml @@ -717,13 +717,7 @@ and expression_desc cxt ~(level : int) f x : cxt = expression_desc cxt ~level:(level : int) f (Is_null_or_undefined e1) | Bin (op, e1, e2) -> let out, lft, rght = Js_op_util.op_prec op in - let need_paren = - level > out - || - match op with - | Lsl | Lsr | Asr -> true - | _ -> false - in + let need_paren = level > out in (* We are more conservative here, to make the generated code more readable to the user *) P.cond_paren_group f need_paren (fun _ -> @@ -735,13 +729,7 @@ and expression_desc cxt ~(level : int) f x : cxt = | String_append (e1, e2) -> let op : Js_op.binop = Plus in let out, lft, rght = Js_op_util.op_prec op in - let need_paren = - level > out - || - match op with - | Lsl | Lsr | Asr -> true - | _ -> false - in + let need_paren = level > out in P.cond_paren_group f need_paren (fun _ -> let cxt = expression ~level:lft cxt f e1 in P.space f; diff --git a/lib/es6/Belt_HashMap.js b/lib/es6/Belt_HashMap.js index 1e481f3d5b..c044625d68 100644 --- a/lib/es6/Belt_HashMap.js +++ b/lib/es6/Belt_HashMap.js @@ -66,10 +66,10 @@ function set0(h, key, value, eq, hash) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashMapInt.js b/lib/es6/Belt_HashMapInt.js index eea270865b..553fb6b419 100644 --- a/lib/es6/Belt_HashMapInt.js +++ b/lib/es6/Belt_HashMapInt.js @@ -63,10 +63,10 @@ function set(h, key, value) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashMapString.js b/lib/es6/Belt_HashMapString.js index 6f8a428544..bd5194964b 100644 --- a/lib/es6/Belt_HashMapString.js +++ b/lib/es6/Belt_HashMapString.js @@ -63,10 +63,10 @@ function set(h, key, value) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashSet.js b/lib/es6/Belt_HashSet.js index 8eb7900af2..2ed9b6c306 100644 --- a/lib/es6/Belt_HashSet.js +++ b/lib/es6/Belt_HashSet.js @@ -93,10 +93,10 @@ function add0(h, key, hash, eq) { next: undefined }; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashSetInt.js b/lib/es6/Belt_HashSetInt.js index 7be6585ebd..4ba582eca1 100644 --- a/lib/es6/Belt_HashSetInt.js +++ b/lib/es6/Belt_HashSetInt.js @@ -93,10 +93,10 @@ function add(h, key) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashSetString.js b/lib/es6/Belt_HashSetString.js index e0876a5a76..3dc2d4c4cb 100644 --- a/lib/es6/Belt_HashSetString.js +++ b/lib/es6/Belt_HashSetString.js @@ -93,10 +93,10 @@ function add(h, key) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/es6/Belt_internalBucketsType.js b/lib/es6/Belt_internalBucketsType.js index d2101f53bf..f31e39950f 100644 --- a/lib/es6/Belt_internalBucketsType.js +++ b/lib/es6/Belt_internalBucketsType.js @@ -7,10 +7,10 @@ function power_2_above(_x, n) { if (x >= n) { return x; } - if ((x << 1) < x) { + if (x << 1 < x) { return x; } - _x = (x << 1); + _x = x << 1; continue; }; } diff --git a/lib/es6/Primitive_hash.js b/lib/es6/Primitive_hash.js index 5a6688256a..cb7a8fd4f3 100644 --- a/lib/es6/Primitive_hash.js +++ b/lib/es6/Primitive_hash.js @@ -44,7 +44,7 @@ function unsafe_pop(q) { } function rotl32(x, n) { - return (x << n) | (x >>> (32 - n | 0)) | 0; + return x << n | x >>> (32 - n | 0) | 0; } function hash_mix_int(h, d) { @@ -58,11 +58,11 @@ function hash_mix_int(h, d) { } function hash_final_mix(h) { - let h$1 = h ^ (h >>> 16); + let h$1 = h ^ h >>> 16; h$1 = Math.imul(h$1, -2048144789); - h$1 = h$1 ^ (h$1 >>> 13); + h$1 = h$1 ^ h$1 >>> 13; h$1 = Math.imul(h$1, -1028477387); - return h$1 ^ (h$1 >>> 16); + return h$1 ^ h$1 >>> 16; } function hash_mix_string(h, s) { @@ -70,14 +70,14 @@ function hash_mix_string(h, s) { let block = (len / 4 | 0) - 1 | 0; let hash = h; for (let i = 0; i <= block; ++i) { - let j = (i << 2); - let w = s.charCodeAt(j) | (s.charCodeAt(j + 1 | 0) << 8) | (s.charCodeAt(j + 2 | 0) << 16) | (s.charCodeAt(j + 3 | 0) << 24); + let j = i << 2; + let w = s.charCodeAt(j) | s.charCodeAt(j + 1 | 0) << 8 | s.charCodeAt(j + 2 | 0) << 16 | s.charCodeAt(j + 3 | 0) << 24; hash = hash_mix_int(hash, w); } let modulo = len & 3; if (modulo !== 0) { - let w$1 = modulo === 3 ? (s.charCodeAt(len - 1 | 0) << 16) | (s.charCodeAt(len - 2 | 0) << 8) | s.charCodeAt(len - 3 | 0) : ( - modulo === 2 ? (s.charCodeAt(len - 1 | 0) << 8) | s.charCodeAt(len - 2 | 0) : s.charCodeAt(len - 1 | 0) + let w$1 = modulo === 3 ? s.charCodeAt(len - 1 | 0) << 16 | s.charCodeAt(len - 2 | 0) << 8 | s.charCodeAt(len - 3 | 0) : ( + modulo === 2 ? s.charCodeAt(len - 1 | 0) << 8 | s.charCodeAt(len - 2 | 0) : s.charCodeAt(len - 1 | 0) ); hash = hash_mix_int(hash, w$1); } @@ -117,7 +117,7 @@ function hash(count, _limit, seed, obj) { let size = obj$1.length | 0; if (size !== 0) { let obj_tag = obj$1.TAG; - let tag = (size << 10) | obj_tag; + let tag = size << 10 | obj_tag; s = hash_mix_int(s, tag); let v = size - 1 | 0; let block = v < num ? v : num; @@ -133,7 +133,7 @@ function hash(count, _limit, seed, obj) { } return size })(obj$1, v => push_back(queue, v)); - s = hash_mix_int(s, (size$1 << 10) | 0); + s = hash_mix_int(s, size$1 << 10 | 0); } } diff --git a/lib/js/Belt_HashMap.js b/lib/js/Belt_HashMap.js index 6bd8b97a2d..0e5c387976 100644 --- a/lib/js/Belt_HashMap.js +++ b/lib/js/Belt_HashMap.js @@ -66,10 +66,10 @@ function set0(h, key, value, eq, hash) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashMapInt.js b/lib/js/Belt_HashMapInt.js index 3aff60b364..a255e726cc 100644 --- a/lib/js/Belt_HashMapInt.js +++ b/lib/js/Belt_HashMapInt.js @@ -63,10 +63,10 @@ function set(h, key, value) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashMapString.js b/lib/js/Belt_HashMapString.js index 73e1847781..0f1d4238bd 100644 --- a/lib/js/Belt_HashMapString.js +++ b/lib/js/Belt_HashMapString.js @@ -63,10 +63,10 @@ function set(h, key, value) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashSet.js b/lib/js/Belt_HashSet.js index 0897d41ebb..15e8a0f7ba 100644 --- a/lib/js/Belt_HashSet.js +++ b/lib/js/Belt_HashSet.js @@ -93,10 +93,10 @@ function add0(h, key, hash, eq) { next: undefined }; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashSetInt.js b/lib/js/Belt_HashSetInt.js index db0c833e84..110da44827 100644 --- a/lib/js/Belt_HashSetInt.js +++ b/lib/js/Belt_HashSetInt.js @@ -93,10 +93,10 @@ function add(h, key) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashSetString.js b/lib/js/Belt_HashSetString.js index d2779cf4ff..c3f61176ce 100644 --- a/lib/js/Belt_HashSetString.js +++ b/lib/js/Belt_HashSetString.js @@ -93,10 +93,10 @@ function add(h, key) { }; h.size = h.size + 1 | 0; } - if (h.size > (buckets_len << 1)) { + if (h.size > buckets_len << 1) { let odata = h.buckets; let osize = odata.length; - let nsize = (osize << 1); + let nsize = osize << 1; if (nsize < osize) { return; } diff --git a/lib/js/Belt_internalBucketsType.js b/lib/js/Belt_internalBucketsType.js index afd6d07891..4718cb9c43 100644 --- a/lib/js/Belt_internalBucketsType.js +++ b/lib/js/Belt_internalBucketsType.js @@ -7,10 +7,10 @@ function power_2_above(_x, n) { if (x >= n) { return x; } - if ((x << 1) < x) { + if (x << 1 < x) { return x; } - _x = (x << 1); + _x = x << 1; continue; }; } diff --git a/lib/js/Primitive_hash.js b/lib/js/Primitive_hash.js index e501682ae1..ff04ba7d7f 100644 --- a/lib/js/Primitive_hash.js +++ b/lib/js/Primitive_hash.js @@ -44,7 +44,7 @@ function unsafe_pop(q) { } function rotl32(x, n) { - return (x << n) | (x >>> (32 - n | 0)) | 0; + return x << n | x >>> (32 - n | 0) | 0; } function hash_mix_int(h, d) { @@ -58,11 +58,11 @@ function hash_mix_int(h, d) { } function hash_final_mix(h) { - let h$1 = h ^ (h >>> 16); + let h$1 = h ^ h >>> 16; h$1 = Math.imul(h$1, -2048144789); - h$1 = h$1 ^ (h$1 >>> 13); + h$1 = h$1 ^ h$1 >>> 13; h$1 = Math.imul(h$1, -1028477387); - return h$1 ^ (h$1 >>> 16); + return h$1 ^ h$1 >>> 16; } function hash_mix_string(h, s) { @@ -70,14 +70,14 @@ function hash_mix_string(h, s) { let block = (len / 4 | 0) - 1 | 0; let hash = h; for (let i = 0; i <= block; ++i) { - let j = (i << 2); - let w = s.charCodeAt(j) | (s.charCodeAt(j + 1 | 0) << 8) | (s.charCodeAt(j + 2 | 0) << 16) | (s.charCodeAt(j + 3 | 0) << 24); + let j = i << 2; + let w = s.charCodeAt(j) | s.charCodeAt(j + 1 | 0) << 8 | s.charCodeAt(j + 2 | 0) << 16 | s.charCodeAt(j + 3 | 0) << 24; hash = hash_mix_int(hash, w); } let modulo = len & 3; if (modulo !== 0) { - let w$1 = modulo === 3 ? (s.charCodeAt(len - 1 | 0) << 16) | (s.charCodeAt(len - 2 | 0) << 8) | s.charCodeAt(len - 3 | 0) : ( - modulo === 2 ? (s.charCodeAt(len - 1 | 0) << 8) | s.charCodeAt(len - 2 | 0) : s.charCodeAt(len - 1 | 0) + let w$1 = modulo === 3 ? s.charCodeAt(len - 1 | 0) << 16 | s.charCodeAt(len - 2 | 0) << 8 | s.charCodeAt(len - 3 | 0) : ( + modulo === 2 ? s.charCodeAt(len - 1 | 0) << 8 | s.charCodeAt(len - 2 | 0) : s.charCodeAt(len - 1 | 0) ); hash = hash_mix_int(hash, w$1); } @@ -117,7 +117,7 @@ function hash(count, _limit, seed, obj) { let size = obj$1.length | 0; if (size !== 0) { let obj_tag = obj$1.TAG; - let tag = (size << 10) | obj_tag; + let tag = size << 10 | obj_tag; s = hash_mix_int(s, tag); let v = size - 1 | 0; let block = v < num ? v : num; @@ -133,7 +133,7 @@ function hash(count, _limit, seed, obj) { } return size })(obj$1, v => push_back(queue, v)); - s = hash_mix_int(s, (size$1 << 10) | 0); + s = hash_mix_int(s, size$1 << 10 | 0); } } diff --git a/tests/tests/src/alias_default_value_test.mjs b/tests/tests/src/alias_default_value_test.mjs index f525661bb8..7e6938ecdb 100644 --- a/tests/tests/src/alias_default_value_test.mjs +++ b/tests/tests/src/alias_default_value_test.mjs @@ -5,7 +5,7 @@ function Alias_default_value_test$C0(props) { let __b = props.b; let __a = props.a; let a = __a !== undefined ? __a : 2; - let b = __b !== undefined ? __b : (a << 1); + let b = __b !== undefined ? __b : a << 1; return a + b | 0; } diff --git a/tests/tests/src/belt_list_test.mjs b/tests/tests/src/belt_list_test.mjs index a3c5c28f36..ff68e2fee2 100644 --- a/tests/tests/src/belt_list_test.mjs +++ b/tests/tests/src/belt_list_test.mjs @@ -657,7 +657,7 @@ Mocha.describe("Belt_list_test", () => { }); let id = x => x; Mocha.test("map", () => { - Test_utils.eq("File \"belt_list_test.res\", line 109, characters 7-14", Belt_List.map(Belt_List.makeBy(5, id), x => (x << 1)), { + Test_utils.eq("File \"belt_list_test.res\", line 109, characters 7-14", Belt_List.map(Belt_List.makeBy(5, id), x => x << 1), { hd: 0, tl: { hd: 2, @@ -686,7 +686,7 @@ Mocha.describe("Belt_list_test", () => { let length_10_id = Belt_List.makeBy(10, id); let length_8_id = Belt_List.makeBy(8, id); Mocha.test("mapWithIndex etc.", () => { - let d = Belt_List.makeBy(10, x => (x << 1)); + let d = Belt_List.makeBy(10, x => x << 1); Test_utils.eq("File \"belt_list_test.res\", line 124, characters 7-14", Belt_List.zipBy(length_10_id, length_10_id, add), d); Test_utils.eq("File \"belt_list_test.res\", line 125, characters 7-14", Belt_List.zipBy(/* [] */0, { hd: 1, @@ -697,7 +697,7 @@ Mocha.describe("Belt_list_test", () => { tl: /* [] */0 }, /* [] */0, add), /* [] */0); Test_utils.eq("File \"belt_list_test.res\", line 127, characters 7-14", Belt_List.zipBy(/* [] */0, /* [] */0, add), /* [] */0); - Test_utils.eq("File \"belt_list_test.res\", line 128, characters 7-14", Belt_List.zipBy(length_10_id, length_10_id, add), Belt_List.concat(Belt_List.map(length_8_id, x => (x << 1)), { + Test_utils.eq("File \"belt_list_test.res\", line 128, characters 7-14", Belt_List.zipBy(length_10_id, length_10_id, add), Belt_List.concat(Belt_List.map(length_8_id, x => x << 1), { hd: 16, tl: { hd: 18, @@ -705,7 +705,7 @@ Mocha.describe("Belt_list_test", () => { } })); Test_utils.eq("File \"belt_list_test.res\", line 129, characters 7-14", Belt_List.zipBy(length_10_id, length_8_id, add), Belt_List.mapWithIndex(length_8_id, (i, x) => i + x | 0)); - Test_utils.eq("File \"belt_list_test.res\", line 131, characters 6-13", Belt_List.reverse(Belt_List.mapReverse2(length_10_id, length_10_id, add)), Belt_List.map(length_10_id, x => (x << 1))); + Test_utils.eq("File \"belt_list_test.res\", line 131, characters 6-13", Belt_List.reverse(Belt_List.mapReverse2(length_10_id, length_10_id, add)), Belt_List.map(length_10_id, x => x << 1)); let xs = Belt_List.reverse(Belt_List.mapReverse2(length_8_id, length_10_id, add)); Test_utils.eq("File \"belt_list_test.res\", line 136, characters 7-14", Belt_List.length(xs), 8); Test_utils.eq("File \"belt_list_test.res\", line 137, characters 7-14", xs, Belt_List.zipBy(length_10_id, length_8_id, add)); diff --git a/tests/tests/src/belt_sortarray_test.mjs b/tests/tests/src/belt_sortarray_test.mjs index 6c6ab7f7c4..aaeaa8598c 100644 --- a/tests/tests/src/belt_sortarray_test.mjs +++ b/tests/tests/src/belt_sortarray_test.mjs @@ -268,7 +268,7 @@ Mocha.describe("Belt_sortarray_test", () => { ], 4, cmp), 3); let aa = Array_data_util.range(0, 1000); Test_utils.ok("File \"belt_sortarray_test.res\", line 115, characters 7-14", Belt_Range.every(0, 1000, i => Belt_SortArray.binarySearchBy(aa, i, cmp) === i)); - let cc = Belt_Array.map(Array_data_util.range(0, 2000), x => (x << 1)); + let cc = Belt_Array.map(Array_data_util.range(0, 2000), x => x << 1); Test_utils.eq("File \"belt_sortarray_test.res\", line 118, characters 7-14", Pervasives.lnot(Belt_SortArray.binarySearchBy(cc, 5000, cmp)), 2001); Test_utils.eq("File \"belt_sortarray_test.res\", line 119, characters 7-14", Pervasives.lnot(Belt_SortArray.binarySearchBy(cc, -1, cmp)), 0); Test_utils.eq("File \"belt_sortarray_test.res\", line 120, characters 7-14", Belt_SortArray.binarySearchBy(cc, 0, cmp), 0); diff --git a/tests/tests/src/bigint_test.mjs b/tests/tests/src/bigint_test.mjs index 70f398040d..c4318f5a89 100644 --- a/tests/tests/src/bigint_test.mjs +++ b/tests/tests/src/bigint_test.mjs @@ -74,11 +74,11 @@ function bigint_lxor(prim0, prim1) { } function bigint_lsl(prim0, prim1) { - return (prim0 << prim1); + return prim0 << prim1; } function bigint_asr(prim0, prim1) { - return (prim0 >> prim1); + return prim0 >> prim1; } eq("File \"bigint_test.res\", line 26, characters 5-12", Primitive_bigint.compare(1n, 1n), 0); @@ -135,17 +135,17 @@ eq("File \"bigint_test.res\", line 159, characters 5-12", 9n | 1n, 9n); eq("File \"bigint_test.res\", line 160, characters 5-12", 9n ^ 1n, 8n); -eq("File \"bigint_test.res\", line 161, characters 5-12", (9n << 1n), 18n); +eq("File \"bigint_test.res\", line 161, characters 5-12", 9n << 1n, 18n); -eq("File \"bigint_test.res\", line 162, characters 5-12", (9n << -1n), 4n); +eq("File \"bigint_test.res\", line 162, characters 5-12", 9n << -1n, 4n); -eq("File \"bigint_test.res\", line 163, characters 5-12", (9n >> 1n), 4n); +eq("File \"bigint_test.res\", line 163, characters 5-12", 9n >> 1n, 4n); -eq("File \"bigint_test.res\", line 164, characters 5-12", (9n >> -1n), 18n); +eq("File \"bigint_test.res\", line 164, characters 5-12", 9n >> -1n, 18n); -eq("File \"bigint_test.res\", line 165, characters 5-12", (-9n >> 1n), -5n); +eq("File \"bigint_test.res\", line 165, characters 5-12", -9n >> 1n, -5n); -eq("File \"bigint_test.res\", line 166, characters 5-12", (-9n >> -1n), -18n); +eq("File \"bigint_test.res\", line 166, characters 5-12", -9n >> -1n, -18n); eq("File \"bigint_test.res\", line 167, characters 5-12", 9n > 1n ? 9n : 1n, 9n); diff --git a/tests/tests/src/bs_mutable_set_test.mjs b/tests/tests/src/bs_mutable_set_test.mjs index f5bc04852e..180130c841 100644 --- a/tests/tests/src/bs_mutable_set_test.mjs +++ b/tests/tests/src/bs_mutable_set_test.mjs @@ -447,7 +447,7 @@ for (let i$6 = 0; i$6 <= 200; ++i$6) { eq("File \"bs_mutable_set_test.res\", line 244, characters 5-12", Belt_MutableSetInt.size(copyV), 126); -eq("File \"bs_mutable_set_test.res\", line 245, characters 5-12", Belt_MutableSetInt.toArray(copyV), Belt_Array.makeBy(126, i => (i << 3))); +eq("File \"bs_mutable_set_test.res\", line 245, characters 5-12", Belt_MutableSetInt.toArray(copyV), Belt_Array.makeBy(126, i => i << 3)); eq("File \"bs_mutable_set_test.res\", line 246, characters 5-12", Belt_MutableSetInt.size(v$5), 800); @@ -465,13 +465,13 @@ b("File \"bs_mutable_set_test.res\", line 254, characters 4-11", Belt_MutableSet b("File \"bs_mutable_set_test.res\", line 255, characters 4-11", Belt_MutableSetInt.eq(match$7[1], Belt_MutableSetInt.fromArray(Array_data_util.randomRange(401, 1000)))); -let d = Belt_MutableSetInt.fromArray(Belt_Array.map(Array_data_util.randomRange(0, 1000), x => (x << 1))); +let d = Belt_MutableSetInt.fromArray(Belt_Array.map(Array_data_util.randomRange(0, 1000), x => x << 1)); let match$8 = Belt_MutableSetInt.split(d, 1001); let match$9 = match$8[0]; -b("File \"bs_mutable_set_test.res\", line 258, characters 4-11", Belt_MutableSetInt.eq(match$9[0], Belt_MutableSetInt.fromArray(Belt_Array.makeBy(501, x => (x << 1))))); +b("File \"bs_mutable_set_test.res\", line 258, characters 4-11", Belt_MutableSetInt.eq(match$9[0], Belt_MutableSetInt.fromArray(Belt_Array.makeBy(501, x => x << 1)))); b("File \"bs_mutable_set_test.res\", line 259, characters 4-11", Belt_MutableSetInt.eq(match$9[1], Belt_MutableSetInt.fromArray(Belt_Array.makeBy(500, x => 1002 + (x << 1) | 0)))); diff --git a/tests/tests/src/bs_poly_set_test.mjs b/tests/tests/src/bs_poly_set_test.mjs index 8812401be4..05ee0f2453 100644 --- a/tests/tests/src/bs_poly_set_test.mjs +++ b/tests/tests/src/bs_poly_set_test.mjs @@ -141,7 +141,7 @@ let u25 = Belt_Set.add(u22, 59); let u26 = Belt_Set.add(Belt_Set.make(IntCmp), 3); -let ss = Belt_Array.makeByAndShuffle(100, i => (i << 1)); +let ss = Belt_Array.makeByAndShuffle(100, i => i << 1); let u27 = Belt_Set.fromArray(ss, IntCmp); diff --git a/tests/tests/src/core/Core_TempTests.mjs b/tests/tests/src/core/Core_TempTests.mjs index 7b189a747f..17da4409ce 100644 --- a/tests/tests/src/core/Core_TempTests.mjs +++ b/tests/tests/src/core/Core_TempTests.mjs @@ -24,7 +24,7 @@ let array = [ 4 ]; -console.info(Stdlib_Array.reduce(array.map(x => (x << 1)), 0, (a, b) => a + b | 0)); +console.info(Stdlib_Array.reduce(array.map(x => x << 1), 0, (a, b) => a + b | 0)); console.info(typeof array); diff --git a/tests/tests/src/for_loop_test.mjs b/tests/tests/src/for_loop_test.mjs index d5e5c3602f..81bf46071e 100644 --- a/tests/tests/src/for_loop_test.mjs +++ b/tests/tests/src/for_loop_test.mjs @@ -9,7 +9,7 @@ function for_3(x) { }; let arr = Belt_Array.map(x, param => (() => {})); for (let i = 0, i_finish = x.length; i < i_finish; ++i) { - let j = (i << 1); + let j = i << 1; arr[i] = () => { v.contents = v.contents + j | 0; }; @@ -24,8 +24,8 @@ function for_4(x) { }; let arr = Belt_Array.map(x, param => (() => {})); for (let i = 0, i_finish = x.length; i < i_finish; ++i) { - let j = (i << 1); - let k = (j << 1); + let j = i << 1; + let k = j << 1; arr[i] = () => { v.contents = v.contents + k | 0; }; @@ -69,7 +69,7 @@ function for_6(x, u) { }; for (let i = 0, i_finish = x.length; i < i_finish; ++i) { let k = (u << 1) * u | 0; - let h = (v5.contents << 1); + let h = v5.contents << 1; v2.contents = v2.contents + 1 | 0; arr[i] = () => { v.contents = (((((v.contents + k | 0) + v2.contents | 0) + v4.contents | 0) + v5.contents | 0) + h | 0) + u | 0; @@ -108,7 +108,7 @@ function for_8() { }; let arr = Belt_Array.make(21, () => {}); for (let i = 0; i <= 6; ++i) { - let k = (i << 1); + let k = i << 1; for (let j = 0; j <= 2; ++j) { let h = i + j | 0; arr[(i * 3 | 0) + j | 0] = () => { diff --git a/tests/tests/src/gray_code_test.mjs b/tests/tests/src/gray_code_test.mjs index 209409e41f..93bd7e70f5 100644 --- a/tests/tests/src/gray_code_test.mjs +++ b/tests/tests/src/gray_code_test.mjs @@ -2,19 +2,19 @@ function gray_encode(b) { - return b ^ (b >>> 1); + return b ^ b >>> 1; } function gray_decode(n) { let _p = n; - let _n = (n >>> 1); + let _n = n >>> 1; while (true) { let n$1 = _n; let p = _p; if (n$1 === 0) { return p; } - _n = (n$1 >>> 1); + _n = n$1 >>> 1; _p = p ^ n$1; continue; }; @@ -22,11 +22,11 @@ function gray_decode(n) { function next_power(v) { let v$1 = v - 1 | 0; - let v$2 = (v$1 >>> 1) | v$1; - let v$3 = (v$2 >>> 2) | v$2; - let v$4 = (v$3 >>> 4) | v$3; - let v$5 = (v$4 >>> 8) | v$4; - let v$6 = (v$5 >>> 16) | v$5; + let v$2 = v$1 >>> 1 | v$1; + let v$3 = v$2 >>> 2 | v$2; + let v$4 = v$3 >>> 4 | v$3; + let v$5 = v$4 >>> 8 | v$4; + let v$6 = v$5 >>> 16 | v$5; return v$6 + 1 | 0; } diff --git a/tests/tests/src/js_array_test.mjs b/tests/tests/src/js_array_test.mjs index 9b14eaf969..15a6db301b 100644 --- a/tests/tests/src/js_array_test.mjs +++ b/tests/tests/src/js_array_test.mjs @@ -829,7 +829,7 @@ let suites_1 = { 2, 3, 4 - ].map(n => (n << 1)) + ].map(n => n << 1) }) ], tl: { @@ -848,7 +848,7 @@ let suites_1 = { 2, 3, 4 - ].map((param, i) => (i << 1)) + ].map((param, i) => i << 1) }) ], tl: { diff --git a/tests/tests/src/js_null_test.mjs b/tests/tests/src/js_null_test.mjs index 72e46d20a1..671b05ba7f 100644 --- a/tests/tests/src/js_null_test.mjs +++ b/tests/tests/src/js_null_test.mjs @@ -64,7 +64,7 @@ let suites_1 = { param => ({ TAG: "StrictEq", _0: 4, - _1: Js_null.bind(2, n => (n << 1)) + _1: Js_null.bind(2, n => n << 1) }) ], tl: { diff --git a/tests/tests/src/js_null_undefined_test.mjs b/tests/tests/src/js_null_undefined_test.mjs index a6970c1b5b..124561c819 100644 --- a/tests/tests/src/js_null_undefined_test.mjs +++ b/tests/tests/src/js_null_undefined_test.mjs @@ -118,7 +118,7 @@ let suites_1 = { param => ({ TAG: "Eq", _0: 4, - _1: Js_null_undefined.bind(2, n => (n << 1)) + _1: Js_null_undefined.bind(2, n => n << 1) }) ], tl: { diff --git a/tests/tests/src/js_undefined_test.mjs b/tests/tests/src/js_undefined_test.mjs index 37f280b9c5..ee8d37e893 100644 --- a/tests/tests/src/js_undefined_test.mjs +++ b/tests/tests/src/js_undefined_test.mjs @@ -64,7 +64,7 @@ let suites_1 = { param => ({ TAG: "Eq", _0: 4, - _1: Js_undefined.bind(2, n => (n << 1)) + _1: Js_undefined.bind(2, n => n << 1) }) ], tl: { diff --git a/tests/tests/src/mario_game.mjs b/tests/tests/src/mario_game.mjs index ab8da6cb66..793eebc389 100644 --- a/tests/tests/src/mario_game.mjs +++ b/tests/tests/src/mario_game.mjs @@ -2002,7 +2002,7 @@ function process_collision(dir, c1, c2, state) { let score = 100 * state.multiplier | 0; update_score(state, score); o2.score = score; - state.multiplier = (state.multiplier << 1); + state.multiplier = state.multiplier << 1; return [ undefined, evolve_enemy(o1.dir, typ, s2, o2, context) diff --git a/tests/tests/src/ocaml_compat/Ocaml_List.mjs b/tests/tests/src/ocaml_compat/Ocaml_List.mjs index 582cca5c84..da40aa33cb 100644 --- a/tests/tests/src/ocaml_compat/Ocaml_List.mjs +++ b/tests/tests/src/ocaml_compat/Ocaml_List.mjs @@ -860,7 +860,7 @@ function stable_sort(cmp, l) { } } - let n1 = (n >> 1); + let n1 = n >> 1; let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = rev_sort(n1, l); @@ -1006,7 +1006,7 @@ function stable_sort(cmp, l) { } } - let n1 = (n >> 1); + let n1 = n >> 1; let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = sort(n1, l); @@ -1234,7 +1234,7 @@ function sort_uniq(cmp, l) { } } - let n1 = (n >> 1); + let n1 = n >> 1; let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = rev_sort(n1, l); @@ -1465,7 +1465,7 @@ function sort_uniq(cmp, l) { } } - let n1 = (n >> 1); + let n1 = n >> 1; let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = sort(n1, l); diff --git a/tests/tests/src/record_name_test.mjs b/tests/tests/src/record_name_test.mjs index 80ec9615be..b386062293 100644 --- a/tests/tests/src/record_name_test.mjs +++ b/tests/tests/src/record_name_test.mjs @@ -9,7 +9,7 @@ function f(x) { function set(x) { x.THIS_IS_NOT_EXPRESSIBLE_IN_BUCKLE = 3; - return (x.THIS_IS_NOT_EXPRESSIBLE_IN_BUCKLE << 1); + return x.THIS_IS_NOT_EXPRESSIBLE_IN_BUCKLE << 1; } function f1(u) { @@ -31,7 +31,7 @@ function f3(x) { } function f4(param) { - return (((param.EXACT_MAPPING_TO_JS_LABEL + param.EXACT_2 | 0) + param.z.hello | 0) << 1); + return ((param.EXACT_MAPPING_TO_JS_LABEL + param.EXACT_2 | 0) + param.z.hello | 0) << 1; } function u() { diff --git a/tests/tests/src/test_for_loop.mjs b/tests/tests/src/test_for_loop.mjs index b82b3d3f73..7ddad05ad2 100644 --- a/tests/tests/src/test_for_loop.mjs +++ b/tests/tests/src/test_for_loop.mjs @@ -20,7 +20,7 @@ function for_3(x) { }; let arr = Belt_Array.map(x, param => (() => {})); for (let i = 0, i_finish = x.length; i <= i_finish; ++i) { - let j = (i << 1); + let j = i << 1; arr[i] = () => { v.contents = v.contents + j | 0; }; @@ -35,8 +35,8 @@ function for_4(x) { }; let arr = Belt_Array.map(x, param => (() => {})); for (let i = 0, i_finish = x.length; i <= i_finish; ++i) { - let j = (i << 1); - let k = (j << 1); + let j = i << 1; + let k = j << 1; arr[i] = () => { v.contents = v.contents + k | 0; }; @@ -79,7 +79,7 @@ function for_6(x, u) { }; for (let i = 0, i_finish = x.length; i <= i_finish; ++i) { let k = (u << 1) * u | 0; - let h = (v5.contents << 1); + let h = v5.contents << 1; v2.contents = v2.contents + 1 | 0; arr[i] = () => { v.contents = (((((v.contents + k | 0) + v2.contents | 0) + u | 0) + v4.contents | 0) + v5.contents | 0) + h | 0; diff --git a/tests/tests/src/test_list.mjs b/tests/tests/src/test_list.mjs index ef5979b0a7..46077a2ce1 100644 --- a/tests/tests/src/test_list.mjs +++ b/tests/tests/src/test_list.mjs @@ -754,7 +754,7 @@ function stable_sort(cmp, l) { } } - let n1 = (n >> 1); + let n1 = n >> 1; let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = rev_sort(n1, l); @@ -900,7 +900,7 @@ function stable_sort(cmp, l) { } } - let n1 = (n >> 1); + let n1 = n >> 1; let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = sort(n1, l); @@ -1128,7 +1128,7 @@ function sort_uniq(cmp, l) { } } - let n1 = (n >> 1); + let n1 = n >> 1; let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = rev_sort(n1, l); @@ -1359,7 +1359,7 @@ function sort_uniq(cmp, l) { } } - let n1 = (n >> 1); + let n1 = n >> 1; let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = sort(n1, l); diff --git a/tests/tests/src/test_tuple.mjs b/tests/tests/src/test_tuple.mjs index 975e54d9e4..4b66d82512 100644 --- a/tests/tests/src/test_tuple.mjs +++ b/tests/tests/src/test_tuple.mjs @@ -7,7 +7,7 @@ for (let k = 1; k <= 10; ++k) { for (let i = 1; i <= 10; ++i) { let match = i % 2 === 0 ? [ 1, - (i << 1) + i << 1 ] : [ 2, i * 3 | 0 diff --git a/tests/tests/src/unified_ops_test.mjs b/tests/tests/src/unified_ops_test.mjs index a849e5e12f..01854d6553 100644 --- a/tests/tests/src/unified_ops_test.mjs +++ b/tests/tests/src/unified_ops_test.mjs @@ -75,9 +75,9 @@ function bxor_bigint(a, b) { return a ^ b; } -let shl_bigint = (1n << 2n); +let shl_bigint = 1n << 2n; -let shr_bigint = (8n >> 2n); +let shr_bigint = 8n >> 2n; let int = 3; From e0345449d91e092694efb3233ea6595f902f993f Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Tue, 15 Apr 2025 02:32:22 +0900 Subject: [PATCH 14/16] Revert "unparen shift ops" This reverts commit 5d308e734c2f8b608564f66f120373073828fc7e. --- compiler/core/js_dump.ml | 16 ++++++++++++++-- lib/es6/Belt_HashMap.js | 4 ++-- lib/es6/Belt_HashMapInt.js | 4 ++-- lib/es6/Belt_HashMapString.js | 4 ++-- lib/es6/Belt_HashSet.js | 4 ++-- lib/es6/Belt_HashSetInt.js | 4 ++-- lib/es6/Belt_HashSetString.js | 4 ++-- lib/es6/Belt_internalBucketsType.js | 4 ++-- lib/es6/Primitive_hash.js | 20 ++++++++++---------- lib/js/Belt_HashMap.js | 4 ++-- lib/js/Belt_HashMapInt.js | 4 ++-- lib/js/Belt_HashMapString.js | 4 ++-- lib/js/Belt_HashSet.js | 4 ++-- lib/js/Belt_HashSetInt.js | 4 ++-- lib/js/Belt_HashSetString.js | 4 ++-- lib/js/Belt_internalBucketsType.js | 4 ++-- lib/js/Primitive_hash.js | 20 ++++++++++---------- tests/tests/src/alias_default_value_test.mjs | 2 +- tests/tests/src/belt_list_test.mjs | 8 ++++---- tests/tests/src/belt_sortarray_test.mjs | 2 +- tests/tests/src/bigint_test.mjs | 16 ++++++++-------- tests/tests/src/bs_mutable_set_test.mjs | 6 +++--- tests/tests/src/bs_poly_set_test.mjs | 2 +- tests/tests/src/core/Core_TempTests.mjs | 2 +- tests/tests/src/for_loop_test.mjs | 10 +++++----- tests/tests/src/gray_code_test.mjs | 16 ++++++++-------- tests/tests/src/js_array_test.mjs | 4 ++-- tests/tests/src/js_null_test.mjs | 2 +- tests/tests/src/js_null_undefined_test.mjs | 2 +- tests/tests/src/js_undefined_test.mjs | 2 +- tests/tests/src/mario_game.mjs | 2 +- tests/tests/src/ocaml_compat/Ocaml_List.mjs | 8 ++++---- tests/tests/src/record_name_test.mjs | 4 ++-- tests/tests/src/test_for_loop.mjs | 8 ++++---- tests/tests/src/test_list.mjs | 8 ++++---- tests/tests/src/test_tuple.mjs | 2 +- tests/tests/src/unified_ops_test.mjs | 4 ++-- 37 files changed, 117 insertions(+), 105 deletions(-) diff --git a/compiler/core/js_dump.ml b/compiler/core/js_dump.ml index e1acf79258..bc174e7dd5 100644 --- a/compiler/core/js_dump.ml +++ b/compiler/core/js_dump.ml @@ -717,7 +717,13 @@ and expression_desc cxt ~(level : int) f x : cxt = expression_desc cxt ~level:(level : int) f (Is_null_or_undefined e1) | Bin (op, e1, e2) -> let out, lft, rght = Js_op_util.op_prec op in - let need_paren = level > out in + let need_paren = + level > out + || + match op with + | Lsl | Lsr | Asr -> true + | _ -> false + in (* We are more conservative here, to make the generated code more readable to the user *) P.cond_paren_group f need_paren (fun _ -> @@ -729,7 +735,13 @@ and expression_desc cxt ~(level : int) f x : cxt = | String_append (e1, e2) -> let op : Js_op.binop = Plus in let out, lft, rght = Js_op_util.op_prec op in - let need_paren = level > out in + let need_paren = + level > out + || + match op with + | Lsl | Lsr | Asr -> true + | _ -> false + in P.cond_paren_group f need_paren (fun _ -> let cxt = expression ~level:lft cxt f e1 in P.space f; diff --git a/lib/es6/Belt_HashMap.js b/lib/es6/Belt_HashMap.js index c044625d68..1e481f3d5b 100644 --- a/lib/es6/Belt_HashMap.js +++ b/lib/es6/Belt_HashMap.js @@ -66,10 +66,10 @@ function set0(h, key, value, eq, hash) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashMapInt.js b/lib/es6/Belt_HashMapInt.js index 553fb6b419..eea270865b 100644 --- a/lib/es6/Belt_HashMapInt.js +++ b/lib/es6/Belt_HashMapInt.js @@ -63,10 +63,10 @@ function set(h, key, value) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashMapString.js b/lib/es6/Belt_HashMapString.js index bd5194964b..6f8a428544 100644 --- a/lib/es6/Belt_HashMapString.js +++ b/lib/es6/Belt_HashMapString.js @@ -63,10 +63,10 @@ function set(h, key, value) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashSet.js b/lib/es6/Belt_HashSet.js index 2ed9b6c306..8eb7900af2 100644 --- a/lib/es6/Belt_HashSet.js +++ b/lib/es6/Belt_HashSet.js @@ -93,10 +93,10 @@ function add0(h, key, hash, eq) { next: undefined }; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashSetInt.js b/lib/es6/Belt_HashSetInt.js index 4ba582eca1..7be6585ebd 100644 --- a/lib/es6/Belt_HashSetInt.js +++ b/lib/es6/Belt_HashSetInt.js @@ -93,10 +93,10 @@ function add(h, key) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/es6/Belt_HashSetString.js b/lib/es6/Belt_HashSetString.js index 3dc2d4c4cb..e0876a5a76 100644 --- a/lib/es6/Belt_HashSetString.js +++ b/lib/es6/Belt_HashSetString.js @@ -93,10 +93,10 @@ function add(h, key) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/es6/Belt_internalBucketsType.js b/lib/es6/Belt_internalBucketsType.js index f31e39950f..d2101f53bf 100644 --- a/lib/es6/Belt_internalBucketsType.js +++ b/lib/es6/Belt_internalBucketsType.js @@ -7,10 +7,10 @@ function power_2_above(_x, n) { if (x >= n) { return x; } - if (x << 1 < x) { + if ((x << 1) < x) { return x; } - _x = x << 1; + _x = (x << 1); continue; }; } diff --git a/lib/es6/Primitive_hash.js b/lib/es6/Primitive_hash.js index cb7a8fd4f3..5a6688256a 100644 --- a/lib/es6/Primitive_hash.js +++ b/lib/es6/Primitive_hash.js @@ -44,7 +44,7 @@ function unsafe_pop(q) { } function rotl32(x, n) { - return x << n | x >>> (32 - n | 0) | 0; + return (x << n) | (x >>> (32 - n | 0)) | 0; } function hash_mix_int(h, d) { @@ -58,11 +58,11 @@ function hash_mix_int(h, d) { } function hash_final_mix(h) { - let h$1 = h ^ h >>> 16; + let h$1 = h ^ (h >>> 16); h$1 = Math.imul(h$1, -2048144789); - h$1 = h$1 ^ h$1 >>> 13; + h$1 = h$1 ^ (h$1 >>> 13); h$1 = Math.imul(h$1, -1028477387); - return h$1 ^ h$1 >>> 16; + return h$1 ^ (h$1 >>> 16); } function hash_mix_string(h, s) { @@ -70,14 +70,14 @@ function hash_mix_string(h, s) { let block = (len / 4 | 0) - 1 | 0; let hash = h; for (let i = 0; i <= block; ++i) { - let j = i << 2; - let w = s.charCodeAt(j) | s.charCodeAt(j + 1 | 0) << 8 | s.charCodeAt(j + 2 | 0) << 16 | s.charCodeAt(j + 3 | 0) << 24; + let j = (i << 2); + let w = s.charCodeAt(j) | (s.charCodeAt(j + 1 | 0) << 8) | (s.charCodeAt(j + 2 | 0) << 16) | (s.charCodeAt(j + 3 | 0) << 24); hash = hash_mix_int(hash, w); } let modulo = len & 3; if (modulo !== 0) { - let w$1 = modulo === 3 ? s.charCodeAt(len - 1 | 0) << 16 | s.charCodeAt(len - 2 | 0) << 8 | s.charCodeAt(len - 3 | 0) : ( - modulo === 2 ? s.charCodeAt(len - 1 | 0) << 8 | s.charCodeAt(len - 2 | 0) : s.charCodeAt(len - 1 | 0) + let w$1 = modulo === 3 ? (s.charCodeAt(len - 1 | 0) << 16) | (s.charCodeAt(len - 2 | 0) << 8) | s.charCodeAt(len - 3 | 0) : ( + modulo === 2 ? (s.charCodeAt(len - 1 | 0) << 8) | s.charCodeAt(len - 2 | 0) : s.charCodeAt(len - 1 | 0) ); hash = hash_mix_int(hash, w$1); } @@ -117,7 +117,7 @@ function hash(count, _limit, seed, obj) { let size = obj$1.length | 0; if (size !== 0) { let obj_tag = obj$1.TAG; - let tag = size << 10 | obj_tag; + let tag = (size << 10) | obj_tag; s = hash_mix_int(s, tag); let v = size - 1 | 0; let block = v < num ? v : num; @@ -133,7 +133,7 @@ function hash(count, _limit, seed, obj) { } return size })(obj$1, v => push_back(queue, v)); - s = hash_mix_int(s, size$1 << 10 | 0); + s = hash_mix_int(s, (size$1 << 10) | 0); } } diff --git a/lib/js/Belt_HashMap.js b/lib/js/Belt_HashMap.js index 0e5c387976..6bd8b97a2d 100644 --- a/lib/js/Belt_HashMap.js +++ b/lib/js/Belt_HashMap.js @@ -66,10 +66,10 @@ function set0(h, key, value, eq, hash) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashMapInt.js b/lib/js/Belt_HashMapInt.js index a255e726cc..3aff60b364 100644 --- a/lib/js/Belt_HashMapInt.js +++ b/lib/js/Belt_HashMapInt.js @@ -63,10 +63,10 @@ function set(h, key, value) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashMapString.js b/lib/js/Belt_HashMapString.js index 0f1d4238bd..73e1847781 100644 --- a/lib/js/Belt_HashMapString.js +++ b/lib/js/Belt_HashMapString.js @@ -63,10 +63,10 @@ function set(h, key, value) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashSet.js b/lib/js/Belt_HashSet.js index 15e8a0f7ba..0897d41ebb 100644 --- a/lib/js/Belt_HashSet.js +++ b/lib/js/Belt_HashSet.js @@ -93,10 +93,10 @@ function add0(h, key, hash, eq) { next: undefined }; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashSetInt.js b/lib/js/Belt_HashSetInt.js index 110da44827..db0c833e84 100644 --- a/lib/js/Belt_HashSetInt.js +++ b/lib/js/Belt_HashSetInt.js @@ -93,10 +93,10 @@ function add(h, key) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/js/Belt_HashSetString.js b/lib/js/Belt_HashSetString.js index c3f61176ce..d2779cf4ff 100644 --- a/lib/js/Belt_HashSetString.js +++ b/lib/js/Belt_HashSetString.js @@ -93,10 +93,10 @@ function add(h, key) { }; h.size = h.size + 1 | 0; } - if (h.size > buckets_len << 1) { + if (h.size > (buckets_len << 1)) { let odata = h.buckets; let osize = odata.length; - let nsize = osize << 1; + let nsize = (osize << 1); if (nsize < osize) { return; } diff --git a/lib/js/Belt_internalBucketsType.js b/lib/js/Belt_internalBucketsType.js index 4718cb9c43..afd6d07891 100644 --- a/lib/js/Belt_internalBucketsType.js +++ b/lib/js/Belt_internalBucketsType.js @@ -7,10 +7,10 @@ function power_2_above(_x, n) { if (x >= n) { return x; } - if (x << 1 < x) { + if ((x << 1) < x) { return x; } - _x = x << 1; + _x = (x << 1); continue; }; } diff --git a/lib/js/Primitive_hash.js b/lib/js/Primitive_hash.js index ff04ba7d7f..e501682ae1 100644 --- a/lib/js/Primitive_hash.js +++ b/lib/js/Primitive_hash.js @@ -44,7 +44,7 @@ function unsafe_pop(q) { } function rotl32(x, n) { - return x << n | x >>> (32 - n | 0) | 0; + return (x << n) | (x >>> (32 - n | 0)) | 0; } function hash_mix_int(h, d) { @@ -58,11 +58,11 @@ function hash_mix_int(h, d) { } function hash_final_mix(h) { - let h$1 = h ^ h >>> 16; + let h$1 = h ^ (h >>> 16); h$1 = Math.imul(h$1, -2048144789); - h$1 = h$1 ^ h$1 >>> 13; + h$1 = h$1 ^ (h$1 >>> 13); h$1 = Math.imul(h$1, -1028477387); - return h$1 ^ h$1 >>> 16; + return h$1 ^ (h$1 >>> 16); } function hash_mix_string(h, s) { @@ -70,14 +70,14 @@ function hash_mix_string(h, s) { let block = (len / 4 | 0) - 1 | 0; let hash = h; for (let i = 0; i <= block; ++i) { - let j = i << 2; - let w = s.charCodeAt(j) | s.charCodeAt(j + 1 | 0) << 8 | s.charCodeAt(j + 2 | 0) << 16 | s.charCodeAt(j + 3 | 0) << 24; + let j = (i << 2); + let w = s.charCodeAt(j) | (s.charCodeAt(j + 1 | 0) << 8) | (s.charCodeAt(j + 2 | 0) << 16) | (s.charCodeAt(j + 3 | 0) << 24); hash = hash_mix_int(hash, w); } let modulo = len & 3; if (modulo !== 0) { - let w$1 = modulo === 3 ? s.charCodeAt(len - 1 | 0) << 16 | s.charCodeAt(len - 2 | 0) << 8 | s.charCodeAt(len - 3 | 0) : ( - modulo === 2 ? s.charCodeAt(len - 1 | 0) << 8 | s.charCodeAt(len - 2 | 0) : s.charCodeAt(len - 1 | 0) + let w$1 = modulo === 3 ? (s.charCodeAt(len - 1 | 0) << 16) | (s.charCodeAt(len - 2 | 0) << 8) | s.charCodeAt(len - 3 | 0) : ( + modulo === 2 ? (s.charCodeAt(len - 1 | 0) << 8) | s.charCodeAt(len - 2 | 0) : s.charCodeAt(len - 1 | 0) ); hash = hash_mix_int(hash, w$1); } @@ -117,7 +117,7 @@ function hash(count, _limit, seed, obj) { let size = obj$1.length | 0; if (size !== 0) { let obj_tag = obj$1.TAG; - let tag = size << 10 | obj_tag; + let tag = (size << 10) | obj_tag; s = hash_mix_int(s, tag); let v = size - 1 | 0; let block = v < num ? v : num; @@ -133,7 +133,7 @@ function hash(count, _limit, seed, obj) { } return size })(obj$1, v => push_back(queue, v)); - s = hash_mix_int(s, size$1 << 10 | 0); + s = hash_mix_int(s, (size$1 << 10) | 0); } } diff --git a/tests/tests/src/alias_default_value_test.mjs b/tests/tests/src/alias_default_value_test.mjs index 7e6938ecdb..f525661bb8 100644 --- a/tests/tests/src/alias_default_value_test.mjs +++ b/tests/tests/src/alias_default_value_test.mjs @@ -5,7 +5,7 @@ function Alias_default_value_test$C0(props) { let __b = props.b; let __a = props.a; let a = __a !== undefined ? __a : 2; - let b = __b !== undefined ? __b : a << 1; + let b = __b !== undefined ? __b : (a << 1); return a + b | 0; } diff --git a/tests/tests/src/belt_list_test.mjs b/tests/tests/src/belt_list_test.mjs index ff68e2fee2..a3c5c28f36 100644 --- a/tests/tests/src/belt_list_test.mjs +++ b/tests/tests/src/belt_list_test.mjs @@ -657,7 +657,7 @@ Mocha.describe("Belt_list_test", () => { }); let id = x => x; Mocha.test("map", () => { - Test_utils.eq("File \"belt_list_test.res\", line 109, characters 7-14", Belt_List.map(Belt_List.makeBy(5, id), x => x << 1), { + Test_utils.eq("File \"belt_list_test.res\", line 109, characters 7-14", Belt_List.map(Belt_List.makeBy(5, id), x => (x << 1)), { hd: 0, tl: { hd: 2, @@ -686,7 +686,7 @@ Mocha.describe("Belt_list_test", () => { let length_10_id = Belt_List.makeBy(10, id); let length_8_id = Belt_List.makeBy(8, id); Mocha.test("mapWithIndex etc.", () => { - let d = Belt_List.makeBy(10, x => x << 1); + let d = Belt_List.makeBy(10, x => (x << 1)); Test_utils.eq("File \"belt_list_test.res\", line 124, characters 7-14", Belt_List.zipBy(length_10_id, length_10_id, add), d); Test_utils.eq("File \"belt_list_test.res\", line 125, characters 7-14", Belt_List.zipBy(/* [] */0, { hd: 1, @@ -697,7 +697,7 @@ Mocha.describe("Belt_list_test", () => { tl: /* [] */0 }, /* [] */0, add), /* [] */0); Test_utils.eq("File \"belt_list_test.res\", line 127, characters 7-14", Belt_List.zipBy(/* [] */0, /* [] */0, add), /* [] */0); - Test_utils.eq("File \"belt_list_test.res\", line 128, characters 7-14", Belt_List.zipBy(length_10_id, length_10_id, add), Belt_List.concat(Belt_List.map(length_8_id, x => x << 1), { + Test_utils.eq("File \"belt_list_test.res\", line 128, characters 7-14", Belt_List.zipBy(length_10_id, length_10_id, add), Belt_List.concat(Belt_List.map(length_8_id, x => (x << 1)), { hd: 16, tl: { hd: 18, @@ -705,7 +705,7 @@ Mocha.describe("Belt_list_test", () => { } })); Test_utils.eq("File \"belt_list_test.res\", line 129, characters 7-14", Belt_List.zipBy(length_10_id, length_8_id, add), Belt_List.mapWithIndex(length_8_id, (i, x) => i + x | 0)); - Test_utils.eq("File \"belt_list_test.res\", line 131, characters 6-13", Belt_List.reverse(Belt_List.mapReverse2(length_10_id, length_10_id, add)), Belt_List.map(length_10_id, x => x << 1)); + Test_utils.eq("File \"belt_list_test.res\", line 131, characters 6-13", Belt_List.reverse(Belt_List.mapReverse2(length_10_id, length_10_id, add)), Belt_List.map(length_10_id, x => (x << 1))); let xs = Belt_List.reverse(Belt_List.mapReverse2(length_8_id, length_10_id, add)); Test_utils.eq("File \"belt_list_test.res\", line 136, characters 7-14", Belt_List.length(xs), 8); Test_utils.eq("File \"belt_list_test.res\", line 137, characters 7-14", xs, Belt_List.zipBy(length_10_id, length_8_id, add)); diff --git a/tests/tests/src/belt_sortarray_test.mjs b/tests/tests/src/belt_sortarray_test.mjs index aaeaa8598c..6c6ab7f7c4 100644 --- a/tests/tests/src/belt_sortarray_test.mjs +++ b/tests/tests/src/belt_sortarray_test.mjs @@ -268,7 +268,7 @@ Mocha.describe("Belt_sortarray_test", () => { ], 4, cmp), 3); let aa = Array_data_util.range(0, 1000); Test_utils.ok("File \"belt_sortarray_test.res\", line 115, characters 7-14", Belt_Range.every(0, 1000, i => Belt_SortArray.binarySearchBy(aa, i, cmp) === i)); - let cc = Belt_Array.map(Array_data_util.range(0, 2000), x => x << 1); + let cc = Belt_Array.map(Array_data_util.range(0, 2000), x => (x << 1)); Test_utils.eq("File \"belt_sortarray_test.res\", line 118, characters 7-14", Pervasives.lnot(Belt_SortArray.binarySearchBy(cc, 5000, cmp)), 2001); Test_utils.eq("File \"belt_sortarray_test.res\", line 119, characters 7-14", Pervasives.lnot(Belt_SortArray.binarySearchBy(cc, -1, cmp)), 0); Test_utils.eq("File \"belt_sortarray_test.res\", line 120, characters 7-14", Belt_SortArray.binarySearchBy(cc, 0, cmp), 0); diff --git a/tests/tests/src/bigint_test.mjs b/tests/tests/src/bigint_test.mjs index c4318f5a89..70f398040d 100644 --- a/tests/tests/src/bigint_test.mjs +++ b/tests/tests/src/bigint_test.mjs @@ -74,11 +74,11 @@ function bigint_lxor(prim0, prim1) { } function bigint_lsl(prim0, prim1) { - return prim0 << prim1; + return (prim0 << prim1); } function bigint_asr(prim0, prim1) { - return prim0 >> prim1; + return (prim0 >> prim1); } eq("File \"bigint_test.res\", line 26, characters 5-12", Primitive_bigint.compare(1n, 1n), 0); @@ -135,17 +135,17 @@ eq("File \"bigint_test.res\", line 159, characters 5-12", 9n | 1n, 9n); eq("File \"bigint_test.res\", line 160, characters 5-12", 9n ^ 1n, 8n); -eq("File \"bigint_test.res\", line 161, characters 5-12", 9n << 1n, 18n); +eq("File \"bigint_test.res\", line 161, characters 5-12", (9n << 1n), 18n); -eq("File \"bigint_test.res\", line 162, characters 5-12", 9n << -1n, 4n); +eq("File \"bigint_test.res\", line 162, characters 5-12", (9n << -1n), 4n); -eq("File \"bigint_test.res\", line 163, characters 5-12", 9n >> 1n, 4n); +eq("File \"bigint_test.res\", line 163, characters 5-12", (9n >> 1n), 4n); -eq("File \"bigint_test.res\", line 164, characters 5-12", 9n >> -1n, 18n); +eq("File \"bigint_test.res\", line 164, characters 5-12", (9n >> -1n), 18n); -eq("File \"bigint_test.res\", line 165, characters 5-12", -9n >> 1n, -5n); +eq("File \"bigint_test.res\", line 165, characters 5-12", (-9n >> 1n), -5n); -eq("File \"bigint_test.res\", line 166, characters 5-12", -9n >> -1n, -18n); +eq("File \"bigint_test.res\", line 166, characters 5-12", (-9n >> -1n), -18n); eq("File \"bigint_test.res\", line 167, characters 5-12", 9n > 1n ? 9n : 1n, 9n); diff --git a/tests/tests/src/bs_mutable_set_test.mjs b/tests/tests/src/bs_mutable_set_test.mjs index 180130c841..f5bc04852e 100644 --- a/tests/tests/src/bs_mutable_set_test.mjs +++ b/tests/tests/src/bs_mutable_set_test.mjs @@ -447,7 +447,7 @@ for (let i$6 = 0; i$6 <= 200; ++i$6) { eq("File \"bs_mutable_set_test.res\", line 244, characters 5-12", Belt_MutableSetInt.size(copyV), 126); -eq("File \"bs_mutable_set_test.res\", line 245, characters 5-12", Belt_MutableSetInt.toArray(copyV), Belt_Array.makeBy(126, i => i << 3)); +eq("File \"bs_mutable_set_test.res\", line 245, characters 5-12", Belt_MutableSetInt.toArray(copyV), Belt_Array.makeBy(126, i => (i << 3))); eq("File \"bs_mutable_set_test.res\", line 246, characters 5-12", Belt_MutableSetInt.size(v$5), 800); @@ -465,13 +465,13 @@ b("File \"bs_mutable_set_test.res\", line 254, characters 4-11", Belt_MutableSet b("File \"bs_mutable_set_test.res\", line 255, characters 4-11", Belt_MutableSetInt.eq(match$7[1], Belt_MutableSetInt.fromArray(Array_data_util.randomRange(401, 1000)))); -let d = Belt_MutableSetInt.fromArray(Belt_Array.map(Array_data_util.randomRange(0, 1000), x => x << 1)); +let d = Belt_MutableSetInt.fromArray(Belt_Array.map(Array_data_util.randomRange(0, 1000), x => (x << 1))); let match$8 = Belt_MutableSetInt.split(d, 1001); let match$9 = match$8[0]; -b("File \"bs_mutable_set_test.res\", line 258, characters 4-11", Belt_MutableSetInt.eq(match$9[0], Belt_MutableSetInt.fromArray(Belt_Array.makeBy(501, x => x << 1)))); +b("File \"bs_mutable_set_test.res\", line 258, characters 4-11", Belt_MutableSetInt.eq(match$9[0], Belt_MutableSetInt.fromArray(Belt_Array.makeBy(501, x => (x << 1))))); b("File \"bs_mutable_set_test.res\", line 259, characters 4-11", Belt_MutableSetInt.eq(match$9[1], Belt_MutableSetInt.fromArray(Belt_Array.makeBy(500, x => 1002 + (x << 1) | 0)))); diff --git a/tests/tests/src/bs_poly_set_test.mjs b/tests/tests/src/bs_poly_set_test.mjs index 05ee0f2453..8812401be4 100644 --- a/tests/tests/src/bs_poly_set_test.mjs +++ b/tests/tests/src/bs_poly_set_test.mjs @@ -141,7 +141,7 @@ let u25 = Belt_Set.add(u22, 59); let u26 = Belt_Set.add(Belt_Set.make(IntCmp), 3); -let ss = Belt_Array.makeByAndShuffle(100, i => i << 1); +let ss = Belt_Array.makeByAndShuffle(100, i => (i << 1)); let u27 = Belt_Set.fromArray(ss, IntCmp); diff --git a/tests/tests/src/core/Core_TempTests.mjs b/tests/tests/src/core/Core_TempTests.mjs index 17da4409ce..7b189a747f 100644 --- a/tests/tests/src/core/Core_TempTests.mjs +++ b/tests/tests/src/core/Core_TempTests.mjs @@ -24,7 +24,7 @@ let array = [ 4 ]; -console.info(Stdlib_Array.reduce(array.map(x => x << 1), 0, (a, b) => a + b | 0)); +console.info(Stdlib_Array.reduce(array.map(x => (x << 1)), 0, (a, b) => a + b | 0)); console.info(typeof array); diff --git a/tests/tests/src/for_loop_test.mjs b/tests/tests/src/for_loop_test.mjs index 81bf46071e..d5e5c3602f 100644 --- a/tests/tests/src/for_loop_test.mjs +++ b/tests/tests/src/for_loop_test.mjs @@ -9,7 +9,7 @@ function for_3(x) { }; let arr = Belt_Array.map(x, param => (() => {})); for (let i = 0, i_finish = x.length; i < i_finish; ++i) { - let j = i << 1; + let j = (i << 1); arr[i] = () => { v.contents = v.contents + j | 0; }; @@ -24,8 +24,8 @@ function for_4(x) { }; let arr = Belt_Array.map(x, param => (() => {})); for (let i = 0, i_finish = x.length; i < i_finish; ++i) { - let j = i << 1; - let k = j << 1; + let j = (i << 1); + let k = (j << 1); arr[i] = () => { v.contents = v.contents + k | 0; }; @@ -69,7 +69,7 @@ function for_6(x, u) { }; for (let i = 0, i_finish = x.length; i < i_finish; ++i) { let k = (u << 1) * u | 0; - let h = v5.contents << 1; + let h = (v5.contents << 1); v2.contents = v2.contents + 1 | 0; arr[i] = () => { v.contents = (((((v.contents + k | 0) + v2.contents | 0) + v4.contents | 0) + v5.contents | 0) + h | 0) + u | 0; @@ -108,7 +108,7 @@ function for_8() { }; let arr = Belt_Array.make(21, () => {}); for (let i = 0; i <= 6; ++i) { - let k = i << 1; + let k = (i << 1); for (let j = 0; j <= 2; ++j) { let h = i + j | 0; arr[(i * 3 | 0) + j | 0] = () => { diff --git a/tests/tests/src/gray_code_test.mjs b/tests/tests/src/gray_code_test.mjs index 93bd7e70f5..209409e41f 100644 --- a/tests/tests/src/gray_code_test.mjs +++ b/tests/tests/src/gray_code_test.mjs @@ -2,19 +2,19 @@ function gray_encode(b) { - return b ^ b >>> 1; + return b ^ (b >>> 1); } function gray_decode(n) { let _p = n; - let _n = n >>> 1; + let _n = (n >>> 1); while (true) { let n$1 = _n; let p = _p; if (n$1 === 0) { return p; } - _n = n$1 >>> 1; + _n = (n$1 >>> 1); _p = p ^ n$1; continue; }; @@ -22,11 +22,11 @@ function gray_decode(n) { function next_power(v) { let v$1 = v - 1 | 0; - let v$2 = v$1 >>> 1 | v$1; - let v$3 = v$2 >>> 2 | v$2; - let v$4 = v$3 >>> 4 | v$3; - let v$5 = v$4 >>> 8 | v$4; - let v$6 = v$5 >>> 16 | v$5; + let v$2 = (v$1 >>> 1) | v$1; + let v$3 = (v$2 >>> 2) | v$2; + let v$4 = (v$3 >>> 4) | v$3; + let v$5 = (v$4 >>> 8) | v$4; + let v$6 = (v$5 >>> 16) | v$5; return v$6 + 1 | 0; } diff --git a/tests/tests/src/js_array_test.mjs b/tests/tests/src/js_array_test.mjs index 15a6db301b..9b14eaf969 100644 --- a/tests/tests/src/js_array_test.mjs +++ b/tests/tests/src/js_array_test.mjs @@ -829,7 +829,7 @@ let suites_1 = { 2, 3, 4 - ].map(n => n << 1) + ].map(n => (n << 1)) }) ], tl: { @@ -848,7 +848,7 @@ let suites_1 = { 2, 3, 4 - ].map((param, i) => i << 1) + ].map((param, i) => (i << 1)) }) ], tl: { diff --git a/tests/tests/src/js_null_test.mjs b/tests/tests/src/js_null_test.mjs index 671b05ba7f..72e46d20a1 100644 --- a/tests/tests/src/js_null_test.mjs +++ b/tests/tests/src/js_null_test.mjs @@ -64,7 +64,7 @@ let suites_1 = { param => ({ TAG: "StrictEq", _0: 4, - _1: Js_null.bind(2, n => n << 1) + _1: Js_null.bind(2, n => (n << 1)) }) ], tl: { diff --git a/tests/tests/src/js_null_undefined_test.mjs b/tests/tests/src/js_null_undefined_test.mjs index 124561c819..a6970c1b5b 100644 --- a/tests/tests/src/js_null_undefined_test.mjs +++ b/tests/tests/src/js_null_undefined_test.mjs @@ -118,7 +118,7 @@ let suites_1 = { param => ({ TAG: "Eq", _0: 4, - _1: Js_null_undefined.bind(2, n => n << 1) + _1: Js_null_undefined.bind(2, n => (n << 1)) }) ], tl: { diff --git a/tests/tests/src/js_undefined_test.mjs b/tests/tests/src/js_undefined_test.mjs index ee8d37e893..37f280b9c5 100644 --- a/tests/tests/src/js_undefined_test.mjs +++ b/tests/tests/src/js_undefined_test.mjs @@ -64,7 +64,7 @@ let suites_1 = { param => ({ TAG: "Eq", _0: 4, - _1: Js_undefined.bind(2, n => n << 1) + _1: Js_undefined.bind(2, n => (n << 1)) }) ], tl: { diff --git a/tests/tests/src/mario_game.mjs b/tests/tests/src/mario_game.mjs index 793eebc389..ab8da6cb66 100644 --- a/tests/tests/src/mario_game.mjs +++ b/tests/tests/src/mario_game.mjs @@ -2002,7 +2002,7 @@ function process_collision(dir, c1, c2, state) { let score = 100 * state.multiplier | 0; update_score(state, score); o2.score = score; - state.multiplier = state.multiplier << 1; + state.multiplier = (state.multiplier << 1); return [ undefined, evolve_enemy(o1.dir, typ, s2, o2, context) diff --git a/tests/tests/src/ocaml_compat/Ocaml_List.mjs b/tests/tests/src/ocaml_compat/Ocaml_List.mjs index da40aa33cb..582cca5c84 100644 --- a/tests/tests/src/ocaml_compat/Ocaml_List.mjs +++ b/tests/tests/src/ocaml_compat/Ocaml_List.mjs @@ -860,7 +860,7 @@ function stable_sort(cmp, l) { } } - let n1 = n >> 1; + let n1 = (n >> 1); let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = rev_sort(n1, l); @@ -1006,7 +1006,7 @@ function stable_sort(cmp, l) { } } - let n1 = n >> 1; + let n1 = (n >> 1); let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = sort(n1, l); @@ -1234,7 +1234,7 @@ function sort_uniq(cmp, l) { } } - let n1 = n >> 1; + let n1 = (n >> 1); let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = rev_sort(n1, l); @@ -1465,7 +1465,7 @@ function sort_uniq(cmp, l) { } } - let n1 = n >> 1; + let n1 = (n >> 1); let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = sort(n1, l); diff --git a/tests/tests/src/record_name_test.mjs b/tests/tests/src/record_name_test.mjs index b386062293..80ec9615be 100644 --- a/tests/tests/src/record_name_test.mjs +++ b/tests/tests/src/record_name_test.mjs @@ -9,7 +9,7 @@ function f(x) { function set(x) { x.THIS_IS_NOT_EXPRESSIBLE_IN_BUCKLE = 3; - return x.THIS_IS_NOT_EXPRESSIBLE_IN_BUCKLE << 1; + return (x.THIS_IS_NOT_EXPRESSIBLE_IN_BUCKLE << 1); } function f1(u) { @@ -31,7 +31,7 @@ function f3(x) { } function f4(param) { - return ((param.EXACT_MAPPING_TO_JS_LABEL + param.EXACT_2 | 0) + param.z.hello | 0) << 1; + return (((param.EXACT_MAPPING_TO_JS_LABEL + param.EXACT_2 | 0) + param.z.hello | 0) << 1); } function u() { diff --git a/tests/tests/src/test_for_loop.mjs b/tests/tests/src/test_for_loop.mjs index 7ddad05ad2..b82b3d3f73 100644 --- a/tests/tests/src/test_for_loop.mjs +++ b/tests/tests/src/test_for_loop.mjs @@ -20,7 +20,7 @@ function for_3(x) { }; let arr = Belt_Array.map(x, param => (() => {})); for (let i = 0, i_finish = x.length; i <= i_finish; ++i) { - let j = i << 1; + let j = (i << 1); arr[i] = () => { v.contents = v.contents + j | 0; }; @@ -35,8 +35,8 @@ function for_4(x) { }; let arr = Belt_Array.map(x, param => (() => {})); for (let i = 0, i_finish = x.length; i <= i_finish; ++i) { - let j = i << 1; - let k = j << 1; + let j = (i << 1); + let k = (j << 1); arr[i] = () => { v.contents = v.contents + k | 0; }; @@ -79,7 +79,7 @@ function for_6(x, u) { }; for (let i = 0, i_finish = x.length; i <= i_finish; ++i) { let k = (u << 1) * u | 0; - let h = v5.contents << 1; + let h = (v5.contents << 1); v2.contents = v2.contents + 1 | 0; arr[i] = () => { v.contents = (((((v.contents + k | 0) + v2.contents | 0) + u | 0) + v4.contents | 0) + v5.contents | 0) + h | 0; diff --git a/tests/tests/src/test_list.mjs b/tests/tests/src/test_list.mjs index 46077a2ce1..ef5979b0a7 100644 --- a/tests/tests/src/test_list.mjs +++ b/tests/tests/src/test_list.mjs @@ -754,7 +754,7 @@ function stable_sort(cmp, l) { } } - let n1 = n >> 1; + let n1 = (n >> 1); let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = rev_sort(n1, l); @@ -900,7 +900,7 @@ function stable_sort(cmp, l) { } } - let n1 = n >> 1; + let n1 = (n >> 1); let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = sort(n1, l); @@ -1128,7 +1128,7 @@ function sort_uniq(cmp, l) { } } - let n1 = n >> 1; + let n1 = (n >> 1); let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = rev_sort(n1, l); @@ -1359,7 +1359,7 @@ function sort_uniq(cmp, l) { } } - let n1 = n >> 1; + let n1 = (n >> 1); let n2 = n - n1 | 0; let l2 = chop(n1, l); let s1 = sort(n1, l); diff --git a/tests/tests/src/test_tuple.mjs b/tests/tests/src/test_tuple.mjs index 4b66d82512..975e54d9e4 100644 --- a/tests/tests/src/test_tuple.mjs +++ b/tests/tests/src/test_tuple.mjs @@ -7,7 +7,7 @@ for (let k = 1; k <= 10; ++k) { for (let i = 1; i <= 10; ++i) { let match = i % 2 === 0 ? [ 1, - i << 1 + (i << 1) ] : [ 2, i * 3 | 0 diff --git a/tests/tests/src/unified_ops_test.mjs b/tests/tests/src/unified_ops_test.mjs index 01854d6553..a849e5e12f 100644 --- a/tests/tests/src/unified_ops_test.mjs +++ b/tests/tests/src/unified_ops_test.mjs @@ -75,9 +75,9 @@ function bxor_bigint(a, b) { return a ^ b; } -let shl_bigint = 1n << 2n; +let shl_bigint = (1n << 2n); -let shr_bigint = 8n >> 2n; +let shr_bigint = (8n >> 2n); let int = 3; From dcd890f864d2db59c618970361b0139c00ebbf7b Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Wed, 16 Apr 2025 20:35:58 +0900 Subject: [PATCH 15/16] add changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59e40a7a2c..8fa8129e2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ # 12.0.0-alpha.13 (Unreleased) +#### :rocket: New Feature + +- Add shift (`<<`, `>>`, `>>>`) operators for `int` and `bigint`. https://github.com/rescript-lang/rescript/pull/7183 + # 12.0.0-alpha.12 #### :bug: Bug fix From 7d5ab21082b5b0cb57e85e78ecb5e4a99e1398a8 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Wed, 16 Apr 2025 20:44:50 +0900 Subject: [PATCH 16/16] fix --- compiler/syntax/src/res_parsetree_viewer.ml | 2 +- tests/tests/src/unified_ops_test.mjs | 20 ++++++++++---------- tests/tests/src/unified_ops_test.res | 14 +++++--------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/compiler/syntax/src/res_parsetree_viewer.ml b/compiler/syntax/src/res_parsetree_viewer.ml index 9f1682d495..b2d6444e59 100644 --- a/compiler/syntax/src/res_parsetree_viewer.ml +++ b/compiler/syntax/src/res_parsetree_viewer.ml @@ -301,7 +301,7 @@ let is_binary_operator operator = match operator with | ":=" | "||" | "&&" | "==" | "===" | "<" | ">" | "!=" | "!==" | "<=" | ">=" | "|>" | "+" | "+." | "-" | "-." | "++" | "*" | "*." | "/" | "/." | "**" - | "->" | "<>" | "%" | "^" | "<<" -> + | "->" | "<>" | "%" | "^" | "<<" | ">>" | ">>>" -> true | _ -> false diff --git a/tests/tests/src/unified_ops_test.mjs b/tests/tests/src/unified_ops_test.mjs index a849e5e12f..5cae89378f 100644 --- a/tests/tests/src/unified_ops_test.mjs +++ b/tests/tests/src/unified_ops_test.mjs @@ -75,17 +75,17 @@ function bxor_bigint(a, b) { return a ^ b; } -let shl_bigint = (1n << 2n); +let bigintShiftLeft = (1n << 2n); -let shr_bigint = (8n >> 2n); +let bigintShiftRight = (8n >> 2n); let int = 3; -let shl_int = 4; +let intShiftLeft = 4; -let shr_int = 2; +let intShiftRight = 2; -let lsr_int = 2147483647; +let intShiftRightUnsigned = 2147483647; export { int, @@ -111,10 +111,10 @@ export { pow_overflow, bxor_int, bxor_bigint, - shl_int, - shr_int, - lsr_int, - shl_bigint, - shr_bigint, + intShiftLeft, + intShiftRight, + intShiftRightUnsigned, + bigintShiftLeft, + bigintShiftRight, } /* No side effect */ diff --git a/tests/tests/src/unified_ops_test.res b/tests/tests/src/unified_ops_test.res index e26c8def82..6d814f0a23 100644 --- a/tests/tests/src/unified_ops_test.res +++ b/tests/tests/src/unified_ops_test.res @@ -30,13 +30,9 @@ let pow_overflow = 2147483647 ** 2 let bxor_int = (a, b) => a ^ b let bxor_bigint = (a: bigint, b) => a ^ b -let shl_int = 1 << 2 -let shr_int = 8 >> 2 -let lsr_int = -1 >>> 1 +let intShiftLeft = 1 << 2 +let intShiftRight = 8 >> 2 +let intShiftRightUnsigned = -2 >>> 1 -let lhs_shift = (a: int, b) => a << b -let rhs_shift = (a, b: int) => a << b -let unknown_shift = (a, b) => a << b - -let shl_bigint = 1n << 2n -let shr_bigint = 8n >> 2n +let bigintShiftLeft = 1n << 2n +let bigintShiftRight = 8n >> 2n