/* Abstract syntax tree representation. Copyright (C) 2025 Free Software Foundation, Inc. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "elna/boot/ast.h" namespace elna { namespace boot { void empty_visitor::visit(variable_declaration *) { } void empty_visitor::visit(constant_definition *definition) { definition->body().accept(this); } void empty_visitor::visit(procedure_definition *definition) { definition->heading().accept(this); if (definition->body != nullptr) { definition->body->accept(this); } } void empty_visitor::visit(type_definition *definition) { definition->body().accept(this); } void empty_visitor::visit(call_expression *expression) { for (auto& argument : expression->arguments()) { argument->accept(this); } } void empty_visitor::visit(cast_expression *expression) { expression->target().accept(this); expression->value().accept(this); } void empty_visitor::visit(type_expression *expression) { expression->body().accept(this); } void empty_visitor::visit(call_statement *statement) { statement->body().accept(this); } void empty_visitor::visit(assign_statement *statement) { statement->rvalue().accept(this); } void empty_visitor::visit(if_statement *statement) { statement->body().prerequisite().accept(this); for (const auto body_statement : statement->body().statements) { body_statement->accept(this); } } void empty_visitor::visit(while_statement *statement) { statement->body().prerequisite().accept(this); for (const auto body_statement : statement->body().statements) { body_statement->accept(this); } } void empty_visitor::visit(return_statement *statement) { expression *return_expression = statement->return_expression(); if (return_expression != nullptr) { return_expression->accept(this); } } void empty_visitor::visit(defer_statement *defer) { for (statement *const body_statement : defer->statements) { body_statement->accept(this); } } void empty_visitor::visit(block *block) { for (constant_definition *const constant : block->constants) { constant->accept(this); } for (variable_declaration *const variable : block->variables) { variable->accept(this); } for (statement *const body_statement : block->body) { body_statement->accept(this); } } void empty_visitor::visit(program *program) { visit(reinterpret_cast(program)); for (type_definition *const type : program->types) { type->accept(this); } for (procedure_definition *const procedure : program->procedures) { procedure->accept(this); } } void empty_visitor::visit(binary_expression *expression) { expression->lhs().accept(this); expression->rhs().accept(this); } void empty_visitor::visit(unary_expression *expression) { expression->operand().accept(this); } void empty_visitor::visit(basic_type *) { } void empty_visitor::visit(array_type *expression) { expression->base().accept(this); } void empty_visitor::visit(pointer_type *expression) { expression->base().accept(this); } void empty_visitor::visit(record_type *expression) { for (auto& field : expression->fields) { field.second->accept(this); } } void empty_visitor::visit(union_type *expression) { for (auto& field : expression->fields) { field.second->accept(this); } } void empty_visitor::visit(procedure_type *expression) { for (auto parameter : expression->parameters) { parameter->accept(this); } if (expression->return_type != nullptr) { expression->return_type->accept(this); } } void empty_visitor::visit(variable_expression *) { } void empty_visitor::visit(array_access_expression *expression) { expression->base().accept(this); expression->index().accept(this); } void empty_visitor::visit(field_access_expression *expression) { expression->base().accept(this); } void empty_visitor::visit(dereference_expression *expression) { expression->base().accept(this); } void empty_visitor::visit(number_literal *) { } void empty_visitor::visit(number_literal *) { } void empty_visitor::visit(number_literal *) { } void empty_visitor::visit(number_literal *) { } void empty_visitor::visit(number_literal *) { } void empty_visitor::visit(number_literal *) { } void empty_visitor::visit(number_literal *) { } node::node(const struct position position) : source_position(position) { } const struct position& node::position() const { return this->source_position; } statement::statement(const struct position position) : node(position) { } expression::expression(const struct position position) : node(position) { } top_type::top_type(const struct position position) : node(position) { } std::shared_ptr top_type::is_basic() { return nullptr; } std::shared_ptr top_type::is_array() { return nullptr; } std::shared_ptr top_type::is_record() { return nullptr; } std::shared_ptr top_type::is_union() { return nullptr; } std::shared_ptr top_type::is_pointer() { return nullptr; } std::shared_ptr top_type::is_procedure() { return nullptr; } basic_type::basic_type(const struct position position, const std::string& name) : top_type(position), m_name(name) { } void basic_type::accept(parser_visitor *visitor) { visitor->visit(this); } const std::string& basic_type::base_name() { return m_name; } std::shared_ptr basic_type::is_basic() { return std::static_pointer_cast(shared_from_this()); } array_type::array_type(const struct position position, std::shared_ptr base, const std::uint32_t size) : top_type(position), m_base(base), size(size) { } void array_type::accept(parser_visitor *visitor) { visitor->visit(this); } top_type& array_type::base() { return *m_base; } std::shared_ptr array_type::is_array() { return std::static_pointer_cast(shared_from_this()); } pointer_type::pointer_type(const struct position position, std::shared_ptr base) : top_type(position), m_base(base) { } void pointer_type::accept(parser_visitor *visitor) { visitor->visit(this); } top_type& pointer_type::base() { return *m_base; } std::shared_ptr pointer_type::is_pointer() { return std::static_pointer_cast(shared_from_this()); } record_type::record_type(const struct position position, fields_t&& fields) : top_type(position), fields(std::move(fields)) { } void record_type::accept(parser_visitor *visitor) { visitor->visit(this); } std::shared_ptr record_type::is_record() { return std::static_pointer_cast(shared_from_this()); } union_type::union_type(const struct position position, fields_t&& fields) : top_type(position), fields(std::move(fields)) { } std::shared_ptr union_type::is_union() { return std::static_pointer_cast(shared_from_this()); } void union_type::accept(parser_visitor *visitor) { visitor->visit(this); } variable_declaration::variable_declaration(const struct position position, const std::string& identifier, std::shared_ptr type, const bool exported) : definition(position, identifier, exported), m_type(type) { } void variable_declaration::accept(parser_visitor *visitor) { visitor->visit(this); } top_type& variable_declaration::variable_type() { return *m_type; } definition::definition(const struct position position, const std::string& identifier, const bool exported) : node(position), identifier(identifier), exported(exported) { } constant_definition::constant_definition(const struct position position, const std::string& identifier, const bool exported, literal *body) : definition(position, identifier, exported), m_body(body) { } void constant_definition::accept(parser_visitor *visitor) { visitor->visit(this); } literal& constant_definition::body() { return *m_body; } constant_definition::~constant_definition() { delete m_body; } procedure_type::procedure_type(const struct position position, std::shared_ptr return_type) : top_type(position), return_type(return_type), no_return(false) { } procedure_type::procedure_type(const struct position position, no_return_t) : top_type(position), return_type(nullptr), no_return(true) { } void procedure_type::accept(parser_visitor *visitor) { visitor->visit(this); } std::shared_ptr procedure_type::is_procedure() { return std::static_pointer_cast(shared_from_this()); } procedure_type::~procedure_type() { for (auto parameter : this->parameters) { delete parameter; } } procedure_definition::procedure_definition(const struct position position, const std::string& identifier, const bool exported, std::shared_ptr heading, block *body) : definition(position, identifier, exported), m_heading(heading), body(body) { } void procedure_definition::accept(parser_visitor *visitor) { visitor->visit(this); } procedure_type& procedure_definition::heading() { return *m_heading; } procedure_definition::~procedure_definition() { delete body; } type_definition::type_definition(const struct position position, const std::string& identifier, const bool exported, std::shared_ptr body) : definition(position, identifier, exported), m_body(body) { } void type_definition::accept(parser_visitor *visitor) { visitor->visit(this); } top_type& type_definition::body() { return *m_body; } block::block(const struct position position) : node(position) { } void block::accept(parser_visitor *visitor) { visitor->visit(this); } block::~block() { for (statement *body_statement : this->body) { delete body_statement; } for (variable_declaration *variable : this->variables) { delete variable; } for (constant_definition *constant : this->constants) { delete constant; } } program::program(const struct position position) : block(position) { } void program::accept(parser_visitor *visitor) { visitor->visit(this); } program::~program() { for (procedure_definition *procedure : this->procedures) { delete procedure; } for (type_definition *type : this->types) { delete type; } } literal::literal(const struct position position) : expression(position) { } defer_statement::defer_statement(const struct position position) : statement(position) { } void defer_statement::accept(parser_visitor *visitor) { visitor->visit(this); } defer_statement::~defer_statement() { for (statement *body_statement : statements) { delete body_statement; } } designator_expression::designator_expression(const struct position position) : expression(position) { } variable_expression::variable_expression(const struct position position, const std::string& name) : designator_expression(position), m_name(name) { } void variable_expression::accept(parser_visitor *visitor) { visitor->visit(this); } const std::string& variable_expression::name() const { return m_name; } variable_expression *variable_expression::is_variable() { return this; } array_access_expression::array_access_expression(const struct position position, expression *base, expression *index) : designator_expression(position), m_base(base), m_index(index) { } void array_access_expression::accept(parser_visitor *visitor) { visitor->visit(this); } expression& array_access_expression::index() { return *m_index; } expression& array_access_expression::base() { return *m_base; } array_access_expression *array_access_expression::is_array_access() { return this; } array_access_expression::~array_access_expression() { delete m_index; delete m_base; } field_access_expression::field_access_expression(const struct position position, expression *base, const std::string& field) : designator_expression(position), m_base(base), m_field(field) { } void field_access_expression::accept(parser_visitor *visitor) { visitor->visit(this); } expression& field_access_expression::base() { return *m_base; } std::string& field_access_expression::field() { return m_field; } field_access_expression *field_access_expression::is_field_access() { return this; } field_access_expression::~field_access_expression() { delete m_base; } dereference_expression::dereference_expression(const struct position position, expression *base) : designator_expression(position), m_base(base) { } void dereference_expression::accept(parser_visitor *visitor) { visitor->visit(this); } expression& dereference_expression::base() { return *m_base; } dereference_expression *dereference_expression::is_dereference() { return this; } dereference_expression::~dereference_expression() { delete m_base; } binary_expression::binary_expression(const struct position position, expression *lhs, expression *rhs, const binary_operator operation) : expression(position), m_lhs(lhs), m_rhs(rhs), m_operator(operation) { } void binary_expression::accept(parser_visitor *visitor) { visitor->visit(this); } expression& binary_expression::lhs() { return *m_lhs; } expression& binary_expression::rhs() { return *m_rhs; } binary_operator binary_expression::operation() const { return m_operator; } binary_expression::~binary_expression() { delete m_lhs; delete m_rhs; } unary_expression::unary_expression(const struct position position, expression *operand, const unary_operator operation) : expression(position), m_operand(std::move(operand)), m_operator(operation) { } void unary_expression::accept(parser_visitor *visitor) { visitor->visit(this); } expression& unary_expression::operand() { return *m_operand; } unary_operator unary_expression::operation() const { return this->m_operator; } unary_expression::~unary_expression() { delete m_operand; } call_expression::call_expression(const struct position position, const std::string& name) : expression(position), m_name(name) { } void call_expression::accept(parser_visitor *visitor) { visitor->visit(this); } std::string& call_expression::name() { return m_name; } std::vector& call_expression::arguments() { return m_arguments; } call_expression::~call_expression() { for (auto argument : m_arguments) { delete argument; } } cast_expression::cast_expression(const struct position position, std::shared_ptr target, expression *value) : expression(position), m_target(target), m_value(value) { } void cast_expression::accept(parser_visitor *visitor) { visitor->visit(this); } top_type& cast_expression::target() { return *m_target; } expression& cast_expression::value() { return *m_value; } cast_expression::~cast_expression() { delete m_value; } type_expression::type_expression(const struct position position, std::shared_ptr body) : expression(position), m_body(body) { } void type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } top_type& type_expression::body() { return *m_body; } call_statement::call_statement(const struct position position, call_expression *body) : statement(position), m_body(body) { } void call_statement::accept(parser_visitor *visitor) { visitor->visit(this); } call_expression& call_statement::body() { return *m_body; } call_statement::~call_statement() { delete m_body; } conditional_statements::conditional_statements(expression *prerequisite) : m_prerequisite(prerequisite) { } expression& conditional_statements::prerequisite() { return *m_prerequisite; } conditional_statements::~conditional_statements() { delete m_prerequisite; for (auto statement : statements) { delete statement; } } return_statement::return_statement(const struct position position, expression *return_expression) : statement(position), m_return_expression(return_expression) { } void return_statement::accept(parser_visitor *visitor) { visitor->visit(this); } expression *return_statement::return_expression() { return m_return_expression; } return_statement::~return_statement() { delete m_return_expression; } void assign_statement::accept(parser_visitor *visitor) { visitor->visit(this); } assign_statement::assign_statement(const struct position position, designator_expression *lvalue, expression *rvalue) : statement(position), m_lvalue(lvalue), m_rvalue(rvalue) { } variable_expression *designator_expression::is_variable() { return nullptr; } array_access_expression *designator_expression::is_array_access() { return nullptr; } field_access_expression *designator_expression::is_field_access() { return nullptr; } dereference_expression *designator_expression::is_dereference() { return nullptr; } designator_expression& assign_statement::lvalue() { return *m_lvalue; } expression& assign_statement::rvalue() { return *m_rvalue; } assign_statement::~assign_statement() { delete m_rvalue; } if_statement::if_statement(const struct position position, conditional_statements *body, std::vector *alternative) : statement(position), m_body(body), m_alternative(alternative) { } void if_statement::accept(parser_visitor *visitor) { visitor->visit(this); } conditional_statements& if_statement::body() { return *m_body; } std::vector *if_statement::alternative() { return m_alternative; } if_statement::~if_statement() { delete m_body; for (const auto branch : branches) { delete branch; } delete m_alternative; } while_statement::while_statement(const struct position position, conditional_statements *body) : statement(position), m_body(body) { } void while_statement::accept(parser_visitor *visitor) { visitor->visit(this); } conditional_statements& while_statement::body() { return *m_body; } while_statement::~while_statement() { delete m_body; for (const auto branch : branches) { delete branch; } } const char *print_binary_operator(const binary_operator operation) { switch (operation) { case binary_operator::sum: return "+"; case binary_operator::subtraction: return "-"; case binary_operator::multiplication: return "*"; case binary_operator::division: return "/"; case binary_operator::remainder: return "%"; case binary_operator::equals: return "="; case binary_operator::not_equals: return "<>"; case binary_operator::less: return "<"; case binary_operator::less_equal: return "<="; case binary_operator::greater: return ">"; case binary_operator::greater_equal: return ">="; case binary_operator::conjunction: return "and"; case binary_operator::disjunction: return "or"; case binary_operator::exclusive_disjunction: return "xor"; case binary_operator::shift_left: return "<<"; case binary_operator::shift_right: return ">>"; } __builtin_unreachable(); }; } }