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 { 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)?;

View File

@ -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();

View File

@ -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)
} }

View File

@ -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;

View File

@ -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),
} }
} }
} }

View File

@ -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))

View File

@ -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,
), ),

View File

@ -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",

View File

@ -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