mirror of
https://github.com/gbdev/rgbds.git
synced 2026-05-08 10:59:36 +00:00
Refactor and rename some numeric literal lexing for asm and linkerscript consistency
This commit is contained in:
+25
-26
@@ -970,8 +970,8 @@ static std::tuple<uint32_t, uint32_t, bool> readFractionDigits() {
|
|||||||
prevWasSeparator = true;
|
prevWasSeparator = true;
|
||||||
} else if (isDigit(c)) {
|
} else if (isDigit(c)) {
|
||||||
prevWasSeparator = false;
|
prevWasSeparator = false;
|
||||||
c -= '0';
|
int digit = c - '0';
|
||||||
if (dividend > (UINT32_MAX - c) / 10 || divisor > UINT32_MAX / 10) {
|
if (dividend > (UINT32_MAX - digit) / 10 || divisor > UINT32_MAX / 10) {
|
||||||
warning(
|
warning(
|
||||||
WARNING_LARGE_CONSTANT, "Fixed-point constant has too many fractional digits"
|
WARNING_LARGE_CONSTANT, "Fixed-point constant has too many fractional digits"
|
||||||
);
|
);
|
||||||
@@ -979,7 +979,7 @@ static std::tuple<uint32_t, uint32_t, bool> readFractionDigits() {
|
|||||||
for (int d = peek(); isDigit(d) || d == '_'; c = d, d = nextChar()) {}
|
for (int d = peek(); isDigit(d) || d == '_'; c = d, d = nextChar()) {}
|
||||||
return {dividend, divisor, c == '_'};
|
return {dividend, divisor, c == '_'};
|
||||||
}
|
}
|
||||||
dividend = dividend * 10 + c;
|
dividend = dividend * 10 + digit;
|
||||||
divisor *= 10;
|
divisor *= 10;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -1000,15 +1000,15 @@ static uint8_t readPrecisionSuffix() {
|
|||||||
// '_' is not allowed after 'q'/'Q'
|
// '_' is not allowed after 'q'/'Q'
|
||||||
for (int c = peek(); isDigit(c); c = nextChar()) {
|
for (int c = peek(); isDigit(c); c = nextChar()) {
|
||||||
empty = false;
|
empty = false;
|
||||||
c -= '0';
|
int digit = c - '0';
|
||||||
if (precision > (UINT8_MAX - c) / 10) {
|
if (precision > (UINT8_MAX - digit) / 10) {
|
||||||
// Discard any additional digits
|
// Discard any additional digits
|
||||||
skipChars(isDigit);
|
skipChars(isDigit);
|
||||||
// Return an invalid precision to cause a subsequent error, which is checked afterwards
|
// Return an invalid precision to cause a subsequent error, which is checked afterwards
|
||||||
// to cover the default `options.fixPrecision` as well, just in case
|
// to cover the default `options.fixPrecision` as well, just in case
|
||||||
return UINT8_MAX;
|
return UINT8_MAX;
|
||||||
}
|
}
|
||||||
precision = precision * 10 + c;
|
precision = precision * 10 + digit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
@@ -1093,7 +1093,7 @@ void lexer_SetGfxDigits(char const digits[4]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t readBinaryNumber(char const *prefix) {
|
static uint32_t readBinaryNumber(char const *prefix) {
|
||||||
uint32_t value = 0;
|
uint32_t number = 0;
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
bool prevWasSeparator = false;
|
bool prevWasSeparator = false;
|
||||||
|
|
||||||
@@ -1115,21 +1115,21 @@ static uint32_t readBinaryNumber(char const *prefix) {
|
|||||||
empty = false;
|
empty = false;
|
||||||
prevWasSeparator = false;
|
prevWasSeparator = false;
|
||||||
|
|
||||||
if (value > (UINT32_MAX - bit) / 2) {
|
if (number > (UINT32_MAX - bit) / 2) {
|
||||||
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
||||||
// Discard any additional digits
|
// Discard any additional digits
|
||||||
skipChars([](int d) { return isCustomBinDigit(d) || d == '_'; });
|
skipChars([](int d) { return isCustomBinDigit(d) || d == '_'; });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
value = value * 2 + bit;
|
number = number * 2 + bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDigitsEnding(empty, prefix, prevWasSeparator, "integer");
|
checkDigitsEnding(empty, prefix, prevWasSeparator, "integer");
|
||||||
return value;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t readOctalNumber(char const *prefix) {
|
static uint32_t readOctalNumber(char const *prefix) {
|
||||||
uint32_t value = 0;
|
uint32_t number = 0;
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
bool prevWasSeparator = false;
|
bool prevWasSeparator = false;
|
||||||
|
|
||||||
@@ -1143,26 +1143,26 @@ static uint32_t readOctalNumber(char const *prefix) {
|
|||||||
if (!isOctDigit(c)) {
|
if (!isOctDigit(c)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c -= '0';
|
int digit = c - '0';
|
||||||
empty = false;
|
empty = false;
|
||||||
prevWasSeparator = false;
|
prevWasSeparator = false;
|
||||||
|
|
||||||
if (value > (UINT32_MAX - c) / 8) {
|
if (number > (UINT32_MAX - digit) / 8) {
|
||||||
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
||||||
// Discard any additional digits
|
// Discard any additional digits
|
||||||
skipChars([](int d) { return isOctDigit(d) || d == '_'; });
|
skipChars([](int d) { return isOctDigit(d) || d == '_'; });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
value = value * 8 + c;
|
number = number * 8 + digit;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDigitsEnding(empty, prefix, prevWasSeparator, "integer");
|
checkDigitsEnding(empty, prefix, prevWasSeparator, "integer");
|
||||||
return value;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t readDecimalNumber(int initial) {
|
static uint32_t readDecimalNumber(int initial) {
|
||||||
assume(isDigit(initial));
|
assume(isDigit(initial));
|
||||||
uint32_t value = initial - '0';
|
uint32_t number = initial - '0';
|
||||||
bool prevWasSeparator = false;
|
bool prevWasSeparator = false;
|
||||||
|
|
||||||
for (int c = peek();; c = nextChar()) {
|
for (int c = peek();; c = nextChar()) {
|
||||||
@@ -1175,24 +1175,24 @@ static uint32_t readDecimalNumber(int initial) {
|
|||||||
if (!isDigit(c)) {
|
if (!isDigit(c)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c -= '0';
|
int digit = c - '0';
|
||||||
prevWasSeparator = false;
|
prevWasSeparator = false;
|
||||||
|
|
||||||
if (value > (UINT32_MAX - c) / 10) {
|
if (number > (UINT32_MAX - digit) / 10) {
|
||||||
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
||||||
// Discard any additional digits
|
// Discard any additional digits
|
||||||
skipChars([](int d) { return isDigit(d) || d == '_'; });
|
skipChars([](int d) { return isDigit(d) || d == '_'; });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
value = value * 10 + c;
|
number = number * 10 + digit;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDigitsEnding(false, nullptr, prevWasSeparator, "integer");
|
checkDigitsEnding(false, nullptr, prevWasSeparator, "integer");
|
||||||
return value;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t readHexNumber(char const *prefix) {
|
static uint32_t readHexNumber(char const *prefix) {
|
||||||
uint32_t value = 0;
|
uint32_t number = 0;
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
bool prevWasSeparator = false;
|
bool prevWasSeparator = false;
|
||||||
|
|
||||||
@@ -1210,17 +1210,17 @@ static uint32_t readHexNumber(char const *prefix) {
|
|||||||
empty = false;
|
empty = false;
|
||||||
prevWasSeparator = false;
|
prevWasSeparator = false;
|
||||||
|
|
||||||
if (value > (UINT32_MAX - c) / 16) {
|
if (number > (UINT32_MAX - c) / 16) {
|
||||||
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
||||||
// Discard any additional digits
|
// Discard any additional digits
|
||||||
skipChars([](int d) { return isHexDigit(d) || d == '_'; });
|
skipChars([](int d) { return isHexDigit(d) || d == '_'; });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
value = value * 16 + c;
|
number = number * 16 + c;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDigitsEnding(empty, prefix, prevWasSeparator, "integer");
|
checkDigitsEnding(empty, prefix, prevWasSeparator, "integer");
|
||||||
return value;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t readGfxConstant() {
|
static uint32_t readGfxConstant() {
|
||||||
@@ -2169,9 +2169,8 @@ static Token skipToLeadingKeyword() {
|
|||||||
if (int c = skipChars(isBlankSpace); c == EOF) {
|
if (int c = skipChars(isBlankSpace); c == EOF) {
|
||||||
return Token(T_(YYEOF));
|
return Token(T_(YYEOF));
|
||||||
} else if (isLetter(c)) {
|
} else if (isLetter(c)) {
|
||||||
shiftChar();
|
|
||||||
std::string keyword(1, c);
|
std::string keyword(1, c);
|
||||||
for (c = peek(); continuesIdentifier(c); c = nextChar()) {
|
for (c = nextChar(); continuesIdentifier(c); c = nextChar()) {
|
||||||
keyword += c;
|
keyword += c;
|
||||||
}
|
}
|
||||||
if (auto search = keywords.find(keyword); search != keywords.end()) {
|
if (auto search = keywords.find(keyword); search != keywords.end()) {
|
||||||
|
|||||||
+16
-34
@@ -84,24 +84,23 @@ static yy::parser::symbol_type yywrap() {
|
|||||||
return yy::parser::make_YYEOF();
|
return yy::parser::make_YYEOF();
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string readKeyword(int c) {
|
static std::string readKeyword(int initial) {
|
||||||
LexerStackEntry &context = lexerStack.back();
|
LexerStackEntry &context = lexerStack.back();
|
||||||
std::string keyword;
|
std::string keyword;
|
||||||
keyword.push_back(c);
|
keyword.push_back(initial);
|
||||||
for (c = context.file.sgetc(); isAlphanumeric(c); c = context.file.snextc()) {
|
for (int c = context.file.sgetc(); isAlphanumeric(c); c = context.file.snextc()) {
|
||||||
keyword.push_back(c);
|
keyword.push_back(c);
|
||||||
}
|
}
|
||||||
return keyword;
|
return keyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
static yy::parser::symbol_type parseDecNumber(int c) {
|
static yy::parser::symbol_type parseDecNumber(int initial) {
|
||||||
LexerStackEntry &context = lexerStack.back();
|
LexerStackEntry &context = lexerStack.back();
|
||||||
uint32_t number = c - '0';
|
uint32_t number = initial - '0';
|
||||||
for (c = context.file.sgetc(); isDigit(c) || c == '_'; c = context.file.sgetc()) {
|
for (int c = context.file.sgetc(); isDigit(c) || c == '_'; c = context.file.snextc()) {
|
||||||
if (c != '_') {
|
if (c != '_') {
|
||||||
number = number * 10 + (c - '0');
|
number = number * 10 + (c - '0');
|
||||||
}
|
}
|
||||||
context.file.sbumpc();
|
|
||||||
}
|
}
|
||||||
return yy::parser::make_number(number);
|
return yy::parser::make_number(number);
|
||||||
}
|
}
|
||||||
@@ -115,12 +114,10 @@ static yy::parser::symbol_type parseBinNumber(char const *prefix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t number = c - '0';
|
uint32_t number = c - '0';
|
||||||
context.file.sbumpc();
|
for (c = context.file.snextc(); isBinDigit(c) || c == '_'; c = context.file.snextc()) {
|
||||||
for (c = context.file.sgetc(); isBinDigit(c) || c == '_'; c = context.file.sgetc()) {
|
|
||||||
if (c != '_') {
|
if (c != '_') {
|
||||||
number = number * 2 + (c - '0');
|
number = number * 2 + (c - '0');
|
||||||
}
|
}
|
||||||
context.file.sbumpc();
|
|
||||||
}
|
}
|
||||||
return yy::parser::make_number(number);
|
return yy::parser::make_number(number);
|
||||||
}
|
}
|
||||||
@@ -134,12 +131,10 @@ static yy::parser::symbol_type parseOctNumber(char const *prefix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t number = c - '0';
|
uint32_t number = c - '0';
|
||||||
context.file.sbumpc();
|
for (c = context.file.snextc(); isOctDigit(c) || c == '_'; c = context.file.snextc()) {
|
||||||
for (c = context.file.sgetc(); isOctDigit(c) || c == '_'; c = context.file.sgetc()) {
|
|
||||||
if (c != '_') {
|
if (c != '_') {
|
||||||
number = number * 8 + (c - '0');
|
number = number * 8 + (c - '0');
|
||||||
}
|
}
|
||||||
context.file.sbumpc();
|
|
||||||
}
|
}
|
||||||
return yy::parser::make_number(number);
|
return yy::parser::make_number(number);
|
||||||
}
|
}
|
||||||
@@ -153,41 +148,33 @@ static yy::parser::symbol_type parseHexNumber(char const *prefix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t number = parseHexDigit(c);
|
uint32_t number = parseHexDigit(c);
|
||||||
context.file.sbumpc();
|
for (c = context.file.snextc(); isHexDigit(c) || c == '_'; c = context.file.snextc()) {
|
||||||
for (c = context.file.sgetc(); isHexDigit(c) || c == '_'; c = context.file.sgetc()) {
|
|
||||||
if (c != '_') {
|
if (c != '_') {
|
||||||
number = number * 16 + parseHexDigit(c);
|
number = number * 16 + parseHexDigit(c);
|
||||||
}
|
}
|
||||||
context.file.sbumpc();
|
|
||||||
}
|
}
|
||||||
return yy::parser::make_number(number);
|
return yy::parser::make_number(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
static yy::parser::symbol_type parseAnyNumber(int c) {
|
static yy::parser::symbol_type parseAnyNumber(int initial) {
|
||||||
LexerStackEntry &context = lexerStack.back();
|
LexerStackEntry &context = lexerStack.back();
|
||||||
if (c == '0') {
|
if (initial == '0') {
|
||||||
switch (context.file.sgetc()) {
|
switch (context.file.sgetc()) {
|
||||||
case 'x':
|
case 'x':
|
||||||
context.file.sbumpc();
|
|
||||||
return parseHexNumber("\"0x\"");
|
|
||||||
case 'X':
|
case 'X':
|
||||||
context.file.sbumpc();
|
context.file.sbumpc();
|
||||||
return parseHexNumber("\"0X\"");
|
return parseHexNumber("\"0x\"");
|
||||||
case 'o':
|
case 'o':
|
||||||
context.file.sbumpc();
|
|
||||||
return parseOctNumber("\"0o\"");
|
|
||||||
case 'O':
|
case 'O':
|
||||||
context.file.sbumpc();
|
context.file.sbumpc();
|
||||||
return parseOctNumber("\"0O\"");
|
return parseOctNumber("\"0o\"");
|
||||||
case 'b':
|
case 'b':
|
||||||
context.file.sbumpc();
|
|
||||||
return parseBinNumber("\"0b\"");
|
|
||||||
case 'B':
|
case 'B':
|
||||||
context.file.sbumpc();
|
context.file.sbumpc();
|
||||||
return parseBinNumber("\"0B");
|
return parseBinNumber("\"0b\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return parseDecNumber(c);
|
return parseDecNumber(initial);
|
||||||
}
|
}
|
||||||
|
|
||||||
static yy::parser::symbol_type parseString() {
|
static yy::parser::symbol_type parseString() {
|
||||||
@@ -294,12 +281,7 @@ yy::parser::symbol_type yylex() {
|
|||||||
} else {
|
} else {
|
||||||
scriptError("Unexpected character %s", printChar(c));
|
scriptError("Unexpected character %s", printChar(c));
|
||||||
// Keep reading characters until the EOL, to avoid reporting too many errors.
|
// Keep reading characters until the EOL, to avoid reporting too many errors.
|
||||||
for (c = context.file.sgetc(); !isNewline(c); c = context.file.sgetc()) {
|
for (c = context.file.sgetc(); c != EOF && !isNewline(c); c = context.file.snextc()) {}
|
||||||
if (c == EOF) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
context.file.sbumpc();
|
|
||||||
}
|
|
||||||
return yylex();
|
return yylex();
|
||||||
}
|
}
|
||||||
// Not marking as unreachable; this will generate a warning if any codepath forgets to return.
|
// Not marking as unreachable; this will generate a warning if any codepath forgets to return.
|
||||||
|
|||||||
Reference in New Issue
Block a user