Implement ValueNode
This commit is contained in:
parent
9450e6dc96
commit
8188aa41a5
@ -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};
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
137
src/abstract_tree/value_node.rs
Normal file
137
src/abstract_tree/value_node.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
120
src/value/mod.rs
120
src/value/mod.rs
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user