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 tree_sitter::Node;
use crate::{ use crate::{
AbstractTree, Error, Expression, Function, Identifier, Item, Result, Value, ValueType, AbstractTree, Error, Expression, Function, Identifier, Item, Result, Table, Value, ValueType,
VariableMap, VariableMap,
}; };
@ -54,7 +54,28 @@ impl AbstractTree for ValueNode {
ValueType::ListExact(child_nodes) 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" => { "map" => {
let mut child_nodes = BTreeMap::new(); let mut child_nodes = BTreeMap::new();
let mut current_key = "".to_string(); let mut current_key = "".to_string();
@ -150,7 +171,32 @@ impl AbstractTree for ValueNode {
Value::Map(values) 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()), ValueType::Function(function) => Value::Function(function.clone()),
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff