summary refs log tree commit diff stats
path: root/src/vm.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm.rs')
-rw-r--r--src/vm.rs64
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)"),
                     }
                 }