// using the Eval engine // Find all variable names static public HashSet <string> EvalVariablesUsed(List <Condition> fel) { HashSet <string> str = new HashSet <string>(); Eval evl = new Eval(true, true, true); evl.Fake = true; evl.ReturnFunctionValue = BaseFunctionsForEval.BaseFunctions; evl.AllowMemberSymbol = true; evl.AllowArrays = true; evl.ReturnSymbolValue += (string s) => { str.Add(s); //System.Diagnostics.Debug.WriteLine($"Sym {s}"); return(1L); }; foreach (Condition c in fel) { if (!c.Disabled) { foreach (ConditionEntry ce in c.Fields) { evl.Evaluate(ce.ItemName); evl.Evaluate(ce.MatchString); } } } return(str); }
// return StringParser.ConvertError, string, double, long static public Object Expr(string s, bool checkend = true, bool allowfp = true, bool allowstrings = true) { Eval v = new Eval(s); v.CheckEnd = checkend; v.AllowFP = allowfp; v.AllowStrings = allowstrings; return(v.Evaluate()); }
public Object Functions(string name, IEval evaluator) { Object ret = BaseFunctions != null?BaseFunctions(name, evaluator) : new StringParser.ConvertError("() not recognised"); StringParser.ConvertError ce = ret as StringParser.ConvertError; if (ce != null && ce.ErrorValue.Contains("() not recognised")) { if (functions.ContainsKey(name)) { FuncDef fd = functions[name]; bool hasparas = fd.parameters.Length > 0; if (hasparas) { IEvalParaListType[] plist = new IEvalParaListType[fd.parameters.Length]; plist = Enumerable.Repeat(IEvalParaListType.All, fd.parameters.Length).ToArray(); List <Object> paras = evaluator.Parameters(name, fd.parameters.Length, plist); if (paras == null) // if error, stop and return error { return(evaluator.Value); } symbols.Push(); for (int i = 0; i < fd.parameters.Length; i++) // add to symbol list on next level the parameter names and values { System.Diagnostics.Debug.WriteLine(symbols.Levels + " " + name + " Push " + fd.parameters[i] + "=" + paras[i]); symbols.Add(fd.parameters[i], paras[i]); } } Eval evfunc = (Eval)evaluator.Clone(); // we need a fresh one just to evaluate this, but with the same configuration Object res = evfunc.Evaluate(fd.funcdef); // and evaluate if (hasparas) { symbols.Pop(); // clear back stack.. } return(res); } } return(ret); }
static public Object BaseFunctions(string name, IEval evaluator) { string[] maths = { "Abs", "Acos", "Asin", "Atan", "Ceiling", "Cos", "Cosh", "Exp", "Floor", "Log", "Log10", "Sin", "Sinh", "Sqrt","Tan","Tanh", "Truncate" }; int mathsindex = Array.IndexOf(maths, name); if (mathsindex >= 0) { List <Object> list = evaluator.Parameters(name, 1, new IEvalParaListType[] { IEvalParaListType.NumberOrInteger }); if (list != null) { return(MathFunc(name, typeof(Math), list[0])); } else { return(evaluator.Value); } } string[] chars = { "IsControl", "IsDigit", "IsLetter", "IsLower", "IsNumber", "IsPunctuation", "IsSeparator", "IsSurrogate", "IsSymbol", "IsUpper", "IsWhiteSpace", "ToLower", "ToUpper" }; int charsindex = Array.IndexOf(chars, name); if (charsindex >= 0) { List <Object> list = evaluator.Parameters(name, 1, new IEvalParaListType[] { (name == "ToLower" || name == "ToUpper") ? IEvalParaListType.IntegerOrString : IEvalParaListType.Integer }); if (list != null) { if (name == "ToLower" && list[0] is string) { return(((string)list[0]).ToLower(evaluator.Culture)); } else if (name == "ToUpper" && list[0] is string) { return(((string)list[0]).ToUpper(evaluator.Culture)); } else { var methodarray = typeof(Char).GetMember(name); // get members given name var method = methodarray.FindMember(new Type[] { list[0] is long?typeof(char) : typeof(string) }); // find all members which have a single para of this type if (method.ReturnType == typeof(bool)) { bool value = (bool)method.Invoke(null, new Object[] { (char)(long)list[0] }); return(value ? (long)1 : (long)0); } else { char ch = (char)method.Invoke(null, new Object[] { (char)(long)list[0] }); return((long)ch); } } } else { return(evaluator.Value); } } if (name == "Max" || name == "Min") { List <Object> list = evaluator.Parameters(name, 2, new IEvalParaListType[] { IEvalParaListType.NumberOrInteger, IEvalParaListType.NumberOrInteger }); if (list != null) { if (list[0] is long && list[1] is long) { return(name == "Max" ? Math.Max((long)list[0], (long)list[1]) : Math.Min((long)list[0], (long)list[1])); } else { double[] array = ToDouble(list); return(name == "Max" ? Math.Max(array[0], array[1]) : Math.Min(array[0], array[1])); } } } else if (name == "Pow") { List <Object> list = evaluator.Parameters(name, 2, new IEvalParaListType[] { IEvalParaListType.Number, IEvalParaListType.Number }); if (list != null) { return(Math.Pow((double)list[0], (double)list[1])); } } else if (name == "Round") { List <Object> list = evaluator.Parameters(name, 1, new IEvalParaListType[] { IEvalParaListType.Number, IEvalParaListType.Integer }); if (list != null) { return((list.Count == 1) ? Math.Round((double)list[0]) : Math.Round((double)list[0], (int)(long)list[1])); } } else if (name == "Sign") { List <Object> list = evaluator.Parameters(name, 1, new IEvalParaListType[] { IEvalParaListType.NumberOrInteger }); if (list != null) { return((long)(list[0] is long?Math.Sign((long)list[0]) : Math.Sign((double)list[0]))); } } else if (name == "Fp" || name == "double" || name == "float") { List <Object> list = evaluator.Parameters(name, 1, new IEvalParaListType[] { IEvalParaListType.Number }); // gather a single number if (list != null) { return(list[0]); } } else if (name == "Eval") { List <Object> list = evaluator.Parameters(name, 1, new IEvalParaListType[] { IEvalParaListType.String }); if (list != null) { Eval ev = new Eval(true, true, true); return(ev.Evaluate((string)list[0])); } } else if (name == "ToString") { List <Object> list = evaluator.Parameters(name, 2, new IEvalParaListType[] { IEvalParaListType.NumberOrInteger, IEvalParaListType.String }); if (list != null) { string output; bool ok = (list[0] is double) ? ((double)list[0]).SafeToString(list[1] as string, out output) : ((long)list[0]).SafeToString(list[1] as string, out output); if (ok) { return(output); } else { return(new StringParser.ConvertError(name + "() Format is incorrect")); } } } else if (name == "Unicode") { List <Object> list = evaluator.Parameters(name, 1, new IEvalParaListType[] { IEvalParaListType.Integer }); if (list != null) { return((string)char.ToString((char)(long)list[0])); } } else { return(new StringParser.ConvertError(name + "() not recognised")); } return(evaluator.Value); }