diff --git a/loxGrammar.bnf b/loxGrammar.bnf index b587532..02d591a 100644 --- a/loxGrammar.bnf +++ b/loxGrammar.bnf @@ -48,6 +48,7 @@ | | | + | ::= "print " ";" @@ -64,6 +65,8 @@ ? ";" ? ")" + ::= "return" ? ";" + ::= ::= "=" diff --git a/src/interpreter.rs b/src/interpreter.rs index 6101c43..d2c4d88 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -133,6 +133,9 @@ impl Interpreter { }, ); } + Statement::Return { keyword, value } => { + todo!() + } }; } diff --git a/src/parser.rs b/src/parser.rs index 246d1da..7163f81 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -34,10 +34,7 @@ pub struct Parser<'a> { impl<'a> Parser<'a> { pub fn new(tokens: &'a Vec) -> Self { - Self { - tokens, - current: 0, - } + Self { tokens, current: 0 } } // region grammar components @@ -160,6 +157,10 @@ impl<'a> Parser<'a> { return self.print_statement(); } + if self.match_tokens(vec![Return]) { + return self.return_statement(); + } + self.expression_statement() } @@ -248,20 +249,6 @@ impl<'a> Parser<'a> { Ok(body) } - fn print_statement(&mut self) -> Result { - let expression = self.expression()?; - self.consume(Semicolon, "Expected ';' after the value.")?; - - Ok(Statement::Print { expression }) - } - - fn expression_statement(&mut self) -> Result { - let expression = self.expression()?; - self.consume(Semicolon, "Expected ';' after the value.")?; - - Ok(Statement::Expression { expression }) - } - fn if_statement(&mut self) -> Result { self.consume(LeftParen, "Expected '(' after 'if'")?; let condition = self.expression()?; @@ -284,6 +271,34 @@ impl<'a> Parser<'a> { }) } + fn print_statement(&mut self) -> Result { + let expression = self.expression()?; + self.consume(Semicolon, "Expected ';' after the value.")?; + + Ok(Statement::Print { expression }) + } + + fn return_statement(&mut self) -> Result { + let keyword = self.previous(); + + let mut value = None; + + if !self.check(Semicolon) { + value = Some(self.expression()?); + } + + self.consume(Semicolon, "Expected ';' after return value")?; + + Ok(Statement::Return { keyword, value }) + } + + fn expression_statement(&mut self) -> Result { + let expression = self.expression()?; + self.consume(Semicolon, "Expected ';' after the value.")?; + + Ok(Statement::Expression { expression }) + } + pub fn expression(&mut self) -> Result { self.assignment() } diff --git a/src/statement.rs b/src/statement.rs index 2159eb3..40c31cb 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -36,4 +36,9 @@ pub enum Statement { parameters: Vec, body: Vec, }, + + Return { + keyword: Token, + value: Option, + }, }