summaryrefslogtreecommitdiff
path: root/fparser/extrasrc/fptypes.hh
diff options
context:
space:
mode:
Diffstat (limited to 'fparser/extrasrc/fptypes.hh')
-rw-r--r--fparser/extrasrc/fptypes.hh288
1 files changed, 288 insertions, 0 deletions
diff --git a/fparser/extrasrc/fptypes.hh b/fparser/extrasrc/fptypes.hh
new file mode 100644
index 0000000..159903b
--- /dev/null
+++ b/fparser/extrasrc/fptypes.hh
@@ -0,0 +1,288 @@
+/***************************************************************************\
+|* Function Parser for C++ v4.5.1 *|
+|*-------------------------------------------------------------------------*|
+|* Copyright: Juha Nieminen, Joel Yliluoma *|
+|* *|
+|* This library is distributed under the terms of the *|
+|* GNU Lesser General Public License version 3. *|
+|* (See lgpl.txt and gpl.txt for the license text.) *|
+\***************************************************************************/
+
+// NOTE:
+// This file contains only internal types for the function parser library.
+// You don't need to include this file in your code. Include "fparser.hh"
+// only.
+
+#ifndef ONCE_FPARSER_TYPES_H_
+#define ONCE_FPARSER_TYPES_H_
+
+#include "../fpconfig.hh"
+#include <cstring>
+
+#ifdef ONCE_FPARSER_H_
+#include <map>
+#endif
+
+namespace FUNCTIONPARSERTYPES
+{
+ enum OPCODE
+ {
+// The order of opcodes in the function list must
+// match that which is in the Functions[] array.
+ cAbs,
+ cAcos, cAcosh,
+ cArg, /* get the phase angle of a complex value */
+ cAsin, cAsinh,
+ cAtan, cAtan2, cAtanh,
+ cCbrt, cCeil,
+ cConj, /* get the complex conjugate of a complex value */
+ cCos, cCosh, cCot, cCsc,
+ cExp, cExp2, cFloor, cHypot,
+ cIf,
+ cImag, /* get imaginary part of a complex value */
+ cInt, cLog, cLog10, cLog2, cMax, cMin,
+ cPolar, /* create a complex number from polar coordinates */
+ cPow,
+ cReal, /* get real part of a complex value */
+ cSec, cSin, cSinh, cSqrt, cTan, cTanh,
+ cTrunc,
+
+// These do not need any ordering:
+// Except that if you change the order of {eq,neq,lt,le,gt,ge}, you
+// must also change the order in ConstantFolding_ComparisonOperations().
+ cImmed, cJump,
+ cNeg, cAdd, cSub, cMul, cDiv, cMod,
+ cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq,
+ cNot, cAnd, cOr,
+ cNotNot, /* Protects the double-not sequence from optimizations */
+
+ cDeg, cRad, /* Multiplication and division by 180 / pi */
+
+ cFCall, cPCall,
+
+#ifdef FP_SUPPORT_OPTIMIZER
+ cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything
+ * above [x]. Used for disposing of temporaries.
+ */
+ cLog2by, /* log2by(x,y) = log2(x) * y */
+ cNop, /* Used by fpoptimizer internally; should not occur in bytecode */
+#endif
+ cSinCos, /* sin(x) followed by cos(x) (two values are pushed to stack) */
+ cSinhCosh, /* hyperbolic equivalent of sincos */
+ cAbsAnd, /* As cAnd, but assume both operands are absolute values */
+ cAbsOr, /* As cOr, but assume both operands are absolute values */
+ cAbsNot, /* As cAbsNot, but assume the operand is an absolute value */
+ cAbsNotNot, /* As cAbsNotNot, but assume the operand is an absolute value */
+ cAbsIf, /* As cAbsIf, but assume the 1st operand is an absolute value */
+
+ cDup, /* Duplicates the last value in the stack: Push [Stacktop] */
+ cFetch, /* Same as Dup, except with absolute index
+ * (next value is index) */
+ cInv, /* Inverts the last value in the stack (x = 1/x) */
+ cSqr, /* squares the last operand in the stack, no push/pop */
+ cRDiv, /* reverse division (not x/y, but y/x) */
+ cRSub, /* reverse subtraction (not x-y, but y-x) */
+ cRSqrt, /* inverse square-root (1/sqrt(x)) */
+
+ VarBegin
+ };
+
+#ifdef ONCE_FPARSER_H_
+ struct FuncDefinition
+ {
+ enum FunctionFlags
+ {
+ Enabled = 0x01,
+ AngleIn = 0x02,
+ AngleOut = 0x04,
+ OkForInt = 0x08,
+ ComplexOnly = 0x10
+ };
+
+#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
+ const char name[8];
+#else
+ struct name { } name;
+#endif
+ unsigned params : 8;
+ unsigned flags : 8;
+
+ inline bool okForInt() const { return (flags & OkForInt) != 0; }
+ inline bool complexOnly() const { return (flags & ComplexOnly) != 0; }
+ };
+
+#ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
+# define FP_FNAME(n) n
+#else
+# define FP_FNAME(n) {}
+#endif
+// This list must be in the same order as that in OPCODE enum,
+// because the opcode value is used to index this array, and
+// the pointer to array element is used for generating the opcode.
+ const FuncDefinition Functions[]=
+ {
+ /*cAbs */ { FP_FNAME("abs"), 1, FuncDefinition::OkForInt },
+ /*cAcos */ { FP_FNAME("acos"), 1, FuncDefinition::AngleOut },
+ /*cAcosh*/ { FP_FNAME("acosh"), 1, FuncDefinition::AngleOut },
+ /*cArg */ { FP_FNAME("arg"), 1, FuncDefinition::AngleOut | FuncDefinition::ComplexOnly },
+ /*cAsin */ { FP_FNAME("asin"), 1, FuncDefinition::AngleOut },
+ /*cAsinh*/ { FP_FNAME("asinh"), 1, FuncDefinition::AngleOut },
+ /*cAtan */ { FP_FNAME("atan"), 1, FuncDefinition::AngleOut },
+ /*cAtan2*/ { FP_FNAME("atan2"), 2, FuncDefinition::AngleOut },
+ /*cAtanh*/ { FP_FNAME("atanh"), 1, 0 },
+ /*cCbrt */ { FP_FNAME("cbrt"), 1, 0 },
+ /*cCeil */ { FP_FNAME("ceil"), 1, 0 },
+ /*cConj */ { FP_FNAME("conj"), 1, FuncDefinition::ComplexOnly },
+ /*cCos */ { FP_FNAME("cos"), 1, FuncDefinition::AngleIn },
+ /*cCosh */ { FP_FNAME("cosh"), 1, FuncDefinition::AngleIn },
+ /*cCot */ { FP_FNAME("cot"), 1, FuncDefinition::AngleIn },
+ /*cCsc */ { FP_FNAME("csc"), 1, FuncDefinition::AngleIn },
+ /*cExp */ { FP_FNAME("exp"), 1, 0 },
+ /*cExp2 */ { FP_FNAME("exp2"), 1, 0 },
+ /*cFloor*/ { FP_FNAME("floor"), 1, 0 },
+ /*cHypot*/ { FP_FNAME("hypot"), 2, 0 },
+ /*cIf */ { FP_FNAME("if"), 0, FuncDefinition::OkForInt },
+ /*cImag */ { FP_FNAME("imag"), 1, FuncDefinition::ComplexOnly },
+ /*cInt */ { FP_FNAME("int"), 1, 0 },
+ /*cLog */ { FP_FNAME("log"), 1, 0 },
+ /*cLog10*/ { FP_FNAME("log10"), 1, 0 },
+ /*cLog2 */ { FP_FNAME("log2"), 1, 0 },
+ /*cMax */ { FP_FNAME("max"), 2, FuncDefinition::OkForInt },
+ /*cMin */ { FP_FNAME("min"), 2, FuncDefinition::OkForInt },
+ /*cPolar */{ FP_FNAME("polar"), 2, FuncDefinition::ComplexOnly | FuncDefinition::AngleIn },
+ /*cPow */ { FP_FNAME("pow"), 2, 0 },
+ /*cReal */ { FP_FNAME("real"), 1, FuncDefinition::ComplexOnly },
+ /*cSec */ { FP_FNAME("sec"), 1, FuncDefinition::AngleIn },
+ /*cSin */ { FP_FNAME("sin"), 1, FuncDefinition::AngleIn },
+ /*cSinh */ { FP_FNAME("sinh"), 1, FuncDefinition::AngleIn },
+ /*cSqrt */ { FP_FNAME("sqrt"), 1, 0 },
+ /*cTan */ { FP_FNAME("tan"), 1, FuncDefinition::AngleIn },
+ /*cTanh */ { FP_FNAME("tanh"), 1, FuncDefinition::AngleIn },
+ /*cTrunc*/ { FP_FNAME("trunc"), 1, 0 }
+ };
+#undef FP_FNAME
+
+ struct NamePtr
+ {
+ const char* name;
+ unsigned nameLength;
+
+ NamePtr(const char* n, unsigned l): name(n), nameLength(l) {}
+
+ inline bool operator==(const NamePtr& rhs) const
+ {
+ return nameLength == rhs.nameLength
+ && std::memcmp(name, rhs.name, nameLength) == 0;
+ }
+ inline bool operator<(const NamePtr& rhs) const
+ {
+ for(unsigned i = 0; i < nameLength; ++i)
+ {
+ if(i == rhs.nameLength) return false;
+ const char c1 = name[i], c2 = rhs.name[i];
+ if(c1 < c2) return true;
+ if(c2 < c1) return false;
+ }
+ return nameLength < rhs.nameLength;
+ }
+ };
+
+ template<typename Value_t>
+ struct NameData
+ {
+ enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE };
+ DataType type;
+ unsigned index;
+ Value_t value;
+
+ NameData(DataType t, unsigned v) : type(t), index(v), value() { }
+ NameData(DataType t, Value_t v) : type(t), index(), value(v) { }
+ NameData() { }
+ };
+
+ template<typename Value_t>
+ class NamePtrsMap: public
+ std::map<FUNCTIONPARSERTYPES::NamePtr,
+ FUNCTIONPARSERTYPES::NameData<Value_t> >
+ {
+ };
+
+ const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]);
+#endif // ONCE_FPARSER_H_
+}
+
+#ifdef ONCE_FPARSER_H_
+#include <vector>
+
+template<typename Value_t>
+struct FunctionParserBase<Value_t>::Data
+{
+ unsigned mReferenceCounter;
+
+ char mDelimiterChar;
+ ParseErrorType mParseErrorType;
+ int mEvalErrorType;
+ bool mUseDegreeConversion;
+ bool mHasByteCodeFlags;
+ const char* mErrorLocation;
+
+ unsigned mVariablesAmount;
+ std::string mVariablesString;
+ FUNCTIONPARSERTYPES::NamePtrsMap<Value_t> mNamePtrs;
+
+ struct InlineVariable
+ {
+ FUNCTIONPARSERTYPES::NamePtr mName;
+ unsigned mFetchIndex;
+ };
+
+ typedef std::vector<InlineVariable> InlineVarNamesContainer;
+ InlineVarNamesContainer mInlineVarNames;
+
+ struct FuncWrapperPtrData
+ {
+ /* Only one of the pointers will point to a function, the other
+ will be null. (The raw function pointer could be implemented
+ as a FunctionWrapper specialization, but it's done like this
+ for efficiency.) */
+ FunctionPtr mRawFuncPtr;
+ FunctionWrapper* mFuncWrapperPtr;
+ unsigned mParams;
+
+ FuncWrapperPtrData();
+ ~FuncWrapperPtrData();
+ FuncWrapperPtrData(const FuncWrapperPtrData&);
+ FuncWrapperPtrData& operator=(const FuncWrapperPtrData&);
+ };
+
+ struct FuncParserPtrData
+ {
+ FunctionParserBase<Value_t>* mParserPtr;
+ unsigned mParams;
+ };
+
+ std::vector<FuncWrapperPtrData> mFuncPtrs;
+ std::vector<FuncParserPtrData> mFuncParsers;
+
+ std::vector<unsigned> mByteCode;
+ std::vector<Value_t> mImmed;
+
+#if !defined(FP_USE_THREAD_SAFE_EVAL) && \
+ !defined(FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA)
+ std::vector<Value_t> mStack;
+ // Note: When mStack exists,
+ // mStack.size() and mStackSize are mutually redundant.
+#endif
+
+ unsigned mStackSize;
+
+ Data();
+ Data(const Data&);
+ Data& operator=(const Data&); // not implemented on purpose
+ ~Data();
+};
+#endif
+
+//#include "fpaux.hh"
+
+#endif