aboutsummaryrefslogtreecommitdiff
path: root/boot/ast.cc
diff options
context:
space:
mode:
Diffstat (limited to 'boot/ast.cc')
-rw-r--r--boot/ast.cc426
1 files changed, 340 insertions, 86 deletions
diff --git a/boot/ast.cc b/boot/ast.cc
index b6ce4b3..4270a3b 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -24,11 +24,6 @@ namespace elna::boot
__builtin_unreachable();
}
- void empty_visitor::visit(type_expression *)
- {
- not_implemented();
- }
-
void empty_visitor::visit(array_type_expression *)
{
not_implemented();
@@ -204,6 +199,300 @@ namespace elna::boot
not_implemented();
}
+ 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 (constant_declaration *const constant : declaration->body.value().constants())
+ {
+ constant->accept(this);
+ }
+ for (variable_declaration *const variable : declaration->body.value().variables())
+ {
+ variable->accept(this);
+ }
+ for (statement *const statement : declaration->body.value().statements())
+ {
+ statement->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 (struct statement *const branch_statement : statement->branch().statements)
+ {
+ branch_statement->accept(this);
+ }
+ for (conditional_statements *const branch : statement->branches)
+ {
+ branch->prerequisite().accept(this);
+
+ for (struct statement *const branch_statement : branch->statements)
+ {
+ branch_statement->accept(this);
+ }
+ }
+ if (statement->alternative != nullptr)
+ {
+ for (struct statement *const branch_statement : *statement->alternative)
+ {
+ branch_statement->accept(this);
+ }
+ }
+ }
+
+ void walking_visitor::visit(while_statement *statement)
+ {
+ statement->branch().prerequisite().accept(this);
+ for (struct statement *const branch_statement : statement->branch().statements)
+ {
+ branch_statement->accept(this);
+ }
+ for (conditional_statements *const branch : statement->branches)
+ {
+ branch->prerequisite().accept(this);
+
+ for (struct statement *const branch_statement : branch->statements)
+ {
+ branch_statement->accept(this);
+ }
+ }
+ }
+
+ void walking_visitor::visit(return_statement *statement)
+ {
+ statement->return_expression().accept(this);
+ }
+
+ void walking_visitor::visit(defer_statement *statement)
+ {
+ for (struct statement *const 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 *const case_label : case_block.labels)
+ {
+ case_label->accept(this);
+ }
+ for (struct statement *const block_statement : case_block.statements)
+ {
+ block_statement->accept(this);
+ }
+ }
+ if (statement->alternative != nullptr)
+ {
+ for (struct statement *const block_statement : *statement->alternative)
+ {
+ block_statement->accept(this);
+ }
+ }
+ }
+
+ void walking_visitor::visit(procedure_call *call)
+ {
+ call->callable().accept(this);
+ for (expression *const argument : call->arguments)
+ {
+ argument->accept(this);
+ }
+ }
+
+ void walking_visitor::visit(unit *unit)
+ {
+ for (import_declaration *const _import : unit->imports)
+ {
+ _import->accept(this);
+ }
+ for (type_declaration *const type : unit->types)
+ {
+ type->accept(this);
+ }
+ for (variable_declaration *const variable : unit->variables)
+ {
+ variable->accept(this);
+ }
+ for (constant_declaration *const constant : unit->constants)
+ {
+ constant->accept(this);
+ }
+ for (procedure_declaration *const procedure : unit->procedures)
+ {
+ procedure->accept(this);
+ }
+ if (unit->entry_point.has_value())
+ {
+ for (statement *const entry_statement : unit->entry_point.value())
+ {
+ 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(constant_declaration *declaration)
+ {
+ declaration->initializer().accept(this);
+ }
+
+ void walking_visitor::visit(array_type_expression *expression)
+ {
+ expression->base().accept(this);
+ }
+
+ void walking_visitor::visit(pointer_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(union_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(traits_expression *trait)
+ {
+ if (!trait->parameters.empty())
+ {
+ trait->parameters.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<std::int32_t> *)
+ {
+ }
+
+ void walking_visitor::visit(literal<std::uint32_t> *)
+ {
+ }
+
+ void walking_visitor::visit(literal<double> *)
+ {
+ }
+
+ void walking_visitor::visit(literal<bool> *)
+ {
+ }
+
+ void walking_visitor::visit(literal<unsigned char> *)
+ {
+ }
+
+ void walking_visitor::visit(literal<std::nullptr_t> *)
+ {
+ }
+
+ void walking_visitor::visit(literal<std::string> *)
+ {
+ }
+
node::node(const struct position position)
: source_position(position)
{
@@ -288,43 +577,6 @@ namespace elna::boot
return nullptr;
}
- void type_expression::accept(parser_visitor *visitor)
- {
- if (named_expression *node = is_named())
- {
- return visitor->visit(node);
- }
- else if (array_type_expression *node = is_array())
- {
- return visitor->visit(node);
- }
- else if (pointer_type_expression *node = is_pointer())
- {
- return visitor->visit(node);
- }
- else if (record_type_expression *node = is_record())
- {
- return visitor->visit(node);
- }
- else if (union_type_expression *node = is_union())
- {
- return visitor->visit(node);
- }
- else if (procedure_type_expression *node = is_procedure())
- {
- return visitor->visit(node);
- }
- else if (enumeration_type_expression *node = is_enumeration())
- {
- return visitor->visit(node);
- }
- __builtin_unreachable();
- }
-
- type_expression::~type_expression()
- {
- }
-
array_type_expression::array_type_expression(const struct position position,
type_expression *base, const std::uint32_t size)
: node(position), m_base(base), size(size)
@@ -417,8 +669,8 @@ namespace elna::boot
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)
+ expression *initializer)
+ : node(position), m_variable_type(variable_type), identifiers(std::move(identifier)), initializer(initializer)
{
}
@@ -436,7 +688,7 @@ namespace elna::boot
bool variable_declaration::has_initializer() const
{
- return this->is_extern || this->body != nullptr;
+ return this->is_extern || this->initializer != nullptr;
}
type_expression& variable_declaration::variable_type()
@@ -450,8 +702,8 @@ namespace elna::boot
}
constant_declaration::constant_declaration(const struct position position, identifier_definition identifier,
- expression *body)
- : declaration(position, identifier), m_body(body)
+ expression *initializer)
+ : declaration(position, identifier), m_initializer(initializer)
{
}
@@ -460,14 +712,14 @@ namespace elna::boot
visitor->visit(this);
}
- expression& constant_declaration::body()
+ expression& constant_declaration::initializer()
{
- return *m_body;
+ return *m_initializer;
}
constant_declaration::~constant_declaration()
{
- delete m_body;
+ delete m_initializer;
}
procedure_type_expression::procedure_type_expression(const struct position position,
@@ -511,8 +763,9 @@ namespace elna::boot
}
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::make_optional<block>(std::move(body)))
+ procedure_type_expression *heading, procedure_body&& body)
+ : declaration(position, identifier), m_heading(heading),
+ body(std::make_optional<procedure_body>(std::move(body)))
{
}
@@ -538,14 +791,14 @@ namespace elna::boot
}
type_declaration::type_declaration(const struct position position, identifier_definition identifier,
- type_expression *body)
- : declaration(position, identifier), m_body(body)
+ type_expression *underlying_type)
+ : declaration(position, identifier), m_underlying_type(underlying_type)
{
}
type_declaration::~type_declaration()
{
- delete m_body;
+ delete m_underlying_type;
}
void type_declaration::accept(parser_visitor *visitor)
@@ -553,55 +806,56 @@ namespace elna::boot
visitor->visit(this);
}
- type_expression& type_declaration::body()
+ type_expression& type_declaration::underlying_type()
{
- return *m_body;
+ return *m_underlying_type;
}
- 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))
+ procedure_body::procedure_body(std::vector<constant_declaration *>&& constants,
+ std::vector<variable_declaration *>&& variables, std::vector<statement *>&& statements)
+ : m_variables(std::move(variables)), m_constants(std::move(constants)), m_statements(std::move(statements))
{
}
- block::block(std::vector<constant_declaration*>&& constants, std::vector<variable_declaration *>&& variables)
- : m_variables(std::move(variables)), m_constants(std::move(constants))
+ procedure_body::procedure_body(std::vector<constant_declaration*>&& constants,
+ std::vector<variable_declaration *>&& variables)
+ : procedure_body(std::move(constants), std::move(variables), std::vector<statement *>{})
{
}
- block::block(block&& that)
+ procedure_body::procedure_body(procedure_body&& that)
: m_variables(std::move(that.m_variables)), m_constants(std::move(that.m_constants)),
- m_body(std::move(that.m_body))
+ m_statements(std::move(that.m_statements))
{
}
- block& block::operator=(block&& that)
+ procedure_body& procedure_body::operator=(procedure_body&& that)
{
std::swap(m_variables, that.m_variables);
std::swap(m_constants, that.m_constants);
- std::swap(m_body, that.m_body);
+ std::swap(m_statements, that.m_statements);
return *this;
}
- const std::vector<variable_declaration *>& block::variables()
+ const std::vector<variable_declaration *>& procedure_body::variables()
{
return m_variables;
}
- const std::vector<constant_declaration *>& block::constants()
+ const std::vector<constant_declaration *>& procedure_body::constants()
{
return m_constants;
}
- const std::vector<statement *>& block::body()
+ const std::vector<statement *>& procedure_body::statements()
{
- return m_body;
+ return m_statements;
}
- block::~block()
+ procedure_body::~procedure_body()
{
- for (statement *body_statement : this->body())
+ for (statement *body_statement : this->statements())
{
delete body_statement;
}
@@ -620,8 +874,8 @@ namespace elna::boot
{
}
- unit::unit(const struct position position, std::vector<statement *>&& body)
- : node(position), body(std::make_optional<std::vector<statement *>>(std::move(body)))
+ unit::unit(const struct position position, std::vector<statement *>&& entry_point)
+ : node(position), entry_point(std::make_optional<std::vector<statement *>>(std::move(entry_point)))
{
}
@@ -1073,10 +1327,10 @@ namespace elna::boot
delete m_rvalue;
}
- if_statement::if_statement(const struct position position, conditional_statements *body,
+ if_statement::if_statement(const struct position position, conditional_statements *branch,
std::vector<conditional_statements *>&& branches,
std::vector<statement *> *alternative)
- : node(position), m_body(body), branches(std::move(branches)), alternative(alternative)
+ : node(position), m_branch(branch), branches(std::move(branches)), alternative(alternative)
{
}
@@ -1085,15 +1339,15 @@ namespace elna::boot
visitor->visit(this);
}
- conditional_statements& if_statement::body()
+ conditional_statements& if_statement::branch()
{
- return *m_body;
+ return *m_branch;
}
if_statement::~if_statement()
{
- delete m_body;
- for (const auto branch : branches)
+ delete m_branch;
+ for (conditional_statements *const branch : branches)
{
delete branch;
}
@@ -1110,9 +1364,9 @@ namespace elna::boot
visitor->visit(this);
}
- while_statement::while_statement(const struct position position, conditional_statements *body,
+ while_statement::while_statement(const struct position position, conditional_statements *branch,
std::vector<conditional_statements *>&& branches)
- : node(position), m_body(body), branches(std::move(branches))
+ : node(position), m_branch(branch), branches(std::move(branches))
{
}
@@ -1121,15 +1375,15 @@ namespace elna::boot
visitor->visit(this);
}
- conditional_statements& while_statement::body()
+ conditional_statements& while_statement::branch()
{
- return *m_body;
+ return *m_branch;
}
while_statement::~while_statement()
{
- delete m_body;
- for (const auto branch : branches)
+ delete m_branch;
+ for (conditional_statements *const branch : branches)
{
delete branch;
}