diff --git a/mps-interpreter/src/item.rs b/mps-interpreter/src/item.rs index 9347f3a..9629294 100644 --- a/mps-interpreter/src/item.rs +++ b/mps-interpreter/src/item.rs @@ -41,7 +41,10 @@ impl Display for MpsItem { } impl std::hash::Hash for MpsItem { - fn hash(&self, state: &mut H) where H: std::hash::Hasher { + fn hash(&self, state: &mut H) + where + H: std::hash::Hasher, + { // hashing is order-dependent, so the pseudo-random sorting of HashMap keys // prevents it from working correctly without sorting let mut keys: Vec<_> = self.fields.keys().collect(); diff --git a/mps-interpreter/src/lang/error.rs b/mps-interpreter/src/lang/error.rs index 232e62d..8ea7180 100644 --- a/mps-interpreter/src/lang/error.rs +++ b/mps-interpreter/src/lang/error.rs @@ -53,7 +53,10 @@ impl Display for RuntimeError { } impl std::hash::Hash for RuntimeError { - fn hash(&self, state: &mut H) where H: std::hash::Hasher { + fn hash(&self, state: &mut H) + where + H: std::hash::Hasher, + { self.line.hash(state); self.msg.hash(state); } diff --git a/mps-interpreter/src/lang/type_primitives.rs b/mps-interpreter/src/lang/type_primitives.rs index 733d3b0..c90bd67 100644 --- a/mps-interpreter/src/lang/type_primitives.rs +++ b/mps-interpreter/src/lang/type_primitives.rs @@ -145,7 +145,10 @@ impl PartialOrd for MpsTypePrimitive { } impl std::hash::Hash for MpsTypePrimitive { - fn hash(&self, state: &mut H) where H: std::hash::Hasher { + fn hash(&self, state: &mut H) + where + H: std::hash::Hasher, + { match self { Self::String(s) => s.hash(state), Self::Int(i) => i.hash(state), diff --git a/mps-interpreter/src/lang/vocabulary/filters/field_match_filter.rs b/mps-interpreter/src/lang/vocabulary/filters/field_match_filter.rs index 786e707..f749407 100644 --- a/mps-interpreter/src/lang/vocabulary/filters/field_match_filter.rs +++ b/mps-interpreter/src/lang/vocabulary/filters/field_match_filter.rs @@ -49,7 +49,8 @@ impl MpsFilterPredicate for FieldRegexFilter { let pattern = if let Some((_, regex_c)) = &self.regex_cache { regex_c } else { - let regex_c = Regex::new(variable).map_err(|e| RuntimeMsg(format!("Regex compile error: {}", e)))?; + let regex_c = Regex::new(variable) + .map_err(|e| RuntimeMsg(format!("Regex compile error: {}", e)))?; self.regex_cache = Some((variable.clone(), regex_c)); &self.regex_cache.as_ref().unwrap().1 }; @@ -128,7 +129,7 @@ impl MpsFilterFactory for FieldRegexFilterFactory { let regex_c = Regex::new(&literal).map_err(|_| SyntaxError { line: 0, token: MpsToken::Literal("[valid regex]".to_string()), - got: Some(MpsToken::Literal(literal.clone())) + got: Some(MpsToken::Literal(literal.clone())), })?; let compiled_cache = (literal.clone(), regex_c); let value = VariableOrValue::Value(MpsTypePrimitive::String(literal)); diff --git a/mps-interpreter/src/lang/vocabulary/intersection.rs b/mps-interpreter/src/lang/vocabulary/intersection.rs index a9369ec..25b39bd 100644 --- a/mps-interpreter/src/lang/vocabulary/intersection.rs +++ b/mps-interpreter/src/lang/vocabulary/intersection.rs @@ -1,15 +1,15 @@ -use std::collections::{VecDeque, HashSet}; +use std::collections::{HashSet, VecDeque}; use std::fmt::{Debug, Display, Error, Formatter}; use std::iter::Iterator; use crate::tokens::MpsToken; use crate::MpsContext; -use crate::lang::{MpsLanguageDictionary, PseudoOp}; -use crate::lang::{MpsFunctionFactory, MpsFunctionStatementFactory, MpsIteratorItem, MpsOp}; -use crate::lang::{RuntimeError, SyntaxError}; use crate::lang::repeated_tokens; use crate::lang::vocabulary::union::next_comma; +use crate::lang::{MpsFunctionFactory, MpsFunctionStatementFactory, MpsIteratorItem, MpsOp}; +use crate::lang::{MpsLanguageDictionary, PseudoOp}; +use crate::lang::{RuntimeError, SyntaxError}; #[derive(Debug)] pub struct IntersectionStatement { @@ -59,7 +59,8 @@ impl Iterator for IntersectionStatement { }; real_op.enter(self.context.take().unwrap()); let original_order: VecDeque = real_op.collect(); - let mut set: HashSet = original_order.iter().map(|x| x.to_owned()).collect(); + let mut set: HashSet = + original_order.iter().map(|x| x.to_owned()).collect(); self.context = Some(real_op.escape()); if self.ops.len() != 1 && !set.is_empty() { for i in 1..self.ops.len() { @@ -119,7 +120,6 @@ impl MpsOp for IntersectionStatement { } else { self.context = Some(real_op.escape()); } - } Ok(()) } @@ -139,16 +139,20 @@ impl MpsFunctionFactory for IntersectionFunctionFactory { dict: &MpsLanguageDictionary, ) -> Result { // intersection(op1, op2, ...) - let operations = repeated_tokens(|tokens| { - if let Some(comma_pos) = next_comma(tokens) { - let end_tokens = tokens.split_off(comma_pos); - let op = dict.try_build_statement(tokens); - tokens.extend(end_tokens); - Ok(Some(PseudoOp::from(op?))) - } else { - Ok(Some(PseudoOp::from(dict.try_build_statement(tokens)?))) - } - }, MpsToken::Comma).ingest_all(tokens)?; + let operations = repeated_tokens( + |tokens| { + if let Some(comma_pos) = next_comma(tokens) { + let end_tokens = tokens.split_off(comma_pos); + let op = dict.try_build_statement(tokens); + tokens.extend(end_tokens); + Ok(Some(PseudoOp::from(op?))) + } else { + Ok(Some(PseudoOp::from(dict.try_build_statement(tokens)?))) + } + }, + MpsToken::Comma, + ) + .ingest_all(tokens)?; Ok(IntersectionStatement { context: None, ops: operations, @@ -159,7 +163,8 @@ impl MpsFunctionFactory for IntersectionFunctionFactory { } } -pub type IntersectionStatementFactory = MpsFunctionStatementFactory; +pub type IntersectionStatementFactory = + MpsFunctionStatementFactory; #[inline(always)] pub fn intersection_function_factory() -> IntersectionStatementFactory { diff --git a/mps-interpreter/src/lang/vocabulary/union.rs b/mps-interpreter/src/lang/vocabulary/union.rs index d8caf35..6e4266c 100644 --- a/mps-interpreter/src/lang/vocabulary/union.rs +++ b/mps-interpreter/src/lang/vocabulary/union.rs @@ -5,10 +5,10 @@ use std::iter::Iterator; use crate::tokens::MpsToken; use crate::MpsContext; -use crate::lang::{MpsLanguageDictionary, PseudoOp}; -use crate::lang::{MpsFunctionFactory, MpsFunctionStatementFactory, MpsIteratorItem, MpsOp}; -use crate::lang::{RuntimeError, SyntaxError}; use crate::lang::repeated_tokens; +use crate::lang::{MpsFunctionFactory, MpsFunctionStatementFactory, MpsIteratorItem, MpsOp}; +use crate::lang::{MpsLanguageDictionary, PseudoOp}; +use crate::lang::{RuntimeError, SyntaxError}; #[derive(Debug, Copy, Clone)] enum UnionStrategy { @@ -52,23 +52,25 @@ impl Iterator for UnionStatement { type Item = MpsIteratorItem; fn next(&mut self) -> Option { - if self.index == self.ops.len() {return None;} + if self.index == self.ops.len() { + return None; + } match self.strategy { - UnionStrategy::Sequential => { - loop { - if self.index == self.ops.len() {return None;} - let real_op = match self.ops[self.index].try_real() { - Ok(x) => x, - Err(e) => return Some(Err(e)), - }; - real_op.enter(self.context.take().unwrap()); - while let Some(item) = real_op.next() { - self.context = Some(real_op.escape()); - return Some(item); - } - self.context = Some(real_op.escape()); - self.index += 1; + UnionStrategy::Sequential => loop { + if self.index == self.ops.len() { + return None; } + let real_op = match self.ops[self.index].try_real() { + Ok(x) => x, + Err(e) => return Some(Err(e)), + }; + real_op.enter(self.context.take().unwrap()); + while let Some(item) = real_op.next() { + self.context = Some(real_op.escape()); + return Some(item); + } + self.context = Some(real_op.escape()); + self.index += 1; }, UnionStrategy::Interleave => { let mut none_count = 0; @@ -128,7 +130,6 @@ impl MpsOp for UnionStatement { } else { self.context = Some(real_op.escape()); } - } Ok(()) } @@ -148,16 +149,20 @@ impl MpsFunctionFactory for UnionFunctionFactory { dict: &MpsLanguageDictionary, ) -> Result { // union(op1, op2, ...) - let operations = repeated_tokens(|tokens| { - if let Some(comma_pos) = next_comma(tokens) { - let end_tokens = tokens.split_off(comma_pos); - let op = dict.try_build_statement(tokens); - tokens.extend(end_tokens); - Ok(Some(PseudoOp::from(op?))) - } else { - Ok(Some(PseudoOp::from(dict.try_build_statement(tokens)?))) - } - }, MpsToken::Comma).ingest_all(tokens)?; + let operations = repeated_tokens( + |tokens| { + if let Some(comma_pos) = next_comma(tokens) { + let end_tokens = tokens.split_off(comma_pos); + let op = dict.try_build_statement(tokens); + tokens.extend(end_tokens); + Ok(Some(PseudoOp::from(op?))) + } else { + Ok(Some(PseudoOp::from(dict.try_build_statement(tokens)?))) + } + }, + MpsToken::Comma, + ) + .ingest_all(tokens)?; let combine_strategy = if name == "u" || name == "union" { UnionStrategy::Sequential } else { diff --git a/mps-interpreter/tests/single_line.rs b/mps-interpreter/tests/single_line.rs index 049b2cc..91401d8 100644 --- a/mps-interpreter/tests/single_line.rs +++ b/mps-interpreter/tests/single_line.rs @@ -422,7 +422,7 @@ fn execute_unionfn_line() -> Result<(), Box> { execute_single_line( "interlace(empty(), files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`))", false, - true + true, ) } @@ -460,6 +460,6 @@ fn execute_intersectionfn_line() -> Result<(), Box> { execute_single_line( "n(empty(), files(`~/Music/MusicFlac/Bruno Mars/24K Magic/`))", true, - true + true, ) }