[qfcc] Support block initializers for multi-vectors

They're not supported (yet) for single-group multi-vectors, and
designators are required for all initializer elements.
This commit is contained in:
Bill Currie 2023-09-11 00:24:50 +09:00
parent bce2b7d767
commit d387b56f60
4 changed files with 44 additions and 6 deletions

View file

@ -104,6 +104,7 @@ algebra_t *algebra_get (const struct type_s *type) __attribute__((pure));
int algebra_type_assignable (const struct type_s *dst,
const struct type_s *src) __attribute__((pure));
struct type_s *algebra_base_type (const struct type_s *type) __attribute__((pure));
struct type_s *algebra_struct_type (const struct type_s *type) __attribute__((pure));
bool is_mono_grade (const struct type_s *type) __attribute__((pure));
int algebra_get_grade (const struct type_s *type) __attribute__((pure));
int algebra_blade_grade (basis_blade_t blade) __attribute__((const));

View file

@ -782,6 +782,19 @@ algebra_base_type (const type_t *type)
return ev_types[type->type];
}
type_t *
algebra_struct_type (const type_t *type)
{
symbol_t *sym = 0;
if (type->type == ev_invalid) {
sym = type->t.algebra->mvec_sym;
} else {
sym = type->t.multivec->mvec_sym;
}
return sym ? sym->type : 0;
}
int
algebra_blade_grade (basis_blade_t blade)
{

View file

@ -176,8 +176,8 @@ offset_cast (type_t *type, expr_t *expr, int offset)
return alias_expr (type, expr, offset);
}
static symbol_t *
get_mvec_sym (type_t *type)
static symtab_t *
get_mvec_struct (type_t *type)
{
symbol_t *sym = 0;
if (type->type == ev_invalid) {
@ -185,7 +185,14 @@ get_mvec_sym (type_t *type)
} else {
sym = type->t.multivec->mvec_sym;
}
return sym->type->t.symtab->symbols;
return sym ? sym->type->t.symtab : 0;
}
static symbol_t *
get_mvec_sym (type_t *type)
{
auto symtab = get_mvec_struct (type);
return symtab ? symtab->symbols : 0;
}
static bool

View file

@ -206,8 +206,19 @@ build_element_chain (element_chain_t *element_chain, const type_t *type,
initstate_t state = {};
if (is_algebra (type)) {
error (eles, "block initializer of multi-vector type");
return;
for (auto e = ele; e; e = e->next) {
if (!e->designator) {
error (eles, "block initializer of multi-vector type requires "
"designators for all initializer elements");
return;
}
}
auto t = algebra_struct_type (type);
if (!t) {
error (eles, "block initializer on simple multi-vector type");
return;
}
type = t;
} else if (is_struct (type) || is_union (type)
|| (is_nonscalar (type) && type->t.symtab)) {
state.field = type->t.symtab->symbols;
@ -308,7 +319,7 @@ assign_elements (expr_t *local_expr, expr_t *init,
expr_t *c;
if (type_size (type) == 0)
internal_error (init, "wtf");
internal_error (init, "wtw");
if (element->expr) {
c = constant_expr (element->expr);
} else {
@ -336,6 +347,12 @@ assign_elements (expr_t *local_expr, expr_t *init,
start = in->element;
}
}
if (start < (unsigned) type_size (init_type)) {
expr_t *dst = new_offset_alias_expr (&type_int, init, start);
expr_t *zero = new_int_expr (0);
expr_t *count = new_int_expr (type_size (init_type) - start);
append_expr (local_expr, new_memset_expr (dst, zero, count));
}
set_delete (initialized);
}