diff options
author | Vincent Ambo <mail@tazj.in> | 2020-12-31T15·05+0300 |
---|---|---|
committer | tazjin <mail@tazj.in> | 2020-12-31T15·33+0000 |
commit | 8915cd6fba9a7d449efc13543d7d0db4fca9d0d5 (patch) | |
tree | c915b329ffc83c240c350d92bbb03c7ea3de237f /users/tazjin/rlox/src/parser.rs | |
parent | 3c979acdf367ea18ec2248bbe8e0befa15966bb4 (diff) |
feat(tazjin/rlox): Implement block parsing r/2037
Change-Id: I1b7235ed71fa36120984a36f22cd564f59581352 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2303 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
Diffstat (limited to 'users/tazjin/rlox/src/parser.rs')
-rw-r--r-- | users/tazjin/rlox/src/parser.rs | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/users/tazjin/rlox/src/parser.rs b/users/tazjin/rlox/src/parser.rs index 1a271fd0ae2a..94ad2f4c474b 100644 --- a/users/tazjin/rlox/src/parser.rs +++ b/users/tazjin/rlox/src/parser.rs @@ -62,15 +62,16 @@ pub struct Var<'a> { pub initialiser: Option<Expr<'a>>, } +pub type Block<'a> = Vec<Statement<'a>>; + #[derive(Debug)] pub enum Statement<'a> { Expr(Expr<'a>), Print(Expr<'a>), Var(Var<'a>), + Block(Block<'a>), } -pub type Program<'a> = Vec<Statement<'a>>; - // Parser /* @@ -143,6 +144,8 @@ impl<'a> Parser<'a> { fn statement(&mut self) -> StmtResult<'a> { if self.match_token(&[TokenKind::Print]) { self.print_statement() + } else if self.match_token(&[TokenKind::LeftBrace]) { + self.block_statement() } else { self.expr_statement() } @@ -154,6 +157,18 @@ impl<'a> Parser<'a> { Ok(Statement::Print(expr)) } + fn block_statement(&mut self) -> StmtResult<'a> { + let mut block: Block<'a> = vec![]; + + while !self.check_token(&TokenKind::RightBrace) && !self.is_at_end() { + block.push(self.declaration()?); + } + + self.consume(&TokenKind::RightBrace, ErrorKind::ExpectedClosingBrace)?; + + Ok(Statement::Block(block)) + } + fn expr_statement(&mut self) -> StmtResult<'a> { let expr = self.expression()?; self.consume(&TokenKind::Semicolon, ErrorKind::ExpectedSemicolon)?; @@ -349,9 +364,9 @@ impl<'a> Parser<'a> { } } -pub fn parse<'a>(tokens: Vec<Token<'a>>) -> Result<Program<'a>, Vec<Error>> { +pub fn parse<'a>(tokens: Vec<Token<'a>>) -> Result<Block<'a>, Vec<Error>> { let mut parser = Parser { tokens, current: 0 }; - let mut program: Program<'a> = vec![]; + let mut program: Block<'a> = vec![]; let mut errors: Vec<Error> = vec![]; while !parser.is_at_end() { |