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

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..