dust/src/abstract_tree/function_call.rs

80 lines
2.6 KiB
Rust
Raw Normal View History

2023-10-06 17:32:58 +00:00
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
2023-10-31 19:21:13 +00:00
use crate::{AbstractTree, BuiltInFunction, Error, Map, Result, Value};
2023-10-06 17:32:58 +00:00
use super::expression::Expression;
2023-10-06 17:32:58 +00:00
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
2023-10-31 19:21:13 +00:00
pub enum FunctionCall {
BuiltIn(Box<BuiltInFunction>),
ContextDefined {
name: Expression,
2023-10-31 19:21:13 +00:00
arguments: Vec<Expression>,
},
2023-10-09 19:54:47 +00:00
}
2023-10-06 17:32:58 +00:00
impl AbstractTree for FunctionCall {
2023-10-10 17:29:11 +00:00
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
2023-10-06 17:32:58 +00:00
debug_assert_eq!("function_call", node.kind());
2023-11-15 00:38:19 +00:00
let function_node = node.child(1).unwrap();
2023-10-09 19:54:47 +00:00
let mut arguments = Vec::new();
2023-10-06 17:32:58 +00:00
2023-11-15 00:38:19 +00:00
for index in 2..node.child_count() - 1 {
2023-11-04 10:02:27 +00:00
let node = node.child(index).unwrap();
2023-10-06 17:32:58 +00:00
2023-11-04 10:02:27 +00:00
if node.is_named() {
let expression = Expression::from_syntax_node(source, node)?;
2023-10-06 17:32:58 +00:00
2023-10-11 16:07:30 +00:00
arguments.push(expression);
}
2023-10-06 17:32:58 +00:00
}
2023-10-31 19:21:13 +00:00
let function_call = if function_node.kind() == "built_in_function" {
let function = BuiltInFunction::from_syntax_node(source, function_node)?;
FunctionCall::BuiltIn(Box::new(function))
} else {
let name = Expression::from_syntax_node(source, function_node)?;
2023-10-31 19:21:13 +00:00
FunctionCall::ContextDefined { name, arguments }
2023-10-31 19:21:13 +00:00
};
Ok(function_call)
2023-10-06 17:32:58 +00:00
}
2023-10-25 20:44:50 +00:00
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
2023-10-31 19:21:13 +00:00
let (name, arguments) = match self {
FunctionCall::BuiltIn(function) => return function.run(source, context),
FunctionCall::ContextDefined { name, arguments } => (name, arguments),
};
2023-11-27 20:02:08 +00:00
let function = if let Expression::Identifier(identifier) = name {
if let Some(value) = context.variables()?.get(identifier.inner()) {
value.as_function().cloned()
} else {
return Err(Error::FunctionIdentifierNotFound(identifier.clone()));
}
2023-10-06 17:32:58 +00:00
} else {
let name_run = name.run(source, context)?;
name_run.as_function().cloned()
}?;
2023-11-05 18:54:29 +00:00
let mut function_context = Map::clone_from(context)?;
2023-11-27 20:02:08 +00:00
let parameter_expression_pairs = function.parameters().iter().zip(arguments.iter());
2023-10-06 21:11:50 +00:00
2023-11-27 20:02:08 +00:00
for ((identifier, r#type), expression) in parameter_expression_pairs {
let key = identifier.clone().take_inner();
let value = expression.run(source, context)?;
2023-10-07 01:00:31 +00:00
2023-11-27 20:02:08 +00:00
r#type.check(&value)?;
2023-10-31 22:18:39 +00:00
2023-11-27 20:02:08 +00:00
function_context.variables_mut()?.insert(key, value);
2023-10-07 01:00:31 +00:00
}
2023-11-27 20:02:08 +00:00
function.run(source, &mut function_context)
2023-10-06 17:32:58 +00:00
}
}