1
0
forked from Mirror/wren

Raw strings now ignore whitespace on both ends for consistency and clarity

added more tests, updated documentation
This commit is contained in:
ruby0x1
2021-04-04 22:28:57 -07:00
parent 8304fd5ecc
commit e3c76a3e76
3 changed files with 62 additions and 16 deletions

View File

@ -131,9 +131,10 @@ from any other string, it's just parsed in a different way.
"""hi there""" """hi there"""
</pre> </pre>
When a raw string spans multiple lines, the newline immediately When a raw string spans multiple lines and a triple quote is on it's own line,
after the triple quote will be ignored, and any spaces or tabs after any whitespace on that line will be ignored. This means the opening and closing
the last newline (before the closing triple quote) will be ignored too. lines are not counted as part of the string when the triple quotes are separate lines,
as long as they only contain whitespace (spaces + tabs).
<pre class="snippet"> <pre class="snippet">
""" """
@ -141,8 +142,8 @@ the last newline (before the closing triple quote) will be ignored too.
""" """
</pre> </pre>
The value in the string above has no newlines, but the spaces in front The resulting value in the string above has no newlines or trailing whitespace.
are preserved. The newline after `"""` and the whitespace on the closing line are ignored. Note the spaces in front of the Hello are preserved.
<pre class="snippet"> <pre class="snippet">
Hello world Hello world

View File

@ -859,12 +859,11 @@ static void readRawString(Parser* parser)
nextChar(parser); nextChar(parser);
nextChar(parser); nextChar(parser);
//if there's a newline immediately after, int skipStart = 0;
//discard it so it's not part of the literal int firstNewline = -1;
if(peekChar(parser) == '\n') nextChar(parser);
int skipEnd = -1;
int lastNewline = -1; int lastNewline = -1;
int whitespace = -1;
for (;;) for (;;)
{ {
@ -874,12 +873,24 @@ static void readRawString(Parser* parser)
if(c == '\n') { if(c == '\n') {
lastNewline = string.count; lastNewline = string.count;
whitespace = lastNewline; skipEnd = lastNewline;
firstNewline = firstNewline == -1 ? string.count : firstNewline;
} }
if(c == '"' && c1 == '"' && c2 == '"') break; if(c == '"' && c1 == '"' && c2 == '"') break;
if(c != '\n' && c != ' ' && c != '\t') whitespace = -1; bool isWhitespace = c == ' ' || c == '\t';
skipEnd = c == '\n' || isWhitespace ? skipEnd : -1;
// If we haven't seen a newline or other character yet,
// and still seeing whitespace, count the characters
// as skippable till we know otherwise
bool skippable = skipStart != -1 && isWhitespace && firstNewline == -1;
skipStart = skippable ? string.count + 1 : skipStart;
// We've counted leading whitespace till we hit something else,
// but it's not a newline, so we reset skipStart since we need these characters
if (firstNewline == -1 && !isWhitespace && c != '\n') skipStart = -1;
if (c == '\0' || c1 == '\0' || c2 == '\0') if (c == '\0' || c1 == '\0' || c2 == '\0')
{ {
@ -898,11 +909,16 @@ static void readRawString(Parser* parser)
nextChar(parser); nextChar(parser);
nextChar(parser); nextChar(parser);
int offset = 0;
int count = string.count; int count = string.count;
if(lastNewline != -1 && whitespace == lastNewline) count = lastNewline;
parser->next.value = wrenNewStringLength(parser->vm, if(firstNewline != -1 && skipStart == firstNewline) offset = firstNewline + 1;
(char*)string.data, count); if(lastNewline != -1 && skipEnd == lastNewline) count = lastNewline;
count -= (offset > count) ? count : offset;
parser->next.value = wrenNewStringLength(parser->vm,
((char*)string.data) + offset, count);
wrenByteBufferClear(parser->vm, &string); wrenByteBufferClear(parser->vm, &string);
makeToken(parser, type); makeToken(parser, type);

View File

@ -6,6 +6,8 @@ System.print("A~¶Þॐஃ") // expect: A~¶Þॐஃ
// Raw strings. // Raw strings.
System.print("""A raw string""") // expect: A raw string System.print("""A raw string""") // expect: A raw string
System.print(""" A raw string""") // expect: A raw string
System.print("""A raw string """) // expect: A raw string
var long = " var long = "
A A
@ -27,4 +29,31 @@ var raw = """
System.print(raw) // expect: A if*(<invalid>)* System.print(raw) // expect: A if*(<invalid>)*
// expect: multi line /{}() // expect: multi line /{}()
// expect: raw string [\]/ // expect: raw string [\]/
// expect: "json": "value" // expect: "json": "value"
// Raw strings ignore whitespace on the line with the """
var noNewlines = """
no newlines
"""
System.print(noNewlines) // expect: no newlines
// Spaces after the """ but before the \n
var noLeadingSpaces = """
no leading spaces
"""
System.print(noLeadingSpaces) // expect: no leading spaces
// Spaces before the end """ after the \n
var noTrailingSpaces = """
no trailing spaces
"""
System.print(noTrailingSpaces) // expect: no trailing spaces
var newlineBefore = """
newline before"""
System.print(newlineBefore) // expect: newline before
var newlineAfter = """newline after
"""
System.print(newlineAfter) // expect: newline after