diff --git a/examples/async.ds b/examples/async.ds new file mode 100644 index 0000000..ed313af --- /dev/null +++ b/examples/async.ds @@ -0,0 +1,19 @@ +(output "This will print first.") + +create_random_numbers = |count| => { + numbers = []; + + while (length numbers) < count { + numbers += (random_integer) + } + + (output "Made " + count + " numbers.") +} + +async { + (create_random_numbers 1000) + (create_random_numbers 100) + (create_random_numbers 10) +} + +(output "This will print last.") diff --git a/src/abstract_tree/async.rs b/src/abstract_tree/async.rs index 6884349..cafc9a0 100644 --- a/src/abstract_tree/async.rs +++ b/src/abstract_tree/async.rs @@ -2,43 +2,25 @@ use rayon::prelude::*; use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Block, Error, Map, Result, Value}; +use crate::{AbstractTree, Block, Map, Result, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Async { - statements: Vec, + block: Block, } impl AbstractTree for Async { fn from_syntax_node(source: &str, node: Node) -> Result { debug_assert_eq!("async", node.kind()); - let child_count = node.child_count(); - let mut statements = Vec::with_capacity(child_count); + let block_node = node.child(1).unwrap(); + let block = Block::from_syntax_node(source, block_node)?; - for index in 2..child_count - 1 { - let child = node.child(index).unwrap(); - - let statement = match child.kind() { - "statement" => Block::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); - } - - Ok(Async { statements }) + Ok(Async { block }) } fn run(&self, source: &str, context: &mut Map) -> Result { - let statements = &self.statements; + let statements = self.block.statements(); statements .into_par_iter() @@ -47,6 +29,7 @@ impl AbstractTree for Async { let mut context = context.clone(); let result = statement.run(source, &mut context); + result.clone().unwrap(); if result.is_err() { Some(result) } else if index == statements.len() - 1 { @@ -55,6 +38,6 @@ impl AbstractTree for Async { None } }) - .unwrap() + .unwrap_or(Ok(Value::Empty)) } } diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index 8af949d..c508132 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -8,6 +8,12 @@ pub struct Block { statements: Vec, } +impl Block { + pub fn statements(&self) -> &Vec { + &self.statements + } +} + impl AbstractTree for Block { fn from_syntax_node(source: &str, node: Node) -> Result { debug_assert_eq!("block", node.kind()); diff --git a/src/value/mod.rs b/src/value/mod.rs index 305655b..4d5443a 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -219,19 +219,20 @@ impl Add for Value { type Output = Result; fn add(self, other: Self) -> Self::Output { - match (self.as_integer(), other.as_integer()) { - (Ok(left), Ok(right)) => return Ok(Value::Integer(left + right)), - _ => {} + if let (Ok(left), Ok(right)) = (self.as_integer(), other.as_integer()) { + return Ok(Value::Integer(left + right)); } - match (self.as_number(), other.as_number()) { - (Ok(left), Ok(right)) => return Ok(Value::Float(left + right)), - _ => {} + if let (Ok(left), Ok(right)) = (self.as_number(), other.as_number()) { + return Ok(Value::Float(left + right)); } - match (self.as_string(), other.as_string()) { - (Ok(left), Ok(right)) => return Ok(Value::String(left.to_string() + right)), - _ => {} + if let (Ok(left), Ok(right)) = (self.as_string(), other.as_string()) { + return Ok(Value::String(left.to_string() + right)); + } + + if self.is_string() || other.is_string() { + return Ok(Value::String(self.to_string() + &other.to_string())); } let non_number_or_string = if !self.is_number() == !self.is_string() {