Calculator/calculator.h

122 lines
3.9 KiB
C
Raw Normal View History

2023-11-26 15:56:00 +01:00
/* 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__ */