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(),
};
values.par_iter().try_for_each(|value| {
let mut context = Map::new();
async {};
context.variables_mut().insert(key.clone(), value.clone());
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;
}
}
let should_include = self.item.run(source, &mut context)?.as_boolean()?;
let mut context = Map::new();
if should_include {
new_values.items_mut().push(value.clone());
}
context.variables_mut().insert(key.clone(), value.clone());
Ok::<(), Error>(())
})?;
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);
}
});
}
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(
choice('1', '2', '3', '4', '5', '6', '7', '8', '9', '0')
)),
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,122 +194,200 @@
}
]
},
"_numeric": {
"type": "TOKEN",
"content": {
"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"
}
]
}
}
},
"integer": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "-"
},
{
"type": "BLANK"
}
},
{
"type": "BLANK"
]
},
{
"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"
}
]
}
]
},
{
"type": "SYMBOL",
"name": "_numeric"
}
]
}
]
}
}
},
"float": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "IMMEDIATE_TOKEN",
"content": {
"type": "TOKEN",
"content": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "-"
},
{
"type": "BLANK"
}
},
{
"type": "BLANK"
]
},
{
"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"
}
]
}
]
},
{
"type": "SYMBOL",
"name": "_numeric"
},
{
"type": "IMMEDIATE_TOKEN",
"content": {
},
{
"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"
}
]
}
}
},
{
"type": "SYMBOL",
"name": "_numeric"
}
]
]
}
}
},
"string": {
@ -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": "SYMBOL",
"name": "identifier"
"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": "SYMBOL",
"name": "expression"
"type": "FIELD",
"name": "collection",
"content": {
"type": "SYMBOL",
"name": "expression"
}
},
{
"type": "STRING",
"value": "{"
},
{
"type": "SYMBOL",
"name": "item"
"type": "FIELD",
"name": "predicate",
"content": {
"type": "SYMBOL",
"name": "item"
}
},
{
"type": "STRING",

View File

@ -128,24 +128,47 @@
{
"type": "filter",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "expression",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "item",
"named": 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
}
]
}
}
},
{
@ -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