mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-08-15 14:50:42 +03:00
Fix parsing of empty switch
This commit is contained in:
parent
530f8d777f
commit
08480c40e1
@ -451,7 +451,39 @@ impl<'a> TermParser<'a> {
|
||||
// Switch
|
||||
if self.try_parse_keyword("switch") {
|
||||
unexpected_tag(self)?;
|
||||
return self.parse_switch();
|
||||
let (bnd, arg, with) = self.parse_match_header()?;
|
||||
|
||||
self.consume("{")?;
|
||||
self.try_consume("|");
|
||||
self.consume("0")?;
|
||||
self.consume(":")?;
|
||||
let zero = self.parse_term()?;
|
||||
self.try_consume(";");
|
||||
|
||||
let mut arms = vec![zero];
|
||||
let mut expected_num = 1;
|
||||
loop {
|
||||
self.try_consume("|");
|
||||
// case _
|
||||
if self.try_consume("_") {
|
||||
self.consume(":")?;
|
||||
arms.push(self.parse_term()?);
|
||||
self.try_consume(";");
|
||||
self.consume("}")?;
|
||||
break;
|
||||
}
|
||||
// case num
|
||||
let val = self.parse_u32()?;
|
||||
if val != expected_num {
|
||||
return self.expected(&format!("'{}'", &expected_num.to_string()));
|
||||
}
|
||||
expected_num += 1;
|
||||
self.consume(":")?;
|
||||
arms.push(self.parse_term()?);
|
||||
self.try_consume(";");
|
||||
}
|
||||
let pred = Some(Name::new(format!("{}-{}", bnd.as_ref().unwrap(), arms.len() - 1)));
|
||||
return Ok(Term::Swt { arg: Box::new(arg), bnd, with, pred, arms });
|
||||
}
|
||||
|
||||
// Do (monadic block)
|
||||
@ -612,44 +644,6 @@ impl<'a> TermParser<'a> {
|
||||
let bod = self.parse_term()?;
|
||||
Ok((nam, vec![], bod))
|
||||
}
|
||||
|
||||
fn parse_switch(&mut self) -> ParseResult<Term> {
|
||||
let (bnd, arg, with) = self.parse_match_header()?;
|
||||
self.consume("{")?;
|
||||
let mut expected_num = 0;
|
||||
let mut arms = vec![];
|
||||
let mut to_continue = true;
|
||||
self.skip_trivia();
|
||||
while to_continue && !self.starts_with("}") {
|
||||
self.try_consume("|");
|
||||
self.skip_trivia();
|
||||
let Some(head) = self.peek_one() else { return self.expected("switch pattern") };
|
||||
match head {
|
||||
'_' => {
|
||||
if expected_num == 0 {
|
||||
return self.expected("0");
|
||||
} else {
|
||||
self.consume("_")?;
|
||||
to_continue = false;
|
||||
}
|
||||
}
|
||||
c if c.is_ascii_digit() => {
|
||||
let val = self.parse_u32()?;
|
||||
if val != expected_num {
|
||||
return self.expected(&expected_num.to_string());
|
||||
}
|
||||
}
|
||||
_ => return self.expected("switch pattern"),
|
||||
};
|
||||
self.consume(":")?;
|
||||
arms.push(self.parse_term()?);
|
||||
self.try_consume(";");
|
||||
expected_num += 1;
|
||||
}
|
||||
let pred = Some(Name::new(format!("{}-{}", bnd.as_ref().unwrap(), arms.len() - 1)));
|
||||
self.consume("}")?;
|
||||
Ok(Term::Swt { arg: Box::new(arg), bnd, with, pred, arms })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> for TermParser<'a> {
|
||||
|
@ -594,9 +594,11 @@ impl<'a> PyParser<'a> {
|
||||
indent.enter_level();
|
||||
|
||||
self.consume_indent_exactly(*indent)?;
|
||||
let ini_idx = *self.index();
|
||||
let (fst_case, fst_stmt, mut nxt_indent) = self.parse_switch_case(indent)?;
|
||||
let end_idx = *self.index();
|
||||
if fst_case != Some(0) {
|
||||
return self.expected("case 0");
|
||||
return self.expected_spanned("case 0", ini_idx, end_idx);
|
||||
}
|
||||
let mut arms = vec![fst_stmt];
|
||||
let mut should_continue = fst_case == Some(0);
|
||||
@ -640,10 +642,10 @@ impl<'a> PyParser<'a> {
|
||||
None
|
||||
}
|
||||
c if c.is_ascii_digit() => Some(self.parse_u32()?),
|
||||
_ => return self.expected("Number pattern"),
|
||||
_ => return self.expected("number or '_'"),
|
||||
}
|
||||
} else {
|
||||
return self.expected("Switch pattern")?;
|
||||
return self.expected("number or '_'")?;
|
||||
};
|
||||
|
||||
self.advance_trivia_inline();
|
||||
|
2
tests/golden_tests/compile_file/switch_incomplete.bend
Normal file
2
tests/golden_tests/compile_file/switch_incomplete.bend
Normal file
@ -0,0 +1,2 @@
|
||||
# This should be interpreted as a switch with a SUP argument that is missing its elements.
|
||||
main = switch {}
|
@ -4,6 +4,6 @@ input_file: tests/golden_tests/compile_file/switch_all_patterns.bend
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
In tests/golden_tests/compile_file/switch_all_patterns.bend :
|
||||
[1m- expected:[0m 0
|
||||
[1m- expected:[0m '0'
|
||||
[1m- detected:[0m
|
||||
[0m 7 | [4m[31m_[0m: x-1[0m
|
||||
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/switch_incomplete.bend
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
In tests/golden_tests/compile_file/switch_incomplete.bend :
|
||||
[1m- expected:[0m term
|
||||
[1m- detected:[0m
|
||||
[0m 2 | main = switch {[4m[31m}[0m
|
Loading…
Reference in New Issue
Block a user