mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
A local label starting with a keyword (e.g. jr.local) is an error
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
@@ -56,7 +57,7 @@ struct Token {
|
|||||||
|
|
||||||
// This map lists all RGBASM keywords which `yylex_NORMAL` lexes as identifiers.
|
// This map lists all RGBASM keywords which `yylex_NORMAL` lexes as identifiers.
|
||||||
// All non-identifier tokens are lexed separately.
|
// All non-identifier tokens are lexed separately.
|
||||||
static UpperMap<int> const keywordDict{
|
static UpperMap<int> const keywords{
|
||||||
{"ADC", T_(SM83_ADC) },
|
{"ADC", T_(SM83_ADC) },
|
||||||
{"ADD", T_(SM83_ADD) },
|
{"ADD", T_(SM83_ADD) },
|
||||||
{"AND", T_(SM83_AND) },
|
{"AND", T_(SM83_AND) },
|
||||||
@@ -1269,21 +1270,27 @@ static uint32_t readGfxConstant() {
|
|||||||
|
|
||||||
static Token readIdentifier(char firstChar, bool raw) {
|
static Token readIdentifier(char firstChar, bool raw) {
|
||||||
std::string identifier(1, firstChar);
|
std::string identifier(1, firstChar);
|
||||||
|
bool keywordBeforeLocal = false;
|
||||||
int tokenType = firstChar == '.' ? T_(LOCAL) : T_(SYMBOL);
|
int tokenType = firstChar == '.' ? T_(LOCAL) : T_(SYMBOL);
|
||||||
|
|
||||||
// Continue reading while the char is in the identifier charset
|
// Continue reading while the char is in the identifier charset
|
||||||
for (int c = peek(); continuesIdentifier(c); c = nextChar()) {
|
for (int c = peek(); continuesIdentifier(c); c = nextChar()) {
|
||||||
identifier += c;
|
|
||||||
|
|
||||||
// If the char was a dot, the identifier is a local label
|
// If the char was a dot, the identifier is a local label
|
||||||
if (c == '.') {
|
if (c == '.') {
|
||||||
tokenType = T_(LOCAL);
|
// Check for a keyword before a non-raw local label
|
||||||
}
|
if (!raw && tokenType != T_(LOCAL) && keywords.find(identifier) != keywords.end()) {
|
||||||
|
keywordBeforeLocal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to check for a keyword if the identifier is not raw or a local label
|
tokenType = T_(LOCAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
identifier += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for a keyword if the identifier is not raw and not a local label
|
||||||
if (!raw && tokenType != T_(LOCAL)) {
|
if (!raw && tokenType != T_(LOCAL)) {
|
||||||
if (auto search = keywordDict.find(identifier); search != keywordDict.end()) {
|
if (auto search = keywords.find(identifier); search != keywords.end()) {
|
||||||
return Token(search->second);
|
return Token(search->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1293,6 +1300,14 @@ static Token readIdentifier(char firstChar, bool raw) {
|
|||||||
tokenType = T_(SYMBOL);
|
tokenType = T_(SYMBOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A keyword before a non-raw local label is an error
|
||||||
|
if (keywordBeforeLocal) {
|
||||||
|
error(
|
||||||
|
"Identifier \"%s\" begins with a keyword; did you mean to put a space between them?",
|
||||||
|
identifier.c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return Token(tokenType, identifier);
|
return Token(tokenType, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1336,7 +1351,7 @@ static std::pair<Symbol const *, std::shared_ptr<std::string>> readInterpolation
|
|||||||
if (identifier.starts_with('#')) {
|
if (identifier.starts_with('#')) {
|
||||||
// Skip a '#' raw symbol prefix, but after expanding any nested interpolations.
|
// Skip a '#' raw symbol prefix, but after expanding any nested interpolations.
|
||||||
identifier.erase(0, 1);
|
identifier.erase(0, 1);
|
||||||
} else if (keywordDict.find(identifier) != keywordDict.end()) {
|
} else if (keywords.find(identifier) != keywords.end()) {
|
||||||
// Don't allow symbols that alias keywords without a '#' prefix.
|
// Don't allow symbols that alias keywords without a '#' prefix.
|
||||||
error(
|
error(
|
||||||
"Interpolated symbol `%s` is a reserved keyword; add a '#' prefix to use it as a raw "
|
"Interpolated symbol `%s` is a reserved keyword; add a '#' prefix to use it as a raw "
|
||||||
|
|||||||
3
test/asm/keyword-global.asm
Normal file
3
test/asm/keyword-global.asm
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
section "test", rom0
|
||||||
|
#call.local1
|
||||||
|
call.local2
|
||||||
3
test/asm/keyword-global.err
Normal file
3
test/asm/keyword-global.err
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
error: Identifier "call.local2" begins with a keyword; did you mean to put a space between them?
|
||||||
|
at keyword-global.asm(3)
|
||||||
|
Assembly aborted with 1 error!
|
||||||
Reference in New Issue
Block a user