about summary refs log tree commit diff
path: root/users/tazjin/rlox/src/parser.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2020-12-31T15·05+0300
committertazjin <mail@tazj.in>2020-12-31T15·33+0000
commit8915cd6fba9a7d449efc13543d7d0db4fca9d0d5 (patch)
treec915b329ffc83c240c350d92bbb03c7ea3de237f /users/tazjin/rlox/src/parser.rs
parent3c979acdf367ea18ec2248bbe8e0befa15966bb4 (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.rs23
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() {