2019-05-21 15:16:53 +00:00
|
|
|
|
2019-05-21 15:23:56 +00:00
|
|
|
|
2019-05-21 15:16:53 +00:00
|
|
|
#ifdef TESTS_BUILD
|
|
|
|
#include <catch.hpp>
|
2019-05-21 15:23:56 +00:00
|
|
|
#include "../../src/Parser/Parser.hpp"
|
2019-05-21 15:16:53 +00:00
|
|
|
|
|
|
|
TEST_CASE( "Parse single true keyword", "[parser]" ) {
|
|
|
|
vector<IToken*> v {new SimpleToken(TokenKind::TrueKeyword,0,0), new SimpleToken(TokenKind::EndOfFile,0,0)};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Expression);
|
|
|
|
auto expression = ((ParsedExpressionStatement*)firstStatement)->GetExpression();
|
|
|
|
REQUIRE(expression -> GetKind() == ParsedExpressionKind::LiteralBool);
|
|
|
|
auto boolean = ((LiteralBoolExpression*)expression);
|
|
|
|
REQUIRE(boolean->GetValue() == true);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE( "Parse single false keyword", "[parser]" ) {
|
|
|
|
vector<IToken*> v {new SimpleToken(TokenKind::FalseKeyword,0,0), new SimpleToken(TokenKind::EndOfFile,0,0)};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Expression);
|
|
|
|
auto expression = ((ParsedExpressionStatement*)firstStatement)->GetExpression();
|
|
|
|
REQUIRE(expression -> GetKind() == ParsedExpressionKind::LiteralBool);
|
|
|
|
auto boolean = ((LiteralBoolExpression*)expression);
|
|
|
|
REQUIRE(boolean->GetValue() == false);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE( "Parse simple addition", "[parser]" ) {
|
|
|
|
vector<IToken*> v {
|
|
|
|
new IntegerToken(5, 0, 0),
|
|
|
|
new SimpleToken(TokenKind::PlusToken,0,0),
|
|
|
|
new IntegerToken(10, 0, 0),
|
|
|
|
new SimpleToken(TokenKind::EndOfFile,0,0)
|
|
|
|
};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Expression);
|
|
|
|
auto expression = ((ParsedExpressionStatement*)firstStatement)->GetExpression();
|
|
|
|
REQUIRE(expression -> GetKind() == ParsedExpressionKind::Binary);
|
|
|
|
auto binary = ((BinaryExpression*)expression);
|
|
|
|
CHECK(binary -> GetOperatorKind() == BinaryOperatorKind::Addition);
|
|
|
|
auto left = binary->GetLeft();
|
|
|
|
auto right = binary->GetRight();
|
|
|
|
REQUIRE(left->GetKind() == ParsedExpressionKind::LiteralInteger);
|
|
|
|
REQUIRE(right->GetKind() == ParsedExpressionKind::LiteralInteger);
|
|
|
|
CHECK(((LiteralIntegerExpression*)left)->GetValue() == 5);
|
|
|
|
CHECK(((LiteralIntegerExpression*)right)->GetValue() == 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE( "Parse simple negation", "[parser]" ) {
|
|
|
|
vector<IToken*> v {
|
|
|
|
new SimpleToken(TokenKind::MinusToken,0,0),
|
|
|
|
new IntegerToken(10, 0, 0),
|
|
|
|
new SimpleToken(TokenKind::EndOfFile,0,0)
|
|
|
|
};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Expression);
|
|
|
|
auto expression = ((ParsedExpressionStatement*)firstStatement)->GetExpression();
|
|
|
|
REQUIRE(expression -> GetKind() == ParsedExpressionKind::Unary);
|
|
|
|
auto unary = ((UnaryExpression*)expression);
|
|
|
|
CHECK(unary -> GetOperatorKind() == UnaryOperatorKind::Negation);
|
|
|
|
auto operand = unary->GetOperand();
|
|
|
|
REQUIRE(operand->GetKind() == ParsedExpressionKind::LiteralInteger);
|
|
|
|
CHECK(((LiteralIntegerExpression*)operand)->GetValue() == 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE( "Parse logical negation", "[parser]" ) {
|
|
|
|
vector<IToken*> v {
|
|
|
|
new SimpleToken(TokenKind::NotKeyword,0,0),
|
|
|
|
new SimpleToken(TokenKind::FalseKeyword,0,0),
|
|
|
|
new SimpleToken(TokenKind::EndOfFile,0,0)
|
|
|
|
};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Expression);
|
|
|
|
auto expression = ((ParsedExpressionStatement*)firstStatement)->GetExpression();
|
|
|
|
REQUIRE(expression -> GetKind() == ParsedExpressionKind::Unary);
|
|
|
|
auto unary = ((UnaryExpression*)expression);
|
|
|
|
CHECK(unary -> GetOperatorKind() == UnaryOperatorKind::LogicalNegation);
|
|
|
|
auto operand = unary->GetOperand();
|
|
|
|
REQUIRE(operand->GetKind() == ParsedExpressionKind::LiteralBool);
|
|
|
|
CHECK(((LiteralBoolExpression*)operand)->GetValue() == false);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE( "Are parenthesized expressions valid", "[parser]" ) {
|
|
|
|
vector<IToken*> v {
|
|
|
|
new IntegerToken(5, 0, 0),
|
|
|
|
new SimpleToken(TokenKind::PlusToken,0,0),
|
|
|
|
new IntegerToken(10, 0, 0),
|
|
|
|
new SimpleToken(TokenKind::StarToken,0,0),
|
|
|
|
new IntegerToken(6, 0, 0),
|
|
|
|
new SimpleToken(TokenKind::EndOfFile,0,0)
|
|
|
|
};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Expression);
|
|
|
|
auto expression = ((ParsedExpressionStatement*)firstStatement)->GetExpression();
|
|
|
|
REQUIRE(expression -> GetKind() == ParsedExpressionKind::Binary);
|
|
|
|
auto binary = ((BinaryExpression*)expression);
|
|
|
|
CHECK(binary -> GetOperatorKind() == BinaryOperatorKind::Addition);
|
|
|
|
auto left = binary->GetLeft();
|
|
|
|
auto right = binary->GetRight();
|
|
|
|
REQUIRE(left->GetKind() == ParsedExpressionKind::LiteralInteger);
|
|
|
|
REQUIRE(right->GetKind() == ParsedExpressionKind::Binary);
|
|
|
|
CHECK(((LiteralIntegerExpression*)left)->GetValue() == 5);
|
|
|
|
left = ((BinaryExpression*)right)->GetLeft();
|
|
|
|
right = ((BinaryExpression*)right)->GetRight();
|
|
|
|
CHECK(((LiteralIntegerExpression*)left)->GetValue() == 10);
|
|
|
|
CHECK(((LiteralIntegerExpression*)right)->GetValue() == 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE( "Assert binary precedence", "[parser]" ) {
|
|
|
|
vector<IToken*> v {
|
|
|
|
new SimpleToken(TokenKind::OpenParenthesis,0,0),
|
|
|
|
new IntegerToken(10, 0, 0),
|
|
|
|
new SimpleToken(TokenKind::CloseParenthesis,0,0),
|
|
|
|
new SimpleToken(TokenKind::EndOfFile,0,0)
|
|
|
|
};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Expression);
|
|
|
|
auto expression = ((ParsedExpressionStatement*)firstStatement)->GetExpression();
|
|
|
|
REQUIRE(expression -> GetKind() == ParsedExpressionKind::Parenthesized);
|
|
|
|
auto innerExpression = ((ParenthesizedExpression*)expression) -> GetInnerExpression();
|
|
|
|
REQUIRE(innerExpression -> GetKind() == ParsedExpressionKind::LiteralInteger);
|
2019-05-22 11:29:35 +00:00
|
|
|
}
|
2019-05-21 15:16:53 +00:00
|
|
|
|
2019-05-22 11:29:35 +00:00
|
|
|
TEST_CASE( "Parse String Tokens", "[parser]" ) {
|
|
|
|
vector<IToken*> v {new StringToken("foo bar", 0,0), new SimpleToken(TokenKind::EndOfFile,0,0)};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Expression);
|
|
|
|
auto expression = ((ParsedExpressionStatement*)firstStatement)->GetExpression();
|
|
|
|
REQUIRE(expression -> GetKind() == ParsedExpressionKind::LiteralString);
|
|
|
|
auto boolean = ((LiteralStringExpression*)expression);
|
|
|
|
REQUIRE(boolean->GetValue() == "foo bar");
|
2019-05-21 15:16:53 +00:00
|
|
|
}
|
|
|
|
|
2019-05-26 12:20:40 +00:00
|
|
|
TEST_CASE( "Parse Global Assignment", "[parser]" ) {
|
|
|
|
vector<IToken*> v {
|
|
|
|
new IdentifierToken("foo",0,0),
|
|
|
|
new SimpleToken(TokenKind::AssignmentToken,0,0),
|
|
|
|
new SimpleToken(TokenKind::TrueKeyword,0,0),
|
|
|
|
new SimpleToken(TokenKind::EndOfFile,0,0)
|
|
|
|
};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Assignment);
|
|
|
|
auto assignment = (ParsedAssignmentStatement*)firstStatement;
|
|
|
|
REQUIRE(!assignment -> IsLocal());
|
|
|
|
REQUIRE(assignment->GetIdentifier() == "foo");
|
|
|
|
REQUIRE(((LiteralBoolExpression*)assignment->GetExpression()) -> GetValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE( "Parse local Assignment", "[parser]" ) {
|
|
|
|
vector<IToken*> v {
|
|
|
|
new SimpleToken(TokenKind::LocalKeyword,0,0),
|
|
|
|
new IdentifierToken("foo",0,0),
|
|
|
|
new SimpleToken(TokenKind::AssignmentToken,0,0),
|
|
|
|
new SimpleToken(TokenKind::TrueKeyword,0,0),
|
|
|
|
new SimpleToken(TokenKind::EndOfFile,0,0)
|
|
|
|
};
|
|
|
|
Parser parser = Parser(v, nullptr);
|
|
|
|
auto parsedStatements = parser.Parse() -> GetStatements();
|
|
|
|
REQUIRE(parsedStatements.size() == 1);
|
|
|
|
auto firstStatement = parsedStatements[0];
|
|
|
|
REQUIRE(firstStatement -> GetKind() == ParsedStatementKind::Assignment);
|
|
|
|
auto assignment = (ParsedAssignmentStatement*)firstStatement;
|
|
|
|
REQUIRE(assignment -> IsLocal());
|
|
|
|
REQUIRE(assignment->GetIdentifier() == "foo");
|
|
|
|
REQUIRE(((LiteralBoolExpression*)assignment->GetExpression()) -> GetValue());
|
|
|
|
}
|
|
|
|
|
2019-05-22 11:29:35 +00:00
|
|
|
|
2019-05-21 15:16:53 +00:00
|
|
|
#endif
|