2024-06-04 18:47:15 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
2024-03-09 12:34:34 +00:00
|
|
|
use crate::{
|
|
|
|
context::Context,
|
|
|
|
error::{RuntimeError, ValidationError},
|
2024-04-21 21:00:08 +00:00
|
|
|
value::ValueInner,
|
2024-03-09 12:34:34 +00:00
|
|
|
};
|
|
|
|
|
2024-06-17 14:50:06 +00:00
|
|
|
use super::{AbstractNode, Evaluation, ExpectedType, Expression, Type, TypeConstructor};
|
2024-03-09 12:34:34 +00:00
|
|
|
|
2024-06-04 18:47:15 +00:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
2024-03-09 12:34:34 +00:00
|
|
|
pub struct FunctionCall {
|
2024-06-17 14:10:06 +00:00
|
|
|
function: Box<Expression>,
|
2024-06-17 14:50:06 +00:00
|
|
|
type_arguments: Option<Vec<TypeConstructor>>,
|
2024-06-17 14:10:06 +00:00
|
|
|
value_arguments: Vec<Expression>,
|
2024-03-09 12:34:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl FunctionCall {
|
2024-03-17 11:31:45 +00:00
|
|
|
pub fn new(
|
2024-06-17 14:10:06 +00:00
|
|
|
function: Expression,
|
2024-06-17 14:50:06 +00:00
|
|
|
type_arguments: Option<Vec<TypeConstructor>>,
|
2024-06-17 14:10:06 +00:00
|
|
|
value_arguments: Vec<Expression>,
|
2024-03-17 11:31:45 +00:00
|
|
|
) -> 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-06-17 14:10:06 +00:00
|
|
|
value_arguments,
|
2024-03-09 12:34:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-20 04:28:28 +00:00
|
|
|
impl AbstractNode for FunctionCall {
|
2024-04-22 12:25:20 +00:00
|
|
|
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
|
2024-04-22 11:56:03 +00:00
|
|
|
self.function.validate(context, manage_memory)?;
|
2024-04-22 05:51:34 +00:00
|
|
|
|
2024-06-17 14:10:06 +00:00
|
|
|
for expression in &self.value_arguments {
|
2024-04-22 11:56:03 +00:00
|
|
|
expression.validate(context, manage_memory)?;
|
2024-03-23 21:51:40 +00:00
|
|
|
}
|
|
|
|
|
2024-03-25 04:16:55 +00:00
|
|
|
let function_node_type = self.function.expected_type(context)?;
|
2024-03-24 16:21:08 +00:00
|
|
|
|
|
|
|
if let Type::Function {
|
2024-06-17 14:10:06 +00:00
|
|
|
type_parameters,
|
|
|
|
value_parameters: _,
|
2024-03-24 16:21:08 +00:00
|
|
|
return_type: _,
|
|
|
|
} = function_node_type
|
|
|
|
{
|
2024-06-17 14:10:06 +00:00
|
|
|
match (type_parameters, &self.type_arguments) {
|
|
|
|
(Some(type_parameters), Some(type_arguments)) => {
|
|
|
|
if type_parameters.len() != type_arguments.len() {
|
|
|
|
return Err(ValidationError::WrongTypeArgumentCount {
|
|
|
|
actual: type_parameters.len(),
|
|
|
|
expected: type_arguments.len(),
|
|
|
|
});
|
2024-03-24 19:35:19 +00:00
|
|
|
}
|
2024-06-17 14:10:06 +00:00
|
|
|
}
|
|
|
|
_ => {}
|
2024-03-24 19:35:19 +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,
|
2024-03-25 04:16:55 +00:00
|
|
|
position: self.function.position(),
|
2024-03-17 20:59:52 +00:00
|
|
|
})
|
2024-03-09 13:10:54 +00:00
|
|
|
}
|
2024-03-09 12:34:34 +00:00
|
|
|
}
|
|
|
|
|
2024-06-17 14:10:06 +00:00
|
|
|
fn evaluate(
|
|
|
|
self,
|
|
|
|
context: &mut Context,
|
|
|
|
clear_variables: bool,
|
|
|
|
) -> Result<Evaluation, RuntimeError> {
|
2024-03-25 04:16:55 +00:00
|
|
|
let function_position = self.function.position();
|
2024-06-17 14:10:06 +00:00
|
|
|
let action = self.function.evaluate(context, clear_variables)?;
|
|
|
|
let value = if let Evaluation::Return(value) = action {
|
2024-03-18 07:24:41 +00:00
|
|
|
value
|
|
|
|
} else {
|
|
|
|
return Err(RuntimeError::ValidationFailure(
|
2024-03-25 04:16:55 +00:00
|
|
|
ValidationError::InterpreterExpectedReturn(function_position),
|
2024-03-18 07:24:41 +00:00
|
|
|
));
|
|
|
|
};
|
2024-03-17 20:59:52 +00:00
|
|
|
let function = if let ValueInner::Function(function) = value.inner().as_ref() {
|
2024-06-17 14:10:06 +00:00
|
|
|
function.clone()
|
2024-03-17 20:59:52 +00:00
|
|
|
} else {
|
|
|
|
return Err(RuntimeError::ValidationFailure(
|
|
|
|
ValidationError::ExpectedFunction {
|
2024-03-19 22:31:52 +00:00
|
|
|
actual: value.r#type(context)?,
|
2024-03-25 04:16:55 +00:00
|
|
|
position: function_position,
|
2024-03-17 20:59:52 +00:00
|
|
|
},
|
|
|
|
));
|
|
|
|
};
|
2024-06-17 14:10:06 +00:00
|
|
|
let mut arguments = Vec::with_capacity(self.value_arguments.len());
|
2024-03-09 13:10:54 +00:00
|
|
|
|
2024-06-17 14:10:06 +00:00
|
|
|
for expression in self.value_arguments {
|
2024-03-25 04:16:55 +00:00
|
|
|
let expression_position = expression.position();
|
2024-06-17 14:10:06 +00:00
|
|
|
let action = expression.evaluate(context, clear_variables)?;
|
|
|
|
let value = if let Evaluation::Return(value) = action {
|
2024-03-18 07:24:41 +00:00
|
|
|
value
|
|
|
|
} else {
|
|
|
|
return Err(RuntimeError::ValidationFailure(
|
2024-03-25 04:16:55 +00:00
|
|
|
ValidationError::InterpreterExpectedReturn(expression_position),
|
2024-03-18 07:24:41 +00:00
|
|
|
));
|
|
|
|
};
|
2024-03-09 13:10:54 +00:00
|
|
|
|
|
|
|
arguments.push(value);
|
|
|
|
}
|
|
|
|
|
2024-05-21 20:29:54 +00:00
|
|
|
let mut function_context = Context::new(Some(&context));
|
2024-03-09 13:10:54 +00:00
|
|
|
|
2024-06-17 14:10:06 +00:00
|
|
|
match (function.type_parameters(), self.type_arguments) {
|
|
|
|
(Some(type_parameters), Some(type_arguments)) => {
|
|
|
|
for (parameter, constructor) in
|
|
|
|
type_parameters.into_iter().zip(type_arguments.into_iter())
|
|
|
|
{
|
2024-06-17 14:50:06 +00:00
|
|
|
let r#type = constructor.construct(context)?;
|
2024-06-17 14:10:06 +00:00
|
|
|
|
|
|
|
function_context.set_type(parameter.clone(), r#type)?;
|
|
|
|
}
|
2024-03-24 16:21:08 +00:00
|
|
|
}
|
2024-06-17 14:10:06 +00:00
|
|
|
_ => {}
|
2024-04-21 21:00:08 +00:00
|
|
|
}
|
2024-03-24 16:21:08 +00:00
|
|
|
|
2024-04-22 07:41:21 +00:00
|
|
|
function
|
|
|
|
.clone()
|
|
|
|
.call(arguments, &mut function_context, clear_variables)
|
2024-03-09 12:34:34 +00:00
|
|
|
}
|
|
|
|
}
|
2024-06-16 07:12:04 +00:00
|
|
|
|
|
|
|
impl ExpectedType for FunctionCall {
|
2024-06-19 04:05:58 +00:00
|
|
|
fn expected_type(&self, context: &mut Context) -> Result<Type, ValidationError> {
|
|
|
|
let function_node_type = self.function.expected_type(context)?;
|
|
|
|
|
|
|
|
if let Type::Function {
|
|
|
|
return_type,
|
|
|
|
type_parameters,
|
|
|
|
..
|
|
|
|
} = function_node_type
|
|
|
|
{
|
2024-06-19 04:09:47 +00:00
|
|
|
if let Type::Generic {
|
|
|
|
identifier: return_identifier,
|
|
|
|
..
|
|
|
|
} = *return_type.clone()
|
2024-06-19 04:05:58 +00:00
|
|
|
{
|
2024-06-19 04:22:37 +00:00
|
|
|
if let (Some(type_arguments), Some(type_parameters)) =
|
|
|
|
(&self.type_arguments, &type_parameters)
|
2024-06-19 04:05:58 +00:00
|
|
|
{
|
2024-06-19 04:22:37 +00:00
|
|
|
for (constructor, identifier) in
|
|
|
|
type_arguments.into_iter().zip(type_parameters.into_iter())
|
|
|
|
{
|
|
|
|
if &return_identifier == identifier {
|
|
|
|
let concrete_type = constructor.clone().construct(&context)?;
|
|
|
|
|
|
|
|
return Ok(Type::Generic {
|
|
|
|
identifier: identifier.clone(),
|
|
|
|
concrete_type: Some(Box::new(concrete_type)),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-06-19 04:05:58 +00:00
|
|
|
|
2024-06-19 04:22:37 +00:00
|
|
|
if let (None, Some(type_parameters)) = (&self.type_arguments, type_parameters) {
|
|
|
|
for (expression, identifier) in (&self.value_arguments)
|
|
|
|
.into_iter()
|
|
|
|
.zip(type_parameters.into_iter())
|
|
|
|
{
|
|
|
|
if identifier == return_identifier {
|
|
|
|
let concrete_type = expression.expected_type(context)?;
|
|
|
|
|
|
|
|
return Ok(Type::Generic {
|
|
|
|
identifier,
|
|
|
|
concrete_type: Some(Box::new(concrete_type)),
|
|
|
|
});
|
|
|
|
}
|
2024-06-19 04:05:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-06-16 07:12:04 +00:00
|
|
|
|
2024-06-17 14:10:06 +00:00
|
|
|
Ok(*return_type)
|
2024-06-16 07:12:04 +00:00
|
|
|
} else {
|
|
|
|
Err(ValidationError::ExpectedFunction {
|
|
|
|
actual: function_node_type,
|
|
|
|
position: self.function.position(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|