diff --git a/src/abstract_tree/expression.rs b/src/abstract_tree/expression.rs index 7424c25..1a69c73 100644 --- a/src/abstract_tree/expression.rs +++ b/src/abstract_tree/expression.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{value::ValueNode, AbstractTree, Error, Identifier, Result, Value, VariableMap}; +use crate::{value_node::ValueNode, AbstractTree, Error, Identifier, Result, Value, VariableMap}; use super::{function_call::FunctionCall, logic::Logic, math::Math}; diff --git a/src/abstract_tree/identifier.rs b/src/abstract_tree/identifier.rs index bcc07ca..c9e0387 100644 --- a/src/abstract_tree/identifier.rs +++ b/src/abstract_tree/identifier.rs @@ -27,7 +27,7 @@ impl AbstractTree for Identifier { Ok(Identifier(identifier.to_string())) } - fn run(&self, source: &str, context: &mut VariableMap) -> Result { + fn run(&self, _source: &str, context: &mut VariableMap) -> Result { let value = context.get_value(&self.0)?.unwrap_or_default(); Ok(value) diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index 832a109..9353c03 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -17,6 +17,7 @@ pub mod r#match; pub mod math; pub mod statement; pub mod tool; +pub mod value_node; pub mod r#while; pub use { diff --git a/src/abstract_tree/value_node.rs b/src/abstract_tree/value_node.rs new file mode 100644 index 0000000..40e4e13 --- /dev/null +++ b/src/abstract_tree/value_node.rs @@ -0,0 +1,137 @@ +use std::{collections::BTreeMap, ops::Range}; + +use serde::{Deserialize, Serialize}; +use tree_sitter::Node; + +use crate::{AbstractTree, Error, Expression, Identifier, Result, Value, ValueType, VariableMap}; + +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] +pub struct ValueNode { + value_type: ValueType, + start_byte: usize, + end_byte: usize, +} + +impl ValueNode { + pub fn new(value_type: ValueType, start_byte: usize, end_byte: usize) -> Self { + Self { + value_type, + start_byte, + end_byte, + } + } + + pub fn byte_range(&self) -> Range { + self.start_byte..self.end_byte + } +} + +impl AbstractTree for ValueNode { + fn from_syntax_node(source: &str, node: Node) -> Result { + 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" => { + let mut child_nodes = Vec::new(); + + for index in 1..child.child_count() - 1 { + let child_syntax_node = child.child(index).unwrap(); + + if child_syntax_node.is_named() { + let expression = Expression::from_syntax_node(source, child_syntax_node)?; + child_nodes.push(expression); + } + } + + ValueType::ListExact(child_nodes) + } + "table" => ValueType::Table, + "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(); + } + + if child_syntax_node.kind() == "value" { + let child_value = ValueNode::from_syntax_node(source, child_syntax_node)?; + let key = current_key.clone(); + + child_nodes.insert(key, child_value); + } + } + + ValueType::Map(child_nodes) + } + "function" => ValueType::Function, + _ => { + 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, + start_byte: child.start_byte(), + end_byte: child.end_byte(), + }) + } + + fn run(&self, source: &str, context: &mut VariableMap) -> Result { + let value_source = &source[self.byte_range()]; + let value = match &self.value_type { + ValueType::Any => todo!(), + ValueType::String => { + let without_quotes = &value_source[1..value_source.len() - 1]; + + Value::String(without_quotes.to_string()) + } + ValueType::Float => Value::Float(value_source.parse().unwrap()), + ValueType::Integer => Value::Integer(value_source.parse().unwrap()), + ValueType::Boolean => Value::Boolean(value_source.parse().unwrap()), + ValueType::ListExact(nodes) => { + let mut values = Vec::with_capacity(nodes.len()); + + for node in nodes { + let value = node.run(source, context)?; + + values.push(value); + } + + Value::List(values) + } + ValueType::Empty => Value::Empty, + ValueType::Map(nodes) => { + let mut values = VariableMap::new(); + + for (key, node) in nodes { + let value = node.run(source, context)?; + + values.set_value(key.clone(), value)?; + } + + Value::Map(values) + } + ValueType::Table => todo!(), + ValueType::Function => todo!(), + }; + + Ok(value) + } +} diff --git a/src/value/mod.rs b/src/value/mod.rs index 1202c1e..8aa515e 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -1,7 +1,7 @@ //! Types that represent runtime values. use crate::{ error::{Error, Result}, - AbstractTree, Function, Identifier, Table, ValueType, VariableMap, + Function, Table, ValueType, VariableMap, }; use json::JsonValue; @@ -10,15 +10,13 @@ use serde::{ ser::SerializeTuple, Deserialize, Serialize, Serializer, }; -use tree_sitter::Node; use std::{ cmp::Ordering, - collections::BTreeMap, convert::TryFrom, fmt::{self, Display, Formatter}, marker::PhantomData, - ops::{Add, AddAssign, Range, Sub, SubAssign}, + ops::{Add, AddAssign, Sub, SubAssign}, }; pub mod function; @@ -45,120 +43,6 @@ pub enum Value { Empty, } -#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] -pub struct ValueNode { - value_type: ValueType, - start_byte: usize, - end_byte: usize, -} - -impl ValueNode { - pub fn byte_range(&self) -> Range { - self.start_byte..self.end_byte - } -} - -impl AbstractTree for ValueNode { - fn from_syntax_node(source: &str, node: Node) -> Result { - let value_type = match node.kind() { - "integer" => ValueType::Integer, - "float" => ValueType::Float, - "string" => ValueType::String, - "boolean" => ValueType::Boolean, - "empty" => ValueType::Empty, - "list" => { - let mut child_nodes = Vec::new(); - - for index in 0..node.child_count() - 1 { - let child_syntax_node = node.child(index).unwrap(); - let child_value = ValueNode::from_syntax_node(source, child_syntax_node)?; - - child_nodes.push(child_value); - } - - ValueType::ListExact(child_nodes) - } - "table" => ValueType::Table, - "map" => { - let mut child_nodes = BTreeMap::new(); - let mut current_key = "".to_string(); - - for index in 0..node.child_count() - 1 { - let child_syntax_node = node.child(index).unwrap(); - - if child_syntax_node.kind() == "identifier" { - current_key = - Identifier::from_syntax_node(source, child_syntax_node)?.take_inner(); - } - - if child_syntax_node.kind() == "value" { - let child_value = ValueNode::from_syntax_node(source, child_syntax_node)?; - let key = current_key.clone(); - - child_nodes.insert(key, child_value); - } - } - - ValueType::Map(child_nodes) - } - "function" => ValueType::Function, - _ => { - return Err(Error::UnexpectedSyntaxNode { - expected: - "string, integer, float, boolean, list, table, map, function or empty", - actual: node.kind(), - location: node.start_position(), - relevant_source: source[node.byte_range()].to_string(), - }) - } - }; - - Ok(ValueNode { - value_type, - start_byte: node.start_byte(), - end_byte: node.end_byte(), - }) - } - - fn run(&self, source: &str, context: &mut VariableMap) -> Result { - let value_source = &source[self.byte_range()]; - let value = match &self.value_type { - ValueType::Any => todo!(), - ValueType::String => Value::String(value_source.to_owned()), - ValueType::Float => Value::Float(value_source.parse().unwrap()), - ValueType::Integer => Value::Integer(value_source.parse().unwrap()), - ValueType::Boolean => Value::Boolean(value_source.parse().unwrap()), - ValueType::ListExact(nodes) => { - let mut values = Vec::with_capacity(nodes.len()); - - for node in nodes { - let value = node.run(source, context)?; - - values.push(value); - } - - Value::List(values) - } - ValueType::Empty => Value::Empty, - ValueType::Map(nodes) => { - let mut values = VariableMap::new(); - - for (key, node) in nodes { - let value = node.run(source, context)?; - - values.set_value(key.clone(), value)?; - } - - Value::Map(values) - } - ValueType::Table => todo!(), - ValueType::Function => todo!(), - }; - - Ok(value) - } -} - impl Value { pub fn value_type(&self) -> ValueType { ValueType::from(self) diff --git a/src/value/value_type.rs b/src/value/value_type.rs index 25eb41b..abe1bc6 100644 --- a/src/value/value_type.rs +++ b/src/value/value_type.rs @@ -5,9 +5,7 @@ use std::{ use serde::{Deserialize, Serialize}; -use crate::Value; - -use super::ValueNode; +use crate::{value_node::ValueNode, Expression, Value}; /// The type of a `Value`. #[derive(Clone, Serialize, Deserialize, PartialOrd, Ord)] @@ -17,7 +15,7 @@ pub enum ValueType { Float, Integer, Boolean, - ListExact(Vec), + ListExact(Vec), Empty, Map(BTreeMap), Table, @@ -66,7 +64,7 @@ impl Display for ValueType { write!(f, ")") } ValueType::Empty => write!(f, "empty"), - ValueType::Map(map) => write!(f, "map"), + ValueType::Map(_map) => write!(f, "map"), ValueType::Table => write!(f, "table"), ValueType::Function => write!(f, "function"), } @@ -90,11 +88,7 @@ impl From<&Value> for ValueType { Value::List(list) => { let value_nodes = list .iter() - .map(|value| ValueNode { - value_type: value.value_type(), - start_byte: 0, - end_byte: 0, - }) + .map(|value| Expression::Value(ValueNode::new(value.value_type(), 0, 0))) .collect(); ValueType::ListExact(value_nodes) @@ -104,11 +98,7 @@ impl From<&Value> for ValueType { for (key, value) in map.inner() { let value_type = ValueType::from(value); - let value_node = ValueNode { - value_type, - start_byte: 0, - end_byte: 0, - }; + let value_node = ValueNode::new(value_type, 0, 0); value_nodes.insert(key.to_string(), value_node); }