Implement async blocks

This commit is contained in:
Jeff 2024-03-20 17:18:47 -04:00
parent e29e092875
commit 690e248df6
2 changed files with 36 additions and 9 deletions

View File

@ -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 { if index == statement_count - 1 {
Ok(action) => { let get_write_lock = final_result.write();
if index == statement_count - 1 {
Some(Ok(action)) match get_write_lock {
} else { Ok(mut final_result) => {
*final_result = result;
None None
} }
Err(_error) => Some(Err(RuntimeError::RwLockPoison(RwLockPoisonError))),
} }
Err(runtime_error) => Some(Err(runtime_error)), } else {
None
} }
}) })
.unwrap() .unwrap_or(
final_result
.into_inner()
.map_err(|_| RuntimeError::RwLockPoison(RwLockPoisonError))?,
)
} }
} }

View File

@ -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!(