diff options
Diffstat (limited to 'users/tazjin/rlox')
-rw-r--r-- | users/tazjin/rlox/src/errors.rs | 1 | ||||
-rw-r--r-- | users/tazjin/rlox/src/interpreter.rs | 5 | ||||
-rw-r--r-- | 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 162b80dc00d4..10fc0a352990 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 edaa5e28f234..ba66faf79b16 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 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() { |