예제 #1
0
        public AstLambda(PegAstNode node)
            : base(node)
        {
            CheckLabel(AstLabel.Lambda);
            CheckChildCount(node, 2);

            AstParam name = new AstParam(node.GetChild(0));

            mIdentifiers.Add(name.ToString());
            CatAstNode tmp = Create(node.GetChild(1));

            // lambda nodes either contain quotes or other lambda nodes
            if (!(tmp is AstQuote))
            {
                if (!(tmp is AstLambda))
                {
                    throw new Exception("expected lambda expression or quotation");
                }
                AstLambda lambda = tmp as AstLambda;
                mIdentifiers.AddRange(lambda.mIdentifiers);

                // Take ownership of the terms from the child lambda expression
                mTerms = lambda.mTerms;
            }
            else
            {
                AstQuote q = tmp as AstQuote;

                // Take ownership of the terms from the quote
                mTerms = q.mTerms;
            }
        }
예제 #2
0
파일: CatLambda.cs 프로젝트: noprompt/cat
 public static void RenameFirstInstance(string sOld, string sNew, List <CatAstNode> terms)
 {
     for (int i = 0; i < terms.Count; ++i)
     {
         if (TermContains(terms[i], sOld))
         {
             if (terms[i] is AstLambda)
             {
                 AstLambda l = terms[i] as AstLambda;
                 RenameFirstInstance(sOld, sNew, l.mTerms);
                 return;
             }
             else if (terms[i] is AstQuote)
             {
                 AstQuote q = terms[i] as AstQuote;
                 RenameFirstInstance(sOld, sNew, q.mTerms);
                 return;
             }
             else
             {
                 // Should never happen.
                 throw new Exception("expected either a lamda node or quote node");
             }
         }
         else if (TermEquals(terms[i], sOld))
         {
             terms[i] = new AstName(sNew);
             return;
         }
     }
     throw new Exception(sOld + " was not found in the list of terms");
 }
예제 #3
0
파일: CatLambda.cs 프로젝트: noprompt/cat
 public static bool TermContains(CatAstNode term, string var)
 {
     if (term is AstQuote)
     {
         AstQuote q = term as AstQuote;
         foreach (CatAstNode child in q.mTerms)
         {
             if (TermContainsOrEquals(child, var))
             {
                 return(true);
             }
         }
         return(false);
     }
     else if (term is AstLambda)
     {
         AstLambda l = term as AstLambda;
         foreach (CatAstNode child in l.mTerms)
         {
             if (TermContainsOrEquals(child, var))
             {
                 return(true);
             }
         }
         return(false);
     }
     else
     {
         return(false);
     }
 }
예제 #4
0
파일: CatLambda.cs 프로젝트: noprompt/cat
        public static int CountInstancesOf(string var, List <CatAstNode> terms)
        {
            int ret = 0;

            foreach (CatAstNode term in terms)
            {
                if (term is AstQuote)
                {
                    AstQuote q = term as AstQuote;
                    ret += CountInstancesOf(var, q.mTerms);
                }
                else if (term is AstLambda)
                {
                    AstLambda l = term as AstLambda;
                    ret += CountInstancesOf(var, l.mTerms);
                }
                else
                {
                    if (TermEquals(term, var))
                    {
                        ret += 1;
                    }
                }
            }
            return(ret);
        }
예제 #5
0
        public Function LiteralToFunction(string name, AstLiteral literal)
        {
            switch (literal.GetLabel())
            {
            case AstLabel.Int: {
                AstInt tmp = literal as AstInt;
                return(new PushInt(tmp.GetValue()));
            }

            case AstLabel.Bin: {
                AstBin tmp = literal as AstBin;
                return(new PushInt(tmp.GetValue()));
            }

            case AstLabel.Char: {
                AstChar tmp = literal as AstChar;
                return(new PushValue <char>(tmp.GetValue()));
            }

            case AstLabel.String: {
                AstString tmp = literal as AstString;
                return(new PushValue <string>(tmp.GetValue()));
            }

            case AstLabel.Float: {
                AstFloat tmp = literal as AstFloat;
                return(new PushValue <double>(tmp.GetValue()));
            }

            case AstLabel.Hex: {
                AstHex tmp = literal as AstHex;
                return(new PushInt(tmp.GetValue()));
            }

            case AstLabel.Quote: {
                AstQuote tmp  = literal as AstQuote;
                CatExpr  fxns = NodesToFxns(name, tmp.GetTerms());
                if (Config.gbOptimizeQuotations)
                {
                    MetaCat.ApplyMacros(this, fxns);
                }
                return(new PushFunction(fxns));
            }

            case AstLabel.Lambda: {
                AstLambda tmp = literal as AstLambda;
                CatLambdaConverter.Convert(tmp);
                CatExpr fxns = NodesToFxns(name, tmp.GetTerms());
                if (Config.gbOptimizeLambdas)
                {
                    MetaCat.ApplyMacros(this, fxns);
                }
                return(new PushFunction(fxns));
            }

            default:
                throw new Exception("unhandled literal " + literal.ToString());
            }
        }
예제 #6
0
        public static void Convert( AstLambda l ) {
            ConvertTerms( l.mIdentifiers, l.mTerms );

            // We won't be needing the identifiers anymore and I don't want
            // to have the conversion algorithm get run potentially multiple 
            // times on each lambda term. 
            l.mIdentifiers.Clear();
        }
예제 #7
0
        public static void RemoveTerm( string var, List<CatAstNode> terms ) {
            // Find the first term that either contains, or is equal to the 
            // free variable
            int i = 0;
            while (i < terms.Count) {
                if (TermContainsOrEquals( terms[ i ], var ))
                    break;
                ++i;
            }

            if (i == terms.Count)
                throw new Exception( "error in abstraction elimination algorithm" );

            if (i > 0) {
                AstQuote q = new AstQuote( terms.GetRange( 0, i ) );
                terms.RemoveRange( 0, i );
                terms.Insert( 0, q );
                terms.Insert( 1, new AstName( "dip" ) );
                i = 2;
            } else {
                i = 0;
            }

            if (TermEquals( terms[ i ], var )) {
                terms[ i ] = new AstName( "id" );
                return;
            } else if (TermContains( terms[ i ], var )) {
                if (terms[ i ] is AstQuote) {
                    AstQuote subExpr = terms[ i ] as AstQuote;
                    RemoveTerm( var, subExpr.mTerms );
                } else if (TermContains( terms[ i ], var )) {
                    AstLambda subExpr = terms[ i ] as AstLambda;
                    RemoveTerm( var, subExpr.mTerms );
                } else {
                    throw new Exception( "internal error: expected either a quotation or lambda term" );
                }
                terms.Insert( i + 1, new AstName( "papply" ) );
                return;
            } else {
                throw new Exception( "error in abstraction elimination algorithm" );
            }
        }
예제 #8
0
 public static void Convert(AstLambda l)
 {
     ConvertTerms(l.mIdentifiers, l.mTerms);            
     
     // We won't be needing the identifiers anymore and I don't want
     // to have the conversion algorithm get run potentially multiple 
     // times on each lambda term. 
     l.mIdentifiers.Clear();
 }