diff --git a/src/ast/expressions/boolean.cpp b/src/ast/expressions/boolean.cpp new file mode 100644 index 0000000..ebdad09 --- /dev/null +++ b/src/ast/expressions/boolean.cpp @@ -0,0 +1,15 @@ +#include "boolean.hpp" + +namespace ast { + boolean_literal::boolean_literal(token::token token, bool value) + : token(std::move(token)), + value(value) {} + + std::string boolean_literal::token_literal() const { + return token.literal; + } + + std::string boolean_literal::str() const { + return token.literal; + }; +} // namespace ast diff --git a/src/ast/expressions/boolean.hpp b/src/ast/expressions/boolean.hpp new file mode 100644 index 0000000..093d95b --- /dev/null +++ b/src/ast/expressions/boolean.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include "ast/ast.hpp" +#include "token/token.hpp" + +#include + +namespace ast { + struct boolean_literal : expression { + boolean_literal(token::token, bool); + token::token token; + bool value; + + std::string token_literal() const override; + std::string str() const override; + }; +} // namespace ast diff --git a/test/parser/expression.cpp b/test/parser/expression.cpp index 4fb36cb..a1fa572 100644 --- a/test/parser/expression.cpp +++ b/test/parser/expression.cpp @@ -35,6 +35,50 @@ TEST_SUITE("Parser: expression") { test_integer_literal(expression_stmt->expression, 5); }; + TEST_CASE_FIXTURE(ParserFixture, "Simple statements with booleans") { + SUBCASE("True literal") { + setup("true;"); + REQUIRE(program->statements.size() == 1); + + ast::expression_stmt* expression_stmt = + cast(program->statements[0]); + + test_boolean_literal(expression_stmt->expression, true); + } + + SUBCASE("False literal") { + setup("false;"); + REQUIRE(program->statements.size() == 1); + + ast::expression_stmt* expression_stmt = + cast(program->statements[0]); + + test_boolean_literal(expression_stmt->expression, false); + } + + SUBCASE("True let statement") { + setup("let foo = true;"); + REQUIRE(program->statements.size() == 1); + + ast::let_stmt* let_stmt = + cast(program->statements[0]); + + CHECK(let_stmt->name->value == "foo"); + test_boolean_literal(let_stmt->value, true); + } + + SUBCASE("False let statement") { + setup("let bar = false;"); + REQUIRE(program->statements.size() == 1); + + ast::let_stmt* let_stmt = + cast(program->statements[0]); + + CHECK(let_stmt->name->value == "bar"); + test_boolean_literal(let_stmt->value, false); + } + } + TEST_CASE_FIXTURE( ParserFixture, "Simple expression statement with prefix before integer" @@ -90,7 +134,6 @@ TEST_SUITE("Parser: expression") { #undef CASE } - TEST_CASE_FIXTURE(ParserFixture, "Slightly more complex infix expression") { setup("5 - -15;"); diff --git a/test/parser/utils.cpp b/test/parser/utils.cpp index c3db8de..b02f745 100644 --- a/test/parser/utils.cpp +++ b/test/parser/utils.cpp @@ -1,5 +1,6 @@ #include "utils.hpp" +#include "ast/expressions/boolean.hpp" #include "ast/expressions/identifier.hpp" #include "ast/expressions/infix.hpp" #include "ast/expressions/integer.hpp" @@ -36,6 +37,13 @@ void ParserFixture::setup(std::string source) { ); } +void test_identifier(ast::expression* expr, std::string value) { + ast::identifier* ident = cast(expr); + + REQUIRE(ident->value == value); + REQUIRE(ident->token_literal() == value); +} + void test_integer_literal(ast::expression* expr, int value) { ast::integer_literal* int_lit = cast(expr); @@ -45,16 +53,20 @@ void test_integer_literal(ast::expression* expr, int value) { REQUIRE(int_lit->token_literal() == oss.str()); } -void test_identifier(ast::expression* expr, std::string value) { - ast::identifier* ident = cast(expr); +void test_boolean_literal(ast::expression* expr, bool value) { + ast::boolean_literal* bool_lit = cast(expr); - REQUIRE(ident->value == value); - REQUIRE(ident->token_literal() == value); + REQUIRE(bool_lit->value == value); + std::ostringstream oss; + oss << value; + REQUIRE(bool_lit->token_literal() == oss.str()); } void test_literal_expression(ast::expression* exp, std::any& expected) { if (expected.type() == typeid(int)) return test_integer_literal(exp, std::any_cast(expected)); + if (expected.type() == typeid(bool)) + return test_boolean_literal(exp, std::any_cast(expected)); if (expected.type() == typeid(std::string)) return test_identifier(exp, std::any_cast(expected)); if (expected.type() == typeid(const char*)) diff --git a/test/parser/utils.hpp b/test/parser/utils.hpp index 86304d0..7318cba 100644 --- a/test/parser/utils.hpp +++ b/test/parser/utils.hpp @@ -64,5 +64,6 @@ struct ParserFixture { void test_identifier(ast::expression*, std::string); void test_integer_literal(ast::expression*, int); +void test_boolean_literal(ast::expression*, bool); void test_literal_expression(ast::expression*, std::any&); void test_infix_expression(ast::expression*, std::any, std::string, std::any);