Add async statements
This commit is contained in:
parent
2ccd28bbf4
commit
a9ef75dc12
23
README.md
23
README.md
@ -11,8 +11,10 @@ A basic dust program:
|
|||||||
Dust can do two (or more) things at the same time with effortless concurrency:
|
Dust can do two (or more) things at the same time with effortless concurrency:
|
||||||
|
|
||||||
```dust
|
```dust
|
||||||
async (output 'will this one finish first?')
|
async {
|
||||||
async (output 'or will this one?')
|
(output 'will this one finish first?')
|
||||||
|
(output 'or will this one?')
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Dust is an interpreted, general purpose language with first class functions. It is *data-oriented*, with extensive tools to manage structured and relational data. Dust also includes built-in tooling to import and export data in a variety of formats, including JSON, TOML, YAML and CSV.
|
Dust is an interpreted, general purpose language with first class functions. It is *data-oriented*, with extensive tools to manage structured and relational data. Dust also includes built-in tooling to import and export data in a variety of formats, including JSON, TOML, YAML and CSV.
|
||||||
@ -28,6 +30,7 @@ Dust is an interpreted, general purpose language with first class functions. It
|
|||||||
- [Maps](#maps)
|
- [Maps](#maps)
|
||||||
- [Tables](#tables)
|
- [Tables](#tables)
|
||||||
- [Functions](#functions)
|
- [Functions](#functions)
|
||||||
|
- [Concurrency](#concurrency)
|
||||||
- [Implementation](#implementation)
|
- [Implementation](#implementation)
|
||||||
<!--toc:end-->
|
<!--toc:end-->
|
||||||
|
|
||||||
@ -176,12 +179,20 @@ print = function <input> {
|
|||||||
As a language written in Rust, Dust features effortless concurrency anywhere in your code.
|
As a language written in Rust, Dust features effortless concurrency anywhere in your code.
|
||||||
|
|
||||||
```dust
|
```dust
|
||||||
if (random_integer) % 2 == 0 {
|
async {
|
||||||
run {
|
await 1 + 1
|
||||||
(output 1 + 1)
|
|
||||||
(output 1 + 1 == 2)
|
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The **await** keyword can be used in an asnyc block to indicate what value the async block should evaluate to. In this case, we want "data" to be read from a file.
|
||||||
|
|
||||||
|
```dust
|
||||||
|
data = async {
|
||||||
|
(output "Reading a file...")
|
||||||
|
(read "examples/assets/faithful.csv")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(output data)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
@ -1,23 +1,60 @@
|
|||||||
|
use rayon::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{AbstractTree, Item};
|
use crate::{AbstractTree, Error, Result, Statement, Value, VariableMap};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Async {
|
pub struct Async {
|
||||||
item: Item,
|
statements: Vec<Statement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Async {
|
impl AbstractTree for Async {
|
||||||
fn from_syntax_node(source: &str, node: tree_sitter::Node) -> crate::Result<Self> {
|
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
||||||
debug_assert_eq!("async", node.kind());
|
debug_assert_eq!("async", node.kind());
|
||||||
|
|
||||||
let item_node = node.child(2).unwrap();
|
let child_count = node.child_count();
|
||||||
let item = Item::from_syntax_node(source, item_node)?;
|
let mut statements = Vec::with_capacity(child_count);
|
||||||
|
|
||||||
Ok(Async { item })
|
for index in 2..child_count - 1 {
|
||||||
|
let child = node.child(index).unwrap();
|
||||||
|
|
||||||
|
let statement = match child.kind() {
|
||||||
|
"statement" => Statement::from_syntax_node(source, child)?,
|
||||||
|
_ => {
|
||||||
|
return Err(Error::UnexpectedSyntaxNode {
|
||||||
|
expected: "comment or statement",
|
||||||
|
actual: child.kind(),
|
||||||
|
location: child.start_position(),
|
||||||
|
relevant_source: source[child.byte_range()].to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
statements.push(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &mut crate::VariableMap) -> crate::Result<crate::Value> {
|
Ok(Async { statements })
|
||||||
self.item.run_parallel(source, context)
|
}
|
||||||
|
|
||||||
|
fn run(&self, source: &str, context: &mut VariableMap) -> Result<Value> {
|
||||||
|
let statements = &self.statements;
|
||||||
|
|
||||||
|
statements
|
||||||
|
.into_par_iter()
|
||||||
|
.enumerate()
|
||||||
|
.find_map_last(|(index, statement)| {
|
||||||
|
let mut context = context.clone();
|
||||||
|
let result = statement.run(source, &mut context).unwrap_or_default();
|
||||||
|
|
||||||
|
if index == statements.len() - 1 {
|
||||||
|
Some(result)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.ok_or(Error::CustomMessage(
|
||||||
|
"Async block has nothing to run.".to_string(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,16 @@ impl Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_parallel(&self, source: &str, context: &mut VariableMap) -> Result<Value> {
|
pub fn run_parallel(&self, source: &str, context: &mut VariableMap) -> Result<Value> {
|
||||||
self.statements.par_iter().for_each(|statement| {
|
let statements = &self.statements;
|
||||||
|
let run_result = statements.into_par_iter().try_for_each(|statement| {
|
||||||
let mut context = context.clone();
|
let mut context = context.clone();
|
||||||
|
statement.run(source, &mut context).map(|_| ())
|
||||||
statement.run(source, &mut context);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Value::Empty)
|
match run_result {
|
||||||
|
Ok(()) => Ok(Value::Empty),
|
||||||
|
Err(error) => Err(error),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 0f58ea5a7a05d49d99bbe24b9da03eea5249cbd7
|
Subproject commit cf22950b7ee6f40c7840b6af4d7b2dda69f4965b
|
Loading…
Reference in New Issue
Block a user