Provide record initialization syntax

This commit is contained in:
2025-02-13 22:54:47 +01:00
parent 62d9398772
commit c564847c6b
7 changed files with 115 additions and 56 deletions

View File

@ -56,20 +56,17 @@ namespace gcc
}
else if (DECL_P(symbol) && is_procedure_type(TREE_TYPE(symbol)))
{
tree return_type = TREE_TYPE(TREE_TYPE(symbol));
tree fndecl_type = build_function_type(return_type, TYPE_ARG_TYPES(symbol));
tree printf_fn = build1(ADDR_EXPR, build_pointer_type(fndecl_type), symbol);
vec<tree, va_gc> *arguments = nullptr;
std::vector<tree> arguments(expression->arguments().size());
for (std::size_t i = 0; i < expression->arguments().size(); ++i)
vec_alloc(arguments, expression->arguments().size());
for (boot::expression *const argument : expression->arguments())
{
expression->arguments().at(i)->accept(this);
arguments[i] = this->current_expression;
argument->accept(this);
arguments->quick_push(this->current_expression);
}
tree stmt = build_call_array_loc(get_location(&expression->position()),
return_type, printf_fn, arguments.size(), arguments.data());
tree stmt = build_call_expr_loc_vec(get_location(&expression->position()), symbol, arguments);
if (return_type == void_type_node)
if (TREE_TYPE(TREE_TYPE(symbol)) == void_type_node)
{
append_statement(stmt);
this->current_expression = NULL_TREE;
@ -79,6 +76,18 @@ namespace gcc
this->current_expression = stmt;
}
}
else if (TYPE_P(symbol) && is_record_type(symbol))
{
vec<constructor_elt, va_gc> *arguments = nullptr;
tree record_fields = TYPE_FIELDS(symbol);
for (boot::expression *const argument : expression->arguments())
{
argument->accept(this);
CONSTRUCTOR_APPEND_ELT(arguments, record_fields, this->current_expression);
record_fields = TREE_CHAIN(record_fields);
}
this->current_expression = build_constructor(symbol, arguments);
}
else
{
error_at(call_location, "'%s' cannot be called, it is neither a procedure nor record",
@ -360,7 +369,7 @@ namespace gcc
string_literal, integer_zero_node, NULL_TREE, NULL_TREE);
string_literal = build1(ADDR_EXPR, string_type, string_literal);
vec<constructor_elt, va_gc> *elms = NULL;
vec<constructor_elt, va_gc> *elms = nullptr;
CONSTRUCTOR_APPEND_ELT(elms, elna_string_ptr_field_node, string_literal);
CONSTRUCTOR_APPEND_ELT(elms, elna_string_length_field_node, index_constant);
@ -851,7 +860,7 @@ namespace gcc
else
{
error_at(statement_location,
"cannot assign value of type %s to variable of type %s",
"cannot assign value of type '%s' to variable of type '%s'",
print_type(TREE_TYPE(this->current_expression)).c_str(),
print_type(TREE_TYPE(lvalue)).c_str());
this->current_expression = error_mark_node;