Website Summary Files Commits Branches @commit @diff @stats
path: root / JSImpl / src
diff options
context:
space:
mode:
Commit81297e1f7cae13d9620df902ac968046bc646b3a (patch)
Author
 martin dobrev <martindobrev0@gmail.com>
2018-10-14 12:58:09 +0300
Committer
 martin dobrev <martindobrev0@gmail.com>
2018-10-14 12:58:09 +0300
Files8667315b8a2b7b25a27edab46be9d903c74f086f /JSImpl/src
IPL-81297e1f7cae13d9620df902ac968046bc646b3a.tar
IPL-81297e1f7cae13d9620df902ac968046bc646b3a.tar.gz
IPL-81297e1f7cae13d9620df902ac968046bc646b3a.zip
Parent4e00cd48d86cc10e5b9b8ef413d81c4b94399cfb (diff)
Fix parsing of number which start with '9'
3 files changed, 47 insertions, 50 deletions
-rw-r--r--JSImpl/src/Lexer.cpp16
-rw-r--r--JSImpl/src/Lexer.h2
-rw-r--r--JSImpl/src/main.cpp79
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