mirror of
https://github.com/luau-lang/luau.git
synced 2025-05-04 10:33:46 +01:00
Support un-interpolated strings
This commit is contained in:
parent
8ef45854f7
commit
6e97add1ee
5 changed files with 10 additions and 51 deletions
|
@ -84,9 +84,7 @@ struct Lexeme
|
||||||
BrokenString,
|
BrokenString,
|
||||||
BrokenComment,
|
BrokenComment,
|
||||||
BrokenUnicode,
|
BrokenUnicode,
|
||||||
|
|
||||||
BrokenInterpDoubleBrace,
|
BrokenInterpDoubleBrace,
|
||||||
BrokenInterpNoFormat,
|
|
||||||
|
|
||||||
Error,
|
Error,
|
||||||
|
|
||||||
|
@ -219,7 +217,7 @@ private:
|
||||||
Lexeme readQuotedString();
|
Lexeme readQuotedString();
|
||||||
|
|
||||||
Lexeme readInterpolatedStringBegin();
|
Lexeme readInterpolatedStringBegin();
|
||||||
std::optional<Lexeme> readInterpolatedStringSection(Position start, Lexeme::Type formatType);
|
Lexeme readInterpolatedStringSection(Position start, Lexeme::Type formatType, Lexeme::Type endType);
|
||||||
|
|
||||||
void readBackslashInString();
|
void readBackslashInString();
|
||||||
|
|
||||||
|
|
|
@ -189,9 +189,6 @@ std::string Lexeme::toString() const
|
||||||
case BrokenInterpDoubleBrace:
|
case BrokenInterpDoubleBrace:
|
||||||
return "'{{', which is invalid (did you mean '\\{'?)";
|
return "'{{', which is invalid (did you mean '\\{'?)";
|
||||||
|
|
||||||
case BrokenInterpNoFormat:
|
|
||||||
return "interpolated string with no formatting";
|
|
||||||
|
|
||||||
case BrokenUnicode:
|
case BrokenUnicode:
|
||||||
if (codepoint)
|
if (codepoint)
|
||||||
{
|
{
|
||||||
|
@ -595,15 +592,7 @@ const Lexeme Lexer::nextInterpolatedString()
|
||||||
Position start = position();
|
Position start = position();
|
||||||
unsigned int startOffset = offset;
|
unsigned int startOffset = offset;
|
||||||
|
|
||||||
if (std::optional<Lexeme> readSection = readInterpolatedStringSection(start, Lexeme::InterpStringMid))
|
lexeme = readInterpolatedStringSection(start, Lexeme::InterpStringMid, Lexeme::InterpStringEnd);
|
||||||
{
|
|
||||||
lexeme = *readSection;
|
|
||||||
return lexeme;
|
|
||||||
}
|
|
||||||
|
|
||||||
consume();
|
|
||||||
|
|
||||||
lexeme = Lexeme(Location(start, position()), Lexeme::InterpStringEnd, &buffer[startOffset], offset - startOffset - 1);
|
|
||||||
return lexeme;
|
return lexeme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,17 +601,10 @@ Lexeme Lexer::readInterpolatedStringBegin()
|
||||||
Position start = position();
|
Position start = position();
|
||||||
consume();
|
consume();
|
||||||
|
|
||||||
std::optional<Lexeme> readSectionOpt = readInterpolatedStringSection(start, Lexeme::InterpStringBegin);
|
return readInterpolatedStringSection(start, Lexeme::InterpStringBegin, Lexeme::QuotedString);
|
||||||
|
|
||||||
if (!readSectionOpt)
|
|
||||||
{
|
|
||||||
return Lexeme(Location(start, position()), Lexeme::BrokenInterpNoFormat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *readSectionOpt;
|
Lexeme Lexer::readInterpolatedStringSection(Position start, Lexeme::Type formatType, Lexeme::Type endType)
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<Lexeme> Lexer::readInterpolatedStringSection(Position start, Lexeme::Type formatType)
|
|
||||||
{
|
{
|
||||||
unsigned int startOffset = offset;
|
unsigned int startOffset = offset;
|
||||||
|
|
||||||
|
@ -656,7 +638,8 @@ std::optional<Lexeme> Lexer::readInterpolatedStringSection(Position start, Lexem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
consume();
|
||||||
|
return Lexeme(Location(start, position()), endType, &buffer[startOffset], offset - startOffset - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lexeme Lexer::readNumber(const Position& start, unsigned int startOffset)
|
Lexeme Lexer::readNumber(const Position& start, unsigned int startOffset)
|
||||||
|
|
|
@ -2221,11 +2221,6 @@ AstExpr* Parser::parseSimpleExpr()
|
||||||
nextLexeme();
|
nextLexeme();
|
||||||
return reportExprError(start, {}, ERROR_INVALID_INTERP_DOUBLE_BRACE);
|
return reportExprError(start, {}, ERROR_INVALID_INTERP_DOUBLE_BRACE);
|
||||||
}
|
}
|
||||||
else if (lexer.current().type == Lexeme::BrokenInterpNoFormat)
|
|
||||||
{
|
|
||||||
nextLexeme();
|
|
||||||
return reportExprError(start, {}, "Interpolated strings must contain expressions, and cannot be constant");
|
|
||||||
}
|
|
||||||
else if (lexer.current().type == Lexeme::Dot3)
|
else if (lexer.current().type == Lexeme::Dot3)
|
||||||
{
|
{
|
||||||
if (functionStack.back().vararg)
|
if (functionStack.back().vararg)
|
||||||
|
|
|
@ -1068,23 +1068,6 @@ TEST_CASE_FIXTURE(Fixture, "parse_interpolated_string_double_brace_mid")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "parse_interpolated_string_without_format")
|
|
||||||
{
|
|
||||||
ScopedFastFlag sff{"LuauInterpolatedStringBaseSupport", true};
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
parse(R"(
|
|
||||||
_ = `doge`
|
|
||||||
)");
|
|
||||||
FAIL("Expected ParseErrors to be thrown");
|
|
||||||
}
|
|
||||||
catch (const ParseErrors& e)
|
|
||||||
{
|
|
||||||
CHECK_EQ("Interpolated strings must contain expressions, and cannot be constant", e.getErrors().front().getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE_FIXTURE(Fixture, "parse_interpolated_string_without_end_brace")
|
TEST_CASE_FIXTURE(Fixture, "parse_interpolated_string_without_end_brace")
|
||||||
{
|
{
|
||||||
ScopedFastFlag sff{"LuauInterpolatedStringBaseSupport", true};
|
ScopedFastFlag sff{"LuauInterpolatedStringBaseSupport", true};
|
||||||
|
|
|
@ -31,10 +31,10 @@ assertEq(`This {localName} does not exist`, "This nil does not exist")
|
||||||
assertEq(`Welcome to \
|
assertEq(`Welcome to \
|
||||||
{name}!`, "Welcome to \nLuau!")
|
{name}!`, "Welcome to \nLuau!")
|
||||||
|
|
||||||
assertEq(`Escaped brace: \{} ({1})`, "Escaped brace: {} (1)")
|
assertEq(`Escaped brace: \{}`, "Escaped brace: {}")
|
||||||
assertEq(`Backslash \ that escapes the space is not a part of the string... ({2})`, "Backslash that escapes the space is not a part of the string... (2)")
|
assertEq(`Backslash \ that escapes the space is not a part of the string...`, "Backslash that escapes the space is not a part of the string...")
|
||||||
assertEq(`Escaped backslash \\ ({3})`, "Escaped backslash \\ (3)")
|
assertEq(`Escaped backslash \\`, "Escaped backslash \\")
|
||||||
assertEq(`Escaped backtick: \` ({4})`, "Escaped backtick: ` (4)")
|
assertEq(`Escaped backtick: \``, "Escaped backtick: `")
|
||||||
|
|
||||||
assertEq(`Hello {`from inside {"a nested string"}`}`, "Hello from inside a nested string")
|
assertEq(`Hello {`from inside {"a nested string"}`}`, "Hello from inside a nested string")
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue