don't use a tuple to ensure non-emptiness

This commit is contained in:
Stoeffel 2020-01-08 11:05:53 +01:00
parent 64a562ebc6
commit a98113c88d
6 changed files with 46 additions and 67 deletions

View file

@ -462,17 +462,17 @@ pub fn canonicalize_expr(
let mut can_branches = Vec::with_capacity(branches.len());
for ((loc_pattern, _), loc_expr) in branches {
for (loc_pattern, loc_expr) in branches {
let mut shadowable_idents = scope.idents.clone();
remove_idents(&loc_pattern.value, &mut shadowable_idents);
remove_idents(&loc_pattern.first().unwrap().value, &mut shadowable_idents);
let (can_pattern, loc_can_expr, branch_references) = canonicalize_when_branch(
env,
var_store,
scope,
region,
loc_pattern,
loc_pattern.first().unwrap(),
loc_expr,
&mut output,
);

View file

@ -166,17 +166,14 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
let loc_desugared_cond = &*arena.alloc(desugar_expr(arena, &loc_cond_expr));
let mut desugared_branches = Vec::with_capacity_in(branches.len(), arena);
for ((loc_pattern, _), loc_branch_expr) in branches.into_iter() {
for (loc_pattern, loc_branch_expr) in branches.into_iter() {
let desugared = desugar_expr(arena, &loc_branch_expr);
desugared_branches.push(&*arena.alloc((
(
Located {
region: loc_pattern.region,
value: Pattern::Nested(&loc_pattern.value),
},
Vec::with_capacity_in(0, arena),
),
bumpalo::vec![in arena; Located {
region: loc_pattern.first().unwrap().region,
value: Pattern::Nested(&loc_pattern.first().unwrap().value),
}],
Located {
region: desugared.region,
value: Nested(&desugared.value),
@ -254,13 +251,10 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
let pattern_region = condition.region;
branches.push(&*arena.alloc((
(
Located {
bumpalo::vec![in arena; Located {
value: Pattern::GlobalTag("False"),
region: pattern_region,
},
Vec::new_in(arena),
),
}],
Located {
value: Nested(&else_branch.value),
region: else_branch.region,
@ -268,13 +262,10 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
)));
branches.push(&*arena.alloc((
(
Located {
bumpalo::vec![in arena; Located {
value: Pattern::Underscore,
region: pattern_region,
},
Vec::new_in(arena),
),
}],
Located {
value: Nested(&then_branch.value),
region: then_branch.region,

View file

@ -141,16 +141,21 @@ pub fn fmt_expr<'a>(
buf.push_str(" is\n");
let mut it = branches.iter().peekable();
while let Some(((pattern, _), expr)) = it.next() {
while let Some((patterns, expr)) = it.next() {
add_spaces(buf, indent + INDENT);
match pattern.value {
match patterns.first().unwrap().value {
Pattern::SpaceBefore(nested, spaces) => {
fmt_comments_only(buf, spaces.iter(), indent + INDENT);
fmt_pattern(buf, nested, indent + INDENT, false);
}
_ => {
fmt_pattern(buf, &pattern.value, indent + INDENT, false);
fmt_pattern(
buf,
&patterns.first().unwrap().value,
indent + INDENT,
false,
);
}
}

View file

@ -158,7 +158,7 @@ pub enum Expr<'a> {
If(&'a (Loc<Expr<'a>>, Loc<Expr<'a>>, Loc<Expr<'a>>)),
When(
&'a Loc<Expr<'a>>,
Vec<'a, &'a ((Loc<Pattern<'a>>, Vec<'a, Loc<Pattern<'a>>>), Loc<Expr<'a>>)>,
Vec<'a, &'a (Vec<'a, Loc<Pattern<'a>>>, Loc<Expr<'a>>)>,
),
// Blank Space (e.g. comments, spaces, newlines) before or after an expression.

View file

@ -863,46 +863,29 @@ pub fn when_expr<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
pub fn case_branches<'a>(
min_indent: u16,
) -> impl Parser<
'a,
Vec<
'a,
&'a (
(Located<Pattern<'a>>, Vec<'a, Located<Pattern<'a>>>),
Located<Expr<'a>>,
),
>,
> {
) -> impl Parser<'a, Vec<'a, &'a (Vec<'a, Located<Pattern<'a>>>, Located<Expr<'a>>)>> {
move |arena, state| {
let mut branches: Vec<
'a,
&'a (
(Located<Pattern<'a>>, Vec<'a, Located<Pattern<'a>>>),
Located<Expr<'a>>,
),
> = Vec::with_capacity_in(2, arena);
let mut branches: Vec<'a, &'a (Vec<'a, Located<Pattern<'a>>>, Located<Expr<'a>>)> =
Vec::with_capacity_in(2, arena);
// 1. Parse the first branch and get its indentation level. (It must be >= min_indent.)
// 2. Parse the other branches. Their indentation levels must be == the first branch's.
let (mut loc_first_pattern, state) =
space1_before(loc!(pattern(min_indent)), min_indent).parse(arena, state)?;
let (mut loc_first_pattern, state) = sep_by1(
map!(and!(space1(min_indent), char('|')), |_| ()),
space1_before(loc!(pattern(min_indent)), min_indent),
)
.parse(arena, state)?;
let original_indent = state.indent_col;
let indented_more = original_indent + 1;
let (loc_first_pattern_alt, state) = zero_or_more!(skip_first!(
and!(space0(min_indent), char('|')),
space0_before(loc!(pattern(min_indent)), min_indent)
))
.parse(arena, state)?;
let (spaces_before_arrow, state) = space0(min_indent).parse(arena, state)?;
// Record the spaces before the first "->", if any.
if !spaces_before_arrow.is_empty() {
let region = loc_first_pattern.region;
let value =
Pattern::SpaceAfter(arena.alloc(loc_first_pattern.value), spaces_before_arrow);
loc_first_pattern = Located { region, value };
let last = loc_first_pattern.pop().unwrap();
let region = last.region;
let value = Pattern::SpaceAfter(arena.alloc(last.value), spaces_before_arrow);
loc_first_pattern.push(Located { region, value });
};
// Parse the first "->" and the expression after it.
@ -917,14 +900,14 @@ pub fn case_branches<'a>(
.parse(arena, state)?;
// Record this as the first branch, then optionally parse additional branches.
branches.push(arena.alloc(((loc_first_pattern, loc_first_pattern_alt), loc_first_expr)));
branches.push(arena.alloc((loc_first_pattern, loc_first_expr)));
let branch_parser = and!(
then(
space1_around(loc!(pattern(min_indent)), min_indent),
move |_arena, state, loc_pattern| {
if state.indent_col == original_indent {
Ok(((loc_pattern, Vec::with_capacity_in(0, arena)), state))
Ok((bumpalo::vec![in arena; loc_pattern ], state))
} else {
panic!(
"TODO additional branch didn't have same indentation as first branch"

View file

@ -1364,14 +1364,14 @@ mod test_parse {
let loc_pattern1 = Located::new(1, 1, 1, 7, pattern1);
let expr1 = Int("1");
let loc_expr1 = Located::new(1, 1, 11, 12, expr1);
let branch1 = &*arena.alloc(((loc_pattern1, bumpalo::vec![in &arena;]), loc_expr1));
let branch1 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern1], loc_expr1));
let newlines = bumpalo::vec![in &arena; Newline];
let pattern2 =
Pattern::SpaceBefore(arena.alloc(StrLiteral("mise")), newlines.into_bump_slice());
let loc_pattern2 = Located::new(2, 2, 1, 7, pattern2);
let expr2 = Int("2");
let loc_expr2 = Located::new(2, 2, 11, 12, expr2);
let branch2 = &*arena.alloc(((loc_pattern2, bumpalo::vec![in &arena;]), loc_expr2));
let branch2 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern2 ], loc_expr2));
let branches = bumpalo::vec![in &arena; branch1, branch2];
let loc_cond = Located::new(0, 0, 5, 6, Var(&[], "x"));
let expected = Expr::When(arena.alloc(loc_cond), branches);
@ -1398,14 +1398,14 @@ mod test_parse {
let loc_pattern1 = Located::new(1, 1, 1, 2, pattern1);
let expr1 = Int("2");
let loc_expr1 = Located::new(1, 1, 6, 7, expr1);
let branch1 = &*arena.alloc(((loc_pattern1, bumpalo::vec![in &arena;]), loc_expr1));
let branch1 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern1], loc_expr1));
let newlines = bumpalo::vec![in &arena; Newline];
let pattern2 =
Pattern::SpaceBefore(arena.alloc(IntLiteral("3")), newlines.into_bump_slice());
let loc_pattern2 = Located::new(2, 2, 1, 2, pattern2);
let expr2 = Int("4");
let loc_expr2 = Located::new(2, 2, 6, 7, expr2);
let branch2 = &*arena.alloc(((loc_pattern2, bumpalo::vec![in &arena;]), loc_expr2));
let branch2 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern2], loc_expr2));
let branches = bumpalo::vec![in &arena; branch1, branch2];
let loc_cond = Located::new(0, 0, 5, 6, Var(&[], "x"));
let expected = Expr::When(arena.alloc(loc_cond), branches);
@ -1435,7 +1435,7 @@ mod test_parse {
let loc_pattern1 = Located::new(1, 1, 1, 6, pattern1);
let expr1 = Int("2");
let loc_expr1 = Located::new(1, 1, 10, 11, expr1);
let branch1 = &*arena.alloc(((loc_pattern1, bumpalo::vec![in &arena;]), loc_expr1));
let branch1 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern1 ], loc_expr1));
let newlines = bumpalo::vec![in &arena; Newline];
let identifiers2 = bumpalo::vec![in &arena; Located::new(2, 2, 3, 4, Identifier("z")), Located::new(2, 2, 6, 7, Identifier("w")) ];
let pattern2 = Pattern::SpaceBefore(
@ -1445,7 +1445,7 @@ mod test_parse {
let loc_pattern2 = Located::new(2, 2, 1, 9, pattern2);
let expr2 = Int("4");
let loc_expr2 = Located::new(2, 2, 13, 14, expr2);
let branch2 = &*arena.alloc(((loc_pattern2, bumpalo::vec![in &arena;]), loc_expr2));
let branch2 = &*arena.alloc((bumpalo::vec![in &arena;loc_pattern2 ], loc_expr2));
let branches = bumpalo::vec![in &arena; branch1, branch2];
let loc_cond = Located::new(0, 0, 5, 6, Var(&[], "x"));
let expected = Expr::When(arena.alloc(loc_cond), branches);
@ -1475,7 +1475,7 @@ mod test_parse {
let expr1 = Int("1");
let loc_expr1 = Located::new(1, 1, 20, 21, expr1);
let branch1 = &*arena.alloc((
(loc_pattern1, bumpalo::vec![in &arena;loc_pattern1_alt]),
bumpalo::vec![in &arena;loc_pattern1, loc_pattern1_alt],
loc_expr1,
));
let branches = bumpalo::vec![in &arena; branch1];