about summary refs log tree commit diff
path: root/src/interpret/walker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpret/walker.rs')
-rw-r--r--src/interpret/walker.rs49
1 files changed, 32 insertions, 17 deletions
diff --git a/src/interpret/walker.rs b/src/interpret/walker.rs
index 68dc388..3feed6f 100644
--- a/src/interpret/walker.rs
+++ b/src/interpret/walker.rs
@@ -1,29 +1,38 @@
 use std::{cell::RefCell, rc::Rc};
 
-use crate::parse::ast::{
-    expression::Expression,
-    nodes::{BinaryOperator as BinOp, BlockNode, SimpleLiteral, StrPart, UnaryOperator as UnOp},
-    statement::Statement,
-    Program,
+use crate::{
+    interpret::value::FnValue,
+    parse::ast::{
+        expression::Expression,
+        nodes::{
+            BinaryOperator as BinOp, BlockNode, SimpleLiteral, StrPart, UnaryOperator as UnOp,
+        },
+        statement::Statement,
+        Program,
+    },
 };
 use thiserror::Error;
 
 use super::{
-    scope::{Scope, ScopeError},
+    scope::{ScopeChain, ScopeError},
     value::{OperationError, Value},
 };
 
 pub struct Walker {
-    scope: Scope,
+    scope: ScopeChain,
 }
 
 impl Walker {
     pub fn new() -> Self {
         Walker {
-            scope: Scope::new(),
+            scope: ScopeChain::new(),
         }
     }
 
+    pub fn new_with_scope(scope: ScopeChain) -> Self {
+        Walker { scope }
+    }
+
     pub fn walk(&mut self, program: &Program) {
         self.scope.nest();
         for statement in program.statements.iter() {
@@ -118,14 +127,20 @@ impl Walker {
                 }
                 .map_err(WalkerError::OperationError)
             }
-            Expression::Call(_) => todo!("Calls not implemented yet."),
+            Expression::Call(node) => {
+                let called = self.walk_expression(&node.called)?;
+
+                let mut argument_values = Vec::new();
+                for argument_node in node.arguments.iter() {
+                    argument_values.push(self.walk_expression(argument_node)?);
+                }
+
+                called.call(argument_values)
+            }
             Expression::ArrayAccess(node) => {
                 let array = self.walk_expression(&node.array)?;
                 let index = self.walk_expression(&node.index)?;
-                array
-                    .subscript(index)
-                    .map(|v| v.clone())
-                    .map_err(WalkerError::OperationError)
+                array.subscript(index).map_err(WalkerError::OperationError)
             }
             Expression::MemberAccess(_) => todo!("Structures not implemented yet."),
             Expression::Group(node) => self.walk_expression(node),
@@ -160,10 +175,10 @@ impl Walker {
 
                 Ok(Value::Str(buffer))
             }
-            Expression::FnLiteral(fn_node) => {
-                let node = fn_node.as_ref().clone();
-                Ok(Value::Fn(Rc::new(RefCell::new(node))))
-            }
+            Expression::FnLiteral(node) => Ok(Value::Fn(Rc::new(RefCell::new(FnValue {
+                node: node.as_ref().clone(),
+                scope: self.scope.clone(),
+            })))),
             Expression::If(if_node) => {
                 for conditional in &if_node.conditionals {
                     if let Value::Bool(bool) = self.walk_expression(&conditional.condition)? {