mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
refactor parse AST to allow multiple if branches
This commit is contained in:
parent
c208f500d9
commit
4eea0aff7a
6 changed files with 145 additions and 109 deletions
|
@ -58,8 +58,11 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
|||
loc_expr.is_multiline() || args.iter().any(|loc_arg| loc_arg.is_multiline())
|
||||
}
|
||||
|
||||
If(loc_cond, loc_if_true, loc_if_false) => {
|
||||
loc_cond.is_multiline() || loc_if_true.is_multiline() || loc_if_false.is_multiline()
|
||||
If(branches, final_else) => {
|
||||
final_else.is_multiline()
|
||||
|| branches
|
||||
.iter()
|
||||
.any(|(c, t)| c.is_multiline() || t.is_multiline())
|
||||
}
|
||||
|
||||
BinOp((loc_left, _, loc_right)) => {
|
||||
|
@ -257,8 +260,8 @@ impl<'a> Formattable<'a> for Expr<'a> {
|
|||
// still print the return value.
|
||||
ret.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||
}
|
||||
If(loc_condition, loc_then, loc_else) => {
|
||||
fmt_if(buf, loc_condition, loc_then, loc_else, indent);
|
||||
If(branches, final_else) => {
|
||||
fmt_if(buf, branches, final_else, self.is_multiline(), indent);
|
||||
}
|
||||
When(loc_condition, branches) => fmt_when(buf, loc_condition, branches, indent),
|
||||
List {
|
||||
|
@ -629,15 +632,15 @@ fn fmt_when<'a>(
|
|||
|
||||
fn fmt_if<'a>(
|
||||
buf: &mut String<'a>,
|
||||
loc_condition: &'a Located<Expr<'a>>,
|
||||
loc_then: &'a Located<Expr<'a>>,
|
||||
loc_else: &'a Located<Expr<'a>>,
|
||||
branches: &'a [(Located<Expr<'a>>, Located<Expr<'a>>)],
|
||||
final_else: &'a Located<Expr<'a>>,
|
||||
is_multiline: bool,
|
||||
indent: u16,
|
||||
) {
|
||||
let is_multiline_then = loc_then.is_multiline();
|
||||
let is_multiline_else = loc_else.is_multiline();
|
||||
let is_multiline_condition = loc_condition.is_multiline();
|
||||
let is_multiline = is_multiline_then || is_multiline_else || is_multiline_condition;
|
||||
// let is_multiline_then = loc_then.is_multiline();
|
||||
// let is_multiline_else = final_else.is_multiline();
|
||||
// let is_multiline_condition = loc_condition.is_multiline();
|
||||
// let is_multiline = is_multiline_then || is_multiline_else || is_multiline_condition;
|
||||
|
||||
let return_indent = if is_multiline {
|
||||
indent + INDENT
|
||||
|
@ -645,80 +648,89 @@ fn fmt_if<'a>(
|
|||
indent
|
||||
};
|
||||
|
||||
buf.push_str("if");
|
||||
for (loc_condition, loc_then) in branches.iter() {
|
||||
let is_multiline_condition = loc_condition.is_multiline();
|
||||
|
||||
if is_multiline_condition {
|
||||
match &loc_condition.value {
|
||||
Expr::SpaceBefore(expr_below, spaces_above_expr) => {
|
||||
fmt_comments_only(buf, spaces_above_expr.iter(), NewlineAt::Top, return_indent);
|
||||
newline(buf, return_indent);
|
||||
buf.push_str("if");
|
||||
|
||||
match &expr_below {
|
||||
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
||||
expr_above.format(buf, return_indent);
|
||||
fmt_comments_only(
|
||||
buf,
|
||||
spaces_below_expr.iter(),
|
||||
NewlineAt::Top,
|
||||
return_indent,
|
||||
);
|
||||
newline(buf, indent);
|
||||
}
|
||||
if is_multiline_condition {
|
||||
match &loc_condition.value {
|
||||
Expr::SpaceBefore(expr_below, spaces_above_expr) => {
|
||||
fmt_comments_only(buf, spaces_above_expr.iter(), NewlineAt::Top, return_indent);
|
||||
newline(buf, return_indent);
|
||||
|
||||
_ => {
|
||||
expr_below.format(buf, return_indent);
|
||||
match &expr_below {
|
||||
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
||||
expr_above.format(buf, return_indent);
|
||||
fmt_comments_only(
|
||||
buf,
|
||||
spaces_below_expr.iter(),
|
||||
NewlineAt::Top,
|
||||
return_indent,
|
||||
);
|
||||
newline(buf, indent);
|
||||
}
|
||||
|
||||
_ => {
|
||||
expr_below.format(buf, return_indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
||||
newline(buf, return_indent);
|
||||
expr_above.format(buf, return_indent);
|
||||
fmt_comments_only(buf, spaces_below_expr.iter(), NewlineAt::Top, return_indent);
|
||||
newline(buf, indent);
|
||||
}
|
||||
Expr::SpaceAfter(expr_above, spaces_below_expr) => {
|
||||
newline(buf, return_indent);
|
||||
expr_above.format(buf, return_indent);
|
||||
fmt_comments_only(buf, spaces_below_expr.iter(), NewlineAt::Top, return_indent);
|
||||
newline(buf, indent);
|
||||
}
|
||||
|
||||
_ => {
|
||||
newline(buf, return_indent);
|
||||
loc_condition.format(buf, return_indent);
|
||||
newline(buf, indent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buf.push(' ');
|
||||
loc_condition.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||
buf.push(' ');
|
||||
}
|
||||
|
||||
buf.push_str("then");
|
||||
|
||||
if is_multiline {
|
||||
match &loc_then.value {
|
||||
Expr::SpaceBefore(expr_below, spaces_below) => {
|
||||
// we want exactly one newline, user-inserted extra newlines are ignored.
|
||||
newline(buf, return_indent);
|
||||
fmt_comments_only(buf, spaces_below.iter(), NewlineAt::Bottom, return_indent);
|
||||
|
||||
match &expr_below {
|
||||
Expr::SpaceAfter(expr_above, spaces_above) => {
|
||||
expr_above.format(buf, return_indent);
|
||||
|
||||
fmt_comments_only(buf, spaces_above.iter(), NewlineAt::Top, return_indent);
|
||||
newline(buf, indent);
|
||||
}
|
||||
|
||||
_ => {
|
||||
expr_below.format(buf, return_indent);
|
||||
}
|
||||
_ => {
|
||||
newline(buf, return_indent);
|
||||
loc_condition.format(buf, return_indent);
|
||||
newline(buf, indent);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
loc_condition.format(buf, return_indent);
|
||||
}
|
||||
} else {
|
||||
buf.push(' ');
|
||||
loc_condition.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||
buf.push(' ');
|
||||
}
|
||||
|
||||
buf.push_str("then");
|
||||
|
||||
if is_multiline {
|
||||
match &loc_then.value {
|
||||
Expr::SpaceBefore(expr_below, spaces_below) => {
|
||||
// we want exactly one newline, user-inserted extra newlines are ignored.
|
||||
newline(buf, return_indent);
|
||||
fmt_comments_only(buf, spaces_below.iter(), NewlineAt::Bottom, return_indent);
|
||||
|
||||
match &expr_below {
|
||||
Expr::SpaceAfter(expr_above, spaces_above) => {
|
||||
expr_above.format(buf, return_indent);
|
||||
|
||||
fmt_comments_only(
|
||||
buf,
|
||||
spaces_above.iter(),
|
||||
NewlineAt::Top,
|
||||
return_indent,
|
||||
);
|
||||
newline(buf, indent);
|
||||
}
|
||||
|
||||
_ => {
|
||||
expr_below.format(buf, return_indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
loc_condition.format(buf, return_indent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buf.push_str(" ");
|
||||
loc_then.format(buf, return_indent);
|
||||
}
|
||||
} else {
|
||||
buf.push_str(" ");
|
||||
loc_then.format(buf, return_indent);
|
||||
}
|
||||
|
||||
if is_multiline {
|
||||
|
@ -728,7 +740,7 @@ fn fmt_if<'a>(
|
|||
buf.push_str(" else ");
|
||||
}
|
||||
|
||||
loc_else.format(buf, return_indent);
|
||||
final_else.format(buf, return_indent);
|
||||
}
|
||||
|
||||
pub fn fmt_closure<'a>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue