| 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,8 +9,9 @@ extern { |
| 9 | export fn _start() -> unreachable { | 9 | export fn _start() -> unreachable { |
| 10 | let mut array : [i32; 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,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; | ||
| 127 | 128 | ||
| 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 | } |
| 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 | 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 array | 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 | 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 | } |
| 747 | 755 | ||
| 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 | }; |
| 28 | 28 | ||
| 29 | struct TypeTableEntryArray { | ||
| 30 | TypeTableEntry *child_type; | ||
| 31 | }; | ||
| 32 | |||
| 29 | enum TypeTableEntryId { | 33 | enum 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; |
| 54 | 59 | ||
| 55 | // use these fields to make sure we don't duplicate type table entries for the same type | 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,7 +170,18 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) { |
| 170 | static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) { | 170 | static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) { |
| 171 | assert(node->type == NodeTypeArrayAccessExpr); | 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 | static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) { | 187 | static 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 | } |