Add last-expression-return-value to functions as well
We did it for if and block statements, now functions too support the last expression being its return value. If there isn't an expression (e.g. an assign statement) we just return `nil`. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// This is an auto-generated file. Any changes made to this file may be overwritten.
|
// This is an auto-generated file. Any changes made to this file may be overwritten.
|
||||||
// This file was created at: 2024-10-21 15:09:43
|
// This file was created at: 2024-10-21 15:50:12
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
@@ -127,7 +127,7 @@ pub struct FunctionExpr {
|
|||||||
pub lparen: Token,
|
pub lparen: Token,
|
||||||
pub params: Vec<(Token, Option<ExprP>)>,
|
pub params: Vec<(Token, Option<ExprP>)>,
|
||||||
pub return_type: Option<ExprP>,
|
pub return_type: Option<ExprP>,
|
||||||
pub body: Vec<StmtP>,
|
pub body: BlockExpr,
|
||||||
pub rbrace: Token,
|
pub rbrace: Token,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -943,13 +943,18 @@ impl ExprVisitor for Compiler<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compile body
|
// compile body
|
||||||
for stmt in &expr.body {
|
for stmt in &expr.body.stmts {
|
||||||
self.compile_stmt(stmt)?;
|
self.compile_stmt(stmt)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// always end with a "return nil"
|
// compile the last expression in the block and compile that as the return value
|
||||||
|
if let Some(expr) = expr.body.return_expr.as_ref() {
|
||||||
|
self.compile_expr(expr)?;
|
||||||
|
} else {
|
||||||
|
// otherwise end with a "return nil"
|
||||||
let nil = self.insert_constant(Nil::create())?;
|
let nil = self.insert_constant(Nil::create())?;
|
||||||
self.emit(end_line, Op::PushConstant(nil));
|
self.emit(end_line, Op::PushConstant(nil));
|
||||||
|
}
|
||||||
self.emit(end_line, Op::Return);
|
self.emit(end_line, Op::Return);
|
||||||
|
|
||||||
self.end_scope(end_line);
|
self.end_scope(end_line);
|
||||||
|
|||||||
@@ -165,11 +165,14 @@ pub(super) struct LocalAssignCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LocalAssignCollector {
|
impl LocalAssignCollector {
|
||||||
pub fn collect(body: &Vec<StmtP>) -> HashSet<String> {
|
pub fn collect(block: &BlockExpr) -> HashSet<String> {
|
||||||
let mut collector = Self::default();
|
let mut collector = Self::default();
|
||||||
for stmt in body {
|
for stmt in &block.stmts {
|
||||||
stmt.accept(&mut collector).unwrap();
|
stmt.accept(&mut collector).unwrap();
|
||||||
}
|
}
|
||||||
|
if let Some(expr) = block.return_expr.as_ref() {
|
||||||
|
expr.accept(&mut collector).unwrap();
|
||||||
|
}
|
||||||
collector.names
|
collector.names
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -319,11 +322,14 @@ pub(super) struct LocalNameCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LocalNameCollector {
|
impl LocalNameCollector {
|
||||||
pub fn collect(body: &Vec<StmtP>) -> HashSet<String> {
|
pub fn collect(block: &BlockExpr) -> HashSet<String> {
|
||||||
let mut collector = Self::default();
|
let mut collector = Self::default();
|
||||||
for stmt in body {
|
for stmt in &block.stmts {
|
||||||
stmt.accept(&mut collector).unwrap();
|
stmt.accept(&mut collector).unwrap();
|
||||||
}
|
}
|
||||||
|
if let Some(expr) = block.return_expr.as_ref() {
|
||||||
|
expr.accept(&mut collector).unwrap();
|
||||||
|
}
|
||||||
collector.names
|
collector.names
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -995,7 +995,7 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.expect("expect '{' after function signature", TokenKind::LBrace)?;
|
self.expect("expect '{' after function signature", TokenKind::LBrace)?;
|
||||||
let body = self.block()?;
|
let body = self.block_expr()?;
|
||||||
let rbrace = self.prev.clone().unwrap();
|
let rbrace = self.prev.clone().unwrap();
|
||||||
|
|
||||||
Ok(Box::new(FunctionExpr {
|
Ok(Box::new(FunctionExpr {
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ GENERATE = [
|
|||||||
"lparen: Token",
|
"lparen: Token",
|
||||||
"params: Vec<(Token, Option<ExprP>)>",
|
"params: Vec<(Token, Option<ExprP>)>",
|
||||||
"return_type: Option<ExprP>",
|
"return_type: Option<ExprP>",
|
||||||
"body: Vec<StmtP>",
|
"body: BlockExpr",
|
||||||
"rbrace: Token",
|
"rbrace: Token",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user