support statically initialized array literal

This commit is contained in:
Andrew Kelley 2016-01-22 22:02:07 -07:00
parent 21fc5a6402
commit 523e3b86af
4 changed files with 38 additions and 16 deletions

View File

@ -34,8 +34,6 @@ static AstNode *first_executing_node(AstNode *node) {
return first_executing_node(node->data.field_access_expr.struct_expr);
case NodeTypeSwitchRange:
return first_executing_node(node->data.switch_range.start);
case NodeTypeContainerInitExpr:
return first_executing_node(node->data.container_init_expr.type);
case NodeTypeRoot:
case NodeTypeRootExportDecl:
case NodeTypeFnProto:
@ -72,6 +70,7 @@ static AstNode *first_executing_node(AstNode *node) {
case NodeTypeSwitchExpr:
case NodeTypeSwitchProng:
case NodeTypeArrayType:
case NodeTypeContainerInitExpr:
return node;
}
zig_unreachable();
@ -1586,9 +1585,22 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
assert(pointer_type->id == TypeTableEntryIdPointer);
TypeTableEntry *child_type = pointer_type->data.pointer.child_type;
ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
const_val->ok = true;
const_val->data.x_array.fields = allocate<ConstExprValue*>(elem_count);
for (int i = 0; i < elem_count; i += 1) {
AstNode *elem_node = container_init_expr->entries.at(i);
analyze_expression(g, import, context, child_type, elem_node);
AstNode **elem_node = &container_init_expr->entries.at(i);
analyze_expression(g, import, context, child_type, *elem_node);
if (const_val->ok) {
ConstExprValue *elem_const_val = &get_resolved_expr(*elem_node)->const_val;
if (elem_const_val->ok) {
const_val->data.x_array.fields[i] = elem_const_val;
} else {
const_val->ok = false;
}
}
}
TypeTableEntry *fixed_size_array_type = get_array_type(g, child_type, elem_count);

View File

@ -2105,13 +2105,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
return tag_value;
} else {
zig_panic("TODO");
/*
LLVMValueRef fields[] = {
tag_value,
union_value,
};
return LLVMConstStruct(fields, 2, false);
*/
}
} else if (type_entry->id == TypeTableEntryIdFn) {
return const_val->data.x_fn->fn_value;
@ -2197,10 +2190,11 @@ static void do_code_gen(CodeGen *g) {
} else {
init_val = LLVMConstNull(var->type->type_ref);
}
LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), "");
LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(init_val), buf_ptr(&var->name));
LLVMSetInitializer(global_value, init_val);
LLVMSetGlobalConstant(global_value, var->is_const);
LLVMSetUnnamedAddr(global_value, true);
LLVMSetLinkage(global_value, LLVMInternalLinkage);
var->value_ref = global_value;
}

View File

@ -12,14 +12,14 @@ pub var stdin = InStream {
pub var stdout = OutStream {
.fd = stdout_fileno,
.buffer = uninitialized,
.buffer = undefined,
.index = 0,
.buffered = true,
};
pub var stderr = OutStream {
.fd = stderr_fileno,
.buffer = uninitialized,
.buffer = undefined,
.index = 0,
.buffered = false,
};
@ -34,7 +34,7 @@ pub %.BadPerm;
pub %.PipeFail;
*/
//const buffer_size: u16 = 4 * 1024;
//const buffer_size = 4 * 1024;
const max_u64_base10_digits: isize = 20;
/*

View File

@ -1244,6 +1244,20 @@ pub fn main(args: [][]u8) i32 => {
}
)SOURCE", "OK\n");
add_simple_case("statically initialized array literal", R"SOURCE(
import "std.zig";
const x = []u8{1,2,3,4};
pub fn main(args: [][]u8) i32 => {
const y : [4]u8 = x;
if (y[3] != 4) {
print_str("BAD\n");
}
print_str("OK\n");
return 0;
}
)SOURCE", "OK\n");
}
@ -1498,12 +1512,14 @@ struct A {
z : i32,
}
fn f() => {
// we want the error on the '{' not the 'A' because
// the A could be a complicated expression
const a = A {
.z = 4,
.y = 2,
};
}
)SOURCE", 1, ".tmp_source.zig:8:17: error: missing field: 'x'");
)SOURCE", 1, ".tmp_source.zig:10:17: error: missing field: 'x'");
add_compile_fail_case("invalid field in struct value expression", R"SOURCE(
struct A {