Implement table values
This commit is contained in:
parent
7f049f86c5
commit
834b6743eb
@ -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()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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(
|
||||||
'{',
|
'{',
|
||||||
|
@ -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
Loading…
Reference in New Issue
Block a user