29.07.2011 - fundamental new
This commit is contained in:
148
pievaluator.h
Normal file
148
pievaluator.h
Normal file
@@ -0,0 +1,148 @@
|
||||
#ifndef PIEVALUATOR_H
|
||||
#define PIEVALUATOR_H
|
||||
|
||||
#include "pistring.h"
|
||||
#include "pimath.h"
|
||||
|
||||
namespace PIEvaluatorTypes {
|
||||
static const int operationCount = 14;
|
||||
|
||||
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, bfSh, bfCh, bfTh, bfCth,
|
||||
bfSqrt, bfSqr, bfPow, bfAbs,
|
||||
bfLn, bfLg, bfLog, bfSign,
|
||||
bfIm, bfRe, bfArg, bfLen, bfConj,
|
||||
bfRad, bfDeg};
|
||||
|
||||
struct Instruction {
|
||||
Instruction() {;}
|
||||
Instruction(Operation oper, PIVector<int> opers, int out_ind, int func = -1) {
|
||||
operation = oper; operators = opers; out = out_ind; function = func;}
|
||||
Operation operation;
|
||||
PIVector<int> operators;
|
||||
int out;
|
||||
int function;};
|
||||
struct Element {
|
||||
Element() {;}
|
||||
Element(eType new_type, int new_num, int new_var_num = -1) {set(new_type, new_num, new_var_num);}
|
||||
void set(eType new_type, int new_num, int new_var_num = -1) {type = new_type; num = new_num; var_num = new_var_num;}
|
||||
eType type;
|
||||
int num;
|
||||
int var_num;};
|
||||
struct Function {
|
||||
Function() {arguments = 0; type = bfUnknown;}
|
||||
Function(const PIString & name, int args, BaseFunctions ftype) {identifier = name; arguments = args; type = ftype;}
|
||||
PIString identifier;
|
||||
BaseFunctions type;
|
||||
int arguments;};
|
||||
struct Variable {
|
||||
Variable() {value = 0.;}
|
||||
Variable(const PIString & var_name, complexd val) {name = var_name; value = val;}
|
||||
PIString name;
|
||||
complexd value;};
|
||||
};
|
||||
/*
|
||||
≠ :
|
||||
≥ }
|
||||
≤ {
|
||||
⋀ &
|
||||
⋁ |
|
||||
*/
|
||||
class PIEvaluatorContent
|
||||
{
|
||||
friend class PIEvaluator;
|
||||
public:
|
||||
PIEvaluatorContent();
|
||||
~PIEvaluatorContent() {;}
|
||||
|
||||
inline void addFunction(const PIString & name, int args = 1) {functions.push_back(PIEvaluatorTypes::Function(name, args, getBaseFunction(name)));}
|
||||
inline void addVariable(const PIString & name, const complexd & val = 0.) {variables.push_back(PIEvaluatorTypes::Variable(name, val)); sortVariables();}
|
||||
inline int functionsCount() const {return functions.size();}
|
||||
inline int variablesCount() const {return variables.size();}
|
||||
inline int customVariablesCount() const {return variables.size() - cv_count;}
|
||||
inline int findFunction(const PIString & name) const {for (uint i = 0; i < functions.size(); i++) if (functions[i].identifier == name) return i; return -1;}
|
||||
inline int findVariable(const PIString & var_name) const {for (uint i = 0; i < variables.size(); i++) if (variables[i].name == var_name) return i; return -1;}
|
||||
inline PIEvaluatorTypes::Function function(int index) {if (index < 0 || index >= functions.size_s()) return PIEvaluatorTypes::Function(); return functions[index];}
|
||||
inline PIEvaluatorTypes::Variable variable(int index) {if (index < 0 || index >= variables.size_s()) return PIEvaluatorTypes::Variable(); return variables[index];}
|
||||
inline PIEvaluatorTypes::Function function(const PIString & name) {return function(findFunction(name));}
|
||||
inline PIEvaluatorTypes::Variable variable(const PIString & name) {return variable(findVariable(name));}
|
||||
inline PIEvaluatorTypes::Variable customVariable(int index) {if (index < cv_count || index >= variables.size_s() + cv_count) return PIEvaluatorTypes::Variable(); return variables[index + cv_count];}
|
||||
bool setVariableValue(int index, complexd new_value);
|
||||
bool setVariableName(int index, const PIString & new_name);
|
||||
inline bool setVariableValue(const PIString & var_name, const complexd & new_value) {return setVariableValue(findVariable(var_name), new_value);}
|
||||
inline bool setVariableName(const PIString & var_name, const PIString & new_name) {return setVariableName(findVariable(var_name), new_name);}
|
||||
inline void removeVariable(int index) {variables.remove(index);}
|
||||
inline void removeVariable(const PIString & var_name) {removeVariable(findVariable(var_name));}
|
||||
void clearCustomVariables();
|
||||
void sortVariables();
|
||||
PIEvaluatorTypes::BaseFunctions getBaseFunction(const PIString & name);
|
||||
|
||||
private:
|
||||
PIVector<PIEvaluatorTypes::Function> functions;
|
||||
PIVector<PIEvaluatorTypes::Variable> variables;
|
||||
int cv_count;
|
||||
|
||||
};
|
||||
|
||||
class PIEvaluator
|
||||
{
|
||||
public:
|
||||
PIEvaluator() {;}
|
||||
~PIEvaluator() {;}
|
||||
|
||||
bool check(const PIString & string);
|
||||
inline int setVariable(const PIString & name, complexd value = 0.) {if (content.findVariable(name) < 0) content.addVariable(name, value); else content.setVariableValue(name, value); return content.findVariable(name);}
|
||||
inline void setVariable(int index, complexd value = 0.) {if (index >= 0 && index < content.variablesCount()) content.setVariableValue(index, value);}
|
||||
inline void setCustomVariableValue(int index, complexd value = 0.) {content.variables[index + content.cv_count].value = value;}
|
||||
complexd evaluate();
|
||||
inline void removeVariable(const PIString & name) {content.removeVariable(name);}
|
||||
inline void clearCustomVariables() {content.clearCustomVariables();}
|
||||
inline int variableIndex(const PIString & name) const {return content.findVariable(name);}
|
||||
inline const PIStringList & unknownVariables() {return unknownVars;}
|
||||
inline const PIString & expression() {return currentString;}
|
||||
inline const PIString & error() {return lastError;}
|
||||
inline const complexd & lastResult() {return out;}
|
||||
|
||||
PIEvaluatorContent content;
|
||||
|
||||
private:
|
||||
const PIString & prepare(const PIString & string);
|
||||
const PIString & preprocess(const PIString & string);
|
||||
int parse(const PIString & string, int offset = 0);
|
||||
void convert();
|
||||
void checkBrackets();
|
||||
void removeSpaces();
|
||||
void findUnknownVariables();
|
||||
void removeJunk();
|
||||
void replaceOperators();
|
||||
void makeOutput(PIString & string);
|
||||
bool fillElements();
|
||||
bool setSignes();
|
||||
bool isSign(const PIChar & ch);
|
||||
inline 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);
|
||||
PIEvaluatorTypes::Operation operationInOrder(const int & index);
|
||||
inline complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return kvars->at(index).value;}
|
||||
inline complexd residue(const complexd & f, const complexd & s);
|
||||
inline void execFunction(const PIEvaluatorTypes::Instruction & ci);
|
||||
|
||||
PIVector<PIEvaluatorTypes::Element> elements;
|
||||
PIVector<PIEvaluatorTypes::Variable> currentVariables, variables, tmpvars, * kvars;
|
||||
PIVector<PIEvaluatorTypes::Instruction> instructions;
|
||||
PIStringList unknownVars;
|
||||
PIString currentString, lastError;
|
||||
complexd out;
|
||||
};
|
||||
|
||||
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);}
|
||||
|
||||
#endif // PIEVALUATOR_H
|
||||
Reference in New Issue
Block a user