18#define BOOST_SPIRIT_QI_DEBUG
21#define _USE_MATH_DEFINES
24#include <boost/fusion/include/adapt_struct.hpp>
25#include <boost/fusion/include/io.hpp>
26#include <boost/phoenix.hpp>
27#include <boost/phoenix/object.hpp>
28#include <boost/spirit/include/qi.hpp>
39namespace qi = boost::spirit::qi;
40namespace ascii = boost::spirit::ascii;
41namespace phx = boost::phoenix;
48 virtual double Eval()
const
53 virtual double Eval(
const std::unordered_map<std::string, double> &variables)
const
70 return std::make_shared<Expr>(t);
99 double Eval()
const override
104 double Eval(
const std::unordered_map<std::string, double> &variables)
const override
131 Variable(
const std::string &value =
"") : value(value)
146 double Eval(
const std::unordered_map<std::string, double> &variables)
const override
148 auto it = variables.find(value);
149 if (it != variables.end())
152 throw std::invalid_argument(
"Variable not found: " + value);
185 template <
typename L,
typename R>
BinaryOperator(
char op,
const L &left,
const R &right) : op(op), left(
Clone(left)), right(
Clone(right))
194 return left->Eval() + right->Eval();
196 return left->Eval() - right->Eval();
198 return left->Eval() * right->Eval();
200 return left->Eval() / right->Eval();
202 return pow(left->Eval(), right->Eval());
204 return static_cast<double>(AsInteger(left->Eval()) ^ AsInteger(right->Eval()));
206 throw std::invalid_argument(
"Unknown binary operator");
212 double Eval(
const std::unordered_map<std::string, double> &variables)
const override
217 return left->Eval(variables) + right->Eval(variables);
219 return left->Eval(variables) - right->Eval(variables);
221 return left->Eval(variables) * right->Eval(variables);
223 return left->Eval(variables) / right->Eval(variables);
225 return pow(left->Eval(variables), right->Eval(variables));
227 return static_cast<double>(AsInteger(left->Eval(variables)) ^ AsInteger(right->Eval(variables)));
229 throw std::invalid_argument(
"Unknown binary operator");
241 static long long AsInteger(
double value)
243 if (!std::isfinite(value))
244 throw std::invalid_argument(
"Bitwise XOR ('^') requires finite integer operands, got: " + std::to_string(value));
246 const double rounded = std::round(value);
248 if (std::abs(value - rounded) > 1e-9)
249 throw std::invalid_argument(
"Bitwise XOR ('^') requires integer operands, got: " + std::to_string(value));
253 if (std::abs(rounded) > 4.5e15)
254 throw std::invalid_argument(
"Bitwise XOR ('^') operand is out of the supported integer range: " + std::to_string(value));
256 return static_cast<long long>(rounded);
265 template <
typename,
typename,
typename>
struct result
294 return right->Eval();
296 return -right->Eval();
298 throw std::invalid_argument(
"Unknown unary operator");
304 double Eval(
const std::unordered_map<std::string, double> &variables)
const override
309 return right->Eval(variables);
311 return -right->Eval(variables);
313 throw std::invalid_argument(
"Unknown unary operator");
325 template <
typename,
typename>
struct result
341 template <
typename F>
Function(
const std::string &func,
const F ¶m) : func(func), param(
Clone(param))
348 return sin(param->Eval());
349 else if (func ==
"cos")
350 return cos(param->Eval());
351 else if (func ==
"tan")
352 return tan(param->Eval());
353 else if (func ==
"exp")
354 return exp(param->Eval());
355 else if (func ==
"ln")
356 return log(param->Eval());
357 else if (func ==
"sqrt")
358 return sqrt(param->Eval());
360 throw std::invalid_argument(
"Unknown function");
365 double Eval(
const std::unordered_map<std::string, double> &variables)
const override
368 return sin(param->Eval(variables));
369 else if (func ==
"cos")
370 return cos(param->Eval(variables));
371 else if (func ==
"tan")
372 return tan(param->Eval(variables));
373 else if (func ==
"exp")
374 return exp(param->Eval(variables));
375 else if (func ==
"ln")
376 return log(param->Eval(variables));
377 else if (func ==
"sqrt")
378 return sqrt(param->Eval(variables));
380 throw std::invalid_argument(
"Unknown function");
392 template <
typename,
typename,
typename>
struct result
397 template <
typename Params>
Function operator()(
const std::string &funcName,
const Params ¶ms)
const
425 double Eval(
const std::unordered_map<std::string, double> &variables)
const override
427 return expr->Eval(variables);
AbstractSyntaxTree(AbstractSyntaxTree &&)=default
AbstractSyntaxTree(const AbstractSyntaxTree &)=default
AbstractSyntaxTree()=default
virtual ~AbstractSyntaxTree()=default
virtual double Eval(const std::unordered_map< std::string, double > &variables) const
virtual double Eval() const
AbstractSyntaxTree & operator=(const AbstractSyntaxTree &)=default
AbstractSyntaxTree & operator=(AbstractSyntaxTree &&)=default
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
BinaryOperator(char op, const L &left, const R &right)
double Eval() const override
Constant & operator=(int value)
Constant & operator=(double value)
double Eval(const std::unordered_map< std::string, double > &variables) const override
friend AbstractSyntaxTreePtr Clone(Expression const &e)
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
Function(const std::string &func, const F ¶m)
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
UnaryOperator(char op, const R &right)
double Eval() const override
double Eval(const std::unordered_map< std::string, double > &variables) const override
Variable & operator=(int value)
double Eval() const override
Variable(const std::string &value="")
double Eval(const std::unordered_map< std::string, double > &variables) const override
phx::function< MakeFunctionExpression > MakeFunction
phx::function< MakeUnaryExpression > MakeUnary
phx::function< MakeBinaryExpression > MakeBinary
static AbstractSyntaxTreePtr Clone(Expr const &t)
std::shared_ptr< AbstractSyntaxTree > AbstractSyntaxTreePtr
phx::function< MakeVariableExpression > MakeVariable
phx::function< MakeConstantExpression > MakeConstant
BinaryOperator operator()(C op, const L &lhs, const R &rhs) const
Constant operator()(C op) const
Function operator()(const std::string &funcName, const Params ¶ms) const
UnaryOperator operator()(C op, const R &rhs) const
Variable operator()(V v) const