public override void EvalCond(PathCond evalCond, IDictionary <FullCellAddr, PathCond> evalConds, List <CGCachedExpr> caches) { if (es.Length >= 1) { CachedAtom atom = new CachedAtom(es[0], caches); CGCachedExpr cached = atom.cachedExpr; es[0].EvalCond(evalCond, evalConds, caches); es[0] = cached; for (int i = 1; i < es.Length; i++) { CGExpr iConst = CGConst.Make(i); CGExpr cond = new CGEqual(new CGExpr[] { cached, iConst }); es[i].EvalCond(evalCond.And(new CachedAtom(cond, caches)), evalConds, caches); } } }
public static CGExpr Make(String name, CGExpr[] es) { name = name.ToUpper(); // This switch should agree with the function table in Functions.cs switch (name) { case "+": return(new CGArithmetic2(OpCodes.Add, name, es)); case "*": return(new CGArithmetic2(OpCodes.Mul, name, es)); case "-": return(new CGArithmetic2(OpCodes.Sub, name, es)); case "/": return(new CGArithmetic2(OpCodes.Div, name, es)); case "=": return(CGEqual.Make(es)); case "<>": return(CGNotEqual.Make(es)); case ">": return(new CGGreaterThan(es)); case "<=": return(new CGLessThanOrEqual(es)); case "<": return(new CGLessThan(es)); case ">=": return(new CGGreaterThanOrEqual(es)); // Non-strict, or other special treatment case "AND": return(new CGAnd(es)); case "APPLY": return(new CGApply(es)); case "CHOOSE": return(new CGChoose(es)); case "CLOSURE": return(new CGClosure(es)); case "ERR": return(new CGError(es)); case "EXTERN": return(new CGExtern(es)); case "IF": return(new CGIf(es)); case "NA": if (es.Length == 0) { return(new CGError(ErrorValue.naError)); } else { return(new CGError(ErrorValue.argCountError)); } case "NEG": return(new CGNeg(es)); case "NOT": return(new CGNot(es)); case "OR": return(new CGOr(es)); case "PI": if (es.Length == 0) { return(new CGNumberConst(NumberValue.PI)); } else { return(new CGError(ErrorValue.argCountError)); } case "VOLATILIZE": if (es.Length == 1) { return(es[0]); } else { return(new CGError(ErrorValue.argCountError)); } default: // The general case for most built-in functions with unspecific argument types FunctionInfo functionInfo; if (FunctionInfo.Find(name, out functionInfo)) { return(new CGFunctionCall(functionInfo, es)); } else // May be a sheet-defined function { SdfInfo sdfInfo = SdfManager.GetInfo(name); if (sdfInfo != null) { return(new CGSdfCall(sdfInfo, es)); } else { return(new CGError(ErrorValue.nameError)); } } } }
public override void EvalCond(PathCond evalCond, IDictionary<FullCellAddr, PathCond> evalConds, List<CGCachedExpr> caches) { if (es.Length >= 1) { CachedAtom atom = new CachedAtom(es[0], caches); CGCachedExpr cached = atom.cachedExpr; es[0].EvalCond(evalCond, evalConds, caches); es[0] = cached; for (int i = 1; i < es.Length; i++) { CGExpr iConst = CGConst.Make(i); CGExpr cond = new CGEqual(new CGExpr[] {cached, iConst}); es[i].EvalCond(evalCond.And(new CachedAtom(cond, caches)), evalConds, caches); } } }