예제 #1
0
        public override bool Equals(object obj)
        {
            EvalValue b = obj as EvalValue;

            if (stringValue == null)
            {
                return(D == b.D);
            }
            else
            {
                return(S == b.S);
            }
        }
예제 #2
0
        private decimal evalExternalFunctionCall(String funcName, String expr)
        {
            Tokenizer paramTokenizer = new Tokenizer(expr, ",", true);

            System.Collections.ArrayList functionParms = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10));
            while (paramTokenizer.HasMoreTokens())
            {
                String arg = getNextToken(paramTokenizer).Trim();
                if ((arg.StartsWith("\"") || arg.StartsWith("'")) && (arg.EndsWith("\"") || arg.EndsWith("'")))
                {
                    // it is a string
                    functionParms.Add(arg.Substring(1, (arg.Length - 1) - (1)));
                }
                else
                {
                    // evaluate the parameter
                    EvalValue eValue = eval(arg);
                    // The corresponding type of parameter is passed
                    if (eValue.S == null)
                    {
                        functionParms.Add(eValue.D);
                    }
                    else
                    {
                        functionParms.Add(eValue.S);
                    }
                }

                if (paramTokenizer.HasMoreTokens())
                {
                    // Consume the ','
                    paramTokenizer.NextToken();
                }
            }
            functionParms.Add((decimal)0);
            System.Object[] callParms = new System.Object[functionParms.Count];
            functionParms.CopyTo(callParms);

            bool pAdded = false;

            try
            {
                funcName = funcName.ToLower();

                DynamicExecute(funcName, callParms);
            }
            catch (System.Exception e)
            {
                bool retrySuccessful = false;

                if (!pAdded && e.ToString().IndexOf("ClassNotFoundException") != -1)
                {
                    try
                    {
                        DynamicExecute("p" + funcName, callParms);
                        retrySuccessful = true;
                    }
                    catch (System.Exception)
                    {
                    }
                }
                if (!retrySuccessful)
                {
                    return(throwException(EXTERNAL_FUNCTION_ERROR, e.Message));
                }
            }

            return(Convert.ToDecimal(callParms[callParms.Length - 1], System.Globalization.CultureInfo.InvariantCulture));
        }
예제 #3
0
        private decimal evalFuncCall(String funcName, String expr)
        {
            EvalValue result = 0;

            if (funcName.ToUpper().Equals("rnd".ToUpper()))
            {
                // random function
                result = (decimal)NumberUtil.Random();
            }
            else
            // single variable function
            if (funcName.ToUpper().Equals("abs".ToUpper()))
            {
                result = System.Math.Abs(eval(expr).D);
            }
            else if (funcName.ToUpper().Equals("int".ToUpper()))
            {
                result = System.Math.Floor(eval(expr).D);
            }
            else if (funcName.ToUpper().Equals("frac".ToUpper()))
            {
                EvalValue value    = eval(expr);
                EvalValue int_part = System.Math.Floor(value.D);
                result = value - int_part;
            }
            else if (funcName.ToUpper().Equals("sin".ToUpper()))
            {
                result = (decimal)System.Math.Sin(Convert.ToDouble((decimal)eval(expr)));
            }
            else if (funcName.ToUpper().Equals("asin".ToUpper()))
            {
                result = (decimal)System.Math.Asin(Convert.ToDouble((decimal)eval(expr)));
            }
            else if (funcName.ToUpper().Equals("cos".ToUpper()))
            {
                result = (decimal)System.Math.Cos(Convert.ToDouble((decimal)eval(expr)));
            }
            else if (funcName.ToUpper().Equals("acos".ToUpper()))
            {
                decimal x = eval(expr).D;
                if (x > 1 || x < -1)
                {
                    throwException(EVALUATION_ERROR, "Invalid range");
                }
                result = (decimal)System.Math.Acos(Convert.ToDouble(x));
            }
            else if (funcName.ToUpper().Equals("tan".ToUpper()))
            {
                result = (decimal)System.Math.Tan(Convert.ToDouble((decimal)eval(expr)));
            }
            else if (funcName.ToUpper().Equals("atan".ToUpper()))
            {
                result = (decimal)System.Math.Atan(Convert.ToDouble((decimal)eval(expr)));
            }
            else if (funcName.ToUpper().Equals("floor".ToUpper()))
            {
                result = (decimal)System.Math.Floor(Convert.ToDouble((decimal)eval(expr)));
            }
            else if (funcName.ToUpper().Equals("round".ToUpper()))
            {
                result = System.Math.Round(eval(expr));
            }
            else if (funcName.ToUpper().Equals("ln".ToUpper()) || funcName.ToUpper().Equals("log".ToUpper()))
            {
                decimal val = eval(expr);
                if (val <= 0)
                {
                    return(throwException(EVALUATION_ERROR, "Illegal argument (" + val + ") to function log(" + expr + ")"));
                }
                result = (decimal)System.Math.Log(Convert.ToDouble(val));
            }
            else if (funcName.ToUpper().Equals("exp".ToUpper()))
            {
                result = (decimal)System.Math.Exp(Convert.ToDouble((decimal)eval(expr)));
            }
            else if (funcName.ToUpper().Equals("sqrt".ToUpper()))
            {
                result = (decimal)System.Math.Sqrt(Convert.ToDouble((decimal)eval(expr)));
            }
            else
            // internal functions of 2 variables
            if (funcName.ToUpper().Equals("pow".ToUpper()) || funcName.ToUpper().Equals("max".ToUpper()) || funcName.ToUpper().Equals("min".ToUpper()))
            {
                Tokenizer paramTokenizer = new Tokenizer(expr, ",", true);
                String    sarg1, sarg2;
                try
                {
                    sarg1 = getNextToken(paramTokenizer);
                    paramTokenizer.NextToken();
                    sarg2 = getNextToken(paramTokenizer);
                }
                catch (System.ArgumentOutOfRangeException)
                {
                    return(throwException(EVALUATION_ERROR, "The function " + funcName + " needs 2 arguments"));
                }

                decimal arg1 = eval(sarg1);
                decimal arg2 = eval(sarg2);

                if (funcName.ToUpper().Equals("pow".ToUpper()))
                {
                    result = (decimal)System.Math.Pow(Convert.ToDouble(arg1), Convert.ToDouble(arg2));
                }
                else if (funcName.ToUpper().Equals("max".ToUpper()))
                {
                    result = System.Math.Max(arg1, arg2);
                }
                else if (funcName.ToUpper().Equals("min".ToUpper()))
                {
                    result = System.Math.Min(arg1, arg2);
                }
            }
            else

            if (funcName.ToUpper().Equals("iif".ToUpper()))
            {
                // iif
                Tokenizer paramTokenizer = new Tokenizer(expr, ",", true);
                String    sarg1, sarg2, sarg3;
                try
                {
                    sarg1 = getNextToken(paramTokenizer);
                    paramTokenizer.NextToken();
                    sarg2 = getNextToken(paramTokenizer);
                    paramTokenizer.NextToken();
                    sarg3 = getNextToken(paramTokenizer);
                }
                catch (System.ArgumentOutOfRangeException)
                {
                    return(throwException(EVALUATION_ERROR, "The function " + funcName + " needs 3 arguments"));
                }
                iifContext = true;
                bool iif_result = (eval(sarg1) != 0);
                iifContext = false;
                if (ErrCode != 0)
                {
                    return(result);
                }
                if (iif_result)
                {
                    result = eval(sarg2);
                }
                else
                {
                    result = eval(sarg3);
                }
            }
            else
            {
                result = evalExternalFunctionCall(funcName, expr);
            }
            return(result);
        }
예제 #4
0
        private EvalValue evaluate(String fullExpression, Tokenizer tokenizer, bool stopOnLowPrecedence)
        {
            EvalValue retVal  = eval(tokenizer);
            EvalValue termino = 0;

            while (tokenizer.HasMoreTokens())
            {
                if (stopOnLowPrecedence)
                {
                    string nextOp;
                    if (tokenizer.Peek(out nextOp) && nextOp.Length >= 1 && (nextOp[0] == '+' || nextOp[0] == '-'))
                    {
                        break;
                    }
                }

                string soperador = tokenizer.NextToken();
                if (String.IsNullOrEmpty(soperador.Trim()))
                {
                    continue;
                }

                char operador = soperador[0];

                switch (operador)
                {
                case '+':
                    termino = evaluate(fullExpression, tokenizer, true);
                    retVal  = retVal + termino;
                    break;

                case '-':
                    termino = evaluate(fullExpression, tokenizer, true);
                    retVal  = retVal - termino;
                    break;

                case '*':
                    termino = eval(tokenizer);
                    retVal  = retVal * termino;
                    break;

                case '/':
                    termino = eval(tokenizer);
                    if (termino == 0 && errCode == 0)
                    {
                        throwException(EVALUATION_ERROR, "Division by zero");
                    }
                    if (errCode == 0)
                    {
                        retVal = retVal / termino;
                    }
                    break;

                case '>': return(retVal > evaluate(fullExpression, tokenizer) ? 1 : 0);

                case '<': return(retVal < evaluate(fullExpression, tokenizer) ? 1 : 0);

                case '=': return(retVal == evaluate(fullExpression, tokenizer) ? 1 : 0);

                case GE: return(retVal >= evaluate(fullExpression, tokenizer) ? 1 : 0);

                case LE: return(retVal <= evaluate(fullExpression, tokenizer) ? 1 : 0);

                case AND: return((retVal != 0) && (evaluate(fullExpression, tokenizer) != 0) ? 1 : 0);

                case OR: return((retVal != 0) || (evaluate(fullExpression, tokenizer) != 0) ? 1 : 0);

                case NE: return(retVal != evaluate(fullExpression, tokenizer) ? 1 : 0);

                default:
                    throwException(EVALUATION_ERROR, "Unknown operator '" + soperador + "' found in expression '" + fullExpression + "'");
                    break;
                }
            }
            return(retVal);
        }