Commit 6e0c3dc173

Andrew Kelley <superjoe30@gmail.com>
2015-12-08 22:47:17
array access support
1 parent 75efc31
Changed files (4)
example/arrays/arrays.zig
@@ -9,8 +9,9 @@ extern {
 export fn _start() -> unreachable {
     let mut array : [i32; 10];
 
-    array[4] = array[1] + 5;
+    exit(array[1]);
+
+    //array[4] = array[1] + 5;
 
 
-    exit(0); 
 }
src/analyze.cpp
@@ -124,6 +124,7 @@ static TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, in
         entry->align_in_bits = child_type->align_in_bits;
         entry->di_type = LLVMZigCreateDebugArrayType(g->dbuilder, entry->size_in_bits,
                 entry->align_in_bits, child_type->di_type, array_size);
+        entry->data.array.child_type = child_type;
 
         g->type_table.put(&entry->name, entry);
         child_type->arrays_by_size.put(array_size, entry);
@@ -185,7 +186,7 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node) {
                     size = parse_int(&size_node->data.number);
                 }
 
-                type_node->entry = get_array_type(g, child_type, size); // TODO
+                type_node->entry = get_array_type(g, child_type, size);
                 return type_node->entry;
             }
     }
@@ -737,12 +738,19 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
         case NodeTypeArrayAccessExpr:
             {
                 // here we are always reading the array
-                TypeTableEntry *lhs_type = analyze_expression(g, import, context, nullptr,
+                TypeTableEntry *array_type = analyze_expression(g, import, context, nullptr,
                         node->data.array_access_expr.array_ref_expr);
-                if (lhs_type->id == TypeTableEntryIdArray) {
-                    zig_panic("TODO");
+                if (array_type->id == TypeTableEntryIdArray) {
+                    TypeTableEntry *subscript_type = analyze_expression(g, import, context,
+                            nullptr, node->data.array_access_expr.subscript);
+                    if (subscript_type->id != TypeTableEntryIdInt) {
+                        add_node_error(g, node,
+                            buf_sprintf("array subscripts must be integers"));
+                    }
+                    return_type = array_type->data.array.child_type;
                 } else {
                     add_node_error(g, node, buf_sprintf("array access of non-array"));
+                    return_type = g->builtin_types.entry_invalid;
                 }
 
                 break;
src/analyze.hpp
@@ -26,6 +26,10 @@ struct TypeTableEntryInt {
     bool is_signed;
 };
 
+struct TypeTableEntryArray {
+    TypeTableEntry *child_type;
+};
+
 enum TypeTableEntryId {
     TypeTableEntryIdInvalid,
     TypeTableEntryIdVoid,
@@ -50,6 +54,7 @@ struct TypeTableEntry {
     union {
         TypeTableEntryPointer pointer;
         TypeTableEntryInt integral;
+        TypeTableEntryArray array;
     } data;
 
     // use these fields to make sure we don't duplicate type table entries for the same type
src/codegen.cpp
@@ -170,7 +170,18 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
 static LLVMValueRef gen_array_access_expr(CodeGen *g, AstNode *node) {
     assert(node->type == NodeTypeArrayAccessExpr);
 
-    zig_panic("TODO gen arary access");
+    LLVMValueRef array_ref_value = gen_expr(g, node->data.array_access_expr.array_ref_expr);
+    LLVMValueRef subscript_value = gen_expr(g, node->data.array_access_expr.subscript);
+
+    assert(array_ref_value);
+    assert(subscript_value);
+
+    LLVMValueRef indices[] = {
+        LLVMConstInt(LLVMInt32Type(), 0, false),
+        subscript_value
+    };
+    LLVMValueRef result_ptr = LLVMBuildInBoundsGEP(g->builder, array_ref_value, indices, 2, "");
+    return LLVMBuildLoad(g->builder, result_ptr, "");
 }
 
 static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
@@ -651,8 +662,12 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
                 if (variable->type == g->builtin_types.entry_void) {
                     return nullptr;
                 } else if (variable->is_ptr) {
-                    add_debug_source_node(g, node);
-                    return LLVMBuildLoad(g->builder, variable->value_ref, "");
+                    if (variable->type->id == TypeTableEntryIdArray) {
+                        return variable->value_ref;
+                    } else {
+                        add_debug_source_node(g, node);
+                        return LLVMBuildLoad(g->builder, variable->value_ref, "");
+                    }
                 } else {
                     return variable->value_ref;
                 }