Implement table values

This commit is contained in:
Jeff 2023-10-18 19:26:49 -04:00
parent 7f049f86c5
commit 834b6743eb
7 changed files with 4499 additions and 4774 deletions

View File

@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{
AbstractTree, Error, Expression, Function, Identifier, Item, Result, Value, ValueType,
AbstractTree, Error, Expression, Function, Identifier, Item, Result, Table, Value, ValueType,
VariableMap,
};
@ -54,7 +54,28 @@ impl AbstractTree for ValueNode {
ValueType::ListExact(child_nodes)
}
"table" => ValueType::Table,
"table" => {
let child_count = child.child_count();
let mut column_names = Vec::new();
let expression_node = child.child(child_count - 1).unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
for index in 2..child.child_count() - 2 {
let node = child.child(index).unwrap();
if node.is_named() {
let identifier = Identifier::from_syntax_node(source, node)?;
column_names.push(identifier)
}
}
ValueType::Table {
column_names,
rows: Box::new(expression),
}
}
"map" => {
let mut child_nodes = BTreeMap::new();
let mut current_key = "".to_string();
@ -150,7 +171,32 @@ impl AbstractTree for ValueNode {
Value::Map(values)
}
ValueType::Table => todo!(),
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)?;
let row_values = _row_values.as_list()?;
for value in row_values {
let row = value.as_list()?.clone();
rows.push(row)
}
let table = Table::from_raw_parts(headers, rows);
Value::Table(table)
}
ValueType::Function(function) => Value::Function(function.clone()),
};

View File

@ -175,11 +175,11 @@ mod tests {
assert_eq!(
evaluate(
"
table <messages, numbers> {
table <messages, numbers> [
['hiya', 42]
['foo', 57]
['bar', 99.99]
}
]
"
),
Ok(Value::Table(table))

View File

@ -5,7 +5,7 @@ use std::{
use serde::{Deserialize, Serialize};
use crate::{value_node::ValueNode, Expression, Function, Value};
use crate::{value_node::ValueNode, Expression, Function, Identifier, Value};
/// The type of a `Value`.
#[derive(Clone, Serialize, Deserialize, PartialOrd, Ord)]
@ -18,7 +18,10 @@ pub enum ValueType {
ListExact(Vec<Expression>),
Empty,
Map(BTreeMap<String, Expression>),
Table,
Table {
column_names: Vec<Identifier>,
rows: Box<Expression>,
},
Function(Function),
}
@ -36,7 +39,16 @@ impl PartialEq for ValueType {
(ValueType::ListExact(left), ValueType::ListExact(right)) => left == right,
(ValueType::Empty, ValueType::Empty) => true,
(ValueType::Map(left), ValueType::Map(right)) => left == right,
(ValueType::Table, ValueType::Table) => true,
(
ValueType::Table {
column_names: left_columns,
rows: left_rows,
},
ValueType::Table {
column_names: right_columns,
rows: right_rows,
},
) => left_columns == right_columns && left_rows == right_rows,
(ValueType::Function(left), ValueType::Function(right)) => left == right,
_ => false,
}
@ -65,7 +77,9 @@ impl Display for ValueType {
}
ValueType::Empty => write!(f, "empty"),
ValueType::Map(_map) => write!(f, "map"),
ValueType::Table => write!(f, "table"),
ValueType::Table { column_names, rows } => {
write!(f, "table")
}
ValueType::Function(function) => write!(f, "{function}"),
}
}
@ -106,7 +120,10 @@ impl From<&Value> for ValueType {
ValueType::Map(value_nodes)
}
Value::Table(_) => ValueType::Table,
Value::Table(table) => ValueType::Table {
column_names: todo!(),
rows: todo!(),
},
Value::Function(function) => ValueType::Function(function.clone()),
}
}

View File

@ -2,9 +2,9 @@
Table Declaration
==================
table <text, number> {
table <text, number> [
['answer', 42]
}
]
---
@ -21,18 +21,20 @@ table <text, number> {
(list
(expression
(value
(string)))
(expression
(value
(integer))))))))))))
(list
(expression
(value
(string)))
(expression
(value
(integer)))))))))))))))
==================
Table Assignment
==================
foobar = table <text, number> {
foobar = table <text, number> [
['answer', 42]
}
]
---
@ -53,10 +55,13 @@ foobar = table <text, number> {
(list
(expression
(value
(string)))
(expression
(value
(integer))))))))))))))
(list
(expression
(value
(string)))
(expression
(value
(integer)))))))))))))))))
==================
Table Access

View File

@ -76,13 +76,11 @@ module.exports = grammar({
'}',
),
table: $ => seq(
table: $ => prec.right(seq(
'table',
seq('<', repeat1(seq($.identifier, optional(','))), '>'),
'{',
repeat($.expression),
'}',
),
$.expression,
)),
map: $ => seq(
'{',

View File

@ -307,65 +307,58 @@
]
},
"table": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "table"
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "<"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "table"
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "<"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
},
{
"type": "STRING",
"value": ">"
}
},
{
"type": "STRING",
"value": ">"
}
]
},
{
"type": "STRING",
"value": "{"
},
{
"type": "REPEAT",
"content": {
]
},
{
"type": "SYMBOL",
"name": "expression"
}
},
{
"type": "STRING",
"value": "}"
}
]
]
}
},
"map": {
"type": "SEQ",

File diff suppressed because it is too large Load Diff