dust/dust-lang/src/abstract_tree/function_call.rs

151 lines
4.8 KiB
Rust
Raw Normal View History

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
};
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-25 04:16:55 +00:00
function: Box<Expression>,
2024-03-24 14:58:09 +00:00
type_arguments: Vec<WithPosition<Type>>,
2024-03-25 04:16:55 +00:00
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-03-25 04:16:55 +00:00
function: Expression,
2024-03-24 14:58:09 +00:00
type_arguments: Vec<WithPosition<Type>>,
2024-03-25 04:16:55 +00:00
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-03-09 12:34:34 +00:00
arguments,
}
}
}
impl AbstractNode for FunctionCall {
2024-03-09 12:34:34 +00:00
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
2024-03-25 04:16:55 +00:00
let function_node_type = self.function.expected_type(_context)?;
2024-03-17 20:59:52 +00:00
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,
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-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-25 04:16:55 +00:00
expression.validate(context)?;
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 {
parameter_types,
return_type: _,
} = function_node_type
{
for (type_parameter, type_argument) in
parameter_types.iter().zip(self.type_arguments.iter())
{
2024-04-03 03:13:03 +00:00
if let Type::Argument(_) = type_parameter.node {
continue;
}
2024-03-24 16:21:08 +00:00
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-24 19:35:19 +00:00
for (type_parameter, expression) in parameter_types.iter().zip(self.arguments.iter()) {
2024-04-03 03:13:03 +00:00
if let Type::Argument(_) = type_parameter.node {
continue;
}
2024-03-25 04:16:55 +00:00
let actual = expression.expected_type(context)?;
2024-03-24 19:35:19 +00:00
type_parameter.node.check(&actual).map_err(|conflict| {
ValidationError::TypeCheck {
conflict,
2024-03-25 04:16:55 +00:00
actual_position: expression.position(),
2024-03-24 19:35:19 +00:00
expected_position: type_parameter.position,
}
})?;
}
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
}
fn run(self, context: &Context) -> Result<Action, RuntimeError> {
2024-03-25 04:16:55 +00:00
let function_position = self.function.position();
let action = self.function.run(context)?;
2024-03-18 07:24:41 +00:00
let value = if let Action::Return(value) = action {
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() {
function
} 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-03-09 13:10:54 +00:00
let mut arguments = Vec::with_capacity(self.arguments.len());
for expression in self.arguments {
2024-03-25 04:16:55 +00:00
let expression_position = expression.position();
let action = expression.run(context)?;
2024-03-18 07:24:41 +00:00
let value = if let Action::Return(value) = action {
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-03-17 17:36:31 +00:00
let function_context = Context::new();
2024-03-09 13:10:54 +00:00
2024-04-21 21:00:08 +00:00
for (type_parameter, type_argument) in function
.type_parameters()
.iter()
.map(|r#type| r#type.node.clone())
.zip(self.type_arguments.into_iter().map(|r#type| r#type.node))
2024-03-24 16:21:08 +00:00
{
2024-04-21 21:00:08 +00:00
if let Type::Argument(identifier) = type_parameter {
function_context.set_type(identifier, type_argument)?;
2024-03-24 16:21:08 +00:00
}
2024-04-21 21:00:08 +00:00
}
2024-03-24 16:21:08 +00:00
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
}
}