Fix gcc's warnings.
--HG-- branch : feature
This commit is contained in:
parent
f505234bbd
commit
37ecf9fd86
|
@ -64,7 +64,7 @@ qreal QmuParser::ACosh(qreal v)
|
||||||
|
|
||||||
qreal QmuParser::ATanh(qreal v)
|
qreal QmuParser::ATanh(qreal v)
|
||||||
{
|
{
|
||||||
return ((qreal)0.5 * log((1 + v) / (1 - v)));
|
return (0.5 * log((1 + v) / (1 - v)));
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
// Logarithm functions
|
// Logarithm functions
|
||||||
|
@ -78,7 +78,7 @@ qreal QmuParser::Log2(qreal v)
|
||||||
throw QmuParserError(ecDOMAIN_ERROR, "Log2");
|
throw QmuParserError(ecDOMAIN_ERROR, "Log2");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return log(v)/log((qreal)2);
|
return log(v)/log(2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logarithm base 10
|
// Logarithm base 10
|
||||||
|
@ -102,12 +102,12 @@ qreal QmuParser::Abs(qreal v)
|
||||||
|
|
||||||
qreal QmuParser::Rint(qreal v)
|
qreal QmuParser::Rint(qreal v)
|
||||||
{
|
{
|
||||||
return qFloor(v + (qreal)0.5);
|
return qFloor(v + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal QmuParser::Sign(qreal v)
|
qreal QmuParser::Sign(qreal v)
|
||||||
{
|
{
|
||||||
return (qreal)((v<0) ? -1 : (v>0) ? 1 : 0);
|
return ((v<0) ? -1 : (v>0) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -152,7 +152,7 @@ qreal QmuParser::Avg(const qreal *a_afArg, int a_iArgc)
|
||||||
}
|
}
|
||||||
qreal 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/(qreal)a_iArgc;
|
return fRes/static_cast<qreal>(a_iArgc);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -218,12 +218,12 @@ int QmuParser::IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal)
|
||||||
stream >> fVal;
|
stream >> fVal;
|
||||||
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
|
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
|
||||||
|
|
||||||
if (iEnd==(stringstream_type::pos_type)-1)
|
if (iEnd==static_cast<stringstream_type::pos_type>(-1))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*a_iPos += (int)iEnd;
|
*a_iPos += static_cast<int>(iEnd);
|
||||||
*a_fVal = fVal;
|
*a_fVal = fVal;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -325,8 +325,11 @@ void QmuParser::InitOprt()
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
void QmuParser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
|
void QmuParser::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(pExpr);
|
||||||
|
Q_UNUSED(nStart);
|
||||||
|
Q_UNUSED(nEnd);
|
||||||
// this is just sample code to illustrate modifying variable names on the fly.
|
// this is just sample code to illustrate modifying variable names on the fly.
|
||||||
// I'm not sure anyone really needs such a feature...
|
// I'm not sure anyone really needs such a feature...
|
||||||
/*
|
/*
|
||||||
|
@ -372,9 +375,9 @@ qreal QmuParser::Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon) const
|
||||||
|
|
||||||
// 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 (qFuzzyCompare(fEpsilon + 1, 1 + 0))
|
||||||
{
|
{
|
||||||
fEpsilon = (a_fPos==0) ? (qreal)1e-10 : (qreal)1e-7 * a_fPos;
|
fEpsilon = (qFuzzyCompare(a_fPos + 1, 1 + 0)) ? static_cast<qreal>(1e-10) : static_cast<qreal>(1e-7) * a_fPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
*a_Var = a_fPos+2 * fEpsilon; f[0] = Eval();
|
*a_Var = a_fPos+2 * fEpsilon; f[0] = Eval();
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace qmu
|
||||||
virtual void InitFun();
|
virtual void InitFun();
|
||||||
virtual void InitConst();
|
virtual void InitConst();
|
||||||
virtual void InitOprt();
|
virtual void InitOprt();
|
||||||
virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);
|
virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd);
|
||||||
qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const;
|
qreal Diff(qreal *a_Var, qreal a_fPos, qreal a_fEpsilon = 0) const;
|
||||||
protected:
|
protected:
|
||||||
static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal);
|
static int IsVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal);
|
||||||
|
|
|
@ -58,9 +58,9 @@ const QStringList QmuParserBase::c_DefaultOprt = QStringList() << "<=" << ">=" <
|
||||||
* @throw ParserException if a_szFormula is null.
|
* @throw ParserException if a_szFormula is null.
|
||||||
*/
|
*/
|
||||||
QmuParserBase::QmuParserBase()
|
QmuParserBase::QmuParserBase()
|
||||||
:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_pTokenReader(), m_FunDef(),
|
:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(),
|
||||||
m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true),
|
m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(),
|
||||||
m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(),
|
m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(),
|
||||||
m_nFinalResultIdx(0)
|
m_nFinalResultIdx(0)
|
||||||
{
|
{
|
||||||
InitTokenReader();
|
InitTokenReader();
|
||||||
|
@ -73,9 +73,10 @@ QmuParserBase::QmuParserBase()
|
||||||
* Tha parser can be safely copy constructed but the bytecode is reset during copy construction.
|
* Tha parser can be safely copy constructed but the bytecode is reset during copy construction.
|
||||||
*/
|
*/
|
||||||
QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser)
|
QmuParserBase::QmuParserBase(const QmuParserBase &a_Parser)
|
||||||
:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_pTokenReader(), m_FunDef(),
|
:m_pParseFormula(&QmuParserBase::ParseString), m_vRPN(), m_vStringBuf(), m_vStringVarBuf(), m_pTokenReader(),
|
||||||
m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(), m_bBuiltInOp(true),
|
m_FunDef(), m_PostOprtDef(), m_InfixOprtDef(), m_OprtDef(), m_ConstDef(), m_StrVarDef(), m_VarDef(),
|
||||||
m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0)
|
m_bBuiltInOp(true), m_sNameChars(), m_sOprtChars(), m_sInfixOprtChars(), m_nIfElseCounter(0), m_vStackBuffer(),
|
||||||
|
m_nFinalResultIdx(0)
|
||||||
{
|
{
|
||||||
m_pTokenReader.reset(new token_reader_type(this));
|
m_pTokenReader.reset(new token_reader_type(this));
|
||||||
Assign(a_Parser);
|
Assign(a_Parser);
|
||||||
|
@ -216,8 +217,12 @@ void QmuParserBase::ReInit() const
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
void QmuParserBase::OnDetectVar(QString * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
|
void QmuParserBase::OnDetectVar(const QString &pExpr, int &nStart, int &nEnd)
|
||||||
{}
|
{
|
||||||
|
Q_UNUSED(pExpr);
|
||||||
|
Q_UNUSED(nStart);
|
||||||
|
Q_UNUSED(nEnd);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
@ -361,6 +366,108 @@ void QmuParserBase::CheckOprt(const QString &a_sName, const QmuParserCallback &a
|
||||||
case cmOPRT_INFIX:
|
case cmOPRT_INFIX:
|
||||||
Error(ecINVALID_INFIX_IDENT, -1, a_sName);
|
Error(ecINVALID_INFIX_IDENT, -1, a_sName);
|
||||||
break;
|
break;
|
||||||
|
case cmLE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmNEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmADD:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSUB:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmDIV:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLAND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLOR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmASSIGN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBO:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmELSE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmENDIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_STR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_BULK:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_BIN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Error(ecINVALID_NAME, -1, a_sName);
|
Error(ecINVALID_NAME, -1, a_sName);
|
||||||
break;
|
break;
|
||||||
|
@ -660,6 +767,54 @@ int QmuParserBase::GetOprtPrecedence(const token_type &a_Tok) const
|
||||||
case cmOPRT_INFIX:
|
case cmOPRT_INFIX:
|
||||||
case cmOPRT_BIN:
|
case cmOPRT_BIN:
|
||||||
return a_Tok.GetPri();
|
return a_Tok.GetPri();
|
||||||
|
case cmBO:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmENDIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_STR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_BULK:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Error(ecINTERNAL_ERROR, 5);
|
Error(ecINTERNAL_ERROR, 5);
|
||||||
return 999;
|
return 999;
|
||||||
|
@ -693,6 +848,69 @@ EOprtAssociativity QmuParserBase::GetOprtAssociativity(const token_type &a_Tok)
|
||||||
return oaRIGHT;
|
return oaRIGHT;
|
||||||
case cmOPRT_BIN:
|
case cmOPRT_BIN:
|
||||||
return a_Tok.GetAssociativity();
|
return a_Tok.GetAssociativity();
|
||||||
|
case cmBO:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmELSE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmENDIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_STR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_BULK:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_INFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return oaNONE;
|
return oaNONE;
|
||||||
}
|
}
|
||||||
|
@ -888,30 +1106,122 @@ void QmuParserBase::ApplyFunc( QStack<token_type> &a_stOpt, QStack<token_type> &
|
||||||
|
|
||||||
switch(funTok.GetCode())
|
switch(funTok.GetCode())
|
||||||
{
|
{
|
||||||
case cmFUNC_STR:
|
case cmFUNC_STR:
|
||||||
stArg.push_back(a_stVal.pop());
|
stArg.push_back(a_stVal.pop());
|
||||||
|
|
||||||
if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR )
|
if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR )
|
||||||
{
|
{
|
||||||
Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString());
|
Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyStrFunc(funTok, stArg);
|
ApplyStrFunc(funTok, stArg);
|
||||||
break;
|
break;
|
||||||
case cmFUNC_BULK:
|
case cmFUNC_BULK:
|
||||||
m_vRPN.AddBulkFun(funTok.GetFuncAddr(), (int)stArg.size());
|
m_vRPN.AddBulkFun(funTok.GetFuncAddr(), stArg.size());
|
||||||
break;
|
break;
|
||||||
case cmOPRT_BIN:
|
case cmOPRT_BIN:
|
||||||
case cmOPRT_POSTFIX:
|
case cmOPRT_POSTFIX:
|
||||||
case cmOPRT_INFIX:
|
case cmOPRT_INFIX:
|
||||||
case cmFUNC:
|
case cmFUNC:
|
||||||
if (funTok.GetArgCount()==-1 && iArgCount==0)
|
if (funTok.GetArgCount()==-1 && iArgCount==0)
|
||||||
{
|
{
|
||||||
Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString());
|
Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical);
|
m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical);
|
||||||
break;
|
break;
|
||||||
|
case cmLE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmNEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmADD:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSUB:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmDIV:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLAND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLOR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmASSIGN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBO:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmELSE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmENDIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// Push dummy value representing the function result to the stack
|
// Push dummy value representing the function result to the stack
|
||||||
token_type token;
|
token_type token;
|
||||||
|
@ -939,7 +1249,7 @@ void QmuParserBase::ApplyIfElse(QStack<token_type> &a_stOpt, QStack<token_type>
|
||||||
token_type vVal1 = a_stVal.pop();
|
token_type vVal1 = a_stVal.pop();
|
||||||
token_type vExpr = a_stVal.pop();
|
token_type vExpr = a_stVal.pop();
|
||||||
|
|
||||||
a_stVal.push( (vExpr.GetVal()!=0) ? vVal1 : vVal2);
|
a_stVal.push( (qFuzzyCompare(vExpr.GetVal()+1, 1+0)==false) ? vVal1 : vVal2);
|
||||||
|
|
||||||
token_type opIf = a_stOpt.pop();
|
token_type opIf = a_stOpt.pop();
|
||||||
Q_ASSERT(opElse.GetCode()==cmELSE);
|
Q_ASSERT(opElse.GetCode()==cmELSE);
|
||||||
|
@ -1031,6 +1341,63 @@ void QmuParserBase::ApplyRemainingOprt(QStack<token_type> &stOpt, QStack<token_t
|
||||||
case cmELSE:
|
case cmELSE:
|
||||||
ApplyIfElse(stOpt, stVal);
|
ApplyIfElse(stOpt, stVal);
|
||||||
break;
|
break;
|
||||||
|
case cmBO:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmENDIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_STR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_BULK:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Error(ecINTERNAL_ERROR);
|
Error(ecINTERNAL_ERROR);
|
||||||
break;
|
break;
|
||||||
|
@ -1082,11 +1449,11 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
|
||||||
continue;
|
continue;
|
||||||
case cmNEQ:
|
case cmNEQ:
|
||||||
--sidx;
|
--sidx;
|
||||||
Stack[sidx] = Stack[sidx] != Stack[sidx+1];
|
Stack[sidx] = (qFuzzyCompare(Stack[sidx], Stack[sidx+1])==false);
|
||||||
continue;
|
continue;
|
||||||
case cmEQ:
|
case cmEQ:
|
||||||
--sidx;
|
--sidx;
|
||||||
Stack[sidx] = Stack[sidx] == Stack[sidx+1];
|
Stack[sidx] = qFuzzyCompare(Stack[sidx], Stack[sidx+1]);
|
||||||
continue;
|
continue;
|
||||||
case cmLT:
|
case cmLT:
|
||||||
--sidx;
|
--sidx;
|
||||||
|
@ -1124,22 +1491,40 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
|
||||||
continue;
|
continue;
|
||||||
case cmLAND:
|
case cmLAND:
|
||||||
--sidx;
|
--sidx;
|
||||||
|
#ifdef Q_CC_GNU
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
|
#endif
|
||||||
Stack[sidx] = Stack[sidx] && Stack[sidx+1];
|
Stack[sidx] = Stack[sidx] && Stack[sidx+1];
|
||||||
|
#ifdef Q_CC_GNU
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
case cmLOR:
|
case cmLOR:
|
||||||
--sidx;
|
--sidx;
|
||||||
|
#ifdef Q_CC_GNU
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
|
#endif
|
||||||
Stack[sidx] = Stack[sidx] || Stack[sidx+1];
|
Stack[sidx] = Stack[sidx] || Stack[sidx+1];
|
||||||
|
#ifdef Q_CC_GNU
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
case cmASSIGN:
|
case cmASSIGN:
|
||||||
--sidx;
|
--sidx;
|
||||||
Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1];
|
Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1];
|
||||||
continue;
|
continue;
|
||||||
//case cmBO: // unused, listed for compiler optimization purposes
|
case cmBO: // unused, listed for compiler optimization purposes
|
||||||
//case cmBC:
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
// Q_ASSERT(INVALID_CODE_IN_BYTECODE);
|
// Q_ASSERT(INVALID_CODE_IN_BYTECODE);
|
||||||
// continue;
|
// continue;
|
||||||
case cmIF:
|
case cmIF:
|
||||||
if (Stack[sidx--]==0)
|
if (qFuzzyCompare(Stack[sidx--]+1, 1+0))
|
||||||
{
|
{
|
||||||
pTok += pTok->Oprt.offset;
|
pTok += pTok->Oprt.offset;
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1534,9 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
|
||||||
continue;
|
continue;
|
||||||
case cmENDIF:
|
case cmENDIF:
|
||||||
continue;
|
continue;
|
||||||
//case cmARG_SEP:
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
// Q_ASSERT(INVALID_CODE_IN_BYTECODE);
|
// Q_ASSERT(INVALID_CODE_IN_BYTECODE);
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
|
@ -1185,55 +1572,57 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
sidx += 1;
|
sidx += 1;
|
||||||
Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)();
|
Stack[sidx] = (*reinterpret_cast<fun_type0>(pTok->Fun.ptr))();
|
||||||
continue;
|
continue;
|
||||||
case 1:
|
case 1:
|
||||||
Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]);
|
Stack[sidx] = (*reinterpret_cast<fun_type1>(pTok->Fun.ptr))(Stack[sidx]);
|
||||||
continue;
|
continue;
|
||||||
case 2:
|
case 2:
|
||||||
sidx -= 1;
|
sidx -= 1;
|
||||||
Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]);
|
Stack[sidx] = (*reinterpret_cast<fun_type2>(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1]);
|
||||||
continue;
|
continue;
|
||||||
case 3:
|
case 3:
|
||||||
sidx -= 2;
|
sidx -= 2;
|
||||||
Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]);
|
Stack[sidx] = (*reinterpret_cast<fun_type3>(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1],
|
||||||
|
Stack[sidx+2]);
|
||||||
continue;
|
continue;
|
||||||
case 4:
|
case 4:
|
||||||
sidx -= 3;
|
sidx -= 3;
|
||||||
Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2],
|
Stack[sidx] = (*reinterpret_cast<fun_type4>(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1],
|
||||||
Stack[sidx+3]);
|
Stack[sidx+2], Stack[sidx+3]);
|
||||||
continue;
|
continue;
|
||||||
case 5:
|
case 5:
|
||||||
sidx -= 4;
|
sidx -= 4;
|
||||||
Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2],
|
Stack[sidx] = (*reinterpret_cast<fun_type5>(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1],
|
||||||
Stack[sidx+3], Stack[sidx+4]);
|
Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]);
|
||||||
continue;
|
continue;
|
||||||
case 6:
|
case 6:
|
||||||
sidx -= 5;
|
sidx -= 5;
|
||||||
Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2],
|
Stack[sidx] = (*reinterpret_cast<fun_type6>(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1],
|
||||||
Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]);
|
Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]);
|
||||||
continue;
|
continue;
|
||||||
case 7:
|
case 7:
|
||||||
sidx -= 6;
|
sidx -= 6;
|
||||||
Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2],
|
Stack[sidx] = (*reinterpret_cast<fun_type7>(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1],
|
||||||
Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]);
|
Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]);
|
||||||
continue;
|
continue;
|
||||||
case 8:
|
case 8:
|
||||||
sidx -= 7;
|
sidx -= 7;
|
||||||
Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2],
|
Stack[sidx] = (*reinterpret_cast<fun_type8>(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1],
|
||||||
Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]);
|
Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6],
|
||||||
|
Stack[sidx+7]);
|
||||||
continue;
|
continue;
|
||||||
case 9:
|
case 9:
|
||||||
sidx -= 8;
|
sidx -= 8;
|
||||||
Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2],
|
Stack[sidx] = (*reinterpret_cast<fun_type9>(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1],
|
||||||
Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7],
|
Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6],
|
||||||
Stack[sidx+8]);
|
Stack[sidx+7], Stack[sidx+8]);
|
||||||
continue;
|
continue;
|
||||||
case 10:
|
case 10:
|
||||||
sidx -= 9;
|
sidx -= 9;
|
||||||
Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2],
|
Stack[sidx] = (*reinterpret_cast<fun_type10>(pTok->Fun.ptr))(Stack[sidx], Stack[sidx+1],
|
||||||
Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7],
|
Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6],
|
||||||
Stack[sidx+8], Stack[sidx+9]);
|
Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]);
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
if (iArgCount>0) // function with variable arguments store the number as a negative value
|
if (iArgCount>0) // function with variable arguments store the number as a negative value
|
||||||
|
@ -1242,7 +1631,7 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
|
||||||
}
|
}
|
||||||
|
|
||||||
sidx -= -iArgCount - 1;
|
sidx -= -iArgCount - 1;
|
||||||
Stack[sidx] =(*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount);
|
Stack[sidx] =(*reinterpret_cast<multfun_type>(pTok->Fun.ptr))(&Stack[sidx], -iArgCount);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1253,25 +1642,27 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
|
||||||
|
|
||||||
// The index of the string argument in the string table
|
// The index of the string argument in the string table
|
||||||
int iIdxStack = pTok->Fun.idx;
|
int iIdxStack = pTok->Fun.idx;
|
||||||
Q_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() );
|
Q_ASSERT( iIdxStack>=0 && iIdxStack<m_vStringBuf.size() );
|
||||||
|
|
||||||
switch(pTok->Fun.argc) // switch according to argument count
|
switch(pTok->Fun.argc) // switch according to argument count
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack));
|
Stack[sidx] = (*reinterpret_cast<strfun_type1>(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack));
|
||||||
continue;
|
continue;
|
||||||
case 1:
|
case 1:
|
||||||
Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx]);
|
Stack[sidx] = (*reinterpret_cast<strfun_type2>(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack),
|
||||||
|
Stack[sidx]);
|
||||||
continue;
|
continue;
|
||||||
case 2:
|
case 2:
|
||||||
Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf.at(iIdxStack), Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<strfun_type3>(pTok->Fun.ptr))(m_vStringBuf.at(iIdxStack),
|
||||||
Stack[sidx+1]);
|
Stack[sidx], Stack[sidx+1]);
|
||||||
continue;
|
continue;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
case cmFUNC_BULK:
|
case cmFUNC_BULK:
|
||||||
{
|
{
|
||||||
int iArgCount = pTok->Fun.argc;
|
int iArgCount = pTok->Fun.argc;
|
||||||
|
@ -1281,59 +1672,61 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
sidx += 1;
|
sidx += 1;
|
||||||
Stack[sidx] = (*(bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID);
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type0>(pTok->Fun.ptr))(nOffset, nThreadID);
|
||||||
continue;
|
continue;
|
||||||
case 1:
|
case 1:
|
||||||
Stack[sidx] = (*(bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]);
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type1>(pTok->Fun.ptr))(nOffset, nThreadID,
|
||||||
|
Stack[sidx]);
|
||||||
continue;
|
continue;
|
||||||
case 2:
|
case 2:
|
||||||
sidx -= 1;
|
sidx -= 1;
|
||||||
Stack[sidx] = (*(bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type2>(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx],
|
||||||
Stack[sidx+1]);
|
Stack[sidx+1]);
|
||||||
continue;
|
continue;
|
||||||
case 3:
|
case 3:
|
||||||
sidx -= 2;
|
sidx -= 2;
|
||||||
Stack[sidx] = (*(bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type3>(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx],
|
||||||
Stack[sidx+1], Stack[sidx+2]);
|
Stack[sidx+1], Stack[sidx+2]);
|
||||||
continue;
|
continue;
|
||||||
case 4:
|
case 4:
|
||||||
sidx -= 3;
|
sidx -= 3;
|
||||||
Stack[sidx] = (*(bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type4>(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx],
|
||||||
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]);
|
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]);
|
||||||
continue;
|
continue;
|
||||||
case 5:
|
case 5:
|
||||||
sidx -= 4;
|
sidx -= 4;
|
||||||
Stack[sidx] = (*(bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type5>(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx],
|
||||||
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
||||||
Stack[sidx+4]);
|
Stack[sidx+4]);
|
||||||
continue;
|
continue;
|
||||||
case 6:
|
case 6:
|
||||||
sidx -= 5;
|
sidx -= 5;
|
||||||
Stack[sidx] = (*(bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type6>(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx],
|
||||||
Stack[sidx+1], Stack[sidx+2],
|
Stack[sidx+1], Stack[sidx+2],
|
||||||
Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]);
|
Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]);
|
||||||
continue;
|
continue;
|
||||||
case 7:
|
case 7:
|
||||||
sidx -= 6;
|
sidx -= 6;
|
||||||
Stack[sidx] = (*(bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type7>(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx],
|
||||||
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
||||||
Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]);
|
Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]);
|
||||||
continue;
|
continue;
|
||||||
case 8:
|
case 8:
|
||||||
sidx -= 7;
|
sidx -= 7;
|
||||||
Stack[sidx] = (*(bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type8>(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx],
|
||||||
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
||||||
Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]);
|
Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]);
|
||||||
continue;
|
continue;
|
||||||
case 9:
|
case 9:
|
||||||
sidx -= 8;
|
sidx -= 8;
|
||||||
Stack[sidx] = (*(bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type9>(pTok->Fun.ptr))(nOffset, nThreadID, Stack[sidx],
|
||||||
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
||||||
Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]);
|
Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]);
|
||||||
continue;
|
continue;
|
||||||
case 10:
|
case 10:
|
||||||
sidx -= 9;
|
sidx -= 9;
|
||||||
Stack[sidx] = (*(bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx],
|
Stack[sidx] = (*reinterpret_cast<bulkfun_type10>(pTok->Fun.ptr))(nOffset, nThreadID,
|
||||||
|
Stack[sidx],
|
||||||
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
Stack[sidx+1], Stack[sidx+2], Stack[sidx+3],
|
||||||
Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8],
|
Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8],
|
||||||
Stack[sidx+9]);
|
Stack[sidx+9]);
|
||||||
|
@ -1343,16 +1736,30 @@ qreal QmuParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//case cmSTRING:
|
case cmSTRING:
|
||||||
//case cmOPRT_BIN:
|
Q_UNREACHABLE();
|
||||||
//case cmOPRT_POSTFIX:
|
break;
|
||||||
//case cmOPRT_INFIX:
|
case cmOPRT_BIN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_INFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
// Q_ASSERT(INVALID_CODE_IN_BYTECODE);
|
// Q_ASSERT(INVALID_CODE_IN_BYTECODE);
|
||||||
// continue;
|
// continue;
|
||||||
|
case cmEND:
|
||||||
//case cmEND:
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
// return Stack[m_nFinalResultIdx];
|
// return Stack[m_nFinalResultIdx];
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Error(ecINTERNAL_ERROR, 3);
|
Error(ecINTERNAL_ERROR, 3);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1392,7 +1799,7 @@ void QmuParserBase::CreateRPN() const
|
||||||
// Next three are different kind of value entries
|
// Next three are different kind of value entries
|
||||||
//
|
//
|
||||||
case cmSTRING:
|
case cmSTRING:
|
||||||
opt.SetIdx((int)m_vStringBuf.size()); // Assign buffer index to token
|
opt.SetIdx(m_vStringBuf.size()); // Assign buffer index to token
|
||||||
stVal.push(opt);
|
stVal.push(opt);
|
||||||
m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer
|
m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer
|
||||||
break;
|
break;
|
||||||
|
@ -1549,6 +1956,27 @@ void QmuParserBase::CreateRPN() const
|
||||||
stOpt.push(opt);
|
stOpt.push(opt);
|
||||||
ApplyFunc(stOpt, stVal, 1); // this is the postfix operator
|
ApplyFunc(stOpt, stVal, 1); // this is the postfix operator
|
||||||
break;
|
break;
|
||||||
|
case cmENDIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Error(ecINTERNAL_ERROR, 3);
|
Error(ecINTERNAL_ERROR, 3);
|
||||||
} // end of switch operator-token
|
} // end of switch operator-token
|
||||||
|
@ -1634,7 +2062,7 @@ qreal QmuParserBase::ParseString() const
|
||||||
* @param a_strTok [in] The token string representation associated with the error.
|
* @param a_strTok [in] The token string representation associated with the error.
|
||||||
* @throw ParserException always throws thats the only purpose of this function.
|
* @throw ParserException always throws thats the only purpose of this function.
|
||||||
*/
|
*/
|
||||||
void QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const
|
void Q_NORETURN QmuParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const QString &a_sTok) const
|
||||||
{
|
{
|
||||||
throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos);
|
throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos);
|
||||||
}
|
}
|
||||||
|
@ -1882,6 +2310,72 @@ void QmuParserBase::StackDump(const QStack<token_type> &a_stVal, const QStack<to
|
||||||
case cmENDIF:
|
case cmENDIF:
|
||||||
qDebug() << "ENDIF\n";
|
qDebug() << "ENDIF\n";
|
||||||
break;
|
break;
|
||||||
|
case cmLE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmNEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmADD:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSUB:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmDIV:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLAND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLOR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmASSIGN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
qDebug() << stOprt.top().GetCode() << " ";
|
qDebug() << stOprt.top().GetCode() << " ";
|
||||||
break;
|
break;
|
||||||
|
@ -1950,7 +2444,7 @@ void QmuParserBase::Eval(qreal *results, int nBulkSize)
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
#ifdef MUP_USE_OPENMP
|
#ifdef QMUP_USE_OPENMP
|
||||||
//#define DEBUG_OMP_STUFF
|
//#define DEBUG_OMP_STUFF
|
||||||
#ifdef DEBUG_OMP_STUFF
|
#ifdef DEBUG_OMP_STUFF
|
||||||
int *pThread = new int[nBulkSize];
|
int *pThread = new int[nBulkSize];
|
||||||
|
|
|
@ -35,226 +35,226 @@
|
||||||
|
|
||||||
namespace qmu
|
namespace qmu
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @brief This file contains the class definition of the qmuparser engine.
|
* @brief This file contains the class definition of the qmuparser engine.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Mathematical expressions parser (base parser engine).
|
* @brief Mathematical expressions parser (base parser engine).
|
||||||
* @author (C) 2013 Ingo Berg
|
* @author (C) 2013 Ingo Berg
|
||||||
*
|
*
|
||||||
* This is the implementation of a bytecode based mathematical expressions parser.
|
* This is the implementation of a bytecode based mathematical expressions parser.
|
||||||
* The formula will be parsed from string and converted into a bytecode.
|
* The formula will be parsed from string and converted into a bytecode.
|
||||||
* Future calculations will be done with the bytecode instead the formula string
|
* Future calculations will be done with the bytecode instead the formula string
|
||||||
* resulting in a significant performance increase.
|
* resulting in a significant performance increase.
|
||||||
* Complementary to a set of internally implemented functions the parser is able to handle
|
* Complementary to a set of internally implemented functions the parser is able to handle
|
||||||
* user defined functions and variables.
|
* user defined functions and variables.
|
||||||
*/
|
*/
|
||||||
class QmuParserBase
|
class QmuParserBase
|
||||||
{
|
{
|
||||||
friend class QmuParserTokenReader;
|
friend class QmuParserTokenReader;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Type of the error class.
|
* @brief Type of the error class.
|
||||||
*
|
*
|
||||||
* Included for backwards compatibility.
|
* Included for backwards compatibility.
|
||||||
*/
|
*/
|
||||||
typedef QmuParserError exception_type;
|
typedef QmuParserError exception_type;
|
||||||
|
|
||||||
QmuParserBase();
|
QmuParserBase();
|
||||||
QmuParserBase(const QmuParserBase &a_Parser);
|
QmuParserBase(const QmuParserBase &a_Parser);
|
||||||
QmuParserBase& operator=(const QmuParserBase &a_Parser);
|
QmuParserBase& operator=(const QmuParserBase &a_Parser);
|
||||||
virtual ~QmuParserBase();
|
virtual ~QmuParserBase();
|
||||||
|
|
||||||
static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
|
static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);
|
||||||
qreal Eval() const;
|
qreal Eval() const;
|
||||||
qreal* Eval(int &nStackSize) const;
|
qreal* Eval(int &nStackSize) const;
|
||||||
void Eval(qreal *results, int nBulkSize);
|
void Eval(qreal *results, int nBulkSize);
|
||||||
int GetNumResults() const;
|
int GetNumResults() const;
|
||||||
void SetExpr(const QString &a_sExpr);
|
void SetExpr(const QString &a_sExpr);
|
||||||
void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
|
void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);
|
||||||
void SetDecSep(char_type cDecSep);
|
void SetDecSep(char_type cDecSep);
|
||||||
void SetThousandsSep(char_type cThousandsSep = 0);
|
void SetThousandsSep(char_type cThousandsSep = 0);
|
||||||
void ResetLocale();
|
void ResetLocale();
|
||||||
void EnableOptimizer(bool a_bIsOn=true);
|
void EnableOptimizer(bool a_bIsOn=true);
|
||||||
void EnableBuiltInOprt(bool a_bIsOn=true);
|
void EnableBuiltInOprt(bool a_bIsOn=true);
|
||||||
bool HasBuiltInOprt() const;
|
bool HasBuiltInOprt() const;
|
||||||
void AddValIdent(identfun_type a_pCallback);
|
void AddValIdent(identfun_type a_pCallback);
|
||||||
void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0,
|
void DefineOprt(const QString &a_strName, fun_type2 a_pFun, unsigned a_iPri=0,
|
||||||
EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
|
EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
|
||||||
void DefineConst(const QString &a_sName, qreal a_fVal);
|
void DefineConst(const QString &a_sName, qreal a_fVal);
|
||||||
void DefineStrConst(const QString &a_sName, const QString &a_strVal);
|
void DefineStrConst(const QString &a_sName, const QString &a_strVal);
|
||||||
void DefineVar(const QString &a_sName, qreal *a_fVar);
|
void DefineVar(const QString &a_sName, qreal *a_fVar);
|
||||||
void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
|
void DefinePostfixOprt(const QString &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
|
||||||
void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX,
|
void DefineInfixOprt(const QString &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX,
|
||||||
bool a_bAllowOpt=true);
|
bool a_bAllowOpt=true);
|
||||||
// Clear user defined variables, constants or functions
|
// Clear user defined variables, constants or functions
|
||||||
void ClearVar();
|
void ClearVar();
|
||||||
void ClearFun();
|
void ClearFun();
|
||||||
void ClearConst();
|
void ClearConst();
|
||||||
void ClearInfixOprt();
|
void ClearInfixOprt();
|
||||||
void ClearPostfixOprt();
|
void ClearPostfixOprt();
|
||||||
void ClearOprt();
|
void ClearOprt();
|
||||||
void RemoveVar(const QString &a_strVarName);
|
void RemoveVar(const QString &a_strVarName);
|
||||||
const varmap_type& GetUsedVar() const;
|
const varmap_type& GetUsedVar() const;
|
||||||
const varmap_type& GetVar() const;
|
const varmap_type& GetVar() const;
|
||||||
const valmap_type& GetConst() const;
|
const valmap_type& GetConst() const;
|
||||||
const QString& GetExpr() const;
|
const QString& GetExpr() const;
|
||||||
const funmap_type& GetFunDef() const;
|
const funmap_type& GetFunDef() const;
|
||||||
QString GetVersion(EParserVersionInfo eInfo = pviFULL) const;
|
QString GetVersion(EParserVersionInfo eInfo = pviFULL) const;
|
||||||
const QStringList& GetOprtDef() const;
|
const QStringList& GetOprtDef() const;
|
||||||
void DefineNameChars(const QString &a_szCharset);
|
void DefineNameChars(const QString &a_szCharset);
|
||||||
void DefineOprtChars(const QString &a_szCharset);
|
void DefineOprtChars(const QString &a_szCharset);
|
||||||
void DefineInfixOprtChars(const QString &a_szCharset);
|
void DefineInfixOprtChars(const QString &a_szCharset);
|
||||||
const QString& ValidNameChars() const;
|
const QString& ValidNameChars() const;
|
||||||
const QString& ValidOprtChars() const;
|
const QString& ValidOprtChars() const;
|
||||||
const QString& ValidInfixOprtChars() const;
|
const QString& ValidInfixOprtChars() const;
|
||||||
void SetArgSep(char_type cArgSep);
|
void SetArgSep(char_type cArgSep);
|
||||||
QChar GetArgSep() const;
|
QChar GetArgSep() const;
|
||||||
void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const;
|
void Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_strTok = QString() ) const;
|
||||||
/**
|
/**
|
||||||
* @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun,
|
* @fn void qmu::QmuParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun,
|
||||||
* bool a_bAllowOpt = true)
|
* bool a_bAllowOpt = true)
|
||||||
* @brief Define a parser function without arguments.
|
* @brief Define a parser function without arguments.
|
||||||
* @param a_strName Name of the function
|
* @param a_strName Name of the function
|
||||||
* @param a_pFun Pointer to the callback function
|
* @param a_pFun Pointer to the callback function
|
||||||
* @param a_bAllowOpt A flag indicating this function may be optimized
|
* @param a_bAllowOpt A flag indicating this function may be optimized
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true)
|
void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt = true)
|
||||||
{
|
{
|
||||||
AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
|
AddCallback( a_strName, QmuParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
static const QStringList c_DefaultOprt;
|
static const QStringList c_DefaultOprt;
|
||||||
static std::locale s_locale; ///< The locale used by the parser
|
static std::locale s_locale; ///< The locale used by the parser
|
||||||
static bool g_DbgDumpCmdCode;
|
static bool g_DbgDumpCmdCode;
|
||||||
static bool g_DbgDumpStack;
|
static bool g_DbgDumpStack;
|
||||||
void Init();
|
void Init();
|
||||||
virtual void InitCharSets() = 0;
|
virtual void InitCharSets() = 0;
|
||||||
virtual void InitFun() = 0;
|
virtual void InitFun() = 0;
|
||||||
virtual void InitConst() = 0;
|
virtual void InitConst() = 0;
|
||||||
virtual void InitOprt() = 0;
|
virtual void InitOprt() = 0;
|
||||||
virtual void OnDetectVar(QString *pExpr, int &nStart, int &nEnd);
|
virtual void OnDetectVar(const QString &pExpr, int &nStart, int &nEnd);
|
||||||
/**
|
/**
|
||||||
* @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>
|
||||||
class change_dec_sep : public std::numpunct<TChar>
|
class change_dec_sep : public std::numpunct<TChar>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
|
explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
|
||||||
:std::numpunct<TChar>(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep)
|
:std::numpunct<TChar>(), m_nGroup(nGroup), m_cDecPoint(cDecSep), m_cThousandsSep(cThousandsSep)
|
||||||
{}
|
{}
|
||||||
protected:
|
protected:
|
||||||
virtual char_type do_decimal_point() const
|
virtual char_type do_decimal_point() const
|
||||||
{
|
{
|
||||||
return m_cDecPoint;
|
return m_cDecPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual char_type do_thousands_sep() const
|
virtual char_type do_thousands_sep() const
|
||||||
{
|
{
|
||||||
return m_cThousandsSep;
|
return m_cThousandsSep;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string do_grouping() const
|
virtual std::string do_grouping() const
|
||||||
{
|
{
|
||||||
return std::string(1, m_nGroup);
|
return std::string(1, m_nGroup);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
int m_nGroup;
|
int m_nGroup;
|
||||||
char_type m_cDecPoint;
|
char_type m_cDecPoint;
|
||||||
char_type m_cThousandsSep;
|
char_type m_cThousandsSep;
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Typedef for the parse functions.
|
* @brief Typedef for the parse functions.
|
||||||
*
|
*
|
||||||
* The parse function do the actual work. The parser exchanges
|
* The parse function do the actual work. The parser exchanges
|
||||||
* 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 qreal (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 QVector<qreal> valbuf_type;
|
typedef QVector<qreal> valbuf_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type for a vector of strings.
|
* @brief Type for a vector of strings.
|
||||||
*/
|
*/
|
||||||
typedef QVector<QString> stringbuf_type;
|
typedef QVector<QString> stringbuf_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Typedef for the token reader.
|
* @brief Typedef for the token reader.
|
||||||
*/
|
*/
|
||||||
typedef QmuParserTokenReader token_reader_type;
|
typedef QmuParserTokenReader token_reader_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type used for parser tokens.
|
* @brief Type used for parser tokens.
|
||||||
*/
|
*/
|
||||||
typedef QmuParserToken<qreal, QString> token_type;
|
typedef QmuParserToken<qreal, QString> 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Pointer to the parser function.
|
* @brief Pointer to the parser function.
|
||||||
*
|
*
|
||||||
* Eval() calls the function whose address is stored there.
|
* Eval() calls the function whose address is stored there.
|
||||||
*/
|
*/
|
||||||
mutable ParseFunction m_pParseFormula;
|
mutable ParseFunction m_pParseFormula;
|
||||||
mutable QmuParserByteCode m_vRPN; ///< The Bytecode class.
|
mutable QmuParserByteCode m_vRPN; ///< The Bytecode class.
|
||||||
mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
|
mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
|
||||||
stringbuf_type m_vStringVarBuf;
|
stringbuf_type m_vStringVarBuf;
|
||||||
|
|
||||||
std::auto_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
|
std::unique_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
|
||||||
|
|
||||||
funmap_type m_FunDef; ///< Map of function names and pointers.
|
funmap_type m_FunDef; ///< Map of function names and pointers.
|
||||||
funmap_type m_PostOprtDef; ///< Postfix operator callbacks
|
funmap_type m_PostOprtDef; ///< Postfix operator callbacks
|
||||||
funmap_type m_InfixOprtDef; ///< unary infix operator.
|
funmap_type m_InfixOprtDef; ///< unary infix operator.
|
||||||
funmap_type m_OprtDef; ///< Binary operator callbacks
|
funmap_type m_OprtDef; ///< Binary operator callbacks
|
||||||
valmap_type m_ConstDef; ///< user constants.
|
valmap_type m_ConstDef; ///< user constants.
|
||||||
strmap_type m_StrVarDef; ///< user defined string constants
|
strmap_type m_StrVarDef; ///< user defined string constants
|
||||||
varmap_type m_VarDef; ///< user defind variables.
|
varmap_type m_VarDef; ///< user defind variables.
|
||||||
|
|
||||||
bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
|
bool m_bBuiltInOp; ///< Flag that can be used for switching built in operators on and off
|
||||||
|
|
||||||
QString m_sNameChars; ///< Charset for names
|
QString m_sNameChars; ///< Charset for names
|
||||||
QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens
|
QString m_sOprtChars; ///< Charset for postfix/ binary operator tokens
|
||||||
QString m_sInfixOprtChars; ///< Charset for infix operator tokens
|
QString m_sInfixOprtChars; ///< Charset for infix operator tokens
|
||||||
|
|
||||||
mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses
|
mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses
|
||||||
|
|
||||||
// items merely used for caching state information
|
// items merely used for caching state information
|
||||||
mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
|
mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
|
||||||
mutable int m_nFinalResultIdx;
|
mutable int m_nFinalResultIdx;
|
||||||
|
|
||||||
void Assign(const QmuParserBase &a_Parser);
|
void Assign(const QmuParserBase &a_Parser);
|
||||||
void InitTokenReader();
|
void InitTokenReader();
|
||||||
void ReInit() const;
|
void ReInit() const;
|
||||||
void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback,
|
void AddCallback(const QString &a_strName, const QmuParserCallback &a_Callback,
|
||||||
funmap_type &a_Storage, const QString &a_szCharSet );
|
funmap_type &a_Storage, const QString &a_szCharSet );
|
||||||
void ApplyRemainingOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
void ApplyRemainingOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||||
void ApplyBinOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
void ApplyBinOprt(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||||
void ApplyIfElse(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
void ApplyIfElse(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal) const;
|
||||||
void ApplyFunc(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal, int iArgCount) const;
|
void ApplyFunc(QStack<token_type> &a_stOpt, QStack<token_type> &a_stVal, int iArgCount) const;
|
||||||
token_type ApplyStrFunc(const token_type &a_FunTok, const QVector<token_type> &a_vArg) const;
|
token_type ApplyStrFunc(const token_type &a_FunTok, const QVector<token_type> &a_vArg) const;
|
||||||
int GetOprtPrecedence(const token_type &a_Tok) const;
|
int GetOprtPrecedence(const token_type &a_Tok) const;
|
||||||
EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const;
|
EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const;
|
||||||
void CreateRPN() const;
|
void CreateRPN() const;
|
||||||
qreal ParseString() const;
|
qreal ParseString() const;
|
||||||
qreal ParseCmdCode() const;
|
qreal ParseCmdCode() const;
|
||||||
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
|
qreal ParseCmdCodeBulk(int nOffset, int nThreadID) const;
|
||||||
void CheckName(const QString &a_strName, const QString &a_CharSet) const;
|
void CheckName(const QString &a_strName, const QString &a_CharSet) const;
|
||||||
void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback,
|
void CheckOprt(const QString &a_sName, const QmuParserCallback &a_Callback,
|
||||||
const QString &a_szCharSet) const;
|
const QString &a_szCharSet) const;
|
||||||
void StackDump(const QStack<token_type > &a_stVal, const QStack<token_type > &a_stOprt) const;
|
void StackDump(const QStack<token_type > &a_stVal, const QStack<token_type > &a_stOprt) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace qmu
|
} // namespace qmu
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,8 @@ QmuParserByteCode::QmuParserByteCode()
|
||||||
* Implemented in Terms of Assign(const QParserByteCode &a_ByteCode)
|
* Implemented in Terms of Assign(const QParserByteCode &a_ByteCode)
|
||||||
*/
|
*/
|
||||||
QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode)
|
QmuParserByteCode::QmuParserByteCode(const QmuParserByteCode &a_ByteCode)
|
||||||
|
:m_iStackPos(a_ByteCode.m_iStackPos), m_iMaxStackSize(a_ByteCode.m_iMaxStackSize), m_vRPN(a_ByteCode.m_vRPN),
|
||||||
|
m_bEnableOptimizer(true)
|
||||||
{
|
{
|
||||||
Assign(a_ByteCode);
|
Assign(a_ByteCode);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +103,7 @@ void QmuParserByteCode::Assign(const QmuParserByteCode &a_ByteCode)
|
||||||
void QmuParserByteCode::AddVar(qreal *a_pVar)
|
void QmuParserByteCode::AddVar(qreal *a_pVar)
|
||||||
{
|
{
|
||||||
++m_iStackPos;
|
++m_iStackPos;
|
||||||
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
|
m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast<size_t>(m_iStackPos));
|
||||||
|
|
||||||
// optimization does not apply
|
// optimization does not apply
|
||||||
SToken tok;
|
SToken tok;
|
||||||
|
@ -129,7 +131,7 @@ void QmuParserByteCode::AddVar(qreal *a_pVar)
|
||||||
void QmuParserByteCode::AddVal(qreal a_fVal)
|
void QmuParserByteCode::AddVal(qreal a_fVal)
|
||||||
{
|
{
|
||||||
++m_iStackPos;
|
++m_iStackPos;
|
||||||
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
|
m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast<size_t>(m_iStackPos));
|
||||||
|
|
||||||
// If optimization does not apply
|
// If optimization does not apply
|
||||||
SToken tok;
|
SToken tok;
|
||||||
|
@ -145,15 +147,15 @@ void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt)
|
||||||
{
|
{
|
||||||
std::size_t sz = m_vRPN.size();
|
std::size_t sz = m_vRPN.size();
|
||||||
qreal &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)
|
||||||
{
|
{
|
||||||
case cmLAND:
|
case cmLAND:
|
||||||
x = (int)x && (int)y;
|
x = static_cast<int>(x) && static_cast<int>(y);
|
||||||
m_vRPN.pop_back();
|
m_vRPN.pop_back();
|
||||||
break;
|
break;
|
||||||
case cmLOR:
|
case cmLOR:
|
||||||
x = (int)x || (int)y;
|
x = static_cast<int>(x) || static_cast<int>(y);
|
||||||
m_vRPN.pop_back();
|
m_vRPN.pop_back();
|
||||||
break;
|
break;
|
||||||
case cmLT:
|
case cmLT:
|
||||||
|
@ -173,11 +175,11 @@ void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt)
|
||||||
m_vRPN.pop_back();
|
m_vRPN.pop_back();
|
||||||
break;
|
break;
|
||||||
case cmNEQ:
|
case cmNEQ:
|
||||||
x = x != y;
|
x = (qFuzzyCompare(x, y) == false);
|
||||||
m_vRPN.pop_back();
|
m_vRPN.pop_back();
|
||||||
break;
|
break;
|
||||||
case cmEQ:
|
case cmEQ:
|
||||||
x = x == y;
|
x = qFuzzyCompare(x, y);
|
||||||
m_vRPN.pop_back();
|
m_vRPN.pop_back();
|
||||||
break;
|
break;
|
||||||
case cmADD:
|
case cmADD:
|
||||||
|
@ -202,10 +204,79 @@ void QmuParserByteCode::ConstantFolding(ECmdCode a_Oprt)
|
||||||
x = x / y;
|
x = x / y;
|
||||||
m_vRPN.pop_back();
|
m_vRPN.pop_back();
|
||||||
break;
|
break;
|
||||||
case cmPOW:
|
case cmPOW:
|
||||||
x = qPow(x, y);
|
x = qPow(x, y);
|
||||||
m_vRPN.pop_back();
|
m_vRPN.pop_back();
|
||||||
break;
|
break;
|
||||||
|
case cmASSIGN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBO:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmELSE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmENDIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_STR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_BULK:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_BIN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_INFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
} // switch opcode
|
} // switch opcode
|
||||||
|
@ -248,15 +319,15 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
|
||||||
// Optimization for ploynomials of low order
|
// Optimization for ploynomials of low order
|
||||||
if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL)
|
if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL)
|
||||||
{
|
{
|
||||||
if (m_vRPN[sz-1].Val.data2==2)
|
if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 2))
|
||||||
{
|
{
|
||||||
m_vRPN[sz-2].Cmd = cmVARPOW2;
|
m_vRPN[sz-2].Cmd = cmVARPOW2;
|
||||||
}
|
}
|
||||||
else if (m_vRPN[sz-1].Val.data2==3)
|
else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 3))
|
||||||
{
|
{
|
||||||
m_vRPN[sz-2].Cmd = cmVARPOW3;
|
m_vRPN[sz-2].Cmd = cmVARPOW3;
|
||||||
}
|
}
|
||||||
else if (m_vRPN[sz-1].Val.data2==4)
|
else if (qFuzzyCompare(m_vRPN[sz-1].Val.data2, 4))
|
||||||
{
|
{
|
||||||
m_vRPN[sz-2].Cmd = cmVARPOW4;
|
m_vRPN[sz-2].Cmd = cmVARPOW4;
|
||||||
}
|
}
|
||||||
|
@ -291,8 +362,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
|
||||||
(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 = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) |
|
m_vRPN[sz-2].Val.ptr = reinterpret_cast<qreal*>(
|
||||||
(long long)(m_vRPN[sz-1].Val.ptr)); // variable
|
reinterpret_cast<qlonglong>(m_vRPN[sz-2].Val.ptr) |
|
||||||
|
reinterpret_cast<qlonglong>(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();
|
||||||
|
@ -304,8 +376,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
|
||||||
(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 = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) |
|
m_vRPN[sz-2].Val.ptr = reinterpret_cast<qreal*>(
|
||||||
(long long)(m_vRPN[sz-1].Val.ptr));
|
reinterpret_cast<qlonglong>(m_vRPN[sz-2].Val.ptr) |
|
||||||
|
reinterpret_cast<qlonglong>(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();
|
||||||
|
@ -316,8 +389,9 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
|
||||||
{
|
{
|
||||||
// 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 = (qreal*)((long long)(m_vRPN[sz-2].Val.ptr) |
|
m_vRPN[sz-2].Val.ptr = reinterpret_cast<qreal*>(
|
||||||
(long long)(m_vRPN[sz-1].Val.ptr));
|
reinterpret_cast<qlonglong>(m_vRPN[sz-2].Val.ptr) |
|
||||||
|
reinterpret_cast<qlonglong>(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;
|
||||||
|
@ -341,7 +415,8 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case cmDIV:
|
case cmDIV:
|
||||||
if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0)
|
if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL &&
|
||||||
|
(qFuzzyCompare(m_vRPN[sz-1].Val.data2+1, 1+0)==false))
|
||||||
{
|
{
|
||||||
// Optimization: 4*a/2 -> 2*a
|
// Optimization: 4*a/2 -> 2*a
|
||||||
m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2;
|
m_vRPN[sz-2].Val.data /= m_vRPN[sz-1].Val.data2;
|
||||||
|
@ -350,8 +425,103 @@ void QmuParserByteCode::AddOp(ECmdCode a_Oprt)
|
||||||
bOptimized = true;
|
bOptimized = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case cmLE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmNEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLAND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLOR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmASSIGN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBO:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmELSE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmENDIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_STR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_BULK:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_BIN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_INFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
} // switch a_Oprt
|
} // switch a_Oprt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +583,7 @@ void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc)
|
||||||
// function with unlimited number of arguments
|
// function with unlimited number of arguments
|
||||||
m_iStackPos = m_iStackPos + a_iArgc + 1;
|
m_iStackPos = m_iStackPos + a_iArgc + 1;
|
||||||
}
|
}
|
||||||
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
|
m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast<size_t>(m_iStackPos));
|
||||||
|
|
||||||
SToken tok;
|
SToken tok;
|
||||||
tok.Cmd = cmFUNC;
|
tok.Cmd = cmFUNC;
|
||||||
|
@ -432,7 +602,7 @@ void QmuParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc)
|
||||||
void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc)
|
void QmuParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc)
|
||||||
{
|
{
|
||||||
m_iStackPos = m_iStackPos - a_iArgc + 1;
|
m_iStackPos = m_iStackPos - a_iArgc + 1;
|
||||||
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
|
m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast<size_t>(m_iStackPos));
|
||||||
|
|
||||||
SToken tok;
|
SToken tok;
|
||||||
tok.Cmd = cmFUNC_BULK;
|
tok.Cmd = cmFUNC_BULK;
|
||||||
|
@ -460,7 +630,7 @@ void QmuParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iI
|
||||||
tok.Fun.ptr = a_pFun;
|
tok.Fun.ptr = a_pFun;
|
||||||
m_vRPN.push_back(tok);
|
m_vRPN.push_back(tok);
|
||||||
|
|
||||||
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
|
m_iMaxStackSize = qMax(m_iMaxStackSize, static_cast<size_t>(m_iStackPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -479,7 +649,7 @@ void QmuParserByteCode::Finalize()
|
||||||
// Determine the if-then-else jump offsets
|
// Determine the if-then-else jump offsets
|
||||||
QStack<int> stIf, stElse;
|
QStack<int> stIf, stElse;
|
||||||
int idx;
|
int idx;
|
||||||
for (int i=0; i<(int)m_vRPN.size(); ++i)
|
for (int i=0; i<m_vRPN.size(); ++i)
|
||||||
{
|
{
|
||||||
switch(m_vRPN[i].Cmd)
|
switch(m_vRPN[i].Cmd)
|
||||||
{
|
{
|
||||||
|
@ -495,6 +665,105 @@ void QmuParserByteCode::Finalize()
|
||||||
idx = stElse.pop();
|
idx = stElse.pop();
|
||||||
m_vRPN[idx].Oprt.offset = i - idx;
|
m_vRPN[idx].Oprt.offset = i - idx;
|
||||||
break;
|
break;
|
||||||
|
case cmLE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmNEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmGT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmADD:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSUB:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmDIV:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLAND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmLOR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmASSIGN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBO:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVAL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_STR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_BULK:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_BIN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_INFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -558,7 +827,7 @@ void QmuParserByteCode::AsciiDump()
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Number of RPN tokens:" << m_vRPN.size() << "\n";
|
qDebug() << "Number of RPN tokens:" << m_vRPN.size() << "\n";
|
||||||
for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i)
|
for (int i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i)
|
||||||
{
|
{
|
||||||
qDebug() << i << " : \t";
|
qDebug() << i << " : \t";
|
||||||
switch (m_vRPN[i].Cmd)
|
switch (m_vRPN[i].Cmd)
|
||||||
|
@ -640,6 +909,39 @@ void QmuParserByteCode::AsciiDump()
|
||||||
case cmASSIGN:
|
case cmASSIGN:
|
||||||
qDebug() << "ASSIGN\t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Oprt.ptr, 'f', 16) << "]\n";
|
qDebug() << "ASSIGN\t" << "[ADDR: 0x" << QString::number(*m_vRPN[i].Oprt.ptr, 'f', 16) << "]\n";
|
||||||
break;
|
break;
|
||||||
|
case cmBO:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_BULK:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_BIN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_INFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
qDebug() << "(unknown code: " << m_vRPN[i].Cmd << ")\n";
|
qDebug() << "(unknown code: " << m_vRPN[i].Cmd << ")\n";
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -30,15 +30,22 @@
|
||||||
namespace qmu
|
namespace qmu
|
||||||
{
|
{
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
//Supressing specific warnings on gcc/g++ http://www.mr-edd.co.uk/blog/supressing_gcc_warnings
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type0 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type0 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode )
|
QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ), m_iCode ( a_iCode ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( a_iPrec ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( a_iCode ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,9 +54,12 @@ QmuParserCallback::QmuParserCallback ( fun_type1 a_pFun, bool a_bAllowOpti, int
|
||||||
* @brief Constructor for constructing funcstion callbacks taking two arguments.
|
* @brief Constructor for constructing funcstion callbacks taking two arguments.
|
||||||
* @throw nothrow
|
* @throw nothrow
|
||||||
*/
|
*/
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -61,72 +71,105 @@ QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti )
|
||||||
* @param a_eOprtAsct The operators associativity
|
* @param a_eOprtAsct The operators associativity
|
||||||
* @throw nothrow
|
* @throw nothrow
|
||||||
*/
|
*/
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec,
|
QmuParserCallback::QmuParserCallback ( fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec,
|
||||||
EOprtAssociativity a_eOprtAsct )
|
EOprtAssociativity a_eOprtAsct )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( a_iPrec ), m_eOprtAsct ( a_eOprtAsct ),
|
||||||
m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmOPRT_BIN ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type3 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type3 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type4 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type4 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type5 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type5 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type6 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type6 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type7 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type7 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type8 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type8 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type9 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type9 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( fun_type10 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( fun_type10 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type0 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type0 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -134,81 +177,120 @@ QmuParserCallback::QmuParserCallback ( bulkfun_type1 a_pFun, bool a_bAllowOpti )
|
||||||
* @brief Constructor for constructing funcstion callbacks taking two arguments.
|
* @brief Constructor for constructing funcstion callbacks taking two arguments.
|
||||||
* @throw nothrow
|
* @throw nothrow
|
||||||
*/
|
*/
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type2 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type2 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type3 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type3 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 3 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type4 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type4 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 4 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type5 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type5 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 5 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type6 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type6 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 6 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type7 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type7 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 7 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type8 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type8 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 8 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type9 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type9 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 9 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( bulkfun_type10 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( bulkfun_type10 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_BULK ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 10 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_BULK ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( multfun_type a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( multfun_type a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( -1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC ), m_iType ( tpDBL ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( strfun_type1 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( strfun_type1 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 0 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( strfun_type2 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( strfun_type2 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 1 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__extension__
|
||||||
|
#endif
|
||||||
QmuParserCallback::QmuParserCallback ( strfun_type3 a_pFun, bool a_bAllowOpti )
|
QmuParserCallback::QmuParserCallback ( strfun_type3 a_pFun, bool a_bAllowOpti )
|
||||||
: m_pFun ( ( void* ) a_pFun ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ), m_iCode ( cmFUNC_STR ),
|
: m_pFun ( reinterpret_cast<void*> ( a_pFun ) ), m_iArgc ( 2 ), m_iPri ( -1 ), m_eOprtAsct ( oaNONE ),
|
||||||
m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
|
m_iCode ( cmFUNC_STR ), m_iType ( tpSTR ), m_bAllowOpti ( a_bAllowOpti )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -227,6 +309,8 @@ QmuParserCallback::QmuParserCallback()
|
||||||
* @throw nothrow
|
* @throw nothrow
|
||||||
*/
|
*/
|
||||||
QmuParserCallback::QmuParserCallback ( const QmuParserCallback &ref )
|
QmuParserCallback::QmuParserCallback ( const QmuParserCallback &ref )
|
||||||
|
: m_pFun ( ref.m_pFun ), m_iArgc ( ref.m_iArgc ), m_iPri ( ref.m_iPri ), m_eOprtAsct ( ref.m_eOprtAsct ),
|
||||||
|
m_iCode ( ref.m_iCode ), m_iType ( ref.m_iType ), m_bAllowOpti ( ref.m_bAllowOpti )
|
||||||
{
|
{
|
||||||
m_pFun = ref.m_pFun;
|
m_pFun = ref.m_pFun;
|
||||||
m_iArgc = ref.m_iArgc;
|
m_iArgc = ref.m_iArgc;
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
OpenMP is used only in the bulk mode it may increase the performance a bit.
|
OpenMP is used only in the bulk mode it may increase the performance a bit.
|
||||||
*/
|
*/
|
||||||
//#define MUP_USE_OPENMP
|
//#define QMUP_USE_OPENMP
|
||||||
|
|
||||||
#if defined(_UNICODE)
|
#if defined(_UNICODE)
|
||||||
/** @brief Definition of the basic parser string type. */
|
/** @brief Definition of the basic parser string type. */
|
||||||
|
|
|
@ -37,27 +37,13 @@ const QmuParserErrorMsg& QmuParserErrorMsg::Instance()
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
QString QmuParserErrorMsg::operator[] ( unsigned a_iIdx ) const
|
QString QmuParserErrorMsg::operator[] ( unsigned a_iIdx ) const
|
||||||
{
|
{
|
||||||
return ( a_iIdx < m_vErrMsg.size() ) ? m_vErrMsg[a_iIdx] : QString();
|
return ( a_iIdx < static_cast<unsigned>( m_vErrMsg.size() ) ) ? m_vErrMsg[a_iIdx] : QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
QmuParserErrorMsg::~QmuParserErrorMsg()
|
QmuParserErrorMsg::~QmuParserErrorMsg()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* @brief Assignement operator is deactivated.
|
|
||||||
*/
|
|
||||||
QmuParserErrorMsg& QmuParserErrorMsg::operator= ( const QmuParserErrorMsg& )
|
|
||||||
{
|
|
||||||
assert ( false );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
|
||||||
QmuParserErrorMsg::QmuParserErrorMsg ( const QmuParserErrorMsg& )
|
|
||||||
{}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
QmuParserErrorMsg::QmuParserErrorMsg()
|
QmuParserErrorMsg::QmuParserErrorMsg()
|
||||||
: m_vErrMsg ( 0 )
|
: m_vErrMsg ( 0 )
|
||||||
|
@ -147,11 +133,9 @@ QmuParserError::QmuParserError ( EErrorCodes a_iErrc )
|
||||||
* @brief Construct an error from a message text.
|
* @brief Construct an error from a message text.
|
||||||
*/
|
*/
|
||||||
QmuParserError::QmuParserError ( const QString &sMsg )
|
QmuParserError::QmuParserError ( const QString &sMsg )
|
||||||
: m_ErrMsg ( QmuParserErrorMsg::Instance() )
|
: m_strMsg(sMsg), m_strFormula(), m_strTok(), m_iPos ( -1 ), m_iErrc ( ecUNDEFINED ),
|
||||||
{
|
m_ErrMsg ( QmuParserErrorMsg::Instance() )
|
||||||
Reset();
|
{}
|
||||||
m_strMsg = sMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
@ -264,9 +248,9 @@ void QmuParserError::ReplaceSubString ( QString &strSource, const QString &strFi
|
||||||
*/
|
*/
|
||||||
void QmuParserError::Reset()
|
void QmuParserError::Reset()
|
||||||
{
|
{
|
||||||
m_strMsg = "";
|
m_strMsg.clear();
|
||||||
m_strFormula = "";
|
m_strFormula.clear();
|
||||||
m_strTok = "";
|
m_strTok.clear();
|
||||||
m_iPos = -1;
|
m_iPos = -1;
|
||||||
m_iErrc = ecUNDEFINED;
|
m_iErrc = ecUNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,8 +99,6 @@ class QmuParserErrorMsg
|
||||||
public:
|
public:
|
||||||
typedef QmuParserErrorMsg self_type;
|
typedef QmuParserErrorMsg self_type;
|
||||||
|
|
||||||
QmuParserErrorMsg& operator= ( const QmuParserErrorMsg & );
|
|
||||||
QmuParserErrorMsg ( const QmuParserErrorMsg& );
|
|
||||||
QmuParserErrorMsg();
|
QmuParserErrorMsg();
|
||||||
~QmuParserErrorMsg();
|
~QmuParserErrorMsg();
|
||||||
|
|
||||||
|
@ -108,6 +106,7 @@ public:
|
||||||
QString operator[] ( unsigned a_iIdx ) const;
|
QString operator[] ( unsigned a_iIdx ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Q_DISABLE_COPY(QmuParserErrorMsg)
|
||||||
QVector<QString> m_vErrMsg; ///< A vector with the predefined error messages
|
QVector<QString> m_vErrMsg; ///< A vector with the predefined error messages
|
||||||
static const self_type m_Instance; ///< The instance pointer
|
static const self_type m_Instance; ///< The instance pointer
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,8 +81,8 @@ int QmuParserTester::IsHexVal ( const QString &a_szExpr, int *a_iPos, qreal *a_f
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*a_iPos += ( int ) ( 2 + nPos );
|
*a_iPos += 2 + nPos;
|
||||||
*a_fVal = ( qreal ) iVal;
|
*a_fVal = static_cast<qreal>(iVal);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -460,7 +460,7 @@ int QmuParserTester::TestVarConst()
|
||||||
// 4 used variables
|
// 4 used variables
|
||||||
p.SetExpr ( "a+b+c+d" );
|
p.SetExpr ( "a+b+c+d" );
|
||||||
qmu::varmap_type UsedVar = p.GetUsedVar();
|
qmu::varmap_type UsedVar = p.GetUsedVar();
|
||||||
int iCount = ( int ) UsedVar.size();
|
int iCount = static_cast<int>(UsedVar.size());
|
||||||
if ( iCount != 4 )
|
if ( iCount != 4 )
|
||||||
{
|
{
|
||||||
throw false;
|
throw false;
|
||||||
|
@ -485,7 +485,7 @@ int QmuParserTester::TestVarConst()
|
||||||
// Test lookup of undefined variables
|
// Test lookup of undefined variables
|
||||||
p.SetExpr ( "undef1+undef2+undef3" );
|
p.SetExpr ( "undef1+undef2+undef3" );
|
||||||
UsedVar = p.GetUsedVar();
|
UsedVar = p.GetUsedVar();
|
||||||
iCount = ( int ) UsedVar.size();
|
iCount = static_cast<int>(UsedVar.size());
|
||||||
if ( iCount != 3 )
|
if ( iCount != 3 )
|
||||||
{
|
{
|
||||||
throw false;
|
throw false;
|
||||||
|
@ -509,7 +509,7 @@ int QmuParserTester::TestVarConst()
|
||||||
// 1 used variables
|
// 1 used variables
|
||||||
p.SetExpr ( "a+b" );
|
p.SetExpr ( "a+b" );
|
||||||
UsedVar = p.GetUsedVar();
|
UsedVar = p.GetUsedVar();
|
||||||
iCount = ( int ) UsedVar.size();
|
iCount = static_cast<int>(UsedVar.size());
|
||||||
if ( iCount != 2 )
|
if ( iCount != 2 )
|
||||||
{
|
{
|
||||||
throw false;
|
throw false;
|
||||||
|
@ -1072,7 +1072,7 @@ void QmuParserTester::Run()
|
||||||
int iStat = 0;
|
int iStat = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < ( int ) m_vTestFun.size(); ++i )
|
for ( int i = 0; i < m_vTestFun.size(); ++i )
|
||||||
{
|
{
|
||||||
iStat += ( this->*m_vTestFun[i] ) ();
|
iStat += ( this->*m_vTestFun[i] ) ();
|
||||||
}
|
}
|
||||||
|
@ -1227,7 +1227,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::auto_ptr<QmuParser> p1;
|
std::unique_ptr<QmuParser> p1;
|
||||||
QmuParser p2, p3; // three parser objects
|
QmuParser p2, p3; // three parser objects
|
||||||
// they will be used for testing copy and assihnment operators
|
// they will be used for testing copy and assihnment operators
|
||||||
// p1 is a pointer since i'm going to delete it in order to test if
|
// p1 is a pointer since i'm going to delete it in order to test if
|
||||||
|
@ -1306,7 +1306,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass
|
||||||
// String parsing and bytecode parsing must yield the same result
|
// String parsing and bytecode parsing must yield the same result
|
||||||
fVal[0] = p1->Eval(); // result from stringparsing
|
fVal[0] = p1->Eval(); // result from stringparsing
|
||||||
fVal[1] = p1->Eval(); // result from bytecode
|
fVal[1] = p1->Eval(); // result from bytecode
|
||||||
if ( fVal[0] != fVal[1] )
|
if ( qFuzzyCompare( fVal[0], fVal[1] ) == false )
|
||||||
{
|
{
|
||||||
throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." );
|
throw QmuParser::exception_type ( "Bytecode / string parsing mismatch." );
|
||||||
}
|
}
|
||||||
|
@ -1354,7 +1354,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass
|
||||||
// http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825
|
// http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825
|
||||||
if ( numeric_limits<qreal>::has_infinity )
|
if ( numeric_limits<qreal>::has_infinity )
|
||||||
{
|
{
|
||||||
bCloseEnough &= ( fabs ( fVal[i] ) != numeric_limits<qreal>::infinity() );
|
bCloseEnough &= (qFuzzyCompare( fabs ( fVal[i] ), numeric_limits<qreal>::infinity())==false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1376,7 +1376,8 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass
|
||||||
{
|
{
|
||||||
if ( a_fPass )
|
if ( a_fPass )
|
||||||
{
|
{
|
||||||
if ( fVal[0] != fVal[2] && fVal[0] != -999 && fVal[1] != -998 )
|
if ( (qFuzzyCompare(fVal[0], fVal[2])==false) && (qFuzzyCompare(fVal[0], -999)==false) &&
|
||||||
|
(qFuzzyCompare(fVal[1], -998 )==false))
|
||||||
{
|
{
|
||||||
qDebug() << "\n fail: " << a_str << " (copy construction)";
|
qDebug() << "\n fail: " << a_str << " (copy construction)";
|
||||||
}
|
}
|
||||||
|
@ -1405,7 +1406,7 @@ int QmuParserTester::EqnTest ( const QString &a_str, double a_fRes, bool a_fPass
|
||||||
/**
|
/**
|
||||||
* @brief Internal error in test class Test is going to be aborted.
|
* @brief Internal error in test class Test is going to be aborted.
|
||||||
*/
|
*/
|
||||||
void QmuParserTester::Abort() const
|
void Q_NORETURN QmuParserTester::Abort() const
|
||||||
{
|
{
|
||||||
qDebug() << "Test failed (internal error in test class)" ;
|
qDebug() << "Test failed (internal error in test class)" ;
|
||||||
while ( !getchar() );
|
while ( !getchar() );
|
||||||
|
|
|
@ -178,7 +178,7 @@ private:
|
||||||
|
|
||||||
static qreal land ( qreal v1, qreal v2 )
|
static qreal land ( qreal v1, qreal v2 )
|
||||||
{
|
{
|
||||||
return ( int ) v1 & ( int ) v2;
|
return static_cast<int>( v1 ) & static_cast<int>( v2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal FirstArg ( const qreal* a_afArg, int a_iArgc )
|
static qreal FirstArg ( const qreal* a_afArg, int a_iArgc )
|
||||||
|
@ -218,12 +218,12 @@ private:
|
||||||
|
|
||||||
static qreal Rnd ( qreal v )
|
static qreal Rnd ( qreal v )
|
||||||
{
|
{
|
||||||
return ( qreal ) ( 1 + ( v * std::rand() / ( RAND_MAX + 1.0 ) ) );
|
return static_cast<qreal>( ( 1 + ( v * qrand() / ( RAND_MAX + 1.0 ) ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal RndWithString ( const char_type* )
|
static qreal RndWithString ( const char_type* )
|
||||||
{
|
{
|
||||||
return ( qreal ) ( 1 + ( 1000.0f * std::rand() / ( RAND_MAX + 1.0 ) ) );
|
return static_cast<qreal>( ( 1 + ( 1000.0f * static_cast<qreal>(qrand()) / ( RAND_MAX + 1.0 ) ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal Ping()
|
static qreal Ping()
|
||||||
|
@ -239,13 +239,13 @@ private:
|
||||||
static qreal StrFun1 ( const QString & v1 )
|
static qreal StrFun1 ( const QString & v1 )
|
||||||
{
|
{
|
||||||
int val = v1.toInt();
|
int val = v1.toInt();
|
||||||
return ( qreal ) val;
|
return static_cast<qreal>(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal StrFun2 ( const QString & v1, qreal v2 )
|
static qreal StrFun2 ( const QString & v1, qreal v2 )
|
||||||
{
|
{
|
||||||
int val = v1.toInt();
|
int val = v1.toInt();
|
||||||
return ( qreal ) ( val + v2 );
|
return static_cast<qreal>( val + v2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 )
|
static qreal StrFun3 ( const QString & v1, qreal v2, qreal v3 )
|
||||||
|
@ -263,17 +263,17 @@ private:
|
||||||
// postfix operator callback
|
// postfix operator callback
|
||||||
static qreal Mega ( qreal a_fVal )
|
static qreal Mega ( qreal a_fVal )
|
||||||
{
|
{
|
||||||
return a_fVal * ( qreal ) 1e6;
|
return a_fVal * static_cast<qreal>( 1e6 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal Micro ( qreal a_fVal )
|
static qreal Micro ( qreal a_fVal )
|
||||||
{
|
{
|
||||||
return a_fVal * ( qreal ) 1e-6;
|
return a_fVal * static_cast<qreal>( 1e-6 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static qreal Milli ( qreal a_fVal )
|
static qreal Milli ( qreal a_fVal )
|
||||||
{
|
{
|
||||||
return a_fVal / ( qreal ) 1e3;
|
return a_fVal / static_cast<qreal>( 1e3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom value recognition
|
// Custom value recognition
|
||||||
|
|
|
@ -1,396 +1,517 @@
|
||||||
/***************************************************************************************************
|
/***************************************************************************************************
|
||||||
**
|
**
|
||||||
** Original work Copyright (C) 2013 Ingo Berg
|
** Original work Copyright (C) 2013 Ingo Berg
|
||||||
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
|
** Modified work Copyright 2014 Roman Telezhynskyi <dismine(at)gmail.com>
|
||||||
**
|
**
|
||||||
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||||
** software and associated documentation files (the "Software"), to deal in the Software
|
** software and associated documentation files (the "Software"), to deal in the Software
|
||||||
** without restriction, including without limitation the rights to use, copy, modify,
|
** without restriction, including without limitation the rights to use, copy, modify,
|
||||||
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
**
|
**
|
||||||
** The above copyright notice and this permission notice shall be included in all copies or
|
** The above copyright notice and this permission notice shall be included in all copies or
|
||||||
** substantial portions of the Software.
|
** substantial portions of the Software.
|
||||||
**
|
**
|
||||||
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||||
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
**
|
**
|
||||||
******************************************************************************************************/
|
******************************************************************************************************/
|
||||||
|
|
||||||
#ifndef QMUPARSERTOKEN_H
|
#ifndef QMUPARSERTOKEN_H
|
||||||
#define QMUPARSERTOKEN_H
|
#define QMUPARSERTOKEN_H
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
#include "qmuparsererror.h"
|
#include "qmuparsererror.h"
|
||||||
#include "qmuparsercallback.h"
|
#include "qmuparsercallback.h"
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
@brief This file contains the parser token definition.
|
@brief This file contains the parser token definition.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace qmu
|
namespace qmu
|
||||||
{
|
{
|
||||||
/** @brief Encapsulation of the data for a single formula token.
|
/**
|
||||||
|
* @brief Encapsulation of the data for a single formula token.
|
||||||
Formula token implementation. Part of the Math Parser Package.
|
*
|
||||||
Formula tokens can be either one of the following:
|
* Formula token implementation. Part of the Math Parser Package.
|
||||||
<ul>
|
* Formula tokens can be either one of the following:
|
||||||
<li>value</li>
|
* <ul>
|
||||||
<li>variable</li>
|
* <li>value</li>
|
||||||
<li>function with numerical arguments</li>
|
* <li>variable</li>
|
||||||
<li>functions with a string as argument</li>
|
* <li>function with numerical arguments</li>
|
||||||
<li>prefix operators</li>
|
* <li>functions with a string as argument</li>
|
||||||
<li>infix operators</li>
|
* <li>prefix operators</li>
|
||||||
<li>binary operator</li>
|
* <li>infix operators</li>
|
||||||
</ul>
|
* <li>binary operator</li>
|
||||||
|
* </ul>
|
||||||
@author (C) 2004-2013 Ingo Berg
|
*
|
||||||
*/
|
* @author (C) 2004-2013 Ingo Berg
|
||||||
template<typename TBase, typename TString>
|
*/
|
||||||
class QmuParserToken
|
template<typename TBase, typename TString>
|
||||||
{
|
class QmuParserToken
|
||||||
private:
|
{
|
||||||
|
public:
|
||||||
ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode.
|
//---------------------------------------------------------------------------
|
||||||
ETypeCode m_iType;
|
/**
|
||||||
void *m_pTok; ///< Stores Token pointer; not applicable for all tokens
|
* @brief Constructor (default).
|
||||||
int m_iIdx; ///< An otional index to an external buffer storing the token data
|
*
|
||||||
TString m_strTok; ///< Token string
|
* Sets token to an neutral state of type cmUNKNOWN.
|
||||||
TString m_strVal; ///< Value for string variables
|
* @throw nothrow
|
||||||
qreal m_fVal; ///< the value
|
* @sa ECmdCode
|
||||||
std::auto_ptr<QmuParserCallback> m_pCallback;
|
*/
|
||||||
|
QmuParserToken()
|
||||||
public:
|
: m_iCode ( cmUNKNOWN ), m_iType ( tpVOID ), m_pTok ( 0 ), m_iIdx ( -1 ), m_strTok(), m_strVal(), m_fVal(),
|
||||||
|
m_pCallback()
|
||||||
//---------------------------------------------------------------------------
|
{}
|
||||||
/** @brief Constructor (default).
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
Sets token to an neutral state of type cmUNKNOWN.
|
/**
|
||||||
@throw nothrow
|
* @brief Create token from another one.
|
||||||
@sa ECmdCode
|
*
|
||||||
*/
|
* Implemented by calling Assign(...)
|
||||||
QmuParserToken()
|
* @throw nothrow
|
||||||
:m_iCode(cmUNKNOWN)
|
* @post m_iType==cmUNKNOWN
|
||||||
,m_iType(tpVOID)
|
* @sa #Assign
|
||||||
,m_pTok(0)
|
*/
|
||||||
,m_iIdx(-1)
|
QmuParserToken ( const QmuParserToken &a_Tok )
|
||||||
,m_strTok()
|
: m_iCode ( a_Tok.m_iCode ), m_iType ( a_Tok.m_iType ), m_pTok ( a_Tok.m_pTok ), m_iIdx ( a_Tok.m_iIdx ),
|
||||||
,m_pCallback()
|
m_strTok( a_Tok.m_strTok ), m_strVal(a_Tok.m_strVal), m_fVal(a_Tok.m_fVal), m_pCallback()
|
||||||
{}
|
{
|
||||||
|
Assign ( a_Tok );
|
||||||
//------------------------------------------------------------------------------
|
}
|
||||||
/** @brief Create token from another one.
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
Implemented by calling Assign(...)
|
/**
|
||||||
@throw nothrow
|
* @brief Assignement operator.
|
||||||
@post m_iType==cmUNKNOWN
|
*
|
||||||
@sa #Assign
|
* Copy token state from another token and return this.
|
||||||
*/
|
* Implemented by calling Assign(...).
|
||||||
QmuParserToken(const QmuParserToken &a_Tok)
|
* @throw nothrow
|
||||||
{
|
*/
|
||||||
Assign(a_Tok);
|
QmuParserToken& operator= ( const QmuParserToken &a_Tok )
|
||||||
}
|
{
|
||||||
|
Assign ( a_Tok );
|
||||||
//------------------------------------------------------------------------------
|
return *this;
|
||||||
/** @brief Assignement operator.
|
}
|
||||||
|
|
||||||
Copy token state from another token and return this.
|
//------------------------------------------------------------------------------
|
||||||
Implemented by calling Assign(...).
|
/**
|
||||||
@throw nothrow
|
* @brief Copy token information from argument.
|
||||||
*/
|
*
|
||||||
QmuParserToken& operator=(const QmuParserToken &a_Tok)
|
* @throw nothrow
|
||||||
{
|
*/
|
||||||
Assign(a_Tok);
|
void Assign ( const QmuParserToken &a_Tok )
|
||||||
return *this;
|
{
|
||||||
}
|
m_iCode = a_Tok.m_iCode;
|
||||||
|
m_pTok = a_Tok.m_pTok;
|
||||||
//------------------------------------------------------------------------------
|
m_strTok = a_Tok.m_strTok;
|
||||||
/** @brief Copy token information from argument.
|
m_iIdx = a_Tok.m_iIdx;
|
||||||
|
m_strVal = a_Tok.m_strVal;
|
||||||
@throw nothrow
|
m_iType = a_Tok.m_iType;
|
||||||
*/
|
m_fVal = a_Tok.m_fVal;
|
||||||
void Assign(const QmuParserToken &a_Tok)
|
// create new callback object if a_Tok has one
|
||||||
{
|
m_pCallback.reset ( a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0 );
|
||||||
m_iCode = a_Tok.m_iCode;
|
}
|
||||||
m_pTok = a_Tok.m_pTok;
|
|
||||||
m_strTok = a_Tok.m_strTok;
|
//------------------------------------------------------------------------------
|
||||||
m_iIdx = a_Tok.m_iIdx;
|
/**
|
||||||
m_strVal = a_Tok.m_strVal;
|
* @brief Assign a token type.
|
||||||
m_iType = a_Tok.m_iType;
|
*
|
||||||
m_fVal = a_Tok.m_fVal;
|
* Token may not be of type value, variable or function. Those have seperate set functions.
|
||||||
// create new callback object if a_Tok has one
|
*
|
||||||
m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0);
|
* @pre [assert] a_iType!=cmVAR
|
||||||
}
|
* @pre [assert] a_iType!=cmVAL
|
||||||
|
* @pre [assert] a_iType!=cmFUNC
|
||||||
//------------------------------------------------------------------------------
|
* @post m_fVal = 0
|
||||||
/** @brief Assign a token type.
|
* @post m_pTok = 0
|
||||||
|
*/
|
||||||
Token may not be of type value, variable or function. Those have seperate set functions.
|
QmuParserToken& Set ( ECmdCode a_iType, const TString &a_strTok = TString() )
|
||||||
|
{
|
||||||
\pre [assert] a_iType!=cmVAR
|
// The following types cant be set this way, they have special Set functions
|
||||||
\pre [assert] a_iType!=cmVAL
|
assert ( a_iType != cmVAR );
|
||||||
\pre [assert] a_iType!=cmFUNC
|
assert ( a_iType != cmVAL );
|
||||||
@post m_fVal = 0
|
assert ( a_iType != cmFUNC );
|
||||||
@post m_pTok = 0
|
|
||||||
*/
|
m_iCode = a_iType;
|
||||||
QmuParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString())
|
m_iType = tpVOID;
|
||||||
{
|
m_pTok = 0;
|
||||||
// The following types cant be set this way, they have special Set functions
|
m_strTok = a_strTok;
|
||||||
assert(a_iType!=cmVAR);
|
m_iIdx = -1;
|
||||||
assert(a_iType!=cmVAL);
|
|
||||||
assert(a_iType!=cmFUNC);
|
return *this;
|
||||||
|
}
|
||||||
m_iCode = a_iType;
|
|
||||||
m_iType = tpVOID;
|
//------------------------------------------------------------------------------
|
||||||
m_pTok = 0;
|
/**
|
||||||
m_strTok = a_strTok;
|
* @brief Set Callback type.
|
||||||
m_iIdx = -1;
|
*/
|
||||||
|
QmuParserToken& Set ( const QmuParserCallback &a_pCallback, const TString &a_sTok )
|
||||||
return *this;
|
{
|
||||||
}
|
assert ( a_pCallback.GetAddr() );
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
m_iCode = a_pCallback.GetCode();
|
||||||
/** @brief Set Callback type. */
|
m_iType = tpVOID;
|
||||||
QmuParserToken& Set(const QmuParserCallback &a_pCallback, const TString &a_sTok)
|
m_strTok = a_sTok;
|
||||||
{
|
m_pCallback.reset ( new QmuParserCallback ( a_pCallback ) );
|
||||||
assert(a_pCallback.GetAddr());
|
|
||||||
|
m_pTok = 0;
|
||||||
m_iCode = a_pCallback.GetCode();
|
m_iIdx = -1;
|
||||||
m_iType = tpVOID;
|
|
||||||
m_strTok = a_sTok;
|
return *this;
|
||||||
m_pCallback.reset(new QmuParserCallback(a_pCallback));
|
}
|
||||||
|
|
||||||
m_pTok = 0;
|
//------------------------------------------------------------------------------
|
||||||
m_iIdx = -1;
|
/**
|
||||||
|
* @brief Make this token a value token.
|
||||||
return *this;
|
*
|
||||||
}
|
* Member variables not necessary for value tokens will be invalidated.
|
||||||
|
* @throw nothrow
|
||||||
//------------------------------------------------------------------------------
|
*/
|
||||||
/** @brief Make this token a value token.
|
QmuParserToken& SetVal ( TBase a_fVal, const TString &a_strTok = TString() )
|
||||||
|
{
|
||||||
Member variables not necessary for value tokens will be invalidated.
|
m_iCode = cmVAL;
|
||||||
@throw nothrow
|
m_iType = tpDBL;
|
||||||
*/
|
m_fVal = a_fVal;
|
||||||
QmuParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString())
|
m_strTok = a_strTok;
|
||||||
{
|
m_iIdx = -1;
|
||||||
m_iCode = cmVAL;
|
|
||||||
m_iType = tpDBL;
|
m_pTok = 0;
|
||||||
m_fVal = a_fVal;
|
m_pCallback.reset ( 0 );
|
||||||
m_strTok = a_strTok;
|
|
||||||
m_iIdx = -1;
|
return *this;
|
||||||
|
}
|
||||||
m_pTok = 0;
|
|
||||||
m_pCallback.reset(0);
|
//------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
return *this;
|
* @brief make this token a variable token.
|
||||||
}
|
*
|
||||||
|
* Member variables not necessary for variable tokens will be invalidated.
|
||||||
//------------------------------------------------------------------------------
|
* @throw nothrow
|
||||||
/** @brief make this token a variable token.
|
*/
|
||||||
|
QmuParserToken& SetVar ( TBase *a_pVar, const TString &a_strTok )
|
||||||
Member variables not necessary for variable tokens will be invalidated.
|
{
|
||||||
@throw nothrow
|
m_iCode = cmVAR;
|
||||||
*/
|
m_iType = tpDBL;
|
||||||
QmuParserToken& SetVar(TBase *a_pVar, const TString &a_strTok)
|
m_strTok = a_strTok;
|
||||||
{
|
m_iIdx = -1;
|
||||||
m_iCode = cmVAR;
|
m_pTok = reinterpret_cast<void*> ( a_pVar );
|
||||||
m_iType = tpDBL;
|
m_pCallback.reset ( 0 );
|
||||||
m_strTok = a_strTok;
|
return *this;
|
||||||
m_iIdx = -1;
|
}
|
||||||
m_pTok = (void*)a_pVar;
|
|
||||||
m_pCallback.reset(0);
|
//------------------------------------------------------------------------------
|
||||||
return *this;
|
/**
|
||||||
}
|
* @brief Make this token a variable token.
|
||||||
|
*
|
||||||
//------------------------------------------------------------------------------
|
* Member variables not necessary for variable tokens will be invalidated.
|
||||||
/** @brief Make this token a variable token.
|
* @throw nothrow
|
||||||
|
*/
|
||||||
Member variables not necessary for variable tokens will be invalidated.
|
QmuParserToken& SetString ( const TString &a_strTok, std::size_t a_iSize )
|
||||||
@throw nothrow
|
{
|
||||||
*/
|
m_iCode = cmSTRING;
|
||||||
QmuParserToken& SetString(const TString &a_strTok, std::size_t a_iSize)
|
m_iType = tpSTR;
|
||||||
{
|
m_strTok = a_strTok;
|
||||||
m_iCode = cmSTRING;
|
m_iIdx = static_cast<int> ( a_iSize );
|
||||||
m_iType = tpSTR;
|
|
||||||
m_strTok = a_strTok;
|
m_pTok = 0;
|
||||||
m_iIdx = static_cast<int>(a_iSize);
|
m_pCallback.reset ( 0 );
|
||||||
|
return *this;
|
||||||
m_pTok = 0;
|
}
|
||||||
m_pCallback.reset(0);
|
|
||||||
return *this;
|
//------------------------------------------------------------------------------
|
||||||
}
|
/**
|
||||||
|
* @brief Set an index associated with the token related data.
|
||||||
//------------------------------------------------------------------------------
|
*
|
||||||
/** @brief Set an index associated with the token related data.
|
* In cmSTRFUNC - This is the index to a string table in the main parser.
|
||||||
|
* @param a_iIdx The index the string function result will take in the bytecode parser.
|
||||||
In cmSTRFUNC - This is the index to a string table in the main parser.
|
* @throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING
|
||||||
* @param a_iIdx The index the string function result will take in the bytecode parser.
|
*/
|
||||||
@throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING
|
void SetIdx ( int a_iIdx )
|
||||||
*/
|
{
|
||||||
void SetIdx(int a_iIdx)
|
if ( m_iCode != cmSTRING || a_iIdx < 0 )
|
||||||
{
|
throw QmuParserError ( ecINTERNAL_ERROR );
|
||||||
if (m_iCode!=cmSTRING || a_iIdx<0)
|
|
||||||
throw QmuParserError(ecINTERNAL_ERROR);
|
m_iIdx = a_iIdx;
|
||||||
|
}
|
||||||
m_iIdx = a_iIdx;
|
|
||||||
}
|
//------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
//------------------------------------------------------------------------------
|
* @brief Return Index associated with the token related data.
|
||||||
/** @brief Return Index associated with the token related data.
|
*
|
||||||
|
* In cmSTRFUNC - This is the index to a string table in the main parser.
|
||||||
In cmSTRFUNC - This is the index to a string table in the main parser.
|
*
|
||||||
|
* @throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING
|
||||||
@throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING
|
* @return The index the result will take in the Bytecode calculatin array (#m_iIdx).
|
||||||
* @return The index the result will take in the Bytecode calculatin array (#m_iIdx).
|
*/
|
||||||
*/
|
int GetIdx() const
|
||||||
int GetIdx() const
|
{
|
||||||
{
|
if ( m_iIdx < 0 || m_iCode != cmSTRING )
|
||||||
if (m_iIdx<0 || m_iCode!=cmSTRING )
|
throw QmuParserError ( ecINTERNAL_ERROR );
|
||||||
throw QmuParserError(ecINTERNAL_ERROR);
|
|
||||||
|
return m_iIdx;
|
||||||
return m_iIdx;
|
}
|
||||||
}
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
//------------------------------------------------------------------------------
|
/**
|
||||||
/** @brief Return the token type.
|
* @brief Return the token type.
|
||||||
|
*
|
||||||
* @return #m_iType
|
* @return #m_iType
|
||||||
@throw nothrow
|
* @throw nothrow
|
||||||
*/
|
*/
|
||||||
ECmdCode GetCode() const
|
ECmdCode GetCode() const
|
||||||
{
|
{
|
||||||
if (m_pCallback.get())
|
if ( m_pCallback.get() )
|
||||||
{
|
{
|
||||||
return m_pCallback->GetCode();
|
return m_pCallback->GetCode();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return m_iCode;
|
return m_iCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
ETypeCode GetType() const
|
ETypeCode GetType() const
|
||||||
{
|
{
|
||||||
if (m_pCallback.get())
|
if ( m_pCallback.get() )
|
||||||
{
|
{
|
||||||
return m_pCallback->GetType();
|
return m_pCallback->GetType();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return m_iType;
|
return m_iType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
int GetPri() const
|
int GetPri() const
|
||||||
{
|
{
|
||||||
if ( !m_pCallback.get())
|
if ( !m_pCallback.get() )
|
||||||
throw QmuParserError(ecINTERNAL_ERROR);
|
throw QmuParserError ( ecINTERNAL_ERROR );
|
||||||
|
|
||||||
if ( m_pCallback->GetCode()!=cmOPRT_BIN && m_pCallback->GetCode()!=cmOPRT_INFIX)
|
if ( m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX )
|
||||||
throw QmuParserError(ecINTERNAL_ERROR);
|
throw QmuParserError ( ecINTERNAL_ERROR );
|
||||||
|
|
||||||
return m_pCallback->GetPri();
|
return m_pCallback->GetPri();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
EOprtAssociativity GetAssociativity() const
|
EOprtAssociativity GetAssociativity() const
|
||||||
{
|
{
|
||||||
if (m_pCallback.get()==NULL || m_pCallback->GetCode()!=cmOPRT_BIN)
|
if ( m_pCallback.get() == NULL || m_pCallback->GetCode() != cmOPRT_BIN )
|
||||||
throw QmuParserError(ecINTERNAL_ERROR);
|
throw QmuParserError ( ecINTERNAL_ERROR );
|
||||||
|
|
||||||
return m_pCallback->GetAssociativity();
|
return m_pCallback->GetAssociativity();
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/** @brief Return the address of the callback function assoziated with
|
/**
|
||||||
function and operator tokens.
|
* @brief Return the address of the callback function assoziated with function and operator tokens.
|
||||||
|
*
|
||||||
* @return The pointer stored in #m_pTok.
|
* @return The pointer stored in #m_pTok.
|
||||||
@throw exception_type if token type is non of:
|
* @throw exception_type if token type is non of:
|
||||||
<ul>
|
* <ul>
|
||||||
<li>cmFUNC</li>
|
* <li>cmFUNC</li>
|
||||||
<li>cmSTRFUNC</li>
|
* <li>cmSTRFUNC</li>
|
||||||
<li>cmPOSTOP</li>
|
* <li>cmPOSTOP</li>
|
||||||
<li>cmINFIXOP</li>
|
* <li>cmINFIXOP</li>
|
||||||
<li>cmOPRT_BIN</li>
|
* <li>cmOPRT_BIN</li>
|
||||||
</ul>
|
* </ul>
|
||||||
@sa ECmdCode
|
* @sa ECmdCode
|
||||||
*/
|
*/
|
||||||
generic_fun_type GetFuncAddr() const
|
generic_fun_type GetFuncAddr() const
|
||||||
{
|
{
|
||||||
return (m_pCallback.get()) ? (generic_fun_type)m_pCallback->GetAddr() : 0;
|
return ( m_pCallback.get() ) ? reinterpret_cast<generic_fun_type> ( m_pCallback->GetAddr() ) :
|
||||||
}
|
reinterpret_cast<generic_fun_type> (0);
|
||||||
|
}
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
/** \biref Get value of the token.
|
//------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
Only applicable to variable and value tokens.
|
* @brief Get value of the token.
|
||||||
@throw exception_type if token is no value/variable token.
|
*
|
||||||
*/
|
* Only applicable to variable and value tokens.
|
||||||
TBase GetVal() const
|
* @throw exception_type if token is no value/variable token.
|
||||||
{
|
*/
|
||||||
switch (m_iCode)
|
TBase GetVal() const
|
||||||
{
|
{
|
||||||
case cmVAL: return m_fVal;
|
switch ( m_iCode )
|
||||||
case cmVAR: return *((TBase*)m_pTok);
|
{
|
||||||
default: throw QmuParserError(ecVAL_EXPECTED);
|
case cmVAL:
|
||||||
}
|
return m_fVal;
|
||||||
}
|
case cmVAR:
|
||||||
|
return * ( reinterpret_cast<TBase*>(m_pTok) );
|
||||||
//------------------------------------------------------------------------------
|
case cmLE:
|
||||||
/** @brief Get address of a variable token.
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
Valid only if m_iType==CmdVar.
|
case cmGE:
|
||||||
@throw exception_type if token is no variable token.
|
Q_UNREACHABLE();
|
||||||
*/
|
break;
|
||||||
TBase* GetVar() const
|
case cmNEQ:
|
||||||
{
|
Q_UNREACHABLE();
|
||||||
if (m_iCode!=cmVAR)
|
break;
|
||||||
throw QmuParserError(ecINTERNAL_ERROR);
|
case cmEQ:
|
||||||
|
Q_UNREACHABLE();
|
||||||
return (TBase*)m_pTok;
|
break;
|
||||||
}
|
case cmLT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
//------------------------------------------------------------------------------
|
break;
|
||||||
/** @brief Return the number of function arguments.
|
case cmGT:
|
||||||
|
Q_UNREACHABLE();
|
||||||
Valid only if m_iType==CmdFUNC.
|
break;
|
||||||
*/
|
case cmADD:
|
||||||
int GetArgCount() const
|
Q_UNREACHABLE();
|
||||||
{
|
break;
|
||||||
assert(m_pCallback.get());
|
case cmSUB:
|
||||||
|
Q_UNREACHABLE();
|
||||||
if (!m_pCallback->GetAddr())
|
break;
|
||||||
throw QmuParserError(ecINTERNAL_ERROR);
|
case cmMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
return m_pCallback->GetArgc();
|
break;
|
||||||
}
|
case cmDIV:
|
||||||
|
Q_UNREACHABLE();
|
||||||
//------------------------------------------------------------------------------
|
break;
|
||||||
/** @brief Return the token identifier.
|
case cmPOW:
|
||||||
|
Q_UNREACHABLE();
|
||||||
If #m_iType is cmSTRING the token identifier is the value of the string argument
|
break;
|
||||||
for a string function.
|
case cmLAND:
|
||||||
* @return #m_strTok
|
Q_UNREACHABLE();
|
||||||
@throw nothrow
|
break;
|
||||||
@sa m_strTok
|
case cmLOR:
|
||||||
*/
|
Q_UNREACHABLE();
|
||||||
const TString& GetAsString() const
|
break;
|
||||||
{
|
case cmASSIGN:
|
||||||
return m_strTok;
|
Q_UNREACHABLE();
|
||||||
}
|
break;
|
||||||
};
|
case cmBO:
|
||||||
} // namespace qmu
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
#endif
|
case cmBC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmELSE:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmENDIF:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmARG_SEP:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW3:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARPOW4:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmVARMUL:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmPOW2:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_STR:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmFUNC_BULK:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmSTRING:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_BIN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_POSTFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmOPRT_INFIX:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmEND:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
case cmUNKNOWN:
|
||||||
|
Q_UNREACHABLE();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw QmuParserError ( ecVAL_EXPECTED );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief Get address of a variable token.
|
||||||
|
*
|
||||||
|
* Valid only if m_iType==CmdVar.
|
||||||
|
* @throw exception_type if token is no variable token.
|
||||||
|
*/
|
||||||
|
TBase* GetVar() const
|
||||||
|
{
|
||||||
|
if ( m_iCode != cmVAR )
|
||||||
|
{
|
||||||
|
throw QmuParserError ( ecINTERNAL_ERROR );
|
||||||
|
}
|
||||||
|
|
||||||
|
return reinterpret_cast<TBase*>( m_pTok );
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief Return the number of function arguments.
|
||||||
|
*
|
||||||
|
* Valid only if m_iType==CmdFUNC.
|
||||||
|
*/
|
||||||
|
int GetArgCount() const
|
||||||
|
{
|
||||||
|
assert ( m_pCallback.get() );
|
||||||
|
|
||||||
|
if ( !m_pCallback->GetAddr() )
|
||||||
|
throw QmuParserError ( ecINTERNAL_ERROR );
|
||||||
|
|
||||||
|
return m_pCallback->GetArgc();
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* @brief Return the token identifier.
|
||||||
|
*
|
||||||
|
* If #m_iType is cmSTRING the token identifier is the value of the string argument
|
||||||
|
* for a string function.
|
||||||
|
* @return #m_strTok
|
||||||
|
* @throw nothrow
|
||||||
|
* @sa m_strTok
|
||||||
|
*/
|
||||||
|
const TString& GetAsString() const
|
||||||
|
{
|
||||||
|
return m_strTok;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode.
|
||||||
|
ETypeCode m_iType;
|
||||||
|
void *m_pTok; ///< Stores Token pointer; not applicable for all tokens
|
||||||
|
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
|
||||||
|
qreal m_fVal; ///< the value
|
||||||
|
std::unique_ptr<QmuParserCallback> m_pCallback;
|
||||||
|
};
|
||||||
|
} // namespace qmu
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -44,9 +44,15 @@ class QmuParserBase;
|
||||||
* @throw nothrow
|
* @throw nothrow
|
||||||
*/
|
*/
|
||||||
QmuParserTokenReader::QmuParserTokenReader ( const QmuParserTokenReader &a_Reader )
|
QmuParserTokenReader::QmuParserTokenReader ( const QmuParserTokenReader &a_Reader )
|
||||||
{
|
:m_pParser( a_Reader.m_pParser ), m_strFormula( a_Reader.m_strFormula ), m_iPos( a_Reader.m_iPos ),
|
||||||
Assign ( a_Reader );
|
m_iSynFlags( a_Reader.m_iSynFlags ), m_bIgnoreUndefVar( a_Reader.m_bIgnoreUndefVar ),
|
||||||
}
|
m_pFunDef( a_Reader.m_pFunDef ), m_pPostOprtDef( a_Reader.m_pPostOprtDef ),
|
||||||
|
m_pInfixOprtDef( a_Reader.m_pInfixOprtDef ), m_pOprtDef( a_Reader.m_pOprtDef),
|
||||||
|
m_pConstDef( a_Reader.m_pConstDef ), m_pStrVarDef( a_Reader.m_pStrVarDef ), m_pVarDef( a_Reader.m_pVarDef ),
|
||||||
|
m_pFactory( a_Reader.m_pFactory ), m_pFactoryData( a_Reader.m_pFactoryData ), m_vIdentFun( a_Reader.m_vIdentFun ),
|
||||||
|
m_UsedVar( a_Reader.m_UsedVar ), m_fZero(0), m_iBrackets( a_Reader.m_iBrackets ), m_lastTok(),
|
||||||
|
m_cArgSep( a_Reader.m_cArgSep )
|
||||||
|
{}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
@ -128,7 +134,7 @@ QmuParserTokenReader::QmuParserTokenReader ( QmuParserBase *a_pParent )
|
||||||
*/
|
*/
|
||||||
QmuParserTokenReader* QmuParserTokenReader::Clone ( QmuParserBase *a_pParent ) const
|
QmuParserTokenReader* QmuParserTokenReader::Clone ( QmuParserBase *a_pParent ) const
|
||||||
{
|
{
|
||||||
std::auto_ptr<QmuParserTokenReader> ptr ( new QmuParserTokenReader ( *this ) );
|
std::unique_ptr<QmuParserTokenReader> ptr ( new QmuParserTokenReader ( *this ) );
|
||||||
ptr->SetParent ( a_pParent );
|
ptr->SetParent ( a_pParent );
|
||||||
return ptr.release();
|
return ptr.release();
|
||||||
}
|
}
|
||||||
|
@ -330,11 +336,11 @@ int QmuParserTokenReader::ExtractToken ( const QString &a_szCharSet, QString &a_
|
||||||
const std::string a_szCharSetStd = a_szCharSet.toStdString();
|
const std::string a_szCharSetStd = a_szCharSet.toStdString();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int iEnd = ( int ) m_strFormulaStd.find_first_not_of ( a_szCharSetStd, a_iPos );
|
int iEnd = static_cast<int>(m_strFormulaStd.find_first_not_of ( a_szCharSetStd, a_iPos ));
|
||||||
|
|
||||||
if ( iEnd == ( int ) string_type::npos )
|
if ( iEnd == static_cast<int>(string_type::npos) )
|
||||||
{
|
{
|
||||||
iEnd = ( int ) m_strFormulaStd.length();
|
iEnd = static_cast<int>(m_strFormulaStd.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign token string if there was something found
|
// Assign token string if there was something found
|
||||||
|
@ -367,10 +373,10 @@ int QmuParserTokenReader::ExtractOperatorToken ( QString &a_sTok, int a_iPos ) c
|
||||||
const std::string m_strFormulaStd = m_strFormula.toStdString();
|
const std::string m_strFormulaStd = m_strFormula.toStdString();
|
||||||
const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString();
|
const std::string oprtCharsStd = m_pParser->ValidInfixOprtChars().toStdString();
|
||||||
#endif
|
#endif
|
||||||
int iEnd = ( int ) m_strFormulaStd.find_first_not_of ( oprtCharsStd, a_iPos );
|
int iEnd = static_cast<int>( m_strFormulaStd.find_first_not_of ( oprtCharsStd, a_iPos ) );
|
||||||
if ( iEnd == ( int ) string_type::npos )
|
if ( iEnd == static_cast<int>( string_type::npos ) )
|
||||||
{
|
{
|
||||||
iEnd = ( int ) m_strFormulaStd.length();
|
iEnd = static_cast<int>( m_strFormulaStd.length() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign token string if there was something found
|
// Assign token string if there was something found
|
||||||
|
@ -492,7 +498,7 @@ bool QmuParserTokenReader::IsBuiltIn ( token_type &a_Tok )
|
||||||
} // switch operator id
|
} // switch operator id
|
||||||
|
|
||||||
m_iPos += len;
|
m_iPos += len;
|
||||||
a_Tok.Set ( ( ECmdCode ) i, pOprtDef.at ( i ) );
|
a_Tok.Set ( static_cast<ECmdCode>(i), pOprtDef.at ( i ) );
|
||||||
return true;
|
return true;
|
||||||
} // if operator string found
|
} // if operator string found
|
||||||
} // end of for all operator strings
|
} // end of for all operator strings
|
||||||
|
@ -578,7 +584,7 @@ bool QmuParserTokenReader::IsInfixOpTok ( token_type &a_Tok )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
a_Tok.Set ( it->second, it->first );
|
a_Tok.Set ( it->second, it->first );
|
||||||
m_iPos += ( int ) it->first.length();
|
m_iPos += static_cast<int>(it->first.length());
|
||||||
|
|
||||||
if ( m_iSynFlags & noINFIXOP )
|
if ( m_iSynFlags & noINFIXOP )
|
||||||
Error ( ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString() );
|
Error ( ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString() );
|
||||||
|
@ -628,7 +634,7 @@ bool QmuParserTokenReader::IsFunTok ( token_type &a_Tok )
|
||||||
|
|
||||||
m_iPos = iEnd;
|
m_iPos = iEnd;
|
||||||
if ( m_iSynFlags & noFUN )
|
if ( m_iSynFlags & noFUN )
|
||||||
Error ( ecUNEXPECTED_FUN, m_iPos - ( int ) a_Tok.GetAsString().length(), a_Tok.GetAsString() );
|
Error ( ecUNEXPECTED_FUN, m_iPos - static_cast<int>(a_Tok.GetAsString().length()), a_Tok.GetAsString() );
|
||||||
|
|
||||||
m_iSynFlags = noANY ^ noBO;
|
m_iSynFlags = noANY ^ noBO;
|
||||||
return true;
|
return true;
|
||||||
|
@ -690,7 +696,7 @@ bool QmuParserTokenReader::IsOprt ( token_type &a_Tok )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_iPos += ( int ) sID.length();
|
m_iPos += sID.length();
|
||||||
m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN;
|
m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -828,7 +834,7 @@ bool QmuParserTokenReader::IsVarTok ( token_type &a_Tok )
|
||||||
if ( m_iSynFlags & noVAR )
|
if ( m_iSynFlags & noVAR )
|
||||||
Error ( ecUNEXPECTED_VAR, m_iPos, strTok );
|
Error ( ecUNEXPECTED_VAR, m_iPos, strTok );
|
||||||
|
|
||||||
m_pParser->OnDetectVar ( &m_strFormula, m_iPos, iEnd );
|
m_pParser->OnDetectVar ( m_strFormula, m_iPos, iEnd );
|
||||||
|
|
||||||
m_iPos = iEnd;
|
m_iPos = iEnd;
|
||||||
a_Tok.SetVar ( item->second, strTok );
|
a_Tok.SetVar ( item->second, strTok );
|
||||||
|
@ -893,7 +899,7 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok )
|
||||||
// token identifier.
|
// token identifier.
|
||||||
// related bug report:
|
// related bug report:
|
||||||
// http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979
|
// http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979
|
||||||
Error ( ecUNEXPECTED_VAR, m_iPos - ( int ) a_Tok.GetAsString().length(), strTok );
|
Error ( ecUNEXPECTED_VAR, m_iPos - a_Tok.GetAsString().length(), strTok );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a factory is available implicitely create new variables
|
// If a factory is available implicitely create new variables
|
||||||
|
@ -913,7 +919,7 @@ bool QmuParserTokenReader::IsUndefVarTok ( token_type &a_Tok )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_Tok.SetVar ( ( qreal* ) &m_fZero, strTok );
|
a_Tok.SetVar ( &m_fZero, strTok );
|
||||||
m_UsedVar[strTok] = 0; // Add variable to used-var-list
|
m_UsedVar[strTok] = 0; // Add variable to used-var-list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,7 +966,7 @@ bool QmuParserTokenReader::IsString ( token_type &a_Tok )
|
||||||
m_pParser->m_vStringBuf.push_back ( strTok ); // Store string in internal buffer
|
m_pParser->m_vStringBuf.push_back ( strTok ); // Store string in internal buffer
|
||||||
a_Tok.SetString ( strTok, m_pParser->m_vStringBuf.size() );
|
a_Tok.SetString ( strTok, m_pParser->m_vStringBuf.size() );
|
||||||
|
|
||||||
m_iPos += ( int ) strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen
|
m_iPos += strTok.length() + 2 + iSkip; // +2 wg Anfhrungszeichen; +iSkip fr entfernte escape zeichen
|
||||||
m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND );
|
m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user