diff --git a/src/abstract_tree/function_call.rs b/src/abstract_tree/function_call.rs index 802c57b..8d8cf83 100644 --- a/src/abstract_tree/function_call.rs +++ b/src/abstract_tree/function_call.rs @@ -12,6 +12,9 @@ pub struct FunctionCall { function_expression: FunctionExpression, arguments: Vec, syntax_position: SourcePosition, + + #[serde(skip)] + context: Context, } impl FunctionCall { @@ -20,11 +23,13 @@ impl FunctionCall { function_expression: FunctionExpression, arguments: Vec, syntax_position: SourcePosition, + context: Context, ) -> Self { Self { function_expression, arguments, syntax_position, + context, } } } @@ -52,6 +57,7 @@ impl AbstractTree for FunctionCall { function_expression, arguments, syntax_position: node.range().into(), + context: Context::new(), }) } @@ -144,16 +150,20 @@ impl AbstractTree for FunctionCall { FunctionExpression::Value(value_node) => value_node.run(source, context)?, FunctionExpression::Index(index) => index.run(source, context)?, }; + let function = value.as_function()?; + let parameter_expression_pairs = function + .parameters() + .unwrap() + .iter() + .zip(self.arguments.iter()); - let mut arguments = Vec::with_capacity(self.arguments.len()); - - for expression in &self.arguments { + for (identifier, expression) in parameter_expression_pairs { let value = expression.run(source, context)?; - arguments.push(value); + self.context.set_value(identifier.inner().clone(), value)?; } - value.as_function()?.call(&arguments, source, context) + value.as_function()?.call(&[], source, context) } } diff --git a/src/abstract_tree/function_node.rs b/src/abstract_tree/function_node.rs index b468dc1..b498e63 100644 --- a/src/abstract_tree/function_node.rs +++ b/src/abstract_tree/function_node.rs @@ -14,9 +14,6 @@ pub struct FunctionNode { body: Block, r#type: Type, syntax_position: SourcePosition, - - #[serde(skip)] - context: Context, } impl FunctionNode { @@ -31,7 +28,6 @@ impl FunctionNode { body, r#type, syntax_position, - context: Context::new(), } } @@ -61,21 +57,8 @@ impl FunctionNode { } } - pub fn call( - &self, - arguments: &[Value], - source: &str, - _context: &Context, - ) -> Result { - let parameter_argument_pairs = self.parameters.iter().zip(arguments.iter()); - - for (identifier, value) in parameter_argument_pairs { - let key = identifier.inner().clone(); - - self.context.set_value(key, value.clone())?; - } - - let return_value = self.body.run(source, &self.context)?; + pub fn call(&self, source: &str, context: &Context) -> Result { + let return_value = self.body.run(source, context)?; Ok(return_value) } @@ -108,15 +91,9 @@ impl AbstractTree for FunctionNode { let return_type_node = node.child(child_count - 2).unwrap(); let return_type = TypeSpecification::from_syntax(return_type_node, source, context)?; - let function_context = Context::with_variables_from(context)?; - let body_node = node.child(child_count - 1).unwrap(); let body = Block::from_syntax(body_node, source, &context)?; - for (parameter, parameter_type) in parameters.iter().zip(parameter_types.iter()) { - function_context.set_type(parameter.inner().clone(), parameter_type.clone())?; - } - let r#type = Type::function(parameter_types, return_type.take_inner()); let syntax_position = node.range().into(); @@ -125,7 +102,6 @@ impl AbstractTree for FunctionNode { body, r#type, syntax_position, - context: function_context, }) } diff --git a/src/value/function.rs b/src/value/function.rs index 050bf48..eb61600 100644 --- a/src/value/function.rs +++ b/src/value/function.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::{ built_in_functions::Callable, error::RuntimeError, BuiltInFunction, Context, Format, - FunctionNode, Type, Value, + FunctionNode, Identifier, Type, Value, }; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] @@ -24,9 +24,7 @@ impl Function { Function::BuiltIn(built_in_function) => { built_in_function.call(arguments, source, outer_context) } - Function::ContextDefined(function_node) => { - function_node.call(arguments, source, outer_context) - } + Function::ContextDefined(function_node) => function_node.call(source, outer_context), } } @@ -38,6 +36,14 @@ impl Function { } } } + + pub fn parameters(&self) -> Option<&Vec> { + if let Function::ContextDefined(function) = self { + Some(function.parameters()) + } else { + None + } + } } impl Format for Function {