Add procedure type expression

This commit is contained in:
2025-02-22 02:43:58 +01:00
parent ff9169a98c
commit 18857e1a88
7 changed files with 199 additions and 142 deletions

View File

@ -86,7 +86,7 @@ namespace gcc
{
std::string output = "proc(";
tree parameter_type = TYPE_ARG_TYPES(type);
while (parameter_type != NULL_TREE)
while (TREE_VALUE(parameter_type) != void_type_node)
{
output += print_type(TREE_VALUE(parameter_type));
parameter_type = TREE_CHAIN(parameter_type);

View File

@ -242,27 +242,17 @@ namespace gcc
void generic_visitor::visit(boot::procedure_definition *definition)
{
std::vector<tree> parameter_types(definition->parameters.size());
for (std::size_t i = 0; i < definition->parameters.size(); ++i)
{
parameter_types[i] = build_type(definition->parameters.at(i)->variable_type());
}
tree return_type = definition->return_type() == nullptr
? void_type_node
: build_type(*definition->return_type());
tree declaration_type = build_function_type_array(return_type,
definition->parameters.size(), parameter_types.data());
tree declaration_type = build_type(definition->heading());
tree fndecl = build_fn_decl(definition->identifier.c_str(), declaration_type);
this->symbol_map->enter(definition->identifier, fndecl);
if (definition->no_return)
if (definition->heading().no_return)
{
TREE_THIS_VOLATILE(fndecl) = 1;
}
if (definition->body() != nullptr)
if (definition->body != nullptr)
{
tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, return_type);
tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, TREE_TYPE(declaration_type));
DECL_CONTEXT(resdecl) = fndecl;
DECL_RESULT(fndecl) = resdecl;
@ -272,27 +262,29 @@ namespace gcc
enter_scope();
}
tree argument_chain = NULL_TREE;
for (std::size_t i = 0; i < definition->parameters.size(); ++i)
function_args_iterator parameter_type;
function_args_iter_init(&parameter_type, declaration_type);
for (const boot::variable_declaration *parameter : definition->heading().parameters)
{
auto parameter = definition->parameters.at(i);
tree declaration_tree = build_decl(get_location(&parameter->position()), PARM_DECL,
get_identifier(parameter->identifier.c_str()), parameter_types[i]);
get_identifier(parameter->identifier.c_str()), function_args_iter_cond(&parameter_type));
DECL_CONTEXT(declaration_tree) = fndecl;
DECL_ARG_TYPE(declaration_tree) = parameter_types[i];
DECL_ARG_TYPE(declaration_tree) = function_args_iter_cond(&parameter_type);
if (definition->body() != nullptr)
if (definition->body != nullptr)
{
this->symbol_map->enter(parameter->identifier, declaration_tree);
}
argument_chain = chainon(argument_chain, declaration_tree);
function_args_iter_next(&parameter_type);
}
DECL_ARGUMENTS(fndecl) = argument_chain;
TREE_PUBLIC(fndecl) = definition->exported;
if (definition->body() != nullptr)
if (definition->body != nullptr)
{
definition->body()->accept(this);
definition->body->accept(this);
tree mapping = leave_scope();
BLOCK_SUPERCONTEXT(BIND_EXPR_BLOCK(mapping)) = fndecl;
@ -749,7 +741,7 @@ namespace gcc
tree generic_visitor::build_type(boot::top_type& type)
{
if (boot::basic_type *basic_type = type.is_basic())
if (std::shared_ptr<boot::basic_type> basic_type = type.is_basic())
{
tree symbol = this->lookup(basic_type->base_name());
@ -762,7 +754,7 @@ namespace gcc
return error_mark_node;
}
else if (boot::array_type *array_type = type.is_array())
else if (std::shared_ptr<boot::array_type> array_type = type.is_array())
{
tree lower_bound = build_int_cst_type(integer_type_node, 0);
tree upper_bound = build_int_cst_type(integer_type_node, array_type->size);
@ -776,7 +768,7 @@ namespace gcc
return build_array_type(base_type, range_type);
}
else if (boot::pointer_type *pointer_type = type.is_pointer())
else if (std::shared_ptr<boot::pointer_type> pointer_type = type.is_pointer())
{
tree base_type = build_type(pointer_type->base());
@ -786,7 +778,7 @@ namespace gcc
}
return build_pointer_type_for_mode(base_type, VOIDmode, true);
}
else if (boot::record_type *record_type = type.is_record())
else if (std::shared_ptr<boot::record_type> record_type = type.is_record())
{
std::set<std::string> field_names;
tree record_type_node = make_node(RECORD_TYPE);
@ -813,7 +805,7 @@ namespace gcc
return record_type_node;
}
else if (boot::union_type *union_type = type.is_union())
else if (std::shared_ptr<boot::union_type> union_type = type.is_union())
{
std::set<std::string> field_names;
tree union_type_node = make_node(UNION_TYPE);
@ -840,6 +832,21 @@ namespace gcc
return union_type_node;
}
else if (std::shared_ptr<boot::procedure_type> procedure_type = type.is_procedure())
{
std::vector<tree> parameter_types(procedure_type->parameters.size());
for (std::size_t i = 0; i < procedure_type->parameters.size(); ++i)
{
parameter_types[i] = build_type(procedure_type->parameters.at(i)->variable_type());
}
tree return_type = procedure_type->return_type == nullptr
? void_type_node
: build_type(*procedure_type->return_type);
return build_function_type_array(return_type,
procedure_type->parameters.size(), parameter_types.data());
}
return NULL_TREE;
}
@ -889,9 +896,15 @@ namespace gcc
"variable '%s' not declared in the current scope",
expression->name().c_str());
this->current_expression = error_mark_node;
return;
}
this->current_expression = symbol;
else if (TREE_CODE(symbol) == FUNCTION_DECL)
{
this->current_expression = build1(ADDR_EXPR, build_pointer_type(TREE_TYPE(symbol)), symbol);
}
else
{
this->current_expression = symbol;
}
}
void generic_visitor::visit(boot::array_access_expression *expression)