static void ExpandInline(CatExpr fxns, PushFunction q, int nMaxDepth) { CatExpr tmp = new CatExpr(); foreach (Function f in q.GetChildren()) { ExpandInline(tmp, f, nMaxDepth - 1); } fxns.Add(new PushFunction(tmp)); }
private static void ApplyMacrosInner(INameLookup names, CatExpr fxns) { // Recursively apply macros for all quotations. for (int i = 0; i < fxns.Count; ++i) { if (fxns[i] is PushFunction) { PushFunction qf = fxns[i] as PushFunction; CatExpr tmp = new CatExpr(qf.GetChildren()); ApplyMacros(names, tmp); fxns[i] = new PushFunction(tmp); } } // This could be done multiple time List <MacroMatch> matches = new List <MacroMatch>(); // The peephole is the maximum size of the range of functions that we will consider // for rewriting. This helps to reduces the overall complexity of the algorithm. //int nPeephole = 20; // This is the maximum size of the sub-expression that will be considered for matching. int nMaxSubExpr = 10; // Find matches int nLastMatchPos = -1; for (int nPos = 0; nPos < fxns.Count; ++nPos) { string s = fxns[nPos].msName; if (mMacros.ContainsKey(s)) { foreach (AstMacro m in mMacros[s]) { MacroMatch match = MacroMatch.Create(m, fxns, nLastMatchPos, nPos, nMaxSubExpr); if (match != null) { nLastMatchPos = nPos; matches.Add(match); } } } } // Replace matches for (int i = matches.Count - 1; i >= 0; --i) { MacroMatch m = matches[i]; List <AstMacroTerm> pattern = m.mMacro.mDest.mPattern; m.Replace(names, fxns, pattern); } }
public bool DoesTokenMatch(AstMacroTerm tkn, CatExpr x, out bool bRecoverable) { bRecoverable = true; if (tkn is AstMacroName) { bRecoverable = false; if (x.Count != 1) { return(false); } Function f = x[0]; string sName = f.GetName(); return(sName == tkn.ToString()); } else if (tkn is AstMacroTypeVar) { if (x.GetFxnType() == null) { return(false); } if (!CatFxnType.CompareFxnTypes(x.GetFxnType(), CatFxnType.PushSomethingType)) { return(false); } mCapturedVars.Add(tkn.ToString(), x); return(true); } else if (tkn is AstMacroQuote) { AstMacroQuote macroQuote = tkn as AstMacroQuote; if (x.Count != 1) { return(false); } PushFunction quote = x[0] as PushFunction; if (quote == null) { return(false); } for (int i = 0; i < macroQuote.mTerms.Count; ++i) { // Are we are at a stack variable in the matching pattern // if so it must be the last token in the pattern // e.g. [1 2 $A] is legal [1 $A 2] is not. if (macroQuote.mTerms[i] is AstMacroStackVar) { if (i != macroQuote.mTerms.Count - 1) { throw new Exception("within a quotation, expression variables can only be used in the right-most postition"); } AstMacroStackVar v = macroQuote.mTerms[0] as AstMacroStackVar; CatExpr expr = quote.GetChildren().GetRangeFrom(i); mCapturedVars.Add(v.msName, expr); return(true); } else if (macroQuote.mTerms[i] is AstMacroName) { // Well this is just an ordinary name pattern AstMacroName name = macroQuote.mTerms[i] as AstMacroName; if (quote.GetChildren().Count <= i) { return(false); } Function f = quote.GetChildren()[i]; if (!f.GetName().Equals(name.ToString())) { return(false); } } else { return(false); } } // No stack variable was encountered in the pattern // therefore the match must have been perfect, which means there are no // more terms in the input if (quote.GetChildren().Count != macroQuote.mTerms.Count) { return(false); } return(true); } else if (tkn is AstMacroStackVar) { AstMacroStackVar v = tkn as AstMacroStackVar; if (v.mType == null) { return(false); } if (x.GetFxnType() == null) { return(false); } if (!CatFxnType.CompareFxnTypes(x.GetFxnType(), v.mType)) { return(false); } mCapturedVars.Add(v.msName, x); return(true); } else { throw new Exception("unrecognized macro term " + tkn.ToString()); } }