mirror of
https://github.com/gbdev/rgbds.git
synced 2026-06-10 02:32:34 +00:00
Handle more numeric literal syntax errors in linker scripts
This commit is contained in:
+37
-30
@@ -97,27 +97,39 @@ static std::string readKeyword(int initial) {
|
||||
|
||||
template<uint32_t Base>
|
||||
requires ValidBaseV<Base>
|
||||
static yy::parser::symbol_type readNumber(int initial, char const *prefix, char const *name) {
|
||||
static yy::parser::symbol_type readNumber(int initial, char const *prefix) {
|
||||
LexerStackEntry &context = lexerStack.back();
|
||||
|
||||
uint32_t number;
|
||||
bool empty;
|
||||
if constexpr (Base == 10) {
|
||||
assume(prefix == nullptr && name == nullptr);
|
||||
assume(prefix == nullptr);
|
||||
number = parseDigit<Base>(initial);
|
||||
empty = false;
|
||||
} else {
|
||||
assume(initial == 0 && prefix != nullptr && name != nullptr);
|
||||
int c = context.file.sgetc();
|
||||
if (!isDigit<Base>(c)) {
|
||||
scriptError("No %s digits found after %s", name, prefix);
|
||||
return yy::parser::make_number(0);
|
||||
}
|
||||
number = parseDigit<Base>(c);
|
||||
context.file.sbumpc();
|
||||
assume(initial == 0 && prefix != nullptr);
|
||||
number = 0;
|
||||
empty = true;
|
||||
}
|
||||
for (int c = context.file.sgetc(); isDigit<Base>(c) || c == '_'; c = context.file.snextc()) {
|
||||
|
||||
bool prevWasSeparator = false;
|
||||
|
||||
for (int c = context.file.sgetc();; c = context.file.snextc()) {
|
||||
if (c == '_') {
|
||||
if (prevWasSeparator) {
|
||||
scriptError("Invalid integer constant, '_' after another '_'");
|
||||
}
|
||||
prevWasSeparator = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isDigit<Base>(c)) {
|
||||
break;
|
||||
}
|
||||
uint32_t digit = parseDigit<Base>(c);
|
||||
empty = false;
|
||||
prevWasSeparator = false;
|
||||
|
||||
if (number > (UINT32_MAX - digit) / Base) {
|
||||
scriptWarning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
||||
// Discard any additional digits
|
||||
@@ -127,21 +139,16 @@ static yy::parser::symbol_type readNumber(int initial, char const *prefix, char
|
||||
}
|
||||
number = number * Base + digit;
|
||||
}
|
||||
|
||||
if (empty) {
|
||||
scriptError("Invalid integer constant, no digits after %s", prefix);
|
||||
}
|
||||
if (prevWasSeparator) {
|
||||
scriptError("Invalid integer constant, trailing '_'");
|
||||
}
|
||||
return yy::parser::make_number(number);
|
||||
}
|
||||
|
||||
static yy::parser::symbol_type parseBinNumber(char const *prefix) {
|
||||
return readNumber<2>(0, prefix, "binary");
|
||||
}
|
||||
|
||||
static yy::parser::symbol_type parseOctNumber(char const *prefix) {
|
||||
return readNumber<8>(0, prefix, "octal");
|
||||
}
|
||||
|
||||
static yy::parser::symbol_type parseHexNumber(char const *prefix) {
|
||||
return readNumber<16>(0, prefix, "hexadecimal");
|
||||
}
|
||||
|
||||
static yy::parser::symbol_type parseAnyNumber(int initial) {
|
||||
LexerStackEntry &context = lexerStack.back();
|
||||
if (initial == '0') {
|
||||
@@ -149,18 +156,18 @@ static yy::parser::symbol_type parseAnyNumber(int initial) {
|
||||
case 'x':
|
||||
case 'X':
|
||||
context.file.sbumpc();
|
||||
return parseHexNumber("\"0x\"");
|
||||
return readNumber<16>(0, "\"0x\"");
|
||||
case 'o':
|
||||
case 'O':
|
||||
context.file.sbumpc();
|
||||
return parseOctNumber("\"0o\"");
|
||||
return readNumber<8>(0, "\"0o\"");
|
||||
case 'b':
|
||||
case 'B':
|
||||
context.file.sbumpc();
|
||||
return parseBinNumber("\"0b\"");
|
||||
return readNumber<2>(0, "\"0b\"");
|
||||
}
|
||||
}
|
||||
return readNumber<10>(initial, nullptr, nullptr);
|
||||
return readNumber<10>(initial, nullptr);
|
||||
}
|
||||
|
||||
static yy::parser::symbol_type parseString() {
|
||||
@@ -226,11 +233,11 @@ yy::parser::symbol_type yylex() {
|
||||
} else if (c == '"') {
|
||||
return parseString();
|
||||
} else if (c == '$') {
|
||||
return parseHexNumber("'$'");
|
||||
return readNumber<16>(0, "'$'");
|
||||
} else if (c == '%') {
|
||||
return parseBinNumber("'%'");
|
||||
return readNumber<2>(0, "'%'");
|
||||
} else if (c == '&') {
|
||||
return parseOctNumber("'&'");
|
||||
return readNumber<8>(0, "'&'");
|
||||
} else if (isDigit<10>(c)) {
|
||||
return parseAnyNumber(c);
|
||||
} else if (isLetter(c)) {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
error: No hexadecimal digits found after '$'
|
||||
error: Invalid integer constant, no digits after '$'
|
||||
at script-lone-dollar.link(1)
|
||||
Linking failed with 1 error
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
error: No binary digits found after '%'
|
||||
error: Invalid integer constant, no digits after '%'
|
||||
at script-lone-percent.link(1)
|
||||
Linking failed with 1 error
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
ROM0
|
||||
org 4_2
|
||||
org %10_10_10
|
||||
org &52_
|
||||
org $2A_
|
||||
org 0b101_010
|
||||
org 0o5_2
|
||||
org &52_ ; trailing '_'
|
||||
org $2A_ ; trailing '_'
|
||||
org 0b101__010 ; '_' after another '_'
|
||||
org 0o__5_2 ; '_' after another '_'
|
||||
org 0x2_A
|
||||
org 41 ; Error!
|
||||
org 41 ; different value
|
||||
org %_ ; no digits
|
||||
org 0x__ ; no digits
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
error: Invalid integer constant, trailing '_'
|
||||
at script-num-fmt.link(4)
|
||||
error: Invalid integer constant, trailing '_'
|
||||
at script-num-fmt.link(5)
|
||||
error: Invalid integer constant, '_' after another '_'
|
||||
at script-num-fmt.link(6)
|
||||
error: Invalid integer constant, '_' after another '_'
|
||||
at script-num-fmt.link(7)
|
||||
error: Cannot decrease the current address (from $002a to $0029)
|
||||
at script-num-fmt.link(9)
|
||||
Linking failed with 1 error
|
||||
error: Invalid integer constant, no digits after '%'
|
||||
at script-num-fmt.link(10)
|
||||
error: Invalid integer constant, trailing '_'
|
||||
at script-num-fmt.link(10)
|
||||
error: Cannot decrease the current address (from $002a to $0000)
|
||||
at script-num-fmt.link(10)
|
||||
error: Invalid integer constant, '_' after another '_'
|
||||
at script-num-fmt.link(11)
|
||||
error: Invalid integer constant, no digits after "0x"
|
||||
at script-num-fmt.link(11)
|
||||
error: Invalid integer constant, trailing '_'
|
||||
at script-num-fmt.link(11)
|
||||
error: Cannot decrease the current address (from $002a to $0000)
|
||||
at script-num-fmt.link(11)
|
||||
Linking failed with 12 errors
|
||||
|
||||
Reference in New Issue
Block a user