feat(tazjin/rlox): Implement early return from functions
In the book this is implemented via exceptions as control flow, and I'm sticking somewhat closely to that by doing it via an error variant. Change-Id: I9c7b84d6bb28265ab94021ea681df84f16a53da2 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2395 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
This commit is contained in:
parent
20a6cfeee2
commit
39439d59e8
3 changed files with 47 additions and 1 deletions
|
|
@ -79,6 +79,11 @@ pub struct Var {
|
|||
pub initialiser: Option<Expr>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Return {
|
||||
pub value: Expr,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct If {
|
||||
pub condition: Expr,
|
||||
|
|
@ -110,6 +115,7 @@ pub enum Statement {
|
|||
If(If),
|
||||
While(While),
|
||||
Function(Rc<Function>),
|
||||
Return(Return),
|
||||
}
|
||||
|
||||
// Parser
|
||||
|
|
@ -130,6 +136,7 @@ statement → exprStmt
|
|||
| forStmt
|
||||
| ifStmt
|
||||
| printStmt
|
||||
| returnStmt
|
||||
| whileStmt
|
||||
| block ;
|
||||
|
||||
|
|
@ -137,6 +144,8 @@ forStmt → "for" "(" ( varDecl | exprStmt | ";" )
|
|||
expression? ";"
|
||||
expression? ")" statement ;
|
||||
|
||||
returnStmt → "return" expression? ";" ;
|
||||
|
||||
whileStmt → "while" "(" expression ")" statement ;
|
||||
|
||||
exprStmt → expression ";" ;
|
||||
|
|
@ -256,6 +265,8 @@ impl Parser {
|
|||
self.while_statement()
|
||||
} else if self.match_token(&TokenKind::For) {
|
||||
self.for_statement()
|
||||
} else if self.match_token(&TokenKind::Return) {
|
||||
self.return_statement()
|
||||
} else {
|
||||
self.expr_statement()
|
||||
}
|
||||
|
|
@ -379,6 +390,12 @@ impl Parser {
|
|||
Ok(body)
|
||||
}
|
||||
|
||||
fn return_statement(&mut self) -> StmtResult {
|
||||
let value = self.expression()?;
|
||||
self.consume(&TokenKind::Semicolon, ErrorKind::ExpectedSemicolon)?;
|
||||
Ok(Statement::Return(Return { value }))
|
||||
}
|
||||
|
||||
fn expr_statement(&mut self) -> StmtResult {
|
||||
let expr = self.expression()?;
|
||||
self.consume(&TokenKind::Semicolon, ErrorKind::ExpectedSemicolon)?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue