From 6cb9054c07202045c9570cd954574a7bd85cb01a Mon Sep 17 00:00:00 2001 From: Kampfkarren Date: Tue, 26 Jul 2022 19:20:33 -0700 Subject: [PATCH] Remove copy paste (though I'm not sure it's much better), start work on {{ parse failure --- Ast/include/Luau/Lexer.h | 1 + Ast/src/Lexer.cpp | 56 ++++++++++++------------------ tests/Parser.test.cpp | 15 ++++++++ tests/conformance/stringinterp.lua | 3 -- 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/Ast/include/Luau/Lexer.h b/Ast/include/Luau/Lexer.h index e72a6d44..8519ca82 100644 --- a/Ast/include/Luau/Lexer.h +++ b/Ast/include/Luau/Lexer.h @@ -218,6 +218,7 @@ private: Lexeme readQuotedString(); Lexeme readInterpolatedStringBegin(); + std::optional readInterpolatedStringSection(Position start, Lexeme::Type formatType); void readBackslashInString(); diff --git a/Ast/src/Lexer.cpp b/Ast/src/Lexer.cpp index 9c9d3d98..b310c976 100644 --- a/Ast/src/Lexer.cpp +++ b/Ast/src/Lexer.cpp @@ -602,35 +602,15 @@ Lexeme Lexer::readQuotedString() const Lexeme Lexer::nextInterpolatedString() { - // INTERP TODO: This is a copy-paste Position start = position(); - unsigned int startOffset = offset; - while (peekch() != '`') + std::optional readSectionOpt = readInterpolatedStringSection(start, Lexeme::InterpStringMid); + + if (auto readSection = readSectionOpt) { - switch (peekch()) - { - case 0: - case '\r': - case '\n': - lexeme = Lexeme(Location(start, position()), Lexeme::BrokenString); - return lexeme; - - case '\\': - readBackslashInString(); - break; - - case '{': - incrementInterpolatedStringDepth(); - - lexeme = Lexeme(Location(start, position()), Lexeme::InterpStringMid, &buffer[startOffset], offset - startOffset); - consume(); - return lexeme; - - default: - consume(); - } + lexeme = *readSection; + return lexeme; } consume(); @@ -642,9 +622,20 @@ const Lexeme Lexer::nextInterpolatedString() Lexeme Lexer::readInterpolatedStringBegin() { Position start = position(); - consume(); + std::optional readSectionOpt = readInterpolatedStringSection(start, Lexeme::InterpStringBegin); + + if (!readSectionOpt) + { + LUAU_ASSERT(!"INTERP TODO: Error if there was no interpolated expression"); + } + + return *readSectionOpt; +} + +std::optional Lexer::readInterpolatedStringSection(Position start, Lexeme::Type formatType) +{ unsigned int startOffset = offset; while (peekch() != '`') @@ -654,27 +645,26 @@ Lexeme Lexer::readInterpolatedStringBegin() case 0: case '\r': case '\n': - return Lexeme(Location(start, position()), Lexeme::BrokenString); + return std::optional(Lexeme(Location(start, position()), Lexeme::BrokenString)); case '\\': readBackslashInString(); break; case '{': + { incrementInterpolatedStringDepth(); - lexeme = Lexeme(Location(start, position()), Lexeme::InterpStringBegin, &buffer[startOffset], offset - startOffset); + auto lexemeOutput = Lexeme(Location(start, position()), Lexeme::InterpStringBegin, &buffer[startOffset], offset - startOffset); consume(); - return lexeme; + return std::optional(lexemeOutput); + } default: consume(); } } - consume(); - - // INTERP TODO: Error if there was no interpolated expression - LUAU_ASSERT(!"INTERP TODO: interpolated string without ending"); + return std::nullopt; } Lexeme Lexer::readNumber(const Position& start, unsigned int startOffset) diff --git a/tests/Parser.test.cpp b/tests/Parser.test.cpp index c517853f..844c588c 100644 --- a/tests/Parser.test.cpp +++ b/tests/Parser.test.cpp @@ -1034,6 +1034,21 @@ TEST_CASE_FIXTURE(Fixture, "parse_compound_assignment_error_multiple") } } +TEST_CASE_FIXTURE(Fixture, "parse_interpolated_string_double_brace") +{ + try + { + parse(R"( + _ = `{{oops}}` + )"); + FAIL("Expected ParseErrors to be thrown"); + } + catch (const ParseErrors& e) + { + CHECK_EQ("INTERP TODO: Message", e.getErrors().front().getMessage()); + } +} + TEST_CASE_FIXTURE(Fixture, "parse_nesting_based_end_detection") { try diff --git a/tests/conformance/stringinterp.lua b/tests/conformance/stringinterp.lua index 52eae5eb..cad3043c 100644 --- a/tests/conformance/stringinterp.lua +++ b/tests/conformance/stringinterp.lua @@ -18,9 +18,6 @@ assertEq(`The lock combinations are: {table.concat(combo, ", ")}`, "The lock com assertEq(`true = {true}`, "true = true") --- -- INTERP TODO: Syntax error --- -- assert(string.find(`{{ "nested braces!" }}`, "table")) - local name = "Luau" assertEq(`Welcome to { name