2023-10-28 10:28:43 -04:00
|
|
|
use rayon::prelude::*;
|
2023-10-17 14:06:02 -04:00
|
|
|
use serde::{Deserialize, Serialize};
|
2023-10-22 15:24:10 -04:00
|
|
|
use tree_sitter::Node;
|
2023-10-17 14:06:02 -04:00
|
|
|
|
2023-12-05 17:08:22 -05:00
|
|
|
use crate::{AbstractTree, Block, Error, Expression, Identifier, Map, Result, Type, Value};
|
2023-10-17 14:06:02 -04:00
|
|
|
|
2023-12-06 13:48:38 -05:00
|
|
|
/// Abstract representation of a for loop statement.
|
2023-10-17 14:06:02 -04:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
|
|
|
pub struct For {
|
2023-10-28 10:28:43 -04:00
|
|
|
is_async: bool,
|
2023-11-04 06:02:27 -04:00
|
|
|
item_id: Identifier,
|
|
|
|
collection: Expression,
|
|
|
|
block: Block,
|
2023-10-17 14:06:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AbstractTree for For {
|
2023-11-29 22:54:46 -05:00
|
|
|
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
|
2023-11-27 17:53:12 -05:00
|
|
|
Error::expect_syntax_node(source, "for", node)?;
|
|
|
|
|
2023-10-28 10:28:43 -04:00
|
|
|
let for_node = node.child(0).unwrap();
|
|
|
|
let is_async = match for_node.kind() {
|
|
|
|
"for" => false,
|
2023-11-04 06:02:27 -04:00
|
|
|
"async for" => true,
|
2023-10-28 10:28:43 -04:00
|
|
|
_ => {
|
|
|
|
return Err(Error::UnexpectedSyntaxNode {
|
2023-11-04 06:02:27 -04:00
|
|
|
expected: "for or async for",
|
2023-10-28 10:28:43 -04:00
|
|
|
actual: for_node.kind(),
|
|
|
|
location: for_node.start_position(),
|
|
|
|
relevant_source: source[for_node.byte_range()].to_string(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-10-17 14:06:02 -04:00
|
|
|
let identifier_node = node.child(1).unwrap();
|
2023-11-29 22:54:46 -05:00
|
|
|
let identifier = Identifier::from_syntax_node(source, identifier_node, context)?;
|
2023-10-17 14:06:02 -04:00
|
|
|
|
|
|
|
let expression_node = node.child(3).unwrap();
|
2023-11-29 22:54:46 -05:00
|
|
|
let expression = Expression::from_syntax_node(source, expression_node, context)?;
|
2023-10-17 14:06:02 -04:00
|
|
|
|
2023-11-03 18:04:45 -04:00
|
|
|
let item_node = node.child(4).unwrap();
|
2023-11-29 22:54:46 -05:00
|
|
|
let item = Block::from_syntax_node(source, item_node, context)?;
|
2023-10-17 14:06:02 -04:00
|
|
|
|
|
|
|
Ok(For {
|
2023-10-28 10:28:43 -04:00
|
|
|
is_async,
|
2023-11-04 06:02:27 -04:00
|
|
|
item_id: identifier,
|
|
|
|
collection: expression,
|
|
|
|
block: item,
|
2023-10-17 14:06:02 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-11-29 19:23:42 -05:00
|
|
|
fn run(&self, source: &str, context: &Map) -> Result<Value> {
|
2023-11-04 06:02:27 -04:00
|
|
|
let expression_run = self.collection.run(source, context)?;
|
2023-10-26 18:03:59 -04:00
|
|
|
let values = expression_run.as_list()?.items();
|
2023-11-04 06:02:27 -04:00
|
|
|
let key = self.item_id.inner();
|
2023-10-23 15:25:22 -04:00
|
|
|
|
2023-10-28 10:28:43 -04:00
|
|
|
if self.is_async {
|
|
|
|
values.par_iter().try_for_each(|value| {
|
2023-11-10 16:24:19 -05:00
|
|
|
let mut iter_context = Map::clone_from(context)?;
|
2023-10-17 14:06:02 -04:00
|
|
|
|
2023-10-29 19:31:06 -04:00
|
|
|
iter_context
|
2023-11-05 13:54:29 -05:00
|
|
|
.variables_mut()?
|
2023-12-09 17:55:47 -05:00
|
|
|
.insert(key.clone(), (value.clone(), value.r#type()));
|
2023-10-23 15:25:22 -04:00
|
|
|
|
2023-11-04 06:02:27 -04:00
|
|
|
self.block.run(source, &mut iter_context).map(|_value| ())
|
2023-10-28 10:28:43 -04:00
|
|
|
})?;
|
2023-10-23 15:25:22 -04:00
|
|
|
} else {
|
2023-11-10 16:24:19 -05:00
|
|
|
let loop_context = Map::clone_from(context)?;
|
2023-11-05 13:54:29 -05:00
|
|
|
|
2023-10-28 10:28:43 -04:00
|
|
|
for value in values.iter() {
|
2023-11-10 16:24:19 -05:00
|
|
|
loop_context
|
|
|
|
.variables_mut()?
|
2023-12-09 17:55:47 -05:00
|
|
|
.insert(key.clone(), (value.clone(), value.r#type()));
|
2023-10-28 10:28:43 -04:00
|
|
|
|
2023-11-05 13:54:29 -05:00
|
|
|
self.block.run(source, &mut loop_context.clone())?;
|
2023-10-28 10:28:43 -04:00
|
|
|
}
|
2023-10-17 14:06:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(Value::Empty)
|
|
|
|
}
|
2023-11-29 19:23:42 -05:00
|
|
|
|
2023-12-05 17:08:22 -05:00
|
|
|
fn expected_type(&self, _context: &Map) -> Result<Type> {
|
|
|
|
Ok(Type::Empty)
|
2023-11-29 19:23:42 -05:00
|
|
|
}
|
2023-10-17 14:06:02 -04:00
|
|
|
}
|