Planeshift
fptypes.h
Go to the documentation of this file.
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.h"
20 #include <cstring>
21 
22 #ifdef ONCE_FPARSER_H_
23 #include <map>
24 #endif
25 
27 {
28  enum OPCODE
29  {
30 // The order of opcodes in the function list must
31 // match that which is in the Functions[] array.
34  cArg, /* get the phase angle of a complex value */
38  cConj, /* get the complex conjugate of a complex value */
41  cIf,
42  cImag, /* get imaginary part of a complex value */
44  cPolar, /* create a complex number from polar coordinates */
46  cReal, /* get real part of a complex value */
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().
57  cNotNot, /* Protects the double-not sequence from optimizations */
58 
59  cDeg, cRad, /* Multiplication and division by 180 / pi */
60 
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 
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 
108  inline bool okForInt() const { return (flags & OkForInt) != 0; }
109  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  /*cHypot*/ { FP_FNAME("hypot") 2, 0 },
142  /*cIf */ { FP_FNAME("if") 0, FuncDefinition::OkForInt },
143  /*cImag */ { FP_FNAME("imag") 1, FuncDefinition::ComplexOnly },
144  /*cInt */ { FP_FNAME("int") 1, 0 },
145  /*cLog */ { FP_FNAME("log") 1, 0 },
146  /*cLog10*/ { FP_FNAME("log10") 1, 0 },
147  /*cLog2 */ { FP_FNAME("log2") 1, 0 },
148  /*cMax */ { FP_FNAME("max") 2, FuncDefinition::OkForInt },
149  /*cMin */ { FP_FNAME("min") 2, FuncDefinition::OkForInt },
150  /*cPolar */{ FP_FNAME("polar") 2, FuncDefinition::ComplexOnly | FuncDefinition::AngleIn },
151  /*cPow */ { FP_FNAME("pow") 2, 0 },
152  /*cReal */ { FP_FNAME("real") 1, FuncDefinition::ComplexOnly },
153  /*cSec */ { FP_FNAME("sec") 1, FuncDefinition::AngleIn },
154  /*cSin */ { FP_FNAME("sin") 1, FuncDefinition::AngleIn },
155  /*cSinh */ { FP_FNAME("sinh") 1, FuncDefinition::AngleIn },
156  /*cSqrt */ { FP_FNAME("sqrt") 1, 0 },
157  /*cTan */ { FP_FNAME("tan") 1, FuncDefinition::AngleIn },
158  /*cTanh */ { FP_FNAME("tanh") 1, FuncDefinition::AngleIn },
159  /*cTrunc*/ { FP_FNAME("trunc") 1, 0 }
160  };
161 #undef FP_FNAME
162 
163  struct NamePtr
164  {
165  const char* name;
166  unsigned nameLength;
167 
168  NamePtr(const char* n, unsigned l): name(n), nameLength(l) {}
169 
170  inline bool operator==(const NamePtr& rhs) const
171  {
172  return nameLength == rhs.nameLength
173  && std::memcmp(name, rhs.name, nameLength) == 0;
174  }
175  inline bool operator<(const NamePtr& rhs) const
176  {
177  for(unsigned i = 0; i < nameLength; ++i)
178  {
179  if(i == rhs.nameLength) return false;
180  const char c1 = name[i], c2 = rhs.name[i];
181  if(c1 < c2) return true;
182  if(c2 < c1) return false;
183  }
184  return nameLength < rhs.nameLength;
185  }
186  };
187 
188  template<typename Value_t>
189  struct NameData
190  {
191  enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE };
192  DataType type;
193  unsigned index;
194  Value_t value;
195 
196  NameData(DataType t, unsigned v) : type(t), index(v), value() { }
197  NameData(DataType t, Value_t v) : type(t), index(), value(v) { }
198  NameData() { }
199  };
200 
201  template<typename Value_t>
202  class NamePtrsMap: public
203  std::map<FUNCTIONPARSERTYPES::NamePtr,
204  FUNCTIONPARSERTYPES::NameData<Value_t> >
205  {
206  };
207 
208  const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]);
209 #endif // ONCE_FPARSER_H_
210 }
211 
212 #ifdef ONCE_FPARSER_H_
213 #include <vector>
214 
215 template<typename Value_t>
216 struct FunctionParserBase<Value_t>::Data
217 {
218  unsigned mReferenceCounter;
219 
220  char mDelimiterChar;
221  ParseErrorType mParseErrorType;
222  int mEvalErrorType;
223  bool mUseDegreeConversion;
224  bool mHasByteCodeFlags;
225  const char* mErrorLocation;
226 
227  unsigned mVariablesAmount;
228  std::string mVariablesString;
229  FUNCTIONPARSERTYPES::NamePtrsMap<Value_t> mNamePtrs;
230 
231  struct InlineVariable
232  {
233  FUNCTIONPARSERTYPES::NamePtr mName;
234  unsigned mFetchIndex;
235  };
236 
237  typedef std::vector<InlineVariable> InlineVarNamesContainer;
238  InlineVarNamesContainer mInlineVarNames;
239 
240  struct FuncWrapperPtrData
241  {
242  /* Only one of the pointers will point to a function, the other
243  will be null. (The raw function pointer could be implemented
244  as a FunctionWrapper specialization, but it's done like this
245  for efficiency.) */
246  FunctionPtr mRawFuncPtr;
247  FunctionWrapper* mFuncWrapperPtr;
248  unsigned mParams;
249 
250  FuncWrapperPtrData();
251  ~FuncWrapperPtrData();
252  FuncWrapperPtrData(const FuncWrapperPtrData&);
253  FuncWrapperPtrData& operator=(const FuncWrapperPtrData&);
254  };
255 
256  struct FuncParserPtrData
257  {
258  FunctionParserBase<Value_t>* mParserPtr;
259  unsigned mParams;
260  };
261 
262  std::vector<FuncWrapperPtrData> mFuncPtrs;
263  std::vector<FuncParserPtrData> mFuncParsers;
264 
265  std::vector<unsigned> mByteCode;
266  std::vector<Value_t> mImmed;
267 
268 #if !defined(FP_USE_THREAD_SAFE_EVAL) && \
269  !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA)
270  std::vector<Value_t> mStack;
271  // Note: When mStack exists,
272  // mStack.size() and mStackSize are mutually redundant.
273 #endif
274 
275  unsigned mStackSize;
276 
277  Data();
278  Data(const Data&);
279  Data& operator=(const Data&); // not implemented on purpose
280  ~Data();
281 };
282 #endif
283 
284 //#include "fpaux.hh"
285 
286 #endif
bool operator<(long lhs, const GmpInt &rhs)
Definition: GmpInt.h:135
bool operator==(T *p, const scoped_ptr< T > &b)
Definition: scoped_ptr.h:134