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; } }
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"); }
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); } }
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); }
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()); } }
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(); }
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" ); } }
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(); }