Commit 0c32b0b4ad

Andrew Kelley <superjoe30@gmail.com>
2016-05-08 10:34:00
add list implementation to standard library
1 parent 18ed87c
src/codegen.cpp
@@ -2386,6 +2386,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
     LLVMPositionBuilderAtEnd(g->builder, then_block);
     LLVMValueRef then_expr_result = gen_expr(g, then_node);
     if (then_endif_reachable) {
+        clear_debug_source_node(g);
         LLVMBuildBr(g->builder, endif_block);
     }
     LLVMBasicBlockRef after_then_block = LLVMGetInsertBlock(g->builder);
@@ -2393,6 +2394,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
     LLVMPositionBuilderAtEnd(g->builder, else_block);
     LLVMValueRef else_expr_result = gen_expr(g, else_node);
     if (else_endif_reachable) {
+        clear_debug_source_node(g);
         LLVMBuildBr(g->builder, endif_block);
     }
     LLVMBasicBlockRef after_else_block = LLVMGetInsertBlock(g->builder);
@@ -2400,6 +2402,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV
     if (then_endif_reachable || else_endif_reachable) {
         LLVMPositionBuilderAtEnd(g->builder, endif_block);
         if (use_then_value && use_else_value) {
+            set_debug_source_node(g, source_node);
             LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(then_expr_result), "");
             LLVMValueRef incoming_values[2] = {then_expr_result, else_expr_result};
             LLVMBasicBlockRef incoming_blocks[2] = {after_then_block, after_else_block};
std/index.zig
@@ -5,6 +5,8 @@ pub const math = @import("math.zig");
 pub const str = @import("str.zig");
 pub const cstr = @import("cstr.zig");
 pub const net = @import("net.zig");
+pub const list = @import("list.zig");
+pub const mem = @import("mem.zig");
 
 pub fn assert(b: bool) {
     if (!b) unreachable{}
std/list.zig
@@ -0,0 +1,92 @@
+const assert = @import("index.zig").assert;
+const mem = @import("mem.zig");
+const Allocator = mem.Allocator;
+
+/*
+fn List(T: type) -> type {
+    List(T, 8)
+}
+*/
+
+pub struct SmallList(T: type, STATIC_SIZE: isize) {
+    items: []T,
+    length: isize,
+    prealloc_items: [STATIC_SIZE]T,
+    allocator: &Allocator,
+
+    pub fn init(l: &SmallList(T, STATIC_SIZE), allocator: &Allocator) {
+        l.items = l.prealloc_items[0...];
+        l.length = 0;
+        l.allocator = allocator;
+    }
+
+    pub fn deinit(l: &SmallList(T, STATIC_SIZE)) {
+        if (l.items.ptr == &l.prealloc_items[0]) {
+            l.allocator.free(l.allocator, ([]u8)(l.items));
+        }
+    }
+
+    pub fn append(l: &SmallList(T, STATIC_SIZE), item: T) -> %void {
+        const new_length = l.length + 1;
+        %return l.ensure_capacity(new_length);
+        l.items[l.length] = item;
+        l.length = new_length;
+    }
+
+    pub fn ensure_capacity(l: &SmallList(T, STATIC_SIZE), new_capacity: isize) -> %void {
+        const old_capacity = l.items.len;
+        var better_capacity = old_capacity;
+        while (better_capacity < new_capacity) {
+            better_capacity *= 2;
+        }
+        if (better_capacity != old_capacity) {
+            const alloc_bytes = better_capacity * @sizeof(T);
+            if (l.items.ptr == &l.prealloc_items[0]) {
+                l.items = ([]T)(%return l.allocator.alloc(l.allocator, alloc_bytes));
+                @memcpy(l.items.ptr, &l.prealloc_items[0], old_capacity * @sizeof(T));
+            } else {
+                l.items = ([]T)(%return l.allocator.realloc(l.allocator, ([]u8)(l.items), alloc_bytes));
+            }
+        }
+    }
+}
+
+var global_allocator = Allocator {
+    .alloc = global_alloc,
+    .realloc = global_realloc,
+    .free = global_free,
+    .context = null,
+};
+
+var some_mem: [200]u8 = undefined;
+var some_mem_index: isize = 0;
+
+fn global_alloc(self: &Allocator, n: isize) -> %[]u8 {
+    const result = some_mem[some_mem_index ... some_mem_index + n];
+    some_mem_index += n;
+    return result;
+}
+
+fn global_realloc(self: &Allocator, old_mem: []u8, new_size: isize) -> %[]u8 {
+    const result = %return global_alloc(self, new_size);
+    @memcpy(result.ptr, old_mem.ptr, old_mem.len);
+    return result;
+}
+
+fn global_free(self: &Allocator, old_mem: []u8) {
+}
+
+#attribute("test")
+fn basic_list_test() {
+    var list: SmallList(i32, 4) = undefined;
+    list.init(&global_allocator);
+    defer list.deinit();
+
+    {var i: isize = 0; while (i < 10; i += 1) {
+        %%list.append(i32(i + 1));
+    }}
+
+    {var i: isize = 0; while (i < 10; i += 1) {
+        assert(list.items[i] == i32(i + 1));
+    }}
+}
std/mem.zig
@@ -0,0 +1,10 @@
+pub error NoMem;
+
+pub type Context = u8;
+pub struct Allocator {
+    alloc: fn (self: &Allocator, n: isize) -> %[]u8,
+    realloc: fn (self: &Allocator, old_mem: []u8, new_size: isize) -> %[]u8,
+    free: fn (self: &Allocator, mem: []u8),
+    context: ?&Context,
+}
+
test/run_tests.cpp
@@ -1666,7 +1666,7 @@ static void run_self_hosted_test(bool is_release_mode) {
     Termination term;
     os_exec_process(zig_exe, args, &term, &zig_stderr, &zig_stdout);
 
-    if (term.how != TerminationIdClean) {
+    if (term.how != TerminationIdClean || term.code != 0) {
         printf("\nSelf-hosted tests failed:\n");
         printf("./zig");
         for (int i = 0; i < args.length; i += 1) {
test/self_hosted.zig
@@ -1622,7 +1622,8 @@ fn div_exact(a: u32, b: u32) -> u32 {
 
 #attribute("test")
 fn null_literal_outside_function() {
-    assert(here_is_a_null_literal.context == null);
+    const is_null = if (const _ ?= here_is_a_null_literal.context) false else true;
+    assert(is_null);
 }
 struct SillyStruct {
     context: ?i32,
CMakeLists.txt
@@ -214,6 +214,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/math.zig" DESTINATION "${ZIG_STD_DEST}")
 install(FILES "${CMAKE_SOURCE_DIR}/std/index.zig" DESTINATION "${ZIG_STD_DEST}")
 install(FILES "${CMAKE_SOURCE_DIR}/std/linux_x86_64.zig" DESTINATION "${ZIG_STD_DEST}")
 install(FILES "${CMAKE_SOURCE_DIR}/std/linux_i386.zig" DESTINATION "${ZIG_STD_DEST}")
+install(FILES "${CMAKE_SOURCE_DIR}/std/mem.zig" DESTINATION "${ZIG_STD_DEST}")
+install(FILES "${CMAKE_SOURCE_DIR}/std/list.zig" DESTINATION "${ZIG_STD_DEST}")
 
 add_executable(run_tests ${TEST_SOURCES})
 target_link_libraries(run_tests)