Begin adding index assignment

This commit is contained in:
Jeff 2023-11-14 20:41:57 -05:00
parent 0b14ab5832
commit a804a85b1f
10 changed files with 11570 additions and 10982 deletions

View File

@ -19,6 +19,8 @@ pub enum AssignmentOperator {
impl AbstractTree for Assignment {
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 = Identifier::from_syntax_node(source, identifier_node)?;

View File

@ -5,9 +5,9 @@ use crate::{AbstractTree, Error, Expression, List, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Index {
collection: Expression,
index: Expression,
index_end: Option<Expression>,
pub collection: Expression,
pub index: Expression,
pub index_end: Option<Expression>,
}
impl AbstractTree for Index {
@ -50,7 +50,7 @@ impl AbstractTree for Index {
Ok(item)
}
Value::Map(mut map) => {
Value::Map(map) => {
let value = if let Expression::Identifier(identifier) = &self.index {
let key = identifier.inner();

View File

@ -19,6 +19,8 @@ pub enum AssignmentOperator {
impl AbstractTree for IndexAssignment {
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 = 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> {
let mut left = self.index.run(source, context)?;
let right = self.statement.run(source, context)?;
let index_collection = self.index.collection.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 {
AssignmentOperator::PlusEqual => left += right,
AssignmentOperator::MinusEqual => left -= right,
AssignmentOperator::Equal => left = right,
let value = self.statement.run(source, &mut context.clone())?;
let new_value = match self.operator {
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)
}

View File

@ -17,6 +17,7 @@ pub mod function_call;
pub mod identifier;
pub mod if_else;
pub mod index;
pub mod index_assignment;
pub mod insert;
pub mod logic;
pub mod r#match;
@ -30,8 +31,9 @@ pub mod r#while;
pub use {
assignment::*, block::*, built_in_function::*, expression::*, filter::*, find::*,
function_call::*, identifier::*, if_else::*, index::*, insert::*, logic::*, math::*, r#for::*,
r#match::*, r#while::*, remove::*, select::*, statement::*, transform::*, value_node::*,
function_call::*, identifier::*, if_else::*, index::*, index_assignment::*, insert::*,
logic::*, math::*, r#for::*, r#match::*, r#while::*, remove::*, select::*, statement::*,
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, Block, Error, Expression, Filter, Find, For, IfElse, Insert, Map,
Match, Remove, Result, Select, Transform, Value, While,
AbstractTree, Assignment, Block, Error, Expression, Filter, Find, For, IfElse, IndexAssignment,
Insert, Map, Match, Remove, Result, Select, Transform, Value, While,
};
/// Abstract representation of a statement.
@ -25,12 +25,11 @@ pub enum Statement {
Remove(Box<Remove>),
Select(Box<Select>),
Insert(Box<Insert>),
IndexAssignment(Box<IndexAssignment>),
}
impl AbstractTree for Statement {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
debug_assert_eq!("statement", node.kind());
let child = node.child(0).unwrap();
match child.kind() {
@ -73,12 +72,14 @@ impl AbstractTree for Statement {
"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, async, find, remove, select or insert",
actual: child.kind(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
}),
"index_assignment" => Ok(Statement::IndexAssignment(Box::new(IndexAssignment::from_syntax_node(
source, child,
)?))),
_ => Err(Error::expect_syntax_node(
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::Select(select) => select.run(source, context),
Statement::Insert(insert) => insert.run(source, context),
Statement::IndexAssignment(index_assignment) => index_assignment.run(source, context),
}
}
}

View File

@ -25,7 +25,7 @@ x:y = 1
(root
(statement
(assignment
(index_assignment
(index
(expression
(identifier))
@ -47,7 +47,7 @@ x:9 = 'foobar'
(root
(statement
(assignment
(index_assignment
(index
(expression
(identifier))

View File

@ -21,7 +21,7 @@ module.exports = grammar({
'}',
),
statement: $ => prec.right(seq(
statement: $ => prec.left(seq(
choice(
$.assignment,
$.block,
@ -30,6 +30,7 @@ module.exports = grammar({
$.find,
$.for,
$.if_else,
$.index_assignment,
$.insert,
$.match,
$.reduce,
@ -153,10 +154,13 @@ module.exports = grammar({
),
assignment: $ => seq(
choice(
$.identifier,
$.index,
$.assignment_operator,
$.statement,
),
index_assignment: $ => seq(
$.index,
$.assignment_operator,
$.statement,
),

View File

@ -50,7 +50,7 @@
]
},
"statement": {
"type": "PREC_RIGHT",
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
@ -86,6 +86,10 @@
"type": "SYMBOL",
"name": "if_else"
},
{
"type": "SYMBOL",
"name": "index_assignment"
},
{
"type": "SYMBOL",
"name": "insert"
@ -706,9 +710,6 @@
},
"assignment": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
@ -716,10 +717,21 @@
},
{
"type": "SYMBOL",
"name": "index"
"name": "assignment_operator"
},
{
"type": "SYMBOL",
"name": "statement"
}
]
},
"index_assignment": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "index"
},
{
"type": "SYMBOL",
"name": "assignment_operator"

View File

@ -15,10 +15,6 @@
"type": "identifier",
"named": true
},
{
"type": "index",
"named": true
},
{
"type": "statement",
"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",
"named": true,
@ -588,6 +607,10 @@
"type": "if_else",
"named": true
},
{
"type": "index_assignment",
"named": true
},
{
"type": "insert",
"named": true

File diff suppressed because it is too large Load Diff