Files
pip/pievaluator.h
2011-07-29 08:17:24 +04:00

149 lines
6.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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