diff options
| Commit | a7575e08c67ab6e4f3c5a48b302c42a17d2500c2 (patch) | |
|---|---|---|
| Author | 2020-10-12 22:56:16 +0300 | |
| Committer | 2020-10-12 22:56:16 +0300 | |
| Files | ab3caa138c0048a0140af070d0dbbdd0d686f15c /JSImpl | |
| IPL-a7575e08c67ab6e4f3c5a48b302c42a17d2500c2.tar IPL-a7575e08c67ab6e4f3c5a48b302c42a17d2500c2.tar.gz IPL-a7575e08c67ab6e4f3c5a48b302c42a17d2500c2.zip | ||
| Parent | d9183dd25685297d0b9278591b910bb753bc93ed (diff) | |
Add support for new lines and tabs in tokenizer.
Improve tests verbosity.
Replace white spaces with tabs.
6 files changed, 187 insertions, 263 deletions
| -rw-r--r-- | JSImpl/src/Lexer.cpp | 129 | ||||
| -rw-r--r-- | JSImpl/src/Lexer.h | 7 | ||||
| -rw-r--r-- | JSImpl/src/main.cpp | 9 | ||||
| -rw-r--r-- | JSImpl/test/CodeGenerationTests.cpp | 27 | ||||
| -rw-r--r-- | JSImpl/test/LexerTests.cpp | 233 | ||||
| -rw-r--r-- | JSImpl/test/ParserTests.cpp | 45 |
diff --git a/JSImpl/src/Lexer.cpp b/JSImpl/src/Lexer.cpp index dbbf92d..8607480 100644 --- a/JSImpl/src/Lexer.cpp +++ b/JSImpl/src/Lexer.cpp @@ -35,7 +35,7 @@ inline bool IsStringBound(char c) inline bool IsWhiteSpace(char c) { - return c == ' ' || c == '\t'; + return c == ' '; } inline bool IsNewLine(char c) @@ -72,7 +72,7 @@ class Tokenizer { public: Tokenizer(const char* code, const LexerSettings& settings); - LexerResult Tokenize(IPLVector<Token>& tokens); + LexerResult Tokenize(); private: Token NextToken(); @@ -81,9 +81,11 @@ private: inline Token ProduceToken(TokenType type); inline Token ProduceToken(TokenType type, IPLString lexeme, double number); inline Token ProduceErrorToken(); + inline Token ProduceInvalidToken(); + + bool FilterToken(TokenType type); IPLString ParseComment(); - IPLString ParseWhitespaces(); double ParseNumber(); IPLString ParseString(); Keyword ParseKeyword(); @@ -94,8 +96,6 @@ private: void SetError(const IPLString& what); - bool SkipWhiteSpaces(); - bool SkipNewLine(); bool Match(const char c); inline void NextSymbol(); @@ -112,21 +112,19 @@ private: State m_GenerationState; LexerSettings m_Settings; - bool m_SkipNextToken; IPLUnorderedMap<IPLString, TokenType> m_KeyWordsTable; }; -LexerResult Tokenize(const char* code, IPLVector<Token>& tokens, const LexerSettings& settings) +LexerResult Tokenize(const char* code, const LexerSettings& settings) { Tokenizer tokenizer(code, settings); - - return tokenizer.Tokenize(tokens); + return tokenizer.Tokenize(); } -LexerResult Tokenize(const char * code, IPLVector<Token>& tokens) +LexerResult Tokenize(const char * code) { - return Tokenize(code, tokens, { false, false }); + return Tokenize(code, { false, false }); } Tokenizer::Tokenizer(const char* code, const LexerSettings& settings) @@ -138,7 +136,6 @@ Tokenizer::Tokenizer(const char* code, const LexerSettings& settings) , m_Error() , m_GenerationState(State::Success) , m_Settings(settings) - , m_SkipNextToken(false) { m_KeyWordsTable["break"] = TokenType::Break; m_KeyWordsTable["case"] = TokenType::Case; @@ -180,60 +177,49 @@ Tokenizer::Tokenizer(const char* code, const LexerSettings& settings) m_KeyWordsTable["false"] = TokenType::False; } -LexerResult Tokenizer::Tokenize(IPLVector<Token>& tokens) +LexerResult Tokenizer::Tokenize() { + LexerResult result{ true, IPLError() }; + Token token; do { - Token token; - do - { - token = NextToken(); - } while (m_SkipNextToken); + token = NextToken(); if (m_GenerationState == State::Error) { - return LexerResult{ false, IPLError(m_Error) }; + result.IsSuccessful = false; + result.Error = IPLError(m_Error); + return result; } + if (FilterToken(token.Type)) + { + result.tokens.emplace_back(token); + } + } while (token.Type != TokenType::Eof); - tokens.emplace_back(token); - } while (tokens.back().Type != TokenType::Eof); - - return LexerResult{ true, IPLError() }; + return result; } -bool Tokenizer::SkipWhiteSpaces() +bool Tokenizer::FilterToken(TokenType type) { - const auto old = m_Current; - while (IsWhiteSpace(m_Code[m_Current])) + if (type == TokenType::Comment) { - NextSymbol(); + return m_Settings.CreateCommentTokens; } - return old != m_Current; -} - -bool Tokenizer::SkipNewLine() -{ - const auto old = m_Current; - while (IsNewLine(m_Code[m_Current])) + else if (type == TokenType::Whitespace || + type == TokenType::Tab || + type == TokenType::NewLine) { - NextLine(); + return m_Settings.CreateWhitespaceTokens; } - return old != m_Current; + return true; } bool Tokenizer::Match(const char c) { if (c == m_Code[m_Current]) { - if (!IsNewLine(m_Code[m_Current])) - { - NextSymbol(); - } - else - { - NextLine(); - } - + NextSymbol(); return true; } return false; @@ -359,6 +345,11 @@ inline Token Tokenizer::ProduceErrorToken() return ProduceToken(TokenType::Invalid, ""); } +inline Token Tokenizer::ProduceInvalidToken() +{ + return ProduceToken(TokenType::Invalid, ""); +} + IPLString Tokenizer::ParseComment() { auto start = m_Current; @@ -395,33 +386,6 @@ IPLString Tokenizer::ParseComment() RETURN_ERROR(IPLString()); } -IPLString Tokenizer::ParseWhitespaces() -{ - if (!IsWhiteSpace(m_Code[m_Current]) && !IsNewLine(m_Code[m_Current])) - { - RETURN_FAIL(IPLString()); - } - - auto start = m_Current; - while (1) - { - if (IsWhiteSpace(m_Code[m_Current])) - { - NextSymbol(); - } - else if (IsNewLine(m_Code[m_Current])) - { - NextLine(); - } - else - { - break; - } - } - - RETURN_SUCCESS(IPLString(m_Code + start, m_Code + m_Current)); -} - double Tokenizer::ParseNumber() { if (!IsDigit(m_Code[m_Current])) @@ -531,8 +495,6 @@ void Tokenizer::SetError(const IPLString& what) Token Tokenizer::NextToken() { - m_SkipNextToken = false; - if (IsEnd(m_Code[m_Current])) { return ProduceToken(TokenType::Eof); @@ -545,25 +507,9 @@ Token Tokenizer::NextToken() } if (IsStateSuccess()) { - if (!m_Settings.CreateCommentTokens) - { - m_SkipNextToken = true; - return ProduceSkipToken(); - } return ProduceToken(TokenType::Comment, comment); } - const auto& spaces = ParseWhitespaces(); - if (IsStateSuccess()) - { - if (!m_Settings.CreateWhitespaceTokens) - { - m_SkipNextToken = true; - return ProduceSkipToken(); - } - return ProduceToken(TokenType::Whitespace, spaces); - } - // Single Char switch (m_Code[m_Current]) { @@ -592,6 +538,9 @@ Token Tokenizer::NextToken() case '[': NextSymbol(); return ProduceToken(TokenType::LeftSquareBracket); case ']': NextSymbol(); return ProduceToken(TokenType::RightSquareBracket); case '\\': NextSymbol(); return ProduceToken(TokenType::Backslash); + case '\n': NextLine(); return ProduceToken(TokenType::NewLine); + case ' ': NextSymbol(); return ProduceToken(TokenType::Whitespace); + case '\t': NextSymbol(); return ProduceToken(TokenType::Tab); default: break; } diff --git a/JSImpl/src/Lexer.h b/JSImpl/src/Lexer.h index 3c0c785..00acc7a 100644 --- a/JSImpl/src/Lexer.h +++ b/JSImpl/src/Lexer.h @@ -100,6 +100,8 @@ enum class TokenType False, Whitespace, + Tab, + NewLine, Comment, Eof, @@ -119,6 +121,7 @@ struct LexerResult { bool IsSuccessful; IPLError Error; + IPLVector<Token> tokens; }; struct LexerSettings @@ -127,5 +130,5 @@ struct LexerSettings bool CreateCommentTokens; }; -LexerResult Tokenize(const char* code, IPLVector<Token>& tokens, const LexerSettings& settings); -LexerResult Tokenize(const char* code, IPLVector<Token>& tokens);
\ No newline at end of file +LexerResult Tokenize(const char* code, const LexerSettings& settings); +LexerResult Tokenize(const char* code);
\ No newline at end of file diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp index 90f6023..ef5ac1b 100644 --- a/JSImpl/src/main.cpp +++ b/JSImpl/src/main.cpp @@ -15,9 +15,8 @@ void RunParseCalc() { - IPLVector<Token> tokens; //Tokenize("var a = 0; var b = a + 123;a+b;", tokens); - Tokenize("var a = 5; if(a == 5){a++;}", tokens); + auto tokens = Tokenize("var a = 5; if(a == 5){a++;}").tokens; // TODO make actual test :D auto expr = Parse(tokens); @@ -60,8 +59,7 @@ void InteractiveInterpreter() i.Print(p); continue; } - IPLVector<Token> tokens; - Tokenize(command, tokens); + auto tokens = Tokenize(command).tokens; auto result = i.Run(Parse(tokens).get()); while (!result.empty()) { std::cout << result.back() << std::endl; @@ -72,7 +70,6 @@ void InteractiveInterpreter() void Generate() { - IPLVector<Token> tokens; //Tokenize("var a = 0; var b = a + 123;a+b;", tokens); /*Tokenize("var a; if(a < 4) { a = 8; if(a < 7) {var b = 4;}} else { a = 2} ", tokens);*/ IPLString source = "var i = 0; \n" @@ -80,7 +77,7 @@ void Generate() "{\n" " i = i + j;\n" "}"; - Tokenize(source.c_str(), tokens); + auto tokens = Tokenize(source.c_str()).tokens; auto asmb = GenerateByteCode(Parse(tokens), source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, true)); diff --git a/JSImpl/test/CodeGenerationTests.cpp b/JSImpl/test/CodeGenerationTests.cpp index d341562..a6ebc6e 100644 --- a/JSImpl/test/CodeGenerationTests.cpp +++ b/JSImpl/test/CodeGenerationTests.cpp @@ -9,9 +9,8 @@ TEST(CodeGen, Empty) { - IPLVector<Token> tokens; IPLString source = ""; - Tokenize(source.c_str(), tokens); + IPLVector<Token> tokens = Tokenize(source.c_str()).tokens; auto ast = Parse(tokens); auto asmb = GenerateByteCode(ast, source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); @@ -23,9 +22,8 @@ TEST(CodeGen, Empty) TEST(CodeGen, VarDeclations) { - IPLVector<Token> tokens; IPLString source = "var a;"; - Tokenize(source.c_str(), tokens); + IPLVector<Token> tokens = Tokenize(source.c_str()).tokens; auto ast = Parse(tokens); auto asmb = GenerateByteCode(ast, source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); @@ -37,9 +35,8 @@ TEST(CodeGen, VarDeclations) TEST(CodeGen, VarDeclationsWithValue) { - IPLVector<Token> tokens; IPLString source = "var a = 5;"; - Tokenize(source.c_str(), tokens); + IPLVector<Token> tokens = Tokenize(source.c_str()).tokens; auto ast = Parse(tokens); auto asmb = GenerateByteCode(ast, source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); @@ -53,9 +50,8 @@ TEST(CodeGen, VarDeclationsWithValue) TEST(CodeGen, VarDeclationsBinaryExpre) { - IPLVector<Token> tokens; IPLString source = "var a = 5 + 6;"; - Tokenize(source.c_str(), tokens); + IPLVector<Token> tokens = Tokenize(source.c_str()).tokens; auto ast = Parse(tokens); auto asmb = GenerateByteCode(ast, source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); @@ -72,9 +68,8 @@ TEST(CodeGen, VarDeclationsBinaryExpre) TEST(CodeGen, VariableAssignment) { - IPLVector<Token> tokens; IPLString source = "var a; a = 5;"; - Tokenize(source.c_str(), tokens); + IPLVector<Token> tokens = Tokenize(source.c_str()).tokens; auto ast = Parse(tokens); auto asmb = GenerateByteCode(ast, source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); @@ -89,9 +84,8 @@ TEST(CodeGen, VariableAssignment) TEST(CodeGen, MultiVariableAssignment) { - IPLVector<Token> tokens; IPLString source = "var a; var b = 6; a = b;"; - Tokenize(source.c_str(), tokens); + IPLVector<Token> tokens = Tokenize(source.c_str()).tokens; auto ast = Parse(tokens); auto asmb = GenerateByteCode(ast, source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); @@ -107,9 +101,8 @@ TEST(CodeGen, MultiVariableAssignment) TEST(CodeGen, SimpleIf) { - IPLVector<Token> tokens; IPLString source = "var a = 5; if (a < 1) { a = 7}"; - Tokenize(source.c_str(), tokens); + IPLVector<Token> tokens = Tokenize(source.c_str()).tokens; auto ast = Parse(tokens); auto asmb = GenerateByteCode(ast, source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); @@ -129,9 +122,8 @@ TEST(CodeGen, SimpleIf) TEST(CodeGen, SimpleIfElse) { - IPLVector<Token> tokens; IPLString source = "var a = 5; if (a < 1) { a = 3; } else { a = 7; }"; - Tokenize(source.c_str(), tokens); + IPLVector<Token> tokens = Tokenize(source.c_str()).tokens; auto ast = Parse(tokens); auto asmb = GenerateByteCode(ast, source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); @@ -154,9 +146,8 @@ TEST(CodeGen, SimpleIfElse) TEST(CodeGen, SimpleFor) { - IPLVector<Token> tokens; IPLString source = "var a = 0; for (var i = 0; i < 5; i++ ){ a = a + i; }"; - Tokenize(source.c_str(), tokens); + IPLVector<Token> tokens = Tokenize(source.c_str()).tokens; auto ast = Parse(tokens); auto asmb = GenerateByteCode(ast, source, ByteCodeGeneratorOptions(ByteCodeGeneratorOptions::OptimizationsType::None, false)); diff --git a/JSImpl/test/LexerTests.cpp b/JSImpl/test/LexerTests.cpp index 2f13916..a1a25d3 100644 --- a/JSImpl/test/LexerTests.cpp +++ b/JSImpl/test/LexerTests.cpp @@ -5,211 +5,210 @@ TEST(Lexer, Less) { - IPLVector<Token> tokens; - Tokenize("<", tokens); + IPLVector<Token> tokens = Tokenize("<").tokens; ASSERT_EQ(tokens.size(), 2u); - ASSERT_EQ(tokens[0].Type, TokenType::Less); + ASSERT_EQ(tokens[0].Type, TokenType::Less); } TEST(Lexer, Number) { - IPLVector<Token> tokens; - Tokenize("213434.24", tokens); + IPLVector<Token> tokens = Tokenize("213434.24").tokens; ASSERT_EQ(tokens.size(), 2u); - ASSERT_EQ(tokens[0].Type, TokenType::Number); - ASSERT_EQ(tokens[0].Number, 213434.24); + ASSERT_EQ(tokens[0].Type, TokenType::Number); + ASSERT_EQ(tokens[0].Number, 213434.24); } TEST(Lexer, HexNumber) { - IPLVector<Token> tokens; - auto result = Tokenize("0x10", tokens); + const auto res = Tokenize("0x10"); + const auto& tokens = res.tokens; - ASSERT_TRUE(result.IsSuccessful); + ASSERT_TRUE(res.IsSuccessful); ASSERT_EQ(tokens.size(), 2u); - ASSERT_EQ(tokens[0].Type, TokenType::Number); - ASSERT_EQ(tokens[0].Number, 16); + ASSERT_EQ(tokens[0].Type, TokenType::Number); + ASSERT_EQ(tokens[0].Number, 16); } TEST(Lexer, ScientificNotationNumber) { - IPLVector<Token> tokens; - auto result = Tokenize("1e2", tokens); + const auto res = Tokenize("1e2"); + const auto& tokens = res.tokens; - ASSERT_TRUE(result.IsSuccessful); + ASSERT_TRUE(res.IsSuccessful); ASSERT_EQ(tokens.size(), 2u); - ASSERT_EQ(tokens[0].Type, TokenType::Number); - ASSERT_EQ(tokens[0].Number, 100); + ASSERT_EQ(tokens[0].Type, TokenType::Number); + ASSERT_EQ(tokens[0].Number, 100); } TEST(Lexer, NumberStartWithNine) { - IPLVector<Token> tokens; - Tokenize("999", tokens); + IPLVector<Token> tokens = Tokenize("999").tokens; ASSERT_EQ(tokens.size(), 2u); - ASSERT_EQ(tokens[0].Type, TokenType::Number); - ASSERT_EQ(tokens[0].Number, 999); + ASSERT_EQ(tokens[0].Type, TokenType::Number); + ASSERT_EQ(tokens[0].Number, 999); } TEST(Lexer, NumberStartWithZero) { - IPLVector<Token> tokens; - Tokenize("0999", tokens); + IPLVector<Token> tokens = Tokenize("0999").tokens; ASSERT_EQ(tokens.size(), 2u); - ASSERT_EQ(tokens[0].Type, TokenType::Number); - ASSERT_EQ(tokens[0].Number, 999); + ASSERT_EQ(tokens[0].Type, TokenType::Number); + ASSERT_EQ(tokens[0].Number, 999); } TEST(Lexer, SpaceNewLineSpace) { - IPLVector<Token> tokens; - Tokenize(" \n var a = 4; ", tokens); - ASSERT_TRUE(tokens.size() == 6 && tokens[0].Type == TokenType::Var && - tokens[1].Type == TokenType::Identifier && - tokens[2].Type == TokenType::Equal && - tokens[3].Type == TokenType::Number && - tokens[4].Type == TokenType::Semicolon); + IPLVector<Token> tokens = Tokenize(" \n var a = 4; ").tokens; + ASSERT_TRUE(tokens.size() == 6 && tokens[0].Type == TokenType::Var); + ASSERT_TRUE(tokens[1].Type == TokenType::Identifier); + ASSERT_TRUE(tokens[2].Type == TokenType::Equal); + ASSERT_TRUE(tokens[3].Type == TokenType::Number); + ASSERT_TRUE(tokens[4].Type == TokenType::Semicolon); } TEST(Lexer, String) { - IPLVector<Token> tokens; - Tokenize("\"alabala\"", tokens); + IPLVector<Token> tokens = Tokenize("\"alabala\"").tokens; ASSERT_TRUE(tokens.size() == 2 && tokens[0].Type == TokenType::String - && tokens[0].Lexeme == "\"alabala\""); + && tokens[0].Lexeme == "\"alabala\""); } TEST(Lexer, StringSingleQuotedStrings) { - IPLVector<Token> tokens; - Tokenize("'alabala'", tokens); + IPLVector<Token> tokens = Tokenize("'alabala'").tokens; ASSERT_TRUE(tokens.size() == 2 && tokens[0].Type == TokenType::String && tokens[0].Lexeme == "'alabala'"); } TEST(Lexer, KeyWord) { - IPLVector<Token> tokens; - Tokenize("for", tokens); + IPLVector<Token> tokens = Tokenize("for").tokens; ASSERT_TRUE(tokens.size() == 2 && tokens[0].Type == TokenType::For); } TEST(Lexer, VariableDeclaration) { - IPLVector<Token> tokens; - Tokenize("var pesho = 10", tokens); + IPLVector<Token> tokens = Tokenize("var pesho = 10").tokens; - ASSERT_TRUE(tokens.size() == 5 && tokens[0].Type == TokenType::Var - && tokens[1].Type == TokenType::Identifier - && tokens[2].Type == TokenType::Equal - && tokens[3].Type == TokenType::Number - && tokens[4].Type == TokenType::Eof); + ASSERT_TRUE(tokens.size() == 5 && tokens[0].Type == TokenType::Var); + ASSERT_TRUE(tokens[1].Type == TokenType::Identifier); + ASSERT_TRUE(tokens[2].Type == TokenType::Equal); + ASSERT_TRUE(tokens[3].Type == TokenType::Number); + ASSERT_TRUE(tokens[4].Type == TokenType::Eof); } TEST(Lexer, StringError) { - IPLVector<Token> tokens; - const auto& res = Tokenize("\" aaaa", tokens); + const auto res = Tokenize("\" aaaa"); ASSERT_TRUE(!res.IsSuccessful && res.Error.Row == 0 && res.Error.Column == 6); } TEST(Lexer, TestWhiteSpaceTokens) { - IPLVector<Token> tokens; - const auto& res = Tokenize(" 1\n2 abc\n \n", tokens, { true, false }); - ASSERT_TRUE(res.IsSuccessful - && tokens.size() == 8 - && tokens[0].Type == TokenType::Whitespace - && tokens[0].Lexeme == " " - && tokens[1].Type == TokenType::Number - && tokens[1].Number == 1 - && tokens[2].Type == TokenType::Whitespace - && tokens[2].Lexeme == "\n" - && tokens[3].Type == TokenType::Number - && tokens[3].Number == 2 - && tokens[4].Type == TokenType::Whitespace - && tokens[4].Lexeme == " " - && tokens[5].Type == TokenType::Identifier - && tokens[5].Lexeme == "abc" - && tokens[6].Type == TokenType::Whitespace - && tokens[6].Lexeme == "\n \n" - && tokens[7].Type == TokenType::Eof); + const auto res = Tokenize(" 1\n2 abc\n \n", { true, false }); + const auto& tokens = res.tokens; + ASSERT_TRUE(res.IsSuccessful); + ASSERT_TRUE(tokens.size() == 11); + ASSERT_TRUE(tokens[0].Type == TokenType::Whitespace); + ASSERT_TRUE(tokens[0].Lexeme == ""); + ASSERT_TRUE(tokens[1].Type == TokenType::Number); + ASSERT_TRUE(tokens[1].Number == 1); + ASSERT_TRUE(tokens[2].Type == TokenType::NewLine); + ASSERT_TRUE(tokens[2].Lexeme == ""); + ASSERT_TRUE(tokens[3].Type == TokenType::Number); + ASSERT_TRUE(tokens[3].Number == 2); + ASSERT_TRUE(tokens[4].Type == TokenType::Whitespace); + ASSERT_TRUE(tokens[4].Lexeme == ""); + ASSERT_TRUE(tokens[5].Type == TokenType::Whitespace); + ASSERT_TRUE(tokens[5].Lexeme == ""); + ASSERT_TRUE(tokens[6].Type == TokenType::Identifier); + ASSERT_TRUE(tokens[6].Lexeme == "abc"); + ASSERT_TRUE(tokens[7].Type == TokenType::NewLine); + ASSERT_TRUE(tokens[7].Lexeme == ""); + ASSERT_TRUE(tokens[8].Type == TokenType::Whitespace); + ASSERT_TRUE(tokens[8].Lexeme == ""); + ASSERT_TRUE(tokens[9].Type == TokenType::NewLine); + ASSERT_TRUE(tokens[9].Lexeme == ""); + ASSERT_TRUE(tokens[10].Type == TokenType::Eof); } TEST(Lexer, SimpleComment) { - IPLVector<Token> tokens; - const auto& res = Tokenize("//comment", tokens, { false, true }); - ASSERT_TRUE(res.IsSuccessful - && tokens.size() == 2 - && tokens[0].Type == TokenType::Comment - && tokens[0].Lexeme == "//comment" - && tokens[1].Type == TokenType::Eof); + const auto res = Tokenize("//comment", { false, true }); + const auto& tokens = res.tokens; + ASSERT_TRUE(res.IsSuccessful); + ASSERT_TRUE(tokens.size() == 2); + ASSERT_TRUE(tokens[0].Type == TokenType::Comment); + ASSERT_TRUE(tokens[0].Lexeme == "//comment"); + ASSERT_TRUE(tokens[1].Type == TokenType::Eof); } TEST(Lexer, SimpleMultiLineComment) { - IPLVector<Token> tokens; - const auto& res = Tokenize("/*comment\ncomment*/", tokens, { false, true }); - ASSERT_TRUE(res.IsSuccessful - && tokens.size() == 2 - && tokens[0].Type == TokenType::Comment - && tokens[0].Lexeme == "/*comment\ncomment*/" - && tokens[1].Type == TokenType::Eof); + const auto res = Tokenize("/*comment\ncomment*/", { false, true }); + const auto& tokens = res.tokens; + ASSERT_TRUE(res.IsSuccessful); + ASSERT_TRUE(tokens.size() == 2); + ASSERT_TRUE(tokens[0].Type == TokenType::Comment); + ASSERT_TRUE(tokens[0].Lexeme == "/*comment\ncomment*/"); + ASSERT_TRUE(tokens[1].Type == TokenType::Eof); } TEST(Lexer, ConsecutiveMultiLineComment) { - IPLVector<Token> tokens; - const auto& res = Tokenize("/*comment1\ncomment1*//*comment2\ncomment2*/", tokens, { false, true }); - ASSERT_TRUE(res.IsSuccessful - && tokens.size() == 3 - && tokens[0].Type == TokenType::Comment - && tokens[0].Lexeme == "/*comment1\ncomment1*/" - && tokens[1].Type == TokenType::Comment - && tokens[1].Lexeme == "/*comment2\ncomment2*/" - && tokens[2].Type == TokenType::Eof); + const auto res = Tokenize("/*comment1\ncomment1*//*comment2\ncomment2*/", { false, true }); + const auto& tokens = res.tokens; + ASSERT_TRUE(res.IsSuccessful); + ASSERT_TRUE(tokens.size() == 3); + ASSERT_TRUE(tokens[0].Type == TokenType::Comment); + ASSERT_TRUE(tokens[0].Lexeme == "/*comment1\ncomment1*/"); + ASSERT_TRUE(tokens[1].Type == TokenType::Comment); + ASSERT_TRUE(tokens[1].Lexeme == "/*comment2\ncomment2*/"); + ASSERT_TRUE(tokens[2].Type == TokenType::Eof); } TEST(Lexer, ConsecutiveMultiLineCommentWithSpace) { - IPLVector<Token> tokens; - const auto& res = Tokenize("/*comment1\ncomment1*/\n\n\n/*comment2\ncomment2*/", tokens, { false, true }); - ASSERT_TRUE(res.IsSuccessful - && tokens.size() == 3 - && tokens[0].Type == TokenType::Comment - && tokens[0].Lexeme == "/*comment1\ncomment1*/" - && tokens[1].Type == TokenType::Comment - && tokens[1].Lexeme == "/*comment2\ncomment2*/" - && tokens[2].Type == TokenType::Eof); + const auto res = Tokenize("/*comment1\ncomment1*/\n\n\n/*comment2\ncomment2*/", { false, true }); + const auto& tokens = res.tokens; + ASSERT_TRUE(res.IsSuccessful); + ASSERT_TRUE(tokens.size() == 3); + ASSERT_TRUE(tokens[0].Type == TokenType::Comment); + ASSERT_TRUE(tokens[0].Lexeme == "/*comment1\ncomment1*/"); + ASSERT_TRUE(tokens[1].Type == TokenType::Comment); + ASSERT_TRUE(tokens[1].Lexeme == "/*comment2\ncomment2*/"); + ASSERT_TRUE(tokens[2].Type == TokenType::Eof); } TEST(Lexer, ConsecutiveMultiLineCommentWithSpaceWithTokens) { - IPLVector<Token> tokens; - const auto& res = Tokenize("//comment1\n/*comment2\ncomment2*/\n\n\n/*comment3\ncomment3*/", tokens, { true, true }); - ASSERT_TRUE(res.IsSuccessful - && tokens.size() == 6 - && tokens[0].Type == TokenType::Comment - && tokens[0].Lexeme == "//comment1" - && tokens[1].Type == TokenType::Whitespace - && tokens[1].Lexeme == "\n" - && tokens[2].Type == TokenType::Comment - && tokens[2].Lexeme == "/*comment2\ncomment2*/" - && tokens[3].Type == TokenType::Whitespace - && tokens[3].Lexeme == "\n\n\n" - && tokens[4].Type == TokenType::Comment - && tokens[4].Lexeme == "/*comment3\ncomment3*/" - && tokens[5].Type == TokenType::Eof); + const auto res = Tokenize("//comment1\n/*comment2\ncomment2*/\n\n\n/*comment3\ncomment3*/", { true, true }); + const auto& tokens = res.tokens; + ASSERT_TRUE(res.IsSuccessful); + ASSERT_TRUE(tokens.size() == 8); + ASSERT_TRUE(tokens[0].Type == TokenType::Comment); + ASSERT_TRUE(tokens[0].Lexeme == "//comment1"); + ASSERT_TRUE(tokens[1].Type == TokenType::NewLine); + ASSERT_TRUE(tokens[1].Lexeme == ""); + ASSERT_TRUE(tokens[2].Type == TokenType::Comment); + ASSERT_TRUE(tokens[2].Lexeme == "/*comment2\ncomment2*/"); + ASSERT_TRUE(tokens[3].Type == TokenType::NewLine); + ASSERT_TRUE(tokens[3].Lexeme == ""); + ASSERT_TRUE(tokens[4].Type == TokenType::NewLine); + ASSERT_TRUE(tokens[4].Lexeme == ""); + ASSERT_TRUE(tokens[5].Type == TokenType::NewLine); + ASSERT_TRUE(tokens[5].Lexeme == ""); + ASSERT_TRUE(tokens[6].Type == TokenType::Comment); + ASSERT_TRUE(tokens[6].Lexeme == "/*comment3\ncomment3*/"); + ASSERT_TRUE(tokens[7].Type == TokenType::Eof); } TEST(Lexer, CommentError) { - IPLVector<Token> tokens; - const auto& res = Tokenize(" aa\n /*", tokens); + auto res = Tokenize(" aa\n /*"); ASSERT_TRUE(!res.IsSuccessful && res.Error.Row == 1 && - res.Error.Column == 3); + res.Error.Column == 3); } diff --git a/JSImpl/test/ParserTests.cpp b/JSImpl/test/ParserTests.cpp index a5b0c99..91534c5 100644 --- a/JSImpl/test/ParserTests.cpp +++ b/JSImpl/test/ParserTests.cpp @@ -10,8 +10,7 @@ TEST(Parser, ParseUnaryExpr) { - IPLVector<Token> tokens; - Tokenize("function pesho() { var a = 0; return a; } var a = \"3\";", tokens); + IPLVector<Token> tokens = Tokenize("function pesho() { var a = 0; return a; } var a = \"3\";").tokens; // TODO make actual test :D auto expr = Parse(tokens); @@ -23,8 +22,7 @@ TEST(Parser, ParseUnaryExpr) TEST(Parser, VariableDeclaration) { - IPLVector<Token> tokens; - Tokenize("var s = 0;", tokens); + IPLVector<Token> tokens = Tokenize("var s = 0;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -36,8 +34,7 @@ TEST(Parser, VariableDeclaration) TEST(Parser, Assignment) { - IPLVector<Token> tokens; - Tokenize("var s = 0; s = 100;", tokens); + IPLVector<Token> tokens = Tokenize("var s = 0; s = 100;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -49,8 +46,7 @@ TEST(Parser, Assignment) TEST(Parser, VariableDeclarationAdditionOfLiterals) { - IPLVector<Token> tokens; - Tokenize("var s = 5 + 6;", tokens); + IPLVector<Token> tokens = Tokenize("var s = 5 + 6;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -62,8 +58,7 @@ TEST(Parser, VariableDeclarationAdditionOfLiterals) TEST(Parser, VariableDeclarationAdditionOfVariables) { - IPLVector<Token> tokens; - Tokenize("var a = 5; var b = 4; var c = a + b;", tokens); + IPLVector<Token> tokens = Tokenize("var a = 5; var b = 4; var c = a + b;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -79,8 +74,7 @@ TEST(Parser, VariableDeclarationAdditionOfVariables) TEST(Parser, VariableDeclarationMultiplicationOfLiterals) { - IPLVector<Token> tokens; - Tokenize("var s = 5 * 6;", tokens); + IPLVector<Token> tokens = Tokenize("var s = 5 * 6;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -92,8 +86,7 @@ TEST(Parser, VariableDeclarationMultiplicationOfLiterals) TEST(Parser, VariableDeclarationMultiplicationOfVariables) { - IPLVector<Token> tokens; - Tokenize("var a = 5; var b = 4; var c = a * b;", tokens); + IPLVector<Token> tokens = Tokenize("var a = 5; var b = 4; var c = a * b;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -110,8 +103,7 @@ TEST(Parser, VariableDeclarationMultiplicationOfVariables) TEST(Parser, Unary) { - IPLVector<Token> tokens; - Tokenize("var a = 5; a++; var b = 6; --b;", tokens); + IPLVector<Token> tokens = Tokenize("var a = 5; a++; var b = 6; --b;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -127,8 +119,7 @@ TEST(Parser, Unary) TEST(Parser, If) { { - IPLVector<Token> tokens; - Tokenize("var a = 5; var b = 3; if(a == 5){a++; b++;} b++;", tokens); + IPLVector<Token> tokens = Tokenize("var a = 5; var b = 3; if(a == 5){a++; b++;} b++;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -140,8 +131,7 @@ TEST(Parser, If) ASSERT_DOUBLE_EQ(i.ModifyVariable("b"), 5.0); } { - IPLVector<Token> tokens; - Tokenize("var a = 5; var b = 3; if(a == 5)a++; b++; b++;", tokens); + IPLVector<Token> tokens = Tokenize("var a = 5; var b = 3; if(a == 5)a++; b++; b++;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -154,8 +144,7 @@ TEST(Parser, If) } { - IPLVector<Token> tokens; - Tokenize("var a = 5; var b = 3; if(a != 5)a++; b++; b++;", tokens); + IPLVector<Token> tokens = Tokenize("var a = 5; var b = 3; if(a != 5)a++; b++; b++;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -168,8 +157,7 @@ TEST(Parser, If) } { - IPLVector<Token> tokens; - Tokenize("var a = 5; var b = 3; if(a != 5){a++;} else { b++;}b++;", tokens); + IPLVector<Token> tokens = Tokenize("var a = 5; var b = 3; if(a != 5){a++;} else { b++;}b++;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -182,8 +170,7 @@ TEST(Parser, If) } { - IPLVector<Token> tokens; - Tokenize("var a = 5; var b = 3; if(a == 5){a++;} else { b++;}b++;", tokens); + IPLVector<Token> tokens = Tokenize("var a = 5; var b = 3; if(a == 5){a++;} else { b++;}b++;").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -199,8 +186,7 @@ TEST(Parser, If) TEST(Parser, For) { { - IPLVector<Token> tokens; - Tokenize("var i = 0; for (var j = 0; j < 10; j++) { i = i + j; }", tokens); + IPLVector<Token> tokens = Tokenize("var i = 0; for (var j = 0; j < 10; j++) { i = i + j; }").tokens; auto expr = Parse(tokens); std::ostringstream output; @@ -210,8 +196,7 @@ TEST(Parser, For) ASSERT_DOUBLE_EQ(i.ModifyVariable("i"), 45.0); } { - IPLVector<Token> tokens; - Tokenize("var i = 0; for (var j = 0; j < 10; j++) i = i + j;", tokens); + IPLVector<Token> tokens = Tokenize("var i = 0; for (var j = 0; j < 10; j++) i = i + j;").tokens; auto expr = Parse(tokens); std::ostringstream output; ASTInterpreter i; |
