diff options
Diffstat (limited to 'frontend/ast.cc')
| -rw-r--r-- | frontend/ast.cc | 1178 |
1 files changed, 1178 insertions, 0 deletions
diff --git a/frontend/ast.cc b/frontend/ast.cc new file mode 100644 index 0000000..e067937 --- /dev/null +++ b/frontend/ast.cc @@ -0,0 +1,1178 @@ +/* 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 +<http://www.gnu.org/licenses/>. */ + +#include "elna/frontend/ast.h" + +namespace elna::frontend +{ + void empty_visitor::not_implemented() + { + __builtin_unreachable(); + } + + void empty_visitor::visit(named_type_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(array_type_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(pointer_type_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(program *) + { + not_implemented(); + } + + void empty_visitor::visit(type_declaration *) + { + not_implemented(); + } + + void empty_visitor::visit(record_type_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(union_type_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(procedure_type_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(enumeration_type_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(variable_declaration *) + { + not_implemented(); + } + + void empty_visitor::visit(constant_declaration *) + { + not_implemented(); + } + + void empty_visitor::visit(procedure_declaration *) + { + not_implemented(); + } + + void empty_visitor::visit(assign_statement *) + { + not_implemented(); + } + + void empty_visitor::visit(if_statement *) + { + not_implemented(); + } + + void empty_visitor::visit(import_declaration *) + { + not_implemented(); + } + + void empty_visitor::visit(while_statement *) + { + not_implemented(); + } + + void empty_visitor::visit(return_statement *) + { + not_implemented(); + } + + void empty_visitor::visit(defer_statement *) + { + not_implemented(); + } + + void empty_visitor::visit(case_statement *) + { + not_implemented(); + } + + void empty_visitor::visit(procedure_call *) + { + not_implemented(); + } + + void empty_visitor::visit(unit *) + { + not_implemented(); + } + + void empty_visitor::visit(cast_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(traits_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(binary_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(unary_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(variable_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(array_access_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(field_access_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(dereference_expression *) + { + not_implemented(); + } + + void empty_visitor::visit(literal<std::int32_t> *) + { + not_implemented(); + } + + void empty_visitor::visit(literal<std::uint32_t> *) + { + not_implemented(); + } + + void empty_visitor::visit(literal<double> *) + { + not_implemented(); + } + + void empty_visitor::visit(literal<bool> *) + { + not_implemented(); + } + + void empty_visitor::visit(literal<unsigned char> *) + { + not_implemented(); + } + + void empty_visitor::visit(literal<std::nullptr_t> *) + { + not_implemented(); + } + + void empty_visitor::visit(literal<std::string> *) + { + not_implemented(); + } + + node::node(const struct position position) + : source_position(position) + { + } + + node::~node() + { + } + + const struct position& node::position() const + { + return this->source_position; + } + + cast_expression *expression::is_cast() + { + return nullptr; + } + + traits_expression *expression::is_traits() + { + return nullptr; + } + + binary_expression *expression::is_binary() + { + return nullptr; + } + + unary_expression *expression::is_unary() + { + return nullptr; + } + + designator_expression *expression::is_designator() + { + return nullptr; + } + + procedure_call *expression::is_call_expression() + { + return nullptr; + } + + literal_expression *expression::is_literal() + { + return nullptr; + } + + type_expression::type_expression(const struct position position) + : node(position) + { + } + + named_type_expression *type_expression::is_named() + { + return nullptr; + } + + array_type_expression *type_expression::is_array() + { + return nullptr; + } + + pointer_type_expression *type_expression::is_pointer() + { + return nullptr; + } + + record_type_expression *type_expression::is_record() + { + return nullptr; + } + + union_type_expression *type_expression::is_union() + { + return nullptr; + } + + procedure_type_expression *type_expression::is_procedure() + { + return nullptr; + } + + enumeration_type_expression *type_expression::is_enumeration() + { + return nullptr; + } + + named_type_expression::named_type_expression(const struct position position, const std::string& name) + : type_expression(position), name(name) + { + } + + void named_type_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + named_type_expression *named_type_expression::is_named() + { + return this; + } + + array_type_expression::array_type_expression(const struct position position, + type_expression *base, const std::uint32_t size) + : type_expression(position), m_base(base), size(size) + { + } + + array_type_expression::~array_type_expression() + { + delete m_base; + } + + void array_type_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + array_type_expression *array_type_expression::is_array() + { + return this; + } + + type_expression& array_type_expression::base() + { + return *m_base; + } + + pointer_type_expression::pointer_type_expression(const struct position position, + type_expression *base) + : type_expression(position), m_base(base) + { + } + + pointer_type_expression::~pointer_type_expression() + { + delete m_base; + } + + void pointer_type_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + pointer_type_expression *pointer_type_expression::is_pointer() + { + return this; + } + + type_expression& pointer_type_expression::base() + { + return *m_base; + } + + record_type_expression::record_type_expression(const struct position position, + std::vector<field_declaration>&& fields) + : type_expression(position), fields(std::move(fields)) + { + } + + record_type_expression::~record_type_expression() + { + for (const field_declaration& field : this->fields) + { + delete field.second; + } + } + + void record_type_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + record_type_expression *record_type_expression::is_record() + { + return this; + } + + union_type_expression::union_type_expression(const struct position position, + std::vector<field_declaration>&& fields) + : type_expression(position), fields(std::move(fields)) + { + } + + union_type_expression::~union_type_expression() + { + for (const field_declaration& field : this->fields) + { + delete field.second; + } + } + + void union_type_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + union_type_expression *union_type_expression::is_union() + { + return this; + } + + variable_declaration::variable_declaration(const struct position position, + std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type, + expression *body) + : node(position), m_variable_type(variable_type), identifiers(std::move(identifier)), body(body) + { + } + + variable_declaration::variable_declaration(const struct position position, + std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type, + std::monostate) + : node(position), m_variable_type(variable_type), identifiers(std::move(identifier)), is_extern(true) + { + } + + void variable_declaration::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + bool variable_declaration::has_initializer() const + { + return this->is_extern || this->body != nullptr; + } + + type_expression& variable_declaration::variable_type() + { + return *m_variable_type; + } + + declaration::declaration(const struct position position, identifier_definition identifier) + : node(position), identifier(identifier) + { + } + + constant_declaration::constant_declaration(const struct position position, identifier_definition identifier, + expression *body) + : declaration(position, identifier), m_body(body) + { + } + + void constant_declaration::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + expression& constant_declaration::body() + { + return *m_body; + } + + constant_declaration::~constant_declaration() + { + delete m_body; + } + + procedure_type_expression::procedure_type_expression(const struct position position, return_t return_type) + : type_expression(position), return_type(return_type) + { + } + + procedure_type_expression::~procedure_type_expression() + { + if (return_type.proper_type != nullptr) + { + delete return_type.proper_type; + } + for (const type_expression *parameter : this->parameters) + { + delete parameter; + } + } + + void procedure_type_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + procedure_type_expression *procedure_type_expression::is_procedure() + { + return this; + } + + enumeration_type_expression::enumeration_type_expression(const struct position position, std::vector<std::string>&& members) + : type_expression(position), members(members) + { + } + + void enumeration_type_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + enumeration_type_expression *enumeration_type_expression::is_enumeration() + { + return this; + } + + procedure_declaration::procedure_declaration(const struct position position, identifier_definition identifier, + procedure_type_expression *heading, block&& body) + : declaration(position, identifier), m_heading(heading), body(std::move(body)) + { + } + + procedure_declaration::procedure_declaration(const struct position position, identifier_definition identifier, + procedure_type_expression *heading) + : declaration(position, identifier), m_heading(heading), body(std::nullopt) + { + } + + void procedure_declaration::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + procedure_type_expression& procedure_declaration::heading() + { + return *m_heading; + } + + procedure_declaration::~procedure_declaration() + { + delete m_heading; + } + + type_declaration::type_declaration(const struct position position, identifier_definition identifier, + type_expression *body) + : declaration(position, identifier), m_body(body) + { + } + + type_declaration::~type_declaration() + { + delete m_body; + } + + void type_declaration::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + type_expression& type_declaration::body() + { + return *m_body; + } + + block::block(std::vector<constant_declaration *>&& constants, std::vector<variable_declaration *>&& variables, + std::vector<statement *>&& body) + : m_variables(std::move(variables)), m_constants(std::move(constants)), m_body(std::move(body)) + { + } + + block::block(block&& that) + : m_variables(std::move(that.m_variables)), m_constants(std::move(that.m_constants)), + m_body(std::move(that.m_body)) + { + } + + block& block::operator=(block&& that) + { + std::swap(m_variables, that.m_variables); + std::swap(m_constants, that.m_constants); + std::swap(m_body, that.m_body); + + return *this; + } + + const std::vector<variable_declaration *>& block::variables() + { + return m_variables; + } + + const std::vector<constant_declaration *>& block::constants() + { + return m_constants; + } + + const std::vector<statement *>& block::body() + { + return m_body; + } + + block::~block() + { + for (statement *body_statement : this->body()) + { + delete body_statement; + } + for (variable_declaration *variable : this->variables()) + { + delete variable; + } + for (constant_declaration *constant : this->constants()) + { + delete constant; + } + } + + unit::unit(const struct position position) + : node(position) + { + } + + void unit::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + unit::~unit() + { + for (procedure_declaration *procedure : this->procedures) + { + delete procedure; + } + for (variable_declaration *variable : this->variables) + { + delete variable; + } + for (type_declaration *type : this->types) + { + delete type; + } + for (constant_declaration *constant : this->constants) + { + delete constant; + } + for (import_declaration *declaration : this->imports) + { + delete declaration; + } + } + + program::program(const struct position position) + : unit(position) + { + } + + void program::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + program::~program() + { + for (statement *body_statement : this->body) + { + delete body_statement; + } + } + + literal_expression::literal_expression() + { + } + + literal_expression *literal_expression::is_literal() + { + return this; + } + + defer_statement::defer_statement(const struct position position, std::vector<statement *>&& statements) + : node(position), statements(std::move(statements)) + { + } + + 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() + { + } + + designator_expression::~designator_expression() + { + } + + designator_expression *designator_expression::is_designator() + { + return this; + } + + void designator_expression::accept(parser_visitor *visitor) + { + if (variable_expression *node = is_variable()) + { + return visitor->visit(node); + } + else if (array_access_expression *node = is_array_access()) + { + return visitor->visit(node); + } + else if (field_access_expression *node = is_field_access()) + { + return visitor->visit(node); + } + else if (dereference_expression *node = is_dereference()) + { + return visitor->visit(node); + } + __builtin_unreachable(); + } + + variable_expression::variable_expression(const struct position position, const std::string& name) + : node(position), name(name) + { + } + + void variable_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + variable_expression *variable_expression::is_variable() + { + return this; + } + + array_access_expression::array_access_expression(const struct position position, + expression *base, expression *index) + : node(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) + : node(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) + : node(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) + : node(position), m_lhs(lhs), m_rhs(rhs), m_operator(operation) + { + } + + void binary_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + binary_expression *binary_expression::is_binary() + { + return 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) + : node(position), m_operand(std::move(operand)), m_operator(operation) + { + } + + void unary_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + unary_expression *unary_expression::is_unary() + { + return 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; + } + + procedure_call::procedure_call(const struct position position, designator_expression *callable) + : node(position), m_callable(callable) + { + } + + void procedure_call::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + procedure_call *procedure_call::is_call_expression() + { + return this; + } + + designator_expression& procedure_call::callable() + { + return *m_callable; + } + + procedure_call::~procedure_call() + { + for (expression *const argument : arguments) + { + delete argument; + } + delete m_callable; + } + + cast_expression::cast_expression(const struct position position, type_expression *target, expression *value) + : node(position), m_target(target), m_value(value) + { + } + + void cast_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + cast_expression *cast_expression::is_cast() + { + return this; + } + + type_expression& cast_expression::target() + { + return *m_target; + } + + expression& cast_expression::value() + { + return *m_value; + } + + cast_expression::~cast_expression() + { + delete m_target; + delete m_value; + } + + traits_expression::traits_expression(const struct position position, const std::string& name) + : node(position), name(name) + { + } + + traits_expression::~traits_expression() + { + for (const type_expression *parameter : this->parameters) + { + delete parameter; + } + } + + void traits_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + traits_expression *traits_expression::is_traits() + { + return this; + } + + conditional_statements::conditional_statements(expression *prerequisite, std::vector<statement *>&& statements) + : m_prerequisite(prerequisite), statements(std::move(statements)) + { + } + + 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) + : node(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; + } + + case_statement::case_statement(const struct position position, + expression *condition, std::vector<switch_case>&& cases, std::vector<statement *> *alternative) + : node(position), m_condition(condition), cases(std::move(cases)), alternative(alternative) + { + } + + void case_statement::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + expression& case_statement::condition() + { + return *m_condition; + } + + assign_statement::assign_statement(const struct position position, designator_expression *lvalue, + expression *rvalue) + : node(position), m_lvalue(lvalue), m_rvalue(rvalue) + { + } + + void assign_statement::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + 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<conditional_statements *>&& branches, + std::vector<statement *> *alternative) + : node(position), m_body(body), branches(std::move(branches)), alternative(alternative) + { + } + + void if_statement::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + conditional_statements& if_statement::body() + { + return *m_body; + } + + if_statement::~if_statement() + { + delete m_body; + for (const auto branch : branches) + { + delete branch; + } + delete this->alternative; + } + + import_declaration::import_declaration(const struct position position, std::vector<std::string>&& segments) + : node(position), segments(std::move(segments)) + { + } + + void import_declaration::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + while_statement::while_statement(const struct position position, conditional_statements *body, + std::vector<conditional_statements *>&& branches) + : node(position), m_body(body), branches(std::move(branches)) + { + } + + 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(); + }; +} |
