1
0
dust/src/abstract_tree/value_node.rs

257 lines
9.4 KiB
Rust
Raw Normal View History

use std::collections::BTreeMap;
2023-10-10 14:12:07 -04:00
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
2023-10-10 17:12:38 -04:00
use crate::{
AbstractTree, BuiltInValue, Error, Expression, Function, Identifier, List, Result, Structure,
StructureInstantiator, Type, Value,
2023-10-10 17:12:38 -04:00
};
2023-10-10 14:12:07 -04:00
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
2023-11-27 17:53:12 -05:00
pub enum ValueNode {
Boolean(String),
Float(String),
2023-12-01 22:54:25 -05:00
Function(Function),
2023-11-27 17:53:12 -05:00
Integer(String),
String(String),
List(Vec<Expression>),
Option(Option<Box<Expression>>),
Structure {
definition_name: Identifier,
instantiator: StructureInstantiator,
},
StructureDefinition(StructureInstantiator),
BuiltInValue(BuiltInValue),
2023-10-10 14:12:07 -04:00
}
impl AbstractTree for ValueNode {
fn from_syntax_node(source: &str, node: Node, context: &Structure) -> Result<Self> {
2023-11-30 09:30:25 -05:00
Error::expect_syntax_node(source, "value", node)?;
2023-10-10 14:12:07 -04:00
let child = node.child(0).unwrap();
2023-11-27 17:53:12 -05:00
let value_node = match child.kind() {
"boolean" => ValueNode::Boolean(source[child.byte_range()].to_string()),
"float" => ValueNode::Float(source[child.byte_range()].to_string()),
2024-01-01 04:59:27 -05:00
"function" => ValueNode::Function(Function::from_syntax_node(source, child, context)?),
2023-11-27 17:53:12 -05:00
"integer" => ValueNode::Integer(source[child.byte_range()].to_string()),
"string" => {
let without_quotes = child.start_byte() + 1..child.end_byte() - 1;
ValueNode::String(source[without_quotes].to_string())
}
2023-10-10 14:12:07 -04:00
"list" => {
2023-10-28 10:28:43 -04:00
let mut expressions = Vec::new();
2023-10-10 14:12:07 -04:00
for index in 1..child.child_count() - 1 {
2023-10-28 10:28:43 -04:00
let current_node = child.child(index).unwrap();
2023-10-10 14:12:07 -04:00
2023-10-28 10:28:43 -04:00
if current_node.is_named() {
2023-11-29 22:54:46 -05:00
let expression =
Expression::from_syntax_node(source, current_node, context)?;
2023-10-28 10:28:43 -04:00
expressions.push(expression);
2023-10-10 14:12:07 -04:00
}
}
2023-11-27 17:53:12 -05:00
ValueNode::List(expressions)
2023-10-10 14:12:07 -04:00
}
"structure" => {
let identifier_node = child.child(1).unwrap();
let identifier = Identifier::from_syntax_node(source, identifier_node, context)?;
2023-10-10 14:12:07 -04:00
let instantiator_node = child.child(2);
2023-10-10 14:12:07 -04:00
if let Some(node) = instantiator_node {
let instantiator =
StructureInstantiator::from_syntax_node(source, node, context)?;
2023-12-20 18:36:42 -05:00
ValueNode::Structure {
definition_name: identifier,
instantiator,
2023-10-10 14:12:07 -04:00
}
} else {
todo!()
2023-10-10 14:12:07 -04:00
}
}
"structure_definition" => {
let instantiator_node = child.child(1).unwrap();
2023-10-10 14:12:07 -04:00
ValueNode::StructureDefinition(StructureInstantiator::from_syntax_node(
source,
instantiator_node,
context,
)?)
2023-10-10 14:12:07 -04:00
}
"option" => {
let first_grandchild = child.child(0).unwrap();
if first_grandchild.kind() == "none" {
ValueNode::Option(None)
} else {
let expression_node = child.child(2).unwrap();
let expression =
Expression::from_syntax_node(source, expression_node, context)?;
ValueNode::Option(Some(Box::new(expression)))
}
}
"built_in_value" => {
let built_in_value_node = child.child(0).unwrap();
ValueNode::BuiltInValue(BuiltInValue::from_syntax_node(
source,
built_in_value_node,
context,
)?)
}
2023-10-10 14:12:07 -04:00
_ => {
return Err(Error::UnexpectedSyntaxNode {
2023-12-30 02:04:39 -05:00
expected: "string, integer, float, boolean, list, map, or option".to_string(),
actual: child.kind().to_string(),
2023-10-10 14:12:07 -04:00
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
})
}
};
2023-11-27 17:53:12 -05:00
Ok(value_node)
2023-10-10 14:12:07 -04:00
}
fn check_type(&self, context: &Structure) -> Result<()> {
match self {
ValueNode::StructureDefinition(instantiator) => {
for (_, (statement_option, type_definition_option)) in instantiator.iter() {
if let (Some(statement), Some(type_definition)) =
(statement_option, type_definition_option)
{
type_definition
.inner()
.check(&statement.expected_type(context)?)?;
}
}
}
_ => {}
}
Ok(())
}
fn run(&self, source: &str, context: &Structure) -> Result<Value> {
2023-11-27 17:53:12 -05:00
let value = match self {
ValueNode::Boolean(value_source) => Value::Boolean(value_source.parse().unwrap()),
ValueNode::Float(value_source) => Value::Float(value_source.parse().unwrap()),
2023-12-01 22:54:25 -05:00
ValueNode::Function(function) => Value::Function(function.clone()),
2023-11-27 17:53:12 -05:00
ValueNode::Integer(value_source) => Value::Integer(value_source.parse().unwrap()),
ValueNode::String(value_source) => Value::string(value_source.clone()),
2023-11-27 17:53:12 -05:00
ValueNode::List(expressions) => {
let mut values = Vec::with_capacity(expressions.len());
for node in expressions {
2023-10-10 14:12:07 -04:00
let value = node.run(source, context)?;
values.push(value);
}
2023-10-26 18:03:59 -04:00
Value::List(List::with_items(values))
2023-10-10 14:12:07 -04:00
}
ValueNode::Option(option) => {
let option_value = if let Some(expression) = option {
Some(Box::new(expression.run(source, context)?))
} else {
None
};
Value::Option(option_value)
}
ValueNode::Structure {
definition_name,
instantiator,
} => {
let variables = context.variables()?;
let definition = if let Some((value, _)) = variables.get(definition_name.inner()) {
value.as_structure()?.instantiator()
} else {
return Err(Error::VariableIdentifierNotFound(
definition_name.inner().clone(),
));
};
2023-10-10 14:12:07 -04:00
let structure = Structure::new(BTreeMap::new(), definition.clone());
2023-10-10 14:12:07 -04:00
for (key, (statement_option, type_definition_option)) in
definition.iter().chain(instantiator.iter())
{
let value = if let Some(statement) = statement_option {
statement.run(source, context)?
} else {
Value::none()
};
if let Some(type_definition) = &type_definition_option {
structure.set(
key.to_string(),
value,
Some(type_definition.inner().clone()),
)?;
} else {
structure.set(key.to_string(), value, None)?;
2023-11-05 13:54:29 -05:00
}
2023-10-10 14:12:07 -04:00
}
Value::Structure(structure)
2023-10-10 14:12:07 -04:00
}
ValueNode::StructureDefinition(instantiator) => instantiator.run(source, context)?,
ValueNode::BuiltInValue(built_in_value) => built_in_value.run(source, context)?,
2023-10-10 14:12:07 -04:00
};
Ok(value)
}
2023-11-29 19:23:42 -05:00
fn expected_type(&self, context: &Structure) -> Result<Type> {
2023-12-31 18:10:42 -05:00
let r#type = match self {
2023-12-05 17:08:22 -05:00
ValueNode::Boolean(_) => Type::Boolean,
ValueNode::Float(_) => Type::Float,
ValueNode::Function(function) => function.r#type().clone(),
ValueNode::Integer(_) => Type::Integer,
ValueNode::String(_) => Type::String,
2023-11-29 19:23:42 -05:00
ValueNode::List(expressions) => {
2023-11-30 00:57:15 -05:00
let mut previous_type = None;
for expression in expressions {
let expression_type = expression.expected_type(context)?;
if let Some(previous) = previous_type {
if expression_type != previous {
2023-12-05 17:08:22 -05:00
return Ok(Type::List(Box::new(Type::Any)));
2023-11-30 00:57:15 -05:00
}
}
2023-11-29 19:23:42 -05:00
2023-11-30 00:57:15 -05:00
previous_type = Some(expression_type);
}
if let Some(previous) = previous_type {
2023-12-05 17:08:22 -05:00
Type::List(Box::new(previous))
2023-11-30 00:57:15 -05:00
} else {
2023-12-05 17:08:22 -05:00
Type::List(Box::new(Type::Any))
2023-11-30 00:57:15 -05:00
}
2023-11-29 19:23:42 -05:00
}
ValueNode::Option(option) => {
if let Some(expression) = option {
2023-12-26 17:19:12 -05:00
Type::Option(Box::new(expression.expected_type(context)?))
} else {
2023-12-26 17:19:12 -05:00
Type::None
}
}
ValueNode::Structure {
definition_name, ..
} => Type::Structure(definition_name.clone()),
ValueNode::StructureDefinition(instantiator) => {
Type::StructureDefinition(instantiator.clone())
2024-01-03 19:57:06 -05:00
}
ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?,
2023-11-29 19:23:42 -05:00
};
2023-12-31 18:10:42 -05:00
Ok(r#type)
2023-11-29 19:23:42 -05:00
}
2023-10-10 14:12:07 -04:00
}