1
0

Begin match implementation

This commit is contained in:
Jeff 2023-10-30 22:12:03 -04:00
parent 9c565e810e
commit 6b916da62d
12 changed files with 7629 additions and 6517 deletions

2
Cargo.lock generated
View File

@ -459,7 +459,7 @@ dependencies = [
[[package]]
name = "dust-lang"
version = "0.3.4"
version = "0.3.5"
dependencies = [
"ansi_term",
"async-std",

View File

@ -21,16 +21,16 @@ remove_card = function <opponent_card> {
}
make_guess = function <current_room> {
if ((length suspects) == 1)
&& ((length rooms) == 1)
&& ((length weapons) == 1)
if (length suspects) == 1
&& (length rooms) == 1
&& (length weapons) == 1
{
(output 'It was '
+ suspects.{0}
+ suspects:0
+ ' in the '
+ rooms.{0}
+ rooms:0
+ ' with the '
+ weapons.{0}
+ weapons:0
+ '!')
} else {
(output 'I accuse '

View File

@ -1,6 +1,6 @@
list = [1 2 3]
async for i in list {
for i in list {
i += 1
(output i)
}

View File

@ -6,8 +6,8 @@ func = function <> {
x
}
assert_equal("foo", (func))
assert_equal("bar", x)
(assert_equal "foo", (func))
(assert_equal "bar", x)
# For Loop
x = 42
@ -16,7 +16,7 @@ for number in [1 2 3] {
x += number
}
assert_equal(48, x)
(assert_equal 48, x)
# Async Loops
@ -30,8 +30,8 @@ transform number in y {
x = 1000
}
assert_equal([43, 44, 45], y)
assert_equal(42, x)
(assert_equal [43, 44, 45], y)
(assert_equal 42, x)
## Filter Loop
@ -43,8 +43,8 @@ transform number in y {
x = 1000
}
assert_equal([43, 44, 45], y)
assert_equal(42, x)
(assert_equal [43, 44, 45], y)
(assert_equal 42, x)
## Filter Loop
@ -56,5 +56,5 @@ filter number in y {
x = 1000
}
assert_equal([43, 44, 45], y)
assert_equal(42, x)
(assert_equal [43, 44, 45], y)
(assert_equal 42, x)

View File

@ -1,5 +1,5 @@
data = (from_json (read "examples/assets/jq_data.json"))
transform item in data {
item.{commit}.{committer}.{name}
item:commit:committer:name
}

View File

@ -1,3 +1,4 @@
use async_std::task;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
@ -6,48 +7,78 @@ use crate::{AbstractTree, Error, Expression, Identifier, Item, List, Map, Result
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Filter {
identifier: Identifier,
expression: Expression,
item: Item,
count: Option<Expression>,
item_id: Identifier,
collection: Expression,
predicate: Item,
}
impl AbstractTree for Filter {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
let identifier_node = node.child(1).unwrap();
let count = if let Some(node) = node.child_by_field_name("count") {
Some(Expression::from_syntax_node(source, node)?)
} else {
None
};
let identifier_node = node.child_by_field_name("item_id").unwrap();
let identifier = Identifier::from_syntax_node(source, identifier_node)?;
let expression_node = node.child(3).unwrap();
let expression_node = node.child_by_field_name("collection").unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
let item_node = node.child(5).unwrap();
let item_node = node.child_by_field_name("predicate").unwrap();
let item = Item::from_syntax_node(source, item_node)?;
Ok(Filter {
identifier,
expression,
item,
count,
item_id: identifier,
collection: expression,
predicate: item,
})
}
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
let value = self.expression.run(source, context)?;
let value = self.collection.run(source, context)?;
let values = value.as_list()?.items();
let key = self.identifier.inner();
let new_values = List::new();
let count = if let Some(expression) = &self.count {
Some(expression.run(source, context)?.as_integer()? as usize)
} else {
None
};
let key = self.item_id.inner();
let new_values = match count {
Some(count) => List::with_capacity(count),
None => List::new(),
};
async {};
for value in values.clone().into_iter() {
task::spawn(async {
let new_values = new_values.clone();
if let Some(max) = count {
if values.len() == max {
return;
}
}
values.par_iter().try_for_each(|value| {
let mut context = Map::new();
context.variables_mut().insert(key.clone(), value.clone());
let should_include = self.item.run(source, &mut context)?.as_boolean()?;
let predicate_run = self.predicate.run(source, &mut context);
let should_include = if let Ok(value) = predicate_run {
value.as_boolean().unwrap_or_default()
} else {
return;
};
if should_include {
new_values.items_mut().push(value.clone());
new_values.items_mut().push(value);
}
});
}
Ok::<(), Error>(())
})?;
Ok(Value::List(new_values))
}

View File

@ -2,7 +2,7 @@
Filter Loop
==================
filter i in [1, 2, 3] {
filter 1 i in [1, 2, 3] {
i <= 1
}
@ -12,6 +12,9 @@ filter i in [1, 2, 3] {
(item
(statement
(filter
(expression
(value
(integer)))
(identifier)
(expression
(value

View File

@ -0,0 +1,126 @@
==================
Simple Match
==================
match 1 {
3 => 'foo'
2 => 'bar'
1 => 42
}
---
(root
(item
(statement
(match
(expression
(value
(integer)))
(expression
(value
(integer)))
(item
(statement
(expression
(value
(string)))))
(expression
(value
(integer)))
(item
(statement
(expression
(value
(string)))))
(expression
(value
(integer)))
(item
(statement
(expression
(value
(integer)))))))))
==================
Nested Matches
==================
match 1 {
3 => match true {
true => match (random_integer) {
0 => 42
9 => 'foo'
}
false => 0
}
2 => 'bar'
1 => 42
}
---
(root
(item
(statement
(match
(expression
(value
(integer)))
(expression
(value
(integer)))
(item
(statement
(match
(expression
(value
(boolean)))
(expression
(value
(boolean)))
(item
(statement
(match
(expression
(tool))
(expression
(value
(integer)))
(item
(statement
(expression
(value
(integer)))))
(expression
(value
(integer)))
(item
(statement
(expression
(value
(string))))))))
(expression
(value
(boolean)))
(item
(statement
(expression
(value
(integer))))))))
(expression
(value
(integer)))
(item
(statement
(expression
(value
(string)))))
(expression
(value
(integer)))
(item
(statement
(expression
(value
(integer)))))))))

View File

@ -22,6 +22,7 @@ module.exports = grammar({
$.filter,
$.find,
$.remove,
$.match,
)),
comment: $ => seq(/[#]+.*/),
@ -54,21 +55,19 @@ module.exports = grammar({
$.map,
),
_numeric: $ => token(repeat1(
integer: $ => prec.left(token(seq(
optional('-'),
repeat1(
choice('1', '2', '3', '4', '5', '6', '7', '8', '9', '0')
)),
),
))),
integer: $ => prec.left(seq(
optional(token.immediate('-')),
$._numeric,
)),
float: $ => prec.left(seq(
optional(token.immediate('-')),
$._numeric,
token.immediate('.'),
$._numeric,
)),
float: $ => prec.left(token(seq(
optional('-'),
repeat1(choice('1', '2', '3', '4', '5', '6', '7', '8', '9', '0')),
'.',
repeat1(choice('1', '2', '3', '4', '5', '6', '7', '8', '9', '0')),
))),
string: $ => /("[^"]*?")|('[^']*?')|(`[^`]*?`)/,
@ -192,6 +191,18 @@ module.exports = grammar({
')',
)),
match: $ => seq(
'match',
$.expression,
'{',
repeat1(seq(
$.expression,
'=>',
$.item,
)),
'}',
),
while: $ => seq(
'while',
$.expression,
@ -222,11 +233,12 @@ module.exports = grammar({
filter: $ => seq(
'filter',
$.identifier,
field('count', optional($.expression)),
field('item_id', $.identifier),
'in',
$.expression,
field('collection', $.expression),
'{',
$.item,
field('predicate', $.item),
'}',
),

View File

@ -77,6 +77,10 @@
{
"type": "SYMBOL",
"name": "remove"
},
{
"type": "SYMBOL",
"name": "match"
}
]
}
@ -190,9 +194,27 @@
}
]
},
"_numeric": {
"integer": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "-"
},
{
"type": "BLANK"
}
]
},
{
"type": "REPEAT1",
"content": {
"type": "CHOICE",
@ -240,38 +262,15 @@
]
}
}
},
"integer": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "-"
}
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "_numeric"
}
]
}
},
"float": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
@ -279,11 +278,8 @@
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "STRING",
"value": "-"
}
},
{
"type": "BLANK"
@ -291,23 +287,109 @@
]
},
{
"type": "SYMBOL",
"name": "_numeric"
},
{
"type": "IMMEDIATE_TOKEN",
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "."
}
"value": "1"
},
{
"type": "SYMBOL",
"name": "_numeric"
"type": "STRING",
"value": "2"
},
{
"type": "STRING",
"value": "3"
},
{
"type": "STRING",
"value": "4"
},
{
"type": "STRING",
"value": "5"
},
{
"type": "STRING",
"value": "6"
},
{
"type": "STRING",
"value": "7"
},
{
"type": "STRING",
"value": "8"
},
{
"type": "STRING",
"value": "9"
},
{
"type": "STRING",
"value": "0"
}
]
}
},
{
"type": "STRING",
"value": "."
},
{
"type": "REPEAT1",
"content": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "1"
},
{
"type": "STRING",
"value": "2"
},
{
"type": "STRING",
"value": "3"
},
{
"type": "STRING",
"value": "4"
},
{
"type": "STRING",
"value": "5"
},
{
"type": "STRING",
"value": "6"
},
{
"type": "STRING",
"value": "7"
},
{
"type": "STRING",
"value": "8"
},
{
"type": "STRING",
"value": "9"
},
{
"type": "STRING",
"value": "0"
}
]
}
}
]
}
}
},
"string": {
"type": "PATTERN",
"value": "(\"[^\"]*?\")|('[^']*?')|(`[^`]*?`)"
@ -852,6 +934,47 @@
]
}
},
"match": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "match"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "STRING",
"value": "{"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "STRING",
"value": "=>"
},
{
"type": "SYMBOL",
"name": "item"
}
]
}
},
{
"type": "STRING",
"value": "}"
}
]
},
"while": {
"type": "SEQ",
"members": [
@ -951,24 +1074,52 @@
"value": "filter"
},
{
"type": "FIELD",
"name": "count",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "BLANK"
}
]
}
},
{
"type": "FIELD",
"name": "item_id",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
},
{
"type": "STRING",
"value": "in"
},
{
"type": "FIELD",
"name": "collection",
"content": {
"type": "SYMBOL",
"name": "expression"
}
},
{
"type": "STRING",
"value": "{"
},
{
"type": "FIELD",
"name": "predicate",
"content": {
"type": "SYMBOL",
"name": "item"
}
},
{
"type": "STRING",

View File

@ -128,25 +128,48 @@
{
"type": "filter",
"named": true,
"fields": {},
"children": {
"multiple": true,
"fields": {
"collection": {
"multiple": false,
"required": true,
"types": [
{
"type": "expression",
"named": true
}
]
},
"count": {
"multiple": false,
"required": false,
"types": [
{
"type": "expression",
"named": true
}
]
},
"item_id": {
"multiple": false,
"required": true,
"types": [
{
"type": "identifier",
"named": true
}
]
},
"predicate": {
"multiple": false,
"required": true,
"types": [
{
"type": "item",
"named": true
}
]
}
}
},
{
"type": "find",
@ -391,6 +414,25 @@
]
}
},
{
"type": "match",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "item",
"named": true
}
]
}
},
{
"type": "math",
"named": true,
@ -520,6 +562,10 @@
"type": "insert",
"named": true
},
{
"type": "match",
"named": true
},
{
"type": "remove",
"named": true
@ -702,10 +748,6 @@
"type": "-=",
"named": false
},
{
"type": ".",
"named": false
},
{
"type": "..",
"named": false
@ -734,6 +776,10 @@
"type": "==",
"named": false
},
{
"type": "=>",
"named": false
},
{
"type": ">",
"named": false
@ -846,6 +892,10 @@
"type": "length",
"named": false
},
{
"type": "match",
"named": false
},
{
"type": "metadata",
"named": false

File diff suppressed because it is too large Load Diff