Consolidate readString and appendStringLiteral

This commit is contained in:
Rangi42
2025-07-11 23:31:41 -04:00
parent 01a5c94c7e
commit f2708ce967

View File

@@ -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 (rawMode) {
str += '"';
}
if (peek() == '"') { if (peek() == '"') {
shiftChar(); shiftChar();
if (rawMode) {
str += '"';
}
if (peek() == '"') { if (peek() == '"') {
// """ begins a multi-line string // """ begins a multi-line string
shiftChar(); shiftChar();
multiline = true; if (rawMode) {
} 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 += '"'; str += '"';
if (peek() == '"') { }
str += '"';
shiftChar();
if (peek() == '"') {
// """ begins a multi-line string
str += '"';
shiftChar();
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) {
if (rawMode) {
str += c;
}
return;
}
// Only """ ends a multi-line string // Only """ ends a multi-line string
str += c;
if (peek() != '"') { if (peek() != '"') {
str += c;
continue; continue;
} }
shiftChar(); shiftChar();
str += c;
if (peek() != '"') { if (peek() != '"') {
str += "\"\"";
continue; continue;
} }
shiftChar(); 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;