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)); }
public CatExpr NodesToFxns(string name, List <CatAstNode> nodes) { CatExpr result = new CatExpr(); for (int i = 0; i < nodes.Count; ++i) { CatAstNode node = nodes[i]; if (node.GetLabel().Equals(AstLabel.Name)) { string s = node.ToString(); if (s.Equals(name)) { result.Add(new SelfFunction(name)); } else { result.Add(ThrowingLookup(s)); } } else if (node is AstLiteral) { result.Add(LiteralToFunction(name, node as AstLiteral)); } else if (node is AstDef) { MakeFunction(node as AstDef); } else if (node is AstMacro) { MetaCat.AddMacro(node as AstMacro); } else { throw new Exception("unable to convert node to function: " + node.ToString()); } } return(result); }
static void ExpandInline(CatExpr list, Function f, int nMaxDepth) { if (nMaxDepth == 0) { list.Add(f); } else if (f is PushFunction) { ExpandInline(list, f as PushFunction, nMaxDepth); } else if (f is QuotedFunction) { ExpandInline(list, f as QuotedFunction, nMaxDepth); } else if (f is DefinedFunction) { ExpandInline(list, f as DefinedFunction, nMaxDepth); } else { list.Add(f); } }
public CatExpr PatternToFxns(INameLookup names, List <AstMacroTerm> pattern) { CatExpr ret = new CatExpr(); foreach (AstMacroTerm t in pattern) { if (t is AstMacroTypeVar) { string s = t.ToString(); if (!mCapturedVars.ContainsKey(s)) { throw new Exception("macro variable " + s + " was not captured"); } CatExpr expr = mCapturedVars[s]; ret.AddRange(expr); } else if (t is AstMacroStackVar) { string s = (t as AstMacroStackVar).msName; if (!mCapturedVars.ContainsKey(s)) { throw new Exception("macro variable " + s + " was not captured"); } CatExpr expr = mCapturedVars[s]; ret.AddRange(expr); } else if (t is AstMacroName) { string s = t.ToString(); if (s.Length < 1) { throw new Exception("internal error: macro name is empty string"); } Function f = names.ThrowingLookup(s); if (f == null) { if (Char.IsDigit(s[0])) { f = new PushInt(int.Parse(s)); } else { throw new Exception("Could not find function " + s); } } ret.Add(f); } else if (t is AstMacroQuote) { // TODO: handle typed terms within a quotation. AstMacroQuote macroQuote = t as AstMacroQuote; List <AstMacroTerm> localPattern = macroQuote.mTerms; PushFunction q = new PushFunction(PatternToFxns(names, localPattern)); ret.Add(q); } else { throw new Exception("unrecognized macro term " + t.ToString()); } } return(ret); }
/// <summary> /// We attempt to execute an expression (list of functions) on an empty stack. /// When no exception is raised we know that the subexpression can be replaced with anything /// that generates the values. /// </summary> static CatExpr PartialEval(Executor exec, CatExpr fxns) { // Recursively partially evaluate all quotations for (int i = 0; i < fxns.Count; ++i) { Function f = fxns[i]; if (f is PushFunction) { PushFunction q = f as PushFunction; CatExpr tmp = PartialEval(new Executor(), q.GetSubFxns()); fxns[i] = new PushFunction(tmp); } } CatExpr ret = new CatExpr(); object[] values = null; int j = 0; while (j < fxns.Count) { try { Function f = fxns[j]; if (f is DefinedFunction) { f.Eval(exec); } else { if (f.GetFxnType() == null) { throw new Exception("no type availables"); } if (f.GetFxnType().HasSideEffects()) { throw new Exception("can't perform partial execution when an expression has side-effects"); } f.Eval(exec); } // at each step, we have to get the values stored so far // since they could keep changing and any exception // will obliterate the old values. values = exec.GetStackAsArray(); } catch { if (values != null) { // Copy all of the values from the previous good execution for (int k = values.Length - 1; k >= 0; --k) { ret.Add(ValueToFunction(values[k])); } } ret.Add(fxns[j]); exec.Clear(); values = null; } j++; } if (values != null) { for (int l = values.Length - 1; l >= 0; --l) { ret.Add(ValueToFunction(values[l])); } } return(ret); }