MathLib, ValueType: Support integer suffix "i64"

This commit is contained in:
PKEuS 2016-07-26 13:19:28 +02:00
parent 7ff9545b10
commit fc1603eb9b
4 changed files with 63 additions and 28 deletions

View File

@ -49,7 +49,7 @@ MathLib::value::value(const std::string &s) :
} }
if (!MathLib::isInt(s)) if (!MathLib::isInt(s))
throw InternalError(0, "Invalid value"); throw InternalError(0, "Invalid value: " + s);
type = MathLib::value::INT; type = MathLib::value::INT;
intValue = MathLib::toLongNumber(s); intValue = MathLib::toLongNumber(s);
@ -68,7 +68,8 @@ MathLib::value::value(const std::string &s) :
type = MathLib::value::LONG; type = MathLib::value::LONG;
else if (type == MathLib::value::LONG) else if (type == MathLib::value::LONG)
type = MathLib::value::LONGLONG; type = MathLib::value::LONGLONG;
} } else if (i > 2U && c == '4' && s[i-1] == '6' && s[i-2] == 'i')
type = MathLib::value::LONGLONG;
} }
} }
} }
@ -829,7 +830,7 @@ bool MathLib::isFloatHex(const std::string& s)
bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string::const_iterator end) bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string::const_iterator end)
{ {
enum {START, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU, SUFFIX_I, SUFFIX_I6, SUFFIX_I64} state = START; enum {START, SUFFIX_U, SUFFIX_UL, SUFFIX_ULL, SUFFIX_L, SUFFIX_LU, SUFFIX_LL, SUFFIX_LLU, SUFFIX_I, SUFFIX_I6, SUFFIX_I64, SUFFIX_UI, SUFFIX_UI6, SUFFIX_UI64} state = START;
for (; it != end; ++it) { for (; it != end; ++it) {
switch (state) { switch (state) {
case START: case START:
@ -845,6 +846,8 @@ bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string::
case SUFFIX_U: case SUFFIX_U:
if (*it == 'l' || *it == 'L') if (*it == 'l' || *it == 'L')
state = SUFFIX_UL; // UL state = SUFFIX_UL; // UL
else if (*it == 'i')
state = SUFFIX_UI;
else else
return false; return false;
break; break;
@ -882,6 +885,18 @@ bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string::
else else
return false; return false;
break; break;
case SUFFIX_UI:
if (*it == '6')
state = SUFFIX_UI6;
else
return false;
break;
case SUFFIX_UI6:
if (*it == '4')
state = SUFFIX_UI64;
else
return false;
break;
default: default:
return false; return false;
} }
@ -893,7 +908,8 @@ bool MathLib::isValidIntegerSuffix(std::string::const_iterator it, std::string::
(state == SUFFIX_LL) || (state == SUFFIX_LL) ||
(state == SUFFIX_ULL) || (state == SUFFIX_ULL) ||
(state == SUFFIX_LLU) || (state == SUFFIX_LLU) ||
(state == SUFFIX_I64)); (state == SUFFIX_I64) ||
(state == SUFFIX_UI64));
} }
/*! \brief Does the string represent a binary number? /*! \brief Does the string represent a binary number?
@ -986,33 +1002,41 @@ bool MathLib::isInt(const std::string & s)
return isDec(s) || isIntHex(s) || isOct(s) || isBin(s); return isDec(s) || isIntHex(s) || isOct(s) || isBin(s);
} }
static std::string getsuffix(const std::string& value)
{
if (value.size() > 3 && value[value.size() - 3] == 'i' && value[value.size() - 2] == '6' && value[value.size() - 1] == '4') {
if (value[value.size() - 4] == 'u')
return "ULL";
return "LL";
}
bool isUnsigned = false;
unsigned int longState = 0;
for (std::size_t i = 1U; i < value.size(); ++i) {
char c = value[value.size() - i];
if (c == 'u' || c == 'U')
isUnsigned = true;
else if (c == 'L' || c == 'l')
longState++;
else break;
}
if (longState == 0)
return isUnsigned ? "U" : "";
if (longState == 1)
return isUnsigned ? "UL" : "L";
if (longState == 2)
return isUnsigned ? "ULL" : "LL";
else return "";
}
static std::string intsuffix(const std::string & first, const std::string & second) static std::string intsuffix(const std::string & first, const std::string & second)
{ {
std::string suffix1, suffix2; std::string suffix1 = getsuffix(first);
for (std::size_t i = 1U; i < first.size(); ++i) { std::string suffix2 = getsuffix(second);
char c = first[first.size() - i]; if (suffix1 == "ULL" || suffix2 == "ULL")
if (c == 'l' || c == 'u')
c = c - 'a' + 'A';
if (c != 'L' && c != 'U')
break;
suffix1 = c + suffix1;
}
for (std::size_t i = 1U; i < second.size(); ++i) {
char c = second[second.size() - i];
if (c == 'l' || c == 'u')
c = c - 'a' + 'A';
if (c != 'L' && c != 'U')
break;
suffix2 = c + suffix2;
}
if (suffix1 == "ULL" || suffix2 == "ULL"
|| suffix1 == "LLU" || suffix2 == "LLU")
return "ULL"; return "ULL";
if (suffix1 == "LL" || suffix2 == "LL") if (suffix1 == "LL" || suffix2 == "LL")
return "LL"; return "LL";
if (suffix1 == "UL" || suffix2 == "UL" if (suffix1 == "UL" || suffix2 == "UL")
|| suffix1 == "LU" || suffix2 == "LU")
return "UL"; return "UL";
if (suffix1 == "L" || suffix2 == "L") if (suffix1 == "L" || suffix2 == "L")
return "L"; return "L";

View File

@ -4412,12 +4412,16 @@ void SymbolDatabase::setValueTypeInTokenList(Token *tokens, bool cpp, char defau
ValueType::Type type = ValueType::Type::INT; ValueType::Type type = ValueType::Type::INT;
if (MathLib::isIntHex(tok->str())) if (MathLib::isIntHex(tok->str()))
sign = ValueType::Sign::UNSIGNED; sign = ValueType::Sign::UNSIGNED;
for (std::size_t pos = tok->str().size() - 1U; pos > 0U && std::isalpha(tok->str()[pos]); --pos) { for (std::size_t pos = tok->str().size() - 1U; pos > 0U; --pos) {
const char suffix = tok->str()[pos]; const char suffix = tok->str()[pos];
if (suffix == 'u' || suffix == 'U') if (suffix == 'u' || suffix == 'U')
sign = ValueType::Sign::UNSIGNED; sign = ValueType::Sign::UNSIGNED;
if (suffix == 'l' || suffix == 'L') else if (suffix == 'l' || suffix == 'L')
type = (type == ValueType::Type::INT) ? ValueType::Type::LONG : ValueType::Type::LONGLONG; type = (type == ValueType::Type::INT) ? ValueType::Type::LONG : ValueType::Type::LONGLONG;
else if (pos > 2U && suffix == '4' && tok->str()[pos - 1] == '6' && tok->str()[pos - 2] == 'i') {
type = ValueType::Type::LONGLONG;
pos -= 2;
} else break;
} }
::setValueType(tok, ValueType(sign, type, 0U), cpp, defsign, lib); ::setValueType(tok, ValueType(sign, type, 0U), cpp, defsign, lib);
} }

View File

@ -177,7 +177,9 @@ private:
ASSERT_EQUALS("2L", MathLib::add("1L", "1")); ASSERT_EQUALS("2L", MathLib::add("1L", "1"));
ASSERT_EQUALS("2UL", MathLib::add("1UL", "1")); ASSERT_EQUALS("2UL", MathLib::add("1UL", "1"));
ASSERT_EQUALS("2LL", MathLib::add("1LL", "1")); ASSERT_EQUALS("2LL", MathLib::add("1LL", "1"));
ASSERT_EQUALS("2LL", MathLib::add("1i64", "1"));
ASSERT_EQUALS("2ULL", MathLib::add("1ULL", "1")); ASSERT_EQUALS("2ULL", MathLib::add("1ULL", "1"));
ASSERT_EQUALS("2ULL", MathLib::add("1ui64","1"));
ASSERT_EQUALS("2U", MathLib::add("1", "1U")); ASSERT_EQUALS("2U", MathLib::add("1", "1U"));
ASSERT_EQUALS("2U", MathLib::add("1U", "1U")); ASSERT_EQUALS("2U", MathLib::add("1U", "1U"));
@ -738,6 +740,9 @@ private:
value = "i64"; value = "i64";
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end())); ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
value = "ui64";
ASSERT_EQUALS(true, MathLib::isValidIntegerSuffix(value.begin(), value.end()));
} }
void ispositive() const { void ispositive() const {

View File

@ -3534,6 +3534,8 @@ private:
ASSERT_EQUALS("unsigned long", typeOf("1UL", "1UL")); ASSERT_EQUALS("unsigned long", typeOf("1UL", "1UL"));
ASSERT_EQUALS("signed long long", typeOf("1LL", "1LL")); ASSERT_EQUALS("signed long long", typeOf("1LL", "1LL"));
ASSERT_EQUALS("unsigned long long", typeOf("1ULL", "1ULL")); ASSERT_EQUALS("unsigned long long", typeOf("1ULL", "1ULL"));
ASSERT_EQUALS("signed long long", typeOf("1i64", "1i64"));
ASSERT_EQUALS("unsigned long long", typeOf("1ui64", "1ui64"));
ASSERT_EQUALS("unsigned int", typeOf("1u", "1u")); ASSERT_EQUALS("unsigned int", typeOf("1u", "1u"));
ASSERT_EQUALS("signed long", typeOf("1l", "1l")); ASSERT_EQUALS("signed long", typeOf("1l", "1l"));
ASSERT_EQUALS("unsigned long", typeOf("1ul", "1ul")); ASSERT_EQUALS("unsigned long", typeOf("1ul", "1ul"));