diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-05-21 23:58:34 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-05-21 23:58:34 +0200 |
| commit | a175d37ff245bca5e2b6f4b1d150d425b9e83e1c (patch) | |
| tree | 2c36a83a46a12f39f06ff29179a615f05f31a2ce | |
| parent | 6472c1e425013021acb19f77c29f1896e202482e (diff) | |
Refactor parser a bit
| -rw-r--r-- | src/parse/parser.rs | 59 |
1 files changed, 27 insertions, 32 deletions
diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 5d390bc1..729d0a8d 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -51,7 +51,7 @@ pub enum Group { Subheader, /// A group ended by a semicolon or a line break: `;`, `\n`. Stmt, - /// A group for a single expression. Not ended by something specific. + /// A group for a single expression, ended by a line break. Expr, } @@ -330,25 +330,23 @@ impl<'s> Parser<'s> { scanner } - /// Move to the next token, skipping whitespace and comments in code mode. + /// Move to the next token. fn bump(&mut self) { self.last_end = self.tokens.pos(); self.next_start = self.tokens.pos(); self.next = self.tokens.next(); - match self.tokens.mode() { - TokenMode::Markup => {} - TokenMode::Code => loop { - match self.next { - Some(Token::Space(n)) if n < 1 || !self.in_line_group() => {} - Some(Token::LineComment(_)) => {} - Some(Token::BlockComment(_)) => {} - _ => break, - } - + if self.tokens.mode() == TokenMode::Code { + // Skip whitespace and comments. + while match self.next { + Some(Token::Space(n)) => n < 1 || !self.stop_at_newline(), + Some(Token::LineComment(_)) => true, + Some(Token::BlockComment(_)) => true, + _ => false, + } { self.next_start = self.tokens.pos(); self.next = self.tokens.next(); - }, + } } self.repeek(); @@ -362,31 +360,28 @@ impl<'s> Parser<'s> { None => return, }; - let inside = |x| self.kinds().any(|k| k == x); - match token { - Token::RightParen if inside(Group::Paren) => {} - Token::RightBracket if inside(Group::Bracket) => {} - Token::RightBrace if inside(Group::Brace) => {} - Token::Semicolon if inside(Group::Stmt) => {} - Token::Pipe if inside(Group::Subheader) => {} - Token::Space(n) if n >= 1 && self.in_line_group() => {} - _ => return, + if match token { + Token::RightParen => self.inside(Group::Paren), + Token::RightBracket => self.inside(Group::Bracket), + Token::RightBrace => self.inside(Group::Brace), + Token::Semicolon => self.inside(Group::Stmt), + Token::Pipe => self.inside(Group::Subheader), + Token::Space(n) => n >= 1 && self.stop_at_newline(), + _ => false, + } { + self.peeked = None; } - - self.peeked = None; } /// Whether the active group ends at a newline. - fn in_line_group(&self) -> bool { - matches!( - self.kinds().next_back(), - Some(Group::Stmt) | Some(Group::Expr) - ) + fn stop_at_newline(&self) -> bool { + let active = self.groups.last().map(|group| group.kind); + matches!(active, Some(Group::Stmt) | Some(Group::Expr)) } - /// The outer groups. - fn kinds(&self) -> impl DoubleEndedIterator<Item = Group> + '_ { - self.groups.iter().map(|group| group.kind) + /// Whether we are inside the given group. + fn inside(&self, kind: Group) -> bool { + self.groups.iter().any(|g| g.kind == kind) } } |
