Parse import declarations

This commit is contained in:
2025-05-16 23:16:19 +02:00
parent 981059e745
commit 573d812f1c
9 changed files with 333 additions and 227 deletions

View File

@ -352,31 +352,13 @@ namespace elna::gcc
DECL_ARGUMENTS(fndecl) = argument_chain;
TREE_PUBLIC(fndecl) = definition->identifier.exported;
TREE_ADDRESSABLE(fndecl) = 1;
DECL_EXTERNAL(fndecl) = definition->body == nullptr;
DECL_EXTERNAL(fndecl) = !definition->body.has_value();
}
void generic_visitor::visit(boot::program *program)
{
for (boot::constant_definition *const constant : program->constants)
{
constant->accept(this);
}
for (boot::type_definition *const type : program->types)
{
type->accept(this);
}
for (boot::variable_declaration *const variable : program->variables)
{
variable->accept(this);
}
for (boot::procedure_definition *const procedure : program->procedures)
{
declare_procedure(procedure);
}
for (boot::procedure_definition *const procedure : program->procedures)
{
procedure->accept(this);
}
visit(static_cast<boot::unit *>(program));
tree declaration_type = build_function_type_list(integer_type_node, elna_int_type_node,
build_global_pointer_type(build_global_pointer_type(elna_char_type_node)), NULL_TREE);
tree fndecl = build_fn_decl("main", declaration_type);
@ -421,22 +403,37 @@ namespace elna::gcc
cgraph_node::finalize_function(fndecl, true);
}
void generic_visitor::visit(boot::block *block)
void generic_visitor::visit(boot::unit *unit)
{
for (boot::constant_definition *const constant : block->constants)
for (boot::import_declaration *const declaration : unit->imports)
{
declaration->accept(this);
}
for (boot::constant_definition *const constant : unit->constants)
{
constant->accept(this);
}
for (boot::variable_declaration *const variable : block->variables)
for (boot::type_definition *const type : unit->types)
{
type->accept(this);
}
for (boot::variable_declaration *const variable : unit->variables)
{
variable->accept(this);
}
visit_statements(block->body);
for (boot::procedure_definition *const procedure : unit->procedures)
{
declare_procedure(procedure);
}
for (boot::procedure_definition *const procedure : unit->procedures)
{
procedure->accept(this);
}
}
void generic_visitor::visit(boot::procedure_definition *definition)
{
if (definition->body == nullptr)
if (!definition->body.has_value())
{
return;
}
@ -452,7 +449,16 @@ namespace elna::gcc
{
this->symbols->enter(IDENTIFIER_POINTER(DECL_NAME(argument_chain)), argument_chain);
}
definition->body->accept(this);
for (boot::constant_definition *const constant : definition->body.value().constants())
{
constant->accept(this);
}
for (boot::variable_declaration *const variable : definition->body.value().variables())
{
variable->accept(this);
}
visit_statements(definition->body.value().body());
tree mapping = leave_scope();
BLOCK_SUPERCONTEXT(BIND_EXPR_BLOCK(mapping)) = fndecl;
@ -1285,32 +1291,8 @@ namespace elna::gcc
append_statement(else_label_expr);
}
void generic_visitor::visit(boot::escape_statement *statement)
void generic_visitor::visit(boot::import_declaration *)
{
for (const auto& [begin, end] : this->loops)
{
if (statement->label == IDENTIFIER_POINTER(DECL_NAME(begin)))
{
tree target_declaration{ NULL_TREE };
switch (statement->direction)
{
case boot::escape_direction::begin:
target_declaration = begin;
break;
case boot::escape_direction::end:
target_declaration = end;
break;
default:
gcc_unreachable();
}
tree goto_expression = build1(GOTO_EXPR, void_type_node, target_declaration);
TREE_USED(target_declaration) = 1;
append_statement(goto_expression);
return;
}
}
error_at(get_location(&statement->position()), "Unknown loop labeled '%s'", statement->label.c_str());
}
void generic_visitor::visit(boot::while_statement *statement)
@ -1324,8 +1306,6 @@ namespace elna::gcc
tree branch_end_declaration = build_label_decl(loop_identifier.c_str(), UNKNOWN_LOCATION);
tree branch_end_expression = build1_loc(UNKNOWN_LOCATION, LABEL_EXPR, void_type_node, branch_end_declaration);
this->loops.push_front({ prerequisite_label_decl, branch_end_declaration });
append_statement(prerequisite_label_expr);
make_if_branch(statement->body(), goto_check);