diff options
Diffstat (limited to 'extrasrc/fptypes.hh')
-rw-r--r-- | extrasrc/fptypes.hh | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/extrasrc/fptypes.hh b/extrasrc/fptypes.hh new file mode 100644 index 0000000..ea28cbc --- /dev/null +++ b/extrasrc/fptypes.hh @@ -0,0 +1,286 @@ +/***************************************************************************\ +|* Function Parser for C++ v4.5.2 *| +|*-------------------------------------------------------------------------*| +|* Copyright: Juha Nieminen, Joel Yliluoma *| +|* *| +|* This library is distributed under the terms of the *| +|* GNU Lesser General Public License version 3. *| +|* (See lgpl.txt and gpl.txt for the license text.) *| +\***************************************************************************/ + +// NOTE: +// This file contains only internal types for the function parser library. +// You don't need to include this file in your code. Include "fparser.hh" +// only. + +#ifndef ONCE_FPARSER_TYPES_H_ +#define ONCE_FPARSER_TYPES_H_ + +#include "../fpconfig.hh" +#include <cstring> + +#ifdef ONCE_FPARSER_H_ +#include <map> +#endif + +namespace FUNCTIONPARSERTYPES +{ + enum OPCODE + { +// The order of opcodes in the function list must +// match that which is in the Functions[] array. + cAbs, + cAcos, cAcosh, + cArg, /* get the phase angle of a complex value */ + cAsin, cAsinh, + cAtan, cAtan2, cAtanh, + cCbrt, cCeil, + cConj, /* get the complex conjugate of a complex value */ + cCos, cCosh, cCot, cCsc, + cExp, cExp2, cFloor, cHypot, + cIf, + cImag, /* get imaginary part of a complex value */ + cInt, cLog, cLog10, cLog2, cMax, cMin, + cPolar, /* create a complex number from polar coordinates */ + cPow, + cReal, /* get real part of a complex value */ + cSec, cSin, cSinh, cSqrt, cTan, cTanh, + cTrunc, + +// These do not need any ordering: +// Except that if you change the order of {eq,neq,lt,le,gt,ge}, you +// must also change the order in ConstantFolding_ComparisonOperations(). + cImmed, cJump, + cNeg, cAdd, cSub, cMul, cDiv, cMod, + cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq, + cNot, cAnd, cOr, + cNotNot, /* Protects the double-not sequence from optimizations */ + + cDeg, cRad, /* Multiplication and division by 180 / pi */ + + cFCall, cPCall, + +#ifdef FP_SUPPORT_OPTIMIZER + cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything + * above [x]. Used for disposing of temporaries. + */ + cLog2by, /* log2by(x,y) = log2(x) * y */ + cNop, /* Used by fpoptimizer internally; should not occur in bytecode */ +#endif + cSinCos, /* sin(x) followed by cos(x) (two values are pushed to stack) */ + cSinhCosh, /* hyperbolic equivalent of sincos */ + cAbsAnd, /* As cAnd, but assume both operands are absolute values */ + cAbsOr, /* As cOr, but assume both operands are absolute values */ + cAbsNot, /* As cAbsNot, but assume the operand is an absolute value */ + cAbsNotNot, /* As cAbsNotNot, but assume the operand is an absolute value */ + cAbsIf, /* As cAbsIf, but assume the 1st operand is an absolute value */ + + cDup, /* Duplicates the last value in the stack: Push [Stacktop] */ + cFetch, /* Same as Dup, except with absolute index + * (next value is index) */ + cInv, /* Inverts the last value in the stack (x = 1/x) */ + cSqr, /* squares the last operand in the stack, no push/pop */ + cRDiv, /* reverse division (not x/y, but y/x) */ + cRSub, /* reverse subtraction (not x-y, but y-x) */ + cRSqrt, /* inverse square-root (1/sqrt(x)) */ + + VarBegin + }; + +#ifdef ONCE_FPARSER_H_ + struct FuncDefinition + { + enum FunctionFlags + { + Enabled = 0x01, + AngleIn = 0x02, + AngleOut = 0x04, + OkForInt = 0x08, + ComplexOnly = 0x10 + }; + +#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING + const char name[8]; +#endif + unsigned params : 8; + unsigned flags : 8; + + inline bool okForInt() const { return (flags & OkForInt) != 0; } + inline bool complexOnly() const { return (flags & ComplexOnly) != 0; } + }; + +#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING +# define FP_FNAME(n) n, +#else +# define FP_FNAME(n) +#endif +// This list must be in the same order as that in OPCODE enum, +// because the opcode value is used to index this array, and +// the pointer to array element is used for generating the opcode. + const FuncDefinition Functions[]= + { + /*cAbs */ { FP_FNAME("abs") 1, FuncDefinition::OkForInt }, + /*cAcos */ { FP_FNAME("acos") 1, FuncDefinition::AngleOut }, + /*cAcosh*/ { FP_FNAME("acosh") 1, FuncDefinition::AngleOut }, + /*cArg */ { FP_FNAME("arg") 1, FuncDefinition::AngleOut | FuncDefinition::ComplexOnly }, + /*cAsin */ { FP_FNAME("asin") 1, FuncDefinition::AngleOut }, + /*cAsinh*/ { FP_FNAME("asinh") 1, FuncDefinition::AngleOut }, + /*cAtan */ { FP_FNAME("atan") 1, FuncDefinition::AngleOut }, + /*cAtan2*/ { FP_FNAME("atan2") 2, FuncDefinition::AngleOut }, + /*cAtanh*/ { FP_FNAME("atanh") 1, 0 }, + /*cCbrt */ { FP_FNAME("cbrt") 1, 0 }, + /*cCeil */ { FP_FNAME("ceil") 1, 0 }, + /*cConj */ { FP_FNAME("conj") 1, FuncDefinition::ComplexOnly }, + /*cCos */ { FP_FNAME("cos") 1, FuncDefinition::AngleIn }, + /*cCosh */ { FP_FNAME("cosh") 1, FuncDefinition::AngleIn }, + /*cCot */ { FP_FNAME("cot") 1, FuncDefinition::AngleIn }, + /*cCsc */ { FP_FNAME("csc") 1, FuncDefinition::AngleIn }, + /*cExp */ { FP_FNAME("exp") 1, 0 }, + /*cExp2 */ { FP_FNAME("exp2") 1, 0 }, + /*cFloor*/ { FP_FNAME("floor") 1, 0 }, + /*cHypot*/ { FP_FNAME("hypot") 2, 0 }, + /*cIf */ { FP_FNAME("if") 0, FuncDefinition::OkForInt }, + /*cImag */ { FP_FNAME("imag") 1, FuncDefinition::ComplexOnly }, + /*cInt */ { FP_FNAME("int") 1, 0 }, + /*cLog */ { FP_FNAME("log") 1, 0 }, + /*cLog10*/ { FP_FNAME("log10") 1, 0 }, + /*cLog2 */ { FP_FNAME("log2") 1, 0 }, + /*cMax */ { FP_FNAME("max") 2, FuncDefinition::OkForInt }, + /*cMin */ { FP_FNAME("min") 2, FuncDefinition::OkForInt }, + /*cPolar */{ FP_FNAME("polar") 2, FuncDefinition::ComplexOnly | FuncDefinition::AngleIn }, + /*cPow */ { FP_FNAME("pow") 2, 0 }, + /*cReal */ { FP_FNAME("real") 1, FuncDefinition::ComplexOnly }, + /*cSec */ { FP_FNAME("sec") 1, FuncDefinition::AngleIn }, + /*cSin */ { FP_FNAME("sin") 1, FuncDefinition::AngleIn }, + /*cSinh */ { FP_FNAME("sinh") 1, FuncDefinition::AngleIn }, + /*cSqrt */ { FP_FNAME("sqrt") 1, 0 }, + /*cTan */ { FP_FNAME("tan") 1, FuncDefinition::AngleIn }, + /*cTanh */ { FP_FNAME("tanh") 1, FuncDefinition::AngleIn }, + /*cTrunc*/ { FP_FNAME("trunc") 1, 0 } + }; +#undef FP_FNAME + + struct NamePtr + { + const char* name; + unsigned nameLength; + + NamePtr(const char* n, unsigned l): name(n), nameLength(l) {} + + inline bool operator==(const NamePtr& rhs) const + { + return nameLength == rhs.nameLength + && std::memcmp(name, rhs.name, nameLength) == 0; + } + inline bool operator<(const NamePtr& rhs) const + { + for(unsigned i = 0; i < nameLength; ++i) + { + if(i == rhs.nameLength) return false; + const char c1 = name[i], c2 = rhs.name[i]; + if(c1 < c2) return true; + if(c2 < c1) return false; + } + return nameLength < rhs.nameLength; + } + }; + + template<typename Value_t> + struct NameData + { + enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE }; + DataType type; + unsigned index; + Value_t value; + + NameData(DataType t, unsigned v) : type(t), index(v), value() { } + NameData(DataType t, Value_t v) : type(t), index(), value(v) { } + NameData() { } + }; + + template<typename Value_t> + class NamePtrsMap: public + std::map<FUNCTIONPARSERTYPES::NamePtr, + FUNCTIONPARSERTYPES::NameData<Value_t> > + { + }; + + const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]); +#endif // ONCE_FPARSER_H_ +} + +#ifdef ONCE_FPARSER_H_ +#include <vector> + +template<typename Value_t> +struct FunctionParserBase<Value_t>::Data +{ + unsigned mReferenceCounter; + + char mDelimiterChar; + ParseErrorType mParseErrorType; + int mEvalErrorType; + bool mUseDegreeConversion; + bool mHasByteCodeFlags; + const char* mErrorLocation; + + unsigned mVariablesAmount; + std::string mVariablesString; + FUNCTIONPARSERTYPES::NamePtrsMap<Value_t> mNamePtrs; + + struct InlineVariable + { + FUNCTIONPARSERTYPES::NamePtr mName; + unsigned mFetchIndex; + }; + + typedef std::vector<InlineVariable> InlineVarNamesContainer; + InlineVarNamesContainer mInlineVarNames; + + struct FuncWrapperPtrData + { + /* Only one of the pointers will point to a function, the other + will be null. (The raw function pointer could be implemented + as a FunctionWrapper specialization, but it's done like this + for efficiency.) */ + FunctionPtr mRawFuncPtr; + FunctionWrapper* mFuncWrapperPtr; + unsigned mParams; + + FuncWrapperPtrData(); + ~FuncWrapperPtrData(); + FuncWrapperPtrData(const FuncWrapperPtrData&); + FuncWrapperPtrData& operator=(const FuncWrapperPtrData&); + }; + + struct FuncParserPtrData + { + FunctionParserBase<Value_t>* mParserPtr; + unsigned mParams; + }; + + std::vector<FuncWrapperPtrData> mFuncPtrs; + std::vector<FuncParserPtrData> mFuncParsers; + + std::vector<unsigned> mByteCode; + std::vector<Value_t> mImmed; + +#if !defined(FP_USE_THREAD_SAFE_EVAL) && \ + !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA) + std::vector<Value_t> mStack; + // Note: When mStack exists, + // mStack.size() and mStackSize are mutually redundant. +#endif + + unsigned mStackSize; + + Data(); + Data(const Data&); + Data& operator=(const Data&); // not implemented on purpose + ~Data(); +}; +#endif + +//#include "fpaux.hh" + +#endif |