2023-08-22 15:40:50 +00:00
|
|
|
use std::fmt::{self, Display, Formatter};
|
|
|
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
2023-12-02 03:54:25 +00:00
|
|
|
use tree_sitter::Node;
|
2023-08-22 15:40:50 +00:00
|
|
|
|
2023-12-02 03:54:25 +00:00
|
|
|
use crate::{
|
|
|
|
AbstractTree, Block, Error, Expression, Identifier, Map, Result, Type, TypeDefinition, Value,
|
|
|
|
};
|
2023-08-22 15:40:50 +00:00
|
|
|
|
2023-09-30 21:52:37 +00:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
|
|
|
pub struct Function {
|
2023-11-30 14:30:25 +00:00
|
|
|
parameters: Vec<(Identifier, TypeDefinition)>,
|
2023-11-27 20:02:08 +00:00
|
|
|
body: Block,
|
2023-11-30 14:30:25 +00:00
|
|
|
return_type: TypeDefinition,
|
2023-09-30 21:52:37 +00:00
|
|
|
}
|
2023-08-22 15:40:50 +00:00
|
|
|
|
|
|
|
impl Function {
|
2023-11-30 14:30:25 +00:00
|
|
|
pub fn new(
|
|
|
|
parameters: Vec<(Identifier, TypeDefinition)>,
|
|
|
|
body: Block,
|
|
|
|
return_type: TypeDefinition,
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
parameters,
|
|
|
|
body,
|
|
|
|
return_type,
|
|
|
|
}
|
2023-11-30 10:40:39 +00:00
|
|
|
}
|
|
|
|
|
2023-11-30 14:30:25 +00:00
|
|
|
pub fn parameters(&self) -> &Vec<(Identifier, TypeDefinition)> {
|
2023-11-27 20:02:08 +00:00
|
|
|
&self.parameters
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
2023-11-30 00:23:42 +00:00
|
|
|
|
|
|
|
pub fn body(&self) -> &Block {
|
|
|
|
&self.body
|
|
|
|
}
|
|
|
|
|
2023-11-30 14:30:25 +00:00
|
|
|
pub fn return_type(&self) -> &TypeDefinition {
|
|
|
|
&self.return_type
|
2023-11-30 00:23:42 +00:00
|
|
|
}
|
2023-12-02 03:16:50 +00:00
|
|
|
|
2023-12-02 04:20:33 +00:00
|
|
|
pub fn r#type(&self) -> TypeDefinition {
|
|
|
|
let mut parameter_types = Vec::with_capacity(self.parameters.len());
|
|
|
|
|
|
|
|
for (_, type_definition) in &self.parameters {
|
|
|
|
parameter_types.push(type_definition.inner().clone());
|
|
|
|
}
|
|
|
|
|
|
|
|
TypeDefinition::new(Type::Function {
|
|
|
|
parameter_types,
|
|
|
|
return_type: Box::new(self.return_type.inner().clone()),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-12-02 03:16:50 +00:00
|
|
|
pub fn call(&self, arguments: &[Expression], source: &str, context: &Map) -> Result<Value> {
|
2023-12-02 04:20:33 +00:00
|
|
|
let function_context = Map::clone_from(context)?;
|
2023-12-02 03:16:50 +00:00
|
|
|
let parameter_argument_pairs = self.parameters.iter().zip(arguments.iter());
|
|
|
|
|
|
|
|
for ((identifier, type_definition), expression) in parameter_argument_pairs {
|
|
|
|
let key = identifier.inner();
|
|
|
|
let value = expression.run(source, context)?;
|
|
|
|
|
|
|
|
println!("{key} {value}");
|
|
|
|
|
|
|
|
function_context.variables_mut()?.insert(key.clone(), value);
|
|
|
|
}
|
|
|
|
|
|
|
|
let return_value = self.body.run(source, &function_context)?;
|
|
|
|
|
|
|
|
Ok(return_value)
|
|
|
|
}
|
2023-10-05 18:29:13 +00:00
|
|
|
}
|
2023-08-22 15:40:50 +00:00
|
|
|
|
2023-12-02 03:54:25 +00:00
|
|
|
impl AbstractTree for Function {
|
|
|
|
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
|
|
|
|
Error::expect_syntax_node(source, "function", node)?;
|
|
|
|
|
|
|
|
let type_node = node.child(0).unwrap();
|
|
|
|
let type_definition = TypeDefinition::from_syntax_node(source, type_node, context)?;
|
|
|
|
|
|
|
|
let (parameter_types, return_type) = if let Type::Function {
|
|
|
|
parameter_types,
|
|
|
|
return_type,
|
|
|
|
} = type_definition.inner()
|
|
|
|
{
|
|
|
|
(parameter_types, return_type)
|
|
|
|
} else {
|
|
|
|
return Err(Error::TypeCheck {
|
2023-12-02 07:34:23 +00:00
|
|
|
expected: Type::Function {
|
2023-12-02 03:54:25 +00:00
|
|
|
parameter_types: Vec::with_capacity(0),
|
|
|
|
return_type: Box::new(Type::Empty),
|
2023-12-02 07:34:23 +00:00
|
|
|
},
|
|
|
|
actual: type_definition.take_inner(),
|
2023-12-02 03:54:25 +00:00
|
|
|
location: type_node.start_position(),
|
|
|
|
source: source[type_node.byte_range()].to_string(),
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
let child_count = node.child_count();
|
|
|
|
let mut parameters = Vec::new();
|
|
|
|
|
|
|
|
for index in 2..child_count - 2 {
|
|
|
|
let child = node.child(index).unwrap();
|
|
|
|
|
|
|
|
let parameter_index = parameters.len();
|
|
|
|
let parameter_type = parameter_types.get(parameter_index).unwrap_or(&Type::Empty);
|
|
|
|
|
|
|
|
if child.is_named() {
|
|
|
|
let identifier = Identifier::from_syntax_node(source, child, context)?;
|
|
|
|
parameters.push((identifier, TypeDefinition::new(parameter_type.clone())));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let body_node = node.child(child_count - 1).unwrap();
|
|
|
|
let body = Block::from_syntax_node(source, body_node, context)?;
|
|
|
|
|
|
|
|
Ok(Function::new(
|
|
|
|
parameters,
|
|
|
|
body,
|
|
|
|
TypeDefinition::new(return_type.as_ref().clone()),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn run(&self, _source: &str, _context: &Map) -> Result<Value> {
|
|
|
|
Ok(Value::Function(self.clone()))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn expected_type(&self, context: &Map) -> Result<TypeDefinition> {
|
|
|
|
Value::Function(self.clone()).r#type(context)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-22 15:40:50 +00:00
|
|
|
impl Display for Function {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
2023-12-02 04:20:33 +00:00
|
|
|
write!(f, "{}", Value::Function(self.clone()))?;
|
2023-09-30 21:52:37 +00:00
|
|
|
write!(
|
|
|
|
f,
|
2023-11-30 00:23:42 +00:00
|
|
|
"Function {{ parameters: {:?}, body: {:?} }}",
|
|
|
|
self.parameters, self.body
|
2023-09-30 21:52:37 +00:00
|
|
|
)
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-12-02 03:54:25 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use crate::{evaluate, Value};
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn simple_function_declaration() {
|
|
|
|
let test = evaluate(
|
|
|
|
"
|
|
|
|
foo = <fn int -> int> |x| { x }
|
|
|
|
(foo 42)
|
|
|
|
",
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
assert_eq!(Value::Integer(42), test);
|
|
|
|
}
|
|
|
|
}
|