[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, int algebra_type_assignable (const struct type_s *dst,
const struct type_s *src) __attribute__((pure)); const struct type_s *src) __attribute__((pure));
struct type_s *algebra_base_type (const struct type_s *type) __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)); bool is_mono_grade (const struct type_s *type) __attribute__((pure));
int algebra_get_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)); 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]; 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 int
algebra_blade_grade (basis_blade_t blade) 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); return alias_expr (type, expr, offset);
} }
static symbol_t * static symtab_t *
get_mvec_sym (type_t *type) get_mvec_struct (type_t *type)
{ {
symbol_t *sym = 0; symbol_t *sym = 0;
if (type->type == ev_invalid) { if (type->type == ev_invalid) {
@ -185,7 +185,14 @@ get_mvec_sym (type_t *type)
} else { } else {
sym = type->t.multivec->mvec_sym; 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 static bool

View file

@ -206,8 +206,19 @@ build_element_chain (element_chain_t *element_chain, const type_t *type,
initstate_t state = {}; initstate_t state = {};
if (is_algebra (type)) { if (is_algebra (type)) {
error (eles, "block initializer of multi-vector type"); for (auto e = ele; e; e = e->next) {
return; 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) } else if (is_struct (type) || is_union (type)
|| (is_nonscalar (type) && type->t.symtab)) { || (is_nonscalar (type) && type->t.symtab)) {
state.field = type->t.symtab->symbols; state.field = type->t.symtab->symbols;
@ -308,7 +319,7 @@ assign_elements (expr_t *local_expr, expr_t *init,
expr_t *c; expr_t *c;
if (type_size (type) == 0) if (type_size (type) == 0)
internal_error (init, "wtf"); internal_error (init, "wtw");
if (element->expr) { if (element->expr) {
c = constant_expr (element->expr); c = constant_expr (element->expr);
} else { } else {
@ -336,6 +347,12 @@ assign_elements (expr_t *local_expr, expr_t *init,
start = in->element; 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); set_delete (initialized);
} }