| author | |
| committer | |
| log | 6e0c3dc173507b92fc04515659454044f918efbb |
| tree | a1e12b910b101293f2e6b6ee0213cd201f82fe29 |
| parent | 75efc313299af89c69c5f2b4a7c2758753ed36c3 |
4 files changed, 38 insertions(+), 9 deletions(-)
example/arrays/arrays.zig+3-2| ... | ... | @@ -9,8 +9,9 @@ extern { |
| 9 | 9 | export fn _start() -> unreachable { |
| 10 | 10 | let mut array : [i32; 10]; |
| 11 | 11 | |
| 12 | array[4] = array[1] + 5; | |
| 12 | exit(array[1]); | |
| 13 | ||
| 14 | //array[4] = array[1] + 5; | |
| 13 | 15 | |
| 14 | 16 | |
| 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 | 124 | entry->align_in_bits = child_type->align_in_bits; |
| 125 | 125 | entry->di_type = LLVMZigCreateDebugArrayType(g->dbuilder, entry->size_in_bits, |
| 126 | 126 | entry->align_in_bits, child_type->di_type, array_size); |
| 127 | entry->data.array.child_type = child_type; | |
| 127 | 128 | |
| 128 | 129 | g->type_table.put(&entry->name, entry); |
| 129 | 130 | child_type->arrays_by_size.put(array_size, entry); |
| ... | ... | @@ -185,7 +186,7 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) { |
| 185 | 186 | size = parse_int(&size_node->data.number); |
| 186 | 187 | } |
| 187 | 188 | |
| 188 | type_node->entry = get_array_type(g, child_type, size); // TODO | |
| 189 | type_node->entry = get_array_type(g, child_type, size); | |
| 189 | 190 | return type_node->entry; |
| 190 | 191 | } |
| 191 | 192 | } |
| ... | ... | @@ -737,12 +738,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 737 | 738 | case NodeTypeArrayAccessExpr: |
| 738 | 739 | { |
| 739 | 740 | // 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 | 742 | node->data.array_access_expr.array_ref_expr); |
| 742 | if (lhs_type->id == TypeTableEntryIdArray) { | |
| 743 | zig_panic("TODO"); | |
| 743 | if (array_type->id == TypeTableEntryIdArray) { | |
| 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 | 751 | } else { |
| 745 | 752 | add_node_error(g, node, buf_sprintf("array access of non-array")); |
| 753 | return_type = g->builtin_types.entry_invalid; | |
| 746 | 754 | } |
| 747 | 755 | |
| 748 | 756 | break; |
src/analyze.hpp+5| ... | ... | @@ -26,6 +26,10 @@ struct TypeTableEntryInt { |
| 26 | 26 | bool is_signed; |
| 27 | 27 | }; |
| 28 | 28 | |
| 29 | struct TypeTableEntryArray { | |
| 30 | TypeTableEntry *child_type; | |
| 31 | }; | |
| 32 | ||
| 29 | 33 | enum TypeTableEntryId { |
| 30 | 34 | TypeTableEntryIdInvalid, |
| 31 | 35 | TypeTableEntryIdVoid, |
| ... | ... | @@ -50,6 +54,7 @@ struct TypeTableEntry { |
| 50 | 54 | union { |
| 51 | 55 | TypeTableEntryPointer pointer; |
| 52 | 56 | TypeTableEntryInt integral; |
| 57 | TypeTableEntryArray array; | |
| 53 | 58 | } data; |
| 54 | 59 | |
| 55 | 60 | // 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 | 170 | static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) { |
| 171 | 171 | assert(node->type == NodeTypeArrayAccessExpr); |
| 172 | 172 | |
| 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 | } |
| 175 | 186 | |
| 176 | 187 | static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { |
| ... | ... | @@ -651,8 +662,12 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |
| 651 | 662 | if (variable->type == g->builtin_types.entry_void) { |
| 652 | 663 | return nullptr; |
| 653 | 664 | } else if (variable->is_ptr) { |
| 654 | add_debug_source_node(g, node); | |
| 655 | return LLVMBuildLoad(g->builder, variable->value_ref, ""); | |
| 665 | if (variable->type->id == TypeTableEntryIdArray) { | |
| 666 | return variable->value_ref; | |
| 667 | } else { | |
| 668 | add_debug_source_node(g, node); | |
| 669 | return LLVMBuildLoad(g->builder, variable->value_ref, ""); | |
| 670 | } | |
| 656 | 671 | } else { |
| 657 | 672 | return variable->value_ref; |
| 658 | 673 | } |