diff options
| Commit | 81297e1f7cae13d9620df902ac968046bc646b3a (patch) | |
|---|---|---|
| Author | 2018-10-14 12:58:09 +0300 | |
| Committer | 2018-10-14 12:58:09 +0300 | |
| Files | 8667315b8a2b7b25a27edab46be9d903c74f086f /JSImpl/src | |
| IPL-81297e1f7cae13d9620df902ac968046bc646b3a.tar IPL-81297e1f7cae13d9620df902ac968046bc646b3a.tar.gz IPL-81297e1f7cae13d9620df902ac968046bc646b3a.zip | ||
| Parent | 4e00cd48d86cc10e5b9b8ef413d81c4b94399cfb (diff) | |
Fix parsing of number which start with '9'
3 files changed, 47 insertions, 50 deletions
| -rw-r--r-- | JSImpl/src/Lexer.cpp | 16 | ||||
| -rw-r--r-- | JSImpl/src/Lexer.h | 2 | ||||
| -rw-r--r-- | JSImpl/src/main.cpp | 79 |
diff --git a/JSImpl/src/Lexer.cpp b/JSImpl/src/Lexer.cpp index a6c2bf6..1d9035a 100644 --- a/JSImpl/src/Lexer.cpp +++ b/JSImpl/src/Lexer.cpp @@ -121,12 +121,12 @@ bool Tokenizer::Match(const char c) Token Tokenizer::ProduceToken(TokenType type) { - return { type, m_Line, "" }; + return { type, m_Line, "", 0.0 }; } Token Tokenizer::ProduceToken(TokenType type, IPLString lexeme) { - return{ type, m_Line, lexeme }; + return{ type, m_Line, lexeme, 0.0 }; } namespace @@ -146,7 +146,7 @@ Token Tokenizer::NextToken() { if (m_Code[m_Current] == '\0') { - return Token{ TokenType::Eof, 0, "" }; + return Token{ TokenType::Eof, 0, "", 0.0 }; } while (SkipWhiteSpaces() || SkipNewLine()); @@ -183,7 +183,7 @@ Token Tokenizer::NextToken() } // Number const char c = m_Code[m_Current]; - if (c >= '0' && c < '9') + if (c >= '0' && c <= '9') { size_t parsedBytes = 0; const double number = std::stod(m_Code + m_Current, &parsedBytes); @@ -201,7 +201,7 @@ Token Tokenizer::NextToken() ++m_Current; } m_Current++; // skip second '"' - return Token{ TokenType::String, m_Line, IPLString(m_Code + start, m_Code + m_Current) }; + return Token{ TokenType::String, m_Line, IPLString(m_Code + start, m_Code + m_Current), 0.0 }; } // Key words @@ -217,7 +217,7 @@ Token Tokenizer::NextToken() auto word = m_KeyWordsTable.find(key); if (word != m_KeyWordsTable.end()) { - return Token{ word->second, m_Line, key }; + return Token{ word->second, m_Line, key, 0.0 }; } // It's not a key word so we must revert current counter m_Current = start; @@ -232,8 +232,8 @@ Token Tokenizer::NextToken() { ++m_Current; } - return Token{ TokenType::Identifier, m_Line, IPLString(m_Code + start, m_Code + m_Current) }; + return Token{ TokenType::Identifier, m_Line, IPLString(m_Code + start, m_Code + m_Current), 0.0 }; } // TODO: Error reporting - return Token{ TokenType::Eof, m_Line, "" }; + return Token{ TokenType::Eof, m_Line, "", 0.0 }; } diff --git a/JSImpl/src/Lexer.h b/JSImpl/src/Lexer.h index db07f7d..fd3d244 100644 --- a/JSImpl/src/Lexer.h +++ b/JSImpl/src/Lexer.h @@ -107,7 +107,7 @@ struct Token TokenType Type; unsigned Line; IPLString Lexeme; - double Number = 0.0; + double Number; }; IPLVector<Token> Tokenize(const char* code, const std::function<void()>& onError = {}); diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp index 03880cc..13fdafc 100644 --- a/JSImpl/src/main.cpp +++ b/JSImpl/src/main.cpp @@ -3,75 +3,68 @@ #include <iostream> #define LOG(msg) std::cout << msg << std::endl #define EXECUTE_TEST(test) std::cout << #test << " "; test(); +#define CHECH(cond) if (cond) {LOG("PASS");} else {LOG(#cond " FAIL");} // Lexer Tests void TestLess() { auto tokens = Tokenize("<"); - if (tokens.size() == 2 && tokens[0].Type == TokenType::Less) - { - LOG("PASS"); - } - else - { - LOG("FAIL"); - } + CHECH(tokens.size() == 2 && tokens[0].Type == TokenType::Less); + } void TestNumber() { - auto tokens = Tokenize("213434.24"); - if (tokens.size() == 2 && tokens[0].Type == TokenType::Number && tokens[0].Number == 213434.24) - { - LOG("PASS"); - } - else { - LOG("FAIL"); + auto tokens = Tokenize("213434.24"); + CHECH(tokens.size() == 2 && tokens[0].Type == TokenType::Number && tokens[0].Number == 213434.24) + } + +} + +void TestNumberStartWithNine() +{ + auto tokens = Tokenize("999"); + CHECH(tokens.size() == 2 && tokens[0].Type == TokenType::Number && tokens[0].Number == 999) +} + +void TestNumberStartWithZero() +{ + auto tokens = Tokenize("0999"); + CHECH(tokens.size() == 2 && tokens[0].Type == TokenType::Number && tokens[0].Number == 999) +} + +void TestSpaceNewLineSpace() +{ + auto tokens = Tokenize(" \n var a = 4;"); + CHECH(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); } void TestString() { auto tokens = Tokenize("\"alabala\""); - if (tokens.size() == 2 && tokens[0].Type == TokenType::String && tokens[0].Lexeme == "\"alabala\"") - { - LOG("PASS"); - } - else - { - LOG("FAIL"); - } + CHECH(tokens.size() == 2 && tokens[0].Type == TokenType::String && tokens[0].Lexeme == "\"alabala\""); } void TestKeyWord() { auto tokens = Tokenize("for"); - if (tokens.size() == 2 && tokens[0].Type == TokenType::For) - { - LOG("PASS"); - } - else - { - LOG("FAIL"); - } + CHECH(tokens.size() == 2 && tokens[0].Type == TokenType::For); } void TestVariableDeclaration() { auto tokens = Tokenize("var pesho = 10"); - if (tokens.size() == 5 && tokens[0].Type == TokenType::Var + CHECH(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) - { - LOG("PASS"); - } - else - { - LOG("FAIL"); - } + && tokens[4].Type == TokenType::Eof); } // Parser Tests void TestParseUnaryExpr() @@ -85,10 +78,14 @@ int main() { EXECUTE_TEST(TestLess); EXECUTE_TEST(TestNumber); + EXECUTE_TEST(TestNumberStartWithNine); + EXECUTE_TEST(TestNumberStartWithZero); EXECUTE_TEST(TestString); + EXECUTE_TEST(TestSpaceNewLineSpace); EXECUTE_TEST(TestKeyWord); EXECUTE_TEST(TestVariableDeclaration); - EXECUTE_TEST(TestParseUnaryExpr); + + //EXECUTE_TEST(TestParseUnaryExpr); #if defined(_WIN32) std::system("pause"); #endif |
