Parse import declarations
This commit is contained in:
@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user