Esempio n. 1
0
        /// <summary>
        /// Build a .NET func for the provided formula.
        /// </summary>
        /// <param name="formulaText">The formula that must be converted into a .NET func.</param>
        /// <param name="constants">Constant values for variables defined into the formula. They variables will be replaced by the constant value at pre-compilation time.</param>
        /// <returns>A .NET func for the provided formula.</returns>
        public Func <IDictionary <string, double>, double> Build(string formulaText, IDictionary <string, double> constants)
        {
            if (string.IsNullOrEmpty(formulaText))
            {
                throw new ArgumentNullException("formulaText");
            }


            ConstantRegistry compiledConstants = new ConstantRegistry(caseSensitive);

            if (constants != null)
            {
                foreach (var constant in constants)
                {
                    compiledConstants.RegisterConstant(constant.Key, constant.Value);
                }
            }

            if (IsInFormulaCache(formulaText, compiledConstants, out var result))
            {
                return(result);
            }
            else
            {
                Operation operation = BuildAbstractSyntaxTree(formulaText, compiledConstants);
                return(BuildFormula(formulaText, compiledConstants, operation));
            }
        }
Esempio n. 2
0
        public void TestOverwritable()
        {
            ConstantRegistry registry = new ConstantRegistry(false);

            registry.RegisterConstant("test", 42.0);
            registry.RegisterConstant("test", 26.3);
        }
Esempio n. 3
0
        public void TestNotOverwritable()
        {
            ConstantRegistry registry = new ConstantRegistry(false);

            registry.RegisterConstant("test", 42.0, false);

            AssertExtensions.ThrowsException <Exception>(() =>
            {
                registry.RegisterConstant("test", 26.3, false);
            });
        }
Esempio n. 4
0
        public void TestAddConstant()
        {
            ConstantRegistry registry = new ConstantRegistry(false);

            registry.RegisterConstant("test", 42.0);

            ConstantInfo functionInfo = registry.GetConstantInfo("test");

            Assert.IsNotNull(functionInfo);
            Assert.AreEqual("test", functionInfo.ConstantName);
            Assert.AreEqual(42.0, functionInfo.Value);
        }
Esempio n. 5
0
        /// <summary>
        /// Verify a collection of variables to ensure that all the variable names are valid.
        /// Users are not allowed to overwrite reserved variables or use function names as variables.
        /// If an invalid variable is detected an exception is thrown.
        /// </summary>
        /// <param name="variables">The colletion of variables that must be verified.</param>
        internal void VerifyVariableNames(IDictionary <string, ExecutionResult> variables)
        {
            foreach (string variableName in variables.Keys)
            {
                if (ConstantRegistry.IsConstantName(variableName) && !ConstantRegistry.GetConstantInfo(variableName).IsOverWritable)
                {
                    throw new ArgumentException(string.Format("The name \"{0}\" is a reservered variable name that cannot be overwritten.", variableName), "variables");
                }

                if (FunctionRegistry.IsFunctionName(variableName))
                {
                    throw new ArgumentException(string.Format("The name \"{0}\" is a function name. Parameters cannot have this name.", variableName), "variables");
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Build the abstract syntax tree for a given formula. The formula string will
        /// be first tokenized.
        /// </summary>
        /// <param name="formulaText">A string containing the mathematical formula that must be converted
        /// into an abstract syntax tree.</param>
        /// <returns>The abstract syntax tree of the formula.</returns>
        private Operation BuildAbstractSyntaxTree(string formulaText, ConstantRegistry compiledConstants)
        {
            TokenReader  tokenReader = new TokenReader(cultureInfo);
            List <Token> tokens      = tokenReader.Read(formulaText);

            AstBuilder astBuilder = new AstBuilder(FunctionRegistry, caseSensitive, compiledConstants);
            Operation  operation  = astBuilder.Build(tokens);

            if (optimizerEnabled)
            {
                return(optimizer.Optimize(operation, this.FunctionRegistry, this.ConstantRegistry));
            }
            else
            {
                return(operation);
            }
        }
Esempio n. 7
0
 private void RegisterDefaultConstants()
 {
     ConstantRegistry.RegisterConstant("e", Math.E, false);
     ConstantRegistry.RegisterConstant("pi", Math.PI, false);
 }
Esempio n. 8
0
 /// <summary>
 /// Removes a constant in the calculation engine.
 /// </summary>
 /// <param name="constantName">The name of the constant.</param>
 /// <param name="force">Can remove by force?(remove even nonWritable items)</param>
 public void RemoveConstant(string constantName, bool force = false)
 {
     ConstantRegistry.UnregisterConstant(constantName, force);
 }
Esempio n. 9
0
 /// <summary>
 /// Add a constant to the calculation engine.
 /// </summary>
 /// <param name="constantName">The name of the constant. This name can be used in mathematical formulas.</param>
 /// <param name="value">The value of the constant.</param>
 public void AddConstant(string constantName, ExecutionResult value)
 {
     ConstantRegistry.RegisterConstant(constantName, value);
 }
Esempio n. 10
0
 private string GenerateFormulaCacheKey(string formulaText, ConstantRegistry compiledConstants)
 {
     return((compiledConstants != null && compiledConstants.Any()) ? $"{formulaText}@{String.Join(",", compiledConstants?.Select(x => $"{x.ConstantName}:{x.Value}"))}" : formulaText);
 }
Esempio n. 11
0
 private bool IsInFormulaCache(string formulaText, ConstantRegistry compiledConstants, out Func <IDictionary <string, double>, double> function)
 {
     function = null;
     return(cacheEnabled && executionFormulaCache.TryGetValue(GenerateFormulaCacheKey(formulaText, compiledConstants), out function));
 }
Esempio n. 12
0
 private Func <IDictionary <string, double>, double> BuildFormula(string formulaText, ConstantRegistry compiledConstants, Operation operation)
 {
     return(executionFormulaCache.GetOrAdd(GenerateFormulaCacheKey(formulaText, compiledConstants), v => executor.BuildFormula(operation, this.FunctionRegistry, this.ConstantRegistry)));
 }
Esempio n. 13
0
 /// <summary>
 /// Add a constant to the calculation engine.
 /// </summary>
 /// <param name="constantName">The name of the constant. This name can be used in mathematical formulas.</param>
 /// <param name="value">The value of the constant.</param>
 public void AddConstant(string constantName, double value)
 {
     ConstantRegistry.RegisterConstant(constantName, value);
 }