Begin adding index assignment
This commit is contained in:
parent
0b14ab5832
commit
a804a85b1f
@ -19,6 +19,8 @@ pub enum AssignmentOperator {
|
|||||||
|
|
||||||
impl AbstractTree for Assignment {
|
impl AbstractTree for Assignment {
|
||||||
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
||||||
|
Error::expect_syntax_node(source, "assignment", node)?;
|
||||||
|
|
||||||
let identifier_node = node.child(0).unwrap();
|
let identifier_node = node.child(0).unwrap();
|
||||||
let identifier = Identifier::from_syntax_node(source, identifier_node)?;
|
let identifier = Identifier::from_syntax_node(source, identifier_node)?;
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@ use crate::{AbstractTree, Error, Expression, List, Map, Result, Value};
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Index {
|
pub struct Index {
|
||||||
collection: Expression,
|
pub collection: Expression,
|
||||||
index: Expression,
|
pub index: Expression,
|
||||||
index_end: Option<Expression>,
|
pub index_end: Option<Expression>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Index {
|
impl AbstractTree for Index {
|
||||||
@ -50,7 +50,7 @@ impl AbstractTree for Index {
|
|||||||
|
|
||||||
Ok(item)
|
Ok(item)
|
||||||
}
|
}
|
||||||
Value::Map(mut map) => {
|
Value::Map(map) => {
|
||||||
let value = if let Expression::Identifier(identifier) = &self.index {
|
let value = if let Expression::Identifier(identifier) = &self.index {
|
||||||
let key = identifier.inner();
|
let key = identifier.inner();
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@ pub enum AssignmentOperator {
|
|||||||
|
|
||||||
impl AbstractTree for IndexAssignment {
|
impl AbstractTree for IndexAssignment {
|
||||||
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
||||||
|
Error::expect_syntax_node(source, "index_assignment", node)?;
|
||||||
|
|
||||||
let index_node = node.child(0).unwrap();
|
let index_node = node.child(0).unwrap();
|
||||||
let index = Index::from_syntax_node(source, index_node)?;
|
let index = Index::from_syntax_node(source, index_node)?;
|
||||||
|
|
||||||
@ -48,14 +50,43 @@ impl AbstractTree for IndexAssignment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
||||||
let mut left = self.index.run(source, context)?;
|
let index_collection = self.index.collection.run(source, context)?;
|
||||||
let right = self.statement.run(source, context)?;
|
let index_context = index_collection.as_map().unwrap_or(&context);
|
||||||
|
let index_key = if let crate::Expression::Identifier(identifier) = &self.index.index {
|
||||||
|
identifier.inner()
|
||||||
|
} else {
|
||||||
|
return Err(Error::VariableIdentifierNotFound(
|
||||||
|
self.index.index.run(source, context)?.to_string(),
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
match self.operator {
|
let value = self.statement.run(source, &mut context.clone())?;
|
||||||
AssignmentOperator::PlusEqual => left += right,
|
|
||||||
AssignmentOperator::MinusEqual => left -= right,
|
let new_value = match self.operator {
|
||||||
AssignmentOperator::Equal => left = right,
|
AssignmentOperator::PlusEqual => {
|
||||||
}
|
if let Some(mut previous_value) = index_context.variables()?.get(index_key).cloned()
|
||||||
|
{
|
||||||
|
previous_value += value;
|
||||||
|
previous_value
|
||||||
|
} else {
|
||||||
|
Value::Empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AssignmentOperator::MinusEqual => {
|
||||||
|
if let Some(mut previous_value) = index_context.variables()?.get(index_key).cloned()
|
||||||
|
{
|
||||||
|
previous_value -= value;
|
||||||
|
previous_value
|
||||||
|
} else {
|
||||||
|
Value::Empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AssignmentOperator::Equal => value,
|
||||||
|
};
|
||||||
|
|
||||||
|
context
|
||||||
|
.variables_mut()?
|
||||||
|
.insert(index_key.clone(), new_value);
|
||||||
|
|
||||||
Ok(Value::Empty)
|
Ok(Value::Empty)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ pub mod function_call;
|
|||||||
pub mod identifier;
|
pub mod identifier;
|
||||||
pub mod if_else;
|
pub mod if_else;
|
||||||
pub mod index;
|
pub mod index;
|
||||||
|
pub mod index_assignment;
|
||||||
pub mod insert;
|
pub mod insert;
|
||||||
pub mod logic;
|
pub mod logic;
|
||||||
pub mod r#match;
|
pub mod r#match;
|
||||||
@ -30,8 +31,9 @@ pub mod r#while;
|
|||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
assignment::*, block::*, built_in_function::*, expression::*, filter::*, find::*,
|
assignment::*, block::*, built_in_function::*, expression::*, filter::*, find::*,
|
||||||
function_call::*, identifier::*, if_else::*, index::*, insert::*, logic::*, math::*, r#for::*,
|
function_call::*, identifier::*, if_else::*, index::*, index_assignment::*, insert::*,
|
||||||
r#match::*, r#while::*, remove::*, select::*, statement::*, transform::*, value_node::*,
|
logic::*, math::*, r#for::*, r#match::*, r#while::*, remove::*, select::*, statement::*,
|
||||||
|
transform::*, value_node::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AbstractTree, Assignment, Block, Error, Expression, Filter, Find, For, IfElse, Insert, Map,
|
AbstractTree, Assignment, Block, Error, Expression, Filter, Find, For, IfElse, IndexAssignment,
|
||||||
Match, Remove, Result, Select, Transform, Value, While,
|
Insert, Map, Match, Remove, Result, Select, Transform, Value, While,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Abstract representation of a statement.
|
/// Abstract representation of a statement.
|
||||||
@ -25,12 +25,11 @@ pub enum Statement {
|
|||||||
Remove(Box<Remove>),
|
Remove(Box<Remove>),
|
||||||
Select(Box<Select>),
|
Select(Box<Select>),
|
||||||
Insert(Box<Insert>),
|
Insert(Box<Insert>),
|
||||||
|
IndexAssignment(Box<IndexAssignment>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Statement {
|
impl AbstractTree for Statement {
|
||||||
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
||||||
debug_assert_eq!("statement", node.kind());
|
|
||||||
|
|
||||||
let child = node.child(0).unwrap();
|
let child = node.child(0).unwrap();
|
||||||
|
|
||||||
match child.kind() {
|
match child.kind() {
|
||||||
@ -73,12 +72,14 @@ impl AbstractTree for Statement {
|
|||||||
"insert" => Ok(Statement::Insert(Box::new(Insert::from_syntax_node(
|
"insert" => Ok(Statement::Insert(Box::new(Insert::from_syntax_node(
|
||||||
source, child,
|
source, child,
|
||||||
)?))),
|
)?))),
|
||||||
_ => Err(Error::UnexpectedSyntaxNode {
|
"index_assignment" => Ok(Statement::IndexAssignment(Box::new(IndexAssignment::from_syntax_node(
|
||||||
expected: "assignment, expression, if...else, while, for, transform, filter, tool, async, find, remove, select or insert",
|
source, child,
|
||||||
actual: child.kind(),
|
)?))),
|
||||||
location: child.start_position(),
|
_ => Err(Error::expect_syntax_node(
|
||||||
relevant_source: source[child.byte_range()].to_string(),
|
source,
|
||||||
}),
|
"assignment, expression, if...else, while, for, transform, filter, tool, async, find, remove, select, insert or index_assignment",
|
||||||
|
child
|
||||||
|
).unwrap_err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +98,7 @@ impl AbstractTree for Statement {
|
|||||||
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),
|
Statement::Insert(insert) => insert.run(source, context),
|
||||||
|
Statement::IndexAssignment(index_assignment) => index_assignment.run(source, context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ x:y = 1
|
|||||||
|
|
||||||
(root
|
(root
|
||||||
(statement
|
(statement
|
||||||
(assignment
|
(index_assignment
|
||||||
(index
|
(index
|
||||||
(expression
|
(expression
|
||||||
(identifier))
|
(identifier))
|
||||||
@ -47,7 +47,7 @@ x:9 = 'foobar'
|
|||||||
|
|
||||||
(root
|
(root
|
||||||
(statement
|
(statement
|
||||||
(assignment
|
(index_assignment
|
||||||
(index
|
(index
|
||||||
(expression
|
(expression
|
||||||
(identifier))
|
(identifier))
|
||||||
|
@ -21,7 +21,7 @@ module.exports = grammar({
|
|||||||
'}',
|
'}',
|
||||||
),
|
),
|
||||||
|
|
||||||
statement: $ => prec.right(seq(
|
statement: $ => prec.left(seq(
|
||||||
choice(
|
choice(
|
||||||
$.assignment,
|
$.assignment,
|
||||||
$.block,
|
$.block,
|
||||||
@ -30,6 +30,7 @@ module.exports = grammar({
|
|||||||
$.find,
|
$.find,
|
||||||
$.for,
|
$.for,
|
||||||
$.if_else,
|
$.if_else,
|
||||||
|
$.index_assignment,
|
||||||
$.insert,
|
$.insert,
|
||||||
$.match,
|
$.match,
|
||||||
$.reduce,
|
$.reduce,
|
||||||
@ -153,10 +154,13 @@ module.exports = grammar({
|
|||||||
),
|
),
|
||||||
|
|
||||||
assignment: $ => seq(
|
assignment: $ => seq(
|
||||||
choice(
|
$.identifier,
|
||||||
$.identifier,
|
$.assignment_operator,
|
||||||
$.index,
|
$.statement,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
index_assignment: $ => seq(
|
||||||
|
$.index,
|
||||||
$.assignment_operator,
|
$.assignment_operator,
|
||||||
$.statement,
|
$.statement,
|
||||||
),
|
),
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"statement": {
|
"statement": {
|
||||||
"type": "PREC_RIGHT",
|
"type": "PREC_LEFT",
|
||||||
"value": 0,
|
"value": 0,
|
||||||
"content": {
|
"content": {
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
@ -86,6 +86,10 @@
|
|||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "if_else"
|
"name": "if_else"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "index_assignment"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "insert"
|
"name": "insert"
|
||||||
@ -708,17 +712,25 @@
|
|||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "CHOICE",
|
"type": "SYMBOL",
|
||||||
"members": [
|
"name": "identifier"
|
||||||
{
|
},
|
||||||
"type": "SYMBOL",
|
{
|
||||||
"name": "identifier"
|
"type": "SYMBOL",
|
||||||
},
|
"name": "assignment_operator"
|
||||||
{
|
},
|
||||||
"type": "SYMBOL",
|
{
|
||||||
"name": "index"
|
"type": "SYMBOL",
|
||||||
}
|
"name": "statement"
|
||||||
]
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"index_assignment": {
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "index"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
|
@ -15,10 +15,6 @@
|
|||||||
"type": "identifier",
|
"type": "identifier",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "index",
|
|
||||||
"named": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "statement",
|
"type": "statement",
|
||||||
"named": true
|
"named": true
|
||||||
@ -348,6 +344,29 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "index_assignment",
|
||||||
|
"named": true,
|
||||||
|
"fields": {},
|
||||||
|
"children": {
|
||||||
|
"multiple": true,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "assignment_operator",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "index",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "statement",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "insert",
|
"type": "insert",
|
||||||
"named": true,
|
"named": true,
|
||||||
@ -588,6 +607,10 @@
|
|||||||
"type": "if_else",
|
"type": "if_else",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "index_assignment",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "insert",
|
"type": "insert",
|
||||||
"named": true
|
"named": true
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user