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 ```dust
names = select name from animals 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. 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) (assert_equal test_select, test_table)
test_table = table <text number bool> [ test_table = table <text number bool> [
["a", 1, true] [1, true]
["a", 3, true] [3, true]
] ]
test_select_where = select <> from my_table { test_select_where = select <number, bool> from my_table {
text == "a" text == "a"
} }
(assert_equal test_select_where, test_table) (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 function_call;
pub mod identifier; pub mod identifier;
pub mod if_else; pub mod if_else;
pub mod insert;
pub mod item; pub mod item;
pub mod logic; pub mod logic;
pub mod r#match; pub mod r#match;
@ -29,8 +30,8 @@ pub mod r#while;
pub use { pub use {
assignment::*, expression::*, filter::*, find::*, function_call::*, identifier::*, if_else::*, assignment::*, expression::*, filter::*, find::*, function_call::*, identifier::*, if_else::*,
item::*, logic::*, math::*, r#async::*, r#for::*, r#match::*, r#while::*, remove::*, select::*, insert::*, item::*, logic::*, math::*, r#async::*, r#for::*, r#match::*, r#while::*, remove::*,
statement::*, tool::*, transform::*, value_node::*, select::*, statement::*, tool::*, transform::*, value_node::*,
}; };
use tree_sitter::Node; use tree_sitter::Node;

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff