1
0

Implement tables

This commit is contained in:
Jeff 2023-10-02 23:19:01 -04:00
parent a42b43ed78
commit 5551f40ffd
3 changed files with 241 additions and 162 deletions

View File

@ -5,7 +5,7 @@
use std::fmt::{self, Debug, Formatter};
use serde::{Deserialize, Serialize};
use tree_sitter::{Parser, Tree as TSTree, TreeCursor};
use tree_sitter::{Node, Parser, Tree as TSTree, TreeCursor};
use crate::{language, Error, Primitive, Result, Value, VariableMap};
@ -63,7 +63,7 @@ pub trait EvaluatorTree: Sized {
///
/// If necessary, the source code can be accessed directly by getting the
/// node's byte range.
fn new(source: &str, cursor: &mut TreeCursor) -> Result<Self>;
fn from_syntax_node(node: Node, source: &str) -> Result<Self>;
/// Execute dust code by traversing the tree
fn run(&self, context: &mut VariableMap) -> Result<Value>;
@ -109,10 +109,8 @@ impl<'context, 'code> Evaluator<'context, 'code> {
assert_eq!(cursor_0.node().kind(), "root");
cursor_1.goto_first_child();
for _ in node.children(&mut cursor_0) {
let item_result = Item::new(self.source, &mut cursor_1);
for item_node in node.children(&mut cursor_0) {
let item_result = Item::from_syntax_node(item_node, self.source);
match item_result {
Ok(item) => {
@ -140,12 +138,10 @@ pub enum Item {
}
impl EvaluatorTree for Item {
fn new(source: &str, cursor: &mut TreeCursor) -> Result<Self> {
let node = cursor.node();
cursor.goto_first_child();
let child = cursor.node();
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
debug_assert_eq!(node.kind(), "item");
assert_eq!(node.kind(), "item");
let child = node.child(0).unwrap();
if child.kind() == "comment" {
let byte_range = child.byte_range();
@ -153,7 +149,7 @@ impl EvaluatorTree for Item {
Ok(Item::Comment(comment_text.to_string()))
} else if child.kind() == "statement" {
Ok(Item::Statement(Statement::new(source, cursor)?))
Ok(Item::Statement(Statement::from_syntax_node(child, source)?))
} else {
Err(Error::UnexpectedSyntax {
expected: "comment or statement",
@ -182,12 +178,15 @@ pub enum Statement {
}
impl EvaluatorTree for Statement {
fn new(source: &str, cursor: &mut TreeCursor) -> Result<Self> {
cursor.goto_first_child();
let child = cursor.node();
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
debug_assert_eq!(node.kind(), "statement");
let child = node.child(0).unwrap();
match child.kind() {
"expression" => Ok(Self::Expression(Expression::new(source, cursor)?)),
"expression" => Ok(Self::Expression(Expression::from_syntax_node(
child, source,
)?)),
_ => Err(Error::UnexpectedSyntax {
expected: "expression",
actual: child.kind(),
@ -214,20 +213,24 @@ pub enum Expression {
}
impl EvaluatorTree for Expression {
fn new(source: &str, cursor: &mut TreeCursor) -> Result<Self> {
let node = cursor.node();
cursor.goto_first_child();
let child = cursor.node();
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
debug_assert_eq!(node.kind(), "expression");
assert_eq!(node.kind(), "expression");
let child = node.child(0).unwrap();
let expression = match child.kind() {
"identifier" => Self::Identifier(Identifier::new(source, cursor)?),
"value" => Expression::Value(Value::from_source(source, cursor)?),
"control_flow" => Expression::ControlFlow(Box::new(ControlFlow::new(source, cursor)?)),
"assignment" => Expression::Assignment(Box::new(Assignment::new(source, cursor)?)),
"math" => Expression::Math(Box::new(Math::new(source, cursor)?)),
"function_call" => Expression::FunctionCall(FunctionCall::new(source, cursor)?),
"identifier" => Self::Identifier(Identifier::from_syntax_node(child, source)?),
"value" => Expression::Value(Value::from_syntax_node(child, source)?),
"control_flow" => {
Expression::ControlFlow(Box::new(ControlFlow::from_syntax_node(child, source)?))
}
"assignment" => {
Expression::Assignment(Box::new(Assignment::from_syntax_node(child, source)?))
}
"math" => Expression::Math(Box::new(Math::from_syntax_node(child, source)?)),
"function_call" => {
Expression::FunctionCall(FunctionCall::from_syntax_node(child, source)?)
}
_ => return Err(Error::UnexpectedSyntax {
expected:
"identifier, operation, control_flow, assignment, math, function_call or value",
@ -265,9 +268,7 @@ impl Identifier {
}
impl EvaluatorTree for Identifier {
fn new(source: &str, cursor: &mut TreeCursor) -> Result<Self> {
let node = cursor.node();
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
assert_eq!(node.kind(), "identifier");
let identifier = &source[node.byte_range()];
@ -290,35 +291,26 @@ pub struct ControlFlow {
}
impl EvaluatorTree for ControlFlow {
fn new(source: &str, cursor: &mut TreeCursor) -> Result<Self> {
let node = cursor.node();
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
assert_eq!(node.kind(), "control_flow");
println!("{node:?}");
// Skip the child nodes for the keywords "if", "then" and "else".
let if_node = node.child_by_field_name("if_expression").unwrap();
cursor.reset(if_node);
let if_expression = Expression::new(source, cursor)?;
println!("{:?}", cursor.node());
let if_expression = Expression::from_syntax_node(if_node, source)?;
let then_node = node.child_by_field_name("then_statement").unwrap();
let then_statement = Statement::from_syntax_node(then_node, source)?;
cursor.reset(then_node);
let position = cursor.node();
let then_statement = Statement::new(source, cursor)?;
cursor.reset(position);
let else_node = node.child_by_field_name("else_statement");
let else_statement = if let Some(node) = else_node {
Some(Statement::from_syntax_node(node, source)?)
} else {
None
};
Ok(ControlFlow {
if_expression,
then_statement,
else_statement: None,
else_statement,
})
}
@ -342,18 +334,14 @@ pub struct Assignment {
}
impl EvaluatorTree for Assignment {
fn new(source: &str, cursor: &mut TreeCursor) -> Result<Self> {
let node = cursor.node();
cursor.goto_first_child();
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
assert_eq!(node.kind(), "assignment");
cursor.goto_next_sibling();
let identifier = Identifier::new(source, cursor)?;
let identifier_node = node.child(0).unwrap();
let identifier = Identifier::from_syntax_node(identifier_node, source)?;
cursor.goto_next_sibling();
let statement = Statement::new(source, cursor)?;
cursor.goto_next_sibling();
let statement_node = node.child(2).unwrap();
let statement = Statement::from_syntax_node(statement_node, source)?;
Ok(Assignment {
identifier,
@ -379,15 +367,13 @@ pub struct Math {
}
impl EvaluatorTree for Math {
fn new(source: &str, cursor: &mut TreeCursor) -> Result<Self> {
let node = cursor.node();
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
assert_eq!(node.kind(), "math");
cursor.goto_first_child();
let left = Expression::new(source, cursor)?;
let left_node = node.child(0).unwrap();
let left = Expression::from_syntax_node(left_node, source)?;
cursor.goto_next_sibling();
let operator_node = cursor.node();
let operator_node = left_node.next_sibling().unwrap();
let operator = match operator_node.kind() {
"+" => MathOperator::Add,
"-" => MathOperator::Subtract,
@ -403,8 +389,8 @@ impl EvaluatorTree for Math {
}
};
cursor.goto_next_sibling();
let right = Expression::new(source, cursor)?;
let right_node = operator_node.next_sibling().unwrap();
let right = Expression::from_syntax_node(right_node, source)?;
Ok(Math {
left,
@ -444,22 +430,15 @@ pub struct FunctionCall {
}
impl EvaluatorTree for FunctionCall {
fn new(source: &str, cursor: &mut TreeCursor) -> Result<Self> {
let node = cursor.node();
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
assert_eq!(node.kind(), "function_call");
cursor.goto_first_child();
let identifier = Identifier::new(source, cursor)?;
let identifier_node = node.child(0).unwrap();
let identifier = Identifier::from_syntax_node(identifier_node, source)?;
let mut expressions = Vec::new();
for index in 2..node.child_count() - 1 {
cursor.goto_next_sibling();
let expression = Expression::new(source, cursor)?;
expressions.push(expression);
}
todo!();
Ok(FunctionCall {
identifier,

View File

@ -37,6 +37,50 @@ pub enum Primitive {
Empty,
}
impl Primitive {
fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
match node.kind() {
"integer" => Primitive::integer_from_source(source, node.byte_range()),
"float" => Primitive::float_from_source(source, node.byte_range()),
"boolean" => Primitive::boolean_from_source(source, node.byte_range()),
"string" => Primitive::string_from_source(source, node.byte_range()),
"empty" => Ok(Primitive::Empty),
_ => Err(Error::UnexpectedSyntax {
expected: "integer, float, boolean, string or empty",
actual: node.kind(),
location: node.start_position(),
}),
}
}
pub fn integer_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
let value_snippet = &source[byte_range];
let raw = value_snippet.parse::<i64>().unwrap_or_default();
Ok(Primitive::Integer(raw))
}
pub fn float_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
let value_snippet = &source[byte_range];
let raw = value_snippet.parse::<f64>().unwrap_or_default();
Ok(Primitive::Float(raw))
}
pub fn boolean_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
let value_snippet = &source[byte_range];
let raw = value_snippet.parse::<bool>().unwrap_or_default();
Ok(Primitive::Boolean(raw))
}
pub fn string_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
let value_snippet = &source[byte_range];
let without_quotes = &value_snippet[1..value_snippet.len() - 1];
Ok(Primitive::String(without_quotes.to_string()))
}
}
impl Eq for Primitive {}
impl Ord for Primitive {
@ -74,53 +118,90 @@ pub enum Value {
}
impl Value {
pub fn from_source(source: &str, mut cursor: &mut TreeCursor) -> Result<Self> {
let node = cursor.node();
cursor.goto_first_child();
let child = cursor.node();
pub fn from_syntax_node(node: Node, source: &str) -> Result<Self> {
debug_assert_eq!(node.kind(), "value");
assert_eq!(node.kind(), "value");
let child = node.child(0).unwrap();
match child.kind() {
"integer" | "float" | "boolean" | "string" | "empty" => {
Value::simple_from_syntax_node(node, source)
}
"integer" | "float" | "boolean" | "string" | "empty" => Ok(Value::Primitive(
Primitive::from_syntax_node(child, source)?,
)),
"list" => {
let list_length = child.named_child_count();
let mut values = Vec::with_capacity(list_length);
let item_count = child.named_child_count();
let mut values = Vec::with_capacity(item_count);
let mut current_node = child.child(1).unwrap();
cursor.goto_first_child();
while values.len() < item_count {
if current_node.is_named() {
let value = Value::from_syntax_node(current_node, source)?;
for value_node in child.children_by_field_name("item", &mut cursor) {
let value = Value::simple_from_syntax_node(value_node, source)?;
values.push(value);
}
values.push(value);
current_node = current_node.next_sibling().unwrap();
}
Ok(Value::List(values))
}
"table" => {
let mut column_names = Vec::new();
let mut current_node = child.child(0).unwrap();
let header_and_row_count = child.named_child_count();
let mut table = Table::new(column_names);
let mut headers = Vec::new();
let mut rows = Vec::new();
while headers.len() + rows.len() < header_and_row_count {
println!("{current_node:?}");
if current_node.kind() == "identifier" {
let identifier = Identifier::from_syntax_node(current_node, source)?;
let identifier_text = identifier.take_inner();
headers.push(identifier_text);
}
if current_node.kind() == "list" {
let value = Value::list_from_syntax_node(current_node, source)?;
let row = value.into_inner_list()?;
rows.push(row);
}
if let Some(node) = current_node.next_sibling() {
current_node = node;
} else {
break;
}
}
let table = Table::from_raw_parts(headers, rows);
Ok(Value::Table(table))
}
"map" => {
let mut map = VariableMap::new();
let pair_count = child.named_child_count();
let mut current_key = String::new();
let mut current_node = child.child(0).unwrap();
for key_value_node in child.children_by_field_name("key_value_pair", &mut cursor) {
if key_value_node.kind() == "identifier" {
let identifier_text = &source[key_value_node.byte_range()];
while map.len() < pair_count {
if current_node.kind() == "identifier" {
let identifier_text = &source[current_node.byte_range()];
current_key = identifier_text.to_string();
}
if key_value_node.kind() == "value" {
let value = Value::simple_from_syntax_node(key_value_node, source)?;
if current_node.kind() == "value" {
let value = Value::from_syntax_node(current_node, source)?;
map.set_value(current_key.to_string(), value)?;
}
if let Some(node) = current_node.next_sibling() {
current_node = node;
} else {
break;
}
}
Ok(Value::Map(map))
@ -133,17 +214,17 @@ impl Value {
for index in 0..child_count {
let child = child.child(index).unwrap();
if child.kind() == "identifier" {
let identifier = Identifier::new(source, cursor)?;
// if child.kind() == "identifier" {
// let identifier = Identifier::new(source, cursor)?;
identifiers.push(identifier)
}
// identifiers.push(identifier)
// }
if child.kind() == "statement" {
let statement = Statement::new(source, cursor)?;
// if child.kind() == "statement" {
// let statement = Statement::new(source, cursor)?;
statements.push(statement)
}
// statements.push(statement)
// }
}
Ok(Value::Function(Function::new(identifiers, statements)))
@ -156,56 +237,53 @@ impl Value {
}
}
/// Creates a simple value from the given source code and a node in the
/// syntax tree.
///
///
pub fn simple_from_syntax_node(node: Node, source: &str) -> Result<Self> {
let child = node.child(0).unwrap();
pub fn list_from_syntax_node(node: Node, source: &str) -> Result<Self> {
debug_assert_eq!(node.kind(), "list");
match child.kind() {
"integer" => Value::integer_from_source(source, child.byte_range()),
"float" => Value::float_from_source(source, child.byte_range()),
"boolean" => Value::boolean_from_source(source, child.byte_range()),
"string" => Value::string_from_source(source, child.byte_range()),
"empty" => Ok(Value::Primitive(Primitive::Empty)),
_ => Err(Error::UnexpectedSyntax {
expected: "integer, float, boolean, string or empty",
actual: child.kind(),
location: child.start_position(),
}),
let item_count = node.named_child_count();
let mut values = Vec::with_capacity(item_count);
let mut current_node = node.child(1).unwrap();
while values.len() < item_count {
if current_node.is_named() {
let value = Value::from_syntax_node(current_node, source)?;
values.push(value);
}
current_node = current_node.next_sibling().unwrap();
}
Ok(Value::List(values))
}
pub fn integer_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
let value_snippet = &source[byte_range];
let raw = value_snippet.parse::<i64>().unwrap_or_default();
// pub fn integer_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
// let value_snippet = &source[byte_range];
// let raw = value_snippet.parse::<i64>().unwrap_or_default();
Ok(Value::Primitive(Primitive::Integer(raw)))
}
// Ok(Primitive::Integer(raw))
// }
pub fn float_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
let value_snippet = &source[byte_range];
let raw = value_snippet.parse::<f64>().unwrap_or_default();
// pub fn float_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
// let value_snippet = &source[byte_range];
// let raw = value_snippet.parse::<f64>().unwrap_or_default();
Ok(Value::Primitive(Primitive::Float(raw)))
}
// Ok(Primitive::Float(raw))
// }
pub fn boolean_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
let value_snippet = &source[byte_range];
let raw = value_snippet.parse::<bool>().unwrap_or_default();
// pub fn boolean_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
// let value_snippet = &source[byte_range];
// let raw = value_snippet.parse::<bool>().unwrap_or_default();
Ok(Value::Primitive(Primitive::Boolean(raw)))
}
// Ok(Primitive::Boolean(raw))
// }
pub fn string_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
let value_snippet = &source[byte_range];
let without_quotes = &value_snippet[1..value_snippet.len() - 1];
// pub fn string_from_source(source: &str, byte_range: Range<usize>) -> Result<Self> {
// let value_snippet = &source[byte_range];
// let without_quotes = &value_snippet[1..value_snippet.len() - 1];
Ok(Value::Primitive(Primitive::String(
without_quotes.to_string(),
)))
}
// Ok(Primitive::String(without_quotes.to_string()))
// }
pub fn value_type(&self) -> ValueType {
ValueType::from(self)
@ -532,7 +610,13 @@ impl Display for Value {
Value::Primitive(Primitive::Integer(int)) => write!(f, "{}", int),
Value::Primitive(Primitive::Boolean(boolean)) => write!(f, "{}", boolean),
Value::Primitive(Primitive::Empty) => write!(f, "()"),
Value::List(list) => Table::from(list).fmt(f),
Value::List(list) => {
write!(f, "(")?;
for value in list {
write!(f, " {value} ")?;
}
write!(f, ")")
}
Value::Map(map) => write!(f, "{map}"),
Value::Table(table) => write!(f, "{table}"),
Value::Function(function) => write!(f, "{function}"),

View File

@ -8,26 +8,42 @@ use std::{
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Table {
header: Vec<String>,
headers: Vec<String>,
rows: Vec<Vec<Value>>,
primary_key_index: usize,
}
impl Table {
pub fn new(column_names: Vec<String>) -> Self {
pub fn new(headers: Vec<String>) -> Self {
Table {
header: column_names,
headers,
rows: Vec::new(),
primary_key_index: 0,
}
}
pub fn with_capacity(capacity: usize, headers: Vec<String>) -> Self {
Table {
headers,
rows: Vec::with_capacity(capacity),
primary_key_index: 0,
}
}
pub fn from_raw_parts(headers: Vec<String>, rows: Vec<Vec<Value>>) -> Self {
Table {
headers,
rows,
primary_key_index: 0,
}
}
pub fn reserve(&mut self, additional: usize) {
self.rows.reserve(additional);
}
pub fn column_names(&self) -> &Vec<String> {
&self.header
&self.headers
}
pub fn rows(&self) -> &Vec<Vec<Value>> {
@ -47,9 +63,9 @@ impl Table {
}
pub fn insert(&mut self, row: Vec<Value>) -> Result<()> {
if row.len() != self.header.len() {
if row.len() != self.headers.len() {
return Err(Error::WrongColumnAmount {
expected: self.header.len(),
expected: self.headers.len(),
actual: row.len(),
});
}
@ -82,10 +98,10 @@ impl Table {
let mut new_row = Vec::new();
for (i, value) in row.iter().enumerate() {
let column_name = self.header.get(i).unwrap();
let column_name = self.headers.get(i).unwrap();
let new_table_column_index =
new_table
.header
.headers
.iter()
.enumerate()
.find_map(|(index, new_column_name)| {
@ -125,7 +141,7 @@ impl Table {
}
pub fn filter(&self, column_name: &str, expected: &Value) -> Option<Table> {
let mut filtered = Table::new(self.header.clone());
let mut filtered = Table::new(self.headers.clone());
let column_index = self.get_column_index(column_name)?;
for row in &self.rows {
@ -140,7 +156,7 @@ impl Table {
}
pub fn get_column_index(&self, column_name: &str) -> Option<usize> {
let column_names = &self.header;
let column_names = &self.headers;
for (i, column) in column_names.iter().enumerate() {
if column == column_name {
return Some(i);
@ -157,7 +173,7 @@ impl Display for Table {
table
.load_preset("││──├─┼┤│ ┬┴╭╮╰╯")
.set_content_arrangement(ContentArrangement::Dynamic)
.set_header(&self.header);
.set_header(&self.headers);
for row in &self.rows {
let row = row.iter().map(|value| {
@ -209,7 +225,7 @@ impl Display for Table {
table.add_row(row);
}
if self.header.is_empty() {
if self.headers.is_empty() {
table.set_header(["empty"]);
}
@ -360,7 +376,7 @@ impl Eq for Table {}
impl PartialEq for Table {
fn eq(&self, other: &Self) -> bool {
if self.header != other.header {
if self.headers != other.headers {
return false;
}
@ -370,12 +386,12 @@ impl PartialEq for Table {
impl PartialOrd for Table {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.header.partial_cmp(&other.header)
self.headers.partial_cmp(&other.headers)
}
}
impl Ord for Table {
fn cmp(&self, other: &Self) -> Ordering {
self.header.cmp(&other.header)
self.headers.cmp(&other.headers)
}
}