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