Skip to content

Commit 931bb42

Browse files
fix(grainfmt): Format rational numbers with parens when needed for precedence (#1385)
Co-authored-by: Oscar Spencer <oscar@grain-lang.org>
1 parent 4363ad1 commit 931bb42

File tree

4 files changed

+49
-31
lines changed

4 files changed

+49
-31
lines changed

compiler/src/formatting/format.re

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,39 +1703,26 @@ and print_infix_application =
17031703
| _ => false
17041704
};
17051705

1706-
let (left_grouping_required, right_grouping_required) =
1707-
switch (first.pexp_desc, second.pexp_desc) {
1708-
| (PExpApp(fn1, _), PExpApp(fn2, _)) =>
1709-
let left_prec = op_precedence(get_function_name(fn1));
1710-
let right_prec = op_precedence(get_function_name(fn2));
1711-
let parent_prec = op_precedence(function_name);
1712-
1713-
// the equality check is needed for the function on the right
1714-
// as we process from the left by default when the same prededence
1715-
1716-
let needed_left = left_prec < parent_prec;
1717-
let needed_right = right_prec <= parent_prec;
1718-
1719-
(needed_left, needed_right);
1706+
let parent_prec = op_precedence(function_name);
17201707

1721-
| (PExpApp(fn1, _), _) =>
1722-
let left_prec = op_precedence(get_function_name(fn1));
1723-
let parent_prec = op_precedence(function_name);
1724-
if (left_prec < parent_prec) {
1725-
(true, false);
1726-
} else {
1727-
(false, false);
1728-
};
1729-
| (_, PExpApp(fn2, _)) =>
1730-
let parent_prec = op_precedence(function_name);
1731-
let right_prec = op_precedence(get_function_name(fn2));
1732-
if (right_prec <= parent_prec) {
1733-
(false, true);
1734-
} else {
1735-
(false, false);
1736-
};
1708+
let left_grouping_required =
1709+
switch (first.pexp_desc) {
1710+
| PExpApp(fn1, _) =>
1711+
op_precedence(get_function_name(fn1)) < parent_prec
1712+
| PExpConstant(PConstNumber(PConstNumberRational(_, _))) =>
1713+
op_precedence("/") < parent_prec
1714+
| _ => false
1715+
};
17371716

1738-
| _ => (false, false)
1717+
let right_grouping_required =
1718+
// the equality check is needed for the value on the right
1719+
// as we process from the left by default when the same prededence
1720+
switch (second.pexp_desc) {
1721+
| PExpApp(fn1, _) =>
1722+
op_precedence(get_function_name(fn1)) <= parent_prec
1723+
| PExpConstant(PConstNumber(PConstNumberRational(_, _))) =>
1724+
op_precedence("/") <= parent_prec
1725+
| _ => false
17391726
};
17401727

17411728
let left_needs_parens = left_is_if || left_grouping_required;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Int32 from "int32"
2+
3+
let a = Int32.toNumber(3l) * (2/3)
4+
5+
let b = 2/3 + Int32.toNumber(4l)
6+
7+
let c = Int32.toNumber(3l) + (2/3)
8+
9+
let x = 3 * (2/3)
10+
11+
let y = 2/3 + 4
12+
13+
let z = 3 + (2/3)
14+
15+
assert 4 * (2/3) == 8/3
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Int32 from "int32"
2+
3+
let a = Int32.toNumber(3l) * (2/3)
4+
5+
let b = 2/3 + Int32.toNumber(4l)
6+
7+
let c = Int32.toNumber(3l) + 2/3
8+
9+
let x = 3 * (2/3)
10+
11+
let y = 2/3 + 4
12+
13+
let z = 3 + 2/3
14+
15+
assert 4 * (2/3) == 8/3

compiler/test/suites/formatter.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@ describe("formatter", ({test, testSkip}) => {
4545
assertFormatOutput("parens", "parens");
4646
assertFormatOutput("windows", "windows");
4747
assertFormatOutput("patterns", "patterns");
48+
assertFormatOutput("rationals", "rationals");
4849
assertFormatOutput("constraints", "constraints");
4950
});

0 commit comments

Comments
 (0)