aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-09 17:24:42 +0200
committerEugen Wissner <belka@caraus.de>2026-07-09 17:24:42 +0200
commit36440faa345bf842c348711325312c2b02e4cc23 (patch)
treea7ec54ad2f948efc556f3a74b59064321ae581c9 /boot
parent8d8e771af944796eba10cfa9568d284daaab93a1 (diff)
downloadelna-36440faa345bf842c348711325312c2b02e4cc23.tar.gz
Merge program and unit AST types
Diffstat (limited to 'boot')
-rw-r--r--boot/ast.cc45
-rw-r--r--boot/parser.yy6
-rw-r--r--boot/semantic.cc93
3 files changed, 60 insertions, 84 deletions
diff --git a/boot/ast.cc b/boot/ast.cc
index 3599308..b6ce4b3 100644
--- a/boot/ast.cc
+++ b/boot/ast.cc
@@ -39,11 +39,6 @@ namespace elna::boot
not_implemented();
}
- void empty_visitor::visit(program *)
- {
- not_implemented();
- }
-
void empty_visitor::visit(type_declaration *)
{
not_implemented();
@@ -383,8 +378,14 @@ namespace elna::boot
}
record_type_expression::record_type_expression(const struct position position,
- std::vector<field_declaration>&& fields, std::optional<std::string> base)
- : node(position), fields(std::move(fields)), base(base)
+ std::vector<field_declaration>&& fields)
+ : node(position), fields(std::move(fields))
+ {
+ }
+
+ record_type_expression::record_type_expression(const struct position position,
+ std::vector<field_declaration>&& fields, std::string&& base)
+ : node(position), fields(std::move(fields)), base(std::make_optional<std::string>(std::move(base)))
{
}
@@ -493,7 +494,8 @@ namespace elna::boot
return this;
}
- enumeration_type_expression::enumeration_type_expression(const struct position position, std::vector<std::string>&& members)
+ enumeration_type_expression::enumeration_type_expression(const struct position position,
+ std::vector<std::string>&& members)
: node(position), members(members)
{
}
@@ -510,13 +512,13 @@ 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::move(body))
+ : declaration(position, identifier), m_heading(heading), body(std::make_optional<block>(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)
+ : declaration(position, identifier), m_heading(heading)
{
}
@@ -618,6 +620,11 @@ 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)))
+ {
+ }
+
void unit::accept(parser_visitor *visitor)
{
visitor->visit(this);
@@ -647,24 +654,6 @@ namespace elna::boot
}
}
- 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::is_literal()
{
return this;
diff --git a/boot/parser.yy b/boot/parser.yy
index 7797dd1..42840ff 100644
--- a/boot/parser.yy
+++ b/boot/parser.yy
@@ -164,8 +164,8 @@ program:
{
if ($6)
{
- boot::program *tree = new boot::program(boot::make_position(@1));
- std::swap(tree->body, *$6.release());
+ boot::unit *tree = new boot::unit(boot::make_position(@1));
+ tree->body = std::make_optional<std::vector<boot::statement *>>(std::move(*$6.release()));
driver.tree.reset(tree);
}
@@ -460,7 +460,7 @@ type_expression:
}
| "record" optional_fields "end"
{
- $$ = new boot::record_type_expression(boot::make_position(@1), std::move($2), std::nullopt);
+ $$ = new boot::record_type_expression(boot::make_position(@1), std::move($2));
}
| "record" "(" IDENTIFIER ")" optional_fields "end"
{
diff --git a/boot/semantic.cc b/boot/semantic.cc
index a48226b..0530448 100644
--- a/boot/semantic.cc
+++ b/boot/semantic.cc
@@ -96,11 +96,6 @@ namespace elna::boot
{
}
- void type_analysis_visitor::visit(program *program)
- {
- visit(static_cast<unit *>(program));
- }
-
void type_analysis_visitor::visit(procedure_declaration *definition)
{
if (definition->body.has_value() && definition->heading().return_type.proper_type != nullptr)
@@ -195,17 +190,17 @@ namespace elna::boot
}
std::pair<procedure_type, std::vector<std::string>> name_analysis_visitor::build_procedure(
- procedure_type_expression& type_expression)
+ procedure_type_expression& expression)
{
procedure_type::return_t result_return;
- if (type_expression.return_type.no_return)
+ if (expression.return_type.no_return)
{
result_return = procedure_type::return_t(std::monostate{});
}
- else if (type_expression.return_type.proper_type != nullptr)
+ else if (expression.return_type.proper_type != nullptr)
{
- type_expression.return_type.proper_type->accept(this);
+ expression.return_type.proper_type->accept(this);
result_return = procedure_type::return_t(this->current_type);
}
else
@@ -215,7 +210,7 @@ namespace elna::boot
std::pair<procedure_type, std::vector<std::string>> result_type{
procedure_type(result_return), std::vector<std::string>()
};
- for (auto& [parameter_names, parameters_type] : type_expression.parameters)
+ for (auto& [parameter_names, parameters_type] : expression.parameters)
{
parameters_type->accept(this);
for (auto& parameter_name : parameter_names)
@@ -227,26 +222,6 @@ namespace elna::boot
return result_type;
}
- void name_analysis_visitor::visit(program *program)
- {
- visit(static_cast<unit *>(program));
-
- this->bag.enter();
- auto variable_type = this->bag.lookup("Int")->is_type()->symbol;
- this->bag.enter("count", std::make_shared<variable_info>(variable_type, false));
-
- variable_type = this->bag.lookup("Char")->is_type()->symbol;
- variable_type = type(std::make_shared<pointer_type>(variable_type));
- variable_type = type(std::make_shared<pointer_type>(variable_type));
- this->bag.enter("parameters", std::make_shared<variable_info>(variable_type, false));
-
- for (statement *const statement : program->body)
- {
- statement->accept(this);
- }
- this->bag.leave();
- }
-
void name_analysis_visitor::visit(type_declaration *definition)
{
definition->body().accept(this);
@@ -261,16 +236,16 @@ namespace elna::boot
{
}
- void name_analysis_visitor::visit(pointer_type_expression *type_expression)
+ void name_analysis_visitor::visit(pointer_type_expression *expression)
{
- type_expression->base().accept(this);
+ expression->base().accept(this);
this->current_type = type(std::make_shared<pointer_type>(this->current_type));
}
- void name_analysis_visitor::visit(array_type_expression *type_expression)
+ void name_analysis_visitor::visit(array_type_expression *expression)
{
- type_expression->base().accept(this);
- auto result_type{ std::make_shared<array_type>(this->current_type, type_expression->size) };
+ expression->base().accept(this);
+ auto result_type = std::make_shared<array_type>(this->current_type, expression->size);
this->current_type = type(result_type);
}
@@ -299,16 +274,16 @@ namespace elna::boot
return result;
}
- void name_analysis_visitor::visit(record_type_expression *type_expression)
+ void name_analysis_visitor::visit(record_type_expression *expression)
{
std::shared_ptr<record_type> result_type;
- if (type_expression->base.has_value())
+ if (expression->base.has_value())
{
- if (auto unresolved_alias = this->bag.declared(type_expression->base.value()))
+ if (auto unresolved_alias = this->bag.declared(expression->base.value()))
{
result_type = std::make_shared<record_type>(type(unresolved_alias));
}
- else if (auto base_symbol = this->bag.lookup(type_expression->base.value()))
+ else if (auto base_symbol = this->bag.lookup(expression->base.value()))
{
if (auto base_type_info = base_symbol->is_type())
{
@@ -316,14 +291,14 @@ namespace elna::boot
}
else
{
- add_error<base_type_error>(type_expression->base.value(), type_expression->position());
+ add_error<base_type_error>(expression->base.value(), expression->position());
this->current_type = type();
return;
}
}
else
{
- add_error<undeclared_error>(type_expression->base.value(), type_expression->position());
+ add_error<undeclared_error>(expression->base.value(), expression->position());
this->current_type = type();
return;
}
@@ -332,31 +307,31 @@ namespace elna::boot
{
result_type = std::make_shared<record_type>();
}
- result_type->fields = build_composite_type(type_expression->fields);
+ result_type->fields = build_composite_type(expression->fields);
this->current_type = type(result_type);
}
- void name_analysis_visitor::visit(union_type_expression *type_expression)
+ void name_analysis_visitor::visit(union_type_expression *expression)
{
auto result_type = std::make_shared<union_type>();
- result_type->fields = build_composite_type(type_expression->fields);
+ result_type->fields = build_composite_type(expression->fields);
this->current_type = type(result_type);
}
- void name_analysis_visitor::visit(procedure_type_expression *type_expression)
+ void name_analysis_visitor::visit(procedure_type_expression *expression)
{
std::shared_ptr<procedure_type> result_type =
- std::make_shared<procedure_type>(std::move(build_procedure(*type_expression).first));
+ std::make_shared<procedure_type>(std::move(build_procedure(*expression).first));
this->current_type = type(result_type);
}
- void name_analysis_visitor::visit(enumeration_type_expression *type_expression)
+ void name_analysis_visitor::visit(enumeration_type_expression *expression)
{
- std::shared_ptr<enumeration_type> result_type = std::make_shared<enumeration_type>(type_expression->members);
+ std::shared_ptr<enumeration_type> result_type = std::make_shared<enumeration_type>(expression->members);
this->current_type = type(result_type);
}
@@ -561,6 +536,23 @@ namespace elna::boot
{
procedure->accept(this);
}
+ if (unit->body.has_value())
+ {
+ this->bag.enter();
+ auto variable_type = this->bag.lookup("Int")->is_type()->symbol;
+ this->bag.enter("count", std::make_shared<variable_info>(variable_type, false));
+
+ variable_type = this->bag.lookup("Char")->is_type()->symbol;
+ variable_type = type(std::make_shared<pointer_type>(variable_type));
+ variable_type = type(std::make_shared<pointer_type>(variable_type));
+ this->bag.enter("parameters", std::make_shared<variable_info>(variable_type, false));
+
+ for (statement *const statement : unit->body.value())
+ {
+ statement->accept(this);
+ }
+ this->bag.leave();
+ }
}
void name_analysis_visitor::visit(traits_expression *trait)
@@ -666,11 +658,6 @@ namespace elna::boot
{
}
- void declaration_visitor::visit(program *program)
- {
- visit(static_cast<unit *>(program));
- }
-
void declaration_visitor::visit(import_declaration *)
{
}