Used qreal for datatype. Deleted _T() macros.
--HG-- branch : feature
This commit is contained in:
parent
0b4d69f821
commit
11f527143b
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
@ -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();
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user