From 8915cd6fba9a7d449efc13543d7d0db4fca9d0d5 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Thu, 31 Dec 2020 18:05:58 +0300 Subject: [PATCH] feat(tazjin/rlox): Implement block parsing Change-Id: I1b7235ed71fa36120984a36f22cd564f59581352 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2303 Reviewed-by: tazjin Tested-by: BuildkiteCI --- users/tazjin/rlox/src/errors.rs | 1 + users/tazjin/rlox/src/interpreter.rs | 5 +++-- users/tazjin/rlox/src/parser.rs | 23 +++++++++++++++++++---- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/users/tazjin/rlox/src/errors.rs b/users/tazjin/rlox/src/errors.rs index 162b80dc0..10fc0a352 100644 --- a/users/tazjin/rlox/src/errors.rs +++ b/users/tazjin/rlox/src/errors.rs @@ -5,6 +5,7 @@ pub enum ErrorKind { UnmatchedParens, ExpectedExpression(String), ExpectedSemicolon, + ExpectedClosingBrace, ExpectedVariableName, TypeError(String), UndefinedVariable(String), diff --git a/users/tazjin/rlox/src/interpreter.rs b/users/tazjin/rlox/src/interpreter.rs index edaa5e28f..ba66faf79 100644 --- a/users/tazjin/rlox/src/interpreter.rs +++ b/users/tazjin/rlox/src/interpreter.rs @@ -1,5 +1,5 @@ use crate::errors::{Error, ErrorKind}; -use crate::parser::{self, Expr, Literal, Program, Statement}; +use crate::parser::{self, Block, Expr, Literal, Statement}; use crate::scanner::{self, TokenKind}; use std::collections::HashMap; use std::rc::Rc; @@ -78,7 +78,7 @@ pub struct Interpreter { } impl Interpreter { - pub fn interpret<'a>(&mut self, program: &Program<'a>) -> Result<(), Error> { + pub fn interpret<'a>(&mut self, program: &Block<'a>) -> Result<(), Error> { for stmt in program { self.interpret_stmt(stmt)?; } @@ -96,6 +96,7 @@ impl Interpreter { println!("{:?}", result) } Statement::Var(var) => return self.interpret_var(var), + Statement::Block(_) => unimplemented!(), } Ok(()) diff --git a/users/tazjin/rlox/src/parser.rs b/users/tazjin/rlox/src/parser.rs index 1a271fd0a..94ad2f4c4 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>, } +pub type Block<'a> = Vec>; + #[derive(Debug)] pub enum Statement<'a> { Expr(Expr<'a>), Print(Expr<'a>), Var(Var<'a>), + Block(Block<'a>), } -pub type Program<'a> = Vec>; - // 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>) -> Result, Vec> { +pub fn parse<'a>(tokens: Vec>) -> Result, Vec> { let mut parser = Parser { tokens, current: 0 }; - let mut program: Program<'a> = vec![]; + let mut program: Block<'a> = vec![]; let mut errors: Vec = vec![]; while !parser.is_at_end() {