From 8910d9df18f19f91ddcf271dc2a471369a918a79 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Mon, 31 Oct 2022 23:51:35 -0400 Subject: [PATCH] Refactor filter op --- interpreter/src/lang/filter.rs | 284 +++++++----------------- interpreter/src/processing/variables.rs | 10 + 2 files changed, 87 insertions(+), 207 deletions(-) diff --git a/interpreter/src/lang/filter.rs b/interpreter/src/lang/filter.rs index 371bed8..0762197 100644 --- a/interpreter/src/lang/filter.rs +++ b/interpreter/src/lang/filter.rs @@ -197,119 +197,21 @@ impl Op for FilterStatement

{ } } -impl Iterator for FilterStatement

{ - type Item = IteratorItem; - - fn next(&mut self) -> Option { - if (self.predicate.is_complete() && self.other_filters.is_none()) || self.is_failing { - return None; - } - //let self_clone = self.clone(); - //let self_clone2 = self_clone.clone(); - let fake = PseudoOp::Fake(format!("{}", self)); - //let ctx = self.context.as_mut().unwrap(); +impl FilterStatement

{ + fn next_item(&mut self) -> Option { + let fake_op = PseudoOp::from_printable(self); match &mut self.iterable { - VariableOrOp::Op(op) => match op.try_real() { + VariableOrOp::Op(op) => match op.try_real() { Ok(real_op) => { let ctx = self.context.take().unwrap(); real_op.enter(ctx); - let mut maybe_result = None; - while let Some(item) = real_op.next() { - let mut ctx = real_op.escape(); - match item { - Err(e) => { - //self.context = Some(op.escape()); - maybe_result = Some(Err(e)); - self.context = Some(ctx); - break; - } - Ok(item) => { - let matches_result = self.predicate.matches(&item, &mut ctx); - let matches = match matches_result { - Err(e) => { - maybe_result = Some(Err(e.with(RuntimeOp(fake)))); - self.context = Some(ctx); - break; - } - Ok(b) => b, - }; - if let Some(inner) = &mut self.other_filters { - // handle other filters - // make fake inner item - let single_op = SingleItem::new_ok(item.clone()); - match ctx - .variables - .declare(INNER_VARIABLE_NAME, Type::Op(Box::new(single_op))) - { - Ok(x) => x, - Err(e) => { - //self.context = Some(op.escape()); - maybe_result = Some(Err(e.with(RuntimeOp(fake)))); - self.context = Some(ctx); - break; - } - }; - let inner_real = match inner.try_real() { - Ok(x) => x, - Err(e) => { - //self.context = Some(op.escape()); - maybe_result = Some(Err(e)); - self.context = Some(ctx); - break; - } - }; - inner_real.enter(ctx); - match inner_real.next() { - Some(item) => { - maybe_result = Some(item); - ctx = inner_real.escape(); - match ctx.variables.remove(INNER_VARIABLE_NAME) { - Ok(_) => {} - Err(e) => match maybe_result { - Some(Ok(_)) => { - maybe_result = - Some(Err(e.with(RuntimeOp(fake)))) - } - Some(Err(e2)) => maybe_result = Some(Err(e2)), // already failing, do not replace error, - None => {} // impossible - }, - } - self.context = Some(ctx); - break; - } - None => { - ctx = inner_real.escape(); // move ctx back to expected spot - match ctx.variables.remove(INNER_VARIABLE_NAME) { - Ok(_) => {} - Err(e) => { - //self.context = Some(op.escape()); - maybe_result = - Some(Err(e.with(RuntimeOp(fake)))); - self.context = Some(ctx); - break; - } - } - } - } - } - if matches { - //self.context = Some(op.escape()); - maybe_result = Some(Ok(item)); - self.context = Some(ctx); - break; - } - } - } - real_op.enter(ctx); - } - if self.context.is_none() { - self.context = Some(real_op.escape()); - } - maybe_result + let item = real_op.next(); + self.context = Some(real_op.escape()); + item } - Err(e) => Some(Err(e)), - }, - VariableOrOp::Variable(variable_name) => { + Err(e) => return Some(Err(e)), + }, + VariableOrOp::Variable(variable_name) => { let mut variable = match self .context .as_mut() @@ -321,7 +223,7 @@ impl Iterator for FilterStatement

{ Ok(x) => { return Some(Err(RuntimeError { line: 0, - op: fake, + op: fake_op, msg: format!( "Expected operation/iterable type in variable {}, got {}", &variable_name, x @@ -329,115 +231,83 @@ impl Iterator for FilterStatement

{ })) } Err(e) => { - self.is_failing = true; // this is unrecoverable and reproducible, so it shouldn't be tried again (to prevent error spam) - return Some(Err(e.with(RuntimeOp(fake)))); - } + self.is_failing = true; + return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))); + }, }; - let mut maybe_result = None; - let ctx = self.context.take().unwrap(); - variable.enter(ctx); - while let Some(item) = variable.next() { - let mut ctx = variable.escape(); - match item { - Err(e) => { - maybe_result = Some(Err(e)); - self.context = Some(ctx); - break; - } - Ok(item) => { - let matches_result = self.predicate.matches(&item, &mut ctx); - let matches = match matches_result { - Err(e) => { - maybe_result = Some(Err(e.with(RuntimeOp(fake.clone())))); - self.context = Some(ctx); - break; - } - Ok(b) => b, - }; - if let Some(inner) = &mut self.other_filters { - // handle other filters - // make fake inner item - let single_op = SingleItem::new_ok(item.clone()); - match ctx - .variables - .declare(INNER_VARIABLE_NAME, Type::Op(Box::new(single_op))) - { - Ok(x) => x, - Err(e) => { - //self.context = Some(op.escape()); - maybe_result = Some(Err(e.with(RuntimeOp(fake.clone())))); - self.context = Some(ctx); - break; - } - }; - let inner_real = match inner.try_real() { - Ok(x) => x, - Err(e) => { - //self.context = Some(op.escape()); - maybe_result = Some(Err(e)); - self.context = Some(ctx); - break; - } - }; - inner_real.enter(ctx); - match inner_real.next() { - Some(item) => { - maybe_result = Some(item); - ctx = inner_real.escape(); - match ctx.variables.remove(INNER_VARIABLE_NAME) { - Ok(_) => {} - Err(e) => match maybe_result { - Some(Ok(_)) => { - maybe_result = - Some(Err(e.with(RuntimeOp(fake.clone())))) - } - Some(Err(e2)) => maybe_result = Some(Err(e2)), // already failing, do not replace error, - None => {} // impossible - }, - } - self.context = Some(ctx); - break; - } - None => { - ctx = inner_real.escape(); // move ctx back to expected spot - match ctx.variables.remove(INNER_VARIABLE_NAME) { - Ok(_) => {} - Err(e) => { - //self.context = Some(op.escape()); - maybe_result = - Some(Err(e.with(RuntimeOp(fake.clone())))); - self.context = Some(ctx); - break; - } - } - } - } - } - if matches { - maybe_result = Some(Ok(item)); - self.context = Some(ctx); - break; - } - } - } - variable.enter(ctx); - } - if self.context.is_none() { - self.context = Some(variable.escape()); - } - match self + + variable.enter(self.context.take().unwrap()); + let item = variable.next(); + self.context = Some(variable.escape()); + if let Err(e) = self .context .as_mut() .unwrap() .variables .declare(variable_name, Type::Op(variable)) { - Err(e) => Some(Err(e.with(RuntimeOp(fake)))), - Ok(_) => maybe_result, + return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))); } + item } } } +} + +impl Iterator for FilterStatement

{ + type Item = IteratorItem; + + fn next(&mut self) -> Option { + if (self.predicate.is_complete() && self.other_filters.is_none()) || self.is_failing { + return None; + } + //let ctx = self.context.as_mut().unwrap(); + while let Some(next_item) = self.next_item() { + match next_item { + Ok(item) => { + //let ctx = self.context.as_mut().unwrap(); + let matches_result = self.predicate.matches(&item, self.context.as_mut().unwrap()); + let matches = match matches_result { + Err(e) => { + //maybe_result = Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))); + //self.context = Some(ctx); + return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))); + } + Ok(b) => b, + }; + if let Some(inner) = &mut self.other_filters { + // handle other filters + // make fake inner item + let single_op = SingleItem::new_ok(item.clone()); + let preexisting_var = self.context.as_mut().unwrap() + .variables + .swap(INNER_VARIABLE_NAME, Some(Type::Op(Box::new(single_op)))); + let inner_real = match inner.try_real() { + Ok(x) => x, + Err(e) => return Some(Err(e)) + }; + inner_real.enter(self.context.take().unwrap()); + match inner_real.next() { + Some(item) => { + self.context = Some(inner_real.escape()); + self.context.as_mut().unwrap().variables.swap(INNER_VARIABLE_NAME, preexisting_var); + return Some(item); + } + None => { + self.context = Some(inner_real.escape()); // move ctx back to expected spot + self.context.as_mut().unwrap().variables.swap(INNER_VARIABLE_NAME, preexisting_var); + } + } + } + if matches { + return Some(Ok(item)); + } + }, + Err(e) => return Some(Err(e)), + }; + } + None + } fn size_hint(&self) -> (usize, Option) { match &self.iterable { diff --git a/interpreter/src/processing/variables.rs b/interpreter/src/processing/variables.rs index 17021a5..987b36a 100644 --- a/interpreter/src/processing/variables.rs +++ b/interpreter/src/processing/variables.rs @@ -56,6 +56,8 @@ pub trait VariableStorer: Debug { fn remove(&mut self, name: &str) -> Result; + fn swap(&mut self, name: &str, value: Option) -> Option; + fn exists(&self, name: &str) -> bool { self.get_opt(name).is_some() } @@ -99,6 +101,14 @@ impl VariableStorer for OpStorage { } } + fn swap(&mut self, key: &str, item: Option) -> Option { + if let Some(item) = item { + self.storage.insert(key.to_string(), item) + } else { + None + } + } + fn remove(&mut self, key: &str) -> Result { if self.storage.contains_key(key) { Ok(self.storage.remove(key).unwrap())