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); } } }
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); } } }