refactor(tazjin/rlox): Refactor Compiler::consume into a macro
Making this function a macro instead makes it possible to match arbitrary token kinds, even the ones that carry data, without changing the syntax too much. Change-Id: I5cda9e36d6833bd9c259f7d4d8340db6e783b4e8 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2593 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
This commit is contained in:
parent
822e5ae57f
commit
b7b94335cc
1 changed files with 21 additions and 18 deletions
|
@ -153,6 +153,15 @@ fn rule_for<T: Iterator<Item = Token>>(token: &TokenKind) -> ParseRule<T> {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! consume {
|
||||
( $self:ident, $expected:pat, $err:expr ) => {
|
||||
match $self.current().kind {
|
||||
$expected => $self.advance(),
|
||||
_ => $self.error_at($self.current().line, $err),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<T: Iterator<Item = Token>> Compiler<T> {
|
||||
fn compile(&mut self) -> LoxResult<()> {
|
||||
self.advance();
|
||||
|
@ -193,9 +202,10 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
|||
|
||||
fn print_statement(&mut self) -> LoxResult<()> {
|
||||
self.expression()?;
|
||||
self.consume(
|
||||
&TokenKind::Semicolon,
|
||||
ErrorKind::ExpectedToken("Expected ';' after value"),
|
||||
consume!(
|
||||
self,
|
||||
TokenKind::Semicolon,
|
||||
ErrorKind::ExpectedToken("Expected ';' after value")
|
||||
);
|
||||
self.emit_op(OpCode::OpPrint);
|
||||
Ok(())
|
||||
|
@ -203,9 +213,10 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
|||
|
||||
fn expression_statement(&mut self) -> LoxResult<()> {
|
||||
self.expression()?;
|
||||
self.consume(
|
||||
&TokenKind::Semicolon,
|
||||
ErrorKind::ExpectedToken("Expected ';' after expression"),
|
||||
consume!(
|
||||
self,
|
||||
TokenKind::Semicolon,
|
||||
ErrorKind::ExpectedToken("Expected ';' after expression")
|
||||
);
|
||||
self.emit_op(OpCode::OpPop);
|
||||
Ok(())
|
||||
|
@ -222,9 +233,10 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
|||
|
||||
fn grouping(&mut self) -> LoxResult<()> {
|
||||
self.expression()?;
|
||||
self.consume(
|
||||
&TokenKind::RightParen,
|
||||
ErrorKind::ExpectedToken("Expected ')' after expression"),
|
||||
consume!(
|
||||
self,
|
||||
TokenKind::RightParen,
|
||||
ErrorKind::ExpectedToken("Expected ')' after expression")
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -334,15 +346,6 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn consume(&mut self, expected: &TokenKind, err: ErrorKind) {
|
||||
if self.current().kind == *expected {
|
||||
self.advance();
|
||||
return;
|
||||
}
|
||||
|
||||
self.error_at(self.current().line, err);
|
||||
}
|
||||
|
||||
fn current_chunk(&mut self) -> &mut Chunk {
|
||||
&mut self.chunk
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue