/* 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"
#include
namespace elna::boot
{
void empty_visitor::visit(array_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(slice_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(pointer_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(constant_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(type_declaration *)
{
__builtin_unreachable();
}
void empty_visitor::visit(record_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(procedure_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(enumeration_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(variable_declaration *)
{
__builtin_unreachable();
}
void empty_visitor::visit(procedure_declaration *)
{
__builtin_unreachable();
}
void empty_visitor::visit(assign_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(if_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(import_declaration *)
{
__builtin_unreachable();
}
void empty_visitor::visit(while_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(defer_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(empty_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(case_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(procedure_call *)
{
__builtin_unreachable();
}
void empty_visitor::visit(unit *)
{
__builtin_unreachable();
}
void empty_visitor::visit(cast_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(record_constructor_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(array_constructor_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(slicing_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(traits_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(binary_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(unary_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(named_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(array_access_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(field_access_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(dereference_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal *)
{
__builtin_unreachable();
}
void walking_visitor::visit(import_declaration *)
{
}
void walking_visitor::visit(procedure_declaration *declaration)
{
for (const field_declaration& parameter : declaration->heading().parameters)
{
parameter.second->accept(this);
}
if (declaration->heading().return_type.proper_type != nullptr)
{
declaration->heading().return_type.proper_type->accept(this);
}
if (declaration->body.has_value())
{
for (variable_declaration *variable : declaration->body.value().variables)
{
variable->accept(this);
}
for (auto *statement : declaration->body.value().entry_point)
{
statement->accept(this);
}
if (declaration->body.value().return_expression != nullptr)
{
declaration->body.value().return_expression->accept(this);
}
}
}
void walking_visitor::visit(assign_statement *statement)
{
statement->lvalue().accept(this);
statement->rvalue().accept(this);
}
void walking_visitor::visit(if_statement *statement)
{
statement->branch().prerequisite().accept(this);
for (auto *branch_statement : statement->branch().statements)
{
branch_statement->accept(this);
}
for (conditional_statements *branch : statement->branches)
{
branch->prerequisite().accept(this);
for (auto *branch_statement : branch->statements)
{
branch_statement->accept(this);
}
}
if (statement->alternative != nullptr)
{
for (auto *branch_statement : *statement->alternative)
{
branch_statement->accept(this);
}
}
}
void walking_visitor::visit(while_statement *statement)
{
statement->branch().prerequisite().accept(this);
for (auto *branch_statement : statement->branch().statements)
{
branch_statement->accept(this);
}
for (conditional_statements *branch : statement->branches)
{
branch->prerequisite().accept(this);
for (auto *branch_statement : branch->statements)
{
branch_statement->accept(this);
}
}
}
void walking_visitor::visit(defer_statement *statement)
{
for (auto *block_statement : statement->statements)
{
block_statement->accept(this);
}
}
void walking_visitor::visit(empty_statement *)
{
}
void walking_visitor::visit(case_statement *statement)
{
statement->condition().accept(this);
for (const switch_case& case_block : statement->cases)
{
for (expression *case_label : case_block.labels)
{
case_label->accept(this);
}
for (auto *block_statement : case_block.statements)
{
block_statement->accept(this);
}
}
if (statement->alternative != nullptr)
{
for (auto *block_statement : *statement->alternative)
{
block_statement->accept(this);
}
}
}
void walking_visitor::visit(procedure_call *call)
{
call->callable().accept(this);
for (expression *argument : call->arguments)
{
argument->accept(this);
}
}
void walking_visitor::visit(unit *unit)
{
for (import_declaration *_import : unit->imports)
{
_import->accept(this);
}
for (type_declaration *type : unit->types)
{
type->accept(this);
}
for (variable_declaration *variable : unit->variables)
{
variable->accept(this);
}
for (procedure_declaration *procedure : unit->procedures)
{
procedure->accept(this);
}
for (auto *entry_statement : unit->entry_point)
{
entry_statement->accept(this);
}
}
void walking_visitor::visit(type_declaration *declaration)
{
declaration->underlying_type().accept(this);
}
void walking_visitor::visit(variable_declaration *declaration)
{
declaration->variable_type().accept(this);
if (declaration->initializer != nullptr)
{
declaration->initializer->accept(this);
}
}
void walking_visitor::visit(array_type_expression *expression)
{
expression->base().accept(this);
}
void walking_visitor::visit(slice_type_expression *expression)
{
expression->base().accept(this);
}
void walking_visitor::visit(pointer_type_expression *expression)
{
expression->base().accept(this);
}
void walking_visitor::visit(constant_type_expression *expression)
{
expression->base().accept(this);
}
void walking_visitor::visit(record_type_expression *expression)
{
for (const field_declaration& field : expression->fields)
{
field.second->accept(this);
}
}
void walking_visitor::visit(procedure_type_expression *expression)
{
for (const field_declaration& field : expression->parameters)
{
field.second->accept(this);
}
if (expression->return_type.proper_type != nullptr)
{
expression->return_type.proper_type->accept(this);
}
}
void walking_visitor::visit(enumeration_type_expression *)
{
}
void walking_visitor::visit(cast_expression *expression)
{
expression->value().accept(this);
expression->target().accept(this);
}
void walking_visitor::visit(record_constructor_expression *expression)
{
for (const field_initializer& initializer : expression->field_initializers)
{
initializer.value().accept(this);
}
}
void walking_visitor::visit(array_constructor_expression *expression)
{
expression->m_element_type->accept(this);
for (auto *element : expression->elements)
{
element->accept(this);
}
}
void walking_visitor::visit(slicing_expression *expression)
{
expression->base().accept(this);
expression->start().accept(this);
expression->end().accept(this);
}
void walking_visitor::visit(traits_expression *trait)
{
if (!trait->arguments.empty())
{
trait->arguments.front()->accept(this);
}
}
void walking_visitor::visit(binary_expression *expression)
{
expression->lhs().accept(this);
expression->rhs().accept(this);
}
void walking_visitor::visit(unary_expression *expression)
{
expression->operand().accept(this);
}
void walking_visitor::visit(named_expression *)
{
}
void walking_visitor::visit(array_access_expression *expression)
{
expression->base().accept(this);
expression->index().accept(this);
}
void walking_visitor::visit(field_access_expression *expression)
{
expression->base().accept(this);
}
void walking_visitor::visit(dereference_expression *expression)
{
expression->base().accept(this);
}
void walking_visitor::visit(literal *)
{
}
void walking_visitor::visit(literal *)
{
}
void walking_visitor::visit(literal *)
{
}
void walking_visitor::visit(literal *)
{
}
void walking_visitor::visit(literal *)
{
}
void walking_visitor::visit(literal *)
{
}
void walking_visitor::visit(literal *)
{
}
node::node(const source_position position)
: m_position(position)
{
}
node::~node() = default;
const source_position& node::position() const
{
return this->m_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;
}
record_constructor_expression *expression::is_record_constructor()
{
return nullptr;
}
array_constructor_expression *expression::is_array_constructor()
{
return nullptr;
}
named_expression *type_expression::is_named()
{
return nullptr;
}
slice_type_expression *type_expression::is_slice()
{
return nullptr;
}
array_type_expression *type_expression::is_array()
{
return nullptr;
}
pointer_type_expression *type_expression::is_pointer()
{
return nullptr;
}
constant_type_expression *type_expression::is_constant()
{
return nullptr;
}
record_type_expression *type_expression::is_record()
{
return nullptr;
}
procedure_type_expression *type_expression::is_procedure()
{
return nullptr;
}
enumeration_type_expression *type_expression::is_enumeration()
{
return nullptr;
}
array_type_expression::array_type_expression(const source_position position,
type_expression *base, const std::uint32_t size)
: node(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;
}
slice_type_expression::slice_type_expression(const source_position position,
type_expression *base)
: node(position), m_base(base)
{
}
slice_type_expression::~slice_type_expression()
{
delete m_base;
}
void slice_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
slice_type_expression *slice_type_expression::is_slice()
{
return this;
}
type_expression& slice_type_expression::base()
{
return *m_base;
}
pointer_type_expression::pointer_type_expression(const source_position position,
type_expression *base)
: node(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;
}
constant_type_expression::constant_type_expression(const source_position position,
type_expression *base)
: node(position), m_base(base)
{
}
constant_type_expression::~constant_type_expression()
{
delete m_base;
}
void constant_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
constant_type_expression *constant_type_expression::is_constant()
{
return this;
}
type_expression& constant_type_expression::base()
{
return *m_base;
}
record_type_expression::record_type_expression(const source_position position,
std::vector&& fields)
: node(position), fields(std::move(fields))
{
}
record_type_expression::record_type_expression(const source_position position,
std::vector&& fields, identifier&& base)
: node(position), fields(std::move(fields)), base(std::make_optional(std::move(base)))
{
}
void record_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
record_type_expression *record_type_expression::is_record()
{
return this;
}
field_initializer::field_initializer(identifier name, expression *value)
: m_name(std::move(name)), m_value(value)
{
}
field_initializer::~field_initializer()
{
delete this->m_value;
}
field_initializer::field_initializer(field_initializer&& other) noexcept
: m_name(std::move(other.m_name)), m_value(other.m_value)
{
other.m_value = nullptr;
}
field_initializer& field_initializer::operator=(field_initializer&& other) noexcept
{
delete this->m_value;
this->m_name = std::move(other.m_name);
this->m_value = other.m_value;
other.m_value = nullptr;
return *this;
}
const std::string& field_initializer::name() const
{
return this->m_name.name();
}
const identifier& field_initializer::id() const
{
return this->m_name;
}
expression& field_initializer::value() const
{
return *this->m_value;
}
record_constructor_expression::record_constructor_expression(const source_position position,
identifier&& type_name,
std::vector&& field_initializers)
: node(position), type_name(std::move(type_name)), field_initializers(std::move(field_initializers))
{
}
void record_constructor_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
record_constructor_expression *record_constructor_expression::is_record_constructor()
{
return this;
}
array_constructor_expression::array_constructor_expression(const source_position position,
std::uint32_t size, type_expression *element_type,
std::vector&& elements)
: node(position), size(size), m_element_type(element_type), elements(std::move(elements))
{
}
void array_constructor_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
array_constructor_expression *array_constructor_expression::is_array_constructor()
{
return this;
}
array_constructor_expression::~array_constructor_expression()
{
delete m_element_type;
for (const expression *element : elements)
{
delete element;
}
}
variable_declaration::variable_declaration(const source_position position,
std::vector&& identifier, std::shared_ptr variable_type,
expression *initializer)
: node(position), m_variable_type(std::move(variable_type)), identifiers(std::move(identifier)), initializer(initializer)
{
}
variable_declaration::variable_declaration(const source_position position,
std::vector&& identifier, std::shared_ptr variable_type,
std::monostate)
: node(position), m_variable_type(std::move(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->initializer != nullptr;
}
type_expression& variable_declaration::variable_type()
{
return *m_variable_type;
}
declaration::declaration(const source_position position, identifier_definition identifier)
: node(position), identifier(std::move(identifier))
{
}
procedure_type_expression::procedure_type_expression(const source_position position,
std::vector&& parameters, return_t return_type)
: node(position), return_type(return_type), parameters(std::move(parameters))
{
}
procedure_type_expression::~procedure_type_expression()
{
delete return_type.proper_type;
}
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 source_position position,
std::vector&& members)
: node(position), members(std::move(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 source_position position, identifier_definition identifier,
procedure_type_expression *heading, procedure_body&& body)
: declaration(position, std::move(identifier)), m_heading(heading),
body(std::make_optional(std::move(body)))
{
}
procedure_declaration::procedure_declaration(const source_position position, identifier_definition identifier,
procedure_type_expression *heading)
: declaration(position, std::move(identifier)), m_heading(heading)
{
}
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 source_position position, identifier_definition identifier,
type_expression *underlying_type)
: declaration(position, std::move(identifier)), m_underlying_type(underlying_type)
{
}
type_declaration::~type_declaration()
{
delete m_underlying_type;
}
void type_declaration::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
type_expression& type_declaration::underlying_type()
{
return *m_underlying_type;
}
procedure_body::procedure_body(std::vector&& variables,
std::vector&& entry_point, expression *return_expression)
: variables(std::move(variables)),
entry_point(std::move(entry_point)), return_expression(return_expression)
{
}
procedure_body::procedure_body(procedure_body&& that)
: variables(std::move(const_cast&>(that.variables))),
entry_point(std::move(const_cast&>(that.entry_point))),
return_expression(that.return_expression)
{
}
procedure_body::~procedure_body()
{
for (const statement *body_statement : this->entry_point)
{
delete body_statement;
}
for (const variable_declaration *variable : this->variables)
{
delete variable;
}
}
unit::unit(const source_position position)
: node(position),
procedure_body(std::vector{}, std::vector{}, nullptr)
{
}
unit::unit(const source_position position,
std::vector&& imports,
std::vector&& types,
std::vector&& variables,
std::vector&& procedures,
std::vector&& entry_point)
: node(position),
procedure_body(std::move(variables), std::move(entry_point)),
imports(std::move(imports)), types(std::move(types)), procedures(std::move(procedures))
{
}
void unit::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
bool unit::has_body() const
{
return !this->entry_point.empty();
}
unit::~unit()
{
for (const procedure_declaration *procedure : this->procedures)
{
delete procedure;
}
for (const type_declaration *type : this->types)
{
delete type;
}
for (const import_declaration *declaration : this->imports)
{
delete declaration;
}
}
literal_expression *literal_expression::is_literal()
{
return this;
}
defer_statement::defer_statement(const source_position position, std::vector&& statements)
: node(position), statements(std::move(statements))
{
}
void defer_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
defer_statement::~defer_statement()
{
for (const statement *body_statement : statements)
{
delete body_statement;
}
}
void empty_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
empty_statement::empty_statement(const source_position position)
: node(position)
{
}
designator_expression::~designator_expression() = default;
designator_expression *designator_expression::is_designator()
{
return this;
}
void designator_expression::accept(parser_visitor *visitor)
{
if (named_expression *node = is_named())
{
visitor->visit(node);
}
else if (array_access_expression *node = is_array_access())
{
visitor->visit(node);
}
else if (field_access_expression *node = is_field_access())
{
visitor->visit(node);
}
else if (dereference_expression *node = is_dereference())
{
visitor->visit(node);
}
else
{
__builtin_unreachable();
}
}
slicing_expression::slicing_expression(const source_position position,
expression *base, expression *start, expression *end)
: node(position), m_base(base), m_start(start), m_end(end)
{
}
void slicing_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
slicing_expression *slicing_expression::is_slicing()
{
return this;
}
slicing_expression::~slicing_expression()
{
delete m_base;
delete m_start;
delete m_end;
}
expression& slicing_expression::base()
{
return *this->m_base;
}
expression& slicing_expression::start()
{
return *this->m_start;
}
expression& slicing_expression::end()
{
return *this->m_end;
}
named_expression::named_expression(const source_position position, const std::string& name)
: node(position), name(name)
{
}
void named_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
named_expression *named_expression::is_named()
{
return this;
}
array_access_expression::array_access_expression(const source_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 source_position position,
expression *base, identifier&& field)
: node(position), m_base(base), m_field(std::move(field))
{
}
void field_access_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
expression& field_access_expression::base()
{
return *m_base;
}
const identifier& 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 source_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 source_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;
}
void binary_expression::operation(binary_operator operation)
{
this->m_operator = operation;
}
binary_expression::~binary_expression()
{
delete m_lhs;
delete m_rhs;
}
unary_expression::unary_expression(const source_position position, expression *operand,
const unary_operator operation)
: node(position), m_operand(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;
}
void unary_expression::operation(unary_operator operation)
{
this->m_operator = operation;
}
unary_expression::~unary_expression()
{
delete m_operand;
}
procedure_call::procedure_call(const source_position position, designator_expression *callable,
std::vector&& arguments)
: node(position), m_callable(callable), arguments(std::move(arguments))
{
}
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 (const expression *argument : arguments)
{
delete argument;
}
delete m_callable;
}
cast_expression::cast_expression(const source_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 source_position position, identifier&& name,
std::vector&& arguments)
: node(position), arguments(std::move(arguments)), name(std::move(name))
{
}
traits_expression::~traits_expression()
{
for (const type_expression *argument : this->arguments)
{
delete argument;
}
}
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&& 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;
}
}
case_statement::case_statement(const source_position position,
expression *condition, std::vector&& cases, std::vector *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 source_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);
}
named_expression *designator_expression::is_named()
{
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;
}
slicing_expression *designator_expression::is_slicing()
{
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 source_position position, conditional_statements *branch,
std::vector&& branches,
std::vector *alternative)
: node(position), m_branch(branch), branches(std::move(branches)), alternative(alternative)
{
}
void if_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
conditional_statements& if_statement::branch()
{
return *m_branch;
}
if_statement::~if_statement()
{
delete m_branch;
for (const conditional_statements *branch : branches)
{
delete branch;
}
delete this->alternative;
}
import_declaration::import_declaration(const source_position position, std::vector&& segments)
: node(position), segments(std::move(segments))
{
}
void import_declaration::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
while_statement::while_statement(const source_position position, conditional_statements *branch,
std::vector&& branches)
: node(position), m_branch(branch), branches(std::move(branches))
{
}
void while_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
conditional_statements& while_statement::branch()
{
return *m_branch;
}
while_statement::~while_statement()
{
delete m_branch;
for (const conditional_statements *branch : branches)
{
delete branch;
}
}
const char *print_binary_operator(const binary_operator operation)
{
switch (operation)
{
using enum binary_operator;
case sum:
return "+";
case subtraction:
return "-";
case multiplication:
return "*";
case division:
return "/";
case remainder:
return "%";
case equals:
return "=";
case not_equals:
return "<>";
case less:
return "<";
case less_equal:
return "<=";
case greater:
return ">";
case greater_equal:
return ">=";
case conjunction:
case logical_conjunction:
case bitwise_conjunction:
return "&";
case disjunction:
case logical_disjunction:
case bitwise_disjunction:
return "or";
case exclusive_disjunction:
case logical_exclusive_disjunction:
case bitwise_exclusive_disjunction:
return "xor";
case shift_left:
return "<<";
case shift_right:
return ">>";
}
__builtin_unreachable();
};
}