Support multiple function arguments
This commit is contained in:
@@ -16,8 +16,9 @@ namespace elna::source
|
||||
|
||||
void name_analysis_visitor::visit(declaration *declaration)
|
||||
{
|
||||
auto declaration_type = std::dynamic_pointer_cast<type_info>(table->lookup(declaration->type()));
|
||||
this->table->enter(declaration->identifier(),
|
||||
std::make_shared<variable_info>(variable_info()));
|
||||
std::make_shared<variable_info>(declaration_type->type()));
|
||||
}
|
||||
|
||||
void name_analysis_visitor::visit(program *program)
|
||||
@@ -31,7 +32,15 @@ namespace elna::source
|
||||
auto info = std::make_shared<procedure_info>(this->table);
|
||||
this->table->enter(procedure->identifier(), info);
|
||||
this->table = info->scope();
|
||||
empty_visitor::visit(procedure);
|
||||
|
||||
for (auto& parameter : procedure->parameters())
|
||||
{
|
||||
auto declaration_type = std::dynamic_pointer_cast<type_info>(table->lookup(parameter->type()));
|
||||
this->table->enter(parameter->identifier(),
|
||||
std::make_shared<parameter_info>(declaration_type->type()));
|
||||
}
|
||||
procedure->body().accept(this);
|
||||
|
||||
this->table = info->scope()->scope();
|
||||
}
|
||||
|
||||
@@ -42,22 +51,49 @@ namespace elna::source
|
||||
|
||||
void allocator_visitor::visit(declaration *declaration)
|
||||
{
|
||||
this->offset -= sizeof(std::int32_t);
|
||||
auto declaration_info = this->table->lookup(declaration->identifier());
|
||||
|
||||
if (auto variable = std::dynamic_pointer_cast<variable_info>(declaration_info))
|
||||
{
|
||||
this->local_offset -= sizeof(std::int32_t);
|
||||
variable->offset = this->local_offset;
|
||||
}
|
||||
else if (auto parameter = std::dynamic_pointer_cast<parameter_info>(declaration_info))
|
||||
{
|
||||
parameter->offset = this->argument_offset;
|
||||
this->argument_offset += sizeof(std::int32_t);
|
||||
}
|
||||
}
|
||||
|
||||
void allocator_visitor::visit(program *program)
|
||||
{
|
||||
this->offset = 0;
|
||||
this->local_offset = 0;
|
||||
this->argument_offset = 0;
|
||||
|
||||
empty_visitor::visit(program);
|
||||
std::dynamic_pointer_cast<procedure_info>(table->lookup("main"))
|
||||
->stack_size(std::abs(this->offset));
|
||||
std::dynamic_pointer_cast<procedure_info>(table->lookup("main"))->local_stack_size =
|
||||
std::abs(this->local_offset);
|
||||
}
|
||||
|
||||
void allocator_visitor::visit(procedure_definition *procedure)
|
||||
{
|
||||
this->offset = 0;
|
||||
this->local_offset = 0;
|
||||
this->argument_offset = 0;
|
||||
auto info = std::dynamic_pointer_cast<procedure_info>(this->table->lookup(procedure->identifier()));
|
||||
this->table = info->scope();
|
||||
|
||||
empty_visitor::visit(procedure);
|
||||
std::dynamic_pointer_cast<procedure_info>(table->lookup(procedure->identifier()))
|
||||
->stack_size(std::abs(this->offset));
|
||||
|
||||
this->table = info->scope()->scope();
|
||||
info->local_stack_size = std::abs(this->local_offset);
|
||||
info->argument_stack_size = this->argument_offset;
|
||||
}
|
||||
|
||||
void allocator_visitor::visit(call_statement *statement)
|
||||
{
|
||||
auto call_info = std::dynamic_pointer_cast<intrinsic_info>(this->table->lookup(statement->name()));
|
||||
|
||||
this->argument_offset = std::max(static_cast<std::size_t>(this->argument_offset),
|
||||
call_info->parameter_stack_size());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user