Tokenizer:simplifyMathFunction: added support for [ll]div() functions and corresponding unittests. The simplifcation is only performed, if a division by 1 is detected.

This commit is contained in:
Martin Ettl 2013-09-26 07:01:08 +02:00
parent cf0c666d79
commit 805d082cd1
2 changed files with 54 additions and 21 deletions

View File

@ -8323,7 +8323,7 @@ void Tokenizer::simplifyMathFunctions()
tok->str(strLeftNumber); // insert e.g. 1.0
}
} else if (Token::Match(tok, "isgreater ( %num% , %num% )")) {
// The isgreater(x,y) function is the same as writing (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.
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
const std::string strRightNumber(tok->tokAt(4)->str()); // get right number
@ -8333,7 +8333,7 @@ void Tokenizer::simplifyMathFunctions()
tok->str((isGreater == true) ? "true": "false"); // insert results
}
} else if (Token::Match(tok, "isgreaterequal ( %num% , %num% )")) {
// The isgreaterequal(x,y) function is the same as writing (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.
// False (0) is returned otherwise.
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
@ -8344,7 +8344,7 @@ void Tokenizer::simplifyMathFunctions()
tok->str((isGreaterEqual == true) ? "true": "false"); // insert results
}
} else if (Token::Match(tok, "isless ( %num% , %num% )")) {
// The is (x,y) function is the same as writing (x)<(y).
// 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
@ -8355,7 +8355,7 @@ void Tokenizer::simplifyMathFunctions()
tok->str((isLess == true) ? "true": "false"); // insert results
}
} else if (Token::Match(tok, "islessequal ( %num% , %num% )")) {
// The is (x,y) function is the same as writing (x)<=(y).
// 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
@ -8366,7 +8366,7 @@ void Tokenizer::simplifyMathFunctions()
tok->str((isLessEqual == true) ? "true": "false"); // insert results
}
} else if (Token::Match(tok, "islessgreater ( %num% , %num% )")) {
// The is (x,y) function is the same as writing (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.
// False (0) is returned otherwise.
const std::string strLeftNumber(tok->tokAt(2)->str()); // get left number
@ -8377,22 +8377,21 @@ void Tokenizer::simplifyMathFunctions()
tok->deleteNext(5); // delete tokens
tok->str((isLessOrGreater == true) ? "true": "false"); // insert results
}
}
else if (Token::Match(tok, "pow|powf|powl ( %any% , %num% )")) {
// pow( anyNumber,1 ) --> can be simplified to anynumber
const std::string base = (tok->tokAt(2)->str()); // get the base
const std::string exponent(tok->tokAt(4)->str()); // get exponent number
if (!exponent.empty()) {
const bool isNegative = MathLib::isNegative(exponent);
const bool isInteger = MathLib::isInt(exponent);
const bool isFloat = MathLib::isFloat(exponent);
if (!isNegative && isInteger && (MathLib::toLongNumber(exponent) == 1L)) {
} else if (Token::Match(tok, "div|ldiv|lldiv|pow|powf|powl ( %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).
// In case of pow( anyNumber,1 ): It can be simplified to anynumber.
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()) {
const bool isNegative = MathLib::isNegative(rightNumber);
const bool isInteger = MathLib::isInt(rightNumber);
const bool isFloat = MathLib::isFloat(rightNumber);
const bool allowToSimplify = ((!isNegative && isInteger && (MathLib::toLongNumber(rightNumber) == 1L)) // case: integer numbers
|| (!isNegative && isFloat && (MathLib::toDoubleNumber(rightNumber)-1.0) <= 0.)); // case: float numbers
if (allowToSimplify == true) {
tok->deleteNext(5); // delete tokens
tok->str(base); // insert results
} else if (!isNegative && isFloat && (MathLib::toDoubleNumber(exponent)-1.0) <= 0.) {
tok->deleteNext(5); // delete tokens
tok->str(base); // insert results
tok->str(leftParameter); // insert simplified result
}
}
}

View File

@ -8280,7 +8280,41 @@ private:
void simplifyMathFunctions() { //#5031
// verify pow(),pow(),powl() simplifcation
// verify div(), ldiv(), lldiv() - simplifcation
const char code_div[] ="void f(int x) {\n"
" std::cout << div(x,1);\n" //simplify
" std::cout << div(x,-1);\n" // do not simplify
" std::cout << ldiv(10L,1L);\n" // simplify
" std::cout << ldiv(10L,132L);\n" // do not simplify
" std::cout << lldiv(10LL,1LL);\n" // simplify
" std::cout << lldiv(10LL,132LL);\n" // do not simplify
"}";
const char expected_div[] = "void f ( int x ) {\n"
"std :: cout << x ;\n"
"std :: cout << div ( x , -1 ) ;\n"
"std :: cout << 10L ;\n"
"std :: cout << ldiv ( 10L , 132L ) ;\n"
"std :: cout << 10LL ;\n"
"std :: cout << lldiv ( 10LL , 132LL ) ;\n"
"}";
ASSERT_EQUALS(expected_div, tokenizeAndStringify(code_div));
// Do not simplify class members.
// case: div
const char code_div1[] = "int f(const Fred &fred) {return fred.div(12,3);}";
const char expected_div1[] = "int f ( const Fred & fred ) { return fred . div ( 12 , 3 ) ; }";
ASSERT_EQUALS(expected_div1, tokenizeAndStringify(code_div1));
// case: ldiv
const char code_div2[] = "int f(const Fred &fred) {return fred.ldiv(12,3);}";
const char expected_div2[] = "int f ( const Fred & fred ) { return fred . ldiv ( 12 , 3 ) ; }";
ASSERT_EQUALS(expected_div2, tokenizeAndStringify(code_div2));
// case: lldiv
const char code_div3[] = "int f(const Fred &fred) {return fred.lldiv(12,3);}";
const char expected_div3[] = "int f ( const Fred & fred ) { return fred . lldiv ( 12 , 3 ) ; }";
ASSERT_EQUALS(expected_div3, tokenizeAndStringify(code_div3));
// verify pow(),pow(),powl() - simplifcation
const char code_pow[] ="void f() {\n"
" std::cout << pow(-1.0,1);\n"
" std::cout << pow(1.0,1);\n"