mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 10:42:07 +00:00
Consolidate readString and appendStringLiteral
This commit is contained in:
@@ -1563,77 +1563,27 @@ static void appendCharInLiteral(std::string &str, int c, bool rawString) {
|
|||||||
str += c; // Copy the character
|
str += c; // Copy the character
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string readString(bool raw) {
|
static void readString(std::string &str, bool rawString) {
|
||||||
Defer reenableExpansions = scopedDisableExpansions();
|
Defer reenableExpansions = scopedDisableExpansions();
|
||||||
|
|
||||||
|
bool rawMode = lexerState->mode == LEXER_RAW;
|
||||||
|
|
||||||
// We reach this function after reading a single quote, but we also support triple quotes
|
// We reach this function after reading a single quote, but we also support triple quotes
|
||||||
bool multiline = false;
|
bool multiline = false;
|
||||||
if (peek() == '"') {
|
if (rawMode) {
|
||||||
shiftChar();
|
|
||||||
if (peek() == '"') {
|
|
||||||
// """ begins a multi-line string
|
|
||||||
shiftChar();
|
|
||||||
multiline = true;
|
|
||||||
} else {
|
|
||||||
// "" is an empty string, skip the loop
|
|
||||||
return ""s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::string str = ""s;;) {
|
|
||||||
int c = peek();
|
|
||||||
|
|
||||||
// '\r', '\n' or EOF ends a single-line string early
|
|
||||||
if (c == EOF || (!multiline && (c == '\r' || c == '\n'))) {
|
|
||||||
error("Unterminated string");
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We'll be staying in the string, so we can safely consume the char
|
|
||||||
shiftChar();
|
|
||||||
|
|
||||||
// Handle '\r' or '\n' (in multiline strings only, already handled above otherwise)
|
|
||||||
if (c == '\r' || c == '\n') {
|
|
||||||
handleCRLF(c);
|
|
||||||
nextLine();
|
|
||||||
c = '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the string if it's terminated
|
|
||||||
if (c == '"') {
|
|
||||||
if (!multiline) {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
// Only """ ends a multi-line string
|
|
||||||
if (peek() == '"') {
|
|
||||||
shiftChar();
|
|
||||||
if (peek() == '"') {
|
|
||||||
shiftChar();
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
str += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the character or handle special ones
|
|
||||||
appendCharInLiteral(str, c, raw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void appendStringLiteral(std::string &str, bool raw) {
|
|
||||||
// This is essentially a modified `readString`
|
|
||||||
Defer reenableExpansions = scopedDisableExpansions();
|
|
||||||
|
|
||||||
// We reach this function after reading a single quote, but we also support triple quotes
|
|
||||||
bool multiline = false;
|
|
||||||
str += '"';
|
|
||||||
if (peek() == '"') {
|
|
||||||
str += '"';
|
str += '"';
|
||||||
|
}
|
||||||
|
if (peek() == '"') {
|
||||||
shiftChar();
|
shiftChar();
|
||||||
|
if (rawMode) {
|
||||||
|
str += '"';
|
||||||
|
}
|
||||||
if (peek() == '"') {
|
if (peek() == '"') {
|
||||||
// """ begins a multi-line string
|
// """ begins a multi-line string
|
||||||
str += '"';
|
|
||||||
shiftChar();
|
shiftChar();
|
||||||
|
if (rawMode) {
|
||||||
|
str += '"';
|
||||||
|
}
|
||||||
multiline = true;
|
multiline = true;
|
||||||
} else {
|
} else {
|
||||||
// "" is an empty string, skip the loop
|
// "" is an empty string, skip the loop
|
||||||
@@ -1657,30 +1607,37 @@ static void appendStringLiteral(std::string &str, bool raw) {
|
|||||||
if (c == '\r' || c == '\n') {
|
if (c == '\r' || c == '\n') {
|
||||||
handleCRLF(c);
|
handleCRLF(c);
|
||||||
nextLine();
|
nextLine();
|
||||||
c = '\n';
|
str += '\n';
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the string and return if it's terminated
|
// Close the string and return if it's terminated
|
||||||
if (c == '"') {
|
if (c == '"') {
|
||||||
if (multiline) {
|
if (!multiline) {
|
||||||
// Only """ ends a multi-line string
|
if (rawMode) {
|
||||||
str += c;
|
str += c;
|
||||||
if (peek() != '"') {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
shiftChar();
|
return;
|
||||||
str += c;
|
}
|
||||||
if (peek() != '"') {
|
// Only """ ends a multi-line string
|
||||||
continue;
|
if (peek() != '"') {
|
||||||
}
|
str += c;
|
||||||
shiftChar();
|
continue;
|
||||||
|
}
|
||||||
|
shiftChar();
|
||||||
|
if (peek() != '"') {
|
||||||
|
str += "\"\"";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
shiftChar();
|
||||||
|
if (rawMode) {
|
||||||
|
str += "\"\"\"";
|
||||||
}
|
}
|
||||||
str += c;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the character or handle special ones
|
// Append the character or handle special ones
|
||||||
appendCharInLiteral(str, c, raw);
|
appendCharInLiteral(str, c, rawString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1968,8 +1925,11 @@ static Token yylex_NORMAL() {
|
|||||||
|
|
||||||
// Handle strings
|
// Handle strings
|
||||||
|
|
||||||
case '"':
|
case '"': {
|
||||||
return Token(T_(STRING), readString(false));
|
std::string str;
|
||||||
|
readString(str, false);
|
||||||
|
return Token(T_(STRING), str);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle newlines and EOF
|
// Handle newlines and EOF
|
||||||
|
|
||||||
@@ -1995,7 +1955,9 @@ static Token yylex_NORMAL() {
|
|||||||
case '#':
|
case '#':
|
||||||
if (peek() == '"') {
|
if (peek() == '"') {
|
||||||
shiftChar();
|
shiftChar();
|
||||||
return Token(T_(STRING), readString(true));
|
std::string str;
|
||||||
|
readString(str, true);
|
||||||
|
return Token(T_(STRING), str);
|
||||||
}
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
|
||||||
@@ -2067,7 +2029,7 @@ static Token yylex_NORMAL() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Token yylex_RAW() {
|
static Token yylex_RAW() {
|
||||||
// This is essentially a highly modified `appendStringLiteral`
|
// This is essentially a highly modified `readString`
|
||||||
std::string str;
|
std::string str;
|
||||||
size_t parenDepth = 0;
|
size_t parenDepth = 0;
|
||||||
int c;
|
int c;
|
||||||
@@ -2097,7 +2059,7 @@ static Token yylex_RAW() {
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case '"': // String literals inside macro args
|
case '"': // String literals inside macro args
|
||||||
shiftChar();
|
shiftChar();
|
||||||
appendStringLiteral(str, false);
|
readString(str, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '#': // Raw string literals inside macro args
|
case '#': // Raw string literals inside macro args
|
||||||
@@ -2105,7 +2067,7 @@ static Token yylex_RAW() {
|
|||||||
shiftChar();
|
shiftChar();
|
||||||
if (peek() == '"') {
|
if (peek() == '"') {
|
||||||
shiftChar();
|
shiftChar();
|
||||||
appendStringLiteral(str, true);
|
readString(str, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user