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)); }
// 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); }