Skip to content

Commit 971f935

Browse files
authored
Add remainder (% aka modulus) operator (#7152)
Resolved #6455
1 parent 7a58f3b commit 971f935

File tree

15 files changed

+40
-5
lines changed

15 files changed

+40
-5
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414

1515
#### :rocket: New Feature
1616

17-
- Introduce "Unified operators" for arithmetic operators (`+`, `-`, `*`, `/`, `mod`). See https://github.com/rescript-lang/rescript-compiler/pull/7057
17+
- Introduce "Unified operators" for arithmetic operators (`+`, `-`, `*`, `/`, `mod`). https://github.com/rescript-lang/rescript-compiler/pull/7057
18+
- Add remainder (`%`, aka modulus) operator. https://github.com/rescript-lang/rescript-compiler/pull/7152
1819

1920
# 12.0.0-alpha.4
2021

compiler/ml/unified_ops.ml

+13
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,19 @@ let entries =
135135
string = None;
136136
};
137137
};
138+
{
139+
path = builtin "%";
140+
name = "%mod";
141+
form = Binary;
142+
specialization =
143+
{
144+
int = Pmodint Safe;
145+
bool = None;
146+
float = Some Pmodfloat;
147+
bigint = Some Pmodbigint;
148+
string = None;
149+
};
150+
};
138151
{
139152
path = builtin "mod";
140153
name = "%mod";

compiler/syntax/src/res_core.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2221,7 +2221,7 @@ and parse_binary_expr ?(context = OrdinaryExpr) ?a p prec =
22212221
*
22222222
* First case is unary, second is a binary operator.
22232223
* See Scanner.isBinaryOp *)
2224-
| (Minus | MinusDot | LessThan)
2224+
| (Minus | MinusDot | LessThan | Percent)
22252225
when (not
22262226
(Scanner.is_binary_op p.scanner.src p.start_pos.pos_cnum
22272227
p.end_pos.pos_cnum))

compiler/syntax/src/res_parsetree_viewer.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ let operator_precedence operator =
302302
| "&&" -> 3
303303
| "=" | "==" | "<" | ">" | "!=" | "<>" | "!==" | "<=" | ">=" | "|>" -> 4
304304
| "+" | "+." | "-" | "-." | "^" -> 5
305-
| "*" | "*." | "/" | "/." -> 6
305+
| "*" | "*." | "/" | "/." | "%" -> 6
306306
| "**" -> 7
307307
| "#" | "##" | "|." | "|.u" -> 8
308308
| _ -> 0
@@ -326,7 +326,7 @@ let is_binary_operator operator =
326326
match operator with
327327
| ":=" | "||" | "&&" | "=" | "==" | "<" | ">" | "!=" | "!==" | "<=" | ">="
328328
| "|>" | "+" | "+." | "-" | "-." | "^" | "*" | "*." | "/" | "/." | "**" | "|."
329-
| "|.u" | "<>" ->
329+
| "|.u" | "<>" | "%" ->
330330
true
331331
| _ -> false
332332

compiler/syntax/src/res_token.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ let precedence = function
106106
| BangEqualEqual | LessEqual | GreaterEqual | BarGreater ->
107107
4
108108
| Plus | PlusDot | Minus | MinusDot | PlusPlus -> 5
109-
| Asterisk | AsteriskDot | Forwardslash | ForwardslashDot -> 6
109+
| Asterisk | AsteriskDot | Forwardslash | ForwardslashDot | Percent -> 6
110110
| Exponentiation -> 7
111111
| MinusGreater -> 8
112112
| Dot -> 9

runtime/Pervasives.res

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ external \"+": ('a, 'a) => 'a = "%add"
4949
external \"-": ('a, 'a) => 'a = "%sub"
5050
external \"*": ('a, 'a) => 'a = "%mul"
5151
external \"/": ('a, 'a) => 'a = "%div"
52+
external \"%": ('a, 'a) => 'a = "%mod"
5253
external mod: ('a, 'a) => 'a = "%mod"
5354

5455
/* Comparisons */

runtime/Pervasives_mini.res

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ external \"+": (int, int) => int = "%addint"
2828
external \"-": (int, int) => int = "%subint"
2929
external \"*": (int, int) => int = "%mulint"
3030
external \"/": (int, int) => int = "%divint"
31+
external \"%": (int, int) => int = "%modint"
3132
external mod: (int, int) => int = "%modint"
3233

3334
/* Comparisons */

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

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ let x = z |> @attr while condition { () }
2727

2828
let x = a + -1 + -2
2929
let x = a + @attr -1 + @attr -2
30+
let x = a % a == 0
3031

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

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

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ let x = while condition do () done z
1313
let x = ((while condition do () done)[@attr ]) z
1414
let x = (a + (-1)) + (-2)
1515
let x = (a + (((-1))[@attr ])) + (((-2))[@attr ])
16+
let x = (a % a) = 0
1617
let x = a - b
1718
let x = a -. b
1819
;;Constructor (a, b)

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

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ let () = (x: int) |> (print_int: int => unit)
5353
// math
5454
x + y / z
5555
x / y + z
56+
x % y * z
5657
100 * x / total
5758
2 / 3 * 10 / 2 + 2
5859
let rotateX = ((range / rect.height) * refY - range / 2) * getXMultiplication(rect.width)

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

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ let () = (print_int: int => unit)((x: int))
8484
// math
8585
x + y / z
8686
x / y + z
87+
x % y * z
8788
100 * x / total
8889
2 / 3 * 10 / 2 + 2
8990
let rotateX = (range / rect.height * refY - range / 2) * getXMultiplication(rect.width)

tests/tests/src/belt_int_test.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Mocha.describe("Belt_int_test", () => {
3535
Test_utils.eq("File \"belt_int_test.res\", line 40, characters 7-14", -1, -1);
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);
38+
Test_utils.eq("File \"belt_int_test.res\", line 43, characters 7-14", 0, 0);
3839
});
3940
});
4041

tests/tests/src/belt_int_test.res

+1
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,6 @@ describe(__MODULE__, () => {
4040
eq(__LOC__, 2 - 3, -1)
4141
eq(__LOC__, 2 * 3, 6)
4242
eq(__LOC__, 2 / 3, 0)
43+
eq(__LOC__, 2 % 2, 0)
4344
})
4445
})

tests/tests/src/unified_ops_test.mjs

+10
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ function case2(a, b) {
5151
return a + "test" + b;
5252
}
5353

54+
function even(n) {
55+
return n % 2 === 0;
56+
}
57+
58+
function odd(n) {
59+
return n % 2 === 1;
60+
}
61+
5462
let int = 3;
5563

5664
export {
@@ -69,5 +77,7 @@ export {
6977
rhsstring,
7078
case1,
7179
case2,
80+
even,
81+
odd,
7282
}
7383
/* No side effect */

tests/tests/src/unified_ops_test.res

+3
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ let rhsstring = (a, b: string) => a + b
1717

1818
let case1 = a => 1 + a
1919
let case2 = (a, b) => a + "test" + b
20+
21+
let even = n => n % 2 == 0
22+
let odd = n => n % 2 == 1

0 commit comments

Comments
 (0)