Optimization Tokenizer::simplifyMathFunctions. Make an a priori check whether the token combination can be a function call at all.
This commit is contained in:
parent
b13e3ac549
commit
6e9e20d5b1
467
lib/tokenize.cpp
467
lib/tokenize.cpp
|
@ -8241,249 +8241,252 @@ bool Tokenizer::simplifyMathFunctions()
|
|||
{
|
||||
bool simplifcationMade = false;
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "atol ( %str% )")) { //@todo Add support for atoll()
|
||||
if (tok->previous() &&
|
||||
Token::simpleMatch(tok->tokAt(-2), "std ::")) {
|
||||
tok = tok->tokAt(-2);// set token index two steps back
|
||||
tok->deleteNext(2); // delete "std ::"
|
||||
}
|
||||
const std::string strNumber = tok->tokAt(2)->strValue(); // get number
|
||||
const bool isNotAnInteger = (!MathLib::isInt(strNumber));// check: is not an integer
|
||||
if (!strNumber.empty() && isNotAnInteger) {
|
||||
// Ignore strings which we can't convert
|
||||
continue;
|
||||
}
|
||||
// remove atol ( %num%
|
||||
tok->deleteNext(3);
|
||||
// Convert string into a number and insert into token list
|
||||
tok->str(MathLib::toString(MathLib::toLongNumber(strNumber)));
|
||||
simplifcationMade = true;
|
||||
} else if (Token::Match(tok, "abs|fabs|labs|llabs ( %num% )")) {
|
||||
if (tok->previous() &&
|
||||
Token::simpleMatch(tok->tokAt(-2), "std ::")) {
|
||||
tok = tok->tokAt(-2);// set token index two steps back
|
||||
tok->deleteNext(2); // delete "std ::"
|
||||
}
|
||||
// get number string
|
||||
std::string strNumber(tok->tokAt(2)->str());
|
||||
// is the string negative?
|
||||
if (!strNumber.empty() && strNumber[0] == '-') {
|
||||
strNumber = strNumber.substr(1); // remove '-' sign
|
||||
}
|
||||
tok->deleteNext(3); // delete e.g. abs ( 1 )
|
||||
tok->str(strNumber); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
} else if (Token::Match(tok, "fma|fmaf|fmal ( %any% , %any% , %any% )")) {
|
||||
// Simplify: fma(a,b,c) == > ( a ) * ( b ) + ( c )
|
||||
// get parameters
|
||||
const std::string a(tok->tokAt(2)->str());
|
||||
const std::string b(tok->tokAt(4)->str());
|
||||
const std::string c(tok->tokAt(6)->str());
|
||||
if (!a.empty() && !b.empty() && !c.empty()) {
|
||||
tok->deleteNext(7); // delete fma call
|
||||
tok->str("( " + a + " ) * ( " + b + " ) + ( " + c + " )"); // insert result into token list
|
||||
const Token * tokNext = tok->next();
|
||||
if (tokNext && tokNext->str() == "(") { // precondition for function
|
||||
if (Token::Match(tok, "atol ( %str% )")) { //@todo Add support for atoll()
|
||||
if (tok->previous() &&
|
||||
Token::simpleMatch(tok->tokAt(-2), "std ::")) {
|
||||
tok = tok->tokAt(-2);// set token index two steps back
|
||||
tok->deleteNext(2); // delete "std ::"
|
||||
}
|
||||
const std::string strNumber = tok->tokAt(2)->strValue(); // get number
|
||||
const bool isNotAnInteger = (!MathLib::isInt(strNumber));// check: is not an integer
|
||||
if (!strNumber.empty() && isNotAnInteger) {
|
||||
// Ignore strings which we can't convert
|
||||
continue;
|
||||
}
|
||||
// remove atol ( %num%
|
||||
tok->deleteNext(3);
|
||||
// Convert string into a number and insert into token list
|
||||
tok->str(MathLib::toString(MathLib::toLongNumber(strNumber)));
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "sqrt|sqrtf|sqrtl|cbrt|cbrtf|cbrtl ( %num% )")) {
|
||||
// Simplify: sqrt(0) = 0 and cbrt(0) == 0
|
||||
// sqrt(1) = 1 and cbrt(1) == 1
|
||||
// get number string
|
||||
const std::string parameter(tok->tokAt(2)->str());
|
||||
// is parameter 0 ?
|
||||
if (isZeroNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("0"); // insert result into token list
|
||||
} else if (Token::Match(tok, "abs|fabs|labs|llabs ( %num% )")) {
|
||||
if (tok->previous() &&
|
||||
Token::simpleMatch(tok->tokAt(-2), "std ::")) {
|
||||
tok = tok->tokAt(-2);// set token index two steps back
|
||||
tok->deleteNext(2); // delete "std ::"
|
||||
}
|
||||
// get number string
|
||||
std::string strNumber(tok->tokAt(2)->str());
|
||||
// is the string negative?
|
||||
if (!strNumber.empty() && strNumber[0] == '-') {
|
||||
strNumber = strNumber.substr(1); // remove '-' sign
|
||||
}
|
||||
tok->deleteNext(3); // delete e.g. abs ( 1 )
|
||||
tok->str(strNumber); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
} else if (isOneNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("1"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "exp|expf|expl|exp2|exp2f|exp2l|cos|cosf|cosl|cosh|coshf|coshl|erfc|erfcf|erfcl ( %num% )")) {
|
||||
// Simplify: exp[f|l](0) = 1 and exp2[f|l](0) = 1
|
||||
// cosh[f|l](0) = 1 and cos[f|l](0) = 1
|
||||
// erfc[f|l](0) = 1
|
||||
// get number string
|
||||
const std::string parameter(tok->tokAt(2)->str());
|
||||
// is parameter 0 ?
|
||||
if (isZeroNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("1"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "log1p|log1pf|log1pl|sin|sinf|sinl|sinh|sinhf|sinhl|erf|erff|erfl|asin|asinf|asinl|asinh|asinhf|asinhl|tan|tanf|tanl|tanh|tanhf|tanhl|atan|atanf|atanl|atanh|atanhf|atanhl|expm1|expm1f|expm1l ( %num% )")) {
|
||||
// Simplify: log1p[f|l](0) = 0 and sin[f|l](0) = 0
|
||||
// sinh[f|l](0) = 0 and erf[f|l](0) = 0
|
||||
// asin[f|l](0) = 0 and sinh[f|l](0) = 0
|
||||
// tan[f|l](0) = 0 and tanh[f|l](0) = 0
|
||||
// atan[f|l](0) = 0 and atanh[f|l](0)= 0
|
||||
// expm1[f|l](0) = 0
|
||||
// get number string
|
||||
const std::string parameter(tok->tokAt(2)->str());
|
||||
// is parameter 0 ?
|
||||
if (isZeroNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("0"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "log2|log2f|log2l|log|logf|logl|log10|log10f|log10l|logb|logbf|logbl|acosh|acoshf|acoshl|acos|acosf|acosl|ilogb|ilogbf|ilogbl ( %num% )")) {
|
||||
// Simplify: log2[f|l](1) = 0 , log10[f|l](1) = 0
|
||||
// log[f|l](1) = 0 , logb10[f|l](1) = 0
|
||||
// acosh[f|l](1) = 0 , acos[f|l](1) = 0
|
||||
// ilogb[f|l](1) = 0
|
||||
// get number string
|
||||
const std::string parameter(tok->tokAt(2)->str());
|
||||
// is parameter 1 ?
|
||||
if (isOneNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("0"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "fmin|fminl|fminf ( %num% , %num% )")) {
|
||||
// @todo if one of the parameters is NaN the other is returned
|
||||
// e.g. printf ("fmin (NaN, -1.0) = %f\n", fmin(NaN,-1.0));
|
||||
// e.g. printf ("fmin (-1.0, NaN) = %f\n", fmin(-1.0,NaN));
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str());
|
||||
const std::string strRightNumber(tok->tokAt(4)->str());
|
||||
const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber);
|
||||
// case: left <= right ==> insert left
|
||||
if (!strLeftNumber.empty() && !strRightNumber.empty() && isLessEqual) {
|
||||
tok->deleteNext(5); // delete e.g. fmin ( -1.0, 1.0 )
|
||||
tok->str(strLeftNumber); // insert e.g. -1.0
|
||||
simplifcationMade = true;
|
||||
} else { // case left > right ==> insert right
|
||||
tok->deleteNext(5); // delete e.g. fmin ( 1.0, 0.0 )
|
||||
tok->str(strRightNumber); // insert e.g. 0.0
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "fmax|fmaxl|fmaxf ( %num% , %num% )")) {
|
||||
// @todo if one of the parameters is NaN the other is returned
|
||||
// e.g. printf ("fmax (NaN, -1.0) = %f\n", fmax(NaN,-1.0));
|
||||
// e.g. printf ("fmax (-1.0, NaN) = %f\n", fmax(-1.0,NaN));
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str());
|
||||
const std::string strRightNumber(tok->tokAt(4)->str());
|
||||
const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber);
|
||||
// case: left <= right ==> insert right
|
||||
if (!strLeftNumber.empty() && !strRightNumber.empty() && isLessEqual) {
|
||||
tok->deleteNext(5); // delete e.g. fmax ( -1.0, 1.0 )
|
||||
tok->str(strRightNumber);// insert e.g. 1.0
|
||||
simplifcationMade = true;
|
||||
} else { // case left > right ==> insert left
|
||||
tok->deleteNext(5); // delete e.g. fmax ( 1.0, 0.0 )
|
||||
tok->str(strLeftNumber); // insert e.g. 1.0
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "isgreater ( %num% , %num% )")) {
|
||||
// The isgreater(x,y) function is the same as calculating (x)>(y).
|
||||
// It returns true (1) if x is greater than y and false (0) otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isGreater = MathLib::isGreater(strLeftNumber, strRightNumber); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isGreater == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "isgreaterequal ( %num% , %num% )")) {
|
||||
// The isgreaterequal(x,y) function is the same as calculating (x)>=(y).
|
||||
// It returns true (1) if x is greater than or equal to y.
|
||||
// False (0) is returned otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isGreaterEqual = MathLib::isGreaterEqual(strLeftNumber, strRightNumber); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isGreaterEqual == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "isless ( %num% , %num% )")) {
|
||||
// Calling this function is the same as calculating (x)<(y).
|
||||
// It returns true (1) if x is less than y.
|
||||
// False (0) is returned otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isLess = MathLib::isLess(strLeftNumber, strRightNumber); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isLess == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "islessequal ( %num% , %num% )")) {
|
||||
// Calling this function is the same as calculating (x)<=(y).
|
||||
// It returns true (1) if x is less or equal to y.
|
||||
// False (0) is returned otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isLessEqual == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "islessgreater ( %num% , %num% )")) {
|
||||
// Calling this function is the same as calculating (x)<(y) || (x)>(y).
|
||||
// It returns true (1) if x is less than y or x is greater than y.
|
||||
// False (0) is returned otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isLessOrGreater(MathLib::isLess(strLeftNumber, strRightNumber) ||
|
||||
MathLib::isGreater(strLeftNumber, strRightNumber)); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isLessOrGreater == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "div|ldiv|lldiv ( %any% , %num% )")) {
|
||||
// Calling the function 'div(x,y)' is the same as calculating (x)/(y). In case y has the value 1
|
||||
// (the identity element), the call can be simplified to (x).
|
||||
const std::string leftParameter(tok->tokAt(2)->str()); // get the left parameter
|
||||
const std::string rightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!rightNumber.empty() && !leftParameter.empty()) {
|
||||
if (isOneNumber(rightNumber)) {
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str(leftParameter); // insert simplified result
|
||||
} else if (Token::Match(tok, "fma|fmaf|fmal ( %any% , %any% , %any% )")) {
|
||||
// Simplify: fma(a,b,c) == > ( a ) * ( b ) + ( c )
|
||||
// get parameters
|
||||
const std::string a(tok->tokAt(2)->str());
|
||||
const std::string b(tok->tokAt(4)->str());
|
||||
const std::string c(tok->tokAt(6)->str());
|
||||
if (!a.empty() && !b.empty() && !c.empty()) {
|
||||
tok->deleteNext(7); // delete fma call
|
||||
tok->str("( " + a + " ) * ( " + b + " ) + ( " + c + " )"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
}
|
||||
}
|
||||
} else if (Token::Match(tok, "pow|powf|powl (")) {
|
||||
if (tok && Token::Match(tok->tokAt(2), "%num% , %num% )")) {
|
||||
// In case of pow ( 0 , anyNumber > 0): It can be simplified to 0
|
||||
// In case of pow ( 0 , 0 ): It simplified to 1
|
||||
// In case of pow ( 1 , anyNumber ): It simplified to 1
|
||||
const std::string leftNumber(tok->tokAt(2)->str()); // get the left parameter
|
||||
const std::string rightNumber(tok->tokAt(4)->str()); // get the right parameter
|
||||
if (!leftNumber.empty() && !rightNumber.empty()) {
|
||||
const bool isLeftNumberZero = isZeroNumber(leftNumber);
|
||||
const bool isLeftNumberOne = isOneNumber(leftNumber);
|
||||
const bool isRightNumberZero = isZeroNumber(rightNumber);
|
||||
if (isLeftNumberZero && !isRightNumberZero && MathLib::isPositive(rightNumber)) { // case: 0^(y) = 0 and y > 0
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str("0"); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
} else if (isLeftNumberZero && isRightNumberZero) { // case: 0^0 = 1
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str("1"); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
} else if (isLeftNumberOne) { // case 1^(y) = 1
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str("1"); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "sqrt|sqrtf|sqrtl|cbrt|cbrtf|cbrtl ( %num% )")) {
|
||||
// Simplify: sqrt(0) = 0 and cbrt(0) == 0
|
||||
// sqrt(1) = 1 and cbrt(1) == 1
|
||||
// get number string
|
||||
const std::string parameter(tok->tokAt(2)->str());
|
||||
// is parameter 0 ?
|
||||
if (isZeroNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("0"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
} else if (isOneNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("1"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
}
|
||||
}
|
||||
if (tok && Token::Match(tok->tokAt(2), "%any% , %num% )")) {
|
||||
// In case of pow( x , 1 ): It can be simplified to x.
|
||||
} else if (Token::Match(tok, "exp|expf|expl|exp2|exp2f|exp2l|cos|cosf|cosl|cosh|coshf|coshl|erfc|erfcf|erfcl ( %num% )")) {
|
||||
// Simplify: exp[f|l](0) = 1 and exp2[f|l](0) = 1
|
||||
// cosh[f|l](0) = 1 and cos[f|l](0) = 1
|
||||
// erfc[f|l](0) = 1
|
||||
// get number string
|
||||
const std::string parameter(tok->tokAt(2)->str());
|
||||
// is parameter 0 ?
|
||||
if (isZeroNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("1"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "log1p|log1pf|log1pl|sin|sinf|sinl|sinh|sinhf|sinhl|erf|erff|erfl|asin|asinf|asinl|asinh|asinhf|asinhl|tan|tanf|tanl|tanh|tanhf|tanhl|atan|atanf|atanl|atanh|atanhf|atanhl|expm1|expm1f|expm1l ( %num% )")) {
|
||||
// Simplify: log1p[f|l](0) = 0 and sin[f|l](0) = 0
|
||||
// sinh[f|l](0) = 0 and erf[f|l](0) = 0
|
||||
// asin[f|l](0) = 0 and sinh[f|l](0) = 0
|
||||
// tan[f|l](0) = 0 and tanh[f|l](0) = 0
|
||||
// atan[f|l](0) = 0 and atanh[f|l](0)= 0
|
||||
// expm1[f|l](0) = 0
|
||||
// get number string
|
||||
const std::string parameter(tok->tokAt(2)->str());
|
||||
// is parameter 0 ?
|
||||
if (isZeroNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("0"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "log2|log2f|log2l|log|logf|logl|log10|log10f|log10l|logb|logbf|logbl|acosh|acoshf|acoshl|acos|acosf|acosl|ilogb|ilogbf|ilogbl ( %num% )")) {
|
||||
// Simplify: log2[f|l](1) = 0 , log10[f|l](1) = 0
|
||||
// log[f|l](1) = 0 , logb10[f|l](1) = 0
|
||||
// acosh[f|l](1) = 0 , acos[f|l](1) = 0
|
||||
// ilogb[f|l](1) = 0
|
||||
// get number string
|
||||
const std::string parameter(tok->tokAt(2)->str());
|
||||
// is parameter 1 ?
|
||||
if (isOneNumber(parameter)) {
|
||||
tok->deleteNext(3); // delete tokens
|
||||
tok->str("0"); // insert result into token list
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "fmin|fminl|fminf ( %num% , %num% )")) {
|
||||
// @todo if one of the parameters is NaN the other is returned
|
||||
// e.g. printf ("fmin (NaN, -1.0) = %f\n", fmin(NaN,-1.0));
|
||||
// e.g. printf ("fmin (-1.0, NaN) = %f\n", fmin(-1.0,NaN));
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str());
|
||||
const std::string strRightNumber(tok->tokAt(4)->str());
|
||||
const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber);
|
||||
// case: left <= right ==> insert left
|
||||
if (!strLeftNumber.empty() && !strRightNumber.empty() && isLessEqual) {
|
||||
tok->deleteNext(5); // delete e.g. fmin ( -1.0, 1.0 )
|
||||
tok->str(strLeftNumber); // insert e.g. -1.0
|
||||
simplifcationMade = true;
|
||||
} else { // case left > right ==> insert right
|
||||
tok->deleteNext(5); // delete e.g. fmin ( 1.0, 0.0 )
|
||||
tok->str(strRightNumber); // insert e.g. 0.0
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "fmax|fmaxl|fmaxf ( %num% , %num% )")) {
|
||||
// @todo if one of the parameters is NaN the other is returned
|
||||
// e.g. printf ("fmax (NaN, -1.0) = %f\n", fmax(NaN,-1.0));
|
||||
// e.g. printf ("fmax (-1.0, NaN) = %f\n", fmax(-1.0,NaN));
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str());
|
||||
const std::string strRightNumber(tok->tokAt(4)->str());
|
||||
const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber);
|
||||
// case: left <= right ==> insert right
|
||||
if (!strLeftNumber.empty() && !strRightNumber.empty() && isLessEqual) {
|
||||
tok->deleteNext(5); // delete e.g. fmax ( -1.0, 1.0 )
|
||||
tok->str(strRightNumber);// insert e.g. 1.0
|
||||
simplifcationMade = true;
|
||||
} else { // case left > right ==> insert left
|
||||
tok->deleteNext(5); // delete e.g. fmax ( 1.0, 0.0 )
|
||||
tok->str(strLeftNumber); // insert e.g. 1.0
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "isgreater ( %num% , %num% )")) {
|
||||
// The isgreater(x,y) function is the same as calculating (x)>(y).
|
||||
// It returns true (1) if x is greater than y and false (0) otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isGreater = MathLib::isGreater(strLeftNumber, strRightNumber); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isGreater == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "isgreaterequal ( %num% , %num% )")) {
|
||||
// The isgreaterequal(x,y) function is the same as calculating (x)>=(y).
|
||||
// It returns true (1) if x is greater than or equal to y.
|
||||
// False (0) is returned otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isGreaterEqual = MathLib::isGreaterEqual(strLeftNumber, strRightNumber); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isGreaterEqual == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "isless ( %num% , %num% )")) {
|
||||
// Calling this function is the same as calculating (x)<(y).
|
||||
// It returns true (1) if x is less than y.
|
||||
// False (0) is returned otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isLess = MathLib::isLess(strLeftNumber, strRightNumber); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isLess == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "islessequal ( %num% , %num% )")) {
|
||||
// Calling this function is the same as calculating (x)<=(y).
|
||||
// It returns true (1) if x is less or equal to y.
|
||||
// False (0) is returned otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isLessEqual == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "islessgreater ( %num% , %num% )")) {
|
||||
// Calling this function is the same as calculating (x)<(y) || (x)>(y).
|
||||
// It returns true (1) if x is less than y or x is greater than y.
|
||||
// False (0) is returned otherwise.
|
||||
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
|
||||
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
|
||||
const bool isLessOrGreater(MathLib::isLess(strLeftNumber, strRightNumber) ||
|
||||
MathLib::isGreater(strLeftNumber, strRightNumber)); // compare numbers
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str((isLessOrGreater == true) ? "true": "false"); // insert results
|
||||
simplifcationMade = true;
|
||||
}
|
||||
} else if (Token::Match(tok, "div|ldiv|lldiv ( %any% , %num% )")) {
|
||||
// Calling the function 'div(x,y)' is the same as calculating (x)/(y). In case y has the value 1
|
||||
// (the identity element), the call can be simplified to (x).
|
||||
const std::string leftParameter(tok->tokAt(2)->str()); // get the left parameter
|
||||
const std::string rightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!rightNumber.empty() && !leftParameter.empty()) {
|
||||
if (isOneNumber(rightNumber)) { // case: x^(1) = x
|
||||
if (isOneNumber(rightNumber)) {
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str(leftParameter); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
} else if (isZeroNumber(rightNumber)) { // case: x^(0) = 1
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str("1"); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
}
|
||||
}
|
||||
} else if (Token::Match(tok, "pow|powf|powl (")) {
|
||||
if (tok && Token::Match(tok->tokAt(2), "%num% , %num% )")) {
|
||||
// In case of pow ( 0 , anyNumber > 0): It can be simplified to 0
|
||||
// In case of pow ( 0 , 0 ): It simplified to 1
|
||||
// In case of pow ( 1 , anyNumber ): It simplified to 1
|
||||
const std::string leftNumber(tok->tokAt(2)->str()); // get the left parameter
|
||||
const std::string rightNumber(tok->tokAt(4)->str()); // get the right parameter
|
||||
if (!leftNumber.empty() && !rightNumber.empty()) {
|
||||
const bool isLeftNumberZero = isZeroNumber(leftNumber);
|
||||
const bool isLeftNumberOne = isOneNumber(leftNumber);
|
||||
const bool isRightNumberZero = isZeroNumber(rightNumber);
|
||||
if (isLeftNumberZero && !isRightNumberZero && MathLib::isPositive(rightNumber)) { // case: 0^(y) = 0 and y > 0
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str("0"); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
} else if (isLeftNumberZero && isRightNumberZero) { // case: 0^0 = 1
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str("1"); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
} else if (isLeftNumberOne) { // case 1^(y) = 1
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str("1"); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tok && Token::Match(tok->tokAt(2), "%any% , %num% )")) {
|
||||
// In case of pow( x , 1 ): It can be simplified to x.
|
||||
const std::string leftParameter(tok->tokAt(2)->str()); // get the left parameter
|
||||
const std::string rightNumber(tok->tokAt(4)->str()); // get right number
|
||||
if (!rightNumber.empty() && !leftParameter.empty()) {
|
||||
if (isOneNumber(rightNumber)) { // case: x^(1) = x
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str(leftParameter); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
} else if (isZeroNumber(rightNumber)) { // case: x^(0) = 1
|
||||
tok->deleteNext(5); // delete tokens
|
||||
tok->str("1"); // insert simplified result
|
||||
simplifcationMade = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue