diff --git a/src/abstract_tree/assignment.rs b/src/abstract_tree/assignment.rs index 017f60c..a08575a 100644 --- a/src/abstract_tree/assignment.rs +++ b/src/abstract_tree/assignment.rs @@ -3,8 +3,8 @@ use serde::{Deserialize, Serialize}; use crate::{ context::Context, error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, AssignmentOperator, Format, Function, Identifier, SourcePosition, Statement, - SyntaxNode, Type, TypeSpecification, Value, + AbstractTree, AssignmentOperator, Format, Identifier, SourcePosition, Statement, SyntaxNode, + Type, TypeSpecification, Value, }; /// Variable assignment, including add-assign and subtract-assign operations. diff --git a/src/abstract_tree/for.rs b/src/abstract_tree/for.rs index cdb923d..89171d6 100644 --- a/src/abstract_tree/for.rs +++ b/src/abstract_tree/for.rs @@ -47,7 +47,7 @@ impl AbstractTree for For { let loop_context = Context::with_variables_from(context)?; let item_node = node.child(4).unwrap(); - let item = Block::from_syntax(item_node, source, context)?; + let item = Block::from_syntax(item_node, source, &loop_context)?; Ok(For { is_async, @@ -78,11 +78,14 @@ impl AbstractTree for For { }; let key = self.item_id.inner().clone(); + self.context.inherit_from(context)?; self.context.set_type(key, item_type)?; self.block.validate(_source, &self.context) } fn run(&self, source: &str, context: &Context) -> Result { + self.context.inherit_from(context)?; + let expression_run = self.collection.run(source, context)?; let key = self.item_id.inner(); diff --git a/src/abstract_tree/function_call.rs b/src/abstract_tree/function_call.rs index 80c3052..815c627 100644 --- a/src/abstract_tree/function_call.rs +++ b/src/abstract_tree/function_call.rs @@ -1,6 +1,7 @@ use serde::{Deserialize, Serialize}; use crate::{ + built_in_functions::Callable, error::{RuntimeError, SyntaxError, ValidationError}, AbstractTree, Context, Expression, Format, FunctionExpression, SourcePosition, SyntaxNode, Type, Value, @@ -153,19 +154,32 @@ impl AbstractTree for FunctionCall { FunctionExpression::Index(index) => index.run(source, context)?, }; let function = value.as_function()?; - let parameter_expression_pairs = function - .parameters() - .unwrap() - .iter() - .zip(self.arguments.iter()); - for (identifier, expression) in parameter_expression_pairs { - let value = expression.run(source, context)?; + match function { + crate::Function::BuiltIn(built_in_function) => { + let mut arguments = Vec::with_capacity(self.arguments.len()); - self.context.set_value(identifier.inner().clone(), value)?; + for expression in &self.arguments { + let value = expression.run(source, context)?; + + arguments.push(value); + } + + built_in_function.call(&arguments, source, &self.context) + } + crate::Function::ContextDefined(function_node) => { + let parameter_expression_pairs = + function_node.parameters().iter().zip(self.arguments.iter()); + + for (identifier, expression) in parameter_expression_pairs { + let value = expression.run(source, context)?; + + self.context.set_value(identifier.inner().clone(), value)?; + } + + function_node.call(source, &self.context) + } } - - function.call(&[], source, &self.context) } } diff --git a/src/built_in_functions/str.rs b/src/built_in_functions/str.rs index 47184eb..af4204a 100644 --- a/src/built_in_functions/str.rs +++ b/src/built_in_functions/str.rs @@ -333,18 +333,20 @@ impl Callable for StrFunction { StrFunction::Retain => { RuntimeError::expect_argument_amount(self.name(), 2, arguments.len())?; - let mut string = arguments.first().unwrap().as_string()?.clone(); - let predicate = arguments.get(1).unwrap().as_function()?; + todo!(); - string.retain(|char| { - predicate - .call(&[Value::string(char)], _source, _outer_context) - .unwrap() - .as_boolean() - .unwrap() - }); + // let mut string = arguments.first().unwrap().as_string()?.clone(); + // let predicate = arguments.get(1).unwrap().as_function()?; - Value::String(string) + // string.retain(|char| { + // predicate + // .call(&[Value::string(char)], _source, _outer_context) + // .unwrap() + // .as_boolean() + // .unwrap() + // }); + + // Value::String(string) } StrFunction::Split => { RuntimeError::expect_argument_amount(self.name(), 2, arguments.len())?; diff --git a/src/value/function.rs b/src/value/function.rs index eb61600..37d5bc2 100644 --- a/src/value/function.rs +++ b/src/value/function.rs @@ -3,8 +3,7 @@ use std::fmt::{self, Display, Formatter}; use serde::{Deserialize, Serialize}; use crate::{ - built_in_functions::Callable, error::RuntimeError, BuiltInFunction, Context, Format, - FunctionNode, Identifier, Type, Value, + built_in_functions::Callable, BuiltInFunction, Format, FunctionNode, Identifier, Type, }; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] @@ -14,20 +13,6 @@ pub enum Function { } impl Function { - pub fn call( - &self, - arguments: &[Value], - source: &str, - outer_context: &Context, - ) -> Result { - match self { - Function::BuiltIn(built_in_function) => { - built_in_function.call(arguments, source, outer_context) - } - Function::ContextDefined(function_node) => function_node.call(source, outer_context), - } - } - pub fn r#type(&self) -> Type { match self { Function::BuiltIn(built_in_function) => built_in_function.r#type(),