diff options
Diffstat (limited to 'src/vm.rs')
-rw-r--r-- | src/vm.rs | 64 |
1 files changed, 52 insertions, 12 deletions
diff --git a/src/vm.rs b/src/vm.rs index 44675f3..a02010f 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -16,15 +16,17 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +use std::collections::BTreeMap; +use std::marker::PhantomData; + +use regex::Regex; + use crate::KVPair; use crate::RefOwn; use crate::PatternTypes; use crate::Predicate; use crate::errors::MatchError; -use std::collections::BTreeMap; -use std::marker::PhantomData; - pub(crate) const MAX_CALLS: usize = 250; type Matches<'a, 'b, T> = BTreeMap<&'a str, KVPair<'b, T>>; @@ -37,7 +39,7 @@ pub(crate) struct PatternConstants<T: PatternTypes> { // Note that we can borrow these when creating the output map. // https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=da26f9175e96273fa0b94971a4e6172f pub(crate) strings: Vec<String>, - pub(crate) regices: Vec<()/* TODO */>, + pub(crate) regices: Vec<Regex>, pub(crate) predicates: Vec<Box<Predicate<T>>>, // NOTE these are part of the constant pool and so have lifetime analogous // to 'a (consistently used to indicate constant pool lifetime) when used @@ -45,6 +47,18 @@ pub(crate) struct PatternConstants<T: PatternTypes> { pub(crate) defs: Vec<T::Own>, } +impl<T: PatternTypes> Default for PatternConstants<T> { + fn default() -> Self { + Self { + protos: Default::default(), + strings: Default::default(), + regices: Default::default(), + predicates: Default::default(), + defs: Default::default(), + } + } +} + /// A pattern element. pub(crate) enum PatternElement<T: PatternTypes> { Arrow, @@ -113,10 +127,16 @@ impl<'a, 'b, T: PatternTypes> Frame<'a, 'b, T> { /// /// See also Holder. enum HolderState<'a, 'b, T: PatternTypes> { + /// Empty holder, for KV pair. EmptyKey, + /// Empty holder, for subtree. EmptySubtree, + /// Non-empty KV pair. Key(KVPair<'b, T>), + /// Non-empty subtree. Subtree(Matches<'a, 'b, T>, RefOwn<'b, T::Ref, T::Own>), + /// Preloaded value. Usually the first holder in a frame. + Value(RefOwn<'b, T::Ref, T::Own>), } impl<'a, 'b, T: PatternTypes> Clone for HolderState<'a, 'b, T> { @@ -126,6 +146,7 @@ impl<'a, 'b, T: PatternTypes> Clone for HolderState<'a, 'b, T> { HolderState::EmptySubtree => HolderState::EmptySubtree, HolderState::Key(v) => HolderState::Key(*v), HolderState::Subtree(m, v) => HolderState::Subtree(m.clone(), *v), + HolderState::Value(v) => HolderState::Value(*v), } } } @@ -143,6 +164,7 @@ impl<'a, 'b, T: PatternTypes> HolderState<'a, 'b, T> { match *self { HolderState::Key((_, value)) => Some(value), HolderState::Subtree(_, value) => Some(value), + HolderState::Value(value) => Some(value), _ => None } } @@ -156,13 +178,14 @@ struct Holder<'a, 'b, T: PatternTypes> { name: Option<&'a str>, value: HolderState<'a, 'b, T>, parent: Option<RefOwn<'b, T::Ref, T::Own>>, - iterator: Box<dyn Iterator<Item=KVPair<'b, T>> + 'b>, + iterator: Option<Box<dyn Iterator<Item=KVPair<'b, T>> + 'b>>, filters: Vec<Box<dyn for<'c> Fn(&'c mut HolderState<'a, 'b, T>) + 'a>>, } impl<'a, 'b, T: PatternTypes> Holder<'a, 'b, T> { fn next(&mut self) -> Option<Result<(), MatchError>> { - if let Self { value: ref mut v, iterator: ref mut it, .. } = self { + // FIXME what even is the point of this? + if let Self { value: ref mut v, iterator: Some(ref mut it), .. } = self { let is_subtree = v.is_subtree(); *v = match it.next() { Some(pair) => HolderState::Key(pair), @@ -182,8 +205,7 @@ impl<'a, 'b, T: PatternTypes> Default for Holder<'a, 'b, T> { name: Default::default(), value: HolderState::EmptyKey, parent: Default::default(), - // TODO https://github.com/rust-lang/rfcs/issues/3059 - iterator: Box::new(std::iter::empty()), + iterator: Default::default(), filters: Default::default(), } } @@ -206,9 +228,12 @@ impl<'a, 'b, T: PatternTypes> Matcher<'a, 'b, T> { iar: None, depth: depth, path: if ops.is_empty() { - Default::default() + // TODO decide on empty matcher behaviour + todo!() } else { - vec![Holder::default()] + let mut holder = Holder::default(); + holder.value = HolderState::Value(obj); + vec![holder] }, in_key: false, }, @@ -218,7 +243,7 @@ impl<'a, 'b, T: PatternTypes> Matcher<'a, 'b, T> { fn on_in_key(&mut self) -> Result<bool, MatchError> { match self.frame.op() { PatternElement::End => { - unimplemented!() + todo!() } _ => unreachable!("on_in_key") } @@ -226,6 +251,19 @@ impl<'a, 'b, T: PatternTypes> Matcher<'a, 'b, T> { fn on_not_in_key(&mut self) -> Result<bool, MatchError> { match self.frame.op() { + PatternElement::Arrow => { + assert!(!self.frame.path.last().expect("path").value.is_empty()); + let mut holder = Holder::default(); + holder.parent = self.frame.path.last().expect("path").value.value(); + self.frame.path.push(holder); + Ok(false) + }, + PatternElement::Identifier(id) => { + let name = self.defs.strings.get(id).map(|s| &**s); + self.frame.path.last_mut().expect("path").name = name; + todo!() + //Ok(true) + }, _ => unreachable!("on_not_in_key") } } @@ -247,6 +285,7 @@ impl<'a, 'b, T: PatternTypes> Matcher<'a, 'b, T> { res.insert(name, pair); } }, + HolderState::Value(_) => (), _ => unreachable!("on_end (End)"), } } @@ -256,7 +295,7 @@ impl<'a, 'b, T: PatternTypes> Matcher<'a, 'b, T> { assert!(false, "frame.prev()"); } Ok((true, res)) - }, + } PatternElement::ApplyPredicate {..} => { assert!(!self.frame.in_key); let mut res: Matches<'a, 'b, T> = Default::default(); @@ -270,6 +309,7 @@ impl<'a, 'b, T: PatternTypes> Matcher<'a, 'b, T> { res.insert(name, pair); } }, + HolderState::Value(_) => (), _ => unreachable!("on_end (ApplyPredicate)"), } } |