From d497e1956428e022555f6c86e48faa970099ac19 Mon Sep 17 00:00:00 2001 From: Nick Krichevsky Date: Tue, 21 May 2024 15:23:53 -0400 Subject: [PATCH] Move token matching into a macro --- src/parse.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/parse.rs b/src/parse.rs index ef6c165..c4e50ae 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -41,6 +41,21 @@ pub fn parse_program, F: FnMut(ScriptError)>( statements } +macro_rules! match_token_kind { + ($tokens_peekable: expr, $($p:pat),+) => {{ + match $tokens_peekable.peek().map(|token| token.kind()) { + $( + Some($p) => { + // consume the peeked token + let token = $tokens_peekable.next().unwrap(); + Some(token) + } + )+ + _ => None + } + }}; +} + // To be used later? fn synchronize_to_next_statement>(iter: &mut I) { for item in iter { @@ -51,7 +66,7 @@ fn synchronize_to_next_statement>(iter: &mut I) { } fn parse_statement>(iter: &mut Peekable) -> Result { - if match_token(iter, &[TokenKind::Print]).is_some() { + if match_token_kind!(iter, TokenKind::Print).is_some() { parse_statement_containing_expression(iter, |expression| Stmt::Print { expression }) } else { parse_statement_containing_expression(iter, |expression| Stmt::Expression { expression }) @@ -65,7 +80,7 @@ fn parse_statement_containing_expression, F: Fn(Expr) // Snatch the next token before we parse it, so we have line information let next_token_line = iter.peek().map(Token::line); let expression = parse_expression(iter)?; - if match_token(iter, &[TokenKind::SemiColon]).is_some() { + if match_token_kind!(iter, TokenKind::SemiColon).is_some() { Ok(make_statement(expression)) } else { Err(ParseError { @@ -117,7 +132,7 @@ fn parse_binary, F: Fn(&mut Peekable) -> Result Result { let mut expr = parse_operand(iter)?; - while let Some(token) = match_token(iter, valid_operators) { + while let Some(token) = match_token_kind_eq(iter, valid_operators) { let operator = token; let right = parse_operand(iter)?; expr = Expr::Binary { @@ -131,7 +146,7 @@ fn parse_binary, F: Fn(&mut Peekable) -> Result>(iter: &mut Peekable) -> Result { - if let Some(token) = match_token(iter, &[TokenKind::Bang, TokenKind::Minus]) { + if let Some(token) = match_token_kind!(iter, TokenKind::Bang, TokenKind::Minus) { let operator = token; let right = parse_unary(iter)?; Ok(Expr::Unary { @@ -178,7 +193,7 @@ fn parse_primary>(iter: &mut Peekable) -> Result>(iter: &mut Peekable) -> Result>( +fn match_token_kind_eq>( iter: &mut Peekable, valid_kinds: &[TokenKind], ) -> Option {