From 690e248df6f0450f76b1da2a5e5a10cec08bd704 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 20 Mar 2024 17:18:47 -0400 Subject: [PATCH] Implement async blocks --- dust-lang/src/abstract_tree/async_block.rs | 28 +++++++++++++++------- dust-lang/tests/statements.rs | 17 +++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/dust-lang/src/abstract_tree/async_block.rs b/dust-lang/src/abstract_tree/async_block.rs index 7d297a1..d869543 100644 --- a/dust-lang/src/abstract_tree/async_block.rs +++ b/dust-lang/src/abstract_tree/async_block.rs @@ -1,8 +1,10 @@ +use std::sync::RwLock; + use rayon::prelude::*; use crate::{ context::Context, - error::{RuntimeError, ValidationError}, + error::{RuntimeError, RwLockPoisonError, ValidationError}, }; use super::{AbstractNode, Action, Statement, Type, WithPosition}; @@ -33,24 +35,32 @@ impl AbstractNode for AsyncBlock { fn run(self, _context: &Context) -> Result { let statement_count = self.statements.len(); + let final_result = RwLock::new(Ok(Action::None)); self.statements .into_par_iter() .enumerate() - .find_map_any(|(index, statement)| { + .find_map_first(|(index, statement)| { let result = statement.node.run(_context); - match result { - Ok(action) => { - if index == statement_count - 1 { - Some(Ok(action)) - } else { + if index == statement_count - 1 { + 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))), } - Err(runtime_error) => Some(Err(runtime_error)), + } else { + None } }) - .unwrap() + .unwrap_or( + final_result + .into_inner() + .map_err(|_| RuntimeError::RwLockPoison(RwLockPoisonError))?, + ) } } diff --git a/dust-lang/tests/statements.rs b/dust-lang/tests/statements.rs index 3b97afb..f5f7a21 100644 --- a/dust-lang/tests/statements.rs +++ b/dust-lang/tests/statements.rs @@ -1,5 +1,22 @@ use dust_lang::*; +#[test] +fn async_block() { + assert_eq!( + interpret( + " + x = 41 + async { + x += 1 + 5 + } + x + " + ), + Ok(Some(Value::integer(42))) + ) +} + #[test] fn loops_and_breaks() { assert_eq!(