diff options
Diffstat (limited to 'users/tazjin')
-rw-r--r-- | users/tazjin/rlox/src/interpreter.rs | 28 | ||||
-rw-r--r-- | users/tazjin/rlox/src/parser.rs | 23 |
2 files changed, 36 insertions, 15 deletions
diff --git a/users/tazjin/rlox/src/interpreter.rs b/users/tazjin/rlox/src/interpreter.rs index c68101cf68a6..5e43e075b03c 100644 --- a/users/tazjin/rlox/src/interpreter.rs +++ b/users/tazjin/rlox/src/interpreter.rs @@ -1,5 +1,5 @@ use crate::errors::{report, Error, ErrorKind}; -use crate::parser::{self, Expr, Literal, Program, Statement}; +use crate::parser::{self, Declaration, Expr, Literal, Program, Statement}; use crate::scanner::{self, TokenKind}; // Run some Lox code and print it to stdout @@ -104,16 +104,24 @@ fn eval<'a>(expr: &Expr<'a>) -> Result<Literal, Error> { } } +fn run_stmt<'a>(stmt: &Statement<'a>) -> Result<(), Error> { + match stmt { + Statement::Expr(expr) => { + eval(expr)?; + } + Statement::Print(expr) => { + let result = eval(expr)?; + println!("{:?}", result) + } + } + + Ok(()) +} + fn run_program<'a>(program: &Program<'a>) -> Result<(), Error> { - for stmt in program { - match stmt { - Statement::Expr(expr) => { - eval(expr)?; - } - Statement::Print(expr) => { - let result = eval(expr)?; - println!("{:?}", result) - } + for decl in program { + match decl { + Declaration::Stmt(stmt) => run_stmt(stmt)?, } } diff --git a/users/tazjin/rlox/src/parser.rs b/users/tazjin/rlox/src/parser.rs index d7155fff10a7..91000db9dd90 100644 --- a/users/tazjin/rlox/src/parser.rs +++ b/users/tazjin/rlox/src/parser.rs @@ -48,12 +48,20 @@ pub enum Statement<'a> { Print(Expr<'a>), } -pub type Program<'a> = Vec<Statement<'a>>; +#[derive(Debug)] +pub enum Declaration<'a> { + Stmt(Statement<'a>), +} + +pub type Program<'a> = Vec<Declaration<'a>>; // Parser /* -program → statement* EOF ; +program → declaration* EOF ; + +declaration → varDecl + | statement ; statement → exprStmt | printStmt ; @@ -79,10 +87,15 @@ struct Parser<'a> { type ExprResult<'a> = Result<Expr<'a>, Error>; type StmtResult<'a> = Result<Statement<'a>, Error>; +type DeclResult<'a> = Result<Declaration<'a>, Error>; impl<'a> Parser<'a> { // recursive-descent parser functions + fn declaration(&mut self) -> DeclResult<'a> { + Ok(Declaration::Stmt(self.statement()?)) + } + fn statement(&mut self) -> StmtResult<'a> { if self.match_token(&[TokenKind::Print]) { self.print_statement() @@ -274,13 +287,13 @@ pub fn parse<'a>(tokens: Vec<Token<'a>>) -> Result<Program<'a>, Vec<Error>> { let mut errors: Vec<Error> = vec![]; while !parser.is_at_end() { - match parser.statement() { + match parser.declaration() { Err(err) => { errors.push(err); parser.synchronise(); } - Ok(stmt) => { - program.push(stmt); + Ok(decl) => { + program.push(decl); } } } |