Skip to content

Commit

Permalink
Merge branch 'master' into refactor/readLine
Browse files Browse the repository at this point in the history
  • Loading branch information
xXenvy authored Aug 14, 2024
2 parents 6a598f1 + 24169ea commit aaa37a0
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/parsing/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@ std::unique_ptr<ASTBase> Parser::parsePrimaryExpression() {
const Token current = currentToken();
const size_t currentLine = current.line;

if (current.type == TokenType::LBRACKET) {
moveForward();
std::unique_ptr<ASTBase> expr = parseExpression(0);
consume({ TokenType::RBRACKET, ")", currentLine });
return expr;
}

// Handles case for negative number.
if (current.type == TokenType::SUBTRACT) {
moveForward();
Expand Down
45 changes: 45 additions & 0 deletions tests/test_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -647,4 +647,49 @@ TEST(EvaluatorTest, EvaluateLogicalOrFalseFalse) {
Evaluator evaluator;
evaluator.evaluate(program.get());
ASSERT_EQ(testing::internal::GetCapturedStdout(), "false\n");
}

TEST(EvaluatorTest, EvaluatePrintExpressionWithParentheses) {
const std::string code = "println((1 + 2) * 5);";
Lexer lexer(code);
const std::vector<Token> tokens = lexer.tokenize();

Parser parser(tokens);
const auto program = parser.parse();

testing::internal::CaptureStdout();
Evaluator evaluator;
evaluator.evaluate(program.get());
ASSERT_EQ(testing::internal::GetCapturedStdout(), "15\n");
}

TEST(EvaluatorTest, EvaluatePrintNestedParentheses) {
const std::string code = "println(((3 + 4) * (2 + 1)));";
Lexer lexer(code);
const std::vector<Token> tokens = lexer.tokenize();

Parser parser(tokens);
const auto program = parser.parse();

testing::internal::CaptureStdout();
Evaluator evaluator;
evaluator.evaluate(program.get());
ASSERT_EQ(testing::internal::GetCapturedStdout(), "21\n");
}

TEST(EvaluatorTest, EvaluateVarNestedParentheses) {
const std::string code = R"(
var x: int = ((3 + 4) * (2 + 1));
println(x);
)";
Lexer lexer(code);
const std::vector<Token> tokens = lexer.tokenize();

Parser parser(tokens);
const auto program = parser.parse();

testing::internal::CaptureStdout();
Evaluator evaluator;
evaluator.evaluate(program.get());
ASSERT_EQ(testing::internal::GetCapturedStdout(), "21\n");
}
76 changes: 76 additions & 0 deletions tests/test_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,82 @@ TEST(ParserTest, parseOrOperation) {
ASSERT_EQ(rightValue->value, "false");
}

TEST(ParserTest, parsePrintExpressionWithParentheses) {
Lexer lexer("println((1 + 2) * 5);");
const std::vector<Token> tokens = lexer.tokenize();

Parser parser(tokens);
auto program = parser.parse();

ASSERT_EQ(program->type, ASTType::Program);
ASSERT_EQ(program->body.size(), 1);
ASSERT_EQ(program->body.front()->type, ASTType::Print);

const auto printStmt = static_cast<ASTPrint*>(program->body.front().get());
ASSERT_TRUE(printStmt);

const auto operation = static_cast<ASTBinaryOperation*>(printStmt->expression.get());
ASSERT_EQ(operation->op, "*");

const auto leftExpr = static_cast<ASTBinaryOperation*>(operation->left.get());
ASSERT_NE(leftExpr, nullptr);
ASSERT_EQ(leftExpr->op, "+");

const auto rightExpr = static_cast<ASTValue*>(leftExpr->right.get());
ASSERT_NE(rightExpr, nullptr);
ASSERT_EQ(rightExpr->value, "2");

const auto leftValue = static_cast<ASTValue*>(leftExpr->left.get());
ASSERT_NE(leftValue, nullptr);
ASSERT_EQ(leftValue->value, "1");

const auto multiplier = static_cast<ASTValue*>(operation->right.get());
ASSERT_NE(multiplier, nullptr);
ASSERT_EQ(multiplier->value, "5");
}

TEST(ParserTest, parsePrintNestedParentheses) {
Lexer lexer("println(((3 + 4) * (2 + 1)));");
const std::vector<Token> tokens = lexer.tokenize();

Parser parser(tokens);
auto program = parser.parse();

ASSERT_EQ(program->type, ASTType::Program);
ASSERT_EQ(program->body.size(), 1);
ASSERT_EQ(program->body.front()->type, ASTType::Print);

const auto printStmt = static_cast<ASTPrint*>(program->body.front().get());
ASSERT_TRUE(printStmt);

const auto operation = static_cast<ASTBinaryOperation*>(printStmt->expression.get());
ASSERT_EQ(operation->op, "*");

const auto leftExpr = static_cast<ASTBinaryOperation*>(operation->left.get());
ASSERT_NE(leftExpr, nullptr);
ASSERT_EQ(leftExpr->op, "+");

const auto rightExpr = static_cast<ASTBinaryOperation*>(operation->right.get());
ASSERT_NE(rightExpr, nullptr);
ASSERT_EQ(rightExpr->op, "+");

const auto leftValue = static_cast<ASTValue*>(leftExpr->left.get());
ASSERT_NE(leftValue, nullptr);
ASSERT_EQ(leftValue->value, "3");

const auto rightValue = static_cast<ASTValue*>(leftExpr->right.get());
ASSERT_NE(rightValue, nullptr);
ASSERT_EQ(rightValue->value, "4");

const auto nestedLeftValue = static_cast<ASTValue*>(rightExpr->left.get());
ASSERT_NE(nestedLeftValue, nullptr);
ASSERT_EQ(nestedLeftValue->value, "2");

const auto nestedRightValue = static_cast<ASTValue*>(rightExpr->right.get());
ASSERT_NE(nestedRightValue, nullptr);
ASSERT_EQ(nestedRightValue->value, "1");
}

TEST(ParserTest, parseNegativeBoolThrowsException) {
Lexer lexer("var a: bool = -true;");
const std::vector<Token> tokens = lexer.tokenize();
Expand Down

0 comments on commit aaa37a0

Please sign in to comment.