Add context to function call nodes
This commit is contained in:
parent
daf78919da
commit
bbab728ce9
@ -12,6 +12,9 @@ pub struct FunctionCall {
|
||||
function_expression: FunctionExpression,
|
||||
arguments: Vec<Expression>,
|
||||
syntax_position: SourcePosition,
|
||||
|
||||
#[serde(skip)]
|
||||
context: Context,
|
||||
}
|
||||
|
||||
impl FunctionCall {
|
||||
@ -20,11 +23,13 @@ impl FunctionCall {
|
||||
function_expression: FunctionExpression,
|
||||
arguments: Vec<Expression>,
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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<Identifier>> {
|
||||
if let Function::ContextDefined(function) = self {
|
||||
Some(function.parameters())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Format for Function {
|
||||
|
Loading…
Reference in New Issue
Block a user