summaryrefslogtreecommitdiff
path: root/frontend/ast.cc
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/ast.cc')
-rw-r--r--frontend/ast.cc1178
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();
+ };
+}