code format
This commit is contained in:
@@ -5,120 +5,208 @@
|
||||
* \~russian Вычислитель математических выражений
|
||||
*/
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream calculations
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Evaluator designed for stream calculations
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIEVALUATOR_H
|
||||
#define PIEVALUATOR_H
|
||||
|
||||
#include "pistringlist.h"
|
||||
#include "pimathcomplex.h"
|
||||
#include "pistringlist.h"
|
||||
|
||||
|
||||
namespace PIEvaluatorTypes {
|
||||
|
||||
typedef std::function<complexd(void * , int, complexd * )> FuncHanlder;
|
||||
typedef std::function<complexd(void *, int, complexd *)> FuncHanlder;
|
||||
|
||||
enum eType {etNumber, etOperator, etVariable, etFunction};
|
||||
enum Operation {oNone, oAdd, oSubtract, oMultiply, oDivide, oResidue, oPower,
|
||||
oEqual, oNotEqual, oGreater, oSmaller, oGreaterEqual, oSmallerEqual,
|
||||
oAnd, oOr, oFunction
|
||||
};
|
||||
enum BaseFunctions {bfUnknown, bfSin, bfCos, bfTg, bfCtg,
|
||||
bfArcsin, bfArccos, bfArctg, bfArcctg,
|
||||
bfExp, bfRandom, bfRandomn,
|
||||
bfSh, bfCh, bfTh, bfCth,
|
||||
bfSqrt, bfSqr, bfPow, bfAbs,
|
||||
bfLn, bfLg, bfLog, bfSign,
|
||||
bfIm, bfRe, bfArg, bfLen, bfConj,
|
||||
bfRad, bfDeg, bfJ0, bfJ1, bfJN,
|
||||
bfY0, bfY1, bfYN, bfMin, bfMax,
|
||||
bfClamp, bfStep, bfMix, bfDefined,
|
||||
bfRound,
|
||||
bfCustom = 0xFFFF
|
||||
};
|
||||
enum eType {
|
||||
etNumber,
|
||||
etOperator,
|
||||
etVariable,
|
||||
etFunction
|
||||
};
|
||||
enum Operation {
|
||||
oNone,
|
||||
oAdd,
|
||||
oSubtract,
|
||||
oMultiply,
|
||||
oDivide,
|
||||
oResidue,
|
||||
oPower,
|
||||
oEqual,
|
||||
oNotEqual,
|
||||
oGreater,
|
||||
oSmaller,
|
||||
oGreaterEqual,
|
||||
oSmallerEqual,
|
||||
oAnd,
|
||||
oOr,
|
||||
oFunction
|
||||
};
|
||||
enum BaseFunctions {
|
||||
bfUnknown,
|
||||
bfSin,
|
||||
bfCos,
|
||||
bfTg,
|
||||
bfCtg,
|
||||
bfArcsin,
|
||||
bfArccos,
|
||||
bfArctg,
|
||||
bfArcctg,
|
||||
bfExp,
|
||||
bfRandom,
|
||||
bfRandomn,
|
||||
bfSh,
|
||||
bfCh,
|
||||
bfTh,
|
||||
bfCth,
|
||||
bfSqrt,
|
||||
bfSqr,
|
||||
bfPow,
|
||||
bfAbs,
|
||||
bfLn,
|
||||
bfLg,
|
||||
bfLog,
|
||||
bfSign,
|
||||
bfIm,
|
||||
bfRe,
|
||||
bfArg,
|
||||
bfLen,
|
||||
bfConj,
|
||||
bfRad,
|
||||
bfDeg,
|
||||
bfJ0,
|
||||
bfJ1,
|
||||
bfJN,
|
||||
bfY0,
|
||||
bfY1,
|
||||
bfYN,
|
||||
bfMin,
|
||||
bfMax,
|
||||
bfClamp,
|
||||
bfStep,
|
||||
bfMix,
|
||||
bfDefined,
|
||||
bfRound,
|
||||
bfCustom = 0xFFFF
|
||||
};
|
||||
|
||||
struct PIP_EXPORT Instruction {
|
||||
Instruction() {out = -1; function = -1; operation = oNone;}
|
||||
Instruction(Operation oper, PIVector<short> opers, short out_ind, short func = -1) {
|
||||
operation = oper; operators = opers; out = out_ind; function = func;}
|
||||
Operation operation;
|
||||
short out;
|
||||
short function;
|
||||
PIVector<short> operators;
|
||||
};
|
||||
struct PIP_EXPORT Element {
|
||||
Element() {num = 0; var_num = -1; type = etNumber;}
|
||||
Element(eType new_type, short new_num, short new_var_num = -1) {set(new_type, new_num, new_var_num);}
|
||||
void set(eType new_type, short new_num, short new_var_num = -1) {type = new_type; num = new_num; var_num = new_var_num;}
|
||||
eType type;
|
||||
short num;
|
||||
short var_num;
|
||||
};
|
||||
struct PIP_EXPORT Function {
|
||||
Function() {arguments = 0; type = bfUnknown; handler = nullptr;}
|
||||
Function(const PIString & name, short args, BaseFunctions ftype) {identifier = name; arguments = args; type = ftype; handler = nullptr;}
|
||||
Function(const PIString & name, short args, FuncHanlder h) {identifier = name; arguments = args; type = bfCustom; handler = h;}
|
||||
PIString identifier;
|
||||
BaseFunctions type;
|
||||
FuncHanlder handler;
|
||||
short arguments;
|
||||
};
|
||||
struct PIP_EXPORT Variable {
|
||||
Variable() {value = 0.;}
|
||||
Variable(const PIString & var_name, complexd val) {name = var_name; value = val;}
|
||||
PIString name;
|
||||
complexd value;
|
||||
};
|
||||
}
|
||||
struct PIP_EXPORT Instruction {
|
||||
Instruction() {
|
||||
out = -1;
|
||||
function = -1;
|
||||
operation = oNone;
|
||||
}
|
||||
Instruction(Operation oper, PIVector<short> opers, short out_ind, short func = -1) {
|
||||
operation = oper;
|
||||
operators = opers;
|
||||
out = out_ind;
|
||||
function = func;
|
||||
}
|
||||
Operation operation;
|
||||
short out;
|
||||
short function;
|
||||
PIVector<short> operators;
|
||||
};
|
||||
struct PIP_EXPORT Element {
|
||||
Element() {
|
||||
num = 0;
|
||||
var_num = -1;
|
||||
type = etNumber;
|
||||
}
|
||||
Element(eType new_type, short new_num, short new_var_num = -1) { set(new_type, new_num, new_var_num); }
|
||||
void set(eType new_type, short new_num, short new_var_num = -1) {
|
||||
type = new_type;
|
||||
num = new_num;
|
||||
var_num = new_var_num;
|
||||
}
|
||||
eType type;
|
||||
short num;
|
||||
short var_num;
|
||||
};
|
||||
struct PIP_EXPORT Function {
|
||||
Function() {
|
||||
arguments = 0;
|
||||
type = bfUnknown;
|
||||
handler = nullptr;
|
||||
}
|
||||
Function(const PIString & name, short args, BaseFunctions ftype) {
|
||||
identifier = name;
|
||||
arguments = args;
|
||||
type = ftype;
|
||||
handler = nullptr;
|
||||
}
|
||||
Function(const PIString & name, short args, FuncHanlder h) {
|
||||
identifier = name;
|
||||
arguments = args;
|
||||
type = bfCustom;
|
||||
handler = h;
|
||||
}
|
||||
PIString identifier;
|
||||
BaseFunctions type;
|
||||
FuncHanlder handler;
|
||||
short arguments;
|
||||
};
|
||||
struct PIP_EXPORT Variable {
|
||||
Variable() { value = 0.; }
|
||||
Variable(const PIString & var_name, complexd val) {
|
||||
name = var_name;
|
||||
value = val;
|
||||
}
|
||||
PIString name;
|
||||
complexd value;
|
||||
};
|
||||
} // namespace PIEvaluatorTypes
|
||||
/*
|
||||
≠ :
|
||||
≥ }
|
||||
≤ {
|
||||
⋀ &
|
||||
⋁ |
|
||||
≠ :
|
||||
≥ }
|
||||
≤ {
|
||||
⋀ &
|
||||
⋁ |
|
||||
*/
|
||||
|
||||
class PIP_EXPORT PIEvaluatorContent
|
||||
{
|
||||
class PIP_EXPORT PIEvaluatorContent {
|
||||
friend class PIEvaluator;
|
||||
BINARY_STREAM_FRIEND(PIEvaluatorContent);
|
||||
|
||||
public:
|
||||
PIEvaluatorContent();
|
||||
~PIEvaluatorContent() {;}
|
||||
~PIEvaluatorContent() { ; }
|
||||
|
||||
void addFunction(const PIString & name, int args = 1);
|
||||
int addVariable(const PIString & name, const complexd & val = 0.);
|
||||
int addVariable(const PIString & name, const complexd & val = 0.);
|
||||
void addCustomFunction(const PIString & name, int args_count, PIEvaluatorTypes::FuncHanlder func);
|
||||
int functionsCount() const {return functions.size();}
|
||||
int variablesCount() const {return variables.size();}
|
||||
int functionsCount() const { return functions.size(); }
|
||||
int variablesCount() const { return variables.size(); }
|
||||
int customVariablesCount() const;
|
||||
int findFunction(const PIString & name) const;
|
||||
int findVariable(const PIString & var_name) const;
|
||||
PIEvaluatorTypes::Function function(int index);
|
||||
PIEvaluatorTypes::Variable variable(int index);
|
||||
PIEvaluatorTypes::Function function(const PIString & name) {return function(findFunction(name));}
|
||||
PIEvaluatorTypes::Variable variable(const PIString & name) {return variable(findVariable(name));}
|
||||
PIEvaluatorTypes::Function function(const PIString & name) { return function(findFunction(name)); }
|
||||
PIEvaluatorTypes::Variable variable(const PIString & name) { return variable(findVariable(name)); }
|
||||
PIEvaluatorTypes::Variable customVariable(int index);
|
||||
bool setVariableValue(int index, complexd new_value);
|
||||
bool setVariableValue(const PIString & var_name, const complexd & new_value) {return setVariableValue(findVariable(var_name), new_value);}
|
||||
bool setVariableValue(const PIString & var_name, const complexd & new_value) {
|
||||
return setVariableValue(findVariable(var_name), new_value);
|
||||
}
|
||||
bool setVariableName(int index, const PIString & new_name);
|
||||
bool setVariableName(const PIString & var_name, const PIString & new_name) {return setVariableName(findVariable(var_name), new_name);}
|
||||
bool setVariableName(const PIString & var_name, const PIString & new_name) { return setVariableName(findVariable(var_name), new_name); }
|
||||
void clearCustomVariables();
|
||||
PIEvaluatorTypes::BaseFunctions getBaseFunction(const PIString & name);
|
||||
|
||||
@@ -128,32 +216,32 @@ private:
|
||||
PIVector<PIEvaluatorTypes::Function> functions;
|
||||
PIVector<PIEvaluatorTypes::Variable> variables;
|
||||
int cv_count;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PIP_EXPORT PIEvaluator
|
||||
{
|
||||
class PIP_EXPORT PIEvaluator {
|
||||
public:
|
||||
|
||||
//! Constructs an empty evaluator
|
||||
PIEvaluator() {correct = false; data_ = 0;}
|
||||
PIEvaluator() {
|
||||
correct = false;
|
||||
data_ = 0;
|
||||
}
|
||||
|
||||
~PIEvaluator() {;}
|
||||
~PIEvaluator() { ; }
|
||||
|
||||
|
||||
//! Returns custom data
|
||||
void * data() {return data_;}
|
||||
void * data() { return data_; }
|
||||
|
||||
//! Set custom data to "_data"
|
||||
void setData(void * _data) {data_ = _data;}
|
||||
void setData(void * _data) { data_ = _data; }
|
||||
|
||||
|
||||
//! Check mathematical expression and parse it to list of instructions
|
||||
bool check(const PIString & string);
|
||||
|
||||
//! Returns true if expression was checked succesfully
|
||||
bool isCorrect() const {return correct;}
|
||||
bool isCorrect() const { return correct; }
|
||||
|
||||
//! Set variable value with name "name" to value "value". Add variable if it doesn`t exists
|
||||
int setVariable(const PIString & name, complexd value = complexd(0.));
|
||||
@@ -165,25 +253,25 @@ public:
|
||||
complexd evaluate();
|
||||
|
||||
//! Remove all manually added variables
|
||||
void clearCustomVariables() {content.clearCustomVariables();}
|
||||
void clearCustomVariables() { content.clearCustomVariables(); }
|
||||
|
||||
//! Returns index of variable with name "name"
|
||||
int variableIndex(const PIString & name) const {return content.findVariable(name);}
|
||||
int variableIndex(const PIString & name) const { return content.findVariable(name); }
|
||||
|
||||
//! Returns all unknown variables founded in last expression passed to \a check() function
|
||||
const PIStringList & unknownVariables() const {return unknownVars;}
|
||||
const PIStringList & unknownVariables() const { return unknownVars; }
|
||||
|
||||
//! Returns all used variables founded in last expression passed to \a check() function
|
||||
const PIStringList & usedVariables() const {return usedVars;}
|
||||
const PIStringList & usedVariables() const { return usedVars; }
|
||||
|
||||
//! Returns processed last expression passed to \a check() function
|
||||
const PIString & expression() const {return currentString;}
|
||||
const PIString & expression() const { return currentString; }
|
||||
|
||||
//! Returns last error description occured in \a check() function
|
||||
const PIString & error() const {return lastError;}
|
||||
const PIString & error() const { return lastError; }
|
||||
|
||||
//! Returns last result of \a evaluate()
|
||||
const complexd & lastResult() const {return out;}
|
||||
const complexd & lastResult() const { return out; }
|
||||
|
||||
//! Save to %PIByteArray evaluator state (expression, variables, errors, compiled instructions)
|
||||
PIByteArray save() const;
|
||||
@@ -205,13 +293,24 @@ private:
|
||||
bool fillElements();
|
||||
bool setSignes();
|
||||
bool isSign(const PIChar & ch);
|
||||
PIString inverse(const PIString & string) {int len = string.length(); PIString s; for (int i = 0; i < len; i++) s += string[len - i - 1]; return s;}
|
||||
PIString inverse(const PIString & string) {
|
||||
int len = string.length();
|
||||
PIString s;
|
||||
for (int i = 0; i < len; i++)
|
||||
s += string[len - i - 1];
|
||||
return s;
|
||||
}
|
||||
bool check();
|
||||
bool execInstructions();
|
||||
PIString inBrackets(const PIString & string);
|
||||
PIString operationChar(const PIEvaluatorTypes::Operation & operation);
|
||||
void operationsByPriority(int p, PIVector<PIEvaluatorTypes::Operation> & ret);
|
||||
complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return content.variables[index].value;}
|
||||
complexd value(const int & index) {
|
||||
if (index < 0)
|
||||
return tmpvars[-index - 1].value;
|
||||
else
|
||||
return content.variables[index].value;
|
||||
}
|
||||
inline complexd residue(const complexd & f, const complexd & s);
|
||||
inline void execFunction(const PIEvaluatorTypes::Instruction & ci);
|
||||
|
||||
@@ -226,19 +325,47 @@ private:
|
||||
void * data_;
|
||||
};
|
||||
|
||||
inline bool operator ==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type == e2.type && e1.num == e2.num);}
|
||||
inline bool operator !=(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {return (e1.type != e2.type || e1.num != e2.num);}
|
||||
inline bool operator==(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {
|
||||
return (e1.type == e2.type && e1.num == e2.num);
|
||||
}
|
||||
inline bool operator!=(PIEvaluatorTypes::Element e1, PIEvaluatorTypes::Element e2) {
|
||||
return (e1.type != e2.type || e1.num != e2.num);
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Instruction) {s << PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) << v.operators; return s;}
|
||||
BINARY_STREAM_READ (PIEvaluatorTypes::Instruction) {s >> PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) >> v.operators; return s;}
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Instruction) {
|
||||
s << PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) << v.operators;
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIEvaluatorTypes::Instruction) {
|
||||
s >> PIMemoryBlock(&v, sizeof(v) - sizeof(v.operators)) >> v.operators;
|
||||
return s;
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Element) {s << createMemoryBlock(&v); return s;}
|
||||
BINARY_STREAM_READ (PIEvaluatorTypes::Element) {s >> createMemoryBlock(&v); return s;}
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Element) {
|
||||
s << createMemoryBlock(&v);
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIEvaluatorTypes::Element) {
|
||||
s >> createMemoryBlock(&v);
|
||||
return s;
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Variable) {s << v.name << v.value; return s;}
|
||||
BINARY_STREAM_READ (PIEvaluatorTypes::Variable) {s >> v.name >> v.value; return s;}
|
||||
BINARY_STREAM_WRITE(PIEvaluatorTypes::Variable) {
|
||||
s << v.name << v.value;
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIEvaluatorTypes::Variable) {
|
||||
s >> v.name >> v.value;
|
||||
return s;
|
||||
}
|
||||
|
||||
BINARY_STREAM_WRITE(PIEvaluatorContent) {s << v.variables << v.cv_count; return s;}
|
||||
BINARY_STREAM_READ (PIEvaluatorContent) {s >> v.variables >> v.cv_count; return s;}
|
||||
BINARY_STREAM_WRITE(PIEvaluatorContent) {
|
||||
s << v.variables << v.cv_count;
|
||||
return s;
|
||||
}
|
||||
BINARY_STREAM_READ(PIEvaluatorContent) {
|
||||
s >> v.variables >> v.cv_count;
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // PIEVALUATOR_H
|
||||
|
||||
Reference in New Issue
Block a user