121 lines
3.9 KiB
C++
121 lines
3.9 KiB
C++
/* inclusion guard */
|
|
#ifndef __CALCULATOR_H__
|
|
#define __CALCULATOR_H__
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
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__ */
|