Generate top-level code from symbol tables

This commit is contained in:
2025-06-19 14:03:03 +02:00
parent f524311f06
commit 6da2a70329
14 changed files with 434 additions and 397 deletions

View File

@ -17,6 +17,8 @@ along with GCC; see the file COPYING3. If not see
#include "elna/boot/semantic.h"
#include <set>
namespace elna::boot
{
undeclared_error::undeclared_error(const std::string& identifier, const char *path, const struct position position)
@ -46,6 +48,17 @@ namespace elna::boot
{
}
field_duplication_error::field_duplication_error(const std::string& field_name,
const char *path, const struct position)
: error(path, position), field_name(field_name)
{
}
std::string field_duplication_error::what() const
{
return "Repeated field name '" + field_name + "'";
}
procedure_type declaration_visitor::build_procedure(procedure_type_expression& type_expression)
{
procedure_type::return_t result_return;
@ -122,15 +135,33 @@ namespace elna::boot
this->current_type = type(std::make_shared<array_type>(this->current_type, type_expression->size));
}
std::vector<type_field> declaration_visitor::build_composite_type(const std::vector<field_declaration>& fields)
{
std::vector<type_field> result;
std::set<std::string> field_names;
for (auto& field : fields)
{
if (field_names.find(field.first) != field_names.cend())
{
add_error<field_duplication_error>(field.first, this->input_file, field.second->position());
}
else
{
field_names.insert(field.first);
field.second->accept(this);
result.push_back(std::make_pair(field.first, this->current_type));
}
}
return result;
}
void declaration_visitor::visit(record_type_expression *type_expression)
{
auto result_type = std::make_shared<record_type>();
for (auto& field : type_expression->fields)
{
field.second->accept(this);
result_type->fields.push_back(std::make_pair(field.first, this->current_type));
}
result_type->fields = build_composite_type(type_expression->fields);
this->current_type = type(result_type);
}
@ -138,11 +169,8 @@ namespace elna::boot
{
auto result_type = std::make_shared<union_type>();
for (const field_declaration& field : type_expression->fields)
{
field.second->accept(this);
result_type->fields.push_back(std::make_pair(field.first, this->current_type));
}
result_type->fields = build_composite_type(type_expression->fields);
this->current_type = type(result_type);
}
@ -179,14 +207,15 @@ namespace elna::boot
void declaration_visitor::visit(procedure_declaration *definition)
{
std::shared_ptr<procedure_info> info = std::make_shared<procedure_info>(
build_procedure(definition->heading()), definition->parameter_names);
this->symbols->enter(definition->identifier.identifier, info);
this->symbols = std::make_shared<symbol_table>(this->symbols);
std::shared_ptr<procedure_info> info;
if (definition->body.has_value())
{
info = std::make_shared<procedure_info>(build_procedure(definition->heading()),
definition->parameter_names, this->symbols);
this->symbols = info->symbols;
for (constant_declaration *const constant : definition->body.value().constants())
{
constant->accept(this);
@ -199,8 +228,14 @@ namespace elna::boot
{
statement->accept(this);
}
this->symbols = this->symbols->scope();
}
this->symbols = this->symbols->scope();
else
{
info = std::make_shared<procedure_info>(build_procedure(definition->heading()),
definition->parameter_names);
}
this->symbols->enter(definition->identifier.identifier, info);
}
void declaration_visitor::visit(assign_statement *statement)
@ -283,6 +318,13 @@ namespace elna::boot
statement->accept(this);
}
}
if (statement->alternative != nullptr)
{
for (struct statement *const statement : *statement->alternative)
{
statement->accept(this);
}
}
}
void declaration_visitor::visit(procedure_call *call)
@ -330,6 +372,7 @@ namespace elna::boot
if (!trait->parameters.empty())
{
trait->parameters.front()->accept(this);
trait->types.push_back(this->current_type);
}
}
@ -337,6 +380,7 @@ namespace elna::boot
{
expression->value().accept(this);
expression->target().accept(this);
expression->expression_type = this->current_type;
}
void declaration_visitor::visit(binary_expression *expression)