diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c1b2be3b8..03747a26f 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3645,20 +3645,28 @@ break; #endif case BuiltinProc_expand_to_tuple: { Type *type = base_type(operand->type); - if (!is_type_struct(type) && - !is_type_union(type)) { + if (!is_type_struct(type) && !is_type_array(type)) { gbString type_str = type_to_string(operand->type); - error(call, "Expected a struct or union type, got '%s'", type_str); + error(call, "Expected a struct or array type, got '%s'", type_str); gb_string_free(type_str); return false; } gbAllocator a = c->allocator; Type *tuple = alloc_type_tuple(); - isize variable_count = type->Struct.fields.count; - array_init(&tuple->Tuple.variables, a, variable_count); - // TODO(bill): Should I copy each of the entities or is this good enough? - gb_memmove_array(tuple->Tuple.variables.data, type->Struct.fields.data, variable_count); + + if (is_type_struct(type)) { + isize variable_count = type->Struct.fields.count; + array_init(&tuple->Tuple.variables, a, variable_count); + // TODO(bill): Should I copy each of the entities or is this good enough? + gb_memmove_array(tuple->Tuple.variables.data, type->Struct.fields.data, variable_count); + } else if (is_type_array(type)) { + isize variable_count = type->Array.count; + array_init(&tuple->Tuple.variables, a, variable_count); + for (isize i = 0; i < variable_count; i++) { + tuple->Tuple.variables[i] = alloc_entity_array_elem(nullptr, blank_token, type->Array.elem, cast(i32)i); + } + } operand->type = tuple; operand->mode = Addressing_Value; diff --git a/src/exact_value.cpp b/src/exact_value.cpp index 8027b1038..4d455c8e2 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -37,9 +37,8 @@ struct ExactValue { f64 value_float; i64 value_pointer; Complex128 value_complex; - Ast * value_compound; - Ast * value_procedure; - Entity * value_entity; + Ast * value_compound; + Ast * value_procedure; }; }; diff --git a/src/ir.cpp b/src/ir.cpp index 98bfbb99f..e546015d7 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4840,19 +4840,29 @@ irValue *ir_build_builtin_proc(irProcedure *proc, Ast *expr, TypeAndValue tv, Bu case BuiltinProc_expand_to_tuple: { ir_emit_comment(proc, str_lit("expand_to_tuple")); - irValue *s = ir_build_expr(proc, ce->args[0]); - Type *t = base_type(ir_type(s)); + irValue *val = ir_build_expr(proc, ce->args[0]); + Type *t = base_type(ir_type(val)); - GB_ASSERT(t->kind == Type_Struct); GB_ASSERT(is_type_tuple(tv.type)); - irValue *tuple = ir_add_local_generated(proc, tv.type); - for_array(src_index, t->Struct.fields) { - Entity *field = t->Struct.fields[src_index]; - i32 field_index = field->Variable.field_index; - irValue *f = ir_emit_struct_ev(proc, s, field_index); - irValue *ep = ir_emit_struct_ep(proc, tuple, cast(i32)src_index); - ir_emit_store(proc, ep, f); + if (t->kind == Type_Struct) { + for_array(src_index, t->Struct.fields) { + Entity *field = t->Struct.fields[src_index]; + i32 field_index = field->Variable.field_index; + irValue *f = ir_emit_struct_ev(proc, val, field_index); + irValue *ep = ir_emit_struct_ep(proc, tuple, cast(i32)src_index); + ir_emit_store(proc, ep, f); + } + } else if (t->kind == Type_Array) { + // TODO(bill): Clean-up this code + irValue *ap = ir_address_from_load_or_generate_local(proc, val); + for (i32 i = 0; i < cast(i32)t->Array.count; i++) { + irValue *f = ir_emit_load(proc, ir_emit_array_epi(proc, ap, i)); + irValue *ep = ir_emit_struct_ep(proc, tuple, i); + ir_emit_store(proc, ep, f); + } + } else { + GB_PANIC("Unknown type of expand_to_tuple"); } return ir_emit_load(proc, tuple); }