aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2021-11-14 22:40:36 +0100
committerMel <einebeere@gmail.com>2021-11-14 22:40:36 +0100
commitc891369f0ce69b2fe78846cae1202899595354b7 (patch)
treed2102071b57e0aa353b5444a7c2c2f0481be3d0f
parent2a3ab5c161ac98cb3c6326173e5ed78089a9ed68 (diff)
downloadrabbithole-c891369f0ce69b2fe78846cae1202899595354b7.tar.zst
rabbithole-c891369f0ce69b2fe78846cae1202899595354b7.zip
Add return statements
-rw-r--r--src/interpret/value.rs9
-rw-r--r--src/interpret/walker.rs9
2 files changed, 14 insertions, 4 deletions
diff --git a/src/interpret/value.rs b/src/interpret/value.rs
index dd8ad54..d108c68 100644
--- a/src/interpret/value.rs
+++ b/src/interpret/value.rs
@@ -261,10 +261,13 @@ impl Value {
// Yes, we create a new walker for every function call,
// it's *way* easier that way.
let mut walker = Walker::new_with_scope(scope);
- let result =
- walker.walk_expression(&Expression::Block(Box::new(called.node.body.clone())))?;
+ let result = walker.walk_expression(&Expression::Block(Box::new(called.node.body.clone())));
- Ok(result)
+ if let Err(WalkerError::Return(returned)) = result {
+ Ok(returned)
+ } else {
+ result
+ }
}
}
diff --git a/src/interpret/walker.rs b/src/interpret/walker.rs
index 3feed6f..15ab37d 100644
--- a/src/interpret/walker.rs
+++ b/src/interpret/walker.rs
@@ -51,7 +51,11 @@ impl Walker {
println!("{}", result);
None
}
- Statement::Return(node) => Some(self.walk_expression(node)?),
+ // FIXME: Returns are always expected to have a return even though `return;` is valid.
+ Statement::Return(node) => {
+ // If there's a function running above us it will catch this error.
+ return Err(WalkerError::Return(self.walk_expression(node)?));
+ }
Statement::Break(node) => {
let returned = if let Some(expression) = node {
Some(self.walk_expression(expression)?)
@@ -307,4 +311,7 @@ pub enum WalkerError {
LoopContinue,
#[error("Break statements are only valid inside loops.")]
LoopBreak(Option<Value>),
+ // Same as with the loop control errors, but for functions.
+ #[error("Return statements are only valid inside functions.")]
+ Return(Value),
}