array access support

This commit is contained in:
Andrew Kelley 2015-12-08 14:47:17 -07:00
parent 75efc31329
commit 6e0c3dc173
4 changed files with 38 additions and 9 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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

View file

@ -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;
}