Implement ValueNode

This commit is contained in:
Jeff 2023-10-10 14:12:07 -04:00
parent 9450e6dc96
commit 8188aa41a5
6 changed files with 147 additions and 135 deletions

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; 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}; use super::{function_call::FunctionCall, logic::Logic, math::Math};

View File

@ -27,7 +27,7 @@ impl AbstractTree for Identifier {
Ok(Identifier(identifier.to_string())) Ok(Identifier(identifier.to_string()))
} }
fn run(&self, source: &str, context: &mut VariableMap) -> Result<Value> { fn run(&self, _source: &str, context: &mut VariableMap) -> Result<Value> {
let value = context.get_value(&self.0)?.unwrap_or_default(); let value = context.get_value(&self.0)?.unwrap_or_default();
Ok(value) Ok(value)

View File

@ -17,6 +17,7 @@ pub mod r#match;
pub mod math; pub mod math;
pub mod statement; pub mod statement;
pub mod tool; pub mod tool;
pub mod value_node;
pub mod r#while; pub mod r#while;
pub use { pub use {

View File

@ -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<usize> {
self.start_byte..self.end_byte
}
}
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" => {
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<Value> {
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)
}
}

View File

@ -1,7 +1,7 @@
//! Types that represent runtime values. //! Types that represent runtime values.
use crate::{ use crate::{
error::{Error, Result}, error::{Error, Result},
AbstractTree, Function, Identifier, Table, ValueType, VariableMap, Function, Table, ValueType, VariableMap,
}; };
use json::JsonValue; use json::JsonValue;
@ -10,15 +10,13 @@ use serde::{
ser::SerializeTuple, ser::SerializeTuple,
Deserialize, Serialize, Serializer, Deserialize, Serialize, Serializer,
}; };
use tree_sitter::Node;
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
collections::BTreeMap,
convert::TryFrom, convert::TryFrom,
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
marker::PhantomData, marker::PhantomData,
ops::{Add, AddAssign, Range, Sub, SubAssign}, ops::{Add, AddAssign, Sub, SubAssign},
}; };
pub mod function; pub mod function;
@ -45,120 +43,6 @@ pub enum Value {
Empty, 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<usize> {
self.start_byte..self.end_byte
}
}
impl AbstractTree for ValueNode {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
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<Value> {
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 { impl Value {
pub fn value_type(&self) -> ValueType { pub fn value_type(&self) -> ValueType {
ValueType::from(self) ValueType::from(self)

View File

@ -5,9 +5,7 @@ use std::{
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::Value; use crate::{value_node::ValueNode, Expression, Value};
use super::ValueNode;
/// The type of a `Value`. /// The type of a `Value`.
#[derive(Clone, Serialize, Deserialize, PartialOrd, Ord)] #[derive(Clone, Serialize, Deserialize, PartialOrd, Ord)]
@ -17,7 +15,7 @@ pub enum ValueType {
Float, Float,
Integer, Integer,
Boolean, Boolean,
ListExact(Vec<ValueNode>), ListExact(Vec<Expression>),
Empty, Empty,
Map(BTreeMap<String, ValueNode>), Map(BTreeMap<String, ValueNode>),
Table, Table,
@ -66,7 +64,7 @@ impl Display for ValueType {
write!(f, ")") write!(f, ")")
} }
ValueType::Empty => write!(f, "empty"), ValueType::Empty => write!(f, "empty"),
ValueType::Map(map) => write!(f, "map"), ValueType::Map(_map) => write!(f, "map"),
ValueType::Table => write!(f, "table"), ValueType::Table => write!(f, "table"),
ValueType::Function => write!(f, "function"), ValueType::Function => write!(f, "function"),
} }
@ -90,11 +88,7 @@ impl From<&Value> for ValueType {
Value::List(list) => { Value::List(list) => {
let value_nodes = list let value_nodes = list
.iter() .iter()
.map(|value| ValueNode { .map(|value| Expression::Value(ValueNode::new(value.value_type(), 0, 0)))
value_type: value.value_type(),
start_byte: 0,
end_byte: 0,
})
.collect(); .collect();
ValueType::ListExact(value_nodes) ValueType::ListExact(value_nodes)
@ -104,11 +98,7 @@ impl From<&Value> for ValueType {
for (key, value) in map.inner() { for (key, value) in map.inner() {
let value_type = ValueType::from(value); let value_type = ValueType::from(value);
let value_node = ValueNode { let value_node = ValueNode::new(value_type, 0, 0);
value_type,
start_byte: 0,
end_byte: 0,
};
value_nodes.insert(key.to_string(), value_node); value_nodes.insert(key.to_string(), value_node);
} }