Implement parallel find loop
This commit is contained in:
parent
98ea049229
commit
d4aac2c729
@ -1,7 +1,8 @@
|
|||||||
|
use rayon::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tree_sitter::Node;
|
use tree_sitter::Node;
|
||||||
|
|
||||||
use crate::{AbstractTree, Block, Expression, Identifier, Map, Result, Value};
|
use crate::{AbstractTree, Block, Error, Expression, Identifier, Map, Result, Value};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Find {
|
pub struct Find {
|
||||||
@ -32,20 +33,37 @@ impl AbstractTree for Find {
|
|||||||
let value = self.expression.run(source, context)?;
|
let value = self.expression.run(source, context)?;
|
||||||
let values = value.as_list()?.items();
|
let values = value.as_list()?.items();
|
||||||
let key = self.identifier.inner();
|
let key = self.identifier.inner();
|
||||||
|
let loop_context = Map::clone_from(context)?;
|
||||||
|
|
||||||
let mut loop_context = Map::clone_from(context)?;
|
let find_result = values.par_iter().find_map_first(|value| {
|
||||||
let mut variables = context.variables_mut()?;
|
loop_context
|
||||||
|
.variables_mut()
|
||||||
|
.unwrap()
|
||||||
|
.insert(key.clone(), (*value).clone());
|
||||||
|
|
||||||
for value in values.iter() {
|
let run_result = self.item.run(source, &mut loop_context.clone());
|
||||||
variables.insert(key.clone(), value.clone());
|
|
||||||
|
|
||||||
let should_return = self.item.run(source, &mut loop_context)?.as_boolean()?;
|
|
||||||
|
|
||||||
|
if let Ok(run_result_value) = run_result {
|
||||||
|
if let Ok(should_return) = run_result_value.as_boolean() {
|
||||||
if should_return {
|
if should_return {
|
||||||
return Ok(value.clone());
|
Some(Ok(value.clone()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Some(Err(Error::ExpectedBoolean {
|
||||||
|
actual: value.clone(),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Some(run_result)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(result) = find_result {
|
||||||
|
result
|
||||||
|
} else {
|
||||||
Ok(Value::Empty)
|
Ok(Value::Empty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -22,7 +22,7 @@ impl Identifier {
|
|||||||
|
|
||||||
impl AbstractTree for Identifier {
|
impl AbstractTree for Identifier {
|
||||||
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
||||||
debug_assert_eq!("identifier", node.kind());
|
Error::expect_syntax_node(source, "identifier", node)?;
|
||||||
|
|
||||||
let identifier = &source[node.byte_range()];
|
let identifier = &source[node.byte_range()];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user