Skip to content

Commit 220b3d0

Browse files
gwansikkcometkim
andauthored
Add shift operators (<<, >>, >>>) (#7183)
Resolved #7171 --------- Co-authored-by: Hyeseong Kim <[email protected]>
1 parent 99c173d commit 220b3d0

File tree

15 files changed

+119
-15
lines changed

15 files changed

+119
-15
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
1313
# 12.0.0-alpha.13 (Unreleased)
1414

15+
#### :rocket: New Feature
16+
17+
- Add shift (`<<`, `>>`, `>>>`) operators for `int` and `bigint`. https://github.com/rescript-lang/rescript/pull/7183
18+
1519
# 12.0.0-alpha.12
1620

1721
#### :bug: Bug fix

compiler/ml/unified_ops.ml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,39 @@ let entries =
148148
string = None;
149149
};
150150
};
151+
{
152+
path = builtin "<<";
153+
name = "%lsl";
154+
form = Binary;
155+
specialization =
156+
{
157+
int = Plslint;
158+
bool = None;
159+
float = None;
160+
bigint = Some Plslbigint;
161+
string = None;
162+
};
163+
};
164+
{
165+
path = builtin ">>";
166+
name = "%asr";
167+
form = Binary;
168+
specialization =
169+
{
170+
int = Pasrint;
171+
bool = None;
172+
float = None;
173+
bigint = Some Pasrbigint;
174+
string = None;
175+
};
176+
};
177+
{
178+
path = builtin ">>>";
179+
name = "%lsr";
180+
form = Binary;
181+
specialization =
182+
{int = Plsrint; bool = None; float = None; bigint = None; string = None};
183+
};
151184
{
152185
path = builtin "mod";
153186
name = "%mod";

compiler/syntax/src/res_parsetree_viewer.ml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,11 @@ let operator_precedence operator =
274274
| "&&" -> 3
275275
| "^" -> 4
276276
| "==" | "===" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 5
277-
| "+" | "+." | "-" | "-." | "++" -> 6
278-
| "*" | "*." | "/" | "/." | "%" -> 7
279-
| "**" -> 8
280-
| "#" | "##" | "->" -> 9
277+
| "<<" | ">>" | ">>>" -> 6
278+
| "+" | "+." | "-" | "-." | "++" -> 7
279+
| "*" | "*." | "/" | "/." | "%" -> 8
280+
| "**" -> 9
281+
| "#" | "##" | "->" -> 10
281282
| _ -> 0
282283

283284
let is_unary_operator operator =
@@ -300,7 +301,7 @@ let is_binary_operator operator =
300301
match operator with
301302
| ":=" | "||" | "&&" | "==" | "===" | "<" | ">" | "!=" | "!==" | "<=" | ">="
302303
| "|>" | "+" | "+." | "-" | "-." | "++" | "*" | "*." | "/" | "/." | "**"
303-
| "->" | "<>" | "%" | "^" ->
304+
| "->" | "<>" | "%" | "^" | "<<" | ">>" | ">>>" ->
304305
true
305306
| _ -> false
306307

compiler/syntax/src/res_scanner.ml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -886,16 +886,30 @@ let rec scan scanner =
886886
| _ ->
887887
next scanner;
888888
Token.Plus)
889-
| '>' -> (
889+
| '>' when not (in_diamond_mode scanner) -> (
890890
match peek scanner with
891-
| '=' when not (in_diamond_mode scanner) ->
891+
| '=' ->
892892
next2 scanner;
893893
Token.GreaterEqual
894+
| '>' -> (
895+
match peek2 scanner with
896+
| '>' ->
897+
next3 scanner;
898+
Token.RightShiftUnsigned
899+
| _ ->
900+
next2 scanner;
901+
Token.RightShift)
894902
| _ ->
895903
next scanner;
896904
Token.GreaterThan)
905+
| '>' ->
906+
next scanner;
907+
Token.GreaterThan
897908
| '<' when not (in_jsx_mode scanner) -> (
898909
match peek scanner with
910+
| '<' when not (in_diamond_mode scanner) ->
911+
next2 scanner;
912+
Token.LeftShift
899913
| '=' ->
900914
next2 scanner;
901915
Token.LessEqual

compiler/syntax/src/res_token.ml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ type t =
9898
| Try
9999
| DocComment of Location.t * string
100100
| ModuleComment of Location.t * string
101+
| LeftShift
102+
| RightShift
103+
| RightShiftUnsigned
101104

102105
let precedence = function
103106
| HashEqual | ColonEqual -> 1
@@ -107,11 +110,12 @@ let precedence = function
107110
| Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual
108111
| BangEqualEqual | LessEqual | GreaterEqual | BarGreater ->
109112
5
110-
| Plus | PlusDot | Minus | MinusDot | PlusPlus -> 6
111-
| Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 7
112-
| Exponentiation -> 8
113-
| MinusGreater -> 9
114-
| Dot -> 10
113+
| LeftShift | RightShift | RightShiftUnsigned -> 6
114+
| Plus | PlusDot | Minus | MinusDot | PlusPlus -> 7
115+
| Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 8
116+
| Exponentiation -> 9
117+
| MinusGreater -> 10
118+
| Dot -> 11
115119
| _ -> 0
116120

117121
let to_string = function
@@ -212,6 +216,9 @@ let to_string = function
212216
| Try -> "try"
213217
| DocComment (_loc, s) -> "DocComment " ^ s
214218
| ModuleComment (_loc, s) -> "ModuleComment " ^ s
219+
| LeftShift -> "<<"
220+
| RightShift -> ">>"
221+
| RightShiftUnsigned -> ">>>"
215222

216223
let keyword_table = function
217224
| "and" -> And

runtime/Pervasives.res

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,12 @@ external \"-": ('a, 'a) => 'a = "%sub"
6565
external \"*": ('a, 'a) => 'a = "%mul"
6666
external \"/": ('a, 'a) => 'a = "%div"
6767
external \"%": ('a, 'a) => 'a = "%mod"
68+
external \"<<": ('a, 'a) => 'a = "%lsl"
6869
external mod: ('a, 'a) => 'a = "%mod"
6970
external \"**": ('a, 'a) => 'a = "%pow"
7071
external \"^": ('a, 'a) => 'a = "%bitxor"
72+
external \">>": ('a, 'a) => 'a = "%asr"
73+
external \">>>": ('a, 'a) => 'a = "%lsr"
7174

7275
/* Comparisons */
7376
/* Note: Later comparisons will be converted to unified operations too */

tests/syntax_tests/data/parsing/errors/typexpr/expected/typeConstructorArgs.res.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,20 @@
3838

3939

4040
Syntax error!
41-
syntax_tests/data/parsing/errors/typexpr/typeConstructorArgs.res:9:28
41+
syntax_tests/data/parsing/errors/typexpr/typeConstructorArgs.res:8:16-17
4242

43+
6 │ type t<'a> = private Belt.Map.t('a)
4344
7 │
4445
8 │ type t = option<<node<int>>
4546
9 │ type t = option(<node<int>>)
4647
10 │
4748

48-
I'm not sure what to parse here when looking at ")".
49+
I'm not sure what to parse here when looking at "<<".
4950

5051
type nonrec 'a node = {
5152
_value: 'a Js.Nullable.value }
5253
type nonrec 'a t = 'a Belt.Map.t
5354
type nonrec 'a t = private 'a Belt.Map.t
54-
type nonrec t = int node option
55+
type nonrec t = option
56+
;;node < (int >> ([%rescript.exprhole ]))
5557
type nonrec t = int node option

tests/syntax_tests/data/parsing/grammar/expressions/binary.res

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ let x = a + -1 + -2
2929
let x = a + @attr -1 + @attr -2
3030
let x = a % a == 0
3131
let x = a ^ a == 0
32+
let x = a << a == 0
33+
let x = a >> a == 0
34+
let x = a >>> a == 0
3235

3336
// should be interpreted as binary expression not prefix op
3437
let x = a -b

tests/syntax_tests/data/parsing/grammar/expressions/expected/binary.res.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ let x = (a + (-1)) + (-2)
1515
let x = (a + (((-1))[@attr ])) + (((-2))[@attr ])
1616
let x = (a % a) == 0
1717
let x = a ^ (a == 0)
18+
let x = (a << a) == 0
19+
let x = (a >> a) == 0
20+
let x = (a >>> a) == 0
1821
let x = a - b
1922
let x = a -. b
2023
;;Constructor (a, b)

tests/syntax_tests/data/printer/expr/binary.res

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ x + y / z
5555
x / y + z
5656
x % y * z
5757
x ^ y + z
58+
x << y + z
59+
x >> y + z
60+
x >>> y + z
5861
100 * x / total
5962
2 / 3 * 10 / 2 + 2
6063
let rotateX = ((range / rect.height) * refY - range / 2) * getXMultiplication(rect.width)

0 commit comments

Comments
 (0)