Browse Source

`expand_to_tuple` for fixed arrays

gingerBill 7 years ago
parent
commit
a11d6e696a
3 changed files with 37 additions and 20 deletions
  1. 15 7
      src/check_expr.cpp
  2. 2 3
      src/exact_value.cpp
  3. 20 10
      src/ir.cpp

+ 15 - 7
src/check_expr.cpp

@@ -3645,20 +3645,28 @@ break;
 	#endif
 	#endif
 	case BuiltinProc_expand_to_tuple: {
 	case BuiltinProc_expand_to_tuple: {
 		Type *type = base_type(operand->type);
 		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);
 			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);
 			gb_string_free(type_str);
 			return false;
 			return false;
 		}
 		}
 		gbAllocator a = c->allocator;
 		gbAllocator a = c->allocator;
 
 
 		Type *tuple = alloc_type_tuple();
 		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->type = tuple;
 		operand->mode = Addressing_Value;
 		operand->mode = Addressing_Value;

+ 2 - 3
src/exact_value.cpp

@@ -37,9 +37,8 @@ struct ExactValue {
 		f64           value_float;
 		f64           value_float;
 		i64           value_pointer;
 		i64           value_pointer;
 		Complex128    value_complex;
 		Complex128    value_complex;
-		Ast *     value_compound;
-		Ast *     value_procedure;
-		Entity *      value_entity;
+		Ast *         value_compound;
+		Ast *         value_procedure;
 	};
 	};
 };
 };
 
 

+ 20 - 10
src/ir.cpp

@@ -4840,19 +4840,29 @@ irValue *ir_build_builtin_proc(irProcedure *proc, Ast *expr, TypeAndValue tv, Bu
 
 
 	case BuiltinProc_expand_to_tuple: {
 	case BuiltinProc_expand_to_tuple: {
 		ir_emit_comment(proc, str_lit("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));
 		GB_ASSERT(is_type_tuple(tv.type));
-
 		irValue *tuple = ir_add_local_generated(proc, 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);
 		return ir_emit_load(proc, tuple);
 	}
 	}