Removed unnecessary conditions and avoid string copying in Tokenizer::simplifyMathFunctions()

This commit is contained in:
PKEuS 2014-10-31 13:59:06 +01:00
parent 19e0e3da1b
commit 9b0b7a77b6
1 changed files with 89 additions and 107 deletions

View File

@ -8395,16 +8395,16 @@ bool Tokenizer::simplifyMathFunctions()
tok = tok->tokAt(-2);// set token index two steps back tok = tok->tokAt(-2);// set token index two steps back
tok->deleteNext(2); // delete "std ::" tok->deleteNext(2); // delete "std ::"
} }
const std::string strNumber = tok->tokAt(2)->strValue(); // get number const std::string& strNumber = tok->tokAt(2)->strValue(); // get number
const bool isNotAnInteger = (!MathLib::isInt(strNumber));// check: is not an integer const bool isNotAnInteger = (!MathLib::isInt(strNumber));// check: is not an integer
if (!strNumber.empty() && isNotAnInteger) { if (strNumber.empty() || isNotAnInteger) {
// Ignore strings which we can't convert // Ignore strings which we can't convert
continue; continue;
} }
// remove atol ( %num%
tok->deleteNext(3);
// Convert string into a number and insert into token list // Convert string into a number and insert into token list
tok->str(MathLib::toString(MathLib::toLongNumber(strNumber))); tok->str(MathLib::toString(MathLib::toLongNumber(strNumber)));
// remove ( %num% )
tok->deleteNext(3);
simplifcationMade = true; simplifcationMade = true;
} else if (Token::Match(tok, "abs|fabs|labs|llabs ( %num% )")) { } else if (Token::Match(tok, "abs|fabs|labs|llabs ( %num% )")) {
if (tok->previous() && if (tok->previous() &&
@ -8415,7 +8415,7 @@ bool Tokenizer::simplifyMathFunctions()
// get number string // get number string
std::string strNumber(tok->strAt(2)); std::string strNumber(tok->strAt(2));
// is the string negative? // is the string negative?
if (!strNumber.empty() && strNumber[0] == '-') { if (strNumber[0] == '-') {
strNumber = strNumber.substr(1); // remove '-' sign strNumber = strNumber.substr(1); // remove '-' sign
} }
tok->deleteNext(3); // delete e.g. abs ( 1 ) tok->deleteNext(3); // delete e.g. abs ( 1 )
@ -8424,19 +8424,17 @@ bool Tokenizer::simplifyMathFunctions()
} else if (Token::Match(tok, "fma|fmaf|fmal ( %any% , %any% , %any% )")) { } else if (Token::Match(tok, "fma|fmaf|fmal ( %any% , %any% , %any% )")) {
// Simplify: fma(a,b,c) == > ( a ) * ( b ) + ( c ) // Simplify: fma(a,b,c) == > ( a ) * ( b ) + ( c )
// get parameters // get parameters
const std::string a(tok->strAt(2)); const std::string& a(tok->strAt(2));
const std::string b(tok->strAt(4)); const std::string& b(tok->strAt(4));
const std::string c(tok->strAt(6)); const std::string& c(tok->strAt(6));
if (!a.empty() && !b.empty() && !c.empty()) {
tok->deleteNext(7); // delete fma call
tok->str("( " + a + " ) * ( " + b + " ) + ( " + c + " )"); // insert result into token list tok->str("( " + a + " ) * ( " + b + " ) + ( " + c + " )"); // insert result into token list
tok->deleteNext(7); // delete fma call
simplifcationMade = true; simplifcationMade = true;
}
} else if (Token::Match(tok, "sqrt|sqrtf|sqrtl|cbrt|cbrtf|cbrtl ( %num% )")) { } else if (Token::Match(tok, "sqrt|sqrtf|sqrtl|cbrt|cbrtf|cbrtl ( %num% )")) {
// Simplify: sqrt(0) = 0 and cbrt(0) == 0 // Simplify: sqrt(0) = 0 and cbrt(0) == 0
// sqrt(1) = 1 and cbrt(1) == 1 // sqrt(1) = 1 and cbrt(1) == 1
// get number string // get number string
const std::string parameter(tok->strAt(2)); const std::string& parameter(tok->strAt(2));
// is parameter 0 ? // is parameter 0 ?
if (isZeroNumber(parameter)) { if (isZeroNumber(parameter)) {
tok->deleteNext(3); // delete tokens tok->deleteNext(3); // delete tokens
@ -8452,7 +8450,7 @@ bool Tokenizer::simplifyMathFunctions()
// cosh[f|l](0) = 1 and cos[f|l](0) = 1 // cosh[f|l](0) = 1 and cos[f|l](0) = 1
// erfc[f|l](0) = 1 // erfc[f|l](0) = 1
// get number string // get number string
const std::string parameter(tok->strAt(2)); const std::string& parameter(tok->strAt(2));
// is parameter 0 ? // is parameter 0 ?
if (isZeroNumber(parameter)) { if (isZeroNumber(parameter)) {
tok->deleteNext(3); // delete tokens tok->deleteNext(3); // delete tokens
@ -8467,7 +8465,7 @@ bool Tokenizer::simplifyMathFunctions()
// atan[f|l](0) = 0 and atanh[f|l](0)= 0 // atan[f|l](0) = 0 and atanh[f|l](0)= 0
// expm1[f|l](0) = 0 // expm1[f|l](0) = 0
// get number string // get number string
const std::string parameter(tok->strAt(2)); const std::string& parameter(tok->strAt(2));
// is parameter 0 ? // is parameter 0 ?
if (isZeroNumber(parameter)) { if (isZeroNumber(parameter)) {
tok->deleteNext(3); // delete tokens tok->deleteNext(3); // delete tokens
@ -8480,7 +8478,7 @@ bool Tokenizer::simplifyMathFunctions()
// acosh[f|l](1) = 0 , acos[f|l](1) = 0 // acosh[f|l](1) = 0 , acos[f|l](1) = 0
// ilogb[f|l](1) = 0 // ilogb[f|l](1) = 0
// get number string // get number string
const std::string parameter(tok->strAt(2)); const std::string& parameter(tok->strAt(2));
// is parameter 1 ? // is parameter 1 ?
if (isOneNumber(parameter)) { if (isOneNumber(parameter)) {
tok->deleteNext(3); // delete tokens tok->deleteNext(3); // delete tokens
@ -8491,116 +8489,103 @@ bool Tokenizer::simplifyMathFunctions()
// @todo if one of the parameters is NaN the other is returned // @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 (NaN, -1.0) = %f\n", fmin(NaN,-1.0));
// e.g. printf ("fmin (-1.0, NaN) = %f\n", fmin(-1.0,NaN)); // e.g. printf ("fmin (-1.0, NaN) = %f\n", fmin(-1.0,NaN));
const std::string strLeftNumber(tok->strAt(2)); const std::string& strLeftNumber(tok->strAt(2));
const std::string strRightNumber(tok->strAt(4)); const std::string& strRightNumber(tok->strAt(4));
const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber); const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber);
// case: left <= right ==> insert left // case: left <= right ==> insert left
if (!strLeftNumber.empty() && !strRightNumber.empty() && isLessEqual) { if (isLessEqual) {
tok->deleteNext(5); // delete e.g. fmin ( -1.0, 1.0 )
tok->str(strLeftNumber); // insert e.g. -1.0 tok->str(strLeftNumber); // insert e.g. -1.0
tok->deleteNext(5); // delete e.g. fmin ( -1.0, 1.0 )
simplifcationMade = true; simplifcationMade = true;
} else { // case left > right ==> insert right } 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 tok->str(strRightNumber); // insert e.g. 0.0
tok->deleteNext(5); // delete e.g. fmin ( 1.0, 0.0 )
simplifcationMade = true; simplifcationMade = true;
} }
} else if (Token::Match(tok, "fmax|fmaxl|fmaxf ( %num% , %num% )")) { } else if (Token::Match(tok, "fmax|fmaxl|fmaxf ( %num% , %num% )")) {
// @todo if one of the parameters is NaN the other is returned // @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 (NaN, -1.0) = %f\n", fmax(NaN,-1.0));
// e.g. printf ("fmax (-1.0, NaN) = %f\n", fmax(-1.0,NaN)); // e.g. printf ("fmax (-1.0, NaN) = %f\n", fmax(-1.0,NaN));
const std::string strLeftNumber(tok->strAt(2)); const std::string& strLeftNumber(tok->strAt(2));
const std::string strRightNumber(tok->strAt(4)); const std::string& strRightNumber(tok->strAt(4));
const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber); const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber);
// case: left <= right ==> insert right // case: left <= right ==> insert right
if (!strLeftNumber.empty() && !strRightNumber.empty() && isLessEqual) { if (isLessEqual) {
tok->deleteNext(5); // delete e.g. fmax ( -1.0, 1.0 )
tok->str(strRightNumber);// insert e.g. 1.0 tok->str(strRightNumber);// insert e.g. 1.0
tok->deleteNext(5); // delete e.g. fmax ( -1.0, 1.0 )
simplifcationMade = true; simplifcationMade = true;
} else { // case left > right ==> insert left } 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 tok->str(strLeftNumber); // insert e.g. 1.0
tok->deleteNext(5); // delete e.g. fmax ( 1.0, 0.0 )
simplifcationMade = true; simplifcationMade = true;
} }
} else if (Token::Match(tok, "isgreater ( %num% , %num% )")) { } else if (Token::Match(tok, "isgreater ( %num% , %num% )")) {
// The isgreater(x,y) function is the same as calculating (x)>(y). // 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. // It returns true (1) if x is greater than y and false (0) otherwise.
const std::string strLeftNumber(tok->strAt(2)); // get left number const std::string& strLeftNumber(tok->strAt(2)); // get left number
const std::string strRightNumber(tok->strAt(4)); // get right number const std::string& strRightNumber(tok->strAt(4)); // get right number
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
const bool isGreater = MathLib::isGreater(strLeftNumber, strRightNumber); // compare numbers const bool isGreater = MathLib::isGreater(strLeftNumber, strRightNumber); // compare numbers
tok->deleteNext(5); // delete tokens tok->deleteNext(5); // delete tokens
tok->str((isGreater == true) ? "true": "false"); // insert results tok->str((isGreater == true) ? "true": "false"); // insert results
simplifcationMade = true; simplifcationMade = true;
}
} else if (Token::Match(tok, "isgreaterequal ( %num% , %num% )")) { } else if (Token::Match(tok, "isgreaterequal ( %num% , %num% )")) {
// The isgreaterequal(x,y) function is the same as calculating (x)>=(y). // 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. // It returns true (1) if x is greater than or equal to y.
// False (0) is returned otherwise. // False (0) is returned otherwise.
const std::string strLeftNumber(tok->strAt(2)); // get left number const std::string& strLeftNumber(tok->strAt(2)); // get left number
const std::string strRightNumber(tok->strAt(4)); // get right number const std::string& strRightNumber(tok->strAt(4)); // get right number
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
const bool isGreaterEqual = MathLib::isGreaterEqual(strLeftNumber, strRightNumber); // compare numbers const bool isGreaterEqual = MathLib::isGreaterEqual(strLeftNumber, strRightNumber); // compare numbers
tok->deleteNext(5); // delete tokens tok->deleteNext(5); // delete tokens
tok->str((isGreaterEqual == true) ? "true": "false"); // insert results tok->str((isGreaterEqual == true) ? "true": "false"); // insert results
simplifcationMade = true; simplifcationMade = true;
}
} else if (Token::Match(tok, "isless ( %num% , %num% )")) { } else if (Token::Match(tok, "isless ( %num% , %num% )")) {
// Calling this function is the same as calculating (x)<(y). // Calling this function is the same as calculating (x)<(y).
// It returns true (1) if x is less than y. // It returns true (1) if x is less than y.
// False (0) is returned otherwise. // False (0) is returned otherwise.
const std::string strLeftNumber(tok->strAt(2)); // get left number const std::string& strLeftNumber(tok->strAt(2)); // get left number
const std::string strRightNumber(tok->strAt(4)); // get right number const std::string& strRightNumber(tok->strAt(4)); // get right number
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
const bool isLess = MathLib::isLess(strLeftNumber, strRightNumber); // compare numbers const bool isLess = MathLib::isLess(strLeftNumber, strRightNumber); // compare numbers
tok->deleteNext(5); // delete tokens tok->deleteNext(5); // delete tokens
tok->str((isLess == true) ? "true": "false"); // insert results tok->str((isLess == true) ? "true": "false"); // insert results
simplifcationMade = true; simplifcationMade = true;
}
} else if (Token::Match(tok, "islessequal ( %num% , %num% )")) { } else if (Token::Match(tok, "islessequal ( %num% , %num% )")) {
// Calling this function is the same as calculating (x)<=(y). // Calling this function is the same as calculating (x)<=(y).
// It returns true (1) if x is less or equal to y. // It returns true (1) if x is less or equal to y.
// False (0) is returned otherwise. // False (0) is returned otherwise.
const std::string strLeftNumber(tok->strAt(2)); // get left number const std::string& strLeftNumber(tok->strAt(2)); // get left number
const std::string strRightNumber(tok->strAt(4)); // get right number const std::string& strRightNumber(tok->strAt(4)); // get right number
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber); // compare numbers const bool isLessEqual = MathLib::isLessEqual(strLeftNumber, strRightNumber); // compare numbers
tok->deleteNext(5); // delete tokens tok->deleteNext(5); // delete tokens
tok->str((isLessEqual == true) ? "true": "false"); // insert results tok->str((isLessEqual == true) ? "true": "false"); // insert results
simplifcationMade = true; simplifcationMade = true;
}
} else if (Token::Match(tok, "islessgreater ( %num% , %num% )")) { } else if (Token::Match(tok, "islessgreater ( %num% , %num% )")) {
// Calling this function is the same as calculating (x)<(y) || (x)>(y). // 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. // It returns true (1) if x is less than y or x is greater than y.
// False (0) is returned otherwise. // False (0) is returned otherwise.
const std::string strLeftNumber(tok->strAt(2)); // get left number const std::string& strLeftNumber(tok->strAt(2)); // get left number
const std::string strRightNumber(tok->strAt(4)); // get right number const std::string& strRightNumber(tok->strAt(4)); // get right number
if (!strRightNumber.empty() && !strLeftNumber.empty()) {
const bool isLessOrGreater(MathLib::isLess(strLeftNumber, strRightNumber) || const bool isLessOrGreater(MathLib::isLess(strLeftNumber, strRightNumber) ||
MathLib::isGreater(strLeftNumber, strRightNumber)); // compare numbers MathLib::isGreater(strLeftNumber, strRightNumber)); // compare numbers
tok->deleteNext(5); // delete tokens tok->deleteNext(5); // delete tokens
tok->str((isLessOrGreater == true) ? "true": "false"); // insert results tok->str((isLessOrGreater == true) ? "true": "false"); // insert results
simplifcationMade = true; simplifcationMade = true;
}
} else if (Token::Match(tok, "div|ldiv|lldiv ( %any% , %num% )")) { } 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 // 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). // (the identity element), the call can be simplified to (x).
const std::string leftParameter(tok->strAt(2)); // get the left parameter const std::string& leftParameter(tok->strAt(2)); // get the left parameter
const std::string rightNumber(tok->strAt(4)); // get right number const std::string& rightNumber(tok->strAt(4)); // get right number
if (!rightNumber.empty() && !leftParameter.empty()) {
if (isOneNumber(rightNumber)) { if (isOneNumber(rightNumber)) {
tok->deleteNext(5); // delete tokens
tok->str(leftParameter); // insert simplified result tok->str(leftParameter); // insert simplified result
tok->deleteNext(5); // delete tokens
simplifcationMade = true; simplifcationMade = true;
} }
}
} else if (Token::Match(tok, "pow|powf|powl (")) { } else if (Token::Match(tok, "pow|powf|powl (")) {
if (tok && Token::Match(tok->tokAt(2), "%num% , %num% )")) { 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 , anyNumber > 0): It can be simplified to 0
// In case of pow ( 0 , 0 ): It simplified to 1 // In case of pow ( 0 , 0 ): It simplified to 1
// In case of pow ( 1 , anyNumber ): It simplified to 1 // In case of pow ( 1 , anyNumber ): It simplified to 1
const std::string leftNumber(tok->strAt(2)); // get the left parameter const std::string& leftNumber(tok->strAt(2)); // get the left parameter
const std::string rightNumber(tok->strAt(4)); // get the right parameter const std::string& rightNumber(tok->strAt(4)); // get the right parameter
if (!leftNumber.empty() && !rightNumber.empty()) {
const bool isLeftNumberZero = isZeroNumber(leftNumber); const bool isLeftNumberZero = isZeroNumber(leftNumber);
const bool isLeftNumberOne = isOneNumber(leftNumber); const bool isLeftNumberOne = isOneNumber(leftNumber);
const bool isRightNumberZero = isZeroNumber(rightNumber); const bool isRightNumberZero = isZeroNumber(rightNumber);
@ -8618,15 +8603,13 @@ bool Tokenizer::simplifyMathFunctions()
simplifcationMade = true; simplifcationMade = true;
} }
} }
}
if (tok && Token::Match(tok->tokAt(2), "%any% , %num% )")) { if (tok && Token::Match(tok->tokAt(2), "%any% , %num% )")) {
// In case of pow( x , 1 ): It can be simplified to x. // In case of pow( x , 1 ): It can be simplified to x.
const std::string leftParameter(tok->strAt(2)); // get the left parameter const std::string& leftParameter(tok->strAt(2)); // get the left parameter
const std::string rightNumber(tok->strAt(4)); // get right number const std::string& rightNumber(tok->strAt(4)); // get right number
if (!rightNumber.empty() && !leftParameter.empty()) {
if (isOneNumber(rightNumber)) { // case: x^(1) = x if (isOneNumber(rightNumber)) { // case: x^(1) = x
tok->deleteNext(5); // delete tokens
tok->str(leftParameter); // insert simplified result tok->str(leftParameter); // insert simplified result
tok->deleteNext(5); // delete tokens
simplifcationMade = true; simplifcationMade = true;
} else if (isZeroNumber(rightNumber)) { // case: x^(0) = 1 } else if (isZeroNumber(rightNumber)) { // case: x^(0) = 1
tok->deleteNext(5); // delete tokens tok->deleteNext(5); // delete tokens
@ -8637,7 +8620,6 @@ bool Tokenizer::simplifyMathFunctions()
} }
} }
} }
}
// returns true if a simplifcation was performed and false otherwise. // returns true if a simplifcation was performed and false otherwise.
return simplifcationMade; return simplifcationMade;
} }