Example #1
0
        /// <summary>
        /// Static version of the Expression Evaluator
        /// </summary>
        /// <param name="expression">expression to be evaluated</param>
        /// <param name="handler">attach a custom function handler</param>
        /// <returns></returns>
        public static object Evaluate(string expression, AdditionalFunctionEventHandler handler)
        {
            ExpressionEval expr = new ExpressionEval(expression);

            expr.AdditionalFunctionEventHandler += handler;
            return(expr.Evaluate());
        }
Example #2
0
        /// <summary>
        /// Executes the function based upon the name of the function
        /// </summary>
        /// <param name="name">name of the function to execute</param>
        /// <param name="p">parameter list</param>
        /// <returns>returned value of executed function</returns>
        //[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private object ExecuteFunction(string name, object[] p)
        {
            object[] parameters = null;
            if (p != null)
            {
                parameters = (object[])p.Clone();
                for (int x = 0; x < parameters.Length; x++)
                {
                    if (parameters[x] is IExpression)
                    {
                        parameters[x] = ((IExpression)parameters[x]).Evaluate();
                    }
                }
            }
            switch (name.ToLower(CultureInfo.CurrentCulture))
            {
            // Math functions
            case "sin":     return(Math.Sin(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "cos":     return(Math.Cos(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "tan":     return(Math.Tan(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "sec":     return(1 / Math.Cos(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "csc":     return(1 / Math.Sin(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "cot":     return(1 / Math.Tan(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "asin":    return(Math.Asin(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "acos":    return(Math.Acos(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "atan":    return(Math.Atan(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "sinh":    return(Math.Sinh(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "cosh":    return(Math.Cosh(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "tanh":    return(Math.Tanh(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "abs":     return(Math.Abs(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "sqrt":    return(Math.Sqrt(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "ciel":    return(Math.Ceiling(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "floor":   return(Math.Floor(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "exp":     return(Math.Exp(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "log10":   return(Math.Log10(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "log":     return((parameters.Length > 1) ?
                                   Math.Log(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToDouble(parameters[1], CultureInfo.CurrentCulture)) :
                                   Math.Log(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            case "max":     return(Math.Max(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToDouble(parameters[1], CultureInfo.CurrentCulture)));

            case "min":     return(Math.Min(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToDouble(parameters[1], CultureInfo.CurrentCulture)));

            case "pow":     return(Math.Pow(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToDouble(parameters[1], CultureInfo.CurrentCulture)));

            case "round":   return((parameters.Length > 1) ?
                                   Math.Round(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture), Convert.ToInt32(parameters[1], CultureInfo.CurrentCulture)) :
                                   Math.Round(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture)));

            //case "trunc":   return Math.Truncate(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));
            case "e":       return(Math.E);

            case "pi":      return(Math.PI);

            //DateTime functions
            case "now":     return(DateTime.Now);

            case "today":   return(DateTime.Today);

            case "mindate": return(DateTime.MinValue);

            case "maxdate": return(DateTime.MaxValue);

            case "monthname": return((new DateTime(2000, Convert.ToInt32(parameters[0]), 1)).ToString("MMMM"));

            case "adddays": return(Convert.ToDateTime(parameters[0]).AddDays(Convert.ToInt32(parameters[1])));

            case "addmonths": return(Convert.ToDateTime(parameters[0]).AddMonths(Convert.ToInt32(parameters[1])));

            case "addyears": return(Convert.ToDateTime(parameters[0]).AddYears(Convert.ToInt32(parameters[1])));

            case "addhours": return(Convert.ToDateTime(parameters[0]).AddHours(Convert.ToInt32(parameters[1])));

            case "addminutes": return(Convert.ToDateTime(parameters[0]).AddMinutes(Convert.ToInt32(parameters[1])));

            case "addseconds": return(Convert.ToDateTime(parameters[0]).AddSeconds(Convert.ToInt32(parameters[1])));

            //Formatting Functions
            case "fmtnum":  return(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture).ToString("" + parameters[1], CultureInfo.CurrentCulture));

            case "fmtdate": return(Convert.ToDateTime(parameters[0], CultureInfo.CurrentCulture).ToString("" + parameters[1], CultureInfo.CurrentCulture));

            //Numerical Expression Evaluation
            case "expr":
            {
                ExpressionEval eval = new ExpressionEval("" + parameters[0]);
                eval.AdditionalFunctionEventHandler += this.AdditionalFunctionEventHandler;
                eval._variables = this._variables;
                return(eval.Evaluate());
            }

            //Casting Functions
            case "cdbl":    return(Convert.ToDouble(parameters[0], CultureInfo.CurrentCulture));

            case "cint":    return(Convert.ToInt32(parameters[0], CultureInfo.CurrentCulture));

            case "clong":   return(Convert.ToInt64(parameters[0], CultureInfo.CurrentCulture));

            case "cuint":   return(Convert.ToUInt32(parameters[0], CultureInfo.CurrentCulture));

            case "culong":  return(Convert.ToUInt64(parameters[0], CultureInfo.CurrentCulture));

            case "cdatetime": return(Convert.ToDateTime(parameters[0], CultureInfo.CurrentCulture));

            case "str":     return(parameters[0].ToString());

            //Logical Functions
            case "iif":     return(Iif(parameters));

            case "case":    return(Case(parameters));

            //security fucntions
            case "currentuserid": return(WindowsIdentity.GetCurrent().Name.ToLower());

            default:        return(AdditionalFunctionHelper(name, parameters));
            }
        }
Example #3
0
        /// <summary>
        /// returns the parameters of a function
        /// </summary>
        /// <param name="m">regex math value</param>
        /// <returns></returns>
        private object [] GetParameters(Match m)
        {
            string    strParams = "";
            int       nIdx      = m.Index + m.Length;
            int       nDepth    = 1;
            int       nLast     = 0;
            bool      bInQuotes = false;
            ArrayList ret       = new ArrayList();

            //Get the parameter string
            while (nDepth > 0)
            {
                if (nIdx >= Expression.Length)
                {
                    throw new ArgumentException("Missing ')' in Expression");
                }

                if (!bInQuotes && Expression[nIdx] == ')')
                {
                    nDepth--;
                }
                if (!bInQuotes && Expression[nIdx] == '(')
                {
                    nDepth++;
                }

                if (Expression[nIdx] == '"' && (nIdx == 0 || Expression[nIdx - 1] != '\\'))
                {
                    bInQuotes = !bInQuotes;
                }

                if (nDepth > 0)
                {
                    nIdx++;
                }
            }
            strParams = Expression.Substring(m.Index + m.Length, nIdx - (m.Index + m.Length));

            if ("" + strParams == "")
            {
                return(null);
            }

            bInQuotes = false;
            for (nIdx = 0; nIdx < strParams.Length; nIdx++)
            {
                if (!bInQuotes && strParams[nIdx] == ')')
                {
                    nDepth--;
                }
                if (!bInQuotes && strParams[nIdx] == '(')
                {
                    nDepth++;
                }

                if (strParams[nIdx] == '"' && (nIdx == 0 || strParams[nIdx - 1] != '\\'))
                {
                    bInQuotes = !bInQuotes;
                }

                if (!bInQuotes && nDepth == 0 && strParams[nIdx] == ',')
                {
                    ret.Add(strParams.Substring(nLast, nIdx - nLast));
                    nLast = nIdx + 1;
                }
            }
            ret.Add(strParams.Substring(nLast, nIdx - nLast));

            for (nIdx = 0; nIdx < ret.Count; nIdx++)
            {
                ExpressionEval eval = new ExpressionEval(ret[nIdx].ToString());
                eval.AdditionalFunctionEventHandler += AdditionalFunctionEventHandler;
                eval._variables = this._variables;
                ret[nIdx]       = eval;
            }
            return(ret.ToArray());
        }
Example #4
0
        /// <summary>
        /// This will search the expression for the next token (operand, operator, etc)
        /// </summary>
        /// <param name="nIdx">Start Position of Search</param>
        /// <returns>First character index after token.</returns>
        //[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private int NextToken(int nIdx)
        {
            Match  mRet = null;
            int    nRet = nIdx;
            object val  = null;

            //Check for preceeding white space from last token index
            Match m = DefinedRegex.WhiteSpace.Match(Expression, nIdx);

            if (m.Success && m.Index == nIdx)
            {
                return(nIdx + m.Length);
            }

            //Check Parenthesis
            m = DefinedRegex.Parenthesis.Match(Expression, nIdx);
            if (m.Success)
            {
                mRet = m;
            }

            //Check Function
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Function.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m;
                }
            }

            //Check Variable
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Variable.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m; val = new Variable(m.Groups["Variable"].Value, _variables);
                }
            }

            //Check Unary Operator
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.UnaryOp.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m; val = new UnaryOp(m.Value);
                }
            }

            //Check Hexadecimal
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Hexadecimal.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m; val = Convert.ToInt32(m.Value, 16);
                }
            }

            //Check Boolean
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Boolean.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m; val = bool.Parse(m.Value);
                }
            }

            //Check DateTime
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.DateTime.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m; val = Convert.ToDateTime(m.Groups["DateString"].Value, CultureInfo.CurrentCulture);
                }
            }

            //Check Timespan
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.TimeSpan.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m;
                    val  = new TimeSpan(
                        int.Parse("0" + m.Groups["Days"].Value),
                        int.Parse(m.Groups["Hours"].Value),
                        int.Parse(m.Groups["Minutes"].Value),
                        int.Parse("0" + m.Groups["Seconds"].Value),
                        int.Parse("0" + m.Groups["Milliseconds"].Value)
                        );
                }
            }

            //Check Numeric
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.Numeric.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    while (m.Success && ("" + m.Value == ""))
                    {
                        m = m.NextMatch();
                    }
                    if (m.Success)
                    {
                        mRet = m;
                        val  = double.Parse(m.Value, CultureInfo.CurrentCulture);
                    }
                }
            }

            if (mRet == null || mRet.Index > nIdx)
            {
                //Check String
                m = DefinedRegex.String.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m; val = m.Groups["String"].Value.Replace("\\\"", "\"");
                }
            }

            //Check Binary Operator
            if (mRet == null || mRet.Index > nIdx)
            {
                m = DefinedRegex.BinaryOp.Match(Expression, nIdx);
                if (m.Success && (mRet == null || m.Index < mRet.Index))
                {
                    mRet = m; val = new BinaryOp(m.Value);
                }
            }

            if (mRet == null)
            {
                throw new ArgumentException("Invalid expression construction: \"" + Expression + "\".");
            }

            if (mRet.Index != nIdx)
            {
                throw new ArgumentException(
                          "Invalid token in expression: [" +
                          Expression.Substring(nIdx, mRet.Index - nIdx).Trim() + "]"
                          );
            }

            if (mRet.Value == "(" || mRet.Value.StartsWith("$"))
            {
                nRet = mRet.Index + mRet.Length;
                int  nDepth    = 1;
                bool bInQuotes = false;
                while (nDepth > 0)
                {
                    if (nRet >= Expression.Length)
                    {
                        throw new ArgumentException("Missing " + (bInQuotes ? "\"" : ")") + " in Expression");
                    }
                    if (!bInQuotes && Expression[nRet] == ')')
                    {
                        nDepth--;
                    }
                    if (!bInQuotes && Expression[nRet] == '(')
                    {
                        nDepth++;
                    }

                    if (Expression[nRet] == '"' && (nRet == 0 || Expression[nRet - 1] != '\\'))
                    {
                        bInQuotes = !bInQuotes;
                    }

                    nRet++;
                }
                if (mRet.Value == "(")
                {
                    ExpressionEval expr = new ExpressionEval(
                        Expression.Substring(mRet.Index + 1, nRet - mRet.Index - 2)
                        );
                    if (this.AdditionalFunctionEventHandler != null)
                    {
                        expr.AdditionalFunctionEventHandler += this.AdditionalFunctionEventHandler;
                    }
                    expr._variables = this._variables;
                    _expressionlist.Add(expr);
                }
                else
                {
                    FunctionEval func = new FunctionEval(
                        Expression.Substring(mRet.Index, (nRet) - mRet.Index)
                        );
                    if (this.AdditionalFunctionEventHandler != null)
                    {
                        func.AdditionalFunctionEventHandler += this.AdditionalFunctionEventHandler;
                    }
                    func._variables = this._variables;
                    _expressionlist.Add(func);
                }
            }
            else
            {
                nRet = mRet.Index + mRet.Length;
                _expressionlist.Add(val);
            }

            return(nRet);
        }
Example #5
0
 public BinaryOp(string strOp)
 {
     _strOp = strOp; _nPrecedence = ExpressionEval.OperatorPrecedence(strOp);
 }
Example #6
0
        /// <summary>
        /// Static version of the Expression Evaluator
        /// </summary>
        /// <param name="expression">expression to be evaluated</param>
        /// <returns></returns>
        public static object Evaluate(string expressionString)
        {
            ExpressionEval expression = new ExpressionEval(expressionString);

            return(expression.Evaluate());
        }