Example #1
0
 public AstMacroQuote(PegAstNode node)
     : base(node)
 {
     CheckLabel(AstLabel.MacroQuote);
     foreach (PegAstNode child in node.GetChildren())
     {
         AstMacroTerm term = Create(child) as AstMacroTerm;
         if (term == null)
         {
             throw new Exception("internal grammar error: macro quotations can only contain macro terms");
         }
         mTerms.Add(term);
     }
 }
Example #2
0
 public AstMacroPattern(PegAstNode node)
     : base(node)
 {
     CheckLabel(AstLabel.MacroPattern);
     foreach (PegAstNode child in node.GetChildren())
     {
         AstMacroTerm tmp = CatAstNode.Create(child) as AstMacroTerm;
         if (tmp == null)
         {
             throw new Exception("invalid grammar: only macro terms can be children of an ast macro mPattern");
         }
         mPattern.Add(tmp);
     }
 }
Example #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());
                }
            }
Example #4
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());
                }
            }
Example #5
0
            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);
            }