Scribus
Open source desktop publishing at your fingertips
fptypes.hh
1 /***************************************************************************\
2 |* Function Parser for C++ v3.3.2 *|
3 |*-------------------------------------------------------------------------*|
4 |* Copyright: Juha Nieminen *|
5 \***************************************************************************/
6 
7 // NOTE:
8 // This file contains only internal types for the function parser library.
9 // You don't need to include this file in your code. Include "fparser.hh"
10 // only.
11 
12 #ifndef ONCE_FPARSER_TYPES_H_
13 #define ONCE_FPARSER_TYPES_H_
14 
15 #include "fpconfig.hh"
16 #include <cmath>
17 
18 namespace FUNCTIONPARSERTYPES
19 {
20 // The functions must be in alphabetical order:
21  enum OPCODE
22  {
23  cAbs,
24  cAcos, cAcosh,
25  cAsin, cAsinh,
26  cAtan, cAtan2, cAtanh,
27  cCeil,
28  cCos, cCosh, cCot, cCsc,
29  cEval,
30  cExp, cExp2, cFloor, cIf, cInt, cLog, cLog10, cLog2, cMax, cMin,
31  cPow, cSec, cSin, cSinh, cSqrt, cTan, cTanh,
32 
33 // These do not need any ordering:
34  cImmed, cJump,
35  cNeg, cAdd, cSub, cMul, cDiv, cMod,
36  cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq,
37  cNot, cAnd, cOr,
38  cNotNot, /* Protects the double-not sequence from optimizations */
39 
40  cDeg, cRad,
41 
42  cFCall, cPCall,
43  cRPow,
44 
45 #ifdef FP_SUPPORT_OPTIMIZER
46  cVar, /* Denotes a variable in CodeTree (not used by bytecode) */
47  cFetch, /* Same as Dup, except with absolute index
48  (next value is index) */
49  cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything
50  above [x] */
51 #endif
52 
53  cDup, /* Duplicates the last value in the stack:
54  Pop A, Push A, Push A */
55  cInv, /* Inverts the last value in the stack (x = 1/x) */
56  cSqr, /* squares the last operand in the stack, no push/pop */
57  cRDiv, /* reverse division (not x/y, but y/x) */
58  cRSub, /* reverse subtraction (not x-y, but y-x) */
59  cRSqrt, /* inverse square-root) */
60 
61  cNop,
62  VarBegin
63  };
64 
65 #ifdef ONCE_FPARSER_H_
66  struct FuncDefinition
67  {
68  const char* name;
69  unsigned nameLength;
70  OPCODE opcode;
71  unsigned params;
72  bool enabled;
73 
74  // This is basically strcmp(), but taking 'nameLength' as string
75  // length (not ending '\0'):
76  bool operator<(const FuncDefinition& rhs) const
77  {
78  for(unsigned i = 0; i < nameLength; ++i)
79  {
80  if(i == rhs.nameLength) return false;
81  const char c1 = name[i], c2 = rhs.name[i];
82  if(c1 < c2) return true;
83  if(c2 < c1) return false;
84  }
85  return nameLength < rhs.nameLength;
86  }
87  };
88 
89 #ifndef FP_DISABLE_EVAL
90 #define FP_EVAL_FUNCTION_ENABLED true
91 #else
92 #define FP_EVAL_FUNCTION_ENABLED false
93 #endif
94 
95 // This list must be in alphabetical order:
96  const FuncDefinition Functions[]=
97  {
98  { "abs", 3, cAbs, 1, true },
99  { "acos", 4, cAcos, 1, true },
100  { "acosh", 5, cAcosh, 1, true },
101  { "asin", 4, cAsin, 1, true },
102  { "asinh", 5, cAsinh, 1, true },
103  { "atan", 4, cAtan, 1, true },
104  { "atan2", 5, cAtan2, 2, true },
105  { "atanh", 5, cAtanh, 1, true },
106  { "ceil", 4, cCeil, 1, true },
107  { "cos", 3, cCos, 1, true },
108  { "cosh", 4, cCosh, 1, true },
109  { "cot", 3, cCot, 1, true },
110  { "csc", 3, cCsc, 1, true },
111  { "eval", 4, cEval, 0, FP_EVAL_FUNCTION_ENABLED },
112  { "exp", 3, cExp, 1, true },
113  { "exp2", 4, cExp2, 1, true },
114  { "floor", 5, cFloor, 1, true },
115  { "if", 2, cIf, 0, true },
116  { "int", 3, cInt, 1, true },
117  { "log", 3, cLog, 1, true },
118  { "log10", 5, cLog10, 1, true },
119  { "log2", 4, cLog2, 1, true },
120  { "max", 3, cMax, 2, true },
121  { "min", 3, cMin, 2, true },
122  { "pow", 3, cPow, 2, true },
123  { "sec", 3, cSec, 1, true },
124  { "sin", 3, cSin, 1, true },
125  { "sinh", 4, cSinh, 1, true },
126  { "sqrt", 4, cSqrt, 1, true },
127  { "tan", 3, cTan, 1, true },
128  { "tanh", 4, cTanh, 1, true }
129  };
130 
131  struct NamePtr
132  {
133  const char* name;
134  unsigned nameLength;
135 
136  NamePtr(const char* n, unsigned l): name(n), nameLength(l) {}
137 
138  inline bool operator<(const NamePtr& rhs) const
139  {
140  for(unsigned i = 0; i < nameLength; ++i)
141  {
142  if(i == rhs.nameLength) return false;
143  const char c1 = name[i], c2 = rhs.name[i];
144  if(c1 < c2) return true;
145  if(c2 < c1) return false;
146  }
147  return nameLength < rhs.nameLength;
148  }
149  };
150 
151  struct NameData
152  {
153  enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR };
154 
155  DataType type;
156  std::string name;
157 
158  union
159  {
160  unsigned index;
161  double value;
162  };
163 
164  NameData(DataType t, const std::string& n): type(t), name(n) {}
165 
166  inline bool operator<(const NameData& rhs) const
167  {
168  return name < rhs.name;
169  }
170  };
171 
172  const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]);
173 
174  // -1 = (lhs < rhs); 0 = (lhs == rhs); 1 = (lhs > rhs)
175  inline int compare(const FuncDefinition& lhs, const NamePtr& rhs)
176  {
177  for(unsigned i = 0; i < lhs.nameLength; ++i)
178  {
179  if(i == rhs.nameLength) return 1;
180  const char c1 = lhs.name[i], c2 = rhs.name[i];
181  if(c1 < c2) return -1;
182  if(c2 < c1) return 1;
183  }
184  return lhs.nameLength < rhs.nameLength ? -1 : 0;
185  }
186 
187  inline const FuncDefinition* findFunction(const NamePtr& functionName)
188  {
189  const FuncDefinition* first = Functions;
190  const FuncDefinition* last = Functions + FUNC_AMOUNT;
191 
192  while(first < last)
193  {
194  const FuncDefinition* middle = first+(last-first)/2;
195  const int comp = compare(*middle, functionName);
196  if(comp == 0) return middle;
197  if(comp < 0) first = middle+1;
198  else last = middle;
199  }
200  return 0;
201  }
202 
203 #ifndef FP_SUPPORT_ASINH
204  inline double fp_asinh(double x) { return log(x + sqrt(x*x + 1)); }
205  inline double fp_acosh(double x) { return log(x + sqrt(x*x - 1)); }
206  inline double fp_atanh(double x) { return log( (1+x) / (1-x) ) * 0.5; }
207 #else
208  inline double fp_asinh(double x) { return asinh(x); }
209  inline double fp_acosh(double x) { return acosh(x); }
210  inline double fp_atanh(double x) { return atanh(x); }
211 #endif // FP_SUPPORT_ASINH
212 
213 #ifdef FP_EPSILON
214  inline bool FloatEqual(double a, double b)
215  { return fabs(a - b) <= FP_EPSILON; }
216 #else
217  inline bool FloatEqual(double a, double b)
218  { return a == b; }
219 #endif // FP_EPSILON
220 
221  inline bool IsIntegerConst(double a)
222  { return FloatEqual(a, (double)(long)a); }
223 
224 #endif // ONCE_FPARSER_H_
225 }
226 
227 #ifdef ONCE_FPARSER_H_
228 #include <map>
229 #include <set>
230 #include <vector>
231 
232 struct FunctionParser::Data
233 {
234  unsigned referenceCounter;
235 
236  std::string variablesString;
237  std::map<FUNCTIONPARSERTYPES::NamePtr, unsigned> variableRefs;
238 
239  std::set<FUNCTIONPARSERTYPES::NameData> nameData;
240  std::map<FUNCTIONPARSERTYPES::NamePtr,
241  const FUNCTIONPARSERTYPES::NameData*> namePtrs;
242 
243  struct FuncPtrData
244  {
245  union { FunctionPtr funcPtr; FunctionParser* parserPtr; };
246  unsigned params;
247  };
248 
249  std::vector<FuncPtrData> FuncPtrs;
250  std::vector<FuncPtrData> FuncParsers;
251 
252  std::vector<unsigned> ByteCode;
253  std::vector<double> Immed;
254  std::vector<double> Stack;
255  unsigned StackSize;
256 
257  Data(): referenceCounter(1),
258  variablesString(),
259  variableRefs(),
260  nameData(),
261  namePtrs(),
262  FuncPtrs(),
263  FuncParsers(),
264  ByteCode(),
265  Immed(), Stack(), StackSize(0) {}
266  Data(const Data&);
267  Data& operator=(const Data&); // not implemented on purpose
268 };
269 #endif
270 
271 #endif
Definition: fpoptimizer.cc:45
Definition: fparser.hh:21