Used qreal for datatype. Deleted _T() macros.

--HG--
branch : feature
This commit is contained in:
dismine 2014-04-25 18:01:23 +03:00
parent 0b4d69f821
commit 11f527143b
17 changed files with 1224 additions and 1243 deletions

View file

@ -49,78 +49,78 @@ namespace qmu
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Trigonometric function // Trigonometric function
value_type QmuParser::Sin(value_type v) { return MathImpl<value_type>::Sin(v); } qreal QmuParser::Sin(qreal v) { return MathImpl<qreal>::Sin(v); }
value_type QmuParser::Cos(value_type v) { return MathImpl<value_type>::Cos(v); } qreal QmuParser::Cos(qreal v) { return MathImpl<qreal>::Cos(v); }
value_type QmuParser::Tan(value_type v) { return MathImpl<value_type>::Tan(v); } qreal QmuParser::Tan(qreal v) { return MathImpl<qreal>::Tan(v); }
value_type QmuParser::ASin(value_type v) { return MathImpl<value_type>::ASin(v); } qreal QmuParser::ASin(qreal v) { return MathImpl<qreal>::ASin(v); }
value_type QmuParser::ACos(value_type v) { return MathImpl<value_type>::ACos(v); } qreal QmuParser::ACos(qreal v) { return MathImpl<qreal>::ACos(v); }
value_type QmuParser::ATan(value_type v) { return MathImpl<value_type>::ATan(v); } qreal QmuParser::ATan(qreal v) { return MathImpl<qreal>::ATan(v); }
value_type QmuParser::ATan2(value_type v1, value_type v2) { return MathImpl<value_type>::ATan2(v1, v2); } qreal QmuParser::ATan2(qreal v1, qreal v2) { return MathImpl<qreal>::ATan2(v1, v2); }
value_type QmuParser::Sinh(value_type v) { return MathImpl<value_type>::Sinh(v); } qreal QmuParser::Sinh(qreal v) { return MathImpl<qreal>::Sinh(v); }
value_type QmuParser::Cosh(value_type v) { return MathImpl<value_type>::Cosh(v); } qreal QmuParser::Cosh(qreal v) { return MathImpl<qreal>::Cosh(v); }
value_type QmuParser::Tanh(value_type v) { return MathImpl<value_type>::Tanh(v); } qreal QmuParser::Tanh(qreal v) { return MathImpl<qreal>::Tanh(v); }
value_type QmuParser::ASinh(value_type v) { return MathImpl<value_type>::ASinh(v); } qreal QmuParser::ASinh(qreal v) { return MathImpl<qreal>::ASinh(v); }
value_type QmuParser::ACosh(value_type v) { return MathImpl<value_type>::ACosh(v); } qreal QmuParser::ACosh(qreal v) { return MathImpl<qreal>::ACosh(v); }
value_type QmuParser::ATanh(value_type v) { return MathImpl<value_type>::ATanh(v); } qreal QmuParser::ATanh(qreal v) { return MathImpl<qreal>::ATanh(v); }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Logarithm functions // Logarithm functions
// Logarithm base 2 // Logarithm base 2
value_type QmuParser::Log2(value_type v) qreal QmuParser::Log2(qreal v)
{ {
#ifdef MUP_MATH_EXCEPTIONS #ifdef MUP_MATH_EXCEPTIONS
if (v<=0) if (v<=0)
throw QmuParserError(ecDOMAIN_ERROR, _T("Log2")); throw QmuParserError(ecDOMAIN_ERROR, "Log2");
#endif #endif
return MathImpl<value_type>::Log2(v); return MathImpl<qreal>::Log2(v);
} }
// Logarithm base 10 // Logarithm base 10
value_type QmuParser::Log10(value_type v) qreal QmuParser::Log10(qreal v)
{ {
#ifdef MUP_MATH_EXCEPTIONS #ifdef MUP_MATH_EXCEPTIONS
if (v<=0) if (v<=0)
throw QmuParserError(ecDOMAIN_ERROR, _T("Log10")); throw QmuParserError(ecDOMAIN_ERROR, "Log10");
#endif #endif
return MathImpl<value_type>::Log10(v); return MathImpl<qreal>::Log10(v);
} }
// Logarithm base e (natural logarithm) // Logarithm base e (natural logarithm)
value_type QmuParser::Ln(value_type v) qreal QmuParser::Ln(qreal v)
{ {
#ifdef MUP_MATH_EXCEPTIONS #ifdef MUP_MATH_EXCEPTIONS
if (v<=0) if (v<=0)
throw QmuParserError(ecDOMAIN_ERROR, _T("Ln")); throw QmuParserError(ecDOMAIN_ERROR, "Ln");
#endif #endif
return MathImpl<value_type>::Log(v); return MathImpl<qreal>::Log(v);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// misc // misc
value_type QmuParser::Exp(value_type v) { return MathImpl<value_type>::Exp(v); } qreal QmuParser::Exp(qreal v) { return MathImpl<qreal>::Exp(v); }
value_type QmuParser::Abs(value_type v) { return MathImpl<value_type>::Abs(v); } qreal QmuParser::Abs(qreal v) { return MathImpl<qreal>::Abs(v); }
value_type QmuParser::Sqrt(value_type v) qreal QmuParser::Sqrt(qreal v)
{ {
#ifdef MUP_MATH_EXCEPTIONS #ifdef MUP_MATH_EXCEPTIONS
if (v<0) if (v<0)
throw QmuParserError(ecDOMAIN_ERROR, _T("sqrt")); throw QmuParserError(ecDOMAIN_ERROR, "sqrt");
#endif #endif
return MathImpl<value_type>::Sqrt(v); return MathImpl<qreal>::Sqrt(v);
} }
value_type QmuParser::Rint(value_type v) { return MathImpl<value_type>::Rint(v); } qreal QmuParser::Rint(qreal v) { return MathImpl<qreal>::Rint(v); }
value_type QmuParser::Sign(value_type v) { return MathImpl<value_type>::Sign(v); } qreal QmuParser::Sign(qreal v) { return MathImpl<qreal>::Sign(v); }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/** \brief Callback for the unary minus operator. /** \brief Callback for the unary minus operator.
\param v The value to negate \param v The value to negate
\return -v \return -v
*/ */
value_type QmuParser::UnaryMinus(value_type v) qreal QmuParser::UnaryMinus(qreal v)
{ {
return -v; return -v;
} }
@ -130,12 +130,12 @@ namespace qmu
\param [in] a_afArg Vector with the function arguments \param [in] a_afArg Vector with the function arguments
\param [in] a_iArgc The size of a_afArg \param [in] a_iArgc The size of a_afArg
*/ */
value_type QmuParser::Sum(const value_type *a_afArg, int a_iArgc) qreal QmuParser::Sum(const qreal *a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw exception_type(_T("too few arguments for function sum.")); throw exception_type("too few arguments for function sum.");
value_type fRes=0; qreal fRes=0;
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i]; for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
return fRes; return fRes;
} }
@ -145,14 +145,14 @@ namespace qmu
\param [in] a_afArg Vector with the function arguments \param [in] a_afArg Vector with the function arguments
\param [in] a_iArgc The size of a_afArg \param [in] a_iArgc The size of a_afArg
*/ */
value_type QmuParser::Avg(const value_type *a_afArg, int a_iArgc) qreal QmuParser::Avg(const qreal *a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw exception_type(_T("too few arguments for function sum.")); throw exception_type("too few arguments for function sum.");
value_type fRes=0; qreal fRes=0;
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i]; for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
return fRes/(value_type)a_iArgc; return fRes/(qreal)a_iArgc;
} }
@ -161,12 +161,12 @@ namespace qmu
\param [in] a_afArg Vector with the function arguments \param [in] a_afArg Vector with the function arguments
\param [in] a_iArgc The size of a_afArg \param [in] a_iArgc The size of a_afArg
*/ */
value_type QmuParser::Min(const value_type *a_afArg, int a_iArgc) qreal QmuParser::Min(const qreal *a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw exception_type(_T("too few arguments for function min.")); throw exception_type("too few arguments for function min.");
value_type fRes=a_afArg[0]; qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i) for (int i=0; i<a_iArgc; ++i)
fRes = std::min(fRes, a_afArg[i]); fRes = std::min(fRes, a_afArg[i]);
@ -179,12 +179,12 @@ namespace qmu
\param [in] a_afArg Vector with the function arguments \param [in] a_afArg Vector with the function arguments
\param [in] a_iArgc The size of a_afArg \param [in] a_iArgc The size of a_afArg
*/ */
value_type QmuParser::Max(const value_type *a_afArg, int a_iArgc) qreal QmuParser::Max(const qreal *a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw exception_type(_T("too few arguments for function min.")); throw exception_type("too few arguments for function min.");
value_type fRes=a_afArg[0]; qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]); for (int i=0; i<a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]);
return fRes; return fRes;
@ -198,9 +198,9 @@ namespace qmu
\param [out] a_fVal Pointer where the value should be stored in case one is found. \param [out] a_fVal Pointer where the value should be stored in case one is found.
\return 1 if a value was found 0 otherwise. \return 1 if a value was found 0 otherwise.
*/ */
int QmuParser::IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal) int QmuParser::IsVal(const char_type* a_szExpr, int *a_iPos, qreal *a_fVal)
{ {
value_type fVal(0); qreal fVal(0);
stringstream_type stream(a_szExpr); stringstream_type stream(a_szExpr);
stream.seekg(0); // todo: check if this really is necessary stream.seekg(0); // todo: check if this really is necessary
@ -242,16 +242,16 @@ namespace qmu
*/ */
void QmuParser::InitCharSets() void QmuParser::InitCharSets()
{ {
DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") ); DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
DefineOprtChars( _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}") ); DefineOprtChars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}" );
DefineInfixOprtChars( _T("/+-*^?<>=#!$%&|~'_") ); DefineInfixOprtChars( "/+-*^?<>=#!$%&|~'_" );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/** \brief Initialize the default functions. */ /** \brief Initialize the default functions. */
void QmuParser::InitFun() void QmuParser::InitFun()
{ {
if (qmu::TypeInfo<qmu::value_type>::IsInteger()) if (qmu::TypeInfo<qreal>::IsInteger())
{ {
// When setting MUP_BASETYPE to an integer type // When setting MUP_BASETYPE to an integer type
// Place functions for dealing with integer values here // Place functions for dealing with integer values here
@ -262,38 +262,38 @@ namespace qmu
else else
{ {
// trigonometric functions // trigonometric functions
DefineFun(_T("sin"), Sin); DefineFun("sin", Sin);
DefineFun(_T("cos"), Cos); DefineFun("cos", Cos);
DefineFun(_T("tan"), Tan); DefineFun("tan", Tan);
// arcus functions // arcus functions
DefineFun(_T("asin"), ASin); DefineFun("asin", ASin);
DefineFun(_T("acos"), ACos); DefineFun("acos", ACos);
DefineFun(_T("atan"), ATan); DefineFun("atan", ATan);
DefineFun(_T("atan2"), ATan2); DefineFun("atan2", ATan2);
// hyperbolic functions // hyperbolic functions
DefineFun(_T("sinh"), Sinh); DefineFun("sinh", Sinh);
DefineFun(_T("cosh"), Cosh); DefineFun("cosh", Cosh);
DefineFun(_T("tanh"), Tanh); DefineFun("tanh", Tanh);
// arcus hyperbolic functions // arcus hyperbolic functions
DefineFun(_T("asinh"), ASinh); DefineFun("asinh", ASinh);
DefineFun(_T("acosh"), ACosh); DefineFun("acosh", ACosh);
DefineFun(_T("atanh"), ATanh); DefineFun("atanh", ATanh);
// Logarithm functions // Logarithm functions
DefineFun(_T("log2"), Log2); DefineFun("log2", Log2);
DefineFun(_T("log10"), Log10); DefineFun("log10", Log10);
DefineFun(_T("log"), Log10); DefineFun("log", Log10);
DefineFun(_T("ln"), Ln); DefineFun("ln", Ln);
// misc // misc
DefineFun(_T("exp"), Exp); DefineFun("exp", Exp);
DefineFun(_T("sqrt"), Sqrt); DefineFun("sqrt", Sqrt);
DefineFun(_T("sign"), Sign); DefineFun("sign", Sign);
DefineFun(_T("rint"), Rint); DefineFun("rint", Rint);
DefineFun(_T("abs"), Abs); DefineFun("abs", Abs);
// Functions with variable number of arguments // Functions with variable number of arguments
DefineFun(_T("sum"), Sum); DefineFun("sum", Sum);
DefineFun(_T("avg"), Avg); DefineFun("avg", Avg);
DefineFun(_T("min"), Min); DefineFun("min", Min);
DefineFun(_T("max"), Max); DefineFun("max", Max);
} }
} }
@ -305,8 +305,8 @@ namespace qmu
*/ */
void QmuParser::InitConst() void QmuParser::InitConst()
{ {
DefineConst(_T("_pi"), (value_type)QmuParser_CONST_PI); DefineConst("_pi", (qreal)QmuParser_CONST_PI);
DefineConst(_T("_e"), (value_type)QmuParser_CONST_E); DefineConst("_e", (qreal)QmuParser_CONST_E);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -316,7 +316,7 @@ namespace qmu
*/ */
void QmuParser::InitOprt() void QmuParser::InitOprt()
{ {
DefineInfixOprt(_T("-"), UnaryMinus); DefineInfixOprt("-", UnaryMinus);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -357,11 +357,11 @@ namespace qmu
http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843 http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843
*/ */
value_type QmuParser::Diff(value_type *a_Var, qreal QmuParser::Diff(qreal *a_Var,
value_type a_fPos, qreal a_fPos,
value_type a_fEpsilon) const qreal a_fEpsilon) const
{ {
value_type fRes(0), qreal fRes(0),
fBuf(*a_Var), fBuf(*a_Var),
f[4] = {0,0,0,0}, f[4] = {0,0,0,0},
fEpsilon(a_fEpsilon); fEpsilon(a_fEpsilon);
@ -369,7 +369,7 @@ namespace qmu
// Backwards compatible calculation of epsilon inc case the user doesnt provide // Backwards compatible calculation of epsilon inc case the user doesnt provide
// his own epsilon // his own epsilon
if (fEpsilon==0) if (fEpsilon==0)
fEpsilon = (a_fPos==0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos; fEpsilon = (a_fPos==0) ? (qreal)1e-10 : (qreal)1e-7 * a_fPos;
*a_Var = a_fPos+2 * fEpsilon; f[0] = Eval(); *a_Var = a_fPos+2 * fEpsilon; f[0] = Eval();
*a_Var = a_fPos+1 * fEpsilon; f[1] = Eval(); *a_Var = a_fPos+1 * fEpsilon; f[1] = Eval();

View file

@ -59,50 +59,50 @@ public:
virtual void InitOprt(); virtual void InitOprt();
virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd); virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);
value_type Diff(value_type *a_Var, value_type a_fPos, value_type a_fEpsilon = 0) const; qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const;
protected: protected:
// Trigonometric functions // Trigonometric functions
static value_type Sin(value_type); static qreal Sin(qreal);
static value_type Cos(value_type); static qreal Cos(qreal);
static value_type Tan(value_type); static qreal Tan(qreal);
static value_type Tan2(value_type, value_type); static qreal Tan2(qreal, qreal);
// arcus functions // arcus functions
static value_type ASin(value_type); static qreal ASin(qreal);
static value_type ACos(value_type); static qreal ACos(qreal);
static value_type ATan(value_type); static qreal ATan(qreal);
static value_type ATan2(value_type, value_type); static qreal ATan2(qreal, qreal);
// hyperbolic functions // hyperbolic functions
static value_type Sinh(value_type); static qreal Sinh(qreal);
static value_type Cosh(value_type); static qreal Cosh(qreal);
static value_type Tanh(value_type); static qreal Tanh(qreal);
// arcus hyperbolic functions // arcus hyperbolic functions
static value_type ASinh(value_type); static qreal ASinh(qreal);
static value_type ACosh(value_type); static qreal ACosh(qreal);
static value_type ATanh(value_type); static qreal ATanh(qreal);
// Logarithm functions // Logarithm functions
static value_type Log2(value_type); // Logarithm Base 2 static qreal Log2(qreal); // Logarithm Base 2
static value_type Log10(value_type); // Logarithm Base 10 static qreal Log10(qreal); // Logarithm Base 10
static value_type Ln(value_type); // Logarithm Base e (natural logarithm) static qreal Ln(qreal); // Logarithm Base e (natural logarithm)
// misc // misc
static value_type Exp(value_type); static qreal Exp(qreal);
static value_type Abs(value_type); static qreal Abs(qreal);
static value_type Sqrt(value_type); static qreal Sqrt(qreal);
static value_type Rint(value_type); static qreal Rint(qreal);
static value_type Sign(value_type); static qreal Sign(qreal);
// Prefix operators // Prefix operators
// !!! Unary Minus is a MUST if you want to use negative signs !!! // !!! Unary Minus is a MUST if you want to use negative signs !!!
static value_type UnaryMinus(value_type); static qreal UnaryMinus(qreal);
// Functions with variable number of arguments // Functions with variable number of arguments
static value_type Sum(const value_type*, int); // sum static qreal Sum(const qreal*, int); // sum
static value_type Avg(const value_type*, int); // mean value static qreal Avg(const qreal*, int); // mean value
static value_type Min(const value_type*, int); // minimum static qreal Min(const qreal*, int); // minimum
static value_type Max(const value_type*, int); // maximum static qreal Max(const qreal*, int); // maximum
static int IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal); static int IsVal(const char_type* a_szExpr, int *a_iPos, qreal *a_fVal);
}; };
} // namespace qmu } // namespace qmu

View file

@ -57,12 +57,12 @@ namespace qmu
*/ */
const char_type* QmuParserBase::c_DefaultOprt[] = const char_type* QmuParserBase::c_DefaultOprt[] =
{ {
_T("<="), _T(">="), _T("!="), "<=", ">=", "!=",
_T("=="), _T("<"), _T(">"), "==", "<", ">",
_T("+"), _T("-"), _T("*"), "+", "-", "*",
_T("/"), _T("^"), _T("&&"), "/", "^", "&&",
_T("||"), _T("="), _T("("), "||", "=", "(",
_T(")"), _T("?"), _T(":"), 0 ")", "?", ":", 0
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -270,38 +270,38 @@ namespace qmu
if (eInfo==pviFULL) if (eInfo==pviFULL)
{ {
ss << _T(" (") << MUP_VERSION_DATE; ss << " (" << MUP_VERSION_DATE;
ss << std::dec << _T("; ") << sizeof(void*)*8 << _T("BIT"); ss << std::dec << "; " << sizeof(void*)*8 << "BIT";
#ifdef _DEBUG #ifdef _DEBUG
ss << _T("; DEBUG"); ss << "; DEBUG";
#else #else
ss << _T("; RELEASE"); ss << "; RELEASE";
#endif #endif
#ifdef _UNICODE #ifdef _UNICODE
ss << _T("; UNICODE"); ss << "; UNICODE";
#else #else
#ifdef _MBCS #ifdef _MBCS
ss << _T("; MBCS"); ss << "; MBCS";
#else #else
ss << _T("; ASCII"); ss << "; ASCII";
#endif #endif
#endif #endif
#ifdef MUP_USE_OPENMP #ifdef QMUP_USE_OPENMP
ss << _T("; OPENMP"); ss << "; OPENMP";
//#else //#else
// ss << _T("; NO_OPENMP"); // ss << "; NO_OPENMP";
#endif #endif
#if defined(MUP_MATH_EXCEPTIONS) #if defined(MUP_MATH_EXCEPTIONS)
ss << _T("; MATHEXC"); ss << "; MATHEXC";
//#else //#else
// ss << _T("; NO_MATHEXC"); // ss << "; NO_MATHEXC";
#endif #endif
ss << _T(")"); ss << ")";
} }
return ss.str(); return ss.str();
@ -417,7 +417,7 @@ namespace qmu
// when calling tellg on a stringstream created from the expression after // when calling tellg on a stringstream created from the expression after
// reading a value at the end of an expression. (mu::Parser::IsVal function) // reading a value at the end of an expression. (mu::Parser::IsVal function)
// (tellg returns -1 otherwise causing the parser to ignore the value) // (tellg returns -1 otherwise causing the parser to ignore the value)
string_type sBuf(a_sExpr + _T(" ") ); string_type sBuf(a_sExpr + " " );
m_pTokenReader->SetFormula(sBuf); m_pTokenReader->SetFormula(sBuf);
ReInit(); ReInit();
} }
@ -589,7 +589,7 @@ namespace qmu
\post Will reset the Parser to string parsing mode. \post Will reset the Parser to string parsing mode.
\throw ParserException in case the name contains invalid signs or a_pVar is NULL. \throw ParserException in case the name contains invalid signs or a_pVar is NULL.
*/ */
void QmuParserBase::DefineVar(const string_type &a_sName, value_type *a_pVar) void QmuParserBase::DefineVar(const string_type &a_sName, qreal *a_pVar)
{ {
if (a_pVar==0) if (a_pVar==0)
Error(ecINVALID_VAR_PTR); Error(ecINVALID_VAR_PTR);
@ -610,7 +610,7 @@ namespace qmu
\post Will reset the Parser to string parsing mode. \post Will reset the Parser to string parsing mode.
\throw ParserException in case the name contains invalid signs. \throw ParserException in case the name contains invalid signs.
*/ */
void QmuParserBase::DefineConst(const string_type &a_sName, value_type a_fVal) void QmuParserBase::DefineConst(const string_type &a_sName, qreal a_fVal)
{ {
CheckName(a_sName, ValidNameChars()); CheckName(a_sName, ValidNameChars());
m_ConstDef[a_sName] = a_fVal; m_ConstDef[a_sName] = a_fVal;
@ -923,7 +923,7 @@ namespace qmu
if (optTok.GetCode()==cmASSIGN) if (optTok.GetCode()==cmASSIGN)
{ {
if (valTok2.GetCode()!=cmVAR) if (valTok2.GetCode()!=cmVAR)
Error(ecUNEXPECTED_OPERATOR, -1, _T("=")); Error(ecUNEXPECTED_OPERATOR, -1, "=");
m_vRPN.AddAssignOp(valTok2.GetVar()); m_vRPN.AddAssignOp(valTok2.GetVar());
} }
@ -990,7 +990,7 @@ namespace qmu
associated operators. The Stack is filled beginning from index one the associated operators. The Stack is filled beginning from index one the
value at index zero is not used at all. value at index zero is not used at all.
*/ */
value_type QmuParserBase::ParseCmdCode() const qreal QmuParserBase::ParseCmdCode() const
{ {
return ParseCmdCodeBulk(0, 0); return ParseCmdCodeBulk(0, 0);
} }
@ -1000,14 +1000,14 @@ namespace qmu
\param nOffset The offset added to variable addresses (for bulk mode) \param nOffset The offset added to variable addresses (for bulk mode)
\param nThreadID OpenMP Thread id of the calling thread \param nThreadID OpenMP Thread id of the calling thread
*/ */
value_type QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
{ {
assert(nThreadID<=s_MaxNumOpenMPThreads); assert(nThreadID<=s_MaxNumOpenMPThreads);
// Note: The check for nOffset==0 and nThreadID here is not necessary but // Note: The check for nOffset==0 and nThreadID here is not necessary but
// brings a minor performance gain when not in bulk mode. // brings a minor performance gain when not in bulk mode.
value_type *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)]; qreal *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)];
value_type buf; qreal buf;
int sidx(0); int sidx(0);
for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok) for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok)
{ {
@ -1033,7 +1033,7 @@ namespace qmu
continue; continue;
case cmPOW: case cmPOW:
--sidx; Stack[sidx] = MathImpl<value_type>::Pow(Stack[sidx], Stack[1+sidx]); --sidx; Stack[sidx] = MathImpl<qreal>::Pow(Stack[sidx], Stack[1+sidx]);
continue; continue;
case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1]; continue; case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1]; continue;
@ -1208,7 +1208,7 @@ namespace qmu
case cmVAR: case cmVAR:
stVal.push(opt); stVal.push(opt);
m_vRPN.AddVar( static_cast<value_type*>(opt.GetVar()) ); m_vRPN.AddVar( static_cast<qreal*>(opt.GetVar()) );
break; break;
case cmVAL: case cmVAL:
@ -1415,7 +1415,7 @@ namespace qmu
pointer #m_pParseFormula will be changed to the second parse routine the pointer #m_pParseFormula will be changed to the second parse routine the
uses bytecode instead of string parsing. uses bytecode instead of string parsing.
*/ */
value_type QmuParserBase::ParseString() const qreal QmuParserBase::ParseString() const
{ {
try try
{ {
@ -1610,14 +1610,14 @@ namespace qmu
QmuParserStack<token_type> stOprt(a_stOprt), QmuParserStack<token_type> stOprt(a_stOprt),
stVal(a_stVal); stVal(a_stVal);
mu::console() << _T("\nValue stack:\n"); mu::console() << "\nValue stack:\n";
while ( !stVal.empty() ) while ( !stVal.empty() )
{ {
token_type val = stVal.pop(); token_type val = stVal.pop();
if (val.GetType()==tpSTR) if (val.GetType()==tpSTR)
mu::console() << _T(" \"") << val.GetAsString() << _T("\" "); mu::console() << " \"" << val.GetAsString() << "\" ";
else else
mu::console() << _T(" ") << val.GetVal() << _T(" "); mu::console() << " " << val.GetVal() << " ";
} }
mu::console() << "\nOperator stack:\n"; mu::console() << "\nOperator stack:\n";
@ -1625,37 +1625,37 @@ namespace qmu
{ {
if (stOprt.top().GetCode()<=cmASSIGN) if (stOprt.top().GetCode()<=cmASSIGN)
{ {
mu::console() << _T("OPRT_INTRNL \"") mu::console() << "OPRT_INTRNL \""
<< QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()] << QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()]
<< _T("\" \n"); << "\" \n";
} }
else else
{ {
switch(stOprt.top().GetCode()) switch(stOprt.top().GetCode())
{ {
case cmVAR: mu::console() << _T("VAR\n"); break; case cmVAR: mu::console() << "VAR\n"; break;
case cmVAL: mu::console() << _T("VAL\n"); break; case cmVAL: mu::console() << "VAL\n"; break;
case cmFUNC: mu::console() << _T("FUNC \"") case cmFUNC: mu::console() << "FUNC \""
<< stOprt.top().GetAsString() << stOprt.top().GetAsString()
<< _T("\"\n"); break; << "\"\n"; break;
case cmFUNC_BULK: mu::console() << _T("FUNC_BULK \"") case cmFUNC_BULK: mu::console() << "FUNC_BULK \""
<< stOprt.top().GetAsString() << stOprt.top().GetAsString()
<< _T("\"\n"); break; << "\"\n"; break;
case cmOPRT_INFIX: mu::console() << _T("OPRT_INFIX \"") case cmOPRT_INFIX: mu::console() << "OPRT_INFIX \""
<< stOprt.top().GetAsString() << stOprt.top().GetAsString()
<< _T("\"\n"); break; << "\"\n"; break;
case cmOPRT_BIN: mu::console() << _T("OPRT_BIN \"") case cmOPRT_BIN: mu::console() << "OPRT_BIN \""
<< stOprt.top().GetAsString() << stOprt.top().GetAsString()
<< _T("\"\n"); break; << "\"\n"; break;
case cmFUNC_STR: mu::console() << _T("FUNC_STR\n"); break; case cmFUNC_STR: mu::console() << "FUNC_STR\n"; break;
case cmEND: mu::console() << _T("END\n"); break; case cmEND: mu::console() << "END\n"; break;
case cmUNKNOWN: mu::console() << _T("UNKNOWN\n"); break; case cmUNKNOWN: mu::console() << "UNKNOWN\n"; break;
case cmBO: mu::console() << _T("BRACKET \"(\"\n"); break; case cmBO: mu::console() << "BRACKET \"(\"\n"; break;
case cmBC: mu::console() << _T("BRACKET \")\"\n"); break; case cmBC: mu::console() << "BRACKET \")\"\n"; break;
case cmIF: mu::console() << _T("IF\n"); break; case cmIF: mu::console() << "IF\n"; break;
case cmELSE: mu::console() << _T("ELSE\n"); break; case cmELSE: mu::console() << "ELSE\n"; break;
case cmENDIF: mu::console() << _T("ENDIF\n"); break; case cmENDIF: mu::console() << "ENDIF\n"; break;
default: mu::console() << stOprt.top().GetCode() << _T(" "); break; default: mu::console() << stOprt.top().GetCode() << " "; break;
} }
} }
stOprt.pop(); stOprt.pop();
@ -1672,7 +1672,7 @@ namespace qmu
This member function can be used to retriev all results of an expression This member function can be used to retriev all results of an expression
made up of multiple comma seperated subexpressions (i.e. "x+y,sin(x),cos(y)") made up of multiple comma seperated subexpressions (i.e. "x+y,sin(x),cos(y)")
*/ */
value_type* QmuParserBase::Eval(int &nStackSize) const qreal* QmuParserBase::Eval(int &nStackSize) const
{ {
(this->*m_pParseFormula)(); (this->*m_pParseFormula)();
nStackSize = m_nFinalResultIdx; nStackSize = m_nFinalResultIdx;
@ -1709,13 +1709,13 @@ namespace qmu
\return The evaluation result \return The evaluation result
\throw ParseException if no Formula is set or in case of any other error related to the formula. \throw ParseException if no Formula is set or in case of any other error related to the formula.
*/ */
value_type QmuParserBase::Eval() const qreal QmuParserBase::Eval() const
{ {
return (this->*m_pParseFormula)(); return (this->*m_pParseFormula)();
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void QmuParserBase::Eval(value_type *results, int nBulkSize) void QmuParserBase::Eval(qreal *results, int nBulkSize)
{ {
CreateRPN(); CreateRPN();

View file

@ -68,10 +68,10 @@ private:
the function pointer to the parser function depending on the function pointer to the parser function depending on
which state it is in. (i.e. bytecode parser vs. string parser) which state it is in. (i.e. bytecode parser vs. string parser)
*/ */
typedef value_type (QmuParserBase::*ParseFunction)() const; typedef qreal (QmuParserBase::*ParseFunction)() const;
/** \brief Type used for storing an array of values. */ /** \brief Type used for storing an array of values. */
typedef std::vector<value_type> valbuf_type; typedef std::vector<qreal> valbuf_type;
/** \brief Type for a vector of strings. */ /** \brief Type for a vector of strings. */
typedef std::vector<string_type> stringbuf_type; typedef std::vector<string_type> stringbuf_type;
@ -80,7 +80,7 @@ private:
typedef QmuParserTokenReader token_reader_type; typedef QmuParserTokenReader token_reader_type;
/** \brief Type used for parser tokens. */ /** \brief Type used for parser tokens. */
typedef QmuParserToken<value_type, string_type> token_type; typedef QmuParserToken<qreal, string_type> token_type;
/** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */ /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */
static const int s_MaxNumOpenMPThreads = 4; static const int s_MaxNumOpenMPThreads = 4;
@ -101,9 +101,9 @@ private:
virtual ~QmuParserBase(); virtual ~QmuParserBase();
value_type Eval() const; qreal Eval() const;
value_type* Eval(int &nStackSize) const; qreal* Eval(int &nStackSize) const;
void Eval(value_type *results, int nBulkSize); void Eval(qreal *results, int nBulkSize);
int GetNumResults() const; int GetNumResults() const;
@ -137,9 +137,9 @@ private:
unsigned a_iPri=0, unsigned a_iPri=0,
EOprtAssociativity a_eAssociativity = oaLEFT, EOprtAssociativity a_eAssociativity = oaLEFT,
bool a_bAllowOpt = false); bool a_bAllowOpt = false);
void DefineConst(const string_type &a_sName, value_type a_fVal); void DefineConst(const string_type &a_sName, qreal a_fVal);
void DefineStrConst(const string_type &a_sName, const string_type &a_strVal); void DefineStrConst(const string_type &a_sName, const string_type &a_strVal);
void DefineVar(const string_type &a_sName, value_type *a_fVar); void DefineVar(const string_type &a_sName, qreal *a_fVar);
void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true); void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true); void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true);
@ -259,9 +259,9 @@ private:
void CreateRPN() const; void CreateRPN() const;
value_type ParseString() const; qreal ParseString() const;
value_type ParseCmdCode() const; qreal ParseCmdCode() const;
value_type ParseCmdCodeBulk(int nOffset, int nThreadID) const; qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
void CheckName(const string_type &a_strName, const string_type &a_CharSet) const; void CheckName(const string_type &a_strName, const string_type &a_CharSet) const;
void CheckOprt(const string_type &a_sName, void CheckOprt(const string_type &a_sName,

View file

@ -95,7 +95,7 @@ namespace qmu
\param a_pVar Pointer to be added. \param a_pVar Pointer to be added.
\throw nothrow \throw nothrow
*/ */
void QmuParserByteCode::AddVar(value_type *a_pVar) void QmuParserByteCode::AddVar(qreal *a_pVar)
{ {
++m_iStackPos; ++m_iStackPos;
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
@ -122,7 +122,7 @@ namespace qmu
\param a_pVal Value to be added. \param a_pVal Value to be added.
\throw nothrow \throw nothrow
*/ */
void QmuParserByteCode::AddVal(value_type a_fVal) void QmuParserByteCode::AddVal(qreal a_fVal)
{ {
++m_iStackPos; ++m_iStackPos;
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos); m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
@ -140,7 +140,7 @@ namespace qmu
void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt) void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt)
{ {
std::size_t sz = m_vRPN.size(); std::size_t sz = m_vRPN.size();
value_type &x = m_vRPN[sz-2].Val.data2, qreal &x = m_vRPN[sz-2].Val.data2,
&y = m_vRPN[sz-1].Val.data2; &y = m_vRPN[sz-1].Val.data2;
switch (a_Oprt) switch (a_Oprt)
{ {
@ -159,14 +159,14 @@ namespace qmu
#if defined(MUP_MATH_EXCEPTIONS) #if defined(MUP_MATH_EXCEPTIONS)
if (y==0) if (y==0)
throw ParserError(ecDIV_BY_ZERO, _T("0")); throw ParserError(ecDIV_BY_ZERO, "0");
#endif #endif
x = x / y; x = x / y;
m_vRPN.pop_back(); m_vRPN.pop_back();
break; break;
case cmPOW: x = MathImpl<value_type>::Pow(x, y); case cmPOW: x = MathImpl<qreal>::Pow(x, y);
m_vRPN.pop_back(); m_vRPN.pop_back();
break; break;
@ -243,7 +243,7 @@ namespace qmu
(m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ); (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) );
m_vRPN[sz-2].Cmd = cmVARMUL; m_vRPN[sz-2].Cmd = cmVARMUL;
m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); // variable m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); // variable
m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2; // offset
m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior m_vRPN[sz-2].Val.data += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data; // multiplikatior
m_vRPN.pop_back(); m_vRPN.pop_back();
@ -256,7 +256,7 @@ namespace qmu
(m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) )
{ {
m_vRPN[sz-2].Cmd = cmVARMUL; m_vRPN[sz-2].Cmd = cmVARMUL;
m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));
m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2; m_vRPN[sz-2].Val.data = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2;
m_vRPN[sz-2].Val.data2 = 0; m_vRPN[sz-2].Val.data2 = 0;
m_vRPN.pop_back(); m_vRPN.pop_back();
@ -267,7 +267,7 @@ namespace qmu
{ {
// Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2 // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2
m_vRPN[sz-2].Cmd = cmVARMUL; m_vRPN[sz-2].Cmd = cmVARMUL;
m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr)); m_vRPN[sz-2].Val.ptr = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));
if (m_vRPN[sz-1].Cmd == cmVAL) if (m_vRPN[sz-1].Cmd == cmVAL)
{ {
m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2; m_vRPN[sz-2].Val.data *= m_vRPN[sz-1].Val.data2;
@ -335,7 +335,7 @@ namespace qmu
\sa ParserToken::ECmdCode \sa ParserToken::ECmdCode
*/ */
void QmuParserByteCode::AddAssignOp(value_type *a_pVar) void QmuParserByteCode::AddAssignOp(qreal *a_pVar)
{ {
--m_iStackPos; --m_iStackPos;
@ -495,89 +495,89 @@ namespace qmu
{ {
if (!m_vRPN.size()) if (!m_vRPN.size())
{ {
mu::console() << _T("No bytecode available\n"); mu::console() << "No bytecode available\n";
return; return;
} }
mu::console() << _T("Number of RPN tokens:") << (int)m_vRPN.size() << _T("\n"); mu::console() << "Number of RPN tokens:" << (int)m_vRPN.size() << "\n";
for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i) for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i)
{ {
mu::console() << std::dec << i << _T(" : \t"); mu::console() << std::dec << i << " : \t";
switch (m_vRPN[i].Cmd) switch (m_vRPN[i].Cmd)
{ {
case cmVAL: mu::console() << _T("VAL \t"); case cmVAL: mu::console() << "VAL \t";
mu::console() << _T("[") << m_vRPN[i].Val.data2 << _T("]\n"); mu::console() << "[" << m_vRPN[i].Val.data2 << "]\n";
break; break;
case cmVAR: mu::console() << _T("VAR \t"); case cmVAR: mu::console() << "VAR \t";
mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
break; break;
case cmVARPOW2: mu::console() << _T("VARPOW2 \t"); case cmVARPOW2: mu::console() << "VARPOW2 \t";
mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
break; break;
case cmVARPOW3: mu::console() << _T("VARPOW3 \t"); case cmVARPOW3: mu::console() << "VARPOW3 \t";
mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
break; break;
case cmVARPOW4: mu::console() << _T("VARPOW4 \t"); case cmVARPOW4: mu::console() << "VARPOW4 \t";
mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]\n";
break; break;
case cmVARMUL: mu::console() << _T("VARMUL \t"); case cmVARMUL: mu::console() << "VARMUL \t";
mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]"); mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Val.ptr << "]";
mu::console() << _T(" * [") << m_vRPN[i].Val.data << _T("]"); mu::console() << " * [" << m_vRPN[i].Val.data << "]";
mu::console() << _T(" + [") << m_vRPN[i].Val.data2 << _T("]\n"); mu::console() << " + [" << m_vRPN[i].Val.data2 << "]\n";
break; break;
case cmFUNC: mu::console() << _T("CALL\t"); case cmFUNC: mu::console() << "CALL\t";
mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]"); mu::console() << "[ARG:" << std::dec << m_vRPN[i].Fun.argc << "]";
mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Fun.ptr << _T("]"); mu::console() << "[ADDR: 0x" << std::hex << m_vRPN[i].Fun.ptr << "]";
mu::console() << _T("\n"); mu::console() << "\n";
break; break;
case cmFUNC_STR: case cmFUNC_STR:
mu::console() << _T("CALL STRFUNC\t"); mu::console() << "CALL STRFUNC\t";
mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]"); mu::console() << "[ARG:" << std::dec << m_vRPN[i].Fun.argc << "]";
mu::console() << _T("[IDX:") << std::dec << m_vRPN[i].Fun.idx << _T("]"); mu::console() << "[IDX:" << std::dec << m_vRPN[i].Fun.idx << "]";
mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Fun.ptr << _T("]\n"); mu::console() << "[ADDR: 0x" << m_vRPN[i].Fun.ptr << "]\n";
break; break;
case cmLT: mu::console() << _T("LT\n"); break; case cmLT: mu::console() << "LT\n"; break;
case cmGT: mu::console() << _T("GT\n"); break; case cmGT: mu::console() << "GT\n"; break;
case cmLE: mu::console() << _T("LE\n"); break; case cmLE: mu::console() << "LE\n"; break;
case cmGE: mu::console() << _T("GE\n"); break; case cmGE: mu::console() << "GE\n"; break;
case cmEQ: mu::console() << _T("EQ\n"); break; case cmEQ: mu::console() << "EQ\n"; break;
case cmNEQ: mu::console() << _T("NEQ\n"); break; case cmNEQ: mu::console() << "NEQ\n"; break;
case cmADD: mu::console() << _T("ADD\n"); break; case cmADD: mu::console() << "ADD\n"; break;
case cmLAND: mu::console() << _T("&&\n"); break; case cmLAND: mu::console() << "&&\n"; break;
case cmLOR: mu::console() << _T("||\n"); break; case cmLOR: mu::console() << "||\n"; break;
case cmSUB: mu::console() << _T("SUB\n"); break; case cmSUB: mu::console() << "SUB\n"; break;
case cmMUL: mu::console() << _T("MUL\n"); break; case cmMUL: mu::console() << "MUL\n"; break;
case cmDIV: mu::console() << _T("DIV\n"); break; case cmDIV: mu::console() << "DIV\n"; break;
case cmPOW: mu::console() << _T("POW\n"); break; case cmPOW: mu::console() << "POW\n"; break;
case cmIF: mu::console() << _T("IF\t"); case cmIF: mu::console() << "IF\t";
mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n"); mu::console() << "[OFFSET:" << std::dec << m_vRPN[i].Oprt.offset << "]\n";
break; break;
case cmELSE: mu::console() << _T("ELSE\t"); case cmELSE: mu::console() << "ELSE\t";
mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n"); mu::console() << "[OFFSET:" << std::dec << m_vRPN[i].Oprt.offset << "]\n";
break; break;
case cmENDIF: mu::console() << _T("ENDIF\n"); break; case cmENDIF: mu::console() << "ENDIF\n"; break;
case cmASSIGN: case cmASSIGN:
mu::console() << _T("ASSIGN\t"); mu::console() << "ASSIGN\t";
mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Oprt.ptr << _T("]\n"); mu::console() << "[ADDR: 0x" << m_vRPN[i].Oprt.ptr << "]\n";
break; break;
default: mu::console() << _T("(unknown code: ") << m_vRPN[i].Cmd << _T(")\n"); default: mu::console() << "(unknown code: " << m_vRPN[i].Cmd << ")\n";
break; break;
} // switch cmdCode } // switch cmdCode
} // while bytecode } // while bytecode
mu::console() << _T("END") << std::endl; mu::console() << "END" << std::endl;
} }
} // namespace qmu } // namespace qmu

View file

@ -48,9 +48,9 @@ namespace qmu
{ {
struct //SValData struct //SValData
{ {
value_type *ptr; qreal *ptr;
value_type data; qreal data;
value_type data2; qreal data2;
} Val; } Val;
struct //SFunData struct //SFunData
@ -66,7 +66,7 @@ namespace qmu
struct //SOprtData struct //SOprtData
{ {
value_type *ptr; qreal *ptr;
int offset; int offset;
} Oprt; } Oprt;
}; };
@ -87,7 +87,7 @@ class QmuParserByteCode
private: private:
/** \brief Token type for internal use only. */ /** \brief Token type for internal use only. */
typedef QmuParserToken<value_type, string_type> token_type; typedef QmuParserToken<qreal, string_type> token_type;
/** \brief Token vector for storing the RPN. */ /** \brief Token vector for storing the RPN. */
typedef std::vector<SToken> rpn_type; typedef std::vector<SToken> rpn_type;
@ -112,11 +112,11 @@ public:
QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode); QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode);
void Assign(const QmuParserByteCode &a_ByteCode); void Assign(const QmuParserByteCode &a_ByteCode);
void AddVar(value_type *a_pVar); void AddVar(qreal *a_pVar);
void AddVal(value_type a_fVal); void AddVal(qreal a_fVal);
void AddOp(ECmdCode a_Oprt); void AddOp(ECmdCode a_Oprt);
void AddIfElse(ECmdCode a_Oprt); void AddIfElse(ECmdCode a_Oprt);
void AddAssignOp(value_type *a_pVar); void AddAssignOp(qreal *a_pVar);
void AddFun(generic_fun_type a_pFun, int a_iArgc); void AddFun(generic_fun_type a_pFun, int a_iArgc);
void AddBulkFun(generic_fun_type a_pFun, int a_iArgc); void AddBulkFun(generic_fun_type a_pFun, int a_iArgc);
void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx); void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx);

View file

@ -34,20 +34,13 @@
\brief This file contains standard definitions used by the parser. \brief This file contains standard definitions used by the parser.
*/ */
#define QMUP_VERSION _T("2.2.3") #define QMUP_VERSION "2.2.3"
#define QMUP_VERSION_DATE _T("20121222; SF") #define QMUP_VERSION_DATE "20121222; SF"
#define QMUP_CHARS _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") #define QMUP_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
/** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */ /** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */
//#define MUP_MATH_EXCEPTIONS //#define QMUP_MATH_EXCEPTIONS
/** \brief Define the base datatype for values.
This datatype must be a built in value type. You can not use custom classes.
It should be working with all types except "int"!
*/
#define QMUP_BASETYPE double
/** \brief Activate this option in order to compile with OpenMP support. /** \brief Activate this option in order to compile with OpenMP support.
@ -59,13 +52,7 @@
/** \brief Definition of the basic parser string type. */ /** \brief Definition of the basic parser string type. */
#define MUP_STRING_TYPE std::wstring #define MUP_STRING_TYPE std::wstring
#if !defined(_T)
#define _T(x) L##x
#endif // not defined _T
#else #else
#ifndef _T
#define _T(x) x
#endif
/** \brief Definition of the basic parser string type. */ /** \brief Definition of the basic parser string type. */
#define MUP_STRING_TYPE std::string #define MUP_STRING_TYPE std::string
@ -89,9 +76,9 @@
if (!(COND)) \ if (!(COND)) \
{ \ { \
stringstream_type ss; \ stringstream_type ss; \
ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") \ ss << "Assertion \"" #COND "\" failed: ") \
<< __FILE__ << _T(" line ") \ << __FILE__ << " line " \
<< __LINE__ << _T("."); \ << __LINE__ << "."; \
throw ParserError( ss.str() ); \ throw ParserError( ss.str() ); \
} }
#else #else
@ -238,12 +225,6 @@ namespace qmu
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// basic types // basic types
/** \brief The numeric datatype used by the parser.
Normally this is a floating point type either single or double precision.
*/
typedef QMUP_BASETYPE value_type;
/** \brief The stringtype used by the parser. /** \brief The stringtype used by the parser.
Depends on wether UNICODE is used or not. Depends on wether UNICODE is used or not.
@ -264,10 +245,10 @@ namespace qmu
// Data container types // Data container types
/** \brief Type used for storing variables. */ /** \brief Type used for storing variables. */
typedef std::map<string_type, value_type*> varmap_type; typedef std::map<string_type, qreal*> varmap_type;
/** \brief Type used for storing constants. */ /** \brief Type used for storing constants. */
typedef std::map<string_type, value_type> valmap_type; typedef std::map<string_type, qreal> valmap_type;
/** \brief Type for assigning a string name to an index in the internal string table. */ /** \brief Type for assigning a string name to an index in the internal string table. */
typedef std::map<string_type, std::size_t> strmap_type; typedef std::map<string_type, std::size_t> strmap_type;
@ -275,91 +256,91 @@ namespace qmu
// Parser callbacks // Parser callbacks
/** \brief Callback type used for functions without arguments. */ /** \brief Callback type used for functions without arguments. */
typedef value_type (*generic_fun_type)(); typedef qreal (*generic_fun_type)();
/** \brief Callback type used for functions without arguments. */ /** \brief Callback type used for functions without arguments. */
typedef value_type (*fun_type0)(); typedef qreal (*fun_type0)();
/** \brief Callback type used for functions with a single arguments. */ /** \brief Callback type used for functions with a single arguments. */
typedef value_type (*fun_type1)(value_type); typedef qreal (*fun_type1)(qreal);
/** \brief Callback type used for functions with two arguments. */ /** \brief Callback type used for functions with two arguments. */
typedef value_type (*fun_type2)(value_type, value_type); typedef qreal (*fun_type2)(qreal, qreal);
/** \brief Callback type used for functions with three arguments. */ /** \brief Callback type used for functions with three arguments. */
typedef value_type (*fun_type3)(value_type, value_type, value_type); typedef qreal (*fun_type3)(qreal, qreal, qreal);
/** \brief Callback type used for functions with four arguments. */ /** \brief Callback type used for functions with four arguments. */
typedef value_type (*fun_type4)(value_type, value_type, value_type, value_type); typedef qreal (*fun_type4)(qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type5)(value_type, value_type, value_type, value_type, value_type); typedef qreal (*fun_type5)(qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type6)(value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*fun_type6)(qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type7)(value_type, value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*fun_type7)(qreal, qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type8)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*fun_type8)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type9)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*fun_type9)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type10)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*fun_type10)(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions without arguments. */ /** \brief Callback type used for functions without arguments. */
typedef value_type (*bulkfun_type0)(int, int); typedef qreal (*bulkfun_type0)(int, int);
/** \brief Callback type used for functions with a single arguments. */ /** \brief Callback type used for functions with a single arguments. */
typedef value_type (*bulkfun_type1)(int, int, value_type); typedef qreal (*bulkfun_type1)(int, int, qreal);
/** \brief Callback type used for functions with two arguments. */ /** \brief Callback type used for functions with two arguments. */
typedef value_type (*bulkfun_type2)(int, int, value_type, value_type); typedef qreal (*bulkfun_type2)(int, int, qreal, qreal);
/** \brief Callback type used for functions with three arguments. */ /** \brief Callback type used for functions with three arguments. */
typedef value_type (*bulkfun_type3)(int, int, value_type, value_type, value_type); typedef qreal (*bulkfun_type3)(int, int, qreal, qreal, qreal);
/** \brief Callback type used for functions with four arguments. */ /** \brief Callback type used for functions with four arguments. */
typedef value_type (*bulkfun_type4)(int, int, value_type, value_type, value_type, value_type); typedef qreal (*bulkfun_type4)(int, int, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type5)(int, int, value_type, value_type, value_type, value_type, value_type); typedef qreal (*bulkfun_type5)(int, int, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type6)(int, int, value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*bulkfun_type6)(int, int, qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type7)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*bulkfun_type7)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type8)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*bulkfun_type8)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type9)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*bulkfun_type9)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with five arguments. */ /** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type10)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type); typedef qreal (*bulkfun_type10)(int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
/** \brief Callback type used for functions with a variable argument list. */ /** \brief Callback type used for functions with a variable argument list. */
typedef value_type (*multfun_type)(const value_type*, int); typedef qreal (*multfun_type)(const qreal*, int);
/** \brief Callback type used for functions taking a string as an argument. */ /** \brief Callback type used for functions taking a string as an argument. */
typedef value_type (*strfun_type1)(const char_type*); typedef qreal (*strfun_type1)(const char_type*);
/** \brief Callback type used for functions taking a string and a value as arguments. */ /** \brief Callback type used for functions taking a string and a value as arguments. */
typedef value_type (*strfun_type2)(const char_type*, value_type); typedef qreal (*strfun_type2)(const char_type*, qreal);
/** \brief Callback type used for functions taking a string and two values as arguments. */ /** \brief Callback type used for functions taking a string and two values as arguments. */
typedef value_type (*strfun_type3)(const char_type*, value_type, value_type); typedef qreal (*strfun_type3)(const char_type*, qreal, qreal);
/** \brief Callback used for functions that identify values in a string. */ /** \brief Callback used for functions that identify values in a string. */
typedef int (*identfun_type)(const char_type *sExpr, int *nPos, value_type *fVal); typedef int (*identfun_type)(const char_type *sExpr, int *nPos, qreal *fVal);
/** \brief Callback used for variable creation factory functions. */ /** \brief Callback used for variable creation factory functions. */
typedef value_type* (*facfun_type)(const char_type*, void*); typedef qreal* (*facfun_type)(const char_type*, void*);
} // end of namespace } // end of namespace
#endif #endif

View file

@ -62,42 +62,42 @@ namespace qmu
{ {
m_vErrMsg.resize(ecCOUNT); m_vErrMsg.resize(ecCOUNT);
m_vErrMsg[ecUNASSIGNABLE_TOKEN] = _T("Unexpected token \"$TOK$\" found at position $POS$."); m_vErrMsg[ecUNASSIGNABLE_TOKEN] = "Unexpected token \"$TOK$\" found at position $POS$.";
m_vErrMsg[ecINTERNAL_ERROR] = _T("Internal error"); m_vErrMsg[ecINTERNAL_ERROR] = "Internal error";
m_vErrMsg[ecINVALID_NAME] = _T("Invalid function-, variable- or constant name: \"$TOK$\"."); m_vErrMsg[ecINVALID_NAME] = "Invalid function-, variable- or constant name: \"$TOK$\".";
m_vErrMsg[ecINVALID_BINOP_IDENT] = _T("Invalid binary operator identifier: \"$TOK$\"."); m_vErrMsg[ecINVALID_BINOP_IDENT] = "Invalid binary operator identifier: \"$TOK$\".";
m_vErrMsg[ecINVALID_INFIX_IDENT] = _T("Invalid infix operator identifier: \"$TOK$\"."); m_vErrMsg[ecINVALID_INFIX_IDENT] = "Invalid infix operator identifier: \"$TOK$\".";
m_vErrMsg[ecINVALID_POSTFIX_IDENT] = _T("Invalid postfix operator identifier: \"$TOK$\"."); m_vErrMsg[ecINVALID_POSTFIX_IDENT] = "Invalid postfix operator identifier: \"$TOK$\".";
m_vErrMsg[ecINVALID_FUN_PTR] = _T("Invalid pointer to callback function."); m_vErrMsg[ecINVALID_FUN_PTR] = "Invalid pointer to callback function.";
m_vErrMsg[ecEMPTY_EXPRESSION] = _T("Expression is empty."); m_vErrMsg[ecEMPTY_EXPRESSION] = "Expression is empty.";
m_vErrMsg[ecINVALID_VAR_PTR] = _T("Invalid pointer to variable."); m_vErrMsg[ecINVALID_VAR_PTR] = "Invalid pointer to variable.";
m_vErrMsg[ecUNEXPECTED_OPERATOR] = _T("Unexpected operator \"$TOK$\" found at position $POS$"); m_vErrMsg[ecUNEXPECTED_OPERATOR] = "Unexpected operator \"$TOK$\" found at position $POS$";
m_vErrMsg[ecUNEXPECTED_EOF] = _T("Unexpected end of expression at position $POS$"); m_vErrMsg[ecUNEXPECTED_EOF] = "Unexpected end of expression at position $POS$";
m_vErrMsg[ecUNEXPECTED_ARG_SEP] = _T("Unexpected argument separator at position $POS$"); m_vErrMsg[ecUNEXPECTED_ARG_SEP] = "Unexpected argument separator at position $POS$";
m_vErrMsg[ecUNEXPECTED_PARENS] = _T("Unexpected parenthesis \"$TOK$\" at position $POS$"); m_vErrMsg[ecUNEXPECTED_PARENS] = "Unexpected parenthesis \"$TOK$\" at position $POS$";
m_vErrMsg[ecUNEXPECTED_FUN] = _T("Unexpected function \"$TOK$\" at position $POS$"); m_vErrMsg[ecUNEXPECTED_FUN] = "Unexpected function \"$TOK$\" at position $POS$";
m_vErrMsg[ecUNEXPECTED_VAL] = _T("Unexpected value \"$TOK$\" found at position $POS$"); m_vErrMsg[ecUNEXPECTED_VAL] = "Unexpected value \"$TOK$\" found at position $POS$";
m_vErrMsg[ecUNEXPECTED_VAR] = _T("Unexpected variable \"$TOK$\" found at position $POS$"); m_vErrMsg[ecUNEXPECTED_VAR] = "Unexpected variable \"$TOK$\" found at position $POS$";
m_vErrMsg[ecUNEXPECTED_ARG] = _T("Function arguments used without a function (position: $POS$)"); m_vErrMsg[ecUNEXPECTED_ARG] = "Function arguments used without a function (position: $POS$)";
m_vErrMsg[ecMISSING_PARENS] = _T("Missing parenthesis"); m_vErrMsg[ecMISSING_PARENS] = "Missing parenthesis";
m_vErrMsg[ecTOO_MANY_PARAMS] = _T("Too many parameters for function \"$TOK$\" at expression position $POS$"); m_vErrMsg[ecTOO_MANY_PARAMS] = "Too many parameters for function \"$TOK$\" at expression position $POS$";
m_vErrMsg[ecTOO_FEW_PARAMS] = _T("Too few parameters for function \"$TOK$\" at expression position $POS$"); m_vErrMsg[ecTOO_FEW_PARAMS] = "Too few parameters for function \"$TOK$\" at expression position $POS$";
m_vErrMsg[ecDIV_BY_ZERO] = _T("Divide by zero"); m_vErrMsg[ecDIV_BY_ZERO] = "Divide by zero";
m_vErrMsg[ecDOMAIN_ERROR] = _T("Domain error"); m_vErrMsg[ecDOMAIN_ERROR] = "Domain error";
m_vErrMsg[ecNAME_CONFLICT] = _T("Name conflict"); m_vErrMsg[ecNAME_CONFLICT] = "Name conflict";
m_vErrMsg[ecOPT_PRI] = _T("Invalid value for operator priority (must be greater or equal to zero)."); m_vErrMsg[ecOPT_PRI] = "Invalid value for operator priority (must be greater or equal to zero).";
m_vErrMsg[ecBUILTIN_OVERLOAD] = _T("user defined binary operator \"$TOK$\" conflicts with a built in operator."); m_vErrMsg[ecBUILTIN_OVERLOAD] = "user defined binary operator \"$TOK$\" conflicts with a built in operator.";
m_vErrMsg[ecUNEXPECTED_STR] = _T("Unexpected string token found at position $POS$."); m_vErrMsg[ecUNEXPECTED_STR] = "Unexpected string token found at position $POS$.";
m_vErrMsg[ecUNTERMINATED_STRING] = _T("Unterminated string starting at position $POS$."); m_vErrMsg[ecUNTERMINATED_STRING] = "Unterminated string starting at position $POS$.";
m_vErrMsg[ecSTRING_EXPECTED] = _T("String function called with a non string type of argument."); m_vErrMsg[ecSTRING_EXPECTED] = "String function called with a non string type of argument.";
m_vErrMsg[ecVAL_EXPECTED] = _T("String value used where a numerical argument is expected."); m_vErrMsg[ecVAL_EXPECTED] = "String value used where a numerical argument is expected.";
m_vErrMsg[ecOPRT_TYPE_CONFLICT] = _T("No suitable overload for operator \"$TOK$\" at position $POS$."); m_vErrMsg[ecOPRT_TYPE_CONFLICT] = "No suitable overload for operator \"$TOK$\" at position $POS$.";
m_vErrMsg[ecSTR_RESULT] = _T("Function result is a string."); m_vErrMsg[ecSTR_RESULT] = "Function result is a string.";
m_vErrMsg[ecGENERIC] = _T("Parser error."); m_vErrMsg[ecGENERIC] = "Parser error.";
m_vErrMsg[ecLOCALE] = _T("Decimal separator is identic to function argument separator."); m_vErrMsg[ecLOCALE] = "Decimal separator is identic to function argument separator.";
m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = _T("The \"$TOK$\" operator must be preceeded by a closing bracket."); m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = "The \"$TOK$\" operator must be preceeded by a closing bracket.";
m_vErrMsg[ecMISSING_ELSE_CLAUSE] = _T("If-then-else operator is missing an else clause"); m_vErrMsg[ecMISSING_ELSE_CLAUSE] = "If-then-else operator is missing an else clause";
m_vErrMsg[ecMISPLACED_COLON] = _T("Misplaced colon at position $POS$"); m_vErrMsg[ecMISPLACED_COLON] = "Misplaced colon at position $POS$";
#if defined(_DEBUG) #if defined(_DEBUG)
for (int i=0; i<ecCOUNT; ++i) for (int i=0; i<ecCOUNT; ++i)
@ -139,8 +139,8 @@ namespace qmu
m_strMsg = m_ErrMsg[m_iErrc]; m_strMsg = m_ErrMsg[m_iErrc];
stringstream_type stream; stringstream_type stream;
stream << (int)m_iPos; stream << (int)m_iPos;
ReplaceSubString(m_strMsg, _T("$POS$"), stream.str()); ReplaceSubString(m_strMsg, "$POS$", stream.str());
ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok); ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -173,8 +173,8 @@ namespace qmu
m_strMsg = m_ErrMsg[m_iErrc]; m_strMsg = m_ErrMsg[m_iErrc];
stringstream_type stream; stringstream_type stream;
stream << (int)m_iPos; stream << (int)m_iPos;
ReplaceSubString(m_strMsg, _T("$POS$"), stream.str()); ReplaceSubString(m_strMsg, "$POS$", stream.str());
ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok); ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -194,8 +194,8 @@ namespace qmu
m_strMsg = m_ErrMsg[m_iErrc]; m_strMsg = m_ErrMsg[m_iErrc];
stringstream_type stream; stringstream_type stream;
stream << (int)m_iPos; stream << (int)m_iPos;
ReplaceSubString(m_strMsg, _T("$POS$"), stream.str()); ReplaceSubString(m_strMsg, "$POS$", stream.str());
ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok); ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -214,8 +214,8 @@ namespace qmu
{ {
stringstream_type stream; stringstream_type stream;
stream << (int)m_iPos; stream << (int)m_iPos;
ReplaceSubString(m_strMsg, _T("$POS$"), stream.str()); ReplaceSubString(m_strMsg, "$POS$", stream.str());
ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok); ReplaceSubString(m_strMsg, "$TOK$", m_strTok);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -280,9 +280,9 @@ namespace qmu
/** \brief Reset the erro object. */ /** \brief Reset the erro object. */
void QmuParserError::Reset() void QmuParserError::Reset()
{ {
m_strMsg = _T(""); m_strMsg = "";
m_strFormula = _T(""); m_strFormula = "";
m_strTok = _T(""); m_strTok = "";
m_iPos = -1; m_iPos = -1;
m_iErrc = ecUNDEFINED; m_iErrc = ecUNDEFINED;
} }

View file

@ -35,49 +35,49 @@ using namespace std;
/** \brief Namespace for mathematical applications. */ /** \brief Namespace for mathematical applications. */
namespace qmu namespace qmu
{ {
value_type QmuParserInt::Abs(value_type v) { return (value_type)Round(fabs((double)v)); } qreal QmuParserInt::Abs(qreal v) { return (qreal)Round(fabs((double)v)); }
value_type QmuParserInt::Sign(value_type v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; } qreal QmuParserInt::Sign(qreal v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; }
value_type QmuParserInt::Ite(value_type v1, qreal QmuParserInt::Ite(qreal v1,
value_type v2, qreal v2,
value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); } qreal v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); }
value_type QmuParserInt::Add(value_type v1, value_type v2) { return Round(v1) + Round(v2); } qreal QmuParserInt::Add(qreal v1, qreal v2) { return Round(v1) + Round(v2); }
value_type QmuParserInt::Sub(value_type v1, value_type v2) { return Round(v1) - Round(v2); } qreal QmuParserInt::Sub(qreal v1, qreal v2) { return Round(v1) - Round(v2); }
value_type QmuParserInt::Mul(value_type v1, value_type v2) { return Round(v1) * Round(v2); } qreal QmuParserInt::Mul(qreal v1, qreal v2) { return Round(v1) * Round(v2); }
value_type QmuParserInt::Div(value_type v1, value_type v2) { return Round(v1) / Round(v2); } qreal QmuParserInt::Div(qreal v1, qreal v2) { return Round(v1) / Round(v2); }
value_type QmuParserInt::Mod(value_type v1, value_type v2) { return Round(v1) % Round(v2); } qreal QmuParserInt::Mod(qreal v1, qreal v2) { return Round(v1) % Round(v2); }
value_type QmuParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); } qreal QmuParserInt::Shr(qreal v1, qreal v2) { return Round(v1) >> Round(v2); }
value_type QmuParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); } qreal QmuParserInt::Shl(qreal v1, qreal v2) { return Round(v1) << Round(v2); }
value_type QmuParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); } qreal QmuParserInt::LogAnd(qreal v1, qreal v2) { return Round(v1) & Round(v2); }
value_type QmuParserInt::LogOr(value_type v1, value_type v2) { return Round(v1) | Round(v2); } qreal QmuParserInt::LogOr(qreal v1, qreal v2) { return Round(v1) | Round(v2); }
value_type QmuParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); } qreal QmuParserInt::And(qreal v1, qreal v2) { return Round(v1) && Round(v2); }
value_type QmuParserInt::Or(value_type v1, value_type v2) { return Round(v1) || Round(v2); } qreal QmuParserInt::Or(qreal v1, qreal v2) { return Round(v1) || Round(v2); }
value_type QmuParserInt::Less(value_type v1, value_type v2) { return Round(v1) < Round(v2); } qreal QmuParserInt::Less(qreal v1, qreal v2) { return Round(v1) < Round(v2); }
value_type QmuParserInt::Greater(value_type v1, value_type v2) { return Round(v1) > Round(v2); } qreal QmuParserInt::Greater(qreal v1, qreal v2) { return Round(v1) > Round(v2); }
value_type QmuParserInt::LessEq(value_type v1, value_type v2) { return Round(v1) <= Round(v2); } qreal QmuParserInt::LessEq(qreal v1, qreal v2) { return Round(v1) <= Round(v2); }
value_type QmuParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); } qreal QmuParserInt::GreaterEq(qreal v1, qreal v2) { return Round(v1) >= Round(v2); }
value_type QmuParserInt::Equal(value_type v1, value_type v2) { return Round(v1) == Round(v2); } qreal QmuParserInt::Equal(qreal v1, qreal v2) { return Round(v1) == Round(v2); }
value_type QmuParserInt::NotEqual(value_type v1, value_type v2) { return Round(v1) != Round(v2); } qreal QmuParserInt::NotEqual(qreal v1, qreal v2) { return Round(v1) != Round(v2); }
value_type QmuParserInt::Not(value_type v) { return !Round(v); } qreal QmuParserInt::Not(qreal v) { return !Round(v); }
value_type QmuParserInt::Pow(value_type v1, value_type v2) qreal QmuParserInt::Pow(qreal v1, qreal v2)
{ {
return std::pow((double)Round(v1), (double)Round(v2)); return std::pow((double)Round(v1), (double)Round(v2));
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Unary operator Callbacks: Infix operators // Unary operator Callbacks: Infix operators
value_type QmuParserInt::UnaryMinus(value_type v) qreal QmuParserInt::UnaryMinus(qreal v)
{ {
return -Round(v); return -Round(v);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
value_type QmuParserInt::Sum(const value_type* a_afArg, int a_iArgc) qreal QmuParserInt::Sum(const qreal* a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw QmuParserError(_T("too few arguments for function sum.")); throw QmuParserError("too few arguments for function sum.");
value_type fRes=0; qreal fRes=0;
for (int i=0; i<a_iArgc; ++i) for (int i=0; i<a_iArgc; ++i)
fRes += a_afArg[i]; fRes += a_afArg[i];
@ -85,12 +85,12 @@ value_type QmuParserInt::Sum(const value_type* a_afArg, int a_iArgc)
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
value_type QmuParserInt::Min(const value_type* a_afArg, int a_iArgc) qreal QmuParserInt::Min(const qreal* a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw QmuParserError( _T("too few arguments for function min.") ); throw QmuParserError( "too few arguments for function min." );
value_type fRes=a_afArg[0]; qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i) for (int i=0; i<a_iArgc; ++i)
fRes = std::min(fRes, a_afArg[i]); fRes = std::min(fRes, a_afArg[i]);
@ -98,12 +98,12 @@ value_type QmuParserInt::Min(const value_type* a_afArg, int a_iArgc)
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
value_type QmuParserInt::Max(const value_type* a_afArg, int a_iArgc) qreal QmuParserInt::Max(const qreal* a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw QmuParserError(_T("too few arguments for function min.")); throw QmuParserError("too few arguments for function min.");
value_type fRes=a_afArg[0]; qreal fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i) for (int i=0; i<a_iArgc; ++i)
fRes = std::max(fRes, a_afArg[i]); fRes = std::max(fRes, a_afArg[i]);
@ -112,10 +112,10 @@ value_type QmuParserInt::Max(const value_type* a_afArg, int a_iArgc)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Default value recognition callback // Default value recognition callback
int QmuParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) int QmuParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal)
{ {
string_type buf(a_szExpr); string_type buf(a_szExpr);
std::size_t pos = buf.find_first_not_of(_T("0123456789")); std::size_t pos = buf.find_first_not_of("0123456789");
if (pos==std::string::npos) if (pos==std::string::npos)
return 0; return 0;
@ -135,7 +135,7 @@ int QmuParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fV
return 0; return 0;
*a_iPos += (int)iEnd; *a_iPos += (int)iEnd;
*a_fVal = (value_type)iVal; *a_fVal = (qreal)iVal;
return 1; return 1;
} }
@ -149,7 +149,7 @@ int QmuParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fV
Hey values must be prefixed with "0x" in order to be detected properly. Hey values must be prefixed with "0x" in order to be detected properly.
*/ */
int QmuParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) int QmuParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal)
{ {
if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') )
return 0; return 0;
@ -166,12 +166,12 @@ int QmuParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a
return 1; return 1;
*a_iPos += (int)(2 + nPos); *a_iPos += (int)(2 + nPos);
*a_fVal = (value_type)iVal; *a_fVal = (qreal)iVal;
return 1; return 1;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int QmuParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) int QmuParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal)
{ {
if (a_szExpr[0]!='#') if (a_szExpr[0]!='#')
return 0; return 0;
@ -187,7 +187,7 @@ int QmuParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a
return 0; return 0;
if (i==iBits) if (i==iBits)
throw exception_type(_T("Binary to integer conversion error (overflow).")); throw exception_type("Binary to integer conversion error (overflow).");
*a_fVal = (unsigned)(iVal >> (iBits-i) ); *a_fVal = (unsigned)(iVal >> (iBits-i) );
*a_iPos += i+1; *a_iPos += i+1;
@ -220,21 +220,21 @@ void QmuParserInt::InitConst()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void QmuParserInt::InitCharSets() void QmuParserInt::InitCharSets()
{ {
DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") ); DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
DefineOprtChars( _T("+-*^/?<>=!%&|~'_") ); DefineOprtChars( "+-*^/?<>=!%&|~'_" );
DefineInfixOprtChars( _T("/+-*^?<>=!%&|~'_") ); DefineInfixOprtChars( "/+-*^?<>=!%&|~'_" );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/** \brief Initialize the default functions. */ /** \brief Initialize the default functions. */
void QmuParserInt::InitFun() void QmuParserInt::InitFun()
{ {
DefineFun( _T("sign"), Sign); DefineFun( "sign", Sign);
DefineFun( _T("abs"), Abs); DefineFun( "abs", Abs);
DefineFun( _T("if"), Ite); DefineFun( "if", Ite);
DefineFun( _T("sum"), Sum); DefineFun( "sum", Sum);
DefineFun( _T("min"), Min); DefineFun( "min", Min);
DefineFun( _T("max"), Max); DefineFun( "max", Max);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -247,31 +247,31 @@ void QmuParserInt::InitOprt()
// Disable all built in operators, they wont work with integer numbers // Disable all built in operators, they wont work with integer numbers
// since they are designed for floating point numbers // since they are designed for floating point numbers
DefineInfixOprt( _T("-"), UnaryMinus); DefineInfixOprt( "-", UnaryMinus);
DefineInfixOprt( _T("!"), Not); DefineInfixOprt( "!", Not);
DefineOprt( _T("&"), LogAnd, prLOGIC); DefineOprt( "&", LogAnd, prLOGIC);
DefineOprt( _T("|"), LogOr, prLOGIC); DefineOprt( "|", LogOr, prLOGIC);
DefineOprt( _T("&&"), And, prLOGIC); DefineOprt( "&&", And, prLOGIC);
DefineOprt( _T("||"), Or, prLOGIC); DefineOprt( "||", Or, prLOGIC);
DefineOprt( _T("<"), Less, prCMP); DefineOprt( "<", Less, prCMP);
DefineOprt( _T(">"), Greater, prCMP); DefineOprt( ">", Greater, prCMP);
DefineOprt( _T("<="), LessEq, prCMP); DefineOprt( "<=", LessEq, prCMP);
DefineOprt( _T(">="), GreaterEq, prCMP); DefineOprt( ">=", GreaterEq, prCMP);
DefineOprt( _T("=="), Equal, prCMP); DefineOprt( "==", Equal, prCMP);
DefineOprt( _T("!="), NotEqual, prCMP); DefineOprt( "!=", NotEqual, prCMP);
DefineOprt( _T("+"), Add, prADD_SUB); DefineOprt( "+", Add, prADD_SUB);
DefineOprt( _T("-"), Sub, prADD_SUB); DefineOprt( "-", Sub, prADD_SUB);
DefineOprt( _T("*"), Mul, prMUL_DIV); DefineOprt( "*", Mul, prMUL_DIV);
DefineOprt( _T("/"), Div, prMUL_DIV); DefineOprt( "/", Div, prMUL_DIV);
DefineOprt( _T("%"), Mod, prMUL_DIV); DefineOprt( "%", Mod, prMUL_DIV);
DefineOprt( _T("^"), Pow, prPOW, oaRIGHT); DefineOprt( "^", Pow, prPOW, oaRIGHT);
DefineOprt( _T(">>"), Shr, prMUL_DIV+1); DefineOprt( ">>", Shr, prMUL_DIV+1);
DefineOprt( _T("<<"), Shl, prMUL_DIV+1); DefineOprt( "<<", Shl, prMUL_DIV+1);
} }
} // namespace qmu } // namespace qmu

View file

@ -43,42 +43,42 @@ namespace qmu
class QmuParserInt : public QmuParserBase class QmuParserInt : public QmuParserBase
{ {
private: private:
static int Round(value_type v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); }; static int Round(qreal v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); };
static value_type Abs(value_type); static qreal Abs(qreal);
static value_type Sign(value_type); static qreal Sign(qreal);
static value_type Ite(value_type, value_type, value_type); static qreal Ite(qreal, qreal, qreal);
// !! The unary Minus is a MUST, otherwise you cant use negative signs !! // !! The unary Minus is a MUST, otherwise you cant use negative signs !!
static value_type UnaryMinus(value_type); static qreal UnaryMinus(qreal);
// Functions with variable number of arguments // Functions with variable number of arguments
static value_type Sum(const value_type* a_afArg, int a_iArgc); // sum static qreal Sum(const qreal* a_afArg, int a_iArgc); // sum
static value_type Min(const value_type* a_afArg, int a_iArgc); // minimum static qreal Min(const qreal* a_afArg, int a_iArgc); // minimum
static value_type Max(const value_type* a_afArg, int a_iArgc); // maximum static qreal Max(const qreal* a_afArg, int a_iArgc); // maximum
// binary operator callbacks // binary operator callbacks
static value_type Add(value_type v1, value_type v2); static qreal Add(qreal v1, qreal v2);
static value_type Sub(value_type v1, value_type v2); static qreal Sub(qreal v1, qreal v2);
static value_type Mul(value_type v1, value_type v2); static qreal Mul(qreal v1, qreal v2);
static value_type Div(value_type v1, value_type v2); static qreal Div(qreal v1, qreal v2);
static value_type Mod(value_type v1, value_type v2); static qreal Mod(qreal v1, qreal v2);
static value_type Pow(value_type v1, value_type v2); static qreal Pow(qreal v1, qreal v2);
static value_type Shr(value_type v1, value_type v2); static qreal Shr(qreal v1, qreal v2);
static value_type Shl(value_type v1, value_type v2); static qreal Shl(qreal v1, qreal v2);
static value_type LogAnd(value_type v1, value_type v2); static qreal LogAnd(qreal v1, qreal v2);
static value_type LogOr(value_type v1, value_type v2); static qreal LogOr(qreal v1, qreal v2);
static value_type And(value_type v1, value_type v2); static qreal And(qreal v1, qreal v2);
static value_type Or(value_type v1, value_type v2); static qreal Or(qreal v1, qreal v2);
static value_type Xor(value_type v1, value_type v2); static qreal Xor(qreal v1, qreal v2);
static value_type Less(value_type v1, value_type v2); static qreal Less(qreal v1, qreal v2);
static value_type Greater(value_type v1, value_type v2); static qreal Greater(qreal v1, qreal v2);
static value_type LessEq(value_type v1, value_type v2); static qreal LessEq(qreal v1, qreal v2);
static value_type GreaterEq(value_type v1, value_type v2); static qreal GreaterEq(qreal v1, qreal v2);
static value_type Equal(value_type v1, value_type v2); static qreal Equal(qreal v1, qreal v2);
static value_type NotEqual(value_type v1, value_type v2); static qreal NotEqual(qreal v1, qreal v2);
static value_type Not(value_type v1); static qreal Not(qreal v1);
static int IsHexVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal); static int IsHexVal(const char_type* a_szExpr, int *a_iPos, qreal *a_iVal);
static int IsBinVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal); static int IsBinVal(const char_type* a_szExpr, int *a_iPos, qreal *a_iVal);
static int IsVal (const char_type* a_szExpr, int *a_iPos, value_type *a_iVal); static int IsVal (const char_type* a_szExpr, int *a_iPos, qreal *a_iVal);
/** \brief A facet class used to change decimal and thousands separator. */ /** \brief A facet class used to change decimal and thousands separator. */
template<class TChar> template<class TChar>

View file

@ -79,7 +79,7 @@ namespace qmu
TValueType pop() TValueType pop()
{ {
if (empty()) if (empty())
throw QmuParserError( _T("stack is empty.") ); throw QmuParserError( "stack is empty." );
TValueType el = top(); TValueType el = top();
m_Stack.pop(); m_Stack.pop();

View file

@ -115,26 +115,26 @@ namespace qmu
template<> \ template<> \
struct MathImpl<TYPE> \ struct MathImpl<TYPE> \
{ \ { \
static TYPE Sin(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Sin(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Cos(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Cos(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Tan(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Tan(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ASin(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE ASin(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ACos(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE ACos(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ATan(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE ATan(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ATan2(TYPE, TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE ATan2(TYPE, TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Sinh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Sinh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Cosh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Cosh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Tanh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Tanh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ASinh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE ASinh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ACosh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE ACosh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE ATanh(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE ATanh(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Log(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Log(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Log2(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Log2(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Log10(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Log10(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Exp(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Exp(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Abs(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Abs(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Sqrt(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Sqrt(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Rint(TYPE) { throw QmuParserError(_T("unimplemented function.")); } \ static TYPE Rint(TYPE) { throw QmuParserError("unimplemented function."); } \
static TYPE Sign(TYPE v) { return (TYPE)((v<0) ? -1 : (v>0) ? 1 : 0); } \ static TYPE Sign(TYPE v) { return (TYPE)((v<0) ? -1 : (v>0) ? 1 : 0); } \
static TYPE Pow(TYPE v1, TYPE v2) { return (TYPE)std::pow((double)v1, (double)v2); } \ static TYPE Pow(TYPE v1, TYPE v2) { return (TYPE)std::pow((double)v1, (double)v2); } \
}; };

File diff suppressed because it is too large Load diff

View file

@ -49,118 +49,118 @@ namespace qmu
static int c_iCount; static int c_iCount;
// Multiarg callbacks // Multiarg callbacks
static value_type f1of1(value_type v) { return v;}; static qreal f1of1(qreal v) { return v;};
static value_type f1of2(value_type v, value_type ) {return v;}; static qreal f1of2(qreal v, qreal ) {return v;};
static value_type f2of2(value_type , value_type v) {return v;}; static qreal f2of2(qreal , qreal v) {return v;};
static value_type f1of3(value_type v, value_type , value_type ) {return v;}; static qreal f1of3(qreal v, qreal , qreal ) {return v;};
static value_type f2of3(value_type , value_type v, value_type ) {return v;}; static qreal f2of3(qreal , qreal v, qreal ) {return v;};
static value_type f3of3(value_type , value_type , value_type v) {return v;}; static qreal f3of3(qreal , qreal , qreal v) {return v;};
static value_type f1of4(value_type v, value_type, value_type , value_type ) {return v;} static qreal f1of4(qreal v, qreal, qreal , qreal ) {return v;}
static value_type f2of4(value_type , value_type v, value_type , value_type ) {return v;} static qreal f2of4(qreal , qreal v, qreal , qreal ) {return v;}
static value_type f3of4(value_type , value_type, value_type v, value_type ) {return v;} static qreal f3of4(qreal , qreal, qreal v, qreal ) {return v;}
static value_type f4of4(value_type , value_type, value_type , value_type v) {return v;} static qreal f4of4(qreal , qreal, qreal , qreal v) {return v;}
static value_type f1of5(value_type v, value_type, value_type , value_type , value_type ) { return v; } static qreal f1of5(qreal v, qreal, qreal , qreal , qreal ) { return v; }
static value_type f2of5(value_type , value_type v, value_type , value_type , value_type ) { return v; } static qreal f2of5(qreal , qreal v, qreal , qreal , qreal ) { return v; }
static value_type f3of5(value_type , value_type, value_type v, value_type , value_type ) { return v; } static qreal f3of5(qreal , qreal, qreal v, qreal , qreal ) { return v; }
static value_type f4of5(value_type , value_type, value_type , value_type v, value_type ) { return v; } static qreal f4of5(qreal , qreal, qreal , qreal v, qreal ) { return v; }
static value_type f5of5(value_type , value_type, value_type , value_type , value_type v) { return v; } static qreal f5of5(qreal , qreal, qreal , qreal , qreal v) { return v; }
static value_type Min(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1<a_fVal2) ? a_fVal1 : a_fVal2; } static qreal Min(qreal a_fVal1, qreal a_fVal2) { return (a_fVal1<a_fVal2) ? a_fVal1 : a_fVal2; }
static value_type Max(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1>a_fVal2) ? a_fVal1 : a_fVal2; } static qreal Max(qreal a_fVal1, qreal a_fVal2) { return (a_fVal1>a_fVal2) ? a_fVal1 : a_fVal2; }
static value_type plus2(value_type v1) { return v1+2; } static qreal plus2(qreal v1) { return v1+2; }
static value_type times3(value_type v1) { return v1*3; } static qreal times3(qreal v1) { return v1*3; }
static value_type sqr(value_type v1) { return v1*v1; } static qreal sqr(qreal v1) { return v1*v1; }
static value_type sign(value_type v) { return -v; } static qreal sign(qreal v) { return -v; }
static value_type add(value_type v1, value_type v2) { return v1+v2; } static qreal add(qreal v1, qreal v2) { return v1+v2; }
static value_type land(value_type v1, value_type v2) { return (int)v1 & (int)v2; } static qreal land(qreal v1, qreal v2) { return (int)v1 & (int)v2; }
static value_type FirstArg(const value_type* a_afArg, int a_iArgc) static qreal FirstArg(const qreal* a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw qmu::QmuParser::exception_type( _T("too few arguments for function FirstArg.") ); throw qmu::QmuParser::exception_type( "too few arguments for function FirstArg." );
return a_afArg[0]; return a_afArg[0];
} }
static value_type LastArg(const value_type* a_afArg, int a_iArgc) static qreal LastArg(const qreal* a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw qmu::QmuParser::exception_type( _T("too few arguments for function LastArg.") ); throw qmu::QmuParser::exception_type( "too few arguments for function LastArg." );
return a_afArg[a_iArgc-1]; return a_afArg[a_iArgc-1];
} }
static value_type Sum(const value_type* a_afArg, int a_iArgc) static qreal Sum(const qreal* a_afArg, int a_iArgc)
{ {
if (!a_iArgc) if (!a_iArgc)
throw qmu::QmuParser::exception_type( _T("too few arguments for function sum.") ); throw qmu::QmuParser::exception_type( "too few arguments for function sum." );
value_type fRes=0; qreal fRes=0;
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i]; for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
return fRes; return fRes;
} }
static value_type Rnd(value_type v) static qreal Rnd(qreal v)
{ {
return (value_type)(1+(v*std::rand()/(RAND_MAX+1.0))); return (qreal)(1+(v*std::rand()/(RAND_MAX+1.0)));
} }
static value_type RndWithString(const char_type*) static qreal RndWithString(const char_type*)
{ {
return (value_type)( 1 + (1000.0f * std::rand() / (RAND_MAX + 1.0) ) ); return (qreal)( 1 + (1000.0f * std::rand() / (RAND_MAX + 1.0) ) );
} }
static value_type Ping() static qreal Ping()
{ {
return 10; return 10;
} }
static value_type ValueOf(const char_type*) static qreal ValueOf(const char_type*)
{ {
return 123; return 123;
} }
static value_type StrFun1(const char_type* v1) static qreal StrFun1(const char_type* v1)
{ {
int val(0); int val(0);
stringstream_type(v1) >> val; stringstream_type(v1) >> val;
return (value_type)val; return (qreal)val;
} }
static value_type StrFun2(const char_type* v1, value_type v2) static qreal StrFun2(const char_type* v1, qreal v2)
{ {
int val(0); int val(0);
stringstream_type(v1) >> val; stringstream_type(v1) >> val;
return (value_type)(val + v2); return (qreal)(val + v2);
} }
static value_type StrFun3(const char_type* v1, value_type v2, value_type v3) static qreal StrFun3(const char_type* v1, qreal v2, qreal v3)
{ {
int val(0); int val(0);
stringstream_type(v1) >> val; stringstream_type(v1) >> val;
return val + v2 + v3; return val + v2 + v3;
} }
static value_type StrToFloat(const char_type* a_szMsg) static qreal StrToFloat(const char_type* a_szMsg)
{ {
value_type val(0); qreal val(0);
stringstream_type(a_szMsg) >> val; stringstream_type(a_szMsg) >> val;
return val; return val;
} }
// postfix operator callback // postfix operator callback
static value_type Mega(value_type a_fVal) { return a_fVal * (value_type)1e6; } static qreal Mega(qreal a_fVal) { return a_fVal * (qreal)1e6; }
static value_type Micro(value_type a_fVal) { return a_fVal * (value_type)1e-6; } static qreal Micro(qreal a_fVal) { return a_fVal * (qreal)1e-6; }
static value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; } static qreal Milli(qreal a_fVal) { return a_fVal / (qreal)1e3; }
// Custom value recognition // Custom value recognition
static int IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal); static int IsHexVal(const char_type *a_szExpr, int *a_iPos, qreal *a_fVal);
int TestNames(); int TestNames();
int TestSyntax(); int TestSyntax();

View file

@ -65,7 +65,7 @@ namespace qmu
int m_iIdx; ///< An otional index to an external buffer storing the token data int m_iIdx; ///< An otional index to an external buffer storing the token data
TString m_strTok; ///< Token string TString m_strTok; ///< Token string
TString m_strVal; ///< Value for string variables TString m_strVal; ///< Value for string variables
value_type m_fVal; ///< the value qreal m_fVal; ///< the value
std::auto_ptr<QmuParserCallback> m_pCallback; std::auto_ptr<QmuParserCallback> m_pCallback;
public: public:

View file

@ -514,7 +514,7 @@ namespace qmu
Error(ecUNEXPECTED_EOF, m_iPos); Error(ecUNEXPECTED_EOF, m_iPos);
if (m_iBrackets>0) if (m_iBrackets>0)
Error(ecMISSING_PARENS, m_iPos, _T(")")); Error(ecMISSING_PARENS, m_iPos, ")");
m_iSynFlags = 0; m_iSynFlags = 0;
a_Tok.Set(cmEND); a_Tok.Set(cmEND);
@ -722,7 +722,7 @@ namespace qmu
assert(m_pParser); assert(m_pParser);
string_type strTok; string_type strTok;
value_type fVal(0); qreal fVal(0);
int iEnd(0); int iEnd(0);
// 2.) Check for user defined constant // 2.) Check for user defined constant
@ -855,7 +855,7 @@ namespace qmu
// If a factory is available implicitely create new variables // If a factory is available implicitely create new variables
if (m_pFactory) if (m_pFactory)
{ {
value_type *fVar = m_pFactory(strTok.c_str(), m_pFactoryData); qreal *fVar = m_pFactory(strTok.c_str(), m_pFactoryData);
a_Tok.SetVar(fVar, strTok ); a_Tok.SetVar(fVar, strTok );
// Do not use m_pParser->DefineVar( strTok, fVar ); // Do not use m_pParser->DefineVar( strTok, fVar );
@ -869,7 +869,7 @@ namespace qmu
} }
else else
{ {
a_Tok.SetVar((value_type*)&m_fZero, strTok); a_Tok.SetVar((qreal*)&m_fZero, strTok);
m_UsedVar[strTok] = 0; // Add variable to used-var-list m_UsedVar[strTok] = 0; // Add variable to used-var-list
} }
@ -897,15 +897,15 @@ namespace qmu
std::size_t iEnd(0), iSkip(0); std::size_t iEnd(0), iSkip(0);
// parser over escaped '\"' end replace them with '"' // parser over escaped '\"' end replace them with '"'
for(iEnd=(int)strBuf.find( _T("\"") ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( _T("\""), iEnd)) for(iEnd=(int)strBuf.find( "\"" ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( "\"", iEnd))
{ {
if (strBuf[iEnd-1]!='\\') break; if (strBuf[iEnd-1]!='\\') break;
strBuf.replace(iEnd-1, 2, _T("\"") ); strBuf.replace(iEnd-1, 2, "\"" );
iSkip++; iSkip++;
} }
if (iEnd==string_type::npos) if (iEnd==string_type::npos)
Error(ecUNTERMINATED_STRING, m_iPos, _T("\"") ); Error(ecUNTERMINATED_STRING, m_iPos, "\"" );
string_type strTok(strBuf.begin(), strBuf.begin()+iEnd); string_type strTok(strBuf.begin(), strBuf.begin()+iEnd);

View file

@ -52,7 +52,7 @@ namespace qmu
{ {
private: private:
typedef QmuParserToken<value_type, string_type> token_type; typedef QmuParserToken<qreal, string_type> token_type;
public: public:
@ -146,7 +146,7 @@ namespace qmu
void *m_pFactoryData; void *m_pFactoryData;
std::list<identfun_type> m_vIdentFun; ///< Value token identification function std::list<identfun_type> m_vIdentFun; ///< Value token identification function
varmap_type m_UsedVar; varmap_type m_UsedVar;
value_type m_fZero; ///< Dummy value of zero, referenced by undefined variables qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables
int m_iBrackets; int m_iBrackets;
token_type m_lastTok; token_type m_lastTok;
char_type m_cArgSep; ///< The character used for separating function arguments char_type m_cArgSep; ///< The character used for separating function arguments