2023-11-18 01:10:07 +00:00
|
|
|
use std::collections::BTreeMap;
|
2023-10-10 18:12:07 +00:00
|
|
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use tree_sitter::Node;
|
|
|
|
|
2023-10-10 21:12:38 +00:00
|
|
|
use crate::{
|
2023-10-31 19:21:13 +00:00
|
|
|
AbstractTree, Block, Error, Expression, Function, Identifier, List, Map, Result, Statement,
|
|
|
|
Table, Value, ValueType,
|
2023-10-10 21:12:38 +00:00
|
|
|
};
|
2023-10-10 18:12:07 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
|
|
|
pub struct ValueNode {
|
|
|
|
value_type: ValueType,
|
2023-11-18 01:10:07 +00:00
|
|
|
source: String,
|
2023-10-10 18:12:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ValueNode {
|
2023-11-18 01:10:07 +00:00
|
|
|
pub fn new(value_type: ValueType, source: String) -> Self {
|
|
|
|
Self { value_type, source }
|
2023-10-10 18:12:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AbstractTree for ValueNode {
|
|
|
|
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
|
|
|
debug_assert_eq!("value", node.kind());
|
|
|
|
|
|
|
|
let child = node.child(0).unwrap();
|
|
|
|
let value_type = match child.kind() {
|
|
|
|
"integer" => ValueType::Integer,
|
|
|
|
"float" => ValueType::Float,
|
|
|
|
"string" => ValueType::String,
|
|
|
|
"boolean" => ValueType::Boolean,
|
|
|
|
"empty" => ValueType::Empty,
|
|
|
|
"list" => {
|
2023-10-28 14:28:43 +00:00
|
|
|
let mut expressions = Vec::new();
|
2023-10-10 18:12:07 +00:00
|
|
|
|
|
|
|
for index in 1..child.child_count() - 1 {
|
2023-10-28 14:28:43 +00:00
|
|
|
let current_node = child.child(index).unwrap();
|
2023-10-10 18:12:07 +00:00
|
|
|
|
2023-10-28 14:28:43 +00:00
|
|
|
if current_node.is_named() {
|
|
|
|
let expression = Expression::from_syntax_node(source, current_node)?;
|
|
|
|
expressions.push(expression);
|
2023-10-10 18:12:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-28 14:28:43 +00:00
|
|
|
ValueType::List(expressions)
|
2023-10-10 18:12:07 +00:00
|
|
|
}
|
2023-10-18 23:26:49 +00:00
|
|
|
"table" => {
|
2023-10-31 22:18:39 +00:00
|
|
|
let identifier_list_node = child.child(1).unwrap();
|
|
|
|
let identifier_count = identifier_list_node.child_count();
|
|
|
|
let mut column_names = Vec::with_capacity(identifier_count);
|
2023-10-18 23:26:49 +00:00
|
|
|
|
2023-10-31 22:18:39 +00:00
|
|
|
for index in 0..identifier_count {
|
|
|
|
let identifier_node = identifier_list_node.child(index).unwrap();
|
2023-10-18 23:26:49 +00:00
|
|
|
|
2023-10-31 22:18:39 +00:00
|
|
|
if identifier_node.is_named() {
|
|
|
|
let identifier = Identifier::from_syntax_node(source, identifier_node)?;
|
2023-10-18 23:26:49 +00:00
|
|
|
|
|
|
|
column_names.push(identifier)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-31 22:18:39 +00:00
|
|
|
let expression_node = child.child(2).unwrap();
|
|
|
|
let expression = Expression::from_syntax_node(source, expression_node)?;
|
|
|
|
|
2023-10-18 23:26:49 +00:00
|
|
|
ValueType::Table {
|
|
|
|
column_names,
|
|
|
|
rows: Box::new(expression),
|
|
|
|
}
|
|
|
|
}
|
2023-10-10 18:12:07 +00:00
|
|
|
"map" => {
|
|
|
|
let mut child_nodes = BTreeMap::new();
|
|
|
|
let mut current_key = "".to_string();
|
|
|
|
|
|
|
|
for index in 0..child.child_count() - 1 {
|
|
|
|
let child_syntax_node = child.child(index).unwrap();
|
|
|
|
|
|
|
|
if child_syntax_node.kind() == "identifier" {
|
|
|
|
current_key =
|
|
|
|
Identifier::from_syntax_node(source, child_syntax_node)?.take_inner();
|
|
|
|
}
|
|
|
|
|
2023-10-31 19:21:13 +00:00
|
|
|
if child_syntax_node.kind() == "statement" {
|
2023-10-10 18:12:07 +00:00
|
|
|
let key = current_key.clone();
|
2023-10-31 19:21:13 +00:00
|
|
|
let statement = Statement::from_syntax_node(source, child_syntax_node)?;
|
2023-10-10 18:12:07 +00:00
|
|
|
|
2023-10-31 19:21:13 +00:00
|
|
|
child_nodes.insert(key, statement);
|
2023-10-10 18:12:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ValueType::Map(child_nodes)
|
|
|
|
}
|
2023-10-10 21:12:38 +00:00
|
|
|
"function" => {
|
2023-10-31 22:18:39 +00:00
|
|
|
let parameters_node = child.child_by_field_name("parameters");
|
|
|
|
let parameters = if let Some(node) = parameters_node {
|
|
|
|
let mut parameter_list = Vec::new();
|
2023-10-10 21:12:38 +00:00
|
|
|
|
2023-10-31 22:18:39 +00:00
|
|
|
for index in 0..node.child_count() {
|
|
|
|
let child_node = node.child(index).unwrap();
|
2023-10-10 21:12:38 +00:00
|
|
|
|
2023-10-31 22:18:39 +00:00
|
|
|
if child_node.is_named() {
|
|
|
|
let parameter = Identifier::from_syntax_node(source, child_node)?;
|
2023-10-10 21:12:38 +00:00
|
|
|
|
2023-10-31 22:18:39 +00:00
|
|
|
parameter_list.push(parameter);
|
|
|
|
}
|
2023-10-10 21:12:38 +00:00
|
|
|
}
|
|
|
|
|
2023-10-31 22:18:39 +00:00
|
|
|
Some(parameter_list)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
let body_node = child.child_by_field_name("body").unwrap();
|
|
|
|
let body = Block::from_syntax_node(source, body_node)?;
|
2023-10-10 21:12:38 +00:00
|
|
|
|
2023-10-31 22:18:39 +00:00
|
|
|
ValueType::Function(Function::new(parameters, body))
|
2023-10-10 21:12:38 +00:00
|
|
|
}
|
2023-10-10 18:12:07 +00:00
|
|
|
_ => {
|
|
|
|
return Err(Error::UnexpectedSyntaxNode {
|
|
|
|
expected:
|
|
|
|
"string, integer, float, boolean, list, table, map, function or empty",
|
|
|
|
actual: child.kind(),
|
|
|
|
location: child.start_position(),
|
|
|
|
relevant_source: source[child.byte_range()].to_string(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(ValueNode {
|
|
|
|
value_type,
|
2023-11-18 01:10:07 +00:00
|
|
|
source: source[child.byte_range()].to_string(),
|
2023-10-10 18:12:07 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-10-25 20:44:50 +00:00
|
|
|
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
2023-10-10 18:12:07 +00:00
|
|
|
let value = match &self.value_type {
|
|
|
|
ValueType::Any => todo!(),
|
|
|
|
ValueType::String => {
|
2023-11-18 01:10:07 +00:00
|
|
|
let without_quotes = &self.source[1..self.source.len() - 1];
|
2023-10-10 18:12:07 +00:00
|
|
|
|
|
|
|
Value::String(without_quotes.to_string())
|
|
|
|
}
|
2023-11-18 01:10:07 +00:00
|
|
|
ValueType::Float => Value::Float(self.source.parse().unwrap()),
|
|
|
|
ValueType::Integer => Value::Integer(self.source.parse().unwrap()),
|
|
|
|
ValueType::Boolean => Value::Boolean(self.source.parse().unwrap()),
|
2023-10-28 14:28:43 +00:00
|
|
|
ValueType::List(nodes) => {
|
2023-10-10 18:12:07 +00:00
|
|
|
let mut values = Vec::with_capacity(nodes.len());
|
|
|
|
|
|
|
|
for node in nodes {
|
|
|
|
let value = node.run(source, context)?;
|
|
|
|
|
|
|
|
values.push(value);
|
|
|
|
}
|
|
|
|
|
2023-10-26 22:03:59 +00:00
|
|
|
Value::List(List::with_items(values))
|
2023-10-10 18:12:07 +00:00
|
|
|
}
|
|
|
|
ValueType::Empty => Value::Empty,
|
|
|
|
ValueType::Map(nodes) => {
|
2023-10-29 23:31:06 +00:00
|
|
|
let map = Map::new();
|
2023-10-10 18:12:07 +00:00
|
|
|
|
2023-11-05 18:54:29 +00:00
|
|
|
{
|
|
|
|
let mut variables = map.variables_mut()?;
|
|
|
|
|
|
|
|
for (key, node) in nodes {
|
|
|
|
let value = node.run(source, context)?;
|
2023-10-10 18:12:07 +00:00
|
|
|
|
2023-11-05 18:54:29 +00:00
|
|
|
variables.insert(key.clone(), value);
|
|
|
|
}
|
2023-10-10 18:12:07 +00:00
|
|
|
}
|
|
|
|
|
2023-10-29 23:31:06 +00:00
|
|
|
Value::Map(map)
|
2023-10-10 18:12:07 +00:00
|
|
|
}
|
2023-10-18 23:26:49 +00:00
|
|
|
ValueType::Table {
|
|
|
|
column_names,
|
|
|
|
rows: row_expression,
|
|
|
|
} => {
|
|
|
|
let mut headers = Vec::with_capacity(column_names.len());
|
|
|
|
let mut rows = Vec::new();
|
|
|
|
|
|
|
|
for identifier in column_names {
|
|
|
|
let name = identifier.inner().clone();
|
|
|
|
|
|
|
|
headers.push(name)
|
|
|
|
}
|
|
|
|
|
|
|
|
let _row_values = row_expression.run(source, context)?;
|
2023-10-26 22:03:59 +00:00
|
|
|
let row_values = _row_values.as_list()?.items();
|
2023-10-18 23:26:49 +00:00
|
|
|
|
2023-10-26 22:03:59 +00:00
|
|
|
for value in row_values.iter() {
|
|
|
|
let row = value.as_list()?.items().clone();
|
2023-10-18 23:26:49 +00:00
|
|
|
|
|
|
|
rows.push(row)
|
|
|
|
}
|
|
|
|
|
|
|
|
let table = Table::from_raw_parts(headers, rows);
|
|
|
|
|
|
|
|
Value::Table(table)
|
|
|
|
}
|
2023-10-10 21:12:38 +00:00
|
|
|
ValueType::Function(function) => Value::Function(function.clone()),
|
2023-10-10 18:12:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(value)
|
|
|
|
}
|
|
|
|
}
|