/* inclusion guard */ #ifndef __CALCULATOR_H__ #define __CALCULATOR_H__ #include #include extern double str_to_double (const char * str); extern long str_to_long (const char * str); extern void addVariable (const char * str, const double x); extern void addRange (const char * str, const double x, const double e, const double s); extern void initData (); extern void finiData (); class Expression { public: virtual double eval () = 0; virtual ~Expression () {} }; class Constant : public Expression { double data; public: explicit Constant (const double x) : data (x) {} explicit Constant (const long x) : data (x) {} double eval () override { /*printf("c=%g", data);*/ return data; } virtual ~Constant() {} }; extern void addExpression (Expression * e); enum UNARY_FNCS { UNARY_MINUS = 0, UNARY_SIN, UNARY_COS, UNARY_EXP, UNARY_LOG, UNARY_max }; enum BINARY_FNCS { BINARY_PLUS = 0, BINARY_MINUS, BINARY_MULT, BINARY_DIV, BINARY_POW, BINARY_max }; typedef double (*unary_function) (const double); typedef double (*binary_function) (const double, const double); extern const unary_function unary_function_table [UNARY_max]; extern const binary_function binary_function_table [BINARY_max]; class Unary : public Expression { Expression * m_expr; unary_function m_f; public: explicit Unary (Expression * e, const UNARY_FNCS nf) : m_expr(e), m_f (unary_function_table[nf]) {} double eval () override { /*printf("(*%p)(%p)", m_f, m_expr);*/ return (m_f (m_expr->eval())); } virtual ~Unary () { delete m_expr; } }; class Binary : public Expression { Expression * m_l, * m_r; binary_function m_f; public: explicit Binary (Expression * l, Expression * r, const BINARY_FNCS nf) : m_l(l), m_r(r), m_f(binary_function_table[nf]) {} double eval () override { /*printf("{%p}[%p]{%p}", m_l, m_f, m_r);*/ return (m_f (m_l->eval(), m_r->eval())); } virtual ~Binary() { delete m_l; delete m_r; } }; struct Range { double value, end, step; }; class VariableList { VariableList * next; char * name; Range data; public: explicit VariableList (const char * _name, const double _value) : next(nullptr) { name = strdup (_name); data.value = _value; data.end = _value; data.step = 0.0; } explicit VariableList (const char * _name, const double _value, const double _end, const double steps) : next(nullptr) { name = strdup (_name); if (_value > _end) { data.value = _end; data.end = _value; } else { data.value = _value; data.end = _end; } if (steps != 0.0) data.step = (data.end - data.value) / steps; else data.step = 1.0; } ~VariableList () { if (next) delete next; free (name); } void add (const char * _name, const double _value) { if (!next) next = new VariableList (_name, _value); else next->add (_name, _value); } void add (const char * _name, const double _value, const double _end, const double steps) { if (!next) next = new VariableList (_name, _value, _end, steps); else next->add (_name, _value, _end, steps); } Range * find (const char * _name) { if (!strcmp (name, _name)) return & data; if (next) return next->find (_name); return nullptr; } VariableList * find_ranged () { if (data.step) return this; if (next) return next->find_ranged(); return nullptr; } Range * get () { return & data; } }; class Variable : public Expression { Range * data; public: explicit Variable (const char * name); double eval() override { return data->value; } virtual ~Variable () {} }; struct CommonData { VariableList * list; Expression * root; explicit CommonData() : list(nullptr), root(nullptr) {} ~CommonData () { if (list) delete list; if (root) delete root; } }; #endif /* __CALCULATOR_H__ */