public override BigDecimal EvaluateFunction(FuncToken token)
        {
            if (token is CallerFuncToken)
            {
                return(parser.FunctionsDict[token.Symbol].Invoke(fallback.EvaluateTokens((token).SubTokens.ToArray())));
            }
            switch (token.Symbol)
            {
            case ParserSymbols.Negate:
                return(eval(token.SubTokens[0]) * -1);

            case ParserSymbols.Rad:
                return(eval(token.SubTokens[0]) * Math.PI / 180);

            case ParserSymbols.Deg:
                return(eval(token.SubTokens[0]) * 180 / Math.PI);

            case ParserSymbols.Floor:
                return(eval(token.SubTokens[0]).Floor());

            case ParserSymbols.Not:
                return(eval(token.SubTokens[0]) == 0 ? 1 : 0);

            case ParserSymbols.Fact:
                var v = eval(token.SubTokens[0]);
                if (v < 0 || v % 1 != 0)
                {
                    return(double.NaN);
                }
                BigDecimal fact = 1;
                for (int i = (int)v; i > 0; i--)
                {
                    fact *= i;
                }
                return(fact);

            case ParserSymbols.Cond:
                return(eval(token.SubTokens[0]) != 0
                        ? eval(token.SubTokens[1])
                        : eval(token.SubTokens[2]));

            default:
                if (Context.Options.StrictMode)
                {
                    throw new UnsupportedOperationException(token.Symbol);
                }
                double result = token.Evaluate(fallback);
                if (double.IsNaN(result))
                {
                    throw new ParserArithmeticException(token.Position);
                }
                else
                {
                    return((BigDecimal)result);
                }
            }
        }
Exemple #2
0
        public override decimal EvaluateFunction(FuncToken token)
        {
            if (token is CallerFuncToken)
            {
                return((decimal)parser.FunctionsDict[token.Symbol].Invoke(fallback.EvaluateTokens((token).SubTokens.ToArray())));
            }
            switch (token.Symbol)
            {
            case ParserSymbols.Negate:
                return(eval(token.SubTokens[0]) * -1);

            case ParserSymbols.Rad:
                return(eval(token.SubTokens[0]) * (decimal)Math.PI / 180);

            case ParserSymbols.Deg:
                return(eval(token.SubTokens[0]) * 180 / (decimal)Math.PI);

            case ParserSymbols.Ceil:
                return(Math.Ceiling(eval(token.SubTokens[0])));

            case ParserSymbols.Floor:
                return(Math.Floor(eval(token.SubTokens[0])));

            case ParserSymbols.Round:
                return(Math.Round(eval(token.SubTokens[0])));

            case ParserSymbols.Sign:
                return(Math.Sign(eval(token.SubTokens[0])));

            case ParserSymbols.Trunc:
                return(Math.Truncate(eval(token.SubTokens[0])));

            case ParserSymbols.Min:
                return(EvaluateTokens(token.SubTokens.ToArray()).Min());

            case ParserSymbols.Max:
                return(EvaluateTokens(token.SubTokens.ToArray()).Max());

            case ParserSymbols.Avg:
                return(EvaluateTokens(token.SubTokens.ToArray()).Average());

            case ParserSymbols.AndFunc:
                return(EvaluateTokens(token.SubTokens.ToArray())
                       .Select(v1 => Convert.ToBoolean(v1))
                       .Aggregate((v1, v2) => v1 & v2) ? 1 : 0);

            case ParserSymbols.OrFunc:
                return(EvaluateTokens(token.SubTokens.ToArray())
                       .Select(v1 => Convert.ToBoolean(v1))
                       .Aggregate((v1, v2) => v1 | v2) ? 1 : 0);

            case ParserSymbols.XorFunc:
                return(EvaluateTokens(token.SubTokens.ToArray())
                       .Select(v1 => Convert.ToBoolean(v1))
                       .Aggregate((v1, v2) => v1 ^ v2) ? 1 : 0);

            case ParserSymbols.Not:
                return(!Convert.ToBoolean(eval(token.SubTokens[0])) ? 1 : 0);

            case ParserSymbols.Fact:
                decimal v = eval(token.SubTokens[0]);
                if (v < 0 || v % 1 != 0)
                {
                    throw new ParserArithmeticException(token.Position);
                }
                decimal fact = 1;
                for (int i = (int)v; i > 0; i--)
                {
                    fact *= i;
                }
                return(fact);

            case ParserSymbols.Cond:
                return(Convert.ToBoolean(eval(token.SubTokens[0]))
                        ? eval(token.SubTokens[1])
                        : eval(token.SubTokens[2]));

            default:
                if (Context.Options.StrictMode)
                {
                    throw new UnsupportedOperationException(token.Symbol);
                }
                double result = token.Evaluate(fallback);
                if (double.IsNaN(result))
                {
                    throw new ParserArithmeticException(token.Position);
                }
                else
                {
                    return((decimal)result);
                }
            }
        }