made setup for expression parsing

This commit is contained in:
Karma Riuk
2025-07-08 15:52:40 +02:00
parent d10e5676c1
commit c9e21213fd
3 changed files with 52 additions and 1 deletions

View File

@@ -35,7 +35,7 @@ namespace parser {
case token::type::RETURN: case token::type::RETURN:
return parse_return(); return parse_return();
default: default:
return nullptr; return parse_expression_stmt();
} }
} }
@@ -102,4 +102,12 @@ namespace parser {
for (const auto& e : errors) for (const auto& e : errors)
delete e; delete e;
} }
void parser::register_prefix(token::type type, prefix_parse_fn fn) {
prefix_parse_fns[type] = fn;
};
void parser::register_infix(token::type type, infix_parse_fn fn) {
infix_parse_fns[type] = fn;
};
} // namespace parser } // namespace parser

View File

@@ -9,9 +9,14 @@
#include "lexer/lexer.hpp" #include "lexer/lexer.hpp"
#include "token/token.hpp" #include "token/token.hpp"
#include <functional>
#include <vector> #include <vector>
namespace parser { namespace parser {
using prefix_parse_fn = std::function<ast::expression*()>;
using infix_parse_fn = std::function<ast::expression*(ast::expression*)>;
struct parser { struct parser {
parser(lexer::lexer& lexer); parser(lexer::lexer& lexer);
~parser(); ~parser();
@@ -23,6 +28,9 @@ namespace parser {
lexer::lexer& lexer; lexer::lexer& lexer;
token::token current, next; token::token current, next;
std::unordered_map<token::type, prefix_parse_fn> prefix_parse_fns;
std::unordered_map<token::type, infix_parse_fn> infix_parse_fns;
void next_token(); void next_token();
ast::statement* parse_statement(); ast::statement* parse_statement();
ast::expression* parse_expression(); ast::expression* parse_expression();
@@ -31,5 +39,8 @@ namespace parser {
ast::expression_stmt* parse_expression_stmt(); ast::expression_stmt* parse_expression_stmt();
bool expect_next(token::type); bool expect_next(token::type);
void next_error(token::type); void next_error(token::type);
void register_prefix(token::type, prefix_parse_fn);
void register_infix(token::type, infix_parse_fn);
}; };
} // namespace parser } // namespace parser

View File

@@ -0,0 +1,32 @@
#include "ast/expressions/identifier.hpp"
#include "utils.hpp"
#include <doctest.h>
TEST_SUITE("Parser: expression") {
TEST_CASE_FIXTURE(ParserFixture, "Simple expression statement") {
setup("foobar;");
REQUIRE(program->statements.size() == 1);
ast::expression_stmt* expression_stmt;
REQUIRE_NOTHROW(
expression_stmt =
dynamic_cast<ast::expression_stmt*>(program->statements[0])
);
REQUIRE_MESSAGE(
expression_stmt != nullptr,
"Couldn't cast statement to an expression statement"
);
ast::identifier* ident;
REQUIRE_NOTHROW(
ident = dynamic_cast<ast::identifier*>(expression_stmt->expression)
);
REQUIRE_MESSAGE(
ident != nullptr,
"Couldn't cast expression to an identifier"
);
REQUIRE(ident->value == "foobar");
REQUIRE(ident->token_literal() == "foobar");
};
}