From 190aa8f9852e1a47b8eb40d1321c70be72f2d516 Mon Sep 17 00:00:00 2001 From: CHatingPython Date: Sat, 20 Jun 2026 11:56:15 +0200 Subject: [PATCH] refactor(furc): move arena allocator out of the parser Refs: #12 --- furc/include/furc/front/parser.hpp | 12 ++++----- furc/src/front/parser.cpp | 40 +++++++++++++++--------------- furc/src/main.cpp | 4 ++- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/furc/include/furc/front/parser.hpp b/furc/include/furc/front/parser.hpp index 40468ae..d9218df 100644 --- a/furc/include/furc/front/parser.hpp +++ b/furc/include/furc/front/parser.hpp @@ -23,7 +23,7 @@ public: * @param filename Filename for debugging. * @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. @@ -32,7 +32,8 @@ public: * * @param filename Name of the file. */ - parser(std::string_view filename); + parser(furlang::arena& arena, std::string_view filename); + ~parser() = default; /** @@ -40,13 +41,12 @@ public: */ parser(parser&&) = default; - parser(const parser&) = delete; - /** * @brief Move constructor. */ parser& operator=(parser&&) = default; + parser(const parser&) = delete; parser& operator=(const parser&) = delete; public: /** @@ -73,11 +73,11 @@ private: std::string m_filename; std::string m_content; lexer m_lexer; - furlang::arena m_arena; + furlang::arena* m_arena; std::vector m_peekBuffer; }; } // namespace front } // namespace furc -#endif // FURC_FRONT_PARSER_HPP \ No newline at end of file +#endif // FURC_FRONT_PARSER_HPP diff --git a/furc/src/front/parser.cpp b/furc/src/front/parser.cpp index b983e69..b2828b8 100644 --- a/furc/src/front/parser.cpp +++ b/furc/src/front/parser.cpp @@ -16,11 +16,11 @@ namespace furc::front { using namespace std::string_literals; -parser::parser(std::string_view filename, std::string_view content) - : m_filename(filename), m_content(content), m_lexer(m_filename, m_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_arena(&arena) {} -parser::parser(std::string_view filename) - : m_filename(filename) { +parser::parser(furlang::arena& arena, std::string_view filename) + : m_filename(filename), m_arena(&arena) { 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)); std::streampos size = file.tellg(); @@ -32,7 +32,7 @@ parser::parser(std::string_view filename) } ast::program_node_r parser::parse() & { - auto program = m_arena.allocate_shared(location{ m_filename }); + auto program = m_arena->allocate_shared(location{ m_filename }); while (peek_token().has_value()) { auto decl = parse_declaration(); @@ -67,13 +67,13 @@ ast::declaration_node_r parser::parse_declaration() { case token_t::LBrace: { ast::body_r body = parse_body(); if (body.has_error()) return ast::declaration_node_r(ast::error{ body.error().location }); - return m_arena.allocate_shared(first->location, + return m_arena->allocate_shared(first->location, name->value.string, std::move(body.value())); } case token_t::Semicolon: { m_peekBuffer.clear(); - return m_arena.allocate_shared(first->location, name->value.string); + return m_arena->allocate_shared(first->location, name->value.string); } 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(); if (peek_token()->type == token_t::Semicolon) { next_token(); - return m_arena.allocate_shared(location); + return m_arena->allocate_shared(location); } auto value = parse_expression(); auto err = eat_token(token_t::Semicolon); if (err.has_error()) return ast::statement_node_r(ast::error{ err.error().location }); - return m_arena.allocate_shared(location, std::move(value.value())); + return m_arena->allocate_shared(location, std::move(value.value())); } case keyword_token::If: { auto tok = next_token(); @@ -136,13 +136,13 @@ ast::statement_node_r parser::parse_statement() { auto elseBody = parse_statement(); if (elseBody.has_error()) return ast::statement_node_r(ast::error{ elseBody.error().location }); - return m_arena.allocate_shared(location, + return m_arena->allocate_shared(location, std::move(cond.value()), std::move(then.value()), std::move(elseBody.value())); } - return m_arena.allocate_shared(location, + return m_arena->allocate_shared(location, std::move(cond.value()), std::move(then.value())); } @@ -160,7 +160,7 @@ ast::statement_node_r parser::parse_statement() { auto body = parse_statement(); if (body.has_error()) return ast::statement_node_r(ast::error{ body.error().location }); - return m_arena.allocate_shared(location, + return m_arena->allocate_shared(location, std::move(cond.value()), std::move(body.value())); } @@ -172,7 +172,7 @@ ast::statement_node_r parser::parse_statement() { case token_t::LBrace: { auto body = parse_body(); if (body.has_error()) return ast::statement_node_r(ast::error{ body.error().location }); - return m_arena.allocate_shared(location, std::move(body.value())); + return m_arena->allocate_shared(location, std::move(body.value())); } default: break; } @@ -204,7 +204,7 @@ ast::expression_node_r parser::parse_expression_primary() { case token_t::Identifier: { auto tok = next_token(); if (tok.has_error()) return ast::expression_node_r(ast::error{ tok.error().location }); - return m_arena.allocate_shared(tok->location, (*tok)->string); + return m_arena->allocate_shared(tok->location, (*tok)->string); } case token_t::LParen: { auto tok = next_token(); @@ -216,12 +216,12 @@ ast::expression_node_r parser::parse_expression_primary() { case token_t::String: { auto tok = next_token(); if (tok.has_error()) return ast::expression_node_r(ast::error{ tok.error().location }); - return m_arena.allocate_shared(tok->location, (*tok)->string); + return m_arena->allocate_shared(tok->location, (*tok)->string); } case token_t::Integer: { auto tok = next_token(); if (tok.has_error()) return ast::expression_node_r(ast::error{ tok.error().location }); - return m_arena.allocate_shared(tok->location, (*tok)->integer); + return m_arena->allocate_shared(tok->location, (*tok)->integer); } default: { 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())); } - result = m_arena.allocate_shared(token->location, + result = m_arena->allocate_shared(token->location, current.type, std::move(expression)); } @@ -389,18 +389,18 @@ ast::expression_node_r parser::parse_expression_rhs(ast::expression_node_p&& ini switch (current.type) { case rhsop_info_t::Unaryop: - lhs = m_arena.allocate_shared(opToken->location, + lhs = m_arena->allocate_shared(opToken->location, current.unary, std::move(lhs)); break; case rhsop_info_t::Binop: - lhs = m_arena.allocate_shared(opToken->location, + lhs = m_arena->allocate_shared(opToken->location, current.binary, std::move(lhs), std::move(rhs)); break; case rhsop_info_t::Assignment: - lhs = m_arena.allocate_shared(opToken->location, + lhs = m_arena->allocate_shared(opToken->location, current.assignment, std::move(lhs), std::move(rhs)); diff --git a/furc/src/main.cpp b/furc/src/main.cpp index 1849438..8de070f 100644 --- a/furc/src/main.cpp +++ b/furc/src/main.cpp @@ -4,6 +4,7 @@ #include "furc/front/ir_generator.hpp" #include "furc/front/parser.hpp" #include "furc/front/ssa.hpp" +#include "furlang/arena.hpp" #include @@ -19,7 +20,8 @@ int main(void) { } } )"; - furc::front::parser parser("", programStr); + furlang::arena arena{}; + furc::front::parser parser(arena, "", programStr); furc::front::ir_generator generator; auto programResult = parser.parse();