implement nested (and struct) block initializers

This commit is contained in:
Bill Currie 2003-04-07 17:44:18 +00:00
parent 33c9ce0f7b
commit ee821705cc
1 changed files with 44 additions and 12 deletions

View File

@ -2341,9 +2341,34 @@ void
init_elements (def_t *def, expr_t *eles) init_elements (def_t *def, expr_t *eles)
{ {
expr_t *e; expr_t *e;
int count, i; int count, i, num_params;
pr_type_t *g = G_POINTER (pr_type_t, def->ofs); pr_type_t *g;
def_t *elements;
if (def->type->type == ev_array) {
elements = calloc (def->type->num_parms, sizeof (def_t));
for (i = 0; i < def->type->num_parms; i++) {
elements[i].type = def->type->aux_type;
elements[i].ofs = def->ofs + i * type_size (def->type->aux_type);
}
num_params = i;
} else if (def->type->type == ev_struct) {
struct_field_t *field;
for (i = 0, field = def->type->struct_head; field;
i++, field = field->next)
;
elements = calloc (i, sizeof (def_t));
for (i = 0, field = def->type->struct_head; field;
i++, field = field->next) {
elements[i].type = field->type;
elements[i].ofs = def->ofs + field->offset;
}
num_params = i;
} else {
error (eles, "invalid initializer");
return;
}
for (count = 0, e = eles->e.block.head; e; count++, e = e->next) for (count = 0, e = eles->e.block.head; e; count++, e = e->next)
if (e->type == ex_error) if (e->type == ex_error)
return; return;
@ -2352,21 +2377,28 @@ init_elements (def_t *def, expr_t *eles)
count = def->type->num_parms; count = def->type->num_parms;
} }
for (i = 0, e = eles->e.block.head; i < count; i++, e = e->next) { for (i = 0, e = eles->e.block.head; i < count; i++, e = e->next) {
g = G_POINTER (pr_type_t, elements[i].ofs);
if (e->type == ex_def && e->e.def->constant) if (e->type == ex_def && e->e.def->constant)
e = constant_expr (e); e = constant_expr (e);
if (e->type == ex_block) { if (e->type == ex_block) {
warning (e, "not yet implemented"); if (elements[i].type->type != ev_array
} else if (e->type >= ex_string) { && elements[i].type->type != ev_struct) {
if (get_type (e) != def->type->aux_type) {
error (e, "type mismatch in initializer"); error (e, "type mismatch in initializer");
g += type_size (def->type->aux_type); continue;
}
init_elements (&elements[i], e);
} else if (e->type >= ex_string) {
if (e->type == ex_integer
&& elements[i].type->type == ev_float)
convert_int (e);
if (get_type (e) != elements[i].type) {
error (e, "type mismatch in initializer");
continue;
}
if (e->type == ex_string) {
EMIT_STRING (g->string_var, e->e.string_val);
} else { } else {
if (e->type == ex_string) { memcpy (g, &e->e, type_size (get_type (e)) * 4);
EMIT_STRING (g->string_var, e->e.string_val);
} else {
memcpy (g, &e->e, type_size (get_type (e)) * 4);
}
g += type_size (get_type (e));
} }
} else { } else {
error (e, "non-constant initializer"); error (e, "non-constant initializer");