Add remove loop logic; Update examples
This commit is contained in:
parent
3a5987a3d7
commit
36a6f5f548
@ -1,11 +1,23 @@
|
|||||||
rooms = ["Library", "Kitchen"];
|
rooms = ['Library', 'Kitchen']
|
||||||
suspects = ["White", "Green"];
|
suspects = ['White', 'Green']
|
||||||
weapons = ["Rope", "Lead Pipe"];
|
weapons = ['Rope', 'Lead_Pipe']
|
||||||
|
cards = [rooms suspects weapons]
|
||||||
|
|
||||||
show_card = function <card> {
|
take_turn = function <current_room opponent_card> {
|
||||||
(remove rooms card)
|
(remove_card opponent_card)
|
||||||
(remove suspects card)
|
(make_guess current_room)
|
||||||
(remove weapons card)
|
}
|
||||||
|
|
||||||
|
remove_card = function <opponent_card> {
|
||||||
|
for card_list in cards {
|
||||||
|
removed_card = remove card from cards {
|
||||||
|
card == opponent_card
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if type of removed_card == 'empty' {
|
||||||
|
(output 'Card not found.')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
make_guess = function <current_room> {
|
make_guess = function <current_room> {
|
||||||
|
8
examples/remove_loop.ds
Normal file
8
examples/remove_loop.ds
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
list = [1 2 1 3]
|
||||||
|
|
||||||
|
removed = remove i in list {
|
||||||
|
i == 3
|
||||||
|
}
|
||||||
|
|
||||||
|
(assert_equal 3 removed)
|
||||||
|
(assert_equal [1 2 1] list)
|
@ -19,6 +19,7 @@ pub mod item;
|
|||||||
pub mod logic;
|
pub mod logic;
|
||||||
pub mod r#match;
|
pub mod r#match;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
|
pub mod remove;
|
||||||
pub mod statement;
|
pub mod statement;
|
||||||
pub mod tool;
|
pub mod tool;
|
||||||
pub mod transform;
|
pub mod transform;
|
||||||
@ -27,8 +28,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::*, statement::*,
|
item::*, logic::*, math::*, r#async::*, r#for::*, r#match::*, r#while::*, remove::*,
|
||||||
transform::*,
|
statement::*, transform::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
57
src/abstract_tree/remove.rs
Normal file
57
src/abstract_tree/remove.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{expression, AbstractTree, Expression, Identifier, Item, Value};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
|
pub struct Remove {
|
||||||
|
identifier: Identifier,
|
||||||
|
expression: Expression,
|
||||||
|
item: Item,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AbstractTree for Remove {
|
||||||
|
fn from_syntax_node(source: &str, node: tree_sitter::Node) -> crate::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)?;
|
||||||
|
|
||||||
|
let item_node = node.child(5).unwrap();
|
||||||
|
let item = Item::from_syntax_node(source, item_node)?;
|
||||||
|
|
||||||
|
Ok(Remove {
|
||||||
|
identifier,
|
||||||
|
expression,
|
||||||
|
item,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(&self, source: &str, context: &mut crate::VariableMap) -> crate::Result<crate::Value> {
|
||||||
|
let value = self.expression.run(source, context)?;
|
||||||
|
let mut list = value.into_inner_list()?;
|
||||||
|
let key = self.identifier.inner();
|
||||||
|
let mut sub_context = context.clone();
|
||||||
|
|
||||||
|
for (index, value) in list.clone().iter().enumerate() {
|
||||||
|
sub_context.set_value(key.clone(), value.clone())?;
|
||||||
|
|
||||||
|
let should_remove = self.item.run(source, &mut sub_context)?.as_boolean()?;
|
||||||
|
|
||||||
|
if should_remove {
|
||||||
|
list.remove(index);
|
||||||
|
|
||||||
|
match &self.expression {
|
||||||
|
Expression::Identifier(identifier) => {
|
||||||
|
context.set_value(identifier.inner().clone(), Value::List(list))?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(value.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Empty)
|
||||||
|
}
|
||||||
|
}
|
@ -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, Result,
|
AbstractTree, Assignment, Async, Error, Expression, Filter, Find, For, IfElse, Match, Remove,
|
||||||
Transform, Value, VariableMap, While,
|
Result, Transform, Value, VariableMap, While,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Abstract representation of a statement.
|
/// Abstract representation of a statement.
|
||||||
@ -22,6 +22,7 @@ pub enum Statement {
|
|||||||
Transform(Box<Transform>),
|
Transform(Box<Transform>),
|
||||||
Filter(Box<Filter>),
|
Filter(Box<Filter>),
|
||||||
Find(Box<Find>),
|
Find(Box<Find>),
|
||||||
|
Remove(Box<Remove>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Statement {
|
impl AbstractTree for Statement {
|
||||||
@ -61,6 +62,9 @@ impl AbstractTree for Statement {
|
|||||||
"find" => Ok(Statement::Find(Box::new(Find::from_syntax_node(
|
"find" => Ok(Statement::Find(Box::new(Find::from_syntax_node(
|
||||||
source, child,
|
source, child,
|
||||||
)?))),
|
)?))),
|
||||||
|
"remove" => Ok(Statement::Remove(Box::new(Remove::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 or async",
|
||||||
actual: child.kind(),
|
actual: child.kind(),
|
||||||
@ -82,6 +86,7 @@ impl AbstractTree for Statement {
|
|||||||
Statement::Transform(transform) => transform.run(source, context),
|
Statement::Transform(transform) => transform.run(source, context),
|
||||||
Statement::Filter(filter) => filter.run(source, context),
|
Statement::Filter(filter) => filter.run(source, context),
|
||||||
Statement::Find(find) => find.run(source, context),
|
Statement::Find(find) => find.run(source, context),
|
||||||
|
Statement::Remove(remove) => remove.run(source, context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
79
tree-sitter-dust/corpus/remove.txt
Normal file
79
tree-sitter-dust/corpus/remove.txt
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
==================
|
||||||
|
Remove Loop
|
||||||
|
==================
|
||||||
|
|
||||||
|
remove i in [1, 2, 3] {
|
||||||
|
i <= 2
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(root
|
||||||
|
(item
|
||||||
|
(statement
|
||||||
|
(remove
|
||||||
|
(identifier)
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(list
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(integer)))
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(integer)))
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(integer))))))
|
||||||
|
(item
|
||||||
|
(statement
|
||||||
|
(expression
|
||||||
|
(logic
|
||||||
|
(expression
|
||||||
|
(identifier))
|
||||||
|
(logic_operator)
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(integer)))))))))))
|
||||||
|
|
||||||
|
==================
|
||||||
|
Remove Loop Assignment
|
||||||
|
==================
|
||||||
|
|
||||||
|
removed = remove i in ["one", "two", "three"] {
|
||||||
|
i == "two"
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(root
|
||||||
|
(item
|
||||||
|
(statement
|
||||||
|
(assignment
|
||||||
|
(identifier)
|
||||||
|
(assignment_operator)
|
||||||
|
(statement
|
||||||
|
(remove
|
||||||
|
(identifier)
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(list
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(string)))
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(string)))
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(string))))))
|
||||||
|
(item
|
||||||
|
(statement
|
||||||
|
(expression
|
||||||
|
(logic
|
||||||
|
(expression
|
||||||
|
(identifier))
|
||||||
|
(logic_operator)
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(string)))))))))))))
|
@ -21,6 +21,7 @@ module.exports = grammar({
|
|||||||
$.transform,
|
$.transform,
|
||||||
$.filter,
|
$.filter,
|
||||||
$.find,
|
$.find,
|
||||||
|
$.remove,
|
||||||
),
|
),
|
||||||
|
|
||||||
comment: $ => seq(/[#]+.*/),
|
comment: $ => seq(/[#]+.*/),
|
||||||
@ -215,6 +216,16 @@ module.exports = grammar({
|
|||||||
'}',
|
'}',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
remove: $ => seq(
|
||||||
|
'remove',
|
||||||
|
$.identifier,
|
||||||
|
'in',
|
||||||
|
$.expression,
|
||||||
|
'{',
|
||||||
|
$.item,
|
||||||
|
'}',
|
||||||
|
),
|
||||||
|
|
||||||
tool: $ => choice(
|
tool: $ => choice(
|
||||||
'assert',
|
'assert',
|
||||||
'assert_equal',
|
'assert_equal',
|
||||||
|
@ -70,6 +70,10 @@
|
|||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "find"
|
"name": "find"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "remove"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -859,6 +863,39 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"remove": {
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "remove"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "identifier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "in"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "expression"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "{"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "item"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"tool": {
|
"tool": {
|
||||||
"type": "CHOICE",
|
"type": "CHOICE",
|
||||||
"members": [
|
"members": [
|
||||||
|
@ -390,6 +390,29 @@
|
|||||||
"named": true,
|
"named": true,
|
||||||
"fields": {}
|
"fields": {}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "remove",
|
||||||
|
"named": true,
|
||||||
|
"fields": {},
|
||||||
|
"children": {
|
||||||
|
"multiple": true,
|
||||||
|
"required": true,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "expression",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "identifier",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "item",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "root",
|
"type": "root",
|
||||||
"named": true,
|
"named": true,
|
||||||
@ -468,6 +491,10 @@
|
|||||||
"type": "insert",
|
"type": "insert",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "remove",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "select",
|
"type": "select",
|
||||||
"named": true
|
"named": true
|
||||||
@ -800,6 +827,10 @@
|
|||||||
"type": "read",
|
"type": "read",
|
||||||
"named": false
|
"named": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "remove",
|
||||||
|
"named": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "select",
|
"type": "select",
|
||||||
"named": false
|
"named": false
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user