// This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "elna/source/ast.h" namespace elna { namespace source { void empty_visitor::visit(variable_declaration *) { } void empty_visitor::visit(constant_definition *definition) { definition->body().accept(this); } void empty_visitor::visit(procedure_definition *definition) { for (auto parameter : definition->parameters) { parameter->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_statement *statement) { for (auto& argument : statement->arguments()) { argument->accept(this); } } void empty_visitor::visit(compound_statement *statement) { for (const auto nested_statement : statement->statements) { nested_statement->accept(this); } } void empty_visitor::visit(assign_statement *statement) { statement->rvalue().accept(this); } void empty_visitor::visit(if_statement *statement) { statement->prerequisite().accept(this); statement->body().accept(this); } void empty_visitor::visit(while_statement *statement) { statement->prerequisite().accept(this); statement->body().accept(this); } void empty_visitor::visit(block *block) { for (const auto definition : block->value_definitions) { definition->accept(this); } for (const auto body_statement : block->body) { body_statement->accept(this); } } void empty_visitor::visit(program *program) { for (auto definition : program->type_definitions) { definition->accept(this); } visit(reinterpret_cast(program)); } 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_expression *) { } void empty_visitor::visit(array_type_expression *expression) { expression->base().accept(this); } void empty_visitor::visit(pointer_type_expression *expression) { expression->base().accept(this); } void empty_visitor::visit(record_type_expression *expression) { for (auto& field : expression->fields) { field.second->accept(this); } } void empty_visitor::visit(union_type_expression *expression) { for (auto& field : expression->fields) { field.second->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(string_literal *) { } operand::~operand() { } integer_operand::integer_operand(const std::int32_t value) : m_value(value) { } std::int32_t integer_operand::value() const { return m_value; } variable_operand::variable_operand(const std::string& name) : m_name(name) { } const std::string& variable_operand::name() const { return m_name; } temporary_variable::temporary_variable(const std::size_t counter) : m_counter(counter) { } std::size_t temporary_variable::counter() const { return m_counter; } label_operand::label_operand(const std::size_t counter) : m_counter(counter) { } std::size_t label_operand::counter() const { return m_counter; } 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) { } type_expression::type_expression(const struct position position) : node(position) { } basic_type_expression *type_expression::is_basic() { return nullptr; } array_type_expression *type_expression::is_array() { return nullptr; } record_type_expression *type_expression::is_record() { return nullptr; } union_type_expression *type_expression::is_union() { return nullptr; } pointer_type_expression *type_expression::is_pointer() { return nullptr; } basic_type_expression::basic_type_expression( const struct position position, const std::string& name) : type_expression(position), m_name(name) { } void basic_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } const std::string& basic_type_expression::base_name() { return m_name; } basic_type_expression *basic_type_expression::is_basic() { 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) { } void array_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } type_expression& array_type_expression::base() { return *m_base; } array_type_expression *array_type_expression::is_array() { return this; } array_type_expression::~array_type_expression() { delete m_base; } pointer_type_expression::pointer_type_expression(const struct position position, type_expression *base) : type_expression(position), m_base(base) { } void pointer_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } type_expression& pointer_type_expression::base() { return *m_base; } pointer_type_expression *pointer_type_expression::is_pointer() { return this; } pointer_type_expression::~pointer_type_expression() { delete m_base; } composite_type_expression::composite_type_expression(const struct position position, fields_t&& fields) : type_expression(position), fields(std::move(fields)) { } composite_type_expression::~composite_type_expression() { for (auto& field_declaration : fields) { delete field_declaration.second; } } record_type_expression::record_type_expression(const struct position position, fields_t&& fields) : composite_type_expression(position, std::move(fields)) { } 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, fields_t&& fields) : composite_type_expression(position, std::move(fields)) { } union_type_expression *union_type_expression::is_union() { return this; } void union_type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } variable_declaration::variable_declaration(const struct position position, const std::string& identifier, type_expression *type) : definition(position, identifier), m_type(type) { } variable_declaration::~variable_declaration() { delete m_type; } void variable_declaration::accept(parser_visitor *visitor) { visitor->visit(this); } type_expression& variable_declaration::type() { return *m_type; } definition::definition(const struct position position, const std::string& identifier) : node(position), m_identifier(identifier) { } std::string& definition::identifier() { return m_identifier; } constant_definition::constant_definition(const struct position position, const std::string& identifier, literal *body) : definition(position, identifier), 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_definition::procedure_definition(const struct position position, const std::string& identifier, block *body) : definition(position, identifier), m_body(body) { } void procedure_definition::accept(parser_visitor *visitor) { visitor->visit(this); } block *procedure_definition::body() { return m_body; } procedure_definition::~procedure_definition() { if (m_body != nullptr) { delete m_body; } for (auto parameter : parameters) { delete parameter; } } type_definition::type_definition(const struct position position, const std::string& identifier, type_expression *body) : definition(position, identifier), m_body(body) { } void type_definition::accept(parser_visitor *visitor) { visitor->visit(this); } type_expression& type_definition::body() { return *m_body; } type_definition::~type_definition() { delete m_body; } block::block(const struct position position, std::vector&& value_definitions, std::vector&& body) : node(position), value_definitions(std::move(value_definitions)), body(std::move(body)) { } void block::accept(parser_visitor *visitor) { visitor->visit(this); } block::~block() { for (auto definition : this->value_definitions) { delete definition; } for (auto body_statement : this->body) { delete body_statement; } } program::program(const struct position position, std::vector&& type_definitions, std::vector&& value_definitions, std::vector&& body) : block(position, std::move(value_definitions), std::move(body)), type_definitions(std::move(type_definitions)) { } void program::accept(parser_visitor *visitor) { visitor->visit(this); } program::~program() { for (auto definition : type_definitions) { delete definition; } } literal::literal(const struct position position) : expression(position) { } string_literal::string_literal(const struct position position, const std::string& value) : literal(position), m_string(value) { } void string_literal::accept(parser_visitor *visitor) { visitor->visit(this); } const std::string& string_literal::string() const { return m_string; } 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, designator_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; } designator_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_base; } field_access_expression::field_access_expression(const struct position position, designator_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); } designator_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, designator_expression *base) : designator_expression(position), m_base(base) { } void dereference_expression::accept(parser_visitor *visitor) { visitor->visit(this); } designator_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 unsigned char operation) : expression(position), m_lhs(std::move(lhs)), m_rhs(std::move(rhs)) { switch (operation) { case '+': this->m_operator = binary_operator::sum; break; case '-': this->m_operator = binary_operator::subtraction; break; case '*': this->m_operator = binary_operator::multiplication; break; case '/': this->m_operator = binary_operator::division; break; case '=': this->m_operator = binary_operator::equals; break; case 'n': this->m_operator = binary_operator::not_equals; break; case '<': this->m_operator = binary_operator::less; break; case 'l': this->m_operator = binary_operator::less_equal; break; case '>': this->m_operator = binary_operator::greater; break; case 'g': this->m_operator = binary_operator::greater_equal; break; case 'o': this->m_operator = binary_operator::disjunction; break; case 'a': this->m_operator = binary_operator::conjunction; break; default: __builtin_unreachable(); } } 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 unsigned char operation) : expression(position), m_operand(std::move(operand)) { switch (operation) { case '@': this->m_operator = unary_operator::reference; break; case '!': this->m_operator = unary_operator::negation; break; default: __builtin_unreachable(); } } 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_statement::call_statement(const struct position position, const std::string& name) : statement(position), m_name(name) { } void call_statement::accept(parser_visitor *visitor) { visitor->visit(this); } std::string& call_statement::name() { return m_name; } std::vector& call_statement::arguments() { return m_arguments; } call_statement::~call_statement() { for (auto argument : m_arguments) { delete argument; } } compound_statement::compound_statement(const struct position position, std::vector&& statements) : statement(position), statements(std::move(statements)) { } void compound_statement::accept(parser_visitor *visitor) { visitor->visit(this); } compound_statement::~compound_statement() { for (auto statement : statements) { delete statement; } } 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, expression *prerequisite, compound_statement *body, compound_statement *alternative) : statement(position), m_prerequisite(prerequisite), m_body(body), m_alternative(alternative) { } void if_statement::accept(parser_visitor *visitor) { visitor->visit(this); } expression& if_statement::prerequisite() { return *m_prerequisite; } compound_statement& if_statement::body() { return *m_body; } compound_statement *if_statement::alternative() { return m_alternative; } if_statement::~if_statement() { delete m_prerequisite; delete m_body; if (m_alternative != nullptr) { delete m_alternative; } } while_statement::while_statement(const struct position position, expression *prerequisite, compound_statement *body) : statement(position), m_prerequisite(prerequisite), m_body(body) { } void while_statement::accept(parser_visitor *visitor) { visitor->visit(this); } expression& while_statement::prerequisite() { return *m_prerequisite; } compound_statement& while_statement::body() { return *m_body; } while_statement::~while_statement() { delete m_prerequisite; delete m_body; } 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::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"; } __builtin_unreachable(); }; } }