Exemplo n.º 1
0
        public override string EvaluateFunction(FuncToken token)
        {
            switch (token.Symbol)
            {
            case ParserSymbols.Sqrt:
                return($"<msqrt>{token.SubTokens[0].Evaluate(this)}</msqrt>");

            case ParserSymbols.Cbrt:
                return($"<mroot><mrow>{token.SubTokens[0].Evaluate(this)}</mrow><mn>3</mn></mroot>");

            case ParserSymbols.Abs:
                return($"<mo>|</mo>{token.SubTokens[0].Evaluate(this)}<mo>|</mo>");

            case ParserSymbols.Log10:
                var sbLog10 = new StringBuilder();
                sbLog10.AppendFormat("<msub><mi>{0}</mi><mn>10</mn></msub>", ParserSymbols.Log);
                sbLog10.AppendFormat("<mo>(</mo>{0}<mo>)</mo>", evalSub(token, 0));
                return(sbLog10.ToString());

            case ParserSymbols.Log:
                var sb = new StringBuilder();
                sb.AppendFormat("<msub><mi>{0}</mi>{1}</msub>", ParserSymbols.Log, evalSub(token, 0));
                sb.AppendFormat("<mo>(</mo>{0}<mo>)</mo>", evalSub(token, 1));
                return(sb.ToString());

            case ParserSymbols.Not:
                return($"<mo>&not;</mo>{evalSub(token, 0)}");

            case ParserSymbols.Fact:
                return($"{evalSub(token, 0)}<mo>!</mo>");

            default:
                return(evalFunctionHelper(token));
            }
        }
Exemplo n.º 2
0
        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);
                }
            }
        }
Exemplo n.º 3
0
        public override string EvaluateFunction(FuncToken token)
        {
            string ret = "";

            foreach (TreeToken tok in token.SubTokens)
            {
                ret += tok.Evaluate(this) + " ";
            }
            return(String.Format("{0}{1}", ret, token.Symbol));
        }
Exemplo n.º 4
0
        public override string EvaluateFunction(FuncToken token)
        {
            var sb = new StringBuilder(token.Symbol);

            sb.Append("(");
            sb.Append(String.Join(
                          parser.Tokenizer.ArgumentSeparator.ToString(),
                          token.SubTokens.Select(t => t.Evaluate(this))
                          ));
            sb.Append(")");
            return(sb.ToString());
        }
Exemplo n.º 5
0
        private string evalFunctionHelper(FuncToken token)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("<mi>{0}</mi>", token.Symbol);
            sb.AppendFormat("<mfenced separators=\"{0}\">", parser.Tokenizer.ArgumentSeparator);
            foreach (TreeToken tok in token.SubTokens)
            {
                sb.Append($"<mrow>{tok.Evaluate(this)}</mrow>");
            }
            sb.Append("</mfenced>");
            return(sb.ToString());
        }
Exemplo n.º 6
0
        public override double EvaluateFunction(FuncToken token)
        {
            if (token is CallerFuncToken)
            {
                return(parser.FunctionsDict[token.Symbol].Invoke(EvaluateTokens((token).SubTokens.ToArray())));
            }
            switch (token.Symbol)
            {
            case ParserSymbols.Negate:
                return(eval(token.SubTokens[0]) * -1);

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

            case ParserSymbols.Cbrt:
                return(Math.Pow(eval(token.SubTokens[0]), (double)1 / 3));

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

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

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

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

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

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

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

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

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

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

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

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

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

            case ParserSymbols.Log:
                return(Math.Log(eval(token.SubTokens[1]), eval(token.SubTokens[0])));

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

            case ParserSymbols.Deg:
                return(eval(token.SubTokens[0]) * 180 / 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:
                double v = eval(token.SubTokens[0]);
                if (v < 0 || v % 1 != 0)
                {
                    return(double.NaN);
                }
                double 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);
                }
                return(double.NaN);
            }
        }
Exemplo n.º 7
0
 /// <summary>
 /// Evaluates a given function token.
 /// </summary>
 /// <param name="token">The token to be evaluated.</param>
 /// <returns>The evaluated value.</returns>
 public abstract T EvaluateFunction(FuncToken token);
Exemplo n.º 8
0
        public override Expression EvaluateFunction(FuncToken token)
        {
            if (token is CallerFuncToken)
            {
                Delegate func = parser.FunctionsDict[token.Symbol];
                return(Expression.Invoke(Expression.Constant(func), EvaluateTokens((token).SubTokens.ToArray())));
            }
            switch (token.Symbol)
            {
            case ParserSymbols.Negate:
                return(Expression.Negate(eval(token.SubTokens[0])));

            case ParserSymbols.Sqrt:
                return(Expression.Power(eval(token.SubTokens[0]), Expression.Constant(0.5)));

            case ParserSymbols.Cbrt:
                return(Expression.Power(eval(token.SubTokens[0]), Expression.Constant(1 / 3.0)));

            case ParserSymbols.Exp:
                return(Expression.Power(Expression.Constant(Math.E), eval(token.SubTokens[0])));

            case ParserSymbols.Sin:
                return(makeFuncExpr <OneFunc>(p => Math.Sin(p), eval(token.SubTokens[0])));

            case ParserSymbols.Cos:
                return(makeFuncExpr <OneFunc>(p => Math.Cos(p), eval(token.SubTokens[0])));

            case ParserSymbols.Tan:
                return(makeFuncExpr <OneFunc>(p => Math.Tan(p), eval(token.SubTokens[0])));

            case ParserSymbols.Abs:
                return(makeFuncExpr <OneFunc>(p => Math.Abs(p), eval(token.SubTokens[0])));

            case ParserSymbols.Log10:
                return(makeFuncExpr <OneFunc>(p => Math.Log10(p), eval(token.SubTokens[0])));

            case ParserSymbols.LogE:
                return(makeFuncExpr <OneFunc>(p => Math.Log(p), eval(token.SubTokens[0])));

            case ParserSymbols.ASin:
                return(makeFuncExpr <OneFunc>(p => Math.Asin(p), eval(token.SubTokens[0])));

            case ParserSymbols.ACos:
                return(makeFuncExpr <OneFunc>(p => Math.Acos(p), eval(token.SubTokens[0])));

            case ParserSymbols.ATan:
                return(makeFuncExpr <OneFunc>(p => Math.Atan(p), eval(token.SubTokens[0])));

            case ParserSymbols.Sinh:
                return(makeFuncExpr <OneFunc>(p => Math.Sinh(p), eval(token.SubTokens[0])));

            case ParserSymbols.Cosh:
                return(makeFuncExpr <OneFunc>(p => Math.Cosh(p), eval(token.SubTokens[0])));

            case ParserSymbols.Tanh:
                return(makeFuncExpr <OneFunc>(p => Math.Tanh(p), eval(token.SubTokens[0])));

            case ParserSymbols.Log:
                return(makeFuncExpr <TwoFunc>((p1, p2) => Math.Log(p1, p2), eval(token.SubTokens[1]), eval(token.SubTokens[0])));

            case ParserSymbols.Rad:
                return(makeFuncExpr <OneFunc>(p => p * Math.PI / 180, eval(token.SubTokens[0])));

            case ParserSymbols.Deg:
                return(makeFuncExpr <OneFunc>(p => p * 180 / Math.PI, eval(token.SubTokens[0])));

            case ParserSymbols.Ceil:
                return(makeFuncExpr <OneFunc>(p => Math.Ceiling(p), eval(token.SubTokens[0])));

            case ParserSymbols.Floor:
                return(makeFuncExpr <OneFunc>(p => Math.Floor(p), eval(token.SubTokens[0])));

            case ParserSymbols.Round:
                return(makeFuncExpr <OneFunc>(p => Math.Round(p), eval(token.SubTokens[0])));

            case ParserSymbols.Sign:
                return(makeFuncExpr <OneFunc>(p => Math.Sign(p), eval(token.SubTokens[0])));

            case ParserSymbols.Trunc:
                return(makeFuncExpr <OneFunc>(p => Math.Truncate(p), eval(token.SubTokens[0])));

            case ParserSymbols.Min:
                return(makeFuncExpr <ArrayFunc>(
                           a => a.Min(),
                           Expression.NewArrayInit(typeof(double), EvaluateTokens(token.SubTokens.ToArray()))));

            case ParserSymbols.Max:
                return(makeFuncExpr <ArrayFunc>(
                           a => a.Max(),
                           Expression.NewArrayInit(typeof(double), EvaluateTokens(token.SubTokens.ToArray()))));

            case ParserSymbols.Avg:
                return(makeFuncExpr <ArrayFunc>(
                           a => a.Average(),
                           Expression.NewArrayInit(typeof(double), EvaluateTokens(token.SubTokens.ToArray()))));

            case ParserSymbols.AndFunc:
                return(makeFuncExpr <ArrayFunc>(
                           a => a.Select(v1 => Convert.ToBoolean(v1)).Aggregate((v1, v2) => v1 & v2) ? 1 : 0,
                           Expression.NewArrayInit(typeof(double), EvaluateTokens(token.SubTokens.ToArray()))));

            case ParserSymbols.OrFunc:
                return(makeFuncExpr <ArrayFunc>(
                           a => a.Select(v1 => Convert.ToBoolean(v1)).Aggregate((v1, v2) => v1 | v2) ? 1 : 0,
                           Expression.NewArrayInit(typeof(double), EvaluateTokens(token.SubTokens.ToArray()))));

            case ParserSymbols.XorFunc:
                return(makeFuncExpr <ArrayFunc>(
                           a => a.Select(v1 => Convert.ToBoolean(v1)).Aggregate((v1, v2) => v1 ^ v2) ? 1 : 0,
                           Expression.NewArrayInit(typeof(double), EvaluateTokens(token.SubTokens.ToArray()))));

            case ParserSymbols.Not:
                return(Expression.Not(toBoolExpr(eval(token.SubTokens[0]))));

            case ParserSymbols.Fact:
                return(makeFuncExpr <OneFunc>(p => fact(p), eval(token.SubTokens[0])));

            case ParserSymbols.Cond:
                return(Expression.Condition(toBoolExpr(eval(token.SubTokens[0])),
                                            eval(token.SubTokens[1]),
                                            eval(token.SubTokens[2])));

            default:
                if (Context.Options.StrictMode)
                {
                    throw new UnsupportedOperationException(token.Symbol);
                }
                return(Expression.Constant(double.NaN));
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Reads the arguments given to a function and puts them into a FuncParamToken.
        /// </summary>
        /// <returns>The created FuncParamToken conatining the arguments given to the function.</returns>
        private Token readFuncParams(FuncToken funcToken, InputStream str)
        {
            if (str.AtEnd)
            {
                throw new ParserSyntaxException("Invalid function usage.", funcToken.Position);
            }
            FuncParamToken     paramtok = new FuncParamToken(str.Position);
            LinkedList <Token> subTokenList = new LinkedList <Token>();
            int    open = 0, close = 0;
            bool   withBrackets = false;
            string removeVar = null;

            // Match the index variable if it's a VarFuncToken.
            if (funcToken is VarFuncToken varFuncToken)
            {
                var match = varFuncRegex.Match(str.InputString);
                if (match.Success)
                {
                    withBrackets = true; open++;
                    var varToken = new VarToken(match.Groups[1].ToString(), str.Position);
                    paramtok.ParamList.Add(new LinkedList <Token>(new[] { varToken }));
                    str.MoveForward(match.Length);
                    if (!TokenDict.ContainsKey(varToken.Symbol))
                    {
                        removeVar = varToken.Symbol;
                        TokenDict.Add(removeVar, new Tuple <Type, int>(typeof(VarToken), 0));
                    }
                }
                else
                {
                    throw new ParserSyntaxException("Invalid index variable definition.", str.Position);
                }
            }
            Token tok = funcToken;

            do
            {
                if (str.StartsWith(ArgumentSeparator.ToString()))
                {
                    paramtok.ParamList.Add(subTokenList);
                    subTokenList = new LinkedList <Token>();
                    tok          = funcToken;
                }
                tok = readNextToken(subTokenList, tok, str);
                if (tok is LeftBracketToken)
                {
                    open++;
                    if (!withBrackets)
                    {
                        withBrackets = true; subTokenList.RemoveLast();
                    }
                    ;
                }
                else if (tok is RightBracketToken)
                {
                    close++;
                }
                if (tok is FuncToken func)
                {
                    subTokenList.AddLast(tok = readFuncParams(func, str));
                }
            }while (!str.AtEnd && (open != close));
            if (open != close)
            {
                throw new ParserBracketException("Unequal number of opening and closing brackets.", str.Position);
            }
            paramtok.ParamList.Add(subTokenList);
            if (withBrackets)
            {
                paramtok.ParamList[paramtok.ParamList.Count - 1].RemoveLast();
            }
            if (removeVar != null)
            {
                TokenDict.Remove(removeVar);
            }
            return(paramtok);
        }
Exemplo n.º 10
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);
                }
            }
        }