예제 #1
0
        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));
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
            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());
                }
            }