From c891369f0ce69b2fe78846cae1202899595354b7 Mon Sep 17 00:00:00 2001 From: Mel Date: Sun, 14 Nov 2021 22:40:36 +0100 Subject: Add return statements --- src/interpret/value.rs | 9 ++++++--- src/interpret/walker.rs | 9 ++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'src') 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), + // Same as with the loop control errors, but for functions. + #[error("Return statements are only valid inside functions.")] + Return(Value), } -- cgit 1.4.1