#ifndef _MATH_EXPRESSION_H_ #define _MATH_EXPRESSION_H_ /****************************************************************************************************************** * Arithmetic operation expression * * support function: "random","floor", "abs", "sqrt", "sin", "cos", "tan", "atan", "log", "exp", "atan2", "pow" * * function can be customized,for exmple: * double len2(double a, double b) { * return sqrt(a*a + b*b); * } * MathExpression::AddFunction("len2", len2); * * exp: std::map vars; * vars["x"] = 100; * vars["y"] = 200; * MathExpression e("(sqrt(x)>y)&&(x>y)", vars); * double ret = e.Evaluator(); * * MathExpression expr1 = MathExpression::Parse("x>y", vars); * std::cout<<"expr1:"< #include #include #include #include #include #include class MathExpression { public: struct Error : std::runtime_error { int position; Error(const std::string& msg, int position = -1) : std::runtime_error(msg), position(position) {} }; //evaluation expression double Evaluator() const; //parse expression static MathExpression Parse(const char *expstr, std::map& vars); MathExpression(double x = 0.0) { m_resreg = 0; m_wrk.push_back(x); } void Swap(MathExpression& other) { std::swap(m_resreg, other.m_resreg); m_code.swap(other.m_code); m_wrk.swap(other.m_wrk); m_variables.swap(other.m_variables); } //structure evaluation expression MathExpression(const char *expstr, std::map& m) { MathExpression e = Parse(expstr, m); Swap(e); } //add custom function static void AddFunction(const char *name, double (*f)()) { m_func0.push_back(f); mp_functions[name] = std::make_pair(m_func0.size()-1, 0); } //add custom function static void AddFunction(const char *name, double (*f)(double)) { m_func1.push_back(f); mp_functions[name] = std::make_pair(m_func1.size()-1, 1); } //add custom function static void AddFunction(const char *name, double (*f)(double, double)) { m_func2.push_back(f); mp_functions[name] = std::make_pair(m_func2.size()-1, 2); } //evaluation expression disassemble std::string Disassemble() const; private: //skip space static void SkipSP(const char *& expstr); static MathExpression PartialParse(const char *& expstr, std::map& vars); int Compile(std::vector& regs,const char *& expstr, std::map& vars, int level); private: enum { MOVE, LOAD, NEG, NOT, ADD, SUB, MUL, DIV, LT, LE, GT, GE, EQ, NE, AND, OR, B_SHL, B_SHR, B_AND, B_OR, B_XOR, FSIN, FCOS, FFLOOR, FABS, FSQRT, FTAN, FATAN, FLOG, FEXP, FATAN2, FPOW, FUNC0, FUNC1, FUNC2 }; int m_resreg; std::vector m_code; mutable std::vector m_wrk; std::vector m_variables; struct Operator { const char *name; int level; int opcode; }; static std::map mp_operators; static int m_max_level; static std::map > mp_inlined; static std::map > mp_functions; static std::vector m_func0; static std::vector m_func1; static std::vector m_func2; class Init; friend class Init; enum { READONLY = 0x4000000 }; int reg(std::vector& regs) { if (regs.size() == 0) { m_wrk.resize(1 + m_wrk.size()); regs.push_back(m_wrk.size()-1); } int r = regs.back(); regs.pop_back(); return r; } }; #endif