Used qreal for datatype. Deleted _T() macros.

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

View file

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

View file

@ -59,50 +59,50 @@ public:
virtual void InitOprt();
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:
// Trigonometric functions
static value_type Sin(value_type);
static value_type Cos(value_type);
static value_type Tan(value_type);
static value_type Tan2(value_type, value_type);
static qreal Sin(qreal);
static qreal Cos(qreal);
static qreal Tan(qreal);
static qreal Tan2(qreal, qreal);
// arcus functions
static value_type ASin(value_type);
static value_type ACos(value_type);
static value_type ATan(value_type);
static value_type ATan2(value_type, value_type);
static qreal ASin(qreal);
static qreal ACos(qreal);
static qreal ATan(qreal);
static qreal ATan2(qreal, qreal);
// hyperbolic functions
static value_type Sinh(value_type);
static value_type Cosh(value_type);
static value_type Tanh(value_type);
static qreal Sinh(qreal);
static qreal Cosh(qreal);
static qreal Tanh(qreal);
// arcus hyperbolic functions
static value_type ASinh(value_type);
static value_type ACosh(value_type);
static value_type ATanh(value_type);
static qreal ASinh(qreal);
static qreal ACosh(qreal);
static qreal ATanh(qreal);
// Logarithm functions
static value_type Log2(value_type); // Logarithm Base 2
static value_type Log10(value_type); // Logarithm Base 10
static value_type Ln(value_type); // Logarithm Base e (natural logarithm)
static qreal Log2(qreal); // Logarithm Base 2
static qreal Log10(qreal); // Logarithm Base 10
static qreal Ln(qreal); // Logarithm Base e (natural logarithm)
// misc
static value_type Exp(value_type);
static value_type Abs(value_type);
static value_type Sqrt(value_type);
static value_type Rint(value_type);
static value_type Sign(value_type);
static qreal Exp(qreal);
static qreal Abs(qreal);
static qreal Sqrt(qreal);
static qreal Rint(qreal);
static qreal Sign(qreal);
// Prefix operators
// !!! 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
static value_type Sum(const value_type*, int); // sum
static value_type Avg(const value_type*, int); // mean value
static value_type Min(const value_type*, int); // minimum
static value_type Max(const value_type*, int); // maximum
static qreal Sum(const qreal*, int); // sum
static qreal Avg(const qreal*, int); // mean value
static qreal Min(const qreal*, int); // minimum
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

View file

@ -57,12 +57,12 @@ namespace qmu
*/
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)
{
ss << _T(" (") << MUP_VERSION_DATE;
ss << std::dec << _T("; ") << sizeof(void*)*8 << _T("BIT");
ss << " (" << MUP_VERSION_DATE;
ss << std::dec << "; " << sizeof(void*)*8 << "BIT";
#ifdef _DEBUG
ss << _T("; DEBUG");
ss << "; DEBUG";
#else
ss << _T("; RELEASE");
ss << "; RELEASE";
#endif
#ifdef _UNICODE
ss << _T("; UNICODE");
ss << "; UNICODE";
#else
#ifdef _MBCS
ss << _T("; MBCS");
ss << "; MBCS";
#else
ss << _T("; ASCII");
ss << "; ASCII";
#endif
#endif
#ifdef MUP_USE_OPENMP
ss << _T("; OPENMP");
#ifdef QMUP_USE_OPENMP
ss << "; OPENMP";
//#else
// ss << _T("; NO_OPENMP");
// ss << "; NO_OPENMP";
#endif
#if defined(MUP_MATH_EXCEPTIONS)
ss << _T("; MATHEXC");
ss << "; MATHEXC";
//#else
// ss << _T("; NO_MATHEXC");
// ss << "; NO_MATHEXC";
#endif
ss << _T(")");
ss << ")";
}
return ss.str();
@ -417,7 +417,7 @@ namespace qmu
// when calling tellg on a stringstream created from the expression after
// reading a value at the end of an expression. (mu::Parser::IsVal function)
// (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);
ReInit();
}
@ -589,7 +589,7 @@ namespace qmu
\post Will reset the Parser to string parsing mode.
\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)
Error(ecINVALID_VAR_PTR);
@ -610,7 +610,7 @@ namespace qmu
\post Will reset the Parser to string parsing mode.
\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());
m_ConstDef[a_sName] = a_fVal;
@ -923,7 +923,7 @@ namespace qmu
if (optTok.GetCode()==cmASSIGN)
{
if (valTok2.GetCode()!=cmVAR)
Error(ecUNEXPECTED_OPERATOR, -1, _T("="));
Error(ecUNEXPECTED_OPERATOR, -1, "=");
m_vRPN.AddAssignOp(valTok2.GetVar());
}
@ -990,7 +990,7 @@ namespace qmu
associated operators. The Stack is filled beginning from index one the
value at index zero is not used at all.
*/
value_type QmuParserBase::ParseCmdCode() const
qreal QmuParserBase::ParseCmdCode() const
{
return ParseCmdCodeBulk(0, 0);
}
@ -1000,14 +1000,14 @@ namespace qmu
\param nOffset The offset added to variable addresses (for bulk mode)
\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);
// Note: The check for nOffset==0 and nThreadID here is not necessary but
// 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)];
value_type buf;
qreal *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)];
qreal buf;
int sidx(0);
for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok)
{
@ -1033,7 +1033,7 @@ namespace qmu
continue;
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;
case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1]; continue;
@ -1208,7 +1208,7 @@ namespace qmu
case cmVAR:
stVal.push(opt);
m_vRPN.AddVar( static_cast<value_type*>(opt.GetVar()) );
m_vRPN.AddVar( static_cast<qreal*>(opt.GetVar()) );
break;
case cmVAL:
@ -1415,7 +1415,7 @@ namespace qmu
pointer #m_pParseFormula will be changed to the second parse routine the
uses bytecode instead of string parsing.
*/
value_type QmuParserBase::ParseString() const
qreal QmuParserBase::ParseString() const
{
try
{
@ -1610,14 +1610,14 @@ namespace qmu
QmuParserStack<token_type> stOprt(a_stOprt),
stVal(a_stVal);
mu::console() << _T("\nValue stack:\n");
mu::console() << "\nValue stack:\n";
while ( !stVal.empty() )
{
token_type val = stVal.pop();
if (val.GetType()==tpSTR)
mu::console() << _T(" \"") << val.GetAsString() << _T("\" ");
mu::console() << " \"" << val.GetAsString() << "\" ";
else
mu::console() << _T(" ") << val.GetVal() << _T(" ");
mu::console() << " " << val.GetVal() << " ";
}
mu::console() << "\nOperator stack:\n";
@ -1625,37 +1625,37 @@ namespace qmu
{
if (stOprt.top().GetCode()<=cmASSIGN)
{
mu::console() << _T("OPRT_INTRNL \"")
mu::console() << "OPRT_INTRNL \""
<< QmuParserBase::c_DefaultOprt[stOprt.top().GetCode()]
<< _T("\" \n");
<< "\" \n";
}
else
{
switch(stOprt.top().GetCode())
{
case cmVAR: mu::console() << _T("VAR\n"); break;
case cmVAL: mu::console() << _T("VAL\n"); break;
case cmFUNC: mu::console() << _T("FUNC \"")
case cmVAR: mu::console() << "VAR\n"; break;
case cmVAL: mu::console() << "VAL\n"; break;
case cmFUNC: mu::console() << "FUNC \""
<< stOprt.top().GetAsString()
<< _T("\"\n"); break;
case cmFUNC_BULK: mu::console() << _T("FUNC_BULK \"")
<< "\"\n"; break;
case cmFUNC_BULK: mu::console() << "FUNC_BULK \""
<< stOprt.top().GetAsString()
<< _T("\"\n"); break;
case cmOPRT_INFIX: mu::console() << _T("OPRT_INFIX \"")
<< "\"\n"; break;
case cmOPRT_INFIX: mu::console() << "OPRT_INFIX \""
<< stOprt.top().GetAsString()
<< _T("\"\n"); break;
case cmOPRT_BIN: mu::console() << _T("OPRT_BIN \"")
<< "\"\n"; break;
case cmOPRT_BIN: mu::console() << "OPRT_BIN \""
<< stOprt.top().GetAsString()
<< _T("\"\n"); break;
case cmFUNC_STR: mu::console() << _T("FUNC_STR\n"); break;
case cmEND: mu::console() << _T("END\n"); break;
case cmUNKNOWN: mu::console() << _T("UNKNOWN\n"); break;
case cmBO: mu::console() << _T("BRACKET \"(\"\n"); break;
case cmBC: mu::console() << _T("BRACKET \")\"\n"); break;
case cmIF: mu::console() << _T("IF\n"); break;
case cmELSE: mu::console() << _T("ELSE\n"); break;
case cmENDIF: mu::console() << _T("ENDIF\n"); break;
default: mu::console() << stOprt.top().GetCode() << _T(" "); break;
<< "\"\n"; break;
case cmFUNC_STR: mu::console() << "FUNC_STR\n"; break;
case cmEND: mu::console() << "END\n"; break;
case cmUNKNOWN: mu::console() << "UNKNOWN\n"; break;
case cmBO: mu::console() << "BRACKET \"(\"\n"; break;
case cmBC: mu::console() << "BRACKET \")\"\n"; break;
case cmIF: mu::console() << "IF\n"; break;
case cmELSE: mu::console() << "ELSE\n"; break;
case cmENDIF: mu::console() << "ENDIF\n"; break;
default: mu::console() << stOprt.top().GetCode() << " "; break;
}
}
stOprt.pop();
@ -1672,7 +1672,7 @@ namespace qmu
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)")
*/
value_type* QmuParserBase::Eval(int &nStackSize) const
qreal* QmuParserBase::Eval(int &nStackSize) const
{
(this->*m_pParseFormula)();
nStackSize = m_nFinalResultIdx;
@ -1709,13 +1709,13 @@ namespace qmu
\return The evaluation result
\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)();
}
//---------------------------------------------------------------------------
void QmuParserBase::Eval(value_type *results, int nBulkSize)
void QmuParserBase::Eval(qreal *results, int nBulkSize)
{
CreateRPN();

View file

@ -68,10 +68,10 @@ private:
the function pointer to the parser function depending on
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. */
typedef std::vector<value_type> valbuf_type;
typedef std::vector<qreal> valbuf_type;
/** \brief Type for a vector of strings. */
typedef std::vector<string_type> stringbuf_type;
@ -80,7 +80,7 @@ private:
typedef QmuParserTokenReader token_reader_type;
/** \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. */
static const int s_MaxNumOpenMPThreads = 4;
@ -101,9 +101,9 @@ private:
virtual ~QmuParserBase();
value_type Eval() const;
value_type* Eval(int &nStackSize) const;
void Eval(value_type *results, int nBulkSize);
qreal Eval() const;
qreal* Eval(int &nStackSize) const;
void Eval(qreal *results, int nBulkSize);
int GetNumResults() const;
@ -137,9 +137,9 @@ private:
unsigned a_iPri=0,
EOprtAssociativity a_eAssociativity = oaLEFT,
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 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 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;
value_type ParseString() const;
value_type ParseCmdCode() const;
value_type ParseCmdCodeBulk(int nOffset, int nThreadID) const;
qreal ParseString() const;
qreal ParseCmdCode() const;
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
void CheckName(const string_type &a_strName, const string_type &a_CharSet) const;
void CheckOprt(const string_type &a_sName,

View file

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

View file

@ -48,9 +48,9 @@ namespace qmu
{
struct //SValData
{
value_type *ptr;
value_type data;
value_type data2;
qreal *ptr;
qreal data;
qreal data2;
} Val;
struct //SFunData
@ -66,7 +66,7 @@ namespace qmu
struct //SOprtData
{
value_type *ptr;
qreal *ptr;
int offset;
} Oprt;
};
@ -87,7 +87,7 @@ class QmuParserByteCode
private:
/** \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. */
typedef std::vector<SToken> rpn_type;
@ -112,11 +112,11 @@ public:
QmuParserByteCode& operator=(const QmuParserByteCode &a_ByteCode);
void Assign(const QmuParserByteCode &a_ByteCode);
void AddVar(value_type *a_pVar);
void AddVal(value_type a_fVal);
void AddVar(qreal *a_pVar);
void AddVal(qreal a_fVal);
void AddOp(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 AddBulkFun(generic_fun_type a_pFun, int a_iArgc);
void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx);

View file

@ -34,20 +34,13 @@
\brief This file contains standard definitions used by the parser.
*/
#define QMUP_VERSION _T("2.2.3")
#define QMUP_VERSION_DATE _T("20121222; SF")
#define QMUP_VERSION "2.2.3"
#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. */
//#define MUP_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
//#define QMUP_MATH_EXCEPTIONS
/** \brief Activate this option in order to compile with OpenMP support.
@ -59,13 +52,7 @@
/** \brief Definition of the basic parser string type. */
#define MUP_STRING_TYPE std::wstring
#if !defined(_T)
#define _T(x) L##x
#endif // not defined _T
#else
#ifndef _T
#define _T(x) x
#endif
/** \brief Definition of the basic parser string type. */
#define MUP_STRING_TYPE std::string
@ -89,9 +76,9 @@
if (!(COND)) \
{ \
stringstream_type ss; \
ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") \
<< __FILE__ << _T(" line ") \
<< __LINE__ << _T("."); \
ss << "Assertion \"" #COND "\" failed: ") \
<< __FILE__ << " line " \
<< __LINE__ << "."; \
throw ParserError( ss.str() ); \
}
#else
@ -238,12 +225,6 @@ namespace qmu
//------------------------------------------------------------------------------
// 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.
Depends on wether UNICODE is used or not.
@ -264,10 +245,10 @@ namespace qmu
// Data container types
/** \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. */
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. */
typedef std::map<string_type, std::size_t> strmap_type;
@ -275,91 +256,91 @@ namespace qmu
// Parser callbacks
/** \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. */
typedef value_type (*fun_type0)();
typedef qreal (*fun_type0)();
/** \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. */
typedef value_type (*fun_type2)(value_type, value_type);
typedef qreal (*fun_type2)(qreal, qreal);
/** \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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
typedef value_type (*bulkfun_type0)(int, int);
typedef qreal (*bulkfun_type0)(int, int);
/** \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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
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. */
typedef value_type* (*facfun_type)(const char_type*, void*);
typedef qreal* (*facfun_type)(const char_type*, void*);
} // end of namespace
#endif

View file

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

View file

@ -35,49 +35,49 @@ using namespace std;
/** \brief Namespace for mathematical applications. */
namespace qmu
{
value_type QmuParserInt::Abs(value_type v) { return (value_type)Round(fabs((double)v)); }
value_type QmuParserInt::Sign(value_type v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; }
value_type QmuParserInt::Ite(value_type v1,
value_type v2,
value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); }
value_type QmuParserInt::Add(value_type v1, value_type v2) { return Round(v1) + Round(v2); }
value_type QmuParserInt::Sub(value_type v1, value_type v2) { return Round(v1) - Round(v2); }
value_type QmuParserInt::Mul(value_type v1, value_type v2) { return Round(v1) * Round(v2); }
value_type QmuParserInt::Div(value_type v1, value_type v2) { return Round(v1) / Round(v2); }
value_type QmuParserInt::Mod(value_type v1, value_type v2) { return Round(v1) % Round(v2); }
value_type QmuParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); }
value_type QmuParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); }
value_type QmuParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); }
value_type QmuParserInt::LogOr(value_type v1, value_type v2) { return Round(v1) | Round(v2); }
value_type QmuParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); }
value_type QmuParserInt::Or(value_type v1, value_type v2) { return Round(v1) || Round(v2); }
value_type QmuParserInt::Less(value_type v1, value_type v2) { return Round(v1) < Round(v2); }
value_type QmuParserInt::Greater(value_type v1, value_type v2) { return Round(v1) > Round(v2); }
value_type QmuParserInt::LessEq(value_type v1, value_type v2) { return Round(v1) <= Round(v2); }
value_type QmuParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); }
value_type QmuParserInt::Equal(value_type v1, value_type v2) { return Round(v1) == Round(v2); }
value_type QmuParserInt::NotEqual(value_type v1, value_type v2) { return Round(v1) != Round(v2); }
value_type QmuParserInt::Not(value_type v) { return !Round(v); }
qreal QmuParserInt::Abs(qreal v) { return (qreal)Round(fabs((double)v)); }
qreal QmuParserInt::Sign(qreal v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; }
qreal QmuParserInt::Ite(qreal v1,
qreal v2,
qreal v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); }
qreal QmuParserInt::Add(qreal v1, qreal v2) { return Round(v1) + Round(v2); }
qreal QmuParserInt::Sub(qreal v1, qreal v2) { return Round(v1) - Round(v2); }
qreal QmuParserInt::Mul(qreal v1, qreal v2) { return Round(v1) * Round(v2); }
qreal QmuParserInt::Div(qreal v1, qreal v2) { return Round(v1) / Round(v2); }
qreal QmuParserInt::Mod(qreal v1, qreal v2) { return Round(v1) % Round(v2); }
qreal QmuParserInt::Shr(qreal v1, qreal v2) { return Round(v1) >> Round(v2); }
qreal QmuParserInt::Shl(qreal v1, qreal v2) { return Round(v1) << Round(v2); }
qreal QmuParserInt::LogAnd(qreal v1, qreal v2) { return Round(v1) & Round(v2); }
qreal QmuParserInt::LogOr(qreal v1, qreal v2) { return Round(v1) | Round(v2); }
qreal QmuParserInt::And(qreal v1, qreal v2) { return Round(v1) && Round(v2); }
qreal QmuParserInt::Or(qreal v1, qreal v2) { return Round(v1) || Round(v2); }
qreal QmuParserInt::Less(qreal v1, qreal v2) { return Round(v1) < Round(v2); }
qreal QmuParserInt::Greater(qreal v1, qreal v2) { return Round(v1) > Round(v2); }
qreal QmuParserInt::LessEq(qreal v1, qreal v2) { return Round(v1) <= Round(v2); }
qreal QmuParserInt::GreaterEq(qreal v1, qreal v2) { return Round(v1) >= Round(v2); }
qreal QmuParserInt::Equal(qreal v1, qreal v2) { return Round(v1) == Round(v2); }
qreal QmuParserInt::NotEqual(qreal v1, qreal v2) { return Round(v1) != Round(v2); }
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));
}
//---------------------------------------------------------------------------
// Unary operator Callbacks: Infix operators
value_type QmuParserInt::UnaryMinus(value_type v)
qreal QmuParserInt::UnaryMinus(qreal 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)
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)
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)
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)
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)
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)
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
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);
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)
return 0;
@ -135,7 +135,7 @@ int QmuParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fV
return 0;
*a_iPos += (int)iEnd;
*a_fVal = (value_type)iVal;
*a_fVal = (qreal)iVal;
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.
*/
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') )
return 0;
@ -166,12 +166,12 @@ int QmuParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a
return 1;
*a_iPos += (int)(2 + nPos);
*a_fVal = (value_type)iVal;
*a_fVal = (qreal)iVal;
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]!='#')
return 0;
@ -187,7 +187,7 @@ int QmuParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a
return 0;
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_iPos += i+1;
@ -220,21 +220,21 @@ void QmuParserInt::InitConst()
//---------------------------------------------------------------------------
void QmuParserInt::InitCharSets()
{
DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
DefineOprtChars( _T("+-*^/?<>=!%&|~'_") );
DefineInfixOprtChars( _T("/+-*^?<>=!%&|~'_") );
DefineNameChars( "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
DefineOprtChars( "+-*^/?<>=!%&|~'_" );
DefineInfixOprtChars( "/+-*^?<>=!%&|~'_" );
}
//---------------------------------------------------------------------------
/** \brief Initialize the default functions. */
void QmuParserInt::InitFun()
{
DefineFun( _T("sign"), Sign);
DefineFun( _T("abs"), Abs);
DefineFun( _T("if"), Ite);
DefineFun( _T("sum"), Sum);
DefineFun( _T("min"), Min);
DefineFun( _T("max"), Max);
DefineFun( "sign", Sign);
DefineFun( "abs", Abs);
DefineFun( "if", Ite);
DefineFun( "sum", Sum);
DefineFun( "min", Min);
DefineFun( "max", Max);
}
//---------------------------------------------------------------------------
@ -247,31 +247,31 @@ void QmuParserInt::InitOprt()
// Disable all built in operators, they wont work with integer numbers
// since they are designed for floating point numbers
DefineInfixOprt( _T("-"), UnaryMinus);
DefineInfixOprt( _T("!"), Not);
DefineInfixOprt( "-", UnaryMinus);
DefineInfixOprt( "!", Not);
DefineOprt( _T("&"), LogAnd, prLOGIC);
DefineOprt( _T("|"), LogOr, prLOGIC);
DefineOprt( _T("&&"), And, prLOGIC);
DefineOprt( _T("||"), Or, prLOGIC);
DefineOprt( "&", LogAnd, prLOGIC);
DefineOprt( "|", LogOr, prLOGIC);
DefineOprt( "&&", And, prLOGIC);
DefineOprt( "||", Or, prLOGIC);
DefineOprt( _T("<"), Less, prCMP);
DefineOprt( _T(">"), Greater, prCMP);
DefineOprt( _T("<="), LessEq, prCMP);
DefineOprt( _T(">="), GreaterEq, prCMP);
DefineOprt( _T("=="), Equal, prCMP);
DefineOprt( _T("!="), NotEqual, prCMP);
DefineOprt( "<", Less, prCMP);
DefineOprt( ">", Greater, prCMP);
DefineOprt( "<=", LessEq, prCMP);
DefineOprt( ">=", GreaterEq, prCMP);
DefineOprt( "==", Equal, prCMP);
DefineOprt( "!=", NotEqual, prCMP);
DefineOprt( _T("+"), Add, prADD_SUB);
DefineOprt( _T("-"), Sub, prADD_SUB);
DefineOprt( "+", Add, prADD_SUB);
DefineOprt( "-", Sub, prADD_SUB);
DefineOprt( _T("*"), Mul, prMUL_DIV);
DefineOprt( _T("/"), Div, prMUL_DIV);
DefineOprt( _T("%"), Mod, prMUL_DIV);
DefineOprt( "*", Mul, prMUL_DIV);
DefineOprt( "/", Div, prMUL_DIV);
DefineOprt( "%", Mod, prMUL_DIV);
DefineOprt( _T("^"), Pow, prPOW, oaRIGHT);
DefineOprt( _T(">>"), Shr, prMUL_DIV+1);
DefineOprt( _T("<<"), Shl, prMUL_DIV+1);
DefineOprt( "^", Pow, prPOW, oaRIGHT);
DefineOprt( ">>", Shr, prMUL_DIV+1);
DefineOprt( "<<", Shl, prMUL_DIV+1);
}
} // namespace qmu

View file

@ -43,42 +43,42 @@ namespace qmu
class QmuParserInt : public QmuParserBase
{
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 value_type Sign(value_type);
static value_type Ite(value_type, value_type, value_type);
static qreal Abs(qreal);
static qreal Sign(qreal);
static qreal Ite(qreal, qreal, qreal);
// !! 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
static value_type Sum(const value_type* a_afArg, int a_iArgc); // sum
static value_type Min(const value_type* a_afArg, int a_iArgc); // minimum
static value_type Max(const value_type* a_afArg, int a_iArgc); // maximum
static qreal Sum(const qreal* a_afArg, int a_iArgc); // sum
static qreal Min(const qreal* a_afArg, int a_iArgc); // minimum
static qreal Max(const qreal* a_afArg, int a_iArgc); // maximum
// binary operator callbacks
static value_type Add(value_type v1, value_type v2);
static value_type Sub(value_type v1, value_type v2);
static value_type Mul(value_type v1, value_type v2);
static value_type Div(value_type v1, value_type v2);
static value_type Mod(value_type v1, value_type v2);
static value_type Pow(value_type v1, value_type v2);
static value_type Shr(value_type v1, value_type v2);
static value_type Shl(value_type v1, value_type v2);
static value_type LogAnd(value_type v1, value_type v2);
static value_type LogOr(value_type v1, value_type v2);
static value_type And(value_type v1, value_type v2);
static value_type Or(value_type v1, value_type v2);
static value_type Xor(value_type v1, value_type v2);
static value_type Less(value_type v1, value_type v2);
static value_type Greater(value_type v1, value_type v2);
static value_type LessEq(value_type v1, value_type v2);
static value_type GreaterEq(value_type v1, value_type v2);
static value_type Equal(value_type v1, value_type v2);
static value_type NotEqual(value_type v1, value_type v2);
static value_type Not(value_type v1);
static qreal Add(qreal v1, qreal v2);
static qreal Sub(qreal v1, qreal v2);
static qreal Mul(qreal v1, qreal v2);
static qreal Div(qreal v1, qreal v2);
static qreal Mod(qreal v1, qreal v2);
static qreal Pow(qreal v1, qreal v2);
static qreal Shr(qreal v1, qreal v2);
static qreal Shl(qreal v1, qreal v2);
static qreal LogAnd(qreal v1, qreal v2);
static qreal LogOr(qreal v1, qreal v2);
static qreal And(qreal v1, qreal v2);
static qreal Or(qreal v1, qreal v2);
static qreal Xor(qreal v1, qreal v2);
static qreal Less(qreal v1, qreal v2);
static qreal Greater(qreal v1, qreal v2);
static qreal LessEq(qreal v1, qreal v2);
static qreal GreaterEq(qreal v1, qreal v2);
static qreal Equal(qreal v1, qreal v2);
static qreal NotEqual(qreal v1, qreal v2);
static qreal Not(qreal v1);
static int IsHexVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);
static int IsBinVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);
static int IsVal (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, qreal *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. */
template<class TChar>

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -49,118 +49,118 @@ namespace qmu
static int c_iCount;
// 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 value_type f2of2(value_type , value_type v) {return v;};
static qreal f1of2(qreal v, qreal ) {return v;};
static qreal f2of2(qreal , qreal v) {return v;};
static value_type f1of3(value_type v, value_type , value_type ) {return v;};
static value_type f2of3(value_type , value_type v, value_type ) {return v;};
static value_type f3of3(value_type , value_type , value_type v) {return v;};
static qreal f1of3(qreal v, qreal , qreal ) {return v;};
static qreal f2of3(qreal , qreal v, qreal ) {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 value_type f2of4(value_type , value_type v, value_type , value_type ) {return v;}
static value_type f3of4(value_type , value_type, value_type v, value_type ) {return v;}
static value_type f4of4(value_type , value_type, value_type , value_type v) {return v;}
static qreal f1of4(qreal v, qreal, qreal , qreal ) {return v;}
static qreal f2of4(qreal , qreal v, qreal , qreal ) {return v;}
static qreal f3of4(qreal , qreal, qreal v, qreal ) {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 value_type f2of5(value_type , value_type v, value_type , value_type , value_type ) { return v; }
static value_type f3of5(value_type , value_type, value_type v, value_type , value_type ) { return v; }
static value_type f4of5(value_type , value_type, value_type , value_type v, value_type ) { return v; }
static value_type f5of5(value_type , value_type, value_type , value_type , value_type v) { return v; }
static qreal f1of5(qreal v, qreal, qreal , qreal , qreal ) { return v; }
static qreal f2of5(qreal , qreal v, qreal , qreal , qreal ) { return v; }
static qreal f3of5(qreal , qreal, qreal v, qreal , qreal ) { return v; }
static qreal f4of5(qreal , qreal, qreal , qreal v, qreal ) { 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 value_type Max(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 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 value_type times3(value_type v1) { return v1*3; }
static value_type sqr(value_type v1) { return v1*v1; }
static value_type sign(value_type v) { return -v; }
static value_type add(value_type v1, value_type v2) { return v1+v2; }
static value_type land(value_type v1, value_type v2) { return (int)v1 & (int)v2; }
static qreal plus2(qreal v1) { return v1+2; }
static qreal times3(qreal v1) { return v1*3; }
static qreal sqr(qreal v1) { return v1*v1; }
static qreal sign(qreal v) { return -v; }
static qreal add(qreal v1, qreal v2) { return v1+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)
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];
}
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)
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];
}
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)
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];
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;
}
static value_type ValueOf(const char_type*)
static qreal ValueOf(const char_type*)
{
return 123;
}
static value_type StrFun1(const char_type* v1)
static qreal StrFun1(const char_type* v1)
{
int val(0);
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);
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);
stringstream_type(v1) >> val;
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;
return val;
}
// postfix operator callback
static value_type Mega(value_type a_fVal) { return a_fVal * (value_type)1e6; }
static value_type Micro(value_type a_fVal) { return a_fVal * (value_type)1e-6; }
static value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; }
static qreal Mega(qreal a_fVal) { return a_fVal * (qreal)1e6; }
static qreal Micro(qreal a_fVal) { return a_fVal * (qreal)1e-6; }
static qreal Milli(qreal a_fVal) { return a_fVal / (qreal)1e3; }
// 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 TestSyntax();

View file

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

View file

@ -514,7 +514,7 @@ namespace qmu
Error(ecUNEXPECTED_EOF, m_iPos);
if (m_iBrackets>0)
Error(ecMISSING_PARENS, m_iPos, _T(")"));
Error(ecMISSING_PARENS, m_iPos, ")");
m_iSynFlags = 0;
a_Tok.Set(cmEND);
@ -722,7 +722,7 @@ namespace qmu
assert(m_pParser);
string_type strTok;
value_type fVal(0);
qreal fVal(0);
int iEnd(0);
// 2.) Check for user defined constant
@ -855,7 +855,7 @@ namespace qmu
// If a factory is available implicitely create new variables
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 );
// Do not use m_pParser->DefineVar( strTok, fVar );
@ -869,7 +869,7 @@ namespace qmu
}
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
}
@ -897,15 +897,15 @@ namespace qmu
std::size_t iEnd(0), iSkip(0);
// 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;
strBuf.replace(iEnd-1, 2, _T("\"") );
strBuf.replace(iEnd-1, 2, "\"" );
iSkip++;
}
if (iEnd==string_type::npos)
Error(ecUNTERMINATED_STRING, m_iPos, _T("\"") );
Error(ecUNTERMINATED_STRING, m_iPos, "\"" );
string_type strTok(strBuf.begin(), strBuf.begin()+iEnd);

View file

@ -52,7 +52,7 @@ namespace qmu
{
private:
typedef QmuParserToken<value_type, string_type> token_type;
typedef QmuParserToken<qreal, string_type> token_type;
public:
@ -146,7 +146,7 @@ namespace qmu
void *m_pFactoryData;
std::list<identfun_type> m_vIdentFun; ///< Value token identification function
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;
token_type m_lastTok;
char_type m_cArgSep; ///< The character used for separating function arguments