about summary refs log tree commit diff
path: root/src/interpret/operator.rs
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2021-12-29 00:48:16 +0100
committerMel <einebeere@gmail.com>2021-12-29 00:48:16 +0100
commit842e76d57274ea6f8d5929e96f2919fd9cf0afb5 (patch)
tree2aae20bdc9e7e60f02e3b89bc1db396eb43a3f61 /src/interpret/operator.rs
parente621f13a226d297d5368f4c294a8549a93843934 (diff)
downloadrabbithole-842e76d57274ea6f8d5929e96f2919fd9cf0afb5.tar.zst
rabbithole-842e76d57274ea6f8d5929e96f2919fd9cf0afb5.zip
Runtime errors
Diffstat (limited to 'src/interpret/operator.rs')
-rw-r--r--src/interpret/operator.rs30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/interpret/operator.rs b/src/interpret/operator.rs
index ce062c7..42c501e 100644
--- a/src/interpret/operator.rs
+++ b/src/interpret/operator.rs
@@ -1,6 +1,10 @@
 use thiserror::Error;
 
-use crate::{parse::ast::expression::Expression, types::bag::TypeBag};
+use crate::{
+    error::{RHError, RHErrorKind},
+    parse::ast::expression::{Expression, ExpressionKind},
+    types::bag::TypeBag,
+};
 
 use super::{
     value::{Value, ValueKind},
@@ -261,12 +265,26 @@ impl<'t> ValueOperator<'t> {
         // Yes, we create a new walker for every function call,
         // it's *way* easier that way.
         let mut walker = Walker::new(scope, self.types.clone());
-        let result = walker.walk_expression(&Expression::Block(Box::new(called.node.body.clone())));
 
-        if let Err(WalkerError::Return(returned)) = result {
-            Ok(returned)
-        } else {
-            result
+        // Re-assemble the function body into an expression.
+        let body_expression = Expression {
+            kind: ExpressionKind::Block(Box::new(called.node.body.clone())),
+            at: called.node.body.at,
+        };
+
+        // Evaluate the function body.
+        let result = walker.walk_expression(&body_expression);
+
+        match result {
+            Err(RHError {
+                kind: RHErrorKind::Run(err),
+                ..
+            }) => match err {
+                WalkerError::Return(returned_value) => Ok(returned_value),
+                _ => Err(err),
+            },
+            Err(_) => panic!("Walker returned non-walker error."),
+            Ok(result) => Ok(result),
         }
     }
 }