// 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(declaration *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); } 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 (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& constant : block->definitions()) { constant->accept(this); } for (const auto& block_declaration : block->declarations()) { block_declaration->accept(this); } block->body().accept(this); } void empty_visitor::visit(program *program) { 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(type_expression *variable) { } void empty_visitor::visit(variable_expression *variable) { } void empty_visitor::visit(number_literal *number) { } void empty_visitor::visit(number_literal *number) { } void empty_visitor::visit(boolean_literal *boolean) { } operand::~operand() noexcept { } integer_operand::integer_operand(const std::int32_t value) : m_value(value) { } std::int32_t integer_operand::value() const noexcept { return m_value; } variable_operand::variable_operand(const std::string& name) : m_name(name) { } const std::string& variable_operand::name() const noexcept { return m_name; } temporary_variable::temporary_variable(const std::size_t counter) : m_counter(counter) { } std::size_t temporary_variable::counter() const noexcept { return m_counter; } label_operand::label_operand(const std::size_t counter) : m_counter(counter) { } std::size_t label_operand::counter() const noexcept { return m_counter; } node::node(const struct position position) : source_position(position) { } const struct position& node::position() const noexcept { 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, const std::string& name, const bool is_pointer) : node(position), m_base(name), m_pointer(is_pointer) { } void type_expression::accept(parser_visitor *visitor) { visitor->visit(this); } const std::string& type_expression::base() const noexcept { return m_base; } bool type_expression::is_pointer() const noexcept { return m_pointer; } declaration::declaration(const struct position position, const std::string& identifier, std::unique_ptr&& type) : definition(position, identifier), m_type(std::move(type)) { } void declaration::accept(parser_visitor *visitor) { visitor->visit(this); } type_expression& declaration::type() noexcept { return *m_type; } definition::definition(const struct position position, const std::string& identifier) : node(position), m_identifier(identifier) { } std::string& definition::identifier() noexcept { return m_identifier; } constant_definition::constant_definition(const struct position position, const std::string& identifier, std::unique_ptr>&& body) : definition(position, identifier), m_body(std::move(body)) { } void constant_definition::accept(parser_visitor *visitor) { visitor->visit(this); } number_literal& constant_definition::body() { return *m_body; } procedure_definition::procedure_definition(const struct position position, const std::string& identifier, std::unique_ptr&& body) : definition(position, identifier), m_body(std::move(body)) { } void procedure_definition::accept(parser_visitor *visitor) { visitor->visit(this); } block& procedure_definition::body() { return *m_body; } std::vector>& procedure_definition::parameters() noexcept { return m_parameters; } block::block(const struct position position, std::vector>&& definitions, std::vector>&& declarations, std::unique_ptr&& body) : node(position), m_definitions(std::move(definitions)), m_declarations(std::move(declarations)), m_body(std::move(body)) { } void block::accept(parser_visitor *visitor) { visitor->visit(this); } statement& block::body() { return *m_body; } std::vector>& block::definitions() noexcept { return m_definitions; } std::vector>& block::declarations() noexcept { return m_declarations; } program::program(const struct position position, std::vector>&& definitions, std::vector>&& declarations, std::unique_ptr&& body) : block(position, std::move(definitions), std::move(declarations), std::move(body)) { } void program::accept(parser_visitor *visitor) { visitor->visit(this); } boolean_literal::boolean_literal(const struct position position, const bool value) : expression(position), m_boolean(value) { } void boolean_literal::accept(parser_visitor *visitor) { visitor->visit(this); } bool boolean_literal::boolean() const noexcept { return m_boolean; } variable_expression::variable_expression(const struct position position, const std::string& name) : expression(position), m_name(name) { } void variable_expression::accept(parser_visitor *visitor) { visitor->visit(this); } const std::string& variable_expression::name() const noexcept { return m_name; } binary_expression::binary_expression(const struct position position, std::unique_ptr&& lhs, std::unique_ptr&& 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; 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 noexcept { return m_operator; } unary_expression::unary_expression(const struct position position, std::unique_ptr&& 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::dereference; 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 noexcept { return this->m_operator; } 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() noexcept { return m_name; } std::vector>& call_statement::arguments() noexcept { return m_arguments; } compound_statement::compound_statement(const struct position position) : statement(position) { } void compound_statement::accept(parser_visitor *visitor) { visitor->visit(this); } std::vector>& compound_statement::statements() { return m_statements; } void assign_statement::accept(parser_visitor *visitor) { visitor->visit(this); } assign_statement::assign_statement(const struct position position, const std::string& lvalue, std::unique_ptr&& rvalue) : statement(position), m_lvalue(lvalue), m_rvalue(std::move(rvalue)) { } std::string& assign_statement::lvalue() noexcept { return m_lvalue; } expression& assign_statement::rvalue() { return *m_rvalue; } if_statement::if_statement(const struct position position, std::unique_ptr&& prerequisite, std::unique_ptr&& body, std::unique_ptr&& alternative) : statement(position), m_prerequisite(std::move(prerequisite)), m_body(std::move(body)), m_alternative(std::move(alternative)) { } void if_statement::accept(parser_visitor *visitor) { visitor->visit(this); } expression& if_statement::prerequisite() { return *m_prerequisite; } statement& if_statement::body() { return *m_body; } std::unique_ptr& if_statement::alternative() { return m_alternative; } while_statement::while_statement(const struct position position, std::unique_ptr&& prerequisite, std::unique_ptr&& body) : statement(position), m_prerequisite(std::move(prerequisite)), m_body(std::move(body)) { } void while_statement::accept(parser_visitor *visitor) { visitor->visit(this); } expression& while_statement::prerequisite() { return *m_prerequisite; } statement& while_statement::body() { return *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 ">="; } }; } }