authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-08 14:47:17-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-08 14:47:17-07:00
log6e0c3dc173507b92fc04515659454044f918efbb
treea1e12b910b101293f2e6b6ee0213cd201f82fe29
parent75efc313299af89c69c5f2b4a7c2758753ed36c3

array access support


4 files changed, 38 insertions(+), 9 deletions(-)

example/arrays/arrays.zig+3-2
...@@ -9,8 +9,9 @@ extern {...@@ -9,8 +9,9 @@ extern {
9export fn _start() -> unreachable {9export fn _start() -> unreachable {
10 let mut array : [i32; 10];10 let mut array : [i32; 10];
1111
12 array[4] = array[1] + 5;12 exit(array[1]);
13
14 //array[4] = array[1] + 5;
1315
1416
15 exit(0);
16}17}
src/analyze.cpp+12-4
...@@ -124,6 +124,7 @@ static TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, in...@@ -124,6 +124,7 @@ static TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, in
124 entry->align_in_bits = child_type->align_in_bits;124 entry->align_in_bits = child_type->align_in_bits;
125 entry->di_type = LLVMZigCreateDebugArrayType(g->dbuilder, entry->size_in_bits,125 entry->di_type = LLVMZigCreateDebugArrayType(g->dbuilder, entry->size_in_bits,
126 entry->align_in_bits, child_type->di_type, array_size);126 entry->align_in_bits, child_type->di_type, array_size);
127 entry->data.array.child_type = child_type;
127128
128 g->type_table.put(&entry->name, entry);129 g->type_table.put(&entry->name, entry);
129 child_type->arrays_by_size.put(array_size, entry);130 child_type->arrays_by_size.put(array_size, entry);
...@@ -185,7 +186,7 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) {...@@ -185,7 +186,7 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) {
185 size = parse_int(&size_node->data.number);186 size = parse_int(&size_node->data.number);
186 }187 }
187188
188 type_node->entry = get_array_type(g, child_type, size); // TODO189 type_node->entry = get_array_type(g, child_type, size);
189 return type_node->entry;190 return type_node->entry;
190 }191 }
191 }192 }
...@@ -737,12 +738,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -737,12 +738,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
737 case NodeTypeArrayAccessExpr:738 case NodeTypeArrayAccessExpr:
738 {739 {
739 // here we are always reading the array740 // here we are always reading the array
740 TypeTableEntry *lhs_type = analyze_expression(g, import, context, nullptr,741 TypeTableEntry *array_type = analyze_expression(g, import, context, nullptr,
741 node->data.array_access_expr.array_ref_expr);742 node->data.array_access_expr.array_ref_expr);
742 if (lhs_type->id == TypeTableEntryIdArray) {743 if (array_type->id == TypeTableEntryIdArray) {
743 zig_panic("TODO");744 TypeTableEntry *subscript_type = analyze_expression(g, import, context,
745 nullptr, node->data.array_access_expr.subscript);
746 if (subscript_type->id != TypeTableEntryIdInt) {
747 add_node_error(g, node,
748 buf_sprintf("array subscripts must be integers"));
749 }
750 return_type = array_type->data.array.child_type;
744 } else {751 } else {
745 add_node_error(g, node, buf_sprintf("array access of non-array"));752 add_node_error(g, node, buf_sprintf("array access of non-array"));
753 return_type = g->builtin_types.entry_invalid;
746 }754 }
747755
748 break;756 break;
src/analyze.hpp+5
...@@ -26,6 +26,10 @@ struct TypeTableEntryInt {...@@ -26,6 +26,10 @@ struct TypeTableEntryInt {
26 bool is_signed;26 bool is_signed;
27};27};
2828
29struct TypeTableEntryArray {
30 TypeTableEntry *child_type;
31};
32
29enum TypeTableEntryId {33enum TypeTableEntryId {
30 TypeTableEntryIdInvalid,34 TypeTableEntryIdInvalid,
31 TypeTableEntryIdVoid,35 TypeTableEntryIdVoid,
...@@ -50,6 +54,7 @@ struct TypeTableEntry {...@@ -50,6 +54,7 @@ struct TypeTableEntry {
50 union {54 union {
51 TypeTableEntryPointer pointer;55 TypeTableEntryPointer pointer;
52 TypeTableEntryInt integral;56 TypeTableEntryInt integral;
57 TypeTableEntryArray array;
53 } data;58 } data;
5459
55 // use these fields to make sure we don't duplicate type table entries for the same type60 // use these fields to make sure we don't duplicate type table entries for the same type
src/codegen.cpp+18-3
...@@ -170,7 +170,18 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -170,7 +170,18 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
170static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) {170static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) {
171 assert(node->type == NodeTypeArrayAccessExpr);171 assert(node->type == NodeTypeArrayAccessExpr);
172172
173 zig_panic("TODO gen arary access");173 LLVMValueRef array_ref_value = gen_expr(g, node->data.array_access_expr.array_ref_expr);
174 LLVMValueRef subscript_value = gen_expr(g, node->data.array_access_expr.subscript);
175
176 assert(array_ref_value);
177 assert(subscript_value);
178
179 LLVMValueRef indices[] = {
180 LLVMConstInt(LLVMInt32Type(), 0, false),
181 subscript_value
182 };
183 LLVMValueRef result_ptr = LLVMBuildInBoundsGEP(g->builder, array_ref_value, indices, 2, "");
184 return LLVMBuildLoad(g->builder, result_ptr, "");
174}185}
175186
176static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {187static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
...@@ -651,8 +662,12 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -651,8 +662,12 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
651 if (variable->type == g->builtin_types.entry_void) {662 if (variable->type == g->builtin_types.entry_void) {
652 return nullptr;663 return nullptr;
653 } else if (variable->is_ptr) {664 } else if (variable->is_ptr) {
654 add_debug_source_node(g, node);665 if (variable->type->id == TypeTableEntryIdArray) {
655 return LLVMBuildLoad(g->builder, variable->value_ref, "");666 return variable->value_ref;
667 } else {
668 add_debug_source_node(g, node);
669 return LLVMBuildLoad(g->builder, variable->value_ref, "");
670 }
656 } else {671 } else {
657 return variable->value_ref;672 return variable->value_ref;
658 }673 }