Commit 6e0c3dc173
Changed files (4)
example
arrays
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;
}