Move token matching into a macro
parent
8cdfbd61a9
commit
d497e19564
27
src/parse.rs
27
src/parse.rs
|
@ -41,6 +41,21 @@ pub fn parse_program<I: Iterator<Item = Token>, 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<I: Iterator<Item = Token>>(iter: &mut I) {
|
||||
for item in iter {
|
||||
|
@ -51,7 +66,7 @@ fn synchronize_to_next_statement<I: Iterator<Item = Token>>(iter: &mut I) {
|
|||
}
|
||||
|
||||
fn parse_statement<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Stmt, ParseError> {
|
||||
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<I: Iterator<Item = Token>, 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<I: Iterator<Item = Token>, F: Fn(&mut Peekable<I>) -> Result<Exp
|
|||
) -> Result<Expr, ParseError> {
|
||||
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<I: Iterator<Item = Token>, F: Fn(&mut Peekable<I>) -> Result<Exp
|
|||
}
|
||||
|
||||
fn parse_unary<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Expr, ParseError> {
|
||||
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<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Ex
|
|||
// consume the left paren
|
||||
iter.next();
|
||||
let expr = parse_expression(iter)?;
|
||||
if match_token(iter, &[TokenKind::RightParen]).is_some() {
|
||||
if match_token_kind!(iter, TokenKind::RightParen).is_some() {
|
||||
Ok(Expr::Grouping {
|
||||
expr: Box::new(expr),
|
||||
})
|
||||
|
@ -197,7 +212,7 @@ fn parse_primary<I: Iterator<Item = Token>>(iter: &mut Peekable<I>) -> Result<Ex
|
|||
}
|
||||
}
|
||||
|
||||
fn match_token<I: Iterator<Item = Token>>(
|
||||
fn match_token_kind_eq<I: Iterator<Item = Token>>(
|
||||
iter: &mut Peekable<I>,
|
||||
valid_kinds: &[TokenKind],
|
||||
) -> Option<Token> {
|
||||
|
|
Loading…
Reference in New Issue