1020 lines
22 KiB
C++
1020 lines
22 KiB
C++
/* 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/boot/ast.h"
|
|
|
|
namespace elna
|
|
{
|
|
namespace boot
|
|
{
|
|
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_expression *expression)
|
|
{
|
|
for (auto& argument : expression->arguments())
|
|
{
|
|
argument->accept(this);
|
|
}
|
|
}
|
|
|
|
void empty_visitor::visit(cast_expression *expression)
|
|
{
|
|
expression->target().accept(this);
|
|
expression->value().accept(this);
|
|
}
|
|
|
|
void empty_visitor::visit(type_expression *expression)
|
|
{
|
|
expression->body().accept(this);
|
|
}
|
|
|
|
void empty_visitor::visit(call_statement *statement)
|
|
{
|
|
statement->body().accept(this);
|
|
}
|
|
|
|
void empty_visitor::visit(assign_statement *statement)
|
|
{
|
|
statement->rvalue().accept(this);
|
|
}
|
|
|
|
void empty_visitor::visit(if_statement *statement)
|
|
{
|
|
statement->body().prerequisite().accept(this);
|
|
for (const auto body_statement : statement->body().statements)
|
|
{
|
|
body_statement->accept(this);
|
|
}
|
|
}
|
|
|
|
void empty_visitor::visit(while_statement *statement)
|
|
{
|
|
statement->body().prerequisite().accept(this);
|
|
for (const auto body_statement : statement->body().statements)
|
|
{
|
|
body_statement->accept(this);
|
|
}
|
|
}
|
|
|
|
void empty_visitor::visit(return_statement *statement)
|
|
{
|
|
expression *return_expression = statement->return_expression();
|
|
|
|
if (return_expression != nullptr)
|
|
{
|
|
return_expression->accept(this);
|
|
}
|
|
}
|
|
|
|
void empty_visitor::visit(defer_statement *defer)
|
|
{
|
|
for (statement *const body_statement : defer->statements)
|
|
{
|
|
body_statement->accept(this);
|
|
}
|
|
}
|
|
|
|
void empty_visitor::visit(block *block)
|
|
{
|
|
for (constant_definition *const constant : block->constants)
|
|
{
|
|
constant->accept(this);
|
|
}
|
|
for (variable_declaration *const variable : block->variables)
|
|
{
|
|
variable->accept(this);
|
|
}
|
|
for (statement *const body_statement : block->body)
|
|
{
|
|
body_statement->accept(this);
|
|
}
|
|
}
|
|
|
|
void empty_visitor::visit(program *program)
|
|
{
|
|
visit(reinterpret_cast<block *>(program));
|
|
for (type_definition *const type : program->types)
|
|
{
|
|
type->accept(this);
|
|
}
|
|
for (procedure_definition *const procedure : program->procedures)
|
|
{
|
|
procedure->accept(this);
|
|
}
|
|
}
|
|
|
|
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 *)
|
|
{
|
|
}
|
|
|
|
void empty_visitor::visit(array_type *expression)
|
|
{
|
|
expression->base().accept(this);
|
|
}
|
|
|
|
void empty_visitor::visit(pointer_type *expression)
|
|
{
|
|
expression->base().accept(this);
|
|
}
|
|
|
|
void empty_visitor::visit(record_type *expression)
|
|
{
|
|
for (auto& field : expression->fields)
|
|
{
|
|
field.second->accept(this);
|
|
}
|
|
}
|
|
|
|
void empty_visitor::visit(union_type *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<std::int32_t> *)
|
|
{
|
|
}
|
|
|
|
void empty_visitor::visit(number_literal<std::uint32_t> *)
|
|
{
|
|
}
|
|
|
|
void empty_visitor::visit(number_literal<double> *)
|
|
{
|
|
}
|
|
|
|
void empty_visitor::visit(number_literal<bool> *)
|
|
{
|
|
}
|
|
|
|
void empty_visitor::visit(number_literal<unsigned char> *)
|
|
{
|
|
}
|
|
|
|
void empty_visitor::visit(number_literal<std::nullptr_t> *)
|
|
{
|
|
}
|
|
|
|
void empty_visitor::visit(number_literal<std::string> *)
|
|
{
|
|
}
|
|
|
|
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)
|
|
{
|
|
}
|
|
|
|
top_type::top_type(const struct position position)
|
|
: node(position)
|
|
{
|
|
}
|
|
|
|
basic_type *top_type::is_basic()
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
array_type *top_type::is_array()
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
record_type *top_type::is_record()
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
union_type *top_type::is_union()
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
pointer_type *top_type::is_pointer()
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
basic_type::basic_type(const struct position position, const std::string& name)
|
|
: top_type(position), m_name(name)
|
|
{
|
|
}
|
|
|
|
void basic_type::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
const std::string& basic_type::base_name()
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
basic_type *basic_type::is_basic()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
array_type::array_type(const struct position position, top_type *base,
|
|
const std::uint32_t size)
|
|
: top_type(position), m_base(base), size(size)
|
|
{
|
|
}
|
|
|
|
void array_type::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
top_type& array_type::base()
|
|
{
|
|
return *m_base;
|
|
}
|
|
|
|
array_type*array_type::is_array()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
array_type::~array_type()
|
|
{
|
|
delete m_base;
|
|
}
|
|
|
|
pointer_type::pointer_type(const struct position position, top_type *base)
|
|
: top_type(position), m_base(base)
|
|
{
|
|
}
|
|
|
|
void pointer_type::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
top_type& pointer_type::base()
|
|
{
|
|
return *m_base;
|
|
}
|
|
|
|
pointer_type *pointer_type::is_pointer()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
pointer_type::~pointer_type()
|
|
{
|
|
delete m_base;
|
|
}
|
|
|
|
composite_type::composite_type(const struct position position, fields_t&& fields)
|
|
: top_type(position), fields(std::move(fields))
|
|
{
|
|
}
|
|
|
|
composite_type::~composite_type()
|
|
{
|
|
for (auto& field_declaration : fields)
|
|
{
|
|
delete field_declaration.second;
|
|
}
|
|
}
|
|
|
|
record_type::record_type(const struct position position, fields_t&& fields)
|
|
: composite_type(position, std::move(fields))
|
|
{
|
|
}
|
|
|
|
void record_type::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
record_type *record_type::is_record()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
union_type::union_type(const struct position position, fields_t&& fields)
|
|
: composite_type(position, std::move(fields))
|
|
{
|
|
}
|
|
|
|
union_type *union_type::is_union()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
void union_type::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
variable_declaration::variable_declaration(const struct position position, const std::string& identifier,
|
|
const bool exported, top_type *type)
|
|
: definition(position, identifier, exported), m_type(type)
|
|
{
|
|
}
|
|
|
|
variable_declaration::~variable_declaration()
|
|
{
|
|
delete m_type;
|
|
}
|
|
|
|
void variable_declaration::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
top_type& variable_declaration::variable_type()
|
|
{
|
|
return *m_type;
|
|
}
|
|
|
|
definition::definition(const struct position position, const std::string& identifier, const bool exported)
|
|
: node(position), identifier(identifier), exported(exported)
|
|
{
|
|
}
|
|
|
|
constant_definition::constant_definition(const struct position position, const std::string& identifier,
|
|
const bool exported, literal *body)
|
|
: definition(position, identifier, exported), 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,
|
|
const bool exported, top_type *return_type)
|
|
: definition(position, identifier, exported), m_return_type(return_type)
|
|
{
|
|
}
|
|
|
|
void procedure_definition::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
block *procedure_definition::body()
|
|
{
|
|
return m_body;
|
|
}
|
|
|
|
procedure_definition *procedure_definition::add_body(block *procedure_body)
|
|
{
|
|
m_body = procedure_body;
|
|
return this;
|
|
}
|
|
|
|
top_type *procedure_definition::return_type()
|
|
{
|
|
return m_return_type;
|
|
}
|
|
|
|
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,
|
|
const bool exported, top_type *body)
|
|
: definition(position, identifier, exported), m_body(body)
|
|
{
|
|
}
|
|
|
|
void type_definition::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
top_type& type_definition::body()
|
|
{
|
|
return *m_body;
|
|
}
|
|
|
|
type_definition::~type_definition()
|
|
{
|
|
delete m_body;
|
|
}
|
|
|
|
block::block(const struct position position)
|
|
: node(position)
|
|
{
|
|
}
|
|
|
|
void block::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
block::~block()
|
|
{
|
|
for (statement *body_statement : this->body)
|
|
{
|
|
delete body_statement;
|
|
}
|
|
for (variable_declaration *variable : this->variables)
|
|
{
|
|
delete variable;
|
|
}
|
|
for (constant_definition *constant : this->constants)
|
|
{
|
|
delete constant;
|
|
}
|
|
}
|
|
|
|
program::program(const struct position position)
|
|
: block(position)
|
|
{
|
|
}
|
|
|
|
void program::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
program::~program()
|
|
{
|
|
for (procedure_definition *procedure : this->procedures)
|
|
{
|
|
delete procedure;
|
|
}
|
|
for (type_definition *type : this->types)
|
|
{
|
|
delete type;
|
|
}
|
|
}
|
|
|
|
literal::literal(const struct position position)
|
|
: expression(position)
|
|
{
|
|
}
|
|
|
|
defer_statement::defer_statement(const struct position position)
|
|
: statement(position)
|
|
{
|
|
}
|
|
|
|
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(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,
|
|
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;
|
|
}
|
|
|
|
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)
|
|
: designator_expression(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)
|
|
: designator_expression(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)
|
|
: expression(position), m_lhs(lhs), m_rhs(rhs), m_operator(operation)
|
|
{
|
|
}
|
|
|
|
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 unary_operator operation)
|
|
: expression(position), m_operand(std::move(operand)), m_operator(operation)
|
|
{
|
|
}
|
|
|
|
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_expression::call_expression(const struct position position, const std::string& name)
|
|
: expression(position), m_name(name)
|
|
{
|
|
}
|
|
|
|
void call_expression::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
std::string& call_expression::name()
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
std::vector<expression *>& call_expression::arguments()
|
|
{
|
|
return m_arguments;
|
|
}
|
|
|
|
call_expression::~call_expression()
|
|
{
|
|
for (auto argument : m_arguments)
|
|
{
|
|
delete argument;
|
|
}
|
|
}
|
|
|
|
cast_expression::cast_expression(const struct position position, top_type *target, expression *value)
|
|
: expression(position), m_target(target), m_value(value)
|
|
{
|
|
}
|
|
|
|
void cast_expression::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
top_type& cast_expression::target()
|
|
{
|
|
return *m_target;
|
|
}
|
|
|
|
expression& cast_expression::value()
|
|
{
|
|
return *m_value;
|
|
}
|
|
|
|
cast_expression::~cast_expression()
|
|
{
|
|
delete m_target;
|
|
delete m_value;
|
|
}
|
|
|
|
type_expression::type_expression(const struct position position, top_type *body)
|
|
: expression(position), m_body(body)
|
|
{
|
|
}
|
|
|
|
void type_expression::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
top_type& type_expression::body()
|
|
{
|
|
return *m_body;
|
|
}
|
|
|
|
type_expression::~type_expression()
|
|
{
|
|
delete m_body;
|
|
}
|
|
|
|
call_statement::call_statement(const struct position position, call_expression *body)
|
|
: statement(position), m_body(body)
|
|
{
|
|
}
|
|
|
|
void call_statement::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
call_expression& call_statement::body()
|
|
{
|
|
return *m_body;
|
|
}
|
|
|
|
call_statement::~call_statement()
|
|
{
|
|
delete m_body;
|
|
}
|
|
|
|
conditional_statements::conditional_statements(expression *prerequisite)
|
|
: m_prerequisite(prerequisite)
|
|
{
|
|
}
|
|
|
|
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)
|
|
: statement(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()
|
|
{
|
|
if (m_return_expression != nullptr)
|
|
{
|
|
delete m_return_expression;
|
|
}
|
|
}
|
|
|
|
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, conditional_statements *body,
|
|
std::vector<statement *> *alternative)
|
|
: statement(position), m_body(body), m_alternative(alternative)
|
|
{
|
|
}
|
|
|
|
void if_statement::accept(parser_visitor *visitor)
|
|
{
|
|
visitor->visit(this);
|
|
}
|
|
|
|
conditional_statements& if_statement::body()
|
|
{
|
|
return *m_body;
|
|
}
|
|
|
|
std::vector<statement *> *if_statement::alternative()
|
|
{
|
|
return m_alternative;
|
|
}
|
|
|
|
if_statement::~if_statement()
|
|
{
|
|
delete m_body;
|
|
for (const auto branch : branches)
|
|
{
|
|
delete branch;
|
|
}
|
|
if (m_alternative != nullptr)
|
|
{
|
|
delete m_alternative;
|
|
}
|
|
}
|
|
|
|
while_statement::while_statement(const struct position position, conditional_statements *body)
|
|
: statement(position), m_body(body)
|
|
{
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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";
|
|
}
|
|
__builtin_unreachable();
|
|
};
|
|
}
|
|
}
|