diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2020-04-17 14:25:21 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2020-04-17 14:26:01 -0300 |
commit | b259b179f5ceba60a1d04fef07559c0b01720c31 (patch) | |
tree | a0315c67fddc7919e6d6892e8d1eb15f328057a6 /abdl/_vm.py | |
parent | 3f9f66712aaa071bd3bb32c46e1e4dc1fed13378 (diff) |
Fix bugs with empty and predicate-only matches
Also clarified the behaviour of empty matches, which match anything, but only once. This behaviour is required for consistency with the rest of the matching rules.
Diffstat (limited to 'abdl/_vm.py')
-rw-r--r-- | abdl/_vm.py | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/abdl/_vm.py b/abdl/_vm.py index 5ab7efb..2f76586 100644 --- a/abdl/_vm.py +++ b/abdl/_vm.py @@ -255,7 +255,15 @@ class ApplyPredicate(PatternElement): def on_end(self, frame, path, defs, in_key): assert not in_key - raise NotImplementedError + res = {} + for holder in path: + if holder.subtree: + for name, pair in holder.match.items(): + res[name] = pair + elif holder.name is not None: + res[holder.name] = (holder.match, holder.value) + path.clear() + return (False, res) class End(PatternElement): """Pseudo-token, used to advance iteration.""" @@ -282,7 +290,8 @@ class End(PatternElement): elif holder.name is not None: res[holder.name] = (holder.match, holder.value) if not frame.prev(): - return (None, res) + # this should never happen + assert False return (True, res) @classmethod @@ -382,6 +391,7 @@ def match_helper(ops, defs, tree): frame = _Frame(ops) if not len(frame.ops): # no ops? + yield {} return # do nothing path = [Holder(value=tree, parent=None, iterator=iter(()))] @@ -390,8 +400,6 @@ def match_helper(ops, defs, tree): if not frame.next(): in_key, res = frame.current_op.on_end(frame, path, defs, in_key) yield res - if in_key is None: - return else: if in_key: in_key = frame.current_op.on_in_key(frame, path, defs) |