diff --git a/examples/assets/seaCreatures.json b/examples/assets/seaCreatures.json new file mode 100644 index 0000000..6b3f6ad --- /dev/null +++ b/examples/assets/seaCreatures.json @@ -0,0 +1,6 @@ +[ + { "name": "Sammy", "type": "shark", "clams": 5 }, + { "name": "Bubbles", "type": "orca", "clams": 3 }, + { "name": "Splish", "type": "dolphin", "clams": 2 }, + { "name": "Splash", "type": "dolphin", "clams": 2 } +] diff --git a/examples/sea_creatures.ds b/examples/sea_creatures.ds new file mode 100644 index 0000000..f05bb1f --- /dev/null +++ b/examples/sea_creatures.ds @@ -0,0 +1,18 @@ +raw_data = (read 'examples/assets/seaCreatures.json') +sea_creatures = (from_json raw_data) + +data = { + creatures = [] + total_clams = 0 + dolphin_clams = 0 +} + +for creature in sea_creatures { + data.creatures += creature.name + data.total_clams += creature.clams + if creature.type == 'dolphin' { + data.dolphin_clams += creature.clams + } +} + +data diff --git a/src/abstract_tree/assignment.rs b/src/abstract_tree/assignment.rs index adc403d..357b5cd 100644 --- a/src/abstract_tree/assignment.rs +++ b/src/abstract_tree/assignment.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Result, Value, VariableMap}; +use crate::{value, AbstractTree, Error, Result, Value, VariableMap}; use super::{identifier::Identifier, statement::Statement}; @@ -51,23 +51,29 @@ impl AbstractTree for Assignment { fn run(&self, source: &str, context: &mut VariableMap) -> Result { let key = self.identifier.inner().clone(); - let mut value = self.statement.run(source, context)?; + let value = self.statement.run(source, context)?; - match self.operator { + let new_value = match self.operator { AssignmentOperator::PlusEqual => { - if let Some(previous_value) = context.get_value(&key)? { - value += previous_value + if let Some(mut previous_value) = context.get_value(&key)? { + previous_value += value; + previous_value + } else { + Value::Empty } } AssignmentOperator::MinusEqual => { - if let Some(previous_value) = context.get_value(&key)? { - value -= previous_value + if let Some(mut previous_value) = context.get_value(&key)? { + previous_value -= value; + previous_value + } else { + Value::Empty } } - AssignmentOperator::Equal => {} - } + AssignmentOperator::Equal => value, + }; - context.set_value(key, value)?; + context.set_value(key, new_value)?; Ok(Value::Empty) } diff --git a/src/value/mod.rs b/src/value/mod.rs index 5216050..64879e6 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -321,6 +321,7 @@ impl AddAssign for Value { (Value::Float(left), Value::Float(right)) => *left += right, (Value::Float(left), Value::Integer(right)) => *left += right as f64, (Value::String(left), Value::String(right)) => *left += &right, + (Value::List(list), value) => list.push(value), _ => {} } } diff --git a/tree-sitter-dust/corpus/identifiers.txt b/tree-sitter-dust/corpus/identifiers.txt index e4242bf..e32bf86 100644 --- a/tree-sitter-dust/corpus/identifiers.txt +++ b/tree-sitter-dust/corpus/identifiers.txt @@ -27,10 +27,19 @@ Dot Notation ================== dust_data.0.name +# Separator +creature.total_clams --- (root + (item + (statement + (expression + (identifier)))) + (item + (statement + (comment))) (item (statement (expression diff --git a/tree-sitter-dust/corpus/lists.txt b/tree-sitter-dust/corpus/lists.txt index 21f8a60..bbd1604 100644 --- a/tree-sitter-dust/corpus/lists.txt +++ b/tree-sitter-dust/corpus/lists.txt @@ -23,11 +23,21 @@ List Declaration List Assignment ================== +empty = [] foobar = ['foobar'] --- (root + (item + (statement + (assignment + (identifier) + (assignment_operator) + (statement + (expression + (value + (list))))))) (item (statement (assignment diff --git a/tree-sitter-dust/grammar.js b/tree-sitter-dust/grammar.js index 2854411..4fa7641 100644 --- a/tree-sitter-dust/grammar.js +++ b/tree-sitter-dust/grammar.js @@ -40,7 +40,7 @@ module.exports = grammar({ $.logic, )), - identifier: $ => /[a-zA-Z|_]+[.a-zA-Z0-9]*/, + identifier: $ => /[a-zA-Z|_]+[._a-zA-Z0-9]*/, value: $ => choice( $.integer, diff --git a/tree-sitter-dust/src/grammar.json b/tree-sitter-dust/src/grammar.json index 5f65adc..0ecf34e 100644 --- a/tree-sitter-dust/src/grammar.json +++ b/tree-sitter-dust/src/grammar.json @@ -147,7 +147,7 @@ }, "identifier": { "type": "PATTERN", - "value": "[a-zA-Z|_]+[.a-zA-Z0-9]*" + "value": "[a-zA-Z|_]+[._a-zA-Z0-9]*" }, "value": { "type": "CHOICE", diff --git a/tree-sitter-dust/src/parser.c b/tree-sitter-dust/src/parser.c index 2325f2f..4a72472 100644 --- a/tree-sitter-dust/src/parser.c +++ b/tree-sitter-dust/src/parser.c @@ -1137,9 +1137,9 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { if (lookahead == '[') ADVANCE(30); if (lookahead == ']') ADVANCE(32); if (lookahead == '`') ADVANCE(8); - if (lookahead == 'e') ADVANCE(23); + if (lookahead == 'e') ADVANCE(22); if (lookahead == '{') ADVANCE(36); - if (lookahead == '|') ADVANCE(21); + if (lookahead == '|') ADVANCE(24); if (lookahead == '}') ADVANCE(37); if (lookahead == '\t' || lookahead == '\n' || @@ -1180,7 +1180,7 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { if (lookahead == '<') ADVANCE(33); if (lookahead == '=') ADVANCE(7); if (lookahead == '>') ADVANCE(35); - if (lookahead == '|') ADVANCE(21); + if (lookahead == '|') ADVANCE(24); if (lookahead == '}') ADVANCE(37); if (lookahead == '\t' || lookahead == '\n' || @@ -1245,7 +1245,7 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { if (lookahead == ']') ADVANCE(32); if (lookahead == '`') ADVANCE(8); if (lookahead == '{') ADVANCE(36); - if (lookahead == '|') ADVANCE(21); + if (lookahead == '|') ADVANCE(24); if (lookahead == '}') ADVANCE(37); if (lookahead == '\t' || lookahead == '\n' || @@ -1287,7 +1287,7 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { if (lookahead == '-') ADVANCE(12); if (lookahead == '[') ADVANCE(30); if (lookahead == '`') ADVANCE(8); - if (lookahead == 'e') ADVANCE(23); + if (lookahead == 'e') ADVANCE(22); if (lookahead == '{') ADVANCE(36); if (lookahead == '}') ADVANCE(37); if (lookahead == '\t' || @@ -1320,50 +1320,50 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { END_STATE(); case 21: ACCEPT_TOKEN(sym_identifier); - if (lookahead == '_') ADVANCE(25); - if (lookahead == '|') ADVANCE(51); + if (lookahead == 'e') ADVANCE(57); + if (lookahead == '|') ADVANCE(25); if (lookahead == '.' || ('0' <= lookahead && lookahead <= '9')) ADVANCE(26); if (('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || ('a' <= lookahead && lookahead <= 'z')) ADVANCE(25); END_STATE(); case 22: ACCEPT_TOKEN(sym_identifier); - if (lookahead == 'e') ADVANCE(57); - if (lookahead == '_' || - lookahead == '|') ADVANCE(25); + if (lookahead == 'l') ADVANCE(23); + if (lookahead == '|') ADVANCE(25); if (lookahead == '.' || ('0' <= lookahead && lookahead <= '9')) ADVANCE(26); if (('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || ('a' <= lookahead && lookahead <= 'z')) ADVANCE(25); END_STATE(); case 23: ACCEPT_TOKEN(sym_identifier); - if (lookahead == 'l') ADVANCE(24); - if (lookahead == '_' || - lookahead == '|') ADVANCE(25); + if (lookahead == 's') ADVANCE(21); + if (lookahead == '|') ADVANCE(25); if (lookahead == '.' || ('0' <= lookahead && lookahead <= '9')) ADVANCE(26); if (('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || ('a' <= lookahead && lookahead <= 'z')) ADVANCE(25); END_STATE(); case 24: ACCEPT_TOKEN(sym_identifier); - if (lookahead == 's') ADVANCE(22); - if (lookahead == '_' || - lookahead == '|') ADVANCE(25); + if (lookahead == '|') ADVANCE(51); if (lookahead == '.' || ('0' <= lookahead && lookahead <= '9')) ADVANCE(26); if (('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || ('a' <= lookahead && lookahead <= 'z')) ADVANCE(25); END_STATE(); case 25: ACCEPT_TOKEN(sym_identifier); - if (lookahead == '_' || - lookahead == '|') ADVANCE(25); + if (lookahead == '|') ADVANCE(25); if (lookahead == '.' || ('0' <= lookahead && lookahead <= '9')) ADVANCE(26); if (('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || ('a' <= lookahead && lookahead <= 'z')) ADVANCE(25); END_STATE(); case 26: @@ -1371,6 +1371,7 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { if (lookahead == '.' || ('0' <= lookahead && lookahead <= '9') || ('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || ('a' <= lookahead && lookahead <= 'z')) ADVANCE(26); END_STATE(); case 27: @@ -1457,11 +1458,11 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { END_STATE(); case 51: ACCEPT_TOKEN(anon_sym_PIPE_PIPE); - if (lookahead == '_' || - lookahead == '|') ADVANCE(25); + if (lookahead == '|') ADVANCE(25); if (lookahead == '.' || ('0' <= lookahead && lookahead <= '9')) ADVANCE(26); if (('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || ('a' <= lookahead && lookahead <= 'z')) ADVANCE(25); END_STATE(); case 52: @@ -1482,11 +1483,11 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { case 57: ACCEPT_TOKEN(anon_sym_else); if (lookahead == ' ') ADVANCE(10); - if (lookahead == '_' || - lookahead == '|') ADVANCE(25); + if (lookahead == '|') ADVANCE(25); if (lookahead == '.' || ('0' <= lookahead && lookahead <= '9')) ADVANCE(26); if (('A' <= lookahead && lookahead <= 'Z') || + lookahead == '_' || ('a' <= lookahead && lookahead <= 'z')) ADVANCE(25); END_STATE(); default: