Implement async blocks
This commit is contained in:
parent
e29e092875
commit
690e248df6
@ -1,8 +1,10 @@
|
|||||||
|
use std::sync::RwLock;
|
||||||
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, RwLockPoisonError, ValidationError},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{AbstractNode, Action, Statement, Type, WithPosition};
|
use super::{AbstractNode, Action, Statement, Type, WithPosition};
|
||||||
@ -33,24 +35,32 @@ impl AbstractNode for AsyncBlock {
|
|||||||
|
|
||||||
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
|
fn run(self, _context: &Context) -> Result<Action, RuntimeError> {
|
||||||
let statement_count = self.statements.len();
|
let statement_count = self.statements.len();
|
||||||
|
let final_result = RwLock::new(Ok(Action::None));
|
||||||
|
|
||||||
self.statements
|
self.statements
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find_map_any(|(index, statement)| {
|
.find_map_first(|(index, statement)| {
|
||||||
let result = statement.node.run(_context);
|
let result = statement.node.run(_context);
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(action) => {
|
|
||||||
if index == statement_count - 1 {
|
if index == statement_count - 1 {
|
||||||
Some(Ok(action))
|
let get_write_lock = final_result.write();
|
||||||
|
|
||||||
|
match get_write_lock {
|
||||||
|
Ok(mut final_result) => {
|
||||||
|
*final_result = result;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
Err(_error) => Some(Err(RuntimeError::RwLockPoison(RwLockPoisonError))),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Err(runtime_error) => Some(Err(runtime_error)),
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap_or(
|
||||||
|
final_result
|
||||||
|
.into_inner()
|
||||||
|
.map_err(|_| RuntimeError::RwLockPoison(RwLockPoisonError))?,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,22 @@
|
|||||||
use dust_lang::*;
|
use dust_lang::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn async_block() {
|
||||||
|
assert_eq!(
|
||||||
|
interpret(
|
||||||
|
"
|
||||||
|
x = 41
|
||||||
|
async {
|
||||||
|
x += 1
|
||||||
|
5
|
||||||
|
}
|
||||||
|
x
|
||||||
|
"
|
||||||
|
),
|
||||||
|
Ok(Some(Value::integer(42)))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn loops_and_breaks() {
|
fn loops_and_breaks() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
Loading…
Reference in New Issue
Block a user