1 /***************************************************************************\
2 |* Function Parser for C++ v4.3 *|
3 |*-------------------------------------------------------------------------*|
4 |* Copyright: Juha Nieminen, Joel Yliluoma *|
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 \***************************************************************************/
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"
16 #ifndef ONCE_FPARSER_TYPES_H_
17 #define ONCE_FPARSER_TYPES_H_
19 #include "fpconfig.hh"
22 #ifdef ONCE_FPARSER_H_
26 namespace FUNCTIONPARSERTYPES
30 // The order of opcodes in the function list must
31 // match that which is in the Functions[] array.
35 cAtan, cAtan2, cAtanh,
37 cCos, cCosh, cCot, cCsc,
39 cExp, cExp2, cFloor, cHypot,
40 cIf, cInt, cLog, cLog10, cLog2, cMax, cMin,
41 cPow, cSec, cSin, cSinh, cSqrt, cTan, cTanh,
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().
48 cNeg, cAdd, cSub, cMul, cDiv, cMod,
49 cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq,
51 cNotNot, /* Protects the double-not sequence from optimizations */
53 cDeg, cRad, /* Multiplication and division by 180 / pi */
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.
61 cLog2by, /* log2by(x,y) = log2(x) * y */
62 cNop, /* Used by fpoptimizer internally; should not occur in bytecode */
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 */
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)) */
83 #ifdef ONCE_FPARSER_H_
94 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
102 inline bool enabled() const { return flags != 0; }
103 inline bool okForInt() const { return (flags & OkForInt) != 0; }
106 #ifndef FP_DISABLE_EVAL
107 # define FP_EVAL_FUNCTION_ENABLED \
108 FuncDefinition::Enabled | FuncDefinition::OkForInt
110 # define FP_EVAL_FUNCTION_ENABLED 0
112 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
113 # define FP_FNAME(n) n
115 # define FP_FNAME(n) {}
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[]=
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 }
185 NamePtr(const char* n, unsigned l): name(n), nameLength(l) {}
187 inline bool operator==(const NamePtr& rhs) const
189 return nameLength == rhs.nameLength
190 && std::memcmp(name, rhs.name, nameLength) == 0;
192 inline bool operator<(const NamePtr& rhs) const
194 for(unsigned i = 0; i < nameLength; ++i)
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;
201 return nameLength < rhs.nameLength;
205 template<typename Value_t>
208 enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE };
213 NameData(DataType t, unsigned v) : type(t), index(v), value() { }
214 NameData(DataType t, Value_t v) : type(t), index(), value(v) { }
218 template<typename Value_t>
219 class NamePtrsMap: public
220 std::map<FUNCTIONPARSERTYPES::NamePtr,
221 FUNCTIONPARSERTYPES::NameData<Value_t> >
225 const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]);
226 #endif // ONCE_FPARSER_H_
229 #ifdef ONCE_FPARSER_H_
232 template<typename Value_t>
233 struct FunctionParserBase<Value_t>::Data
235 unsigned mReferenceCounter;
237 unsigned mVariablesAmount;
238 std::string mVariablesString;
239 FUNCTIONPARSERTYPES::NamePtrsMap<Value_t> mNamePtrs;
241 struct InlineVariable
243 FUNCTIONPARSERTYPES::NamePtr mName;
244 unsigned mFetchIndex;
247 typedef std::vector<InlineVariable> InlineVarNamesContainer;
248 InlineVarNamesContainer mInlineVarNames;
254 FunctionPtr mFuncPtr;
255 FunctionParserBase<Value_t>* mParserPtr;
260 std::vector<FuncPtrData> mFuncPtrs;
261 std::vector<FuncPtrData> mFuncParsers;
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.
275 Data& operator=(const Data&); // not implemented on purpose