/// <summary>
        /// Adds variable definition to the compiler definitions.
        /// </summary>
        /// <typeparam name="T">The type of variable</typeparam>
        /// <param name="name">The variable name.</param>
        /// <param name="constValue">The constant value.</param>
        public void DefineConstant <T>(string name, T constValue)
        {
            var chars = new StringCharacters(name);

            if (_variables.ContainsKey(chars) || _constants.ContainsKey(chars))
            {
                throw new ArgumentException($"Variable or constant of the specified name '{name}' is already defined.", nameof(name));
            }

            _constants[chars] = constValue;
        }
        /// <summary>
        /// Adds variable definition to the compiler definitions.
        /// </summary>
        /// <typeparam name="T">The type of variable</typeparam>
        /// <param name="name">The variable name.</param>
        /// <param name="func">The function to evaluate variable value.</param>
        public void DefineVariable <T>(string name, Func <T> func)
        {
            var chars = new StringCharacters(name);

            if (_variables.ContainsKey(chars) || _constants.ContainsKey(chars))
            {
                throw new ArgumentException($"Variable or constant of the specified name '{name}' is already defined.", nameof(name));
            }

            _variables[chars] = (() => func.Invoke());
        }
        /// <summary>
        /// Adds the function definition to the compiler definitions.
        /// </summary>
        /// <param name="name">The function name.</param>
        /// <param name="function">The function delegate that evaluates the function value.</param>
        /// <param name="paramsCount">The number of function parameters.</param>
        public void DefineFunction(string name, Func <object[], object> function, int paramsCount)
        {
            var c = new StringCharacters(name);

            if (!_functionsByNameByArgCount.TryGetValue(c, out var funByArgCount))
            {
                funByArgCount = new Dictionary <int, Func <object[], object> >();
                _functionsByNameByArgCount[c] = funByArgCount;
            }
            else
            {
                if (funByArgCount.ContainsKey(paramsCount))
                {
                    throw new ArgumentException($"Function '{name}'({paramsCount} params) is already defined.", nameof(name));
                }
            }

            funByArgCount[paramsCount] = function;
        }