mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
@@ -1448,30 +1448,57 @@ static void readString(void)
|
|||||||
dbgPrint("Reading string\n");
|
dbgPrint("Reading string\n");
|
||||||
lexerState->disableMacroArgs = true;
|
lexerState->disableMacroArgs = true;
|
||||||
lexerState->disableInterpolation = true;
|
lexerState->disableInterpolation = true;
|
||||||
|
|
||||||
|
bool multiline = false;
|
||||||
|
|
||||||
|
if (peek(0) == '"') {
|
||||||
|
shiftChars(1);
|
||||||
|
if (peek(0) == '"') {
|
||||||
|
/* """ begins a multi-line string */
|
||||||
|
shiftChars(1);
|
||||||
|
multiline = true;
|
||||||
|
} else {
|
||||||
|
/* "" is an empty string */
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = peek(0);
|
int c = peek(0);
|
||||||
|
|
||||||
|
if (c == '\r' || c == '\n') {
|
||||||
|
if (!multiline) {
|
||||||
|
/* '\r' or '\n' ends a single-line string early */
|
||||||
|
c = EOF;
|
||||||
|
} else if (c == '\r' && peek(1) == '\n') {
|
||||||
|
/* '\r\n' becomes '\n' in multi-line strings */
|
||||||
|
shiftChars(1);
|
||||||
|
c = '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '"':
|
case '"':
|
||||||
shiftChars(1);
|
if (multiline) {
|
||||||
|
/* """ ends a multi-line string */
|
||||||
|
if (peek(1) != '"' || peek(2) != '"')
|
||||||
|
break;
|
||||||
|
shiftChars(3);
|
||||||
|
} else {
|
||||||
|
shiftChars(1);
|
||||||
|
}
|
||||||
if (i == sizeof(yylval.tzString)) {
|
if (i == sizeof(yylval.tzString)) {
|
||||||
i--;
|
i--;
|
||||||
warning(WARNING_LONG_STR, "String constant too long\n");
|
warning(WARNING_LONG_STR, "String constant too long\n");
|
||||||
}
|
}
|
||||||
yylval.tzString[i] = '\0';
|
|
||||||
dbgPrint("Read string \"%s\"\n", yylval.tzString);
|
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
case '\r':
|
|
||||||
case '\n': /* Do not shift these! */
|
|
||||||
case EOF:
|
case EOF:
|
||||||
if (i == sizeof(yylval.tzString)) {
|
if (i == sizeof(yylval.tzString)) {
|
||||||
i--;
|
i--;
|
||||||
warning(WARNING_LONG_STR, "String constant too long\n");
|
warning(WARNING_LONG_STR, "String constant too long\n");
|
||||||
}
|
}
|
||||||
yylval.tzString[i] = '\0';
|
|
||||||
error("Unterminated string\n");
|
error("Unterminated string\n");
|
||||||
dbgPrint("Read string \"%s\"\n", yylval.tzString);
|
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
case '\\': /* Character escape or macro arg */
|
case '\\': /* Character escape or macro arg */
|
||||||
@@ -1553,6 +1580,9 @@ static void readString(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
|
yylval.tzString[i] = '\0';
|
||||||
|
|
||||||
|
dbgPrint("Read string \"%s\"\n", yylval.tzString);
|
||||||
lexerState->disableMacroArgs = false;
|
lexerState->disableMacroArgs = false;
|
||||||
lexerState->disableInterpolation = false;
|
lexerState->disableInterpolation = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,6 +240,14 @@ There are a number of escape sequences you can use within a string:
|
|||||||
.El
|
.El
|
||||||
(Note that some of those can be used outside of strings, when noted further in this document.)
|
(Note that some of those can be used outside of strings, when noted further in this document.)
|
||||||
.Pp
|
.Pp
|
||||||
|
Multi-line strings are contained in triple quotes
|
||||||
|
.Pq Ql \&"\&"\&"for instance\&"\&"\&" .
|
||||||
|
Escape sequences work the same way in multi-line strings; however, literal newline
|
||||||
|
characters will be included as-is, without needing to escape them with
|
||||||
|
.Ql \[rs]r
|
||||||
|
or
|
||||||
|
.Ql \[rs]n .
|
||||||
|
.Pp
|
||||||
A funky feature is
|
A funky feature is
|
||||||
.Ql {symbol}
|
.Ql {symbol}
|
||||||
within a string, called
|
within a string, called
|
||||||
|
|||||||
32
test/asm/multi-line-strings.asm
Normal file
32
test/asm/multi-line-strings.asm
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
S EQUS "Hello"
|
||||||
|
|
||||||
|
PRINTT "\"\"\"\n"
|
||||||
|
|
||||||
|
PRINTT """{S}
|
||||||
|
world
|
||||||
|
"""
|
||||||
|
|
||||||
|
PRINTT """The multi-line string \ ; line continuations work
|
||||||
|
can contain:
|
||||||
|
- "single quotes"
|
||||||
|
- ""double quotes""
|
||||||
|
- even escaped \"""triple"\"" ""\"quotes\"\"\"
|
||||||
|
!"""
|
||||||
|
|
||||||
|
PRINTT """\n"""
|
||||||
|
|
||||||
|
printarg: MACRO
|
||||||
|
PRINTT "arg <\1>\n"
|
||||||
|
PRINTT """arg (\1)\n"""
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
printarg "
|
||||||
|
printarg """
|
||||||
|
|
||||||
|
EMPTY1 EQUS ""
|
||||||
|
EMPTY2 EQUS "\ ; comment
|
||||||
|
"
|
||||||
|
EMPTY3 EQUS """"""
|
||||||
|
EMPTY4 EQUS """\ ; comment
|
||||||
|
"""
|
||||||
|
PRINTT STRCAT("(", "{EMPTY1}", "{EMPTY2}", "{EMPTY3}", "{EMPTY4}", ")\n")
|
||||||
0
test/asm/multi-line-strings.err
Normal file
0
test/asm/multi-line-strings.err
Normal file
13
test/asm/multi-line-strings.out
Normal file
13
test/asm/multi-line-strings.out
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
"""
|
||||||
|
Hello
|
||||||
|
world
|
||||||
|
The multi-line string can contain:
|
||||||
|
- "single quotes"
|
||||||
|
- ""double quotes""
|
||||||
|
- even escaped """triple""" """quotes"""
|
||||||
|
!
|
||||||
|
arg <">
|
||||||
|
arg (")
|
||||||
|
arg <""">
|
||||||
|
arg (""")
|
||||||
|
()
|
||||||
Reference in New Issue
Block a user