Skip to content

Commit

Permalink
Improve pattern parsing and rule parsing error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
imaqtkatt committed Jul 26, 2024
1 parent 1be093b commit 646011e
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 14 deletions.
42 changes: 30 additions & 12 deletions src/fun/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,24 +326,28 @@ impl<'a> TermParser<'a> {
Ok(vec![import])
}

fn parse_rule(&mut self) -> ParseResult<(Name, Rule)> {
// (name pat*) = term
// name pat* = term
let (name, pats) = if self.try_consume_exactly("(") {
fn parse_rule_lhs(&mut self) -> ParseResult<(Name, Vec<Pattern>)> {
if self.try_consume_exactly("(") {
self.skip_trivia();
let name = self.labelled(|p| p.parse_top_level_name(), "function name")?;
let pats = self.list_like(|p| p.parse_pattern(false), "", ")", "", false, 0)?;
self.consume("=")?;
(name, pats)
Ok((name, pats))
} else {
let name = self.labelled(|p| p.parse_top_level_name(), "top-level definition")?;
let mut pats = vec![];
while !self.try_consume("=") {
self.skip_trivia();
while !self.starts_with("=") {
pats.push(self.parse_pattern(false)?);
self.skip_trivia();
}
(name, pats)
};
Ok((name, pats))
}
}

fn parse_rule(&mut self) -> ParseResult<(Name, Rule)> {
let (name, pats) = self.parse_rule_lhs()?;

self.consume("=")?;

let body = self.parse_term()?;

Expand Down Expand Up @@ -425,9 +429,23 @@ impl<'a> TermParser<'a> {
}

// Var
unexpected_tag(self)?;
let nam = self.labelled(|p| p.parse_name_or_era(), "pattern-matching pattern")?;
Ok(Pattern::Var(nam))
if self.starts_with("*")
|| self
.peek_one()
.is_some_and(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.' || c == '-' || c == '/')
{
unexpected_tag(self)?;
let nam = self.parse_name_or_era()?;
return Ok(Pattern::Var(nam));
}

let ini_idx = *self.index();
while !(self.is_eof() || self.starts_with("=")) {
self.advance_one();
}
let cur_idx = *self.index();

self.expected_spanned("pattern or '='", ini_idx..cur_idx)
})
}

Expand Down
1 change: 1 addition & 0 deletions tests/golden_tests/parse_file/strange_pattern.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
main & = (a b c)
4 changes: 2 additions & 2 deletions tests/snapshots/compile_file__just_a_name.bend.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ input_file: tests/golden_tests/compile_file/just_a_name.bend
---
Errors:
In tests/golden_tests/compile_file/just_a_name.bend :
[1m- expected:[0m pattern-matching pattern
[1m- expected:[0m pattern or '='
- detected: end of input
[0m 1 | asdf[4m[31m [0m
[0m 1 | asdf[0m
9 changes: 9 additions & 0 deletions tests/snapshots/parse_file__strange_pattern.bend.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/parse_file/strange_pattern.bend
---
Errors:
In tests/golden_tests/parse_file/strange_pattern.bend :
- expected: pattern or '='
- detected:
 1 | main & = (a b c)

0 comments on commit 646011e

Please sign in to comment.