2024-03-09 12:34:34 +00:00
|
|
|
use crate::{
|
|
|
|
context::Context,
|
|
|
|
error::{RuntimeError, ValidationError},
|
2024-03-24 16:21:08 +00:00
|
|
|
value::{Function, ParsedFunction, ValueInner},
|
2024-03-09 12:34:34 +00:00
|
|
|
};
|
|
|
|
|
2024-03-20 04:28:28 +00:00
|
|
|
use super::{AbstractNode, Action, Expression, Type, WithPosition};
|
2024-03-09 12:34:34 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
|
|
|
|
pub struct FunctionCall {
|
2024-03-17 11:31:45 +00:00
|
|
|
function: Box<WithPosition<Expression>>,
|
2024-03-24 14:58:09 +00:00
|
|
|
type_arguments: Vec<WithPosition<Type>>,
|
2024-03-17 11:31:45 +00:00
|
|
|
arguments: Vec<WithPosition<Expression>>,
|
2024-03-09 12:34:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl FunctionCall {
|
2024-03-17 11:31:45 +00:00
|
|
|
pub fn new(
|
|
|
|
function: WithPosition<Expression>,
|
2024-03-24 14:58:09 +00:00
|
|
|
type_arguments: Vec<WithPosition<Type>>,
|
2024-03-17 11:31:45 +00:00
|
|
|
arguments: Vec<WithPosition<Expression>>,
|
|
|
|
) -> Self {
|
2024-03-09 12:34:34 +00:00
|
|
|
FunctionCall {
|
|
|
|
function: Box::new(function),
|
2024-03-24 14:58:09 +00:00
|
|
|
type_arguments,
|
2024-03-09 12:34:34 +00:00
|
|
|
arguments,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-20 04:28:28 +00:00
|
|
|
impl AbstractNode for FunctionCall {
|
2024-03-09 12:34:34 +00:00
|
|
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
2024-03-17 20:59:52 +00:00
|
|
|
let function_node_type = self.function.node.expected_type(_context)?;
|
|
|
|
|
|
|
|
if let Type::Function { return_type, .. } = function_node_type {
|
2024-03-24 16:21:08 +00:00
|
|
|
Ok(return_type.node)
|
2024-03-09 13:10:54 +00:00
|
|
|
} else {
|
2024-03-17 20:59:52 +00:00
|
|
|
Err(ValidationError::ExpectedFunction {
|
|
|
|
actual: function_node_type,
|
|
|
|
position: self.function.position,
|
|
|
|
})
|
2024-03-09 13:10:54 +00:00
|
|
|
}
|
2024-03-09 12:34:34 +00:00
|
|
|
}
|
|
|
|
|
2024-03-24 16:21:08 +00:00
|
|
|
fn validate(&self, context: &Context) -> Result<(), ValidationError> {
|
2024-03-23 21:51:40 +00:00
|
|
|
for expression in &self.arguments {
|
2024-03-24 16:21:08 +00:00
|
|
|
expression.node.validate(context)?;
|
2024-03-23 21:51:40 +00:00
|
|
|
}
|
|
|
|
|
2024-03-24 16:21:08 +00:00
|
|
|
let function_node_type = self.function.node.expected_type(context)?;
|
|
|
|
|
|
|
|
if let Type::Function {
|
|
|
|
parameter_types,
|
|
|
|
return_type: _,
|
|
|
|
} = function_node_type
|
|
|
|
{
|
|
|
|
for (type_parameter, type_argument) in
|
|
|
|
parameter_types.iter().zip(self.type_arguments.iter())
|
|
|
|
{
|
|
|
|
type_parameter
|
|
|
|
.node
|
|
|
|
.check(&type_argument.node)
|
|
|
|
.map_err(|conflict| ValidationError::TypeCheck {
|
|
|
|
conflict,
|
|
|
|
actual_position: type_argument.position,
|
|
|
|
expected_position: type_parameter.position,
|
|
|
|
})?;
|
|
|
|
}
|
2024-03-17 20:59:52 +00:00
|
|
|
|
2024-03-09 13:10:54 +00:00
|
|
|
Ok(())
|
|
|
|
} else {
|
2024-03-17 20:59:52 +00:00
|
|
|
Err(ValidationError::ExpectedFunction {
|
|
|
|
actual: function_node_type,
|
|
|
|
position: self.function.position,
|
|
|
|
})
|
2024-03-09 13:10:54 +00:00
|
|
|
}
|
2024-03-09 12:34:34 +00:00
|
|
|
}
|
|
|
|
|
2024-03-10 18:48:53 +00:00
|
|
|
fn run(self, context: &Context) -> Result<Action, RuntimeError> {
|
2024-03-18 07:24:41 +00:00
|
|
|
let action = self.function.node.run(context)?;
|
|
|
|
let value = if let Action::Return(value) = action {
|
|
|
|
value
|
|
|
|
} else {
|
|
|
|
return Err(RuntimeError::ValidationFailure(
|
|
|
|
ValidationError::InterpreterExpectedReturn(self.function.position),
|
|
|
|
));
|
|
|
|
};
|
2024-03-17 20:59:52 +00:00
|
|
|
let function = if let ValueInner::Function(function) = value.inner().as_ref() {
|
|
|
|
function
|
|
|
|
} else {
|
|
|
|
return Err(RuntimeError::ValidationFailure(
|
|
|
|
ValidationError::ExpectedFunction {
|
2024-03-19 22:31:52 +00:00
|
|
|
actual: value.r#type(context)?,
|
2024-03-17 20:59:52 +00:00
|
|
|
position: self.function.position,
|
|
|
|
},
|
|
|
|
));
|
|
|
|
};
|
2024-03-09 13:10:54 +00:00
|
|
|
let mut arguments = Vec::with_capacity(self.arguments.len());
|
|
|
|
|
|
|
|
for expression in self.arguments {
|
2024-03-18 07:24:41 +00:00
|
|
|
let action = expression.node.run(context)?;
|
|
|
|
let value = if let Action::Return(value) = action {
|
|
|
|
value
|
|
|
|
} else {
|
|
|
|
return Err(RuntimeError::ValidationFailure(
|
|
|
|
ValidationError::InterpreterExpectedReturn(expression.position),
|
|
|
|
));
|
|
|
|
};
|
2024-03-09 13:10:54 +00:00
|
|
|
|
|
|
|
arguments.push(value);
|
|
|
|
}
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
let function_context = Context::new();
|
2024-03-09 13:10:54 +00:00
|
|
|
|
2024-03-24 16:21:08 +00:00
|
|
|
if let Function::Parsed(ParsedFunction {
|
|
|
|
type_parameters, ..
|
|
|
|
}) = function
|
|
|
|
{
|
|
|
|
for (type_parameter, type_argument) in type_parameters
|
|
|
|
.iter()
|
|
|
|
.map(|r#type| r#type.node.clone())
|
|
|
|
.zip(self.type_arguments.into_iter().map(|r#type| r#type.node))
|
|
|
|
{
|
|
|
|
if let Type::Argument(identifier) = type_parameter {
|
|
|
|
function_context.set_type(identifier, type_argument)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-03-17 17:36:31 +00:00
|
|
|
function_context.inherit_data_from(&context)?;
|
2024-03-17 05:26:05 +00:00
|
|
|
function.clone().call(arguments, function_context)
|
2024-03-09 12:34:34 +00:00
|
|
|
}
|
|
|
|
}
|