ExprtkEvaluator.cpp
1 #include "ExprtkEvaluator.h" 2 #include "exprtk.hpp" 3 #include <iomanip> 4 #include <iostream> 5 #include <sstream> 6 #include <cmath> 7 #include <limits> 8 9 namespace ExprtkCalculator::internal 10 { 11 static double factorial(const double n) 12 { 13 // Only allow non-negative integers 14 if (n < 0.0 || std::floor(n) != n) 15 { 16 return std::numeric_limits<double>::quiet_NaN(); 17 } 18 return std::tgamma(n + 1.0); 19 } 20 21 static double sign(const double n) 22 { 23 if (n > 0.0) return 1.0; 24 if (n < 0.0) return -1.0; 25 return 0.0; 26 } 27 28 std::wstring ToWStringFullPrecision(double value) 29 { 30 std::wostringstream oss; 31 oss << std::fixed << std::setprecision(15) << value; 32 return oss.str(); 33 } 34 35 std::wstring EvaluateExpression( 36 const std::string& expressionText, 37 const std::unordered_map<std::string, double>& constants) 38 { 39 exprtk::symbol_table<double> symbol_table; 40 41 for (auto const& [name, value] : constants) 42 { 43 symbol_table.add_constant(name, value); 44 } 45 46 symbol_table.add_function("factorial", factorial); 47 symbol_table.add_function("sign", sign); 48 49 exprtk::expression<double> expression; 50 expression.register_symbol_table(symbol_table); 51 52 exprtk::parser<double> parser; 53 54 // Enable all base functions and arithmetic operators 55 parser.settings().enable_all_base_functions(); // Enable all base functions like sin, cos, log, etc. 56 parser.settings().enable_all_arithmetic_ops(); // Enable all arithmetic operators like +, -, *, /, etc. 57 58 // Disable all control structures and assignment operators to ensure only expressions are evaluated 59 parser.settings().disable_all_control_structures(); // Disable control structures like if, for, while, etc. 60 parser.settings().disable_all_assignment_ops(); // Disable assignment operators like =, +=, -=, etc. 61 62 // Disabled for now, but can be enabled later for enhanced functionality 63 parser.settings().disable_all_logic_ops(); // Disable logical operators like &&, ||, !, etc. 64 parser.settings().disable_all_inequality_ops(); // Disable inequality operators like <, >, <=, >=, !=, etc. 65 66 if (!parser.compile(expressionText, expression)) 67 return L"NaN"; 68 69 return ToWStringFullPrecision(expression.value()); 70 } 71 }