Add "return" statement
Functions may now be exited by returning a value or no value. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -24,6 +24,7 @@ impl<V: Visit<Out=()>> DefaultAccept<V> for Body {
|
||||
pub enum Stmt {
|
||||
Expr(Expr),
|
||||
Assign(AssignStmt),
|
||||
Return(ReturnStmt),
|
||||
}
|
||||
|
||||
//
|
||||
@@ -43,6 +44,7 @@ impl<V: Visit> DefaultAccept<V> for Stmt {
|
||||
match self {
|
||||
Stmt::Expr(e) => e.accept(visitor),
|
||||
Stmt::Assign(a) => a.accept(visitor),
|
||||
Stmt::Return(r) => r.accept(visitor),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,6 +101,29 @@ impl<V: Visit<Out=()>> DefaultAccept<V> for LhsExpr {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// struct ReturnStmt
|
||||
//
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ReturnStmt {
|
||||
pub expr: Option<Expr>,
|
||||
}
|
||||
|
||||
impl<V: Visit> Accept<V> for ReturnStmt {
|
||||
fn accept(&self, visitor: &mut V) -> V::Out {
|
||||
visitor.visit_return_stmt(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Visit<Out=()>> DefaultAccept<V> for ReturnStmt {
|
||||
fn default_accept(&self, visitor: &mut V) -> V::Out {
|
||||
if let Some(expr) = self.expr.as_ref() {
|
||||
expr.accept(visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// struct Expr
|
||||
//
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
%%
|
||||
fn "fn"
|
||||
return "return"
|
||||
|
||||
[\r\n;]+ "EOL"
|
||||
[a-zA-Z_][a-zA-Z0-9_]* "IDENT"
|
||||
|
||||
@@ -22,6 +22,7 @@ Body -> Result<Vec<Stmt>>:
|
||||
Stmt -> Result<Stmt>:
|
||||
Expr { Ok(Stmt::Expr($1?)) }
|
||||
| Assign { Ok(Stmt::Assign($1?)) }
|
||||
| Return { Ok(Stmt::Return($1?)) }
|
||||
;
|
||||
|
||||
Assign -> Result<AssignStmt>:
|
||||
@@ -41,6 +42,11 @@ LhsExpr -> Result<LhsExpr>:
|
||||
}
|
||||
;
|
||||
|
||||
Return -> Result<ReturnStmt>:
|
||||
'return' Expr { Ok(ReturnStmt { expr: Some($2?), }) }
|
||||
| 'return' { Ok(ReturnStmt { expr: None, }) }
|
||||
;
|
||||
|
||||
Expr -> Result<Expr>: BinExpr { $1 };
|
||||
|
||||
BinExpr -> Result<Expr>:
|
||||
|
||||
@@ -14,6 +14,7 @@ pub trait Visit {
|
||||
fn visit_body(&mut self, body: &Body) -> Self::Out;
|
||||
fn visit_stmt(&mut self, stmt: &Stmt) -> Self::Out;
|
||||
fn visit_assign_stmt(&mut self, assign: &AssignStmt) -> Self::Out;
|
||||
fn visit_return_stmt(&mut self, ret: &ReturnStmt) -> Self::Out;
|
||||
fn visit_lhs_expr(&mut self, lhs_expr: &LhsExpr) -> Self::Out;
|
||||
fn visit_expr(&mut self, expr: &Expr) -> Self::Out;
|
||||
fn visit_bin_expr(&mut self, expr: &BinExpr) -> Self::Out;
|
||||
@@ -31,6 +32,7 @@ copy/paste of default_accepts
|
||||
fn visit_body(&mut self, body: &Body) -> Self::Out { DefaultAccept::default_accept(body, self); }
|
||||
fn visit_stmt(&mut self, stmt: &Stmt) -> Self::Out { DefaultAccept::default_accept(stmt, self); }
|
||||
fn visit_assign_stmt(&mut self, assign: &AssignStmt) -> Self::Out { DefaultAccept::default_accept(assign, self); }
|
||||
fn visit_return_stmt(&mut self, ret: &ReturnStmt) -> Self::Out { DefaultAccept::default_accept(ret, self); }
|
||||
fn visit_lhs_expr(&mut self, lhs_expr: &LhsExpr) -> Self::Out { DefaultAccept::default_accept(lhs_expr, self); }
|
||||
fn visit_expr(&mut self, expr: &Expr) -> Self::Out { DefaultAccept::default_accept(expr, self); }
|
||||
fn visit_bin_expr(&mut self, expr: &BinExpr) -> Self::Out { DefaultAccept::default_accept(expr, self); }
|
||||
|
||||
Reference in New Issue
Block a user