impl interpret block return

This commit is contained in:
me 2025-12-17 00:31:14 +02:00
parent 5c2c9a4600
commit be65935def
2 changed files with 22 additions and 6 deletions

View file

@ -33,7 +33,6 @@ pub enum Expr {
},
Continue,
Break,
Return(Box<Expr>),
*/
}
@ -203,6 +202,8 @@ impl Record {
}
}
pub const UNIT: Expr = Expr::Value(Value::Record(Record(BTreeMap::new())));
#[derive(PartialEq, Debug, thiserror::Error)]
pub enum Error {
#[error("Label not found: {0:?}")]

View file

@ -27,19 +27,27 @@ pub fn run(
Ok(result)
}
enum StatementResult {
Result(ast::Value),
Return(ast::Value),
}
fn eval_statement(
expr_env: &mut Env,
state: &mut State,
statement: &ast::Statement,
) -> Result<ast::Value, Error> {
) -> Result<StatementResult, Error> {
match statement {
ast::Statement::Expr(expr) => eval_expr(expr_env, state, expr),
ast::Statement::Expr(expr) => eval_expr(expr_env, state, expr).map(StatementResult::Result),
ast::Statement::Let(ast::Definition { name, expr }) => {
let result = eval_expr(expr_env, state, expr)?;
expr_env.insert(name.clone(), result.clone());
Ok(result)
Ok(StatementResult::Result(result))
}
ast::Statement::Return(_) => todo!(),
ast::Statement::Return(expr) => match expr {
Some(expr) => eval_expr(expr_env, state, expr).map(StatementResult::Return),
None => eval_expr(expr_env, state, &ast::UNIT).map(StatementResult::Return),
},
}
}
@ -70,7 +78,14 @@ fn eval_expr(expr_env: &Env, state: &mut State, expr: &ast::Expr) -> Result<ast:
let mut block_env = expr_env.clone();
if let Some(last) = statements.iter().try_fold(None, |_, statement| {
let result = eval_statement(&mut block_env, state, statement)?;
Ok::<Option<ast::Value>, Error>(Some(result))
match result {
StatementResult::Result(result) => {
Ok::<Option<ast::Value>, Error>(Some(result))
}
StatementResult::Return(result) => {
return Ok::<Option<ast::Value>, Error>(Some(result));
}
}
})? {
Ok(last)
} else {