Planeshift
|
00001 /***************************************************************************\ 00002 |* Function Parser for C++ v4.5.2 *| 00003 |*-------------------------------------------------------------------------*| 00004 |* Copyright: Juha Nieminen, Joel Yliluoma *| 00005 |* *| 00006 |* This library is distributed under the terms of the *| 00007 |* GNU Lesser General Public License version 3. *| 00008 |* (See lgpl.txt and gpl.txt for the license text.) *| 00009 \***************************************************************************/ 00010 00011 // NOTE: 00012 // This file contains only internal types for the function parser library. 00013 // You don't need to include this file in your code. Include "fparser.hh" 00014 // only. 00015 00016 #ifndef ONCE_FPARSER_TYPES_H_ 00017 #define ONCE_FPARSER_TYPES_H_ 00018 00019 #include "../fpconfig.h" 00020 #include <cstring> 00021 00022 #ifdef ONCE_FPARSER_H_ 00023 #include <map> 00024 #endif 00025 00026 namespace FUNCTIONPARSERTYPES 00027 { 00028 enum OPCODE 00029 { 00030 // The order of opcodes in the function list must 00031 // match that which is in the Functions[] array. 00032 cAbs, 00033 cAcos, cAcosh, 00034 cArg, /* get the phase angle of a complex value */ 00035 cAsin, cAsinh, 00036 cAtan, cAtan2, cAtanh, 00037 cCbrt, cCeil, 00038 cConj, /* get the complex conjugate of a complex value */ 00039 cCos, cCosh, cCot, cCsc, 00040 cExp, cExp2, cFloor, cHypot, 00041 cIf, 00042 cImag, /* get imaginary part of a complex value */ 00043 cInt, cLog, cLog10, cLog2, cMax, cMin, 00044 cPolar, /* create a complex number from polar coordinates */ 00045 cPow, 00046 cReal, /* get real part of a complex value */ 00047 cSec, cSin, cSinh, cSqrt, cTan, cTanh, 00048 cTrunc, 00049 00050 // These do not need any ordering: 00051 // Except that if you change the order of {eq,neq,lt,le,gt,ge}, you 00052 // must also change the order in ConstantFolding_ComparisonOperations(). 00053 cImmed, cJump, 00054 cNeg, cAdd, cSub, cMul, cDiv, cMod, 00055 cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq, 00056 cNot, cAnd, cOr, 00057 cNotNot, /* Protects the double-not sequence from optimizations */ 00058 00059 cDeg, cRad, /* Multiplication and division by 180 / pi */ 00060 00061 cFCall, cPCall, 00062 00063 #ifdef FP_SUPPORT_OPTIMIZER 00064 cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything 00065 * above [x]. Used for disposing of temporaries. 00066 */ 00067 cLog2by, /* log2by(x,y) = log2(x) * y */ 00068 cNop, /* Used by fpoptimizer internally; should not occur in bytecode */ 00069 #endif 00070 cSinCos, /* sin(x) followed by cos(x) (two values are pushed to stack) */ 00071 cSinhCosh, /* hyperbolic equivalent of sincos */ 00072 cAbsAnd, /* As cAnd, but assume both operands are absolute values */ 00073 cAbsOr, /* As cOr, but assume both operands are absolute values */ 00074 cAbsNot, /* As cAbsNot, but assume the operand is an absolute value */ 00075 cAbsNotNot, /* As cAbsNotNot, but assume the operand is an absolute value */ 00076 cAbsIf, /* As cAbsIf, but assume the 1st operand is an absolute value */ 00077 00078 cDup, /* Duplicates the last value in the stack: Push [Stacktop] */ 00079 cFetch, /* Same as Dup, except with absolute index 00080 * (next value is index) */ 00081 cInv, /* Inverts the last value in the stack (x = 1/x) */ 00082 cSqr, /* squares the last operand in the stack, no push/pop */ 00083 cRDiv, /* reverse division (not x/y, but y/x) */ 00084 cRSub, /* reverse subtraction (not x-y, but y-x) */ 00085 cRSqrt, /* inverse square-root (1/sqrt(x)) */ 00086 00087 VarBegin 00088 }; 00089 00090 #ifdef ONCE_FPARSER_H_ 00091 struct FuncDefinition 00092 { 00093 enum FunctionFlags 00094 { 00095 Enabled = 0x01, 00096 AngleIn = 0x02, 00097 AngleOut = 0x04, 00098 OkForInt = 0x08, 00099 ComplexOnly = 0x10 00100 }; 00101 00102 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING 00103 const char name[8]; 00104 #endif 00105 unsigned params : 8; 00106 unsigned flags : 8; 00107 00108 inline bool okForInt() const { return (flags & OkForInt) != 0; } 00109 inline bool complexOnly() const { return (flags & ComplexOnly) != 0; } 00110 }; 00111 00112 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING 00113 # define FP_FNAME(n) n, 00114 #else 00115 # define FP_FNAME(n) 00116 #endif 00117 // This list must be in the same order as that in OPCODE enum, 00118 // because the opcode value is used to index this array, and 00119 // the pointer to array element is used for generating the opcode. 00120 const FuncDefinition Functions[]= 00121 { 00122 /*cAbs */ { FP_FNAME("abs") 1, FuncDefinition::OkForInt }, 00123 /*cAcos */ { FP_FNAME("acos") 1, FuncDefinition::AngleOut }, 00124 /*cAcosh*/ { FP_FNAME("acosh") 1, FuncDefinition::AngleOut }, 00125 /*cArg */ { FP_FNAME("arg") 1, FuncDefinition::AngleOut | FuncDefinition::ComplexOnly }, 00126 /*cAsin */ { FP_FNAME("asin") 1, FuncDefinition::AngleOut }, 00127 /*cAsinh*/ { FP_FNAME("asinh") 1, FuncDefinition::AngleOut }, 00128 /*cAtan */ { FP_FNAME("atan") 1, FuncDefinition::AngleOut }, 00129 /*cAtan2*/ { FP_FNAME("atan2") 2, FuncDefinition::AngleOut }, 00130 /*cAtanh*/ { FP_FNAME("atanh") 1, 0 }, 00131 /*cCbrt */ { FP_FNAME("cbrt") 1, 0 }, 00132 /*cCeil */ { FP_FNAME("ceil") 1, 0 }, 00133 /*cConj */ { FP_FNAME("conj") 1, FuncDefinition::ComplexOnly }, 00134 /*cCos */ { FP_FNAME("cos") 1, FuncDefinition::AngleIn }, 00135 /*cCosh */ { FP_FNAME("cosh") 1, FuncDefinition::AngleIn }, 00136 /*cCot */ { FP_FNAME("cot") 1, FuncDefinition::AngleIn }, 00137 /*cCsc */ { FP_FNAME("csc") 1, FuncDefinition::AngleIn }, 00138 /*cExp */ { FP_FNAME("exp") 1, 0 }, 00139 /*cExp2 */ { FP_FNAME("exp2") 1, 0 }, 00140 /*cFloor*/ { FP_FNAME("floor") 1, 0 }, 00141 /*cHypot*/ { FP_FNAME("hypot") 2, 0 }, 00142 /*cIf */ { FP_FNAME("if") 0, FuncDefinition::OkForInt }, 00143 /*cImag */ { FP_FNAME("imag") 1, FuncDefinition::ComplexOnly }, 00144 /*cInt */ { FP_FNAME("int") 1, 0 }, 00145 /*cLog */ { FP_FNAME("log") 1, 0 }, 00146 /*cLog10*/ { FP_FNAME("log10") 1, 0 }, 00147 /*cLog2 */ { FP_FNAME("log2") 1, 0 }, 00148 /*cMax */ { FP_FNAME("max") 2, FuncDefinition::OkForInt }, 00149 /*cMin */ { FP_FNAME("min") 2, FuncDefinition::OkForInt }, 00150 /*cPolar */{ FP_FNAME("polar") 2, FuncDefinition::ComplexOnly | FuncDefinition::AngleIn }, 00151 /*cPow */ { FP_FNAME("pow") 2, 0 }, 00152 /*cReal */ { FP_FNAME("real") 1, FuncDefinition::ComplexOnly }, 00153 /*cSec */ { FP_FNAME("sec") 1, FuncDefinition::AngleIn }, 00154 /*cSin */ { FP_FNAME("sin") 1, FuncDefinition::AngleIn }, 00155 /*cSinh */ { FP_FNAME("sinh") 1, FuncDefinition::AngleIn }, 00156 /*cSqrt */ { FP_FNAME("sqrt") 1, 0 }, 00157 /*cTan */ { FP_FNAME("tan") 1, FuncDefinition::AngleIn }, 00158 /*cTanh */ { FP_FNAME("tanh") 1, FuncDefinition::AngleIn }, 00159 /*cTrunc*/ { FP_FNAME("trunc") 1, 0 } 00160 }; 00161 #undef FP_FNAME 00162 00163 struct NamePtr 00164 { 00165 const char* name; 00166 unsigned nameLength; 00167 00168 NamePtr(const char* n, unsigned l): name(n), nameLength(l) {} 00169 00170 inline bool operator==(const NamePtr& rhs) const 00171 { 00172 return nameLength == rhs.nameLength 00173 && std::memcmp(name, rhs.name, nameLength) == 0; 00174 } 00175 inline bool operator<(const NamePtr& rhs) const 00176 { 00177 for(unsigned i = 0; i < nameLength; ++i) 00178 { 00179 if(i == rhs.nameLength) return false; 00180 const char c1 = name[i], c2 = rhs.name[i]; 00181 if(c1 < c2) return true; 00182 if(c2 < c1) return false; 00183 } 00184 return nameLength < rhs.nameLength; 00185 } 00186 }; 00187 00188 template<typename Value_t> 00189 struct NameData 00190 { 00191 enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE }; 00192 DataType type; 00193 unsigned index; 00194 Value_t value; 00195 00196 NameData(DataType t, unsigned v) : type(t), index(v), value() { } 00197 NameData(DataType t, Value_t v) : type(t), index(), value(v) { } 00198 NameData() { } 00199 }; 00200 00201 template<typename Value_t> 00202 class NamePtrsMap: public 00203 std::map<FUNCTIONPARSERTYPES::NamePtr, 00204 FUNCTIONPARSERTYPES::NameData<Value_t> > 00205 { 00206 }; 00207 00208 const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]); 00209 #endif // ONCE_FPARSER_H_ 00210 } 00211 00212 #ifdef ONCE_FPARSER_H_ 00213 #include <vector> 00214 00215 template<typename Value_t> 00216 struct FunctionParserBase<Value_t>::Data 00217 { 00218 unsigned mReferenceCounter; 00219 00220 char mDelimiterChar; 00221 ParseErrorType mParseErrorType; 00222 int mEvalErrorType; 00223 bool mUseDegreeConversion; 00224 bool mHasByteCodeFlags; 00225 const char* mErrorLocation; 00226 00227 unsigned mVariablesAmount; 00228 std::string mVariablesString; 00229 FUNCTIONPARSERTYPES::NamePtrsMap<Value_t> mNamePtrs; 00230 00231 struct InlineVariable 00232 { 00233 FUNCTIONPARSERTYPES::NamePtr mName; 00234 unsigned mFetchIndex; 00235 }; 00236 00237 typedef std::vector<InlineVariable> InlineVarNamesContainer; 00238 InlineVarNamesContainer mInlineVarNames; 00239 00240 struct FuncWrapperPtrData 00241 { 00242 /* Only one of the pointers will point to a function, the other 00243 will be null. (The raw function pointer could be implemented 00244 as a FunctionWrapper specialization, but it's done like this 00245 for efficiency.) */ 00246 FunctionPtr mRawFuncPtr; 00247 FunctionWrapper* mFuncWrapperPtr; 00248 unsigned mParams; 00249 00250 FuncWrapperPtrData(); 00251 ~FuncWrapperPtrData(); 00252 FuncWrapperPtrData(const FuncWrapperPtrData&); 00253 FuncWrapperPtrData& operator=(const FuncWrapperPtrData&); 00254 }; 00255 00256 struct FuncParserPtrData 00257 { 00258 FunctionParserBase<Value_t>* mParserPtr; 00259 unsigned mParams; 00260 }; 00261 00262 std::vector<FuncWrapperPtrData> mFuncPtrs; 00263 std::vector<FuncParserPtrData> mFuncParsers; 00264 00265 std::vector<unsigned> mByteCode; 00266 std::vector<Value_t> mImmed; 00267 00268 #if !defined(FP_USE_THREAD_SAFE_EVAL) && \ 00269 !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA) 00270 std::vector<Value_t> mStack; 00271 // Note: When mStack exists, 00272 // mStack.size() and mStackSize are mutually redundant. 00273 #endif 00274 00275 unsigned mStackSize; 00276 00277 Data(); 00278 Data(const Data&); 00279 Data& operator=(const Data&); // not implemented on purpose 00280 ~Data(); 00281 }; 00282 #endif 00283 00284 //#include "fpaux.hh" 00285 00286 #endif