Skip to content

Commit 6a5a015

Browse files
MiryangJungcometkim
andcommitted
add bitxor
Co-authored-by: Hyeseong Kim <[email protected]>
1 parent 95782dd commit 6a5a015

File tree

17 files changed

+56
-45
lines changed

17 files changed

+56
-45
lines changed

compiler/ml/unified_ops.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,11 @@ let entries =
172172
float = Some Ppowfloat;
173173
bigint = Some Ppowbigint;
174174
string = None;
175-
}
175+
};
176176
};
177177
{
178178
path = builtin "^";
179-
name = "%xor";
179+
name = "%bitxor";
180180
form = Binary;
181181
specialization =
182182
{

compiler/syntax/src/res_diagnostics.ml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,8 @@ let explain t =
6565
| UnclosedTemplate ->
6666
"Did you forget to close this template expression with a backtick?"
6767
| UnclosedComment -> "This comment seems to be missing a closing `*/`"
68-
| UnknownUchar uchar -> (
69-
match uchar with
70-
| '^' ->
71-
"Not sure what to do with this character.\n"
72-
^ " If you're trying to dereference a mutable value, use \
73-
`myValue.contents` instead.\n"
74-
^ " To concatenate strings, use `\"a\" ++ \"b\"` instead."
75-
| _ -> "Not sure what to do with this character.")
68+
| UnknownUchar uchar ->
69+
"Not sure what to do with this character \"" ^ Char.escaped uchar ^ "\""
7670
| Expected {context; token = t} ->
7771
let hint =
7872
match context with

compiler/syntax/src/res_parens.ml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ let rhs_binary_expr_operand parent_operator rhs =
162162
};
163163
args = [(_, _left); (_, _right)];
164164
}
165-
when ParsetreeViewer.is_binary_operator operator
166-
&& not (operator_loc.loc_ghost && operator = "++") ->
165+
when ParsetreeViewer.not_ghost_operator operator operator_loc ->
167166
let prec_parent = ParsetreeViewer.operator_precedence parent_operator in
168167
let prec_child = ParsetreeViewer.operator_precedence operator in
169168
prec_parent == prec_child
@@ -180,8 +179,7 @@ let flatten_operand_rhs parent_operator rhs =
180179
};
181180
args = [(_, _left); (_, _right)];
182181
}
183-
when ParsetreeViewer.is_binary_operator operator
184-
&& not (operator_loc.loc_ghost && operator = "++") ->
182+
when ParsetreeViewer.not_ghost_operator operator operator_loc ->
185183
let prec_parent = ParsetreeViewer.operator_precedence parent_operator in
186184
let prec_child = ParsetreeViewer.operator_precedence operator in
187185
prec_parent >= prec_child || rhs.pexp_attributes <> []

compiler/syntax/src/res_parsetree_viewer.ml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,12 @@ let operator_precedence operator =
272272
| ":=" -> 1
273273
| "||" -> 2
274274
| "&&" -> 3
275-
| "==" | "===" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 4
276-
| "+" | "+." | "-" | "-." | "++" -> 5
277-
| "*" | "*." | "/" | "/." | "%" -> 6
278-
| "**" -> 7
279-
| "#" | "##" | "->" -> 8
275+
| "^" -> 4
276+
| "==" | "===" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 5
277+
| "+" | "+." | "-" | "-." | "++" -> 6
278+
| "*" | "*." | "/" | "/." | "%" -> 7
279+
| "**" -> 8
280+
| "#" | "##" | "->" -> 9
280281
| _ -> 0
281282

282283
let is_unary_operator operator =
@@ -295,15 +296,17 @@ let is_unary_expression expr =
295296
true
296297
| _ -> false
297298

298-
(* TODO: tweak this to check for ghost ^ as template literal *)
299299
let is_binary_operator operator =
300300
match operator with
301301
| ":=" | "||" | "&&" | "==" | "===" | "<" | ">" | "!=" | "!==" | "<=" | ">="
302302
| "|>" | "+" | "+." | "-" | "-." | "++" | "*" | "*." | "/" | "/." | "**"
303-
| "->" | "<>" | "%" ->
303+
| "->" | "<>" | "%" | "^" ->
304304
true
305305
| _ -> false
306306

307+
let not_ghost_operator operator (loc : Location.t) =
308+
is_binary_operator operator && not (loc.loc_ghost && operator = "++")
309+
307310
let is_binary_expression expr =
308311
match expr.pexp_desc with
309312
| Pexp_apply
@@ -315,9 +318,7 @@ let is_binary_expression expr =
315318
};
316319
args = [(Nolabel, _operand1); (Nolabel, _operand2)];
317320
}
318-
when is_binary_operator operator
319-
&& not (operator_loc.loc_ghost && operator = "++")
320-
(* template literal *) ->
321+
when not_ghost_operator operator operator_loc ->
321322
true
322323
| _ -> false
323324

compiler/syntax/src/res_parsetree_viewer.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ val is_huggable_rhs : Parsetree.expression -> bool
6565

6666
val operator_precedence : string -> int
6767

68+
val not_ghost_operator : string -> Location.t -> bool
6869
val is_unary_expression : Parsetree.expression -> bool
6970
val is_binary_operator : string -> bool
7071
val is_binary_expression : Parsetree.expression -> bool

compiler/syntax/src/res_scanner.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,9 @@ let rec scan scanner =
834834
| _ ->
835835
next scanner;
836836
Token.Band)
837+
| '^' ->
838+
next scanner;
839+
Token.Caret
837840
| ':' -> (
838841
match peek scanner with
839842
| '=' ->

compiler/syntax/src/res_token.ml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ type t =
7878
| Land
7979
| Lor
8080
| Band (* Bitwise and: & *)
81+
| Caret
8182
| BangEqual
8283
| BangEqualEqual
8384
| LessEqual
@@ -102,14 +103,15 @@ let precedence = function
102103
| HashEqual | ColonEqual -> 1
103104
| Lor -> 2
104105
| Land -> 3
106+
| Caret -> 4
105107
| Equal | EqualEqual | EqualEqualEqual | LessThan | GreaterThan | BangEqual
106108
| BangEqualEqual | LessEqual | GreaterEqual | BarGreater ->
107-
4
108-
| Plus | PlusDot | Minus | MinusDot | PlusPlus -> 5
109-
| Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 6
110-
| Exponentiation -> 7
111-
| MinusGreater -> 8
112-
| Dot -> 9
109+
5
110+
| Plus | PlusDot | Minus | MinusDot | PlusPlus -> 6
111+
| Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 7
112+
| Exponentiation -> 8
113+
| MinusGreater -> 9
114+
| Dot -> 10
113115
| _ -> 0
114116

115117
let to_string = function
@@ -189,6 +191,7 @@ let to_string = function
189191
| Of -> "of"
190192
| Lor -> "||"
191193
| Band -> "&"
194+
| Caret -> "^"
192195
| Land -> "&&"
193196
| BangEqual -> "!="
194197
| BangEqualEqual -> "!=="

runtime/Pervasives.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ external \"/": ('a, 'a) => 'a = "%div"
5252
external \"%": ('a, 'a) => 'a = "%mod"
5353
external mod: ('a, 'a) => 'a = "%mod"
5454
external \"**": ('a, 'a) => 'a = "%pow"
55-
external \"^": ('a, 'a) => 'a = "%xor"
55+
external \"^": ('a, 'a) => 'a = "%bitxor"
5656

5757
/* Comparisons */
5858
/* Note: Later comparisons will be converted to unified operations too */

runtime/Pervasives_mini.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ external \"/": (int, int) => int = "%divint"
3131
external \"%": (int, int) => int = "%modint"
3232
external mod: (int, int) => int = "%modint"
3333
external \"**": (int, int) => int = "%powint"
34-
external \"^": (int, int) => int = "%xorint"
34+
external \"^": (int, int) => int = "%bitxorint"
3535

3636
/* Comparisons */
3737
/* Note: Later comparisons will be converted to unified operations too */

tests/syntax_tests/data/parsing/errors/pattern/expected/templateLiteral.res.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
6 │ | _ => ()
2121
7 │ }
2222

23-
Not sure what to do with this character.
23+
Not sure what to do with this character "$"
2424

2525

2626
Syntax error!

tests/syntax_tests/data/parsing/errors/scanner/expected/badCharacter.res.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
1 │ let $ = 1
66

7-
Not sure what to do with this character.
7+
Not sure what to do with this character "$"
88

99

1010
Syntax error!
Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
11

22
Syntax error!
3-
syntax_tests/data/parsing/errors/scanner/oldDerefOp.res:1:50
3+
syntax_tests/data/parsing/errors/scanner/oldDerefOp.res:1:51
44

55
1 │ let newVelocity = velocity +. a *. secondPerFrame^;
66
2 │ let newX = x +. newVelocity *. secondPerFrame^;
77
3 │
88

9-
Not sure what to do with this character.
10-
If you're trying to dereference a mutable value, use `myValue.contents` instead.
11-
To concatenate strings, use `"a" ++ "b"` instead.
9+
Did you forget to write an expression here?
1210

1311

1412
Syntax error!
15-
syntax_tests/data/parsing/errors/scanner/oldDerefOp.res:2:46
13+
syntax_tests/data/parsing/errors/scanner/oldDerefOp.res:2:47
1614

1715
1 │ let newVelocity = velocity +. a *. secondPerFrame^;
1816
2 │ let newX = x +. newVelocity *. secondPerFrame^;
1917
3 │
2018

21-
Not sure what to do with this character.
22-
If you're trying to dereference a mutable value, use `myValue.contents` instead.
23-
To concatenate strings, use `"a" ++ "b"` instead.
19+
Did you forget to write an expression here?
2420

25-
let newVelocity = velocity +. (a *. secondPerFrame)
26-
let newX = x +. (newVelocity *. secondPerFrame)
21+
let newVelocity =
22+
(velocity +. (a *. secondPerFrame)) ^ ([%rescript.exprhole ])
23+
let newX = (x +. (newVelocity *. secondPerFrame)) ^ ([%rescript.exprhole ])

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ let x = ((while condition do () done)[@attr ]) z
1414
let x = (a + (-1)) + (-2)
1515
let x = (a + (((-1))[@attr ])) + (((-2))[@attr ])
1616
let x = (a % a) == 0
17+
let x = a ^ (a == 0)
1718
let x = a - b
1819
let x = a -. b
1920
;;Constructor (a, b)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ let () = (print_int: int => unit)((x: int))
8585
x + y / z
8686
x / y + z
8787
x % y * z
88+
x ^ y + z
8889
100 * x / total
8990
2 / 3 * 10 / 2 + 2
9091
let rotateX = (range / rect.height * refY - range / 2) * getXMultiplication(rect.width)

tests/tests/src/belt_int_test.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Mocha.describe("Belt_int_test", () => {
3636
Test_utils.eq("File \"belt_int_test.res\", line 41, characters 7-14", 6, 6);
3737
Test_utils.eq("File \"belt_int_test.res\", line 42, characters 7-14", 0, 0);
3838
Test_utils.eq("File \"belt_int_test.res\", line 43, characters 7-14", 0, 0);
39+
Test_utils.eq("File \"belt_int_test.res\", line 44, characters 7-14", 1, 1);
3940
});
4041
});
4142

tests/tests/src/unified_ops_test.mjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ let pow3 = 2n ** 2n;
6767

6868
let pow_overflow = 0;
6969

70+
function bxor_int(a, b) {
71+
return a ^ b;
72+
}
73+
74+
function bxor_bigint(a, b) {
75+
return a ^ b;
76+
}
77+
7078
let int = 3;
7179

7280
export {
@@ -91,5 +99,7 @@ export {
9199
pow2,
92100
pow3,
93101
pow_overflow,
102+
bxor_int,
103+
bxor_bigint,
94104
}
95105
/* No side effect */

tests/tests/src/unified_ops_test.res

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ let pow3 = 2n ** 2n
2727

2828
let pow_overflow = 2147483647 ** 2
2929

30-
let lxor = (a, b: int) => a ^ b
30+
let bxor_int = (a, b) => a ^ b
31+
let bxor_bigint = (a: bigint, b) => a ^ b

0 commit comments

Comments
 (0)