Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 30 additions & 47 deletions src/asm/lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,21 @@ static std::string readAnonLabelRef(char c) {
return sym_MakeAnonLabelName(n, c == '-');
}

static void checkDigitSeparator(bool nonDigit) {
if (nonDigit) {
error("Invalid integer constant, '_' after another '_'");
}
}

static void checkIntegerConstantSuffix(bool empty, bool nonDigit, char const *prefix) {
if (empty) {
error("Invalid integer constant, no digits after %s", prefix);
}
if (nonDigit) {
error("Invalid integer constant, trailing '_'");
}
}

static uint32_t readFractionalPart(uint32_t integer) {
uint32_t value = 0, divisor = 1;
uint8_t precision = 0;
Expand All @@ -948,9 +963,7 @@ static uint32_t readFractionalPart(uint32_t integer) {
for (int c = peek();; c = nextChar()) {
if (state == READFRACTIONALPART_DIGITS) {
if (c == '_') {
if (nonDigit) {
error("Invalid integer constant, '_' after another '_'");
}
checkDigitSeparator(nonDigit);
nonDigit = true;
continue;
}
Expand All @@ -962,15 +975,16 @@ static uint32_t readFractionalPart(uint32_t integer) {
} else if (!isDigit(c)) {
break;
}
c -= '0';
nonDigit = false;

if (divisor > (UINT32_MAX - (c - '0')) / 10) {
if (divisor > (UINT32_MAX - c) / 10) {
warning(WARNING_LARGE_CONSTANT, "Precision of fixed-point constant is too large");
// Discard any additional digits
skipChars([](int d) { return isDigit(d) || d == '_'; });
break;
}
value = value * 10 + (c - '0');
value = value * 10 + c;
divisor *= 10;
} else {
if (c == '.' && state == READFRACTIONALPART_PRECISION) {
Expand Down Expand Up @@ -1061,9 +1075,7 @@ static uint32_t readBinaryNumber(char const *prefix) {

for (int c = peek();; c = nextChar()) {
if (c == '_') {
if (nonDigit) {
error("Invalid integer constant, '_' after another '_'");
}
checkDigitSeparator(nonDigit);
nonDigit = true;
continue;
}
Expand All @@ -1088,13 +1100,7 @@ static uint32_t readBinaryNumber(char const *prefix) {
value = value * 2 + bit;
}

if (empty) {
error("Invalid integer constant, no digits after %s", prefix);
}
if (nonDigit) {
error("Invalid integer constant, trailing '_'");
}

checkIntegerConstantSuffix(empty, nonDigit, prefix);
return value;
}

Expand All @@ -1105,17 +1111,15 @@ static uint32_t readOctalNumber(char const *prefix) {

for (int c = peek();; c = nextChar()) {
if (c == '_') {
if (nonDigit) {
error("Invalid integer constant, '_' after another '_'");
}
checkDigitSeparator(nonDigit);
nonDigit = true;
continue;
}

if (!isOctDigit(c)) {
break;
}
c = c - '0';
c -= '0';
empty = false;
nonDigit = false;

Expand All @@ -1128,13 +1132,7 @@ static uint32_t readOctalNumber(char const *prefix) {
value = value * 8 + c;
}

if (empty) {
error("Invalid integer constant, no digits after %s", prefix);
}
if (nonDigit) {
error("Invalid integer constant, trailing '_'");
}

checkIntegerConstantSuffix(empty, nonDigit, prefix);
return value;
}

Expand All @@ -1145,17 +1143,15 @@ static uint32_t readDecimalNumber(int initial) {

for (int c = peek();; c = nextChar()) {
if (c == '_') {
if (nonDigit) {
error("Invalid integer constant, '_' after another '_'");
}
checkDigitSeparator(nonDigit);
nonDigit = true;
continue;
}

if (!isDigit(c)) {
break;
}
c = c - '0';
c -= '0';
nonDigit = false;

if (value > (UINT32_MAX - c) / 10) {
Expand All @@ -1167,10 +1163,7 @@ static uint32_t readDecimalNumber(int initial) {
value = value * 10 + c;
}

if (nonDigit) {
error("Invalid integer constant, trailing '_'");
}

checkIntegerConstantSuffix(false, nonDigit, nullptr);
return value;
}

Expand All @@ -1181,9 +1174,7 @@ static uint32_t readHexNumber(char const *prefix) {

for (int c = peek();; c = nextChar()) {
if (c == '_') {
if (nonDigit) {
error("Invalid integer constant, '_' after another '_'");
}
checkDigitSeparator(nonDigit);
nonDigit = true;
continue;
}
Expand All @@ -1204,13 +1195,7 @@ static uint32_t readHexNumber(char const *prefix) {
value = value * 16 + c;
}

if (empty) {
error("Invalid integer constant, no digits after %s", prefix);
}
if (nonDigit) {
error("Invalid integer constant, trailing '_'");
}

checkIntegerConstantSuffix(empty, nonDigit, prefix);
return value;
}

Expand All @@ -1221,9 +1206,7 @@ static uint32_t readGfxConstant() {

for (int c = peek();; c = nextChar()) {
if (c == '_') {
if (nonDigit) {
error("Invalid integer constant, '_' after another '_'");
}
checkDigitSeparator(nonDigit);
nonDigit = true;
continue;
}
Expand Down
Loading