From 6e97add1ee2b5cf3241308c17394fa3b76da37a2 Mon Sep 17 00:00:00 2001 From: Kampfkarren Date: Wed, 27 Jul 2022 18:10:06 -0700 Subject: [PATCH] Support un-interpolated strings --- Ast/include/Luau/Lexer.h | 4 +--- Ast/src/Lexer.cpp | 27 +++++---------------------- Ast/src/Parser.cpp | 5 ----- tests/Parser.test.cpp | 17 ----------------- tests/conformance/stringinterp.lua | 8 ++++---- 5 files changed, 10 insertions(+), 51 deletions(-) diff --git a/Ast/include/Luau/Lexer.h b/Ast/include/Luau/Lexer.h index 428e247d..57877454 100644 --- a/Ast/include/Luau/Lexer.h +++ b/Ast/include/Luau/Lexer.h @@ -84,9 +84,7 @@ struct Lexeme BrokenString, BrokenComment, BrokenUnicode, - BrokenInterpDoubleBrace, - BrokenInterpNoFormat, Error, @@ -219,7 +217,7 @@ private: Lexeme readQuotedString(); Lexeme readInterpolatedStringBegin(); - std::optional readInterpolatedStringSection(Position start, Lexeme::Type formatType); + Lexeme readInterpolatedStringSection(Position start, Lexeme::Type formatType, Lexeme::Type endType); void readBackslashInString(); diff --git a/Ast/src/Lexer.cpp b/Ast/src/Lexer.cpp index 85064827..69b097db 100644 --- a/Ast/src/Lexer.cpp +++ b/Ast/src/Lexer.cpp @@ -189,9 +189,6 @@ std::string Lexeme::toString() const case BrokenInterpDoubleBrace: return "'{{', which is invalid (did you mean '\\{'?)"; - case BrokenInterpNoFormat: - return "interpolated string with no formatting"; - case BrokenUnicode: if (codepoint) { @@ -595,15 +592,7 @@ const Lexeme Lexer::nextInterpolatedString() Position start = position(); unsigned int startOffset = offset; - if (std::optional readSection = readInterpolatedStringSection(start, Lexeme::InterpStringMid)) - { - lexeme = *readSection; - return lexeme; - } - - consume(); - - lexeme = Lexeme(Location(start, position()), Lexeme::InterpStringEnd, &buffer[startOffset], offset - startOffset - 1); + lexeme = readInterpolatedStringSection(start, Lexeme::InterpStringMid, Lexeme::InterpStringEnd); return lexeme; } @@ -612,17 +601,10 @@ Lexeme Lexer::readInterpolatedStringBegin() Position start = position(); consume(); - std::optional readSectionOpt = readInterpolatedStringSection(start, Lexeme::InterpStringBegin); - - if (!readSectionOpt) - { - return Lexeme(Location(start, position()), Lexeme::BrokenInterpNoFormat); - } - - return *readSectionOpt; + return readInterpolatedStringSection(start, Lexeme::InterpStringBegin, Lexeme::QuotedString); } -std::optional Lexer::readInterpolatedStringSection(Position start, Lexeme::Type formatType) +Lexeme Lexer::readInterpolatedStringSection(Position start, Lexeme::Type formatType, Lexeme::Type endType) { unsigned int startOffset = offset; @@ -656,7 +638,8 @@ std::optional 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) diff --git a/Ast/src/Parser.cpp b/Ast/src/Parser.cpp index fd12ab0f..327cb167 100644 --- a/Ast/src/Parser.cpp +++ b/Ast/src/Parser.cpp @@ -2221,11 +2221,6 @@ AstExpr* Parser::parseSimpleExpr() nextLexeme(); 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) { if (functionStack.back().vararg) diff --git a/tests/Parser.test.cpp b/tests/Parser.test.cpp index 5c34ebcd..5e0f6da4 100644 --- a/tests/Parser.test.cpp +++ b/tests/Parser.test.cpp @@ -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") { ScopedFastFlag sff{"LuauInterpolatedStringBaseSupport", true}; diff --git a/tests/conformance/stringinterp.lua b/tests/conformance/stringinterp.lua index cad3043c..2c79504a 100644 --- a/tests/conformance/stringinterp.lua +++ b/tests/conformance/stringinterp.lua @@ -31,10 +31,10 @@ assertEq(`This {localName} does not exist`, "This nil does not exist") assertEq(`Welcome to \ {name}!`, "Welcome to \nLuau!") -assertEq(`Escaped brace: \{} ({1})`, "Escaped brace: {} (1)") -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(`Escaped backslash \\ ({3})`, "Escaped backslash \\ (3)") -assertEq(`Escaped backtick: \` ({4})`, "Escaped backtick: ` (4)") +assertEq(`Escaped brace: \{}`, "Escaped brace: {}") +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 \\`, "Escaped backslash \\") +assertEq(`Escaped backtick: \``, "Escaped backtick: `") assertEq(`Hello {`from inside {"a nested string"}`}`, "Hello from inside a nested string")