1
0

Begin adding futures

This commit is contained in:
Jeff 2023-11-03 19:39:34 -04:00
parent 8ca97300d3
commit bc1b88a5fa
11 changed files with 72134 additions and 80561 deletions

45
examples/async.ds Normal file
View File

@ -0,0 +1,45 @@
(output "This will print first.")
(output "This will print second.")
create_random_numbers = |count| => {
numbers = []
while (length numbers) < count {
numbers += (random_integer)
}
}
do_second = async {
{
(create_random_numbers 1000)
(output "Made 1000 numbers")
}
{
(create_random_numbers 100)
(output "Made 100 numbers")
}
{
(create_random_numbers 10)
(output "Made 10 numbers")
}
}
do_first = async {
{
(create_random_numbers 400)
(output "Made 400 numbers")
}
{
(create_random_numbers 40)
(output "Made 40 numbers")
}
{
(create_random_numbers 4)
(output "Made 4 numbers")
}
}
do_first.await
do_second.await
(output "This will print last.")

15
examples/select.ds Normal file
View File

@ -0,0 +1,15 @@
my_table = table |text number bool| [
["a", 1, true]
["b", 2, true]
["a", 3, true]
]
test_table = table |text bool| [
["a", true]
["b", true]
["a", true]
]
test_select = select |text bool| from my_table;
(assert_equal test_select, test_table)

View File

@ -48,8 +48,9 @@ impl AbstractTree for FunctionCall {
} }
fn run(&self, source: &str, context: &mut Map) -> Result<Value> { fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
let mut function_context = Map::clone_from(context);
let (name, arguments) = match self { let (name, arguments) = match self {
FunctionCall::BuiltIn(function) => return function.run(source, context), FunctionCall::BuiltIn(function) => return function.run(source, &mut function_context),
FunctionCall::ContextDefined { name, arguments } => (name, arguments), FunctionCall::ContextDefined { name, arguments } => (name, arguments),
}; };
@ -58,7 +59,6 @@ impl AbstractTree for FunctionCall {
} else { } else {
return Err(Error::FunctionIdentifierNotFound(name.clone())); return Err(Error::FunctionIdentifierNotFound(name.clone()));
}; };
let mut function_context = Map::clone_from(context);
if let Some(parameters) = definition.identifiers() { if let Some(parameters) = definition.identifiers() {
let parameter_expression_pairs = parameters.iter().zip(arguments.iter()); let parameter_expression_pairs = parameters.iter().zip(arguments.iter());

View File

@ -7,49 +7,36 @@ use crate::{AbstractTree, Block, Expression, Identifier, Map, Result, Table, Val
pub struct Select { pub struct Select {
identifiers: Vec<Identifier>, identifiers: Vec<Identifier>,
expression: Expression, expression: Expression,
item: Option<Block>, block: Option<Block>,
} }
impl AbstractTree for Select { impl AbstractTree for Select {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> { fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
let child_count = node.child_count();
let mut identifiers = Vec::new(); let mut identifiers = Vec::new();
let identifier_list = node.child(1).unwrap();
for index in 2..child_count - 4 { for index in 1..identifier_list.child_count() - 1 {
let node = node.child(index).unwrap(); let node = identifier_list.child(index).unwrap();
if node.kind() == "identifier" { if node.is_named() {
let identifier = Identifier::from_syntax_node(source, node)?; let identifier = Identifier::from_syntax_node(source, node)?;
identifiers.push(identifier); identifiers.push(identifier);
} }
if node.kind() == ">" {
break;
}
} }
let final_node = node.child(child_count - 1).unwrap(); let expression_node = node.child(3).unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
let item = if final_node.kind() == "}" { let block = if let Some(block_node) = node.child(4) {
let item_node = node.child(child_count - 2).unwrap(); Some(Block::from_syntax_node(source, block_node)?)
Some(Block::from_syntax_node(source, item_node)?)
} else { } else {
None None
}; };
let expression_node = if item.is_some() {
node.child(child_count - 4).unwrap()
} else {
node.child(child_count - 1).unwrap()
};
let expression = Expression::from_syntax_node(source, expression_node)?;
Ok(Select { Ok(Select {
identifiers, identifiers,
expression, expression,
item, block,
}) })
} }
@ -99,7 +86,7 @@ impl AbstractTree for Select {
} }
} }
if let Some(where_clause) = &self.item { if let Some(where_clause) = &self.block {
let should_include = where_clause.run(source, &mut row_context)?.as_boolean()?; let should_include = where_clause.run(source, &mut row_context)?.as_boolean()?;
if should_include { if should_include {

View File

@ -59,6 +59,13 @@ fn remove_loop() {
evaluate(&file_contents).unwrap(); evaluate(&file_contents).unwrap();
} }
#[test]
fn select() {
let file_contents = read_to_string("examples/select.ds").unwrap();
evaluate(&file_contents).unwrap();
}
#[test] #[test]
fn table() { fn table() {
let file_contents = read_to_string("examples/table.ds").unwrap(); let file_contents = read_to_string("examples/table.ds").unwrap();

View File

@ -1,75 +0,0 @@
==================
Simple Async Statements
==================
async { (output 'Whaddup') }
---
(root
(block
(statement
(async
(block
(statement
(expression
(function_call
(built_in_function
(expression
(value
(string))))))))))))
==================
Complex Async Statements
==================
async {
if 1 % 2 == 0 {
true
} else {
false
}
'foobar'
}
---
(root
(block
(statement
(async
(block
(statement
(if_else
(if
(expression
(logic
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(value
(integer)))))
(logic_operator)
(expression
(value
(integer)))))
(block
(statement
(expression
(value
(boolean))))))
(else
(block
(statement
(expression
(value
(boolean))))))))
(statement
(expression
(value
(string)))))))))

View File

@ -0,0 +1,79 @@
================================================================================
Simple Async Statements
================================================================================
async { (output 'Whaddup') }
--------------------------------------------------------------------------------
(root
(block
(statement
(expression
(value
(future
(block
(statement
(expression
(function_call
(built_in_function
(expression
(value
(string))))))))))))))
================================================================================
Complex Async Statements
================================================================================
async {
if 1 % 2 == 0 {
true
} else {
false
}
'foobar'
}
--------------------------------------------------------------------------------
(root
(block
(statement
(expression
(value
(future
(block
(statement
(if_else
(if
(expression
(logic
(expression
(math
(expression
(value
(integer)))
(math_operator)
(expression
(value
(integer)))))
(logic_operator)
(expression
(value
(integer)))))
(block
(statement
(expression
(value
(boolean))))))
(else
(block
(statement
(expression
(value
(boolean))))))))
(statement
(expression
(value
(string)))))))))))

View File

@ -11,19 +11,18 @@ module.exports = grammar({
], ],
rules: { rules: {
root: $ => repeat1($.block), root: $ => $.block,
comment: $ => /[#][^#\n]*[#|\n]/, comment: $ => /[#][^#\n]*[#|\n]/,
block: $ => choice( block: $ => prec.right(choice(
repeat1($.statement), repeat1($.statement),
seq('{', repeat1($.statement), '}'), seq('{', repeat1($.statement), '}'),
), )),
statement: $ => prec.right(seq( statement: $ => prec.right(seq(
choice( choice(
$.assignment, $.assignment,
$.async,
$.expression, $.expression,
$.filter, $.filter,
$.find, $.find,
@ -67,6 +66,7 @@ module.exports = grammar({
$.function, $.function,
$.table, $.table,
$.map, $.map,
$.future,
), ),
integer: $ => token(prec.left(seq( integer: $ => token(prec.left(seq(
@ -92,7 +92,7 @@ module.exports = grammar({
list: $ => seq( list: $ => seq(
'[', '[',
repeat(prec.left(seq($.expression, optional(',')))), $._expression_list,
']', ']',
), ),
@ -107,6 +107,11 @@ module.exports = grammar({
'}', '}',
), ),
future: $ => seq(
'async',
$.block,
),
index: $ => prec.left(seq( index: $ => prec.left(seq(
$.expression, $.expression,
':', ':',
@ -265,11 +270,6 @@ module.exports = grammar({
$.expression, $.expression,
)), )),
async: $ => seq(
'async',
$.block,
),
identifier_list: $ => prec.right(choice( identifier_list: $ => prec.right(choice(
seq( seq(
'|', '|',

View File

@ -3,47 +3,48 @@
"word": "identifier", "word": "identifier",
"rules": { "rules": {
"root": { "root": {
"type": "REPEAT1", "type": "SYMBOL",
"content": { "name": "block"
"type": "SYMBOL",
"name": "block"
}
}, },
"comment": { "comment": {
"type": "PATTERN", "type": "PATTERN",
"value": "[#][^#\\n]*[#|\\n]" "value": "[#][^#\\n]*[#|\\n]"
}, },
"block": { "block": {
"type": "CHOICE", "type": "PREC_RIGHT",
"members": [ "value": 0,
{ "content": {
"type": "REPEAT1", "type": "CHOICE",
"content": { "members": [
"type": "SYMBOL", {
"name": "statement" "type": "REPEAT1",
} "content": {
}, "type": "SYMBOL",
{ "name": "statement"
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "{"
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "statement"
}
},
{
"type": "STRING",
"value": "}"
} }
] },
} {
] "type": "SEQ",
"members": [
{
"type": "STRING",
"value": "{"
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "statement"
}
},
{
"type": "STRING",
"value": "}"
}
]
}
]
}
}, },
"statement": { "statement": {
"type": "PREC_RIGHT", "type": "PREC_RIGHT",
@ -58,10 +59,6 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "assignment" "name": "assignment"
}, },
{
"type": "SYMBOL",
"name": "async"
},
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expression" "name": "expression"
@ -256,6 +253,10 @@
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "map" "name": "map"
},
{
"type": "SYMBOL",
"name": "future"
} }
] ]
}, },
@ -480,32 +481,8 @@
"value": "[" "value": "["
}, },
{ {
"type": "REPEAT", "type": "SYMBOL",
"content": { "name": "_expression_list"
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
}
}, },
{ {
"type": "STRING", "type": "STRING",
@ -558,6 +535,19 @@
} }
] ]
}, },
"future": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "async"
},
{
"type": "SYMBOL",
"name": "block"
}
]
},
"index": { "index": {
"type": "PREC_LEFT", "type": "PREC_LEFT",
"value": 0, "value": 0,
@ -1119,19 +1109,6 @@
] ]
} }
}, },
"async": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "async"
},
{
"type": "SYMBOL",
"name": "block"
}
]
},
"identifier_list": { "identifier_list": {
"type": "PREC_RIGHT", "type": "PREC_RIGHT",
"value": 0, "value": 0,

View File

@ -27,21 +27,6 @@
"named": true, "named": true,
"fields": {} "fields": {}
}, },
{
"type": "async",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "block",
"named": true
}
]
}
},
{ {
"type": "block", "type": "block",
"named": true, "named": true,
@ -287,6 +272,21 @@
] ]
} }
}, },
{
"type": "future",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "block",
"named": true
}
]
}
},
{ {
"type": "identifier_list", "type": "identifier_list",
"named": true, "named": true,
@ -384,7 +384,7 @@
"fields": {}, "fields": {},
"children": { "children": {
"multiple": true, "multiple": true,
"required": false, "required": true,
"types": [ "types": [
{ {
"type": "expression", "type": "expression",
@ -530,7 +530,7 @@
"named": true, "named": true,
"fields": {}, "fields": {},
"children": { "children": {
"multiple": true, "multiple": false,
"required": true, "required": true,
"types": [ "types": [
{ {
@ -575,10 +575,6 @@
"type": "assignment", "type": "assignment",
"named": true "named": true
}, },
{
"type": "async",
"named": true
},
{ {
"type": "expression", "type": "expression",
"named": true "named": true
@ -692,6 +688,10 @@
"type": "function", "type": "function",
"named": true "named": true
}, },
{
"type": "future",
"named": true
},
{ {
"type": "integer", "type": "integer",
"named": true "named": true

File diff suppressed because it is too large Load Diff