1
0

Add remove loop logic; Update examples

This commit is contained in:
Jeff 2023-10-18 21:50:45 -04:00
parent 3a5987a3d7
commit 36a6f5f548
10 changed files with 5198 additions and 4608 deletions

View File

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

View File

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

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

View File

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

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

View File

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

View File

@ -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": [

View File

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