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> {
|
impl<T: Iterator<Item = Token>> Compiler<T> {
|
||||||
fn compile(&mut self) -> LoxResult<()> {
|
fn compile(&mut self) -> LoxResult<()> {
|
||||||
self.advance();
|
self.advance();
|
||||||
|
@ -193,9 +202,10 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
||||||
|
|
||||||
fn print_statement(&mut self) -> LoxResult<()> {
|
fn print_statement(&mut self) -> LoxResult<()> {
|
||||||
self.expression()?;
|
self.expression()?;
|
||||||
self.consume(
|
consume!(
|
||||||
&TokenKind::Semicolon,
|
self,
|
||||||
ErrorKind::ExpectedToken("Expected ';' after value"),
|
TokenKind::Semicolon,
|
||||||
|
ErrorKind::ExpectedToken("Expected ';' after value")
|
||||||
);
|
);
|
||||||
self.emit_op(OpCode::OpPrint);
|
self.emit_op(OpCode::OpPrint);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -203,9 +213,10 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
||||||
|
|
||||||
fn expression_statement(&mut self) -> LoxResult<()> {
|
fn expression_statement(&mut self) -> LoxResult<()> {
|
||||||
self.expression()?;
|
self.expression()?;
|
||||||
self.consume(
|
consume!(
|
||||||
&TokenKind::Semicolon,
|
self,
|
||||||
ErrorKind::ExpectedToken("Expected ';' after expression"),
|
TokenKind::Semicolon,
|
||||||
|
ErrorKind::ExpectedToken("Expected ';' after expression")
|
||||||
);
|
);
|
||||||
self.emit_op(OpCode::OpPop);
|
self.emit_op(OpCode::OpPop);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -222,9 +233,10 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
||||||
|
|
||||||
fn grouping(&mut self) -> LoxResult<()> {
|
fn grouping(&mut self) -> LoxResult<()> {
|
||||||
self.expression()?;
|
self.expression()?;
|
||||||
self.consume(
|
consume!(
|
||||||
&TokenKind::RightParen,
|
self,
|
||||||
ErrorKind::ExpectedToken("Expected ')' after expression"),
|
TokenKind::RightParen,
|
||||||
|
ErrorKind::ExpectedToken("Expected ')' after expression")
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -334,15 +346,6 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
||||||
Ok(())
|
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 {
|
fn current_chunk(&mut self) -> &mut Chunk {
|
||||||
&mut self.chunk
|
&mut self.chunk
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue