Fix README example; Begin implementing insert

This commit is contained in:
Jeff 2023-10-22 13:55:56 -04:00
parent 7fef56f90d
commit 75f16a3afe
10 changed files with 3528 additions and 3646 deletions

View File

@ -193,7 +193,9 @@ Querying a table is similar to SQL.
```dust
names = select name from animals
youngins = select species from animals where age <= 10
youngins = select species from animals {
age <= 10
}
```
The keywords `table` and `insert` make sure that all of the memory used to hold the rows is allocated at once, so it is good practice to group your rows together instead of using a call for each row.

View File

@ -15,12 +15,29 @@ test_select = select <text bool> from my_table
(assert_equal test_select, test_table)
test_table = table <text number bool> [
["a", 1, true]
["a", 3, true]
[1, true]
[3, true]
]
test_select_where = select <> from my_table {
test_select_where = select <number, bool> from my_table {
text == "a"
}
(assert_equal test_select_where, test_table)
test_table = table <text number bool> [
["a", 1, true]
["b", 2, true]
["a", 3, true]
["c", 4, true]
["d", 5, true]
["e", 6, true]
]
insert into my_table [
["c", 4, true]
["d", 5, true]
["e", 6, true]
]
(assert_equal test_table, my_table)

View File

@ -0,0 +1,40 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Identifier, Item, Result, Value, VariableMap};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Insert {
identifier: Identifier,
expression: Expression,
}
impl AbstractTree for Insert {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
let identifier_node = node.child(1).unwrap();
let identifier = Identifier::from_syntax_node(source, identifier_node)?;
let expression_node = node.child(3).unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
Ok(Insert {
identifier,
expression,
})
}
fn run(&self, source: &str, context: &mut VariableMap) -> Result<Value> {
let table_name = self.identifier.inner().clone();
let mut table = self.identifier.run(source, context)?.as_table()?.clone();
let new_rows = self.expression.run(source, context)?.into_inner_list()?;
table.reserve(new_rows.len());
for row in new_rows {
table.insert(row.into_inner_list()?)?;
}
context.set_value(table_name, Value::Table(table))?;
Ok(Value::Empty)
}
}

View File

@ -15,6 +15,7 @@ pub mod r#for;
pub mod function_call;
pub mod identifier;
pub mod if_else;
pub mod insert;
pub mod item;
pub mod logic;
pub mod r#match;
@ -29,8 +30,8 @@ pub mod r#while;
pub use {
assignment::*, expression::*, filter::*, find::*, function_call::*, identifier::*, if_else::*,
item::*, logic::*, math::*, r#async::*, r#for::*, r#match::*, r#while::*, remove::*, select::*,
statement::*, tool::*, transform::*, value_node::*,
insert::*, item::*, logic::*, math::*, r#async::*, r#for::*, r#match::*, r#while::*, remove::*,
select::*, statement::*, tool::*, transform::*, value_node::*,
};
use tree_sitter::Node;

View File

@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{
AbstractTree, Assignment, Async, Error, Expression, Filter, Find, For, IfElse, Match, Remove,
Result, Select, Transform, Value, VariableMap, While,
AbstractTree, Assignment, Async, Error, Expression, Filter, Find, For, IfElse, Insert, Match,
Remove, Result, Select, Transform, Value, VariableMap, While,
};
/// Abstract representation of a statement.
@ -24,6 +24,7 @@ pub enum Statement {
Find(Box<Find>),
Remove(Box<Remove>),
Select(Box<Select>),
Insert(Box<Insert>),
}
impl AbstractTree for Statement {
@ -69,8 +70,11 @@ impl AbstractTree for Statement {
"select" => Ok(Statement::Select(Box::new(Select::from_syntax_node(
source, child,
)?))),
"insert" => Ok(Statement::Insert(Box::new(Insert::from_syntax_node(
source, child,
)?))),
_ => Err(Error::UnexpectedSyntaxNode {
expected: "assignment, expression, if...else, while, for, transform, filter, tool or async",
expected: "assignment, expression, if...else, while, for, transform, filter, tool, async, find, remove, select or insert",
actual: child.kind(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
@ -92,6 +96,7 @@ impl AbstractTree for Statement {
Statement::Find(find) => find.run(source, context),
Statement::Remove(remove) => remove.run(source, context),
Statement::Select(select) => select.run(source, context),
Statement::Insert(insert) => insert.run(source, context),
}
}
}

View File

@ -95,7 +95,9 @@ select <number> from foobar {
Table Insert
==================
insert ['bob was here', 0] into foobar
insert into foobar [
['bob was here', 0]
]
---
@ -103,11 +105,14 @@ insert ['bob was here', 0] into foobar
(item
(statement
(insert
(identifier)
(list
(expression
(value
(string)))
(expression
(value
(integer))))
(identifier)))))
(list
(expression
(value
(string)))
(expression
(value
(integer)))))))))))

View File

@ -239,12 +239,9 @@ module.exports = grammar({
insert: $ => prec.right(seq(
'insert',
repeat1($.list),
'into',
$.identifier,
optional(
seq('where', $.logic)
),
$.expression,
)),
async: $ => seq(

View File

@ -979,13 +979,6 @@
"type": "STRING",
"value": "insert"
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "list"
}
},
{
"type": "STRING",
"value": "into"
@ -995,25 +988,8 @@
"name": "identifier"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "where"
},
{
"type": "SYMBOL",
"name": "logic"
}
]
},
{
"type": "BLANK"
}
]
"type": "SYMBOL",
"name": "expression"
}
]
}
@ -1134,10 +1110,6 @@
"type": "STRING",
"value": "remove"
},
{
"type": "STRING",
"value": "trash"
},
{
"type": "STRING",
"value": "write"

View File

@ -278,17 +278,13 @@
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "list",
"named": true
},
{
"type": "logic",
"named": true
}
]
}
@ -865,18 +861,10 @@
"type": "transform",
"named": false
},
{
"type": "trash",
"named": false
},
{
"type": "true",
"named": false
},
{
"type": "where",
"named": false
},
{
"type": "while",
"named": false

File diff suppressed because it is too large Load Diff