public IEnumerator <Node> GetNodes(int cutAt) { if (cutAt < 0) { yield return(null); } if (cutAt >= expr.Count) { yield return(null); } CatExpr leftSubExpr = expr.GetRangeFromTo(0, cutAt); CatExpr rightSubExpr = expr.GetRangeFromTo(cutAt + 1, expr.Count - 1); Node leftNode = MakeNode(leftSubExpr); Node rightNode = MakeNode(rightSubExpr); foreach (Node node in leftNode.GetNodeIter()) { yield return(Compose(leftNode, node)); } foreach (Node node in rightNode.GetNodeIter()) { yield return(Compose(node, rightNode)); } }
static public MacroMatch Create(AstMacro m, CatExpr fxns, int nPrevMatchPos, int nFxnIndex, int nSubExprSize) { if (nFxnIndex < 0) { return(null); } if (nFxnIndex >= fxns.Count) { return(null); } List <AstMacroTerm> pattern = m.mSrc.mPattern; MacroMatch match = new MacroMatch(m); int nFirst = nFxnIndex; int nLast = nFxnIndex; int nTokenIndex = pattern.Count - 1; // Start at the end of the pattern and move backwards comparing expressions while (nFirst > nPrevMatchPos) { Trace.Assert(nTokenIndex <= pattern.Count); Trace.Assert(nFirst >= 0); Trace.Assert(nLast >= nFirst); Trace.Assert(nTokenIndex < pattern.Count); // get the current sub-expression that we are evaluating CatExpr expr = fxns.GetRangeFromTo(nFirst, nLast); AstMacroTerm tkn = pattern[nTokenIndex]; bool bRecoverable = false; if (match.DoesTokenMatch(tkn, expr, out bRecoverable)) { // Check if we have matched the whole pattern if (nTokenIndex == 0) { match.mnFxnIndex = nFirst; match.mnFxnCount = (nFxnIndex - nFirst) + 1; return(match); } // Go to the previous token nTokenIndex -= 1; // Adjust the sub-expression range nFirst -= 1; nLast = nFirst; } else { // Some failed matches (such as identifier names) can not be recovered from. if (!bRecoverable) { return(null); } // Widen the sub-expression. nFirst -= 1; // Check if we have passed the limit of how big of a // sub-expression will be examined if (nLast - nFirst > nSubExprSize) { return(null); } } } // The loop was finished and no match was found. return(null); }