]> Shamusworld >> Repos - architektonas/blob - fparser/fptypes.hh
Fixed problem with MDI activation.
[architektonas] / fparser / fptypes.hh
1 /***************************************************************************\
2 |* Function Parser for C++ v4.3                                            *|
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         cAsin, cAsinh,
35         cAtan, cAtan2, cAtanh,
36         cCbrt, cCeil,
37         cCos, cCosh, cCot, cCsc,
38         cEval,
39         cExp, cExp2, cFloor, cHypot,
40         cIf, cInt, cLog, cLog10, cLog2, cMax, cMin,
41         cPow, cSec, cSin, cSinh, cSqrt, cTan, cTanh,
42         cTrunc,
43
44 // These do not need any ordering:
45 // Except that if you change the order of {eq,neq,lt,le,gt,ge}, you
46 // must also change the order in ConstantFolding_ComparisonOperations().
47         cImmed, cJump,
48         cNeg, cAdd, cSub, cMul, cDiv, cMod,
49         cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq,
50         cNot, cAnd, cOr,
51         cNotNot, /* Protects the double-not sequence from optimizations */
52
53         cDeg, cRad, /* Multiplication and division by 180 / pi */
54
55         cFCall, cPCall,
56
57 #ifdef FP_SUPPORT_OPTIMIZER
58         cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything
59                    * above [x]. Used for disposing of temporaries.
60                    */
61         cLog2by, /* log2by(x,y) = log2(x) * y */
62         cNop,    /* Used by fpoptimizer internally; should not occur in bytecode */
63 #endif
64         cSinCos, /* sin(x) followed by cos(x) (two values are pushed to stack) */
65         cAbsAnd,    /* As cAnd,       but assume both operands are absolute values */
66         cAbsOr,     /* As cOr,        but assume both operands are absolute values */
67         cAbsNot,    /* As cAbsNot,    but assume the operand is an absolute value */
68         cAbsNotNot, /* As cAbsNotNot, but assume the operand is an absolute value */
69         cAbsIf,     /* As cAbsIf,     but assume the 1st operand is an absolute value */
70
71         cDup,   /* Duplicates the last value in the stack: Push [Stacktop] */
72         cFetch, /* Same as Dup, except with absolute index
73                  * (next value is index) */
74         cInv,   /* Inverts the last value in the stack (x = 1/x) */
75         cSqr,   /* squares the last operand in the stack, no push/pop */
76         cRDiv,  /* reverse division (not x/y, but y/x) */
77         cRSub,  /* reverse subtraction (not x-y, but y-x) */
78         cRSqrt, /* inverse square-root (1/sqrt(x)) */
79
80         VarBegin
81     };
82
83 #ifdef ONCE_FPARSER_H_
84     struct FuncDefinition
85     {
86         enum FunctionFlags
87         {
88             Enabled  = 0x01,
89             AngleIn  = 0x02,
90             AngleOut = 0x04,
91             OkForInt = 0x08
92         };
93
94 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
95         const char name[8];
96 #else
97         struct name { } name;
98 #endif
99         unsigned params : 8;
100         unsigned flags  : 8;
101
102         inline bool enabled() const { return flags != 0; }
103         inline bool okForInt() const { return (flags & OkForInt) != 0; }
104     };
105
106 #ifndef FP_DISABLE_EVAL
107 # define FP_EVAL_FUNCTION_ENABLED \
108     FuncDefinition::Enabled | FuncDefinition::OkForInt
109 #else
110 # define FP_EVAL_FUNCTION_ENABLED 0
111 #endif
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,
123                      FuncDefinition::Enabled | FuncDefinition::OkForInt },
124         /*cAcos */ { FP_FNAME("acos"),  1,
125                      FuncDefinition::Enabled | FuncDefinition::AngleOut },
126         /*cAcosh*/ { FP_FNAME("acosh"), 1,
127                      FuncDefinition::Enabled | FuncDefinition::AngleOut },
128         /*cAsin */ { FP_FNAME("asin"),  1,
129                      FuncDefinition::Enabled | FuncDefinition::AngleOut },
130         /*cAsinh*/ { FP_FNAME("asinh"), 1,
131                      FuncDefinition::Enabled | FuncDefinition::AngleOut },
132         /*cAtan */ { FP_FNAME("atan"),  1,
133                      FuncDefinition::Enabled | FuncDefinition::AngleOut },
134         /*cAtan2*/ { FP_FNAME("atan2"), 2,
135                      FuncDefinition::Enabled | FuncDefinition::AngleOut },
136         /*cAtanh*/ { FP_FNAME("atanh"), 1, FuncDefinition::Enabled },
137         /*cCbrt */ { FP_FNAME("cbrt"),  1, FuncDefinition::Enabled },
138         /*cCeil */ { FP_FNAME("ceil"),  1, FuncDefinition::Enabled },
139         /*cCos  */ { FP_FNAME("cos"),   1,
140                      FuncDefinition::Enabled | FuncDefinition::AngleIn },
141         /*cCosh */ { FP_FNAME("cosh"),  1,
142                      FuncDefinition::Enabled | FuncDefinition::AngleIn },
143         /*cCot  */ { FP_FNAME("cot"),   1,
144                      FuncDefinition::Enabled | FuncDefinition::AngleIn },
145         /*cCsc  */ { FP_FNAME("csc"),   1,
146                      FuncDefinition::Enabled | FuncDefinition::AngleIn },
147         /*cEval */ { FP_FNAME("eval"),  0, FP_EVAL_FUNCTION_ENABLED },
148         /*cExp  */ { FP_FNAME("exp"),   1, FuncDefinition::Enabled },
149         /*cExp2 */ { FP_FNAME("exp2"),  1, FuncDefinition::Enabled },
150         /*cFloor*/ { FP_FNAME("floor"), 1, FuncDefinition::Enabled },
151         /*cHypot*/ { FP_FNAME("hypot"), 2, FuncDefinition::Enabled },
152         /*cIf   */ { FP_FNAME("if"),    0,
153                      FuncDefinition::Enabled | FuncDefinition::OkForInt },
154         /*cInt  */ { FP_FNAME("int"),   1, FuncDefinition::Enabled },
155         /*cLog  */ { FP_FNAME("log"),   1, FuncDefinition::Enabled },
156         /*cLog10*/ { FP_FNAME("log10"), 1, FuncDefinition::Enabled },
157         /*cLog2 */ { FP_FNAME("log2"),  1, FuncDefinition::Enabled },
158         /*cMax  */ { FP_FNAME("max"),   2,
159                      FuncDefinition::Enabled | FuncDefinition::OkForInt },
160         /*cMin  */ { FP_FNAME("min"),   2,
161                      FuncDefinition::Enabled | FuncDefinition::OkForInt },
162         /*cPow  */ { FP_FNAME("pow"),   2, FuncDefinition::Enabled },
163         /*cSec  */ { FP_FNAME("sec"),   1,
164                      FuncDefinition::Enabled | FuncDefinition::AngleIn },
165         /*cSin  */ { FP_FNAME("sin"),   1,
166                      FuncDefinition::Enabled | FuncDefinition::AngleIn },
167         /*cSinh */ { FP_FNAME("sinh"),  1,
168                      FuncDefinition::Enabled | FuncDefinition::AngleIn },
169         /*cSqrt */ { FP_FNAME("sqrt"),  1,
170                      FuncDefinition::Enabled },
171         /*cTan  */ { FP_FNAME("tan"),   1,
172                      FuncDefinition::Enabled | FuncDefinition::AngleIn },
173         /*cTanh */ { FP_FNAME("tanh"),  1,
174                      FuncDefinition::Enabled | FuncDefinition::AngleIn },
175         /*cTrunc*/ { FP_FNAME("trunc"), 1,
176                      FuncDefinition::Enabled }
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     unsigned mVariablesAmount;
238     std::string mVariablesString;
239     FUNCTIONPARSERTYPES::NamePtrsMap<Value_t> mNamePtrs;
240
241     struct InlineVariable
242     {
243         FUNCTIONPARSERTYPES::NamePtr mName;
244         unsigned mFetchIndex;
245     };
246
247     typedef std::vector<InlineVariable> InlineVarNamesContainer;
248     InlineVarNamesContainer mInlineVarNames;
249
250     struct FuncPtrData
251     {
252         union
253         {
254             FunctionPtr mFuncPtr;
255             FunctionParserBase<Value_t>* mParserPtr;
256         };
257         unsigned mParams;
258     };
259
260     std::vector<FuncPtrData> mFuncPtrs;
261     std::vector<FuncPtrData> mFuncParsers;
262
263     std::vector<unsigned> mByteCode;
264     std::vector<Value_t> mImmed;
265 #if !defined(FP_USE_THREAD_SAFE_EVAL) && \
266     !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA)
267     std::vector<Value_t> mStack;
268     // Note: When mStack exists,
269     //       mStack.size() and mStackSize are mutually redundant.
270 #endif
271     unsigned mStackSize;
272
273     Data();
274     Data(const Data&);
275     Data& operator=(const Data&); // not implemented on purpose
276     ~Data();
277 };
278 #endif
279
280 #include "fpaux.hh"
281
282 #endif