private QilNode MatchPatternsWhosePriorityGreater(QilIterator it, List <Pattern> patternList, QilNode matcher)
        {
            if (patternList.Count == 0)
            {
                return(matcher);
            }
            if (IsNoMatch(matcher))
            {
                return(MatchPatterns(it, patternList));
            }

            QilIterator stopPriority = f.Let(matcher);
            QilNode     result       = f.Int32(NoMatch);
            int         lastPriority = NoMatch;

            foreach (Pattern pattern in patternList)
            {
                // if (stopPriority > pattern.Priority) then stopPriority     else
                // if ($it =~ pattern.Match)            then pattern.Priority else...

                // First 'if' is generated lazily since it is not needed if priorities are consecutive numbers
                Debug.Assert(pattern.Priority > lastPriority);
                if (pattern.Priority > lastPriority + 1)
                {
                    result = f.Conditional(f.Gt(stopPriority, f.Int32(lastPriority)), stopPriority, result);
                }

                result       = f.Conditional(MatchPattern(it, pattern.Match), f.Int32(pattern.Priority), result);
                lastPriority = pattern.Priority;
            }

            // If the last pattern has the highest priority, the check can be eliminated
            if (lastPriority != this.priority)
            {
                result = f.Conditional(f.Gt(stopPriority, f.Int32(lastPriority)), stopPriority, result);
            }

            return(f.Loop(stopPriority, result));
        }
Beispiel #2
0
 // Filers that travers Content being converted to global travers:
 // Filter($j= ... Filter($i = Content(fixup), ...))  -> Filter($j= ... Filter($i = Loop($j = DesendentOrSelf(Root(fixup)), Content($j), ...)))
 protected override QilNode VisitLoop(QilLoop n)
 {
     if (n.Variable.Binding.NodeType == QilNodeType.Root || n.Variable.Binding.NodeType == QilNodeType.Deref)
     {
         // This is absolute path already. We shouldn't touch it
         return(n);
     }
     if (n.Variable.Binding.NodeType == QilNodeType.Content)
     {
         // This is "begin" of reletive path. Let's rewrite it as absolute:
         QilUnary content = (QilUnary)n.Variable.Binding;
         Debug.Assert(content.Child == this.fixup, "Unexpected content node");
         QilIterator it = f.For(f.DescendantOrSelf(f.Root(this.fixup)));
         content.Child      = it;
         n.Variable.Binding = f.Loop(it, content);
         return(n);
     }
     n.Variable.Binding = Visit(n.Variable.Binding);
     return(n);
 }