elna/boot/ast.cc

1210 lines
28 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::boot
{
void empty_visitor::visit(variable_declaration *)
{
__builtin_unreachable();
}
void empty_visitor::visit(constant_definition *)
{
__builtin_unreachable();
}
void empty_visitor::visit(procedure_definition *)
{
__builtin_unreachable();
}
void empty_visitor::visit(type_definition *)
{
__builtin_unreachable();
}
void empty_visitor::visit(procedure_call *)
{
__builtin_unreachable();
}
void empty_visitor::visit(traits_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(cast_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(assign_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(if_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(while_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(return_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(defer_statement *)
{
__builtin_unreachable();
}
void empty_visitor::visit(block *)
{
__builtin_unreachable();
}
void empty_visitor::visit(program *)
{
__builtin_unreachable();
}
void empty_visitor::visit(binary_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(unary_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(primitive_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(array_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(pointer_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(record_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(union_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(procedure_type_expression *)
{
__builtin_unreachable();
}
void empty_visitor::visit(variable_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<std::int32_t> *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal<std::uint32_t> *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal<double> *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal<bool> *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal<unsigned char> *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal<std::nullptr_t> *)
{
__builtin_unreachable();
}
void empty_visitor::visit(literal<std::string> *)
{
__builtin_unreachable();
}
node::node(const struct position position)
: source_position(position)
{
}
node::~node()
{
}
const struct position& node::position() const
{
return this->source_position;
}
statement::statement()
{
}
statement::~statement()
{
}
assign_statement *statement::is_assign()
{
return nullptr;
}
if_statement *statement::is_if()
{
return nullptr;
}
while_statement *statement::is_while()
{
return nullptr;
}
return_statement *statement::is_return()
{
return nullptr;
}
defer_statement *statement::is_defer()
{
return nullptr;
}
procedure_call *statement::is_call_statement()
{
return nullptr;
}
void statement::accept(parser_visitor *visitor)
{
if (assign_statement *node = is_assign())
{
return node->accept(visitor);
}
else if (if_statement *node = is_if())
{
return node->accept(visitor);
}
else if (while_statement *node = is_while())
{
return node->accept(visitor);
}
else if (return_statement *node = is_return())
{
return node->accept(visitor);
}
else if (defer_statement *node = is_defer())
{
return node->accept(visitor);
}
else if (procedure_call *node = is_call_statement())
{
return node->accept(visitor);
}
__builtin_unreachable();
}
expression::expression()
{
}
expression::~expression()
{
}
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;
}
void expression::accept(parser_visitor *visitor)
{
if (cast_expression *node = is_cast())
{
return node->accept(visitor);
}
else if (traits_expression *node = is_traits())
{
return node->accept(visitor);
}
else if (binary_expression *node = is_binary())
{
return node->accept(visitor);
}
else if (unary_expression *node = is_unary())
{
return node->accept(visitor);
}
else if (designator_expression *node = is_designator())
{
return node->accept(visitor);
}
else if (procedure_call *node = is_call_expression())
{
return node->accept(visitor);
}
else if (literal_expression *node = is_literal())
{
return node->accept(visitor);
}
__builtin_unreachable();
}
type_expression::type_expression(const struct position position)
: node(position)
{
}
std::shared_ptr<primitive_type_expression> type_expression::is_primitive()
{
return nullptr;
}
std::shared_ptr<array_type_expression> type_expression::is_array()
{
return nullptr;
}
std::shared_ptr<pointer_type_expression> type_expression::is_pointer()
{
return nullptr;
}
std::shared_ptr<record_type_expression> type_expression::is_record()
{
return nullptr;
}
std::shared_ptr<union_type_expression> type_expression::is_union()
{
return nullptr;
}
std::shared_ptr<procedure_type_expression> type_expression::is_procedure()
{
return nullptr;
}
void type_expression::accept(parser_visitor *visitor)
{
if (std::shared_ptr<primitive_type_expression> node = is_primitive())
{
return node->accept(visitor);
}
else if (std::shared_ptr<array_type_expression> node = is_array())
{
return node->accept(visitor);
}
else if (std::shared_ptr<pointer_type_expression> node = is_pointer())
{
return node->accept(visitor);
}
else if (std::shared_ptr<record_type_expression> node = is_record())
{
return node->accept(visitor);
}
else if (std::shared_ptr<union_type_expression> node = is_union())
{
return node->accept(visitor);
}
else if (std::shared_ptr<procedure_type_expression> node = is_procedure())
{
return node->accept(visitor);
}
__builtin_unreachable();
}
primitive_type_expression::primitive_type_expression(const struct position position, const std::string& name)
: type_expression(position), name(name)
{
}
void primitive_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
std::shared_ptr<primitive_type_expression> primitive_type_expression::is_primitive()
{
return std::static_pointer_cast<primitive_type_expression>(shared_from_this());
}
array_type_expression::array_type_expression(const struct position position,
std::shared_ptr<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);
}
std::shared_ptr<array_type_expression> array_type_expression::is_array()
{
return std::static_pointer_cast<array_type_expression>(shared_from_this());
}
type_expression& array_type_expression::base()
{
return *m_base;
}
pointer_type_expression::pointer_type_expression(const struct position position,
std::shared_ptr<type_expression> base)
: type_expression(position), m_base(base)
{
}
void pointer_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
std::shared_ptr<pointer_type_expression> pointer_type_expression::is_pointer()
{
return std::static_pointer_cast<pointer_type_expression>(shared_from_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))
{
}
void record_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
std::shared_ptr<record_type_expression> record_type_expression::is_record()
{
return std::static_pointer_cast<record_type_expression>(shared_from_this());
}
union_type_expression::union_type_expression(const struct position position,
std::vector<field_declaration>&& fields)
: type_expression(position), fields(std::move(fields))
{
}
void union_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
std::shared_ptr<union_type_expression> union_type_expression::is_union()
{
return std::static_pointer_cast<union_type_expression>(shared_from_this());
}
variable_declaration::variable_declaration(const struct position position, const std::string& identifier,
std::shared_ptr<type_expression> type, const bool exported)
: definition(position, identifier, exported), m_type(type)
{
}
void variable_declaration::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
type_expression& 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_expression *body)
: definition(position, identifier, exported), m_body(body)
{
}
void constant_definition::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
literal_expression& constant_definition::body()
{
return *m_body;
}
constant_definition::~constant_definition()
{
delete m_body;
}
return_declaration::return_declaration(std::shared_ptr<type_expression> type)
: type(type)
{
}
return_declaration::return_declaration(std::monostate)
: no_return(true)
{
}
procedure_type_expression::procedure_type_expression(const struct position position,
return_declaration return_type)
: type_expression(position), return_type(return_type)
{
}
void procedure_type_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<procedure_type_expression> heading, block *body)
: definition(position, identifier, exported), m_heading(heading), body(body)
{
}
void procedure_definition::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
std::shared_ptr<procedure_type_expression> procedure_type_expression::is_procedure()
{
return std::static_pointer_cast<procedure_type_expression>(shared_from_this());
}
procedure_type_expression& procedure_definition::heading()
{
return *m_heading;
}
procedure_definition::~procedure_definition()
{
delete body;
}
type_definition::type_definition(const struct position position, const std::string& identifier,
const bool exported, std::shared_ptr<type_expression> body)
: definition(position, identifier, exported), m_body(body)
{
}
void type_definition::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
type_expression& type_definition::body()
{
return *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_expression::literal_expression()
{
}
literal_expression *literal_expression::is_literal()
{
return this;
}
void literal_expression::accept(parser_visitor *visitor)
{
if (literal<std::int32_t> *node = is_int())
{
return node->accept(visitor);
}
else if (literal<std::uint32_t> *node = is_word())
{
return node->accept(visitor);
}
else if (literal<double> *node = is_float())
{
return node->accept(visitor);
}
else if (literal<bool> *node = is_bool())
{
return node->accept(visitor);
}
else if (literal<unsigned char> *node = is_char())
{
return node->accept(visitor);
}
else if (literal<std::nullptr_t> *node = is_nil())
{
return node->accept(visitor);
}
else if (literal<std::string> *node = is_string())
{
return node->accept(visitor);
}
else
{
__builtin_unreachable();
}
}
defer_statement::defer_statement(const struct position position)
: node(position)
{
}
void defer_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
defer_statement *defer_statement::is_defer()
{
return 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_statement()
{
return 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,
std::shared_ptr<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_value;
}
traits_expression::traits_expression(const struct position position,
const std::string& name, std::shared_ptr<type_expression> type)
: node(position), m_type(type), name(name)
{
}
void traits_expression::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
traits_expression *traits_expression::is_traits()
{
return this;
}
type_expression& traits_expression::type()
{
return *m_type;
}
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)
: node(position), m_return_expression(return_expression)
{
}
void return_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
return_statement *return_statement::is_return()
{
return this;
}
expression *return_statement::return_expression()
{
return m_return_expression;
}
return_statement::~return_statement()
{
delete m_return_expression;
}
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);
}
assign_statement *assign_statement::is_assign()
{
return 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<statement *> *alternative)
: node(position), m_body(body), m_alternative(alternative)
{
}
void if_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
if_statement *if_statement::is_if()
{
return 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;
}
delete m_alternative;
}
while_statement::while_statement(const struct position position, conditional_statements *body)
: node(position), m_body(body)
{
}
void while_statement::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
while_statement *while_statement::is_while()
{
return 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();
};
}