Skip to content

Commit

Permalink
fix(grainfmt): Format rational numbers with parens when needed for pr…
Browse files Browse the repository at this point in the history
…ecedence (#1385)

Co-authored-by: Oscar Spencer <[email protected]>
  • Loading branch information
marcusroberts and ospencer committed Aug 4, 2022
1 parent 4363ad1 commit 931bb42
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 31 deletions.
49 changes: 18 additions & 31 deletions compiler/src/formatting/format.re
Original file line number Diff line number Diff line change
Expand Up @@ -1703,39 +1703,26 @@ and print_infix_application =
| _ => false
};

let (left_grouping_required, right_grouping_required) =
switch (first.pexp_desc, second.pexp_desc) {
| (PExpApp(fn1, _), PExpApp(fn2, _)) =>
let left_prec = op_precedence(get_function_name(fn1));
let right_prec = op_precedence(get_function_name(fn2));
let parent_prec = op_precedence(function_name);

// the equality check is needed for the function on the right
// as we process from the left by default when the same prededence

let needed_left = left_prec < parent_prec;
let needed_right = right_prec <= parent_prec;

(needed_left, needed_right);
let parent_prec = op_precedence(function_name);

| (PExpApp(fn1, _), _) =>
let left_prec = op_precedence(get_function_name(fn1));
let parent_prec = op_precedence(function_name);
if (left_prec < parent_prec) {
(true, false);
} else {
(false, false);
};
| (_, PExpApp(fn2, _)) =>
let parent_prec = op_precedence(function_name);
let right_prec = op_precedence(get_function_name(fn2));
if (right_prec <= parent_prec) {
(false, true);
} else {
(false, false);
};
let left_grouping_required =
switch (first.pexp_desc) {
| PExpApp(fn1, _) =>
op_precedence(get_function_name(fn1)) < parent_prec
| PExpConstant(PConstNumber(PConstNumberRational(_, _))) =>
op_precedence("/") < parent_prec
| _ => false
};

| _ => (false, false)
let right_grouping_required =
// the equality check is needed for the value on the right
// as we process from the left by default when the same prededence
switch (second.pexp_desc) {
| PExpApp(fn1, _) =>
op_precedence(get_function_name(fn1)) <= parent_prec
| PExpConstant(PConstNumber(PConstNumberRational(_, _))) =>
op_precedence("/") <= parent_prec
| _ => false
};

let left_needs_parens = left_is_if || left_grouping_required;
Expand Down
15 changes: 15 additions & 0 deletions compiler/test/formatter_inputs/rationals.gr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Int32 from "int32"

let a = Int32.toNumber(3l) * (2/3)

let b = 2/3 + Int32.toNumber(4l)

let c = Int32.toNumber(3l) + (2/3)

let x = 3 * (2/3)

let y = 2/3 + 4

let z = 3 + (2/3)

assert 4 * (2/3) == 8/3
15 changes: 15 additions & 0 deletions compiler/test/formatter_outputs/rationals.gr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Int32 from "int32"

let a = Int32.toNumber(3l) * (2/3)

let b = 2/3 + Int32.toNumber(4l)

let c = Int32.toNumber(3l) + 2/3

let x = 3 * (2/3)

let y = 2/3 + 4

let z = 3 + 2/3

assert 4 * (2/3) == 8/3
1 change: 1 addition & 0 deletions compiler/test/suites/formatter.re
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@ describe("formatter", ({test, testSkip}) => {
assertFormatOutput("parens", "parens");
assertFormatOutput("windows", "windows");
assertFormatOutput("patterns", "patterns");
assertFormatOutput("rationals", "rationals");
assertFormatOutput("constraints", "constraints");
});

0 comments on commit 931bb42

Please sign in to comment.