1 /***************************************************************************\ 2 |* Function Parser for C++ v4.5.2 *| 3 |*-------------------------------------------------------------------------*| 4 |* Copyright: Juha Nieminen, Joel Yliluoma *| 5 |* *| 6 |* This library is distributed under the terms of the *| 7 |* GNU Lesser General Public License version 3. *| 8 |* (See lgpl.txt and gpl.txt for the license text.) *| 9 \***************************************************************************/ 10 11 // NOTE: 12 // This file contains only internal types for the function parser library. 13 // You don't need to include this file in your code. Include "fparser.hh" 14 // only. 15 16 #ifndef ONCE_FPARSER_TYPES_H_ 17 #define ONCE_FPARSER_TYPES_H_ 18 19 #include "../fpconfig.hh" 20 #include <cstring> 21 22 #ifdef ONCE_FPARSER_H_ 23 #include <map> 24 #endif 25 26 namespace FUNCTIONPARSERTYPES 27 { 28 enum OPCODE 29 { 30 // The order of opcodes in the function list must 31 // match that which is in the Functions[] array. 32 cAbs, 33 cAcos, cAcosh, 34 cArg, /* get the phase angle of a complex value */ 35 cAsin, cAsinh, 36 cAtan, cAtan2, cAtanh, 37 cCbrt, cCeil, 38 cConj, /* get the complex conjugate of a complex value */ 39 cCos, cCosh, cCot, cCsc, cCsd, 40 cExp, cExp2, cFloor, cHypot, 41 cIf, 42 cImag, /* get imaginary part of a complex value */ 43 cInt, cLog, cLog10, cLog2, cMax, cMin, 44 cPolar, /* create a complex number from polar coordinates */ 45 cPow, cPsh, 46 cReal, /* get real part of a complex value */ 47 cSec, cSin, cSinh, cSqrt, cTan, cTanh, 48 cTrunc, 49 50 // These do not need any ordering: 51 // Except that if you change the order of {eq,neq,lt,le,gt,ge}, you 52 // must also change the order in ConstantFolding_ComparisonOperations(). 53 cImmed, cJump, 54 cNeg, cAdd, cSub, cMul, cDiv, cMod, 55 cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq, 56 cNot, cAnd, cOr, 57 cNotNot, /* Protects the double-not sequence from optimizations */ 58 59 cDeg, cRad, /* Multiplication and division by 180 / pi */ 60 61 cFCall, cPCall, 62 63 #ifdef FP_SUPPORT_OPTIMIZER 64 cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything 65 * above [x]. Used for disposing of temporaries. 66 */ 67 cLog2by, /* log2by(x,y) = log2(x) * y */ 68 cNop, /* Used by fpoptimizer internally; should not occur in bytecode */ 69 #endif 70 cSinCos, /* sin(x) followed by cos(x) (two values are pushed to stack) */ 71 cSinhCosh, /* hyperbolic equivalent of sincos */ 72 cAbsAnd, /* As cAnd, but assume both operands are absolute values */ 73 cAbsOr, /* As cOr, but assume both operands are absolute values */ 74 cAbsNot, /* As cAbsNot, but assume the operand is an absolute value */ 75 cAbsNotNot, /* As cAbsNotNot, but assume the operand is an absolute value */ 76 cAbsIf, /* As cAbsIf, but assume the 1st operand is an absolute value */ 77 78 cDup, /* Duplicates the last value in the stack: Push [Stacktop] */ 79 cFetch, /* Same as Dup, except with absolute index 80 * (next value is index) */ 81 cInv, /* Inverts the last value in the stack (x = 1/x) */ 82 cSqr, /* squares the last operand in the stack, no push/pop */ 83 cRDiv, /* reverse division (not x/y, but y/x) */ 84 cRSub, /* reverse subtraction (not x-y, but y-x) */ 85 cRSqrt, /* inverse square-root (1/sqrt(x)) */ 86 87 VarBegin 88 }; 89 90 #ifdef ONCE_FPARSER_H_ 91 struct FuncDefinition 92 { 93 enum FunctionFlags 94 { 95 Enabled = 0x01, 96 AngleIn = 0x02, 97 AngleOut = 0x04, 98 OkForInt = 0x08, 99 ComplexOnly = 0x10 100 }; 101 102 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING 103 const char name[8]; 104 #endif 105 unsigned params : 8; 106 unsigned flags : 8; 107 okForIntFUNCTIONPARSERTYPES::FuncDefinition108 inline bool okForInt() const { return (flags & OkForInt) != 0; } complexOnlyFUNCTIONPARSERTYPES::FuncDefinition109 inline bool complexOnly() const { return (flags & ComplexOnly) != 0; } 110 }; 111 112 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING 113 # define FP_FNAME(n) n, 114 #else 115 # define FP_FNAME(n) 116 #endif 117 // This list must be in the same order as that in OPCODE enum, 118 // because the opcode value is used to index this array, and 119 // the pointer to array element is used for generating the opcode. 120 const FuncDefinition Functions[]= 121 { 122 /*cAbs */ { FP_FNAME("abs") 1, FuncDefinition::OkForInt }, 123 /*cAcos */ { FP_FNAME("acos") 1, FuncDefinition::AngleOut }, 124 /*cAcosh*/ { FP_FNAME("acosh") 1, FuncDefinition::AngleOut }, 125 /*cArg */ { FP_FNAME("arg") 1, FuncDefinition::AngleOut | FuncDefinition::ComplexOnly }, 126 /*cAsin */ { FP_FNAME("asin") 1, FuncDefinition::AngleOut }, 127 /*cAsinh*/ { FP_FNAME("asinh") 1, FuncDefinition::AngleOut }, 128 /*cAtan */ { FP_FNAME("atan") 1, FuncDefinition::AngleOut }, 129 /*cAtan2*/ { FP_FNAME("atan2") 2, FuncDefinition::AngleOut }, 130 /*cAtanh*/ { FP_FNAME("atanh") 1, 0 }, 131 /*cCbrt */ { FP_FNAME("cbrt") 1, 0 }, 132 /*cCeil */ { FP_FNAME("ceil") 1, 0 }, 133 /*cConj */ { FP_FNAME("conj") 1, FuncDefinition::ComplexOnly }, 134 /*cCos */ { FP_FNAME("cos") 1, FuncDefinition::AngleIn }, 135 /*cCosh */ { FP_FNAME("cosh") 1, FuncDefinition::AngleIn }, 136 /*cCot */ { FP_FNAME("cot") 1, FuncDefinition::AngleIn }, 137 /*cCsc */ { FP_FNAME("csc") 1, FuncDefinition::AngleIn }, 138 /*cExp */ { FP_FNAME("exp") 1, 0 }, 139 /*cExp2 */ { FP_FNAME("exp2") 1, 0 }, 140 /*cFloor*/ { FP_FNAME("floor") 1, 0 }, 141 /*cGet */ { FP_FNAME("get") 1, 0 }, 142 /*cHypot*/ { FP_FNAME("hypot") 2, 0 }, 143 /*cIf */ { FP_FNAME("if") 0, FuncDefinition::OkForInt }, 144 /*cImag */ { FP_FNAME("imag") 1, FuncDefinition::ComplexOnly }, 145 /*cInt */ { FP_FNAME("int") 1, 0 }, 146 /*cLog */ { FP_FNAME("log") 1, 0 }, 147 /*cLog10*/ { FP_FNAME("log10") 1, 0 }, 148 /*cLog2 */ { FP_FNAME("log2") 1, 0 }, 149 /*cMax */ { FP_FNAME("max") 2, FuncDefinition::OkForInt }, 150 /*cMin */ { FP_FNAME("min") 2, FuncDefinition::OkForInt }, 151 /*cPolar */{ FP_FNAME("polar") 2, FuncDefinition::ComplexOnly | FuncDefinition::AngleIn }, 152 /*cPow */ { FP_FNAME("pow") 2, 0 }, 153 /*cPsh */ { FP_FNAME("psh") 2, 0 }, 154 /*cReal */ { FP_FNAME("real") 1, FuncDefinition::ComplexOnly }, 155 /*cSec */ { FP_FNAME("sec") 1, FuncDefinition::AngleIn }, 156 /*cSin */ { FP_FNAME("sin") 1, FuncDefinition::AngleIn }, 157 /*cSinh */ { FP_FNAME("sinh") 1, FuncDefinition::AngleIn }, 158 /*cSqrt */ { FP_FNAME("sqrt") 1, 0 }, 159 /*cTan */ { FP_FNAME("tan") 1, FuncDefinition::AngleIn }, 160 /*cTanh */ { FP_FNAME("tanh") 1, FuncDefinition::AngleIn }, 161 /*cTrunc*/ { FP_FNAME("trunc") 1, 0 } 162 }; 163 #undef FP_FNAME 164 165 struct NamePtr 166 { 167 const char* name; 168 unsigned nameLength; 169 NamePtrFUNCTIONPARSERTYPES::NamePtr170 NamePtr(const char* n, unsigned l): name(n), nameLength(l) {} 171 operator ==FUNCTIONPARSERTYPES::NamePtr172 inline bool operator==(const NamePtr& rhs) const 173 { 174 return nameLength == rhs.nameLength 175 && std::memcmp(name, rhs.name, nameLength) == 0; 176 } operator <FUNCTIONPARSERTYPES::NamePtr177 inline bool operator<(const NamePtr& rhs) const 178 { 179 for(unsigned i = 0; i < nameLength; ++i) 180 { 181 if(i == rhs.nameLength) return false; 182 const char c1 = name[i], c2 = rhs.name[i]; 183 if(c1 < c2) return true; 184 if(c2 < c1) return false; 185 } 186 return nameLength < rhs.nameLength; 187 } 188 }; 189 190 template<typename Value_t> 191 struct NameData 192 { 193 enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE }; 194 DataType type; 195 unsigned index; 196 Value_t value; 197 NameDataFUNCTIONPARSERTYPES::NameData198 NameData(DataType t, unsigned v) : type(t), index(v), value() { } NameDataFUNCTIONPARSERTYPES::NameData199 NameData(DataType t, Value_t v) : type(t), index(), value(v) { } NameDataFUNCTIONPARSERTYPES::NameData200 NameData() { } 201 }; 202 203 template<typename Value_t> 204 class NamePtrsMap: public 205 std::map<FUNCTIONPARSERTYPES::NamePtr, 206 FUNCTIONPARSERTYPES::NameData<Value_t> > 207 { 208 }; 209 210 const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]); 211 #endif // ONCE_FPARSER_H_ 212 } 213 214 #ifdef ONCE_FPARSER_H_ 215 #include <vector> 216 217 template<typename Value_t> 218 struct FunctionParserBase<Value_t>::Data 219 { 220 unsigned mReferenceCounter; 221 222 char mDelimiterChar; 223 ParseErrorType mParseErrorType; 224 int mEvalErrorType; 225 bool mUseDegreeConversion; 226 bool mHasByteCodeFlags; 227 const char* mErrorLocation; 228 229 unsigned mVariablesAmount; 230 std::string mVariablesString; 231 FUNCTIONPARSERTYPES::NamePtrsMap<Value_t> mNamePtrs; 232 233 struct InlineVariable 234 { 235 FUNCTIONPARSERTYPES::NamePtr mName; 236 unsigned mFetchIndex; 237 }; 238 239 typedef std::vector<InlineVariable> InlineVarNamesContainer; 240 InlineVarNamesContainer mInlineVarNames; 241 242 struct FuncWrapperPtrData 243 { 244 /* Only one of the pointers will point to a function, the other 245 will be null. (The raw function pointer could be implemented 246 as a FunctionWrapper specialization, but it's done like this 247 for efficiency.) */ 248 FunctionPtr mRawFuncPtr; 249 FunctionWrapper* mFuncWrapperPtr; 250 unsigned mParams; 251 252 FuncWrapperPtrData(); 253 ~FuncWrapperPtrData(); 254 FuncWrapperPtrData(const FuncWrapperPtrData&); 255 FuncWrapperPtrData& operator=(const FuncWrapperPtrData&); 256 }; 257 258 struct FuncParserPtrData 259 { 260 FunctionParserBase<Value_t>* mParserPtr; 261 unsigned mParams; 262 }; 263 264 std::vector<FuncWrapperPtrData> mFuncPtrs; 265 std::vector<FuncParserPtrData> mFuncParsers; 266 267 std::vector<unsigned> mByteCode; 268 std::vector<Value_t> mImmed; 269 270 #if !defined(FP_USE_THREAD_SAFE_EVAL) && \ 271 !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA) 272 std::vector<Value_t> mStack; 273 std::vector<Value_t> mStacki; 274 std::vector<Value_t> mStackSave; 275 // Note: When mStack exists, 276 // mStack.size() and mStackSize are mutually redundant. 277 #endif 278 279 unsigned mStackSize; 280 281 Data(); 282 Data(const Data&); 283 Data& operator=(const Data&); // not implemented on purpose 284 ~Data(); 285 }; 286 #endif 287 288 //#include "fpaux.hh" 289 290 #endif 291