Beispiel #1
0
        private static bool GetSprite(FunctionArgs p_args)
        {
            if (p_args.Parameters.Length != 1)
            {
                errorMessage = "Invalid number of parameters in GetSprite function.";
                return(false);
            }

            object[] evalParams = p_args.EvaluateParameters();

            if (typeof(Transform).IsAssignableFrom(evalParams[0].GetType()))
            {
                Transform transform = (Transform)evalParams[0];
                Image     image     = transform.GetComponent <Image>();

                if (image != null)
                {
                    p_args.HasResult = true;
                    p_args.Result    = image.sprite;
                    return(true);
                }
                else
                {
                    errorMessage = "Transform has no Image component in GetSprite function.";
                    return(false);
                }
            }

            errorMessage = "Invalid parameters in GetImage function.";
            return(false);
        }
Beispiel #2
0
        public object Invoke(FunctionArgs args)
        {
            if (args.Arguments.Length == 0)
            {
                return(null);
            }

            var result = args.Arguments[0].Evaluate(args.Query, args.ContextNode);

            if (result == null)
            {
                return(0);
            }

            var item = result as QueryContext;

            if (item != null)
            {
                return(1);
            }

            var items = result as QueryContext[];

            if (items != null)
            {
                return(items.Length);
            }

            return(1);
        }
Beispiel #3
0
        // /**
        //  *  Get parent of a transform
        //  */
        // private static bool GetParent(FunctionArgs p_args)
        // {
        //     if (p_args.Parameters.Length != 1)
        //     {
        //         errorMessage = "Invalid parameters in GetParent function.";
        //         return false;
        //     }
        //
        //     object[] evalParams = p_args.EvaluateParameters();
        //
        //     if (typeof(Transform).IsAssignableFrom(evalParams[0].GetType()))
        //     {
        //         p_args.HasResult = true;
        //         p_args.Result = ((Transform) evalParams[0]).parent;
        //         return true;
        //     }
        //
        //     errorMessage = "Invalid parameters in GetParent function.";
        //     return false;
        // }

        /**
         *  Get child of transform at index
         */
        private static bool GetChildAt(FunctionArgs p_args)
        {
            if (p_args.Parameters.Length != 2)
            {
                errorMessage = "Invalid number of parameters in GetChild function.";
                return(false);
            }

            object[] evalParams = p_args.EvaluateParameters();

            if (typeof(Transform).IsAssignableFrom(evalParams[0].GetType()) && evalParams[1].GetType() == typeof(int))
            {
                Transform transform  = (Transform)evalParams[0];
                int       childIndex = (int)evalParams[1];
                if (transform != null && transform.childCount > childIndex)
                {
                    p_args.HasResult = true;
                    p_args.Result    = transform.GetChild(childIndex);
                    return(true);
                }
                else
                {
                    errorMessage = "Invalid transform or child index in GetChildAt function.";
                    return(false);
                }
            }

            errorMessage = "Invalid parameters in GetChildAt function.";
            return(false);
        }
 private void SetPrefixes(FunctionArgs functionArgs, Scripts.Interfaces.IScript script)
 {
     foreach (var par in script.Parameters.Where(p => (p.Context & SIP.ParameterOptions.Calculation) != 0))
     {
         functionArgs.Parameters.First().Parameters.Add($"{_prefix}{par.Name}", par.Value);
     }
 }
        public override object Evaluate(FunctionArgs args)
        {
            if (args.Arguments.Length != 1)
            {
                throw new XPathException("Too many or to few arguments in number()");
            }

            var a0 = args.Arguments[0].Evaluate(args.XPathExpression, args.Context);

            var s = a0 as string;

            if (s != null)
            {
                int i;

                if (!int.TryParse(s, out i))
                {
                    throw new XPathException("Integer expression expected in number()");
                }

                a0 = i;
            }

            if (!(a0 is int))
            {
                throw new XPathException("Integer expression expected in number()");
            }

            return (int)a0;
        }
        private object CalculateScriptFromDatabase(FunctionArgs e)
        {
            if (_scriptRepository != null && _parameterRepository != null)
            {
                var scriptData = _scriptRepository.GetScriptBaseOnNameAsync(_scriptName).Result;
                if (scriptData != null)
                {
                    return(CalculateScript(scriptData, e, _parameterRepository));
                }
            }
            else
            {
                using (var scriptInterpreterDbContext = new ScriptInterpreterDbContext(new DbContextOptions <ScriptInterpreterDbContext>()))
                {
                    var scriptRepository = _scriptRepository ?? new ScriptRepository(scriptInterpreterDbContext);
                    var scriptData       = scriptRepository.GetScriptBaseOnNameAsync(_scriptName).Result;
                    if (scriptData != null)
                    {
                        var parameterRepository = _parameterRepository ?? new ParameterRepository(scriptInterpreterDbContext);
                        return(CalculateScript(scriptData, e, parameterRepository));
                    }
                }
            }

            throw new ArgumentException("No script with name " + _scriptName);
        }
Beispiel #7
0
        private static bool GetCanvas(FunctionArgs p_args)
        {
            if (p_args.Parameters.Length != 1)
            {
                errorMessage = "Invalid number of parameters in GetSprite function.";
                return(false);
            }

            object[] evalParams = p_args.EvaluateParameters();

            if (typeof(Transform).IsAssignableFrom(evalParams[0].GetType()))
            {
                Transform transform = (Transform)evalParams[0];
                Canvas    canvas    = transform.GetComponentInParent <Canvas>();

                if (canvas != null)
                {
                    p_args.HasResult = true;
                    p_args.Result    = canvas;
                    return(true);
                }
                else
                {
                    errorMessage = "Transform or its parents has no Canvas component in GetCanvas function.";
                    return(false);
                }
            }

            errorMessage = "Invalid parameters in GetCanvas function.";
            return(false);
        }
Beispiel #8
0
        /**
         *  Add two values of type T together
         */
        private static bool Add(FunctionArgs p_args)
        {
            if (p_args.Parameters.Length != 2)
            {
                errorMessage = "Invalid parameters in Add function.";
                return(false);
            }

            object[] evalParams = p_args.EvaluateParameters();

            if (evalParams[0].GetType() == typeof(Vector2) && evalParams[1].GetType() == typeof(Vector2))
            {
                p_args.HasResult = true;
                p_args.Result    = (Vector2)evalParams[0] + (Vector2)evalParams[1];
                return(true);
            }

            if (evalParams[0].GetType() == typeof(Vector3) && evalParams[1].GetType() == typeof(Vector3))
            {
                p_args.HasResult = true;
                p_args.Result    = (Vector3)evalParams[0] + (Vector3)evalParams[1];
                return(true);
            }

            errorMessage = "Add function not implemented for parameters " + evalParams[0].GetType() + " and " +
                           evalParams[1].GetType();
            return(false);
        }
        private object CalculateService(FunctionArgs functionArgs)
        {
            IList <object> arguments = new List <object>();

            for (int i = 1; i < functionArgs.Parameters.Length; i++)
            {
                try
                {
                    if (functionArgs.Parameters[i].Evaluate() == null)
                    {
                        arguments.RemoveAt(arguments.Count - 1);
                    }
                    else
                    {
                        arguments.Add(functionArgs.Parameters[i].Evaluate());
                    }
                }
                catch (ArgumentException)
                {
                    arguments.RemoveAt(arguments.Count - 1);
                }
            }

            Calculator.Map(arguments);
            return(SetParameters(Calculator.Calculate(), functionArgs));
        }
Beispiel #10
0
        void json_parse(LanguageInterpreter sender, FunctionArgs args)
        {
            if (EUtils.CheckArgs(1, args))
            {
                object param = args.EvaluateParameters()[0];

                if (EUtils.CheckArgType(param, typeof(string)))
                {
                    string json_str = (string)param;

                    dynamic parsed_json = DynamicJson.Parse(json_str);

                    if (parsed_json.IsArray)
                    {
                        AnonymousVariableArray finalArray = VariableArrayFromDynamic(parsed_json);

                        args.HasResult = true;
                        args.Result    = finalArray;
                    }
                    else
                    {
                        sender.Interpreter.HandleException(new Exception(sender.Interpreter.CurrentFile, sender.Interpreter.CurrentLine, "Unimplemented", "Only arrays are implemented in the JSON parser.", ""));
                    }
                }
                else
                {
                    sender.Interpreter.HandleException(new Exception(sender.Interpreter.CurrentFile, sender.Interpreter.CurrentLine, "Invalid parameter type.", "Function expects parameter of type 'String', got '" + param.GetType().Name + "'.", ""));
                }
            }
            else
            {
                sender.Interpreter.HandleException(Consts.Exceptions.ParameterCountMismatch(sender.Interpreter.CurrentFile, sender.Interpreter.CurrentLine, 1));
            }
        }
Beispiel #11
0
 private void OnEvaluateFunction(string name, FunctionArgs args)
 {
     if (EvaluateFunction != null)
     {
         EvaluateFunction(name, args);
     }
 }
Beispiel #12
0
        /**
         * Scaling function for vector types, standard by components or by a scalar value
         */
        private static bool Scale(FunctionArgs p_args)
        {
            if (p_args.Parameters.Length != 2)
            {
                errorMessage = "Invalid parameters in Scale function.";
                return(false);
            }

            object[] evalParams = p_args.EvaluateParameters();

            if (evalParams[0].GetType() == typeof(Vector2))
            {
                if (evalParams[1].GetType() == typeof(int) || evalParams[1].GetType() == typeof(float) ||
                    evalParams[1].GetType() == typeof(double))
                {
                    p_args.HasResult = true;
                    p_args.Result    = (Vector2)evalParams[0] * Convert.ToSingle(evalParams[1]);
                    return(true);
                }

                if (evalParams[1].GetType() == typeof(Vector2))
                {
                    p_args.HasResult = true;
                    Vector2 v2 = (Vector2)evalParams[0];
                    v2.Scale((Vector2)evalParams[1]);
                    p_args.Result = v2;

                    return(true);
                }

                errorMessage = "Invalid second parameter in Scale function.";
                return(true);
            }

            if (evalParams[0].GetType() == typeof(Vector3))
            {
                if (evalParams[1].GetType() == typeof(int) || evalParams[1].GetType() == typeof(float) ||
                    evalParams[1].GetType() == typeof(double))
                {
                    p_args.HasResult = true;
                    p_args.Result    = (Vector3)evalParams[0] * Convert.ToSingle(evalParams[1]);
                    return(true);
                }

                if (evalParams[1].GetType() == typeof(Vector3))
                {
                    p_args.HasResult = true;
                    Vector3 v3 = (Vector3)evalParams[0];
                    v3.Scale((Vector3)evalParams[1]);
                    p_args.Result = v3;
                    return(true);
                }

                errorMessage = "Invalid second parameter of type " + evalParams[1].GetType() + " for Scale function.";
                return(false);
            }

            errorMessage = "Scale function for types " + evalParams[0].GetType() + ", " + evalParams[1].GetType() + " is not implemented.";
            return(false);
        }
Beispiel #13
0
        /**
         * Normalize Vector type
         */
        private static bool Normalize(FunctionArgs p_args)
        {
            if (p_args.Parameters.Length != 1)
            {
                errorMessage = "Invalid parameters in Normalize function.";
                return(false);
            }

            object[] evalParams = p_args.EvaluateParameters();

            Type paramType = evalParams[0].GetType();

            if (paramType == typeof(Vector2))
            {
                p_args.HasResult = true;
                p_args.Result    = ((Vector2)evalParams[0]).normalized;
                return(true);
            }

            if (paramType == typeof(Vector3))
            {
                p_args.HasResult = true;
                p_args.Result    = ((Vector3)evalParams[0]).normalized;
                return(true);
            }

            errorMessage = "Normalize function for type " + paramType + " is not implemented";
            return(false);
        }
Beispiel #14
0
        private static bool RandomInsideCircle(FunctionArgs p_args)
        {
            if (p_args.Parameters.Length != 0 && p_args.Parameters.Length != 1 && p_args.Parameters.Length != 2)
            {
                errorMessage = "Invalid parameters in RandomInsideCircle function";
                return(false);
            }

            object[] evalParams = p_args.EvaluateParameters();

            switch (evalParams.Length)
            {
            case 0:
                p_args.HasResult = true;
                p_args.Result    = UnityEngine.Random.insideUnitCircle;
                return(true);

            case 2:
                // TODO type checking?

                p_args.HasResult = true;
                p_args.Result    = UnityEngine.Random.insideUnitCircle * Convert.ToSingle(evalParams[0]);
                return(true);

            case 4:
                p_args.HasResult = true;
                var vector = UnityEngine.Random.insideUnitCircle;
                vector.Scale(new Vector2(Convert.ToSingle(evalParams[0]), Convert.ToSingle(evalParams[1])));
                p_args.Result = vector;
                return(true);
            }

            errorMessage = "Unknown error in function RandomInsideCircle";
            return(false);
        }
        protected bool HandleLfoFunc(FunctionArgs args, List <double> evaluatedArgs)
        {
            if (evaluatedArgs.Count != 6)
            {
                return(false);
            }

            double       input  = evaluatedArgs[0];
            double       attack = evaluatedArgs[1];
            WaveformShap shape  = (WaveformShap)evaluatedArgs[2];
            double       phase  = evaluatedArgs[3];
            double       cycles = evaluatedArgs[4];
            double       amount = evaluatedArgs[5];

            if (attack < 0 || attack > 1)
            {
                return(false);
            }

            if (Enum.IsDefined(typeof(WaveformShap), shape) == false)
            {
                return(false);
            }

            //input
            double output = input;

            //cycles
            output *= cycles;

            //phase
            output += phase % 360 / 360.0;

            //shape
            HandleWaveformFunc(output, shape, out output);

            output -= 0.5;

            //attack
            double attackAtInput;

            if (attack == 0)
            {
                attackAtInput = 1;
            }
            else
            {
                attackAtInput = Math.Min(1, input / attack);
            }
            output *= attackAtInput;

            //amount
            output *= amount;

            output += 0.5;

            args.Result = output;
            return(true);
        }
Beispiel #16
0
        /**
         *  Multiply two values of type T together
         */
        private static bool Mul(FunctionArgs p_args)
        {
            if (p_args.Parameters.Length != 2)
            {
                errorMessage = "Invalid parameters in Mul function.";
                return(false);
            }

            object[] evalParams = p_args.EvaluateParameters();

            if (evalParams[0].GetType() == typeof(Vector2) && evalParams[1].GetType() == typeof(float))
            {
                p_args.HasResult = true;
                p_args.Result    = (Vector2)evalParams[0] * (float)evalParams[1];
                return(true);
            }

            if (evalParams[0].GetType() == typeof(float) && evalParams[1].GetType() == typeof(Vector2))
            {
                p_args.HasResult = true;
                p_args.Result    = (float)evalParams[0] * (Vector2)evalParams[1];
                return(true);
            }

            if (evalParams[0].GetType() == typeof(Vector2) && evalParams[1].GetType() == typeof(Vector2))
            {
                p_args.HasResult = true;
                p_args.Result    = (Vector2)evalParams[0] * (Vector2)evalParams[1];
                return(true);
            }

            if (evalParams[0].GetType() == typeof(Vector3) && evalParams[1].GetType() == typeof(float))
            {
                p_args.HasResult = true;
                p_args.Result    = (Vector3)evalParams[0] * (float)evalParams[1];
                return(true);
            }

            if (evalParams[0].GetType() == typeof(float) && evalParams[1].GetType() == typeof(Vector3))
            {
                p_args.HasResult = true;
                p_args.Result    = (float)evalParams[0] * (Vector3)evalParams[1];
                return(true);
            }

            if (evalParams[0].GetType() == typeof(Vector3) && evalParams[1].GetType() == typeof(Vector3))
            {
                p_args.HasResult = true;
                Vector3 scaled = (Vector3)evalParams[0];
                scaled.Scale((Vector3)evalParams[1]);
                p_args.Result = scaled;
                return(true);
            }

            errorMessage = "Mul function not implemented for parameters " + evalParams[0].GetType() + " and " +
                           evalParams[1].GetType();
            return(false);
        }
        private object SetParameters(IResult result, FunctionArgs functionArgs)
        {
            foreach (var property in result.Properties)
            {
                functionArgs.Parameters.First().Parameters.Add($"{_prefix}{property.Key}", property.Value);
            }

            return(true);
        }
 /// <summary>
 /// NCalc custom function evaluator
 /// </summary>
 /// <param name="name">name of the function to be evaluated</param>
 /// <param name="args">FunctionArgs object from where the function arguments will be read and the function evaluation result will be stored</param>
 private void EvaluateFunction(string name, FunctionArgs args)
 {
     if (name == "defined")
     {
         //it is here assumed that defined always takes one argument and is of type identifier
         Identifier identifier = (Identifier)args.Parameters[0].ParsedExpression;
         args.Result = _definesHandler.IsDefined(identifier.Name);
     }
 }
Beispiel #19
0
        private void OnExpOnEvaluateFunction(string name, FunctionArgs args)
        {
            var customExpr = _expressionTable?.Get(name);

            if (customExpr?.ExpressionFunction != null)
            {
                args.Result = customExpr.ExpressionFunction.Invoke(args);
            }
        }
        private IDictionary <string, object> GetParametersValues(FunctionArgs functionArgs)
        {
            IDictionary <string, object> parameterValues = new Dictionary <string, object>();

            for (int i = 1; i < functionArgs.Parameters.Length; i += 2)
            {
                parameterValues.Add(functionArgs.Parameters[i].Evaluate().ToString(), functionArgs.Parameters[i + 1].Evaluate());
            }
            return(parameterValues);
        }
Beispiel #21
0
        private void EvaluateFunctionGetStaticMember(ElementRuntime elementRuntime, FunctionArgs args, CodeContext codeContext)
        {
            string argument = (string)args.Parameters[0].ParsedExpression.ToString();

            string value = (string)mExpressionParser.EvaluateExpression(argument, codeContext);

            ReferencedFileSave rfs = elementRuntime.AssociatedIElement.GetReferencedFileSaveByInstanceNameRecursively(value);

            args.Result = elementRuntime.LoadReferencedFileSave(rfs, true, elementRuntime.AssociatedIElement);
        }
            private void Expr_EvaluateFunction(string name, FunctionArgs args)
            {
                var method = CustomEvaluatorFunctions.FirstOrDefault(m => m.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
                var result = method?.Invoke(null, new object[] { Context, uow, args });

                if (result != null)
                {
                    args.Result = result;
                }
            }
Beispiel #23
0
        protected void OnEvaluateFunction(string name, FunctionArgs args)
        {
            if (name.ToLower() == "contains")
            {
                string v1 = args.Parameters[0].Evaluate().ToString().ToLower();
                string v2 = args.Parameters[1].Evaluate().ToString().ToLower();

                args.Result = v1.Contains(v2);
            }
        }
Beispiel #24
0
        public static object InMilliseconds(FunctionArgs args)
        {
            TimeSpan input = (TimeSpan)args.Parameters[0].Evaluate();

            if (input != null)
            {
                return(input.TotalMilliseconds);
            }

            return(0);
        }
Beispiel #25
0
        /// <summary>
        /// How long since a given time
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public static object UtcAge(FunctionArgs args)
        {
            DateTime input = (DateTime)args.Parameters[0].Evaluate();

            if (input != null)
            {
                return(DateTime.UtcNow - input);
            }

            return(TimeSpan.Zero);
        }
Beispiel #26
0
        public object Invoke(FunctionArgs args)
        {
            var item = args.ContextNode.GetQueryContextItem();

            if (item == null)
            {
                return(null);
            }

            return(item.Language.ToString());
        }
Beispiel #27
0
        public static object URLSpam(FunctionArgs args)
        {
            string input = Convert.ToString(args.Parameters[0].Evaluate());

            if (!(input is null))
            {
                return(r_URLSpam.Match(input).Success);
            }

            return(false);
        }
Beispiel #28
0
 private bool OnValidateFunction(string name, FunctionArgs args)
 {
     if (ValidateFunction != null)
     {
         return(ValidateFunction(name, args));
     }
     else
     {
         return(false);
     }
 }
Beispiel #29
0
 private static void FunctionExtensions(string name, FunctionArgs args)
 {
     if (name.Equals("ClassLevel", StringComparison.OrdinalIgnoreCase))
     {
         args.Result = int.MaxValue;
     }
     if (name.Equals("SubClass", StringComparison.OrdinalIgnoreCase))
     {
         args.Result = "";
     }
 }
Beispiel #30
0
 public static bool CheckArgs(int requiredAmount, FunctionArgs args)
 {
     if (args.Parameters.Length > requiredAmount || args.Parameters.Length < requiredAmount)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
Beispiel #31
0
        public static object GetFileName(FunctionArgs args)
        {
            string input = Convert.ToString(args.Parameters[0].Evaluate());

            if (!(input is null))
            {
                return(Path.GetFileName(input));
            }

            return(null);
        }
        public override object Evaluate(FunctionArgs args)
        {
            if (args.Arguments.Length != 1)
            {
                throw new XPathException("Too many or to few arguments in not()");
            }

            var a0 = args.Arguments[0].Evaluate(args.XPathExpression, args.Context);

            if (!(a0 is bool))
            {
                throw new XPathException("Boolean expression expected in not()");
            }

            return !(bool)a0;
        }
Beispiel #33
0
 private void OnEvaluateFunction(string name, FunctionArgs args)
 {
     if (EvaluateFunction != null)
         EvaluateFunction(name, args);
 }
Beispiel #34
0
        public override void Visit(Function function)
        {
            var args = new FunctionArgs
                           {
                               Parameters = new Expression[function.Expressions.Length]
                           };

            // Don't call parameters right now, instead let the function do it as needed.
            // Some parameters shouldn't be called, for instance, in a if(), the "not" value might be a division by zero
            // Evaluating every value could produce unexpected behaviour
            for (int i = 0; i < function.Expressions.Length; i++ )
            {
                args.Parameters[i] =  new Expression(function.Expressions[i], _options);
                args.Parameters[i].EvaluateFunction += EvaluateFunction;
                args.Parameters[i].EvaluateParameter += EvaluateParameter;

                // Assign the parameters of the Expression to the arguments so that custom Functions and Parameters can use them
                args.Parameters[i].Parameters = Parameters;
            }

            switch (function.Identifier.Name.ToLower())
            {
                case "count":
                case "cnt":
                    var pcnt = Evaluate(function.Expressions[0]) as IList;
                    if (pcnt == null) throw new Exception("Cannot sum because the first parameter is not a list");
                    Result = pcnt.OfType<object>().Select(Convert.ToInt32).ToArray().Count();
                    break;
                case "low":
                    var min = Evaluate(function.Expressions[0]) as IList;
                    if (min == null) throw new Exception("Cannot sum because the first parameter is not a list");
                    Result = min.OfType<object>().Select(Convert.ToInt32).ToArray().Min();
                    break;
                case "high":
                    var max = Evaluate(function.Expressions[0]) as IList;
                    if (max == null) throw new Exception("Cannot sum because the first parameter is not a list");
                    Result = max.OfType<object>().Select(Convert.ToInt32).ToArray().Max();
                    break;
                case "average":
                case "avg":
                    var pAvg = Evaluate(function.Expressions[0]) as IList;
                    if (pAvg == null) throw new Exception("Cannot sum because the first parameter is not a list");
                    Result = pAvg.OfType<object>().Select(Convert.ToInt32).ToArray().Average();
                    break;
                case "sum":
                    var p1 = Evaluate(function.Expressions[0]) as IList;
                    if (p1 == null) throw new Exception("Cannot sum because the first parameter is not a list");
                    Result = p1.OfType<object>().Select(Convert.ToInt32).ToArray().Sum();
                    break;
                case "addmonths":
                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("addMonths() takes exactly 2 arguments");
                        Result = Convert.ToDateTime(Evaluate(function.Expressions[0])).AddMonths(Convert.ToInt32(Evaluate(function.Expressions[1]))).ToString("MM/dd/yyyy");
                        break;
                case "addyears":
                        if (function.Expressions.Length != 2)
                            throw new ArgumentException("addYears() takes exactly 2 arguments");
                        Result = Convert.ToDateTime(Evaluate(function.Expressions[0])).AddYears(Convert.ToInt32(Evaluate(function.Expressions[1]))).ToString("MM/dd/yyyy");
                        break;
                case "adddays":
                        if (function.Expressions.Length != 2)
                            throw new ArgumentException("addDays() takes exactly 2 arguments");
                        Result = Convert.ToDateTime(Evaluate(function.Expressions[0])).AddDays(Convert.ToInt32(Evaluate(function.Expressions[1]))).ToString("MM/dd/yyyy");
                        break;
                case "contains":
                        if (function.Expressions.Length != 2)
                            throw new ArgumentException("contains() takes exactly 2 arguments");
                    Result =
                        Evaluate(function.Expressions[0]).ToString().Contains(
                            Evaluate(function.Expressions[1]).ToString());
                        break;
                #region Abs
                case "abs":

                    CheckCase("Abs", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Abs() takes exactly 1 argument");

                    Result = Math.Abs(Convert.ToDecimal(
                        Evaluate(function.Expressions[0]))
                        );

                    break;

                #endregion

                #region Acos
                case "acos":

                    CheckCase("Acos", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Acos() takes exactly 1 argument");

                    Result = Math.Acos(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Asin
                case "asin":

                    CheckCase("Asin", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Asin() takes exactly 1 argument");

                    Result = Math.Asin(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Atan
                case "atan":

                    CheckCase("Atan", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Atan() takes exactly 1 argument");

                    Result = Math.Atan(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Ceiling
                case "ceiling":

                    CheckCase("Ceiling", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Ceiling() takes exactly 1 argument");

                    Result = Math.Ceiling(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Cos

                case "cos":

                    CheckCase("Cos", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Cos() takes exactly 1 argument");

                    Result = Math.Cos(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Exp
                case "exp":

                    CheckCase("Exp", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Exp() takes exactly 1 argument");

                    Result = Math.Exp(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Floor
                case "floor":

                    CheckCase("Floor", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Floor() takes exactly 1 argument");

                    Result = Math.Floor(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region IEEERemainder
                case "ieeeremainder":

                    CheckCase("IEEERemainder", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("IEEERemainder() takes exactly 2 arguments");

                    Result = Math.IEEERemainder(Convert.ToDouble(Evaluate(function.Expressions[0])), Convert.ToDouble(Evaluate(function.Expressions[1])));

                    break;

                #endregion

                #region Log
                case "log":

                    CheckCase("Log", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("Log() takes exactly 2 arguments");

                    Result = Math.Log(Convert.ToDouble(Evaluate(function.Expressions[0])), Convert.ToDouble(Evaluate(function.Expressions[1])));

                    break;

                #endregion

                #region Log10
                case "log10":

                    CheckCase("Log10", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Log10() takes exactly 1 argument");

                    Result = Math.Log10(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Pow
                case "pow":

                    CheckCase("Pow", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("Pow() takes exactly 2 arguments");

                    Result = Math.Pow(Convert.ToDouble(Evaluate(function.Expressions[0])), Convert.ToDouble(Evaluate(function.Expressions[1])));

                    break;

                #endregion

                #region Round
                case "round":

                    CheckCase("Round", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("Round() takes exactly 2 arguments");

                    MidpointRounding rounding = (_options & EvaluateOptions.RoundAwayFromZero) == EvaluateOptions.RoundAwayFromZero ? MidpointRounding.AwayFromZero : MidpointRounding.ToEven;

                    Result = Math.Round(Convert.ToDouble(Evaluate(function.Expressions[0])), Convert.ToInt16(Evaluate(function.Expressions[1])), rounding);

                    break;

                #endregion

                #region Sign
                case "sign":

                    CheckCase("Sign", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Sign() takes exactly 1 argument");

                    Result = Math.Sign(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Sin
                case "sin":

                    CheckCase("Sin", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Sin() takes exactly 1 argument");

                    Result = Math.Sin(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Sqrt
                case "sqrt":

                    CheckCase("Sqrt", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Sqrt() takes exactly 1 argument");

                    Result = Math.Sqrt(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Tan
                case "tan":

                    CheckCase("Tan", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Tan() takes exactly 1 argument");

                    Result = Math.Tan(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Truncate
                case "truncate":

                    CheckCase("Truncate", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Truncate() takes exactly 1 argument");

                    Result = Math.Truncate(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Max
                case "max":

                    CheckCase("Max", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("Max() takes exactly 2 arguments");

                    object maxleft = Evaluate(function.Expressions[0]);
                    object maxright = Evaluate(function.Expressions[1]);

                    Result = Numbers.Max(maxleft, maxright);
                    break;

                #endregion

                #region Min
                case "min":

                    CheckCase("Min", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("Min() takes exactly 2 arguments");

                    object minleft = Evaluate(function.Expressions[0]);
                    object minright = Evaluate(function.Expressions[1]);

                    Result = Numbers.Min(minleft, minright);
                    break;

                #endregion

                #region if
                case "if":

                    CheckCase("if", function.Identifier.Name);

                    if (function.Expressions.Length != 3)
                        throw new ArgumentException("if() takes exactly 3 arguments");

                    bool cond = Convert.ToBoolean(Evaluate(function.Expressions[0]));

                    Result = cond ? Evaluate(function.Expressions[1]) : Evaluate(function.Expressions[2]);
                    break;

                #endregion

                #region in
                case "in":

                    CheckCase("in", function.Identifier.Name);

                    if (function.Expressions.Length < 2)
                        throw new ArgumentException("in() takes at least 2 arguments");

                    object parameter = Evaluate(function.Expressions[0]);

                    bool evaluation = false;

                    // Goes through any values, and stop whe one is found
                    for (int i = 1; i < function.Expressions.Length; i++)
                    {
                        object argument = Evaluate(function.Expressions[i]);
                        if (CompareUsingMostPreciseType(parameter, argument) == 0)
                        {
                            evaluation = true;
                            break;
                        }
                    }

                    Result = evaluation;
                    break;

                #endregion

                default:
                    // Calls external implementation
                    OnEvaluateFunction(IgnoreCase ? function.Identifier.Name.ToLower() : function.Identifier.Name, args);

                    // If an external implementation was found get the result back
                    if (args.HasResult)
                    {
                        Result = args.Result;
                        return;
                    }

                    throw new ArgumentException("Function not found",
                        function.Identifier.Name);
            }
        }
        public override void Visit(Function function)
        {
            var args = new FunctionArgs
                           {
                               Parameters = new Expression[function.Expressions.Length]
                           };

            // Don't call parameters right now, instead let the function do it as needed.
            // Some parameters shouldn't be called, for instance, in a if(), the "not" value might be a division by zero
            // Evaluating every value could produce unexpected behaviour
            for (int i = 0; i < function.Expressions.Length; i++ )
            {
                args.Parameters[i] =  new Expression(function.Expressions[i], _options);
                args.Parameters[i].EvaluateFunction += EvaluateFunction;
                args.Parameters[i].EvaluateParameter += EvaluateParameter;

                // Assign the parameters of the Expression to the arguments so that custom Functions and Parameters can use them
                args.Parameters[i].Parameters = Parameters;
            }

            // Calls external implementation
            OnEvaluateFunction(IgnoreCase ? function.Identifier.Name.ToLower() : function.Identifier.Name, args);

            // If an external implementation was found get the result back
            if (args.HasResult)
            {
                Result = args.Result;
                return;
            }

            switch (function.Identifier.Name.ToLower())
            {
                #region Abs
                case "abs":

                    //CheckCase("abs", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("abs() takes exactly 1 argument");

                    Result = Math.Abs(Convert.ToDecimal(
                        Evaluate(function.Expressions[0]))
                        );

                    break;

                #endregion

                #region Acos
                case "acos":

                    //CheckCase("acos", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("acos() takes exactly 1 argument");

                    Result = Math.Acos(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Asin
                case "asin":

                    //CheckCase("asin", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("asin() takes exactly 1 argument");

                    Result = Math.Asin(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Atan
                case "atan":

                    //CheckCase("atan", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Atan() takes exactly 1 argument");

                    Result = Math.Atan(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Ceiling
                case "ceil":

                    //CheckCase("ceil", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("ceil() takes exactly 1 argument");

                    Result = Math.Ceiling(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Cos

                case "cos":

                    //CheckCase("cos", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("cos() takes exactly 1 argument");

                    Result = Math.Cos(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Exp
                case "exp":

                    //CheckCase("exp", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("exp() takes exactly 1 argument");

                    Result = Math.Exp(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Floor
                case "floor":

                    //CheckCase("floor", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("floor() takes exactly 1 argument");

                    Result = Math.Floor(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region IEEERemainder
                case "ieeeremainder":

                    //CheckCase("ieeeRemainder", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("ieeeRemainder() takes exactly 2 arguments");

                    Result = Math.IEEERemainder(Convert.ToDouble(Evaluate(function.Expressions[0])), Convert.ToDouble(Evaluate(function.Expressions[1])));

                    break;

                #endregion

                #region Log
                case "log":

                    //CheckCase("log", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("log() takes exactly 2 arguments");

                    Result = Math.Log(Convert.ToDouble(Evaluate(function.Expressions[0])), Convert.ToDouble(Evaluate(function.Expressions[1])));

                    break;

                #endregion

                #region Log10
                case "log10":

                    //CheckCase("log10", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("Log10() takes exactly 1 argument");

                    Result = Math.Log10(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Pow
                case "pow":

                    //CheckCase("pow", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("pow() takes exactly 2 arguments");

                    Result = Math.Pow(Convert.ToDouble(Evaluate(function.Expressions[0])), Convert.ToDouble(Evaluate(function.Expressions[1])));

                    break;

                #endregion

                #region Round
                case "round":

                    //CheckCase("round", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("round() takes exactly 2 arguments");

                    MidpointRounding rounding = (_options & EvaluateOptions.RoundAwayFromZero) == EvaluateOptions.RoundAwayFromZero ? MidpointRounding.AwayFromZero : MidpointRounding.ToEven;

                    Result = Math.Round(Convert.ToDouble(Evaluate(function.Expressions[0])), Convert.ToInt16(Evaluate(function.Expressions[1])), rounding);

                    break;

                #endregion

                #region Sign
                case "sgn":

                    //CheckCase("sgn", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("sgn() takes exactly 1 argument");

                    Result = Math.Sign(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Sin
                case "sin":

                    //CheckCase("sin", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("sin() takes exactly 1 argument");

                    Result = Math.Sin(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Sqrt
                case "sqrt":

                    //CheckCase("sqrt", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("sqrt() takes exactly 1 argument");

                    Result = Math.Sqrt(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region root
                case "root":

                    //CheckCase("root", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("root() takes exactly 1 argument");

                    Result = Math.Sqrt(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Tan
                case "tan":

                    //CheckCase("tan", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("tan() takes exactly 1 argument");

                    Result = Math.Tan(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region truncate
                case "truncate":

                    //CheckCase("truncate", function.Identifier.Name);

                    if (function.Expressions.Length != 1)
                        throw new ArgumentException("truncate() takes exactly 1 argument");

                    Result = Math.Truncate(Convert.ToDouble(Evaluate(function.Expressions[0])));

                    break;

                #endregion

                #region Max
                case "max":

                    //CheckCase("max", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("max() takes exactly 2 arguments");

                    object maxleft = Evaluate(function.Expressions[0]);
                    object maxright = Evaluate(function.Expressions[1]);

                    Result = Numbers.Max(maxleft, maxright);
                    break;

                #endregion

                #region Min
                case "min":

                    //CheckCase("min", function.Identifier.Name);

                    if (function.Expressions.Length != 2)
                        throw new ArgumentException("min() takes exactly 2 arguments");

                    object minleft = Evaluate(function.Expressions[0]);
                    object minright = Evaluate(function.Expressions[1]);

                    Result = Numbers.Min(minleft, minright);
                    break;

                #endregion

                default:
                    throw new ArgumentException("Function not found",
                        function.Identifier.Name);
            }
        }