diff --git a/Ast/src/Lexer.cpp b/Ast/src/Lexer.cpp index 870e11c2..532b9905 100644 --- a/Ast/src/Lexer.cpp +++ b/Ast/src/Lexer.cpp @@ -98,6 +98,7 @@ Lexeme::Lexeme(const Location& location, Type type, const char* data, size_t siz || type == InterpStringMid || type == InterpStringEnd || type == InterpStringSimple + || type == BrokenInterpDoubleBrace || type == Number || type == Comment || type == BlockComment @@ -638,12 +639,16 @@ Lexeme Lexer::readInterpolatedStringSection(Position start, Lexeme::Type formatT case '{': { + braceStack.push_back(BraceType::InterpolatedString); + if (peekch(1) == '{') { - return Lexeme(Location(start, position()), Lexeme::BrokenInterpDoubleBrace); + Lexeme brokenDoubleBrace = Lexeme(Location(start, position()), Lexeme::BrokenInterpDoubleBrace, &buffer[startOffset], offset - startOffset); + consume(); + consume(); + return brokenDoubleBrace; } - braceStack.push_back(BraceType::InterpolatedString); Lexeme lexemeOutput(Location(start, position()), Lexeme::InterpStringBegin, &buffer[startOffset], offset - startOffset); consume(); return lexemeOutput; diff --git a/tests/Lexer.test.cpp b/tests/Lexer.test.cpp index 9ff06bc9..0fafb130 100644 --- a/tests/Lexer.test.cpp +++ b/tests/Lexer.test.cpp @@ -157,6 +157,26 @@ TEST_CASE("string_interpolation_basic") CHECK_EQ(interpEnd.type, Lexeme::InterpStringEnd); } +TEST_CASE("string_interpolation_double_brace") +{ + ScopedFastFlag sff{"LuauInterpolatedStringBaseSupport", true}; + + const std::string testInput = R"(`foo{{bad}}bar`)"; + Luau::Allocator alloc; + AstNameTable table(alloc); + Lexer lexer(testInput.c_str(), testInput.size(), table); + + auto brokenInterpBegin = lexer.next(); + CHECK_EQ(brokenInterpBegin.type, Lexeme::BrokenInterpDoubleBrace); + CHECK_EQ(std::string(brokenInterpBegin.data, brokenInterpBegin.length), std::string("foo")); + + CHECK_EQ(lexer.next().type, Lexeme::Name); + + auto interpEnd = lexer.next(); + CHECK_EQ(interpEnd.type, Lexeme::InterpStringEnd); + CHECK_EQ(std::string(interpEnd.data, interpEnd.length), std::string("}bar")); +} + TEST_CASE("string_interpolation_unmatched_brace") { ScopedFastFlag sff{"LuauInterpolatedStringBaseSupport", true};