authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-15 20:01:49-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-15 20:01:49-07:00
log8205253b2b660791ff074b7cb09b8f11bfe924dc
tree1b6c2bcd23ea540966c7a804af09108647b163d9
parent8bc3fae1cf055e33e01e0cbbbbc67f307f60b95b

support array literals


3 files changed, 70 insertions(+), 9 deletions(-)

src/analyze.cpp+26-4
......@@ -233,8 +233,7 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
233233 }
234234}
235235
236static TypeTableEntry *get_array_type(CodeGen *g, ImportTableEntry *import,
237 TypeTableEntry *child_type, uint64_t array_size)
236static TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size)
238237{
239238 auto existing_entry = child_type->arrays_by_size.maybe_get(array_size);
240239 if (existing_entry) {
......@@ -1389,6 +1388,29 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
13891388 }
13901389 }
13911390 return container_type;
1391 } else if (container_type->id == TypeTableEntryIdStruct &&
1392 container_type->data.structure.is_unknown_size_array &&
1393 kind == ContainerInitKindArray)
1394 {
1395 int elem_count = container_init_expr->entries.length;
1396
1397 TypeTableEntry *pointer_type = container_type->data.structure.fields[0].type_entry;
1398 assert(pointer_type->id == TypeTableEntryIdPointer);
1399 TypeTableEntry *child_type = pointer_type->data.pointer.child_type;
1400
1401 for (int i = 0; i < elem_count; i += 1) {
1402 AstNode *elem_node = container_init_expr->entries.at(i);
1403 analyze_expression(g, import, context, child_type, elem_node);
1404 }
1405
1406 TypeTableEntry *fixed_size_array_type = get_array_type(g, child_type, elem_count);
1407
1408 StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr;
1409 codegen->type_entry = fixed_size_array_type;
1410 codegen->source_node = node;
1411 context->struct_val_expr_alloca_list.append(codegen);
1412
1413 return fixed_size_array_type;
13921414 } else if (container_type->id == TypeTableEntryIdArray) {
13931415 zig_panic("TODO array container init");
13941416 return container_type;
......@@ -2151,7 +2173,7 @@ static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import,
21512173 ConstExprValue *const_val = &get_resolved_expr(size_node)->const_val;
21522174 if (const_val->ok) {
21532175 return resolve_expr_const_val_as_type(g, node,
2154 get_array_type(g, import, child_type, const_val->data.x_uint));
2176 get_array_type(g, child_type, const_val->data.x_uint));
21552177 } else {
21562178 add_node_error(g, size_node, buf_create_from_str("unable to resolve constant expression"));
21572179 return g->builtin_types.entry_invalid;
......@@ -2986,7 +3008,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
29863008 if (node->data.string_literal.c) {
29873009 return_type = g->builtin_types.entry_c_string_literal;
29883010 } else {
2989 return_type = get_array_type(g, import, g->builtin_types.entry_u8,
3011 return_type = get_array_type(g, g->builtin_types.entry_u8,
29903012 buf_len(&node->data.string_literal.buf));
29913013 }
29923014 break;
src/codegen.cpp+25-5
......@@ -1132,7 +1132,8 @@ static LLVMValueRef gen_struct_memcpy(CodeGen *g, AstNode *source_node, LLVMValu
11321132{
11331133 assert(type_entry->id == TypeTableEntryIdStruct ||
11341134 type_entry->id == TypeTableEntryIdMaybe ||
1135 (type_entry->id == TypeTableEntryIdEnum && type_entry->data.enumeration.gen_field_count != 0));
1135 (type_entry->id == TypeTableEntryIdEnum && type_entry->data.enumeration.gen_field_count != 0) ||
1136 type_entry->id == TypeTableEntryIdArray);
11361137
11371138 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
11381139
......@@ -1157,11 +1158,9 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b
11571158{
11581159 if (op1_type->id == TypeTableEntryIdStruct ||
11591160 (op1_type->id == TypeTableEntryIdEnum && op1_type->data.enumeration.gen_field_count != 0) ||
1160 op1_type->id == TypeTableEntryIdMaybe)
1161 op1_type->id == TypeTableEntryIdMaybe ||
1162 op1_type->id == TypeTableEntryIdArray)
11611163 {
1162 assert(op2_type->id == TypeTableEntryIdStruct ||
1163 (op2_type->id == TypeTableEntryIdEnum && op2_type->data.enumeration.gen_field_count != 0) ||
1164 op2_type->id == TypeTableEntryIdMaybe);
11651164 assert(op1_type == op2_type);
11661165 assert(bin_op == BinOpTypeAssign);
11671166
......@@ -1633,6 +1632,27 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
16331632 } else if (type_entry->id == TypeTableEntryIdVoid) {
16341633 assert(node->data.container_init_expr.entries.length == 0);
16351634 return nullptr;
1635 } else if (type_entry->id == TypeTableEntryIdArray) {
1636 StructValExprCodeGen *struct_val_expr_node = &node->data.container_init_expr.resolved_struct_val_expr;
1637 LLVMValueRef tmp_array_ptr = struct_val_expr_node->ptr;
1638
1639 int field_count = type_entry->data.array.len;
1640 assert(field_count == node->data.container_init_expr.entries.length);
1641
1642 for (int i = 0; i < field_count; i += 1) {
1643 AstNode *field_node = node->data.container_init_expr.entries.at(i);
1644 LLVMValueRef elem_val = gen_expr(g, field_node);
1645
1646 LLVMValueRef indices[] = {
1647 LLVMConstNull(g->builtin_types.entry_usize->type_ref),
1648 LLVMConstInt(g->builtin_types.entry_usize->type_ref, i, false),
1649 };
1650 add_debug_source_node(g, field_node);
1651 LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, tmp_array_ptr, indices, 2, "");
1652 LLVMBuildStore(g->builder, elem_val, elem_ptr);
1653 }
1654
1655 return tmp_array_ptr;
16361656 } else {
16371657 zig_unreachable();
16381658 }
test/run_tests.cpp+19
......@@ -1102,6 +1102,25 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
11021102 return 0;
11031103}
11041104 )SOURCE", "OK\n");
1105
1106 add_simple_case("array literal", R"SOURCE(
1107import "std.zig";
1108
1109pub fn main(argc: isize, argv: &&u8, env: &&u8) i32 => {
1110 const HEX_MULT = []u16{4096, 256, 16, 1};
1111
1112 if (HEX_MULT.len != 4) {
1113 print_str("BAD\n");
1114 }
1115
1116 if (HEX_MULT[1] != 256) {
1117 print_str("BAD\n");
1118 }
1119
1120 print_str("OK\n");
1121 return 0;
1122}
1123 )SOURCE", "OK\n");
11051124}
11061125
11071126