refactor(furc): move arena allocator out of the parser

Refs: #12
This commit is contained in:
2026-06-20 11:56:15 +02:00
parent f80abd68ad
commit 190aa8f985
3 changed files with 29 additions and 27 deletions
+5 -5
View File
@@ -23,7 +23,7 @@ public:
* @param filename Filename for debugging. * @param filename Filename for debugging.
* @param content Content. * @param content Content.
*/ */
parser(std::string_view filename, std::string_view content); parser(furlang::arena& arena, std::string_view filename, std::string_view content);
/** /**
* @brief Construct a new parser from file. * @brief Construct a new parser from file.
@@ -32,7 +32,8 @@ public:
* *
* @param filename Name of the file. * @param filename Name of the file.
*/ */
parser(std::string_view filename); parser(furlang::arena& arena, std::string_view filename);
~parser() = default; ~parser() = default;
/** /**
@@ -40,13 +41,12 @@ public:
*/ */
parser(parser&&) = default; parser(parser&&) = default;
parser(const parser&) = delete;
/** /**
* @brief Move constructor. * @brief Move constructor.
*/ */
parser& operator=(parser&&) = default; parser& operator=(parser&&) = default;
parser(const parser&) = delete;
parser& operator=(const parser&) = delete; parser& operator=(const parser&) = delete;
public: public:
/** /**
@@ -73,7 +73,7 @@ private:
std::string m_filename; std::string m_filename;
std::string m_content; std::string m_content;
lexer m_lexer; lexer m_lexer;
furlang::arena m_arena; furlang::arena* m_arena;
std::vector<token_r> m_peekBuffer; std::vector<token_r> m_peekBuffer;
}; };
+20 -20
View File
@@ -16,11 +16,11 @@ namespace furc::front {
using namespace std::string_literals; using namespace std::string_literals;
parser::parser(std::string_view filename, std::string_view content) parser::parser(furlang::arena& arena, std::string_view filename, std::string_view content)
: m_filename(filename), m_content(content), m_lexer(m_filename, m_content) {} : m_filename(filename), m_content(content), m_lexer(m_filename, m_content), m_arena(&arena) {}
parser::parser(std::string_view filename) parser::parser(furlang::arena& arena, std::string_view filename)
: m_filename(filename) { : m_filename(filename), m_arena(&arena) {
std::ifstream file(m_filename, std::ios_base::binary | std::ios_base::ate); std::ifstream file(m_filename, std::ios_base::binary | std::ios_base::ate);
if (!file.is_open()) throw std::runtime_error("failed to open file "s.append(m_filename)); if (!file.is_open()) throw std::runtime_error("failed to open file "s.append(m_filename));
std::streampos size = file.tellg(); std::streampos size = file.tellg();
@@ -32,7 +32,7 @@ parser::parser(std::string_view filename)
} }
ast::program_node_r parser::parse() & { ast::program_node_r parser::parse() & {
auto program = m_arena.allocate_shared<ast::program_node>(location{ m_filename }); auto program = m_arena->allocate_shared<ast::program_node>(location{ m_filename });
while (peek_token().has_value()) { while (peek_token().has_value()) {
auto decl = parse_declaration(); auto decl = parse_declaration();
@@ -67,13 +67,13 @@ ast::declaration_node_r parser::parse_declaration() {
case token_t::LBrace: { case token_t::LBrace: {
ast::body_r body = parse_body(); ast::body_r body = parse_body();
if (body.has_error()) return ast::declaration_node_r(ast::error{ body.error().location }); if (body.has_error()) return ast::declaration_node_r(ast::error{ body.error().location });
return m_arena.allocate_shared<ast::function_definition_node>(first->location, return m_arena->allocate_shared<ast::function_definition_node>(first->location,
name->value.string, name->value.string,
std::move(body.value())); std::move(body.value()));
} }
case token_t::Semicolon: { case token_t::Semicolon: {
m_peekBuffer.clear(); m_peekBuffer.clear();
return m_arena.allocate_shared<ast::function_declaration_node>(first->location, name->value.string); return m_arena->allocate_shared<ast::function_declaration_node>(first->location, name->value.string);
} }
default: return ast::declaration_node_r(ast::error{ tok->location }); default: return ast::declaration_node_r(ast::error{ tok->location });
} }
@@ -109,13 +109,13 @@ ast::statement_node_r parser::parse_statement() {
auto tok = next_token(); auto tok = next_token();
if (peek_token()->type == token_t::Semicolon) { if (peek_token()->type == token_t::Semicolon) {
next_token(); next_token();
return m_arena.allocate_shared<ast::return_statement_node>(location); return m_arena->allocate_shared<ast::return_statement_node>(location);
} }
auto value = parse_expression(); auto value = parse_expression();
auto err = eat_token(token_t::Semicolon); auto err = eat_token(token_t::Semicolon);
if (err.has_error()) return ast::statement_node_r(ast::error{ err.error().location }); if (err.has_error()) return ast::statement_node_r(ast::error{ err.error().location });
return m_arena.allocate_shared<ast::return_statement_node>(location, std::move(value.value())); return m_arena->allocate_shared<ast::return_statement_node>(location, std::move(value.value()));
} }
case keyword_token::If: { case keyword_token::If: {
auto tok = next_token(); auto tok = next_token();
@@ -136,13 +136,13 @@ ast::statement_node_r parser::parse_statement() {
auto elseBody = parse_statement(); auto elseBody = parse_statement();
if (elseBody.has_error()) return ast::statement_node_r(ast::error{ elseBody.error().location }); if (elseBody.has_error()) return ast::statement_node_r(ast::error{ elseBody.error().location });
return m_arena.allocate_shared<ast::if_statement_node>(location, return m_arena->allocate_shared<ast::if_statement_node>(location,
std::move(cond.value()), std::move(cond.value()),
std::move(then.value()), std::move(then.value()),
std::move(elseBody.value())); std::move(elseBody.value()));
} }
return m_arena.allocate_shared<ast::if_statement_node>(location, return m_arena->allocate_shared<ast::if_statement_node>(location,
std::move(cond.value()), std::move(cond.value()),
std::move(then.value())); std::move(then.value()));
} }
@@ -160,7 +160,7 @@ ast::statement_node_r parser::parse_statement() {
auto body = parse_statement(); auto body = parse_statement();
if (body.has_error()) return ast::statement_node_r(ast::error{ body.error().location }); if (body.has_error()) return ast::statement_node_r(ast::error{ body.error().location });
return m_arena.allocate_shared<ast::while_statement_node>(location, return m_arena->allocate_shared<ast::while_statement_node>(location,
std::move(cond.value()), std::move(cond.value()),
std::move(body.value())); std::move(body.value()));
} }
@@ -172,7 +172,7 @@ ast::statement_node_r parser::parse_statement() {
case token_t::LBrace: { case token_t::LBrace: {
auto body = parse_body(); auto body = parse_body();
if (body.has_error()) return ast::statement_node_r(ast::error{ body.error().location }); if (body.has_error()) return ast::statement_node_r(ast::error{ body.error().location });
return m_arena.allocate_shared<ast::compound_statement_node>(location, std::move(body.value())); return m_arena->allocate_shared<ast::compound_statement_node>(location, std::move(body.value()));
} }
default: break; default: break;
} }
@@ -204,7 +204,7 @@ ast::expression_node_r parser::parse_expression_primary() {
case token_t::Identifier: { case token_t::Identifier: {
auto tok = next_token(); auto tok = next_token();
if (tok.has_error()) return ast::expression_node_r(ast::error{ tok.error().location }); if (tok.has_error()) return ast::expression_node_r(ast::error{ tok.error().location });
return m_arena.allocate_shared<ast::var_read_expression_node>(tok->location, (*tok)->string); return m_arena->allocate_shared<ast::var_read_expression_node>(tok->location, (*tok)->string);
} }
case token_t::LParen: { case token_t::LParen: {
auto tok = next_token(); auto tok = next_token();
@@ -216,12 +216,12 @@ ast::expression_node_r parser::parse_expression_primary() {
case token_t::String: { case token_t::String: {
auto tok = next_token(); auto tok = next_token();
if (tok.has_error()) return ast::expression_node_r(ast::error{ tok.error().location }); if (tok.has_error()) return ast::expression_node_r(ast::error{ tok.error().location });
return m_arena.allocate_shared<ast::string_literal_node>(tok->location, (*tok)->string); return m_arena->allocate_shared<ast::string_literal_node>(tok->location, (*tok)->string);
} }
case token_t::Integer: { case token_t::Integer: {
auto tok = next_token(); auto tok = next_token();
if (tok.has_error()) return ast::expression_node_r(ast::error{ tok.error().location }); if (tok.has_error()) return ast::expression_node_r(ast::error{ tok.error().location });
return m_arena.allocate_shared<ast::integer_literal_node>(tok->location, (*tok)->integer); return m_arena->allocate_shared<ast::integer_literal_node>(tok->location, (*tok)->integer);
} }
default: { default: {
return ast::expression_node_r(ast::error{ tok->location }); return ast::expression_node_r(ast::error{ tok->location });
@@ -262,7 +262,7 @@ ast::expression_node_r parser::parse_expression_unary(std::uint32_t precedence)
expression = std::move(std::move(expr.value())); expression = std::move(std::move(expr.value()));
} }
result = m_arena.allocate_shared<ast::unary_op_expression_node>(token->location, result = m_arena->allocate_shared<ast::unary_op_expression_node>(token->location,
current.type, current.type,
std::move(expression)); std::move(expression));
} }
@@ -389,18 +389,18 @@ ast::expression_node_r parser::parse_expression_rhs(ast::expression_node_p&& ini
switch (current.type) { switch (current.type) {
case rhsop_info_t::Unaryop: case rhsop_info_t::Unaryop:
lhs = m_arena.allocate_shared<ast::unary_op_expression_node>(opToken->location, lhs = m_arena->allocate_shared<ast::unary_op_expression_node>(opToken->location,
current.unary, current.unary,
std::move(lhs)); std::move(lhs));
break; break;
case rhsop_info_t::Binop: case rhsop_info_t::Binop:
lhs = m_arena.allocate_shared<ast::binary_op_expression_node>(opToken->location, lhs = m_arena->allocate_shared<ast::binary_op_expression_node>(opToken->location,
current.binary, current.binary,
std::move(lhs), std::move(lhs),
std::move(rhs)); std::move(rhs));
break; break;
case rhsop_info_t::Assignment: case rhsop_info_t::Assignment:
lhs = m_arena.allocate_shared<ast::var_assign_expression_node>(opToken->location, lhs = m_arena->allocate_shared<ast::var_assign_expression_node>(opToken->location,
current.assignment, current.assignment,
std::move(lhs), std::move(lhs),
std::move(rhs)); std::move(rhs));
+3 -1
View File
@@ -4,6 +4,7 @@
#include "furc/front/ir_generator.hpp" #include "furc/front/ir_generator.hpp"
#include "furc/front/parser.hpp" #include "furc/front/parser.hpp"
#include "furc/front/ssa.hpp" #include "furc/front/ssa.hpp"
#include "furlang/arena.hpp"
#include <iostream> #include <iostream>
@@ -19,7 +20,8 @@ int main(void) {
} }
} }
)"; )";
furc::front::parser parser("<TEMP>", programStr); furlang::arena arena{};
furc::front::parser parser(arena, "<TEMP>", programStr);
furc::front::ir_generator generator; furc::front::ir_generator generator;
auto programResult = parser.parse(); auto programResult = parser.parse();