diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-07-18 20:39:53 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-07-18 20:39:53 +0100 |
| commit | 4db462a703d506f2ef23a16921a23a10115feacb (patch) | |
| tree | c8119bf1324e62a95faffbd6a2157c36c321cb38 | |
| parent | a22c6d6c0ca7b58e4942efa62937ee2242ba7b1d (diff) | |
Fix `copy`
| -rw-r--r-- | code/demo.odin | 198 | ||||
| -rw-r--r-- | core/_preload.odin | 5 | ||||
| -rw-r--r-- | core/os.odin | 4 | ||||
| -rw-r--r-- | core/strings.odin | 1 |
4 files changed, 9 insertions, 199 deletions
diff --git a/code/demo.odin b/code/demo.odin index 903278399..11ffec8ce 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -1,199 +1,5 @@ -import ( - "fmt.odin"; - "atomics.odin"; - "bits.odin"; - "hash.odin"; - "math.odin"; - "mem.odin"; - "opengl.odin"; - "os.odin"; - "pool.odin"; - "raw.odin"; - "sort.odin"; - "strconv.odin"; - "strings.odin"; - "sync.odin"; - "types.odin"; - "utf8.odin"; - "utf16.odin"; -) - -Table :: struct(Key, Value: type) { - Slot :: struct { - occupied: bool; - hash: u32; - key: Key; - value: Value; - } - SIZE_MIN :: 32; - - count: int; - allocator: Allocator; - slots: []Slot; -} - -allocate :: proc(table: ^$T/Table, capacity: int) { - c := context; - if table.allocator.procedure != nil do c.allocator = table.allocator; - - push_context c { - table.slots = make([]T.Slot, max(capacity, T.SIZE_MIN)); - } -} - -expand :: proc(table: ^$T/Table) { - c := context; - if table.allocator.procedure != nil do c.allocator = table.allocator; - - push_context c { - old_slots := table.slots; - - cap := max(2*cap(table.slots), T.SIZE_MIN); - allocate(table, cap); - - for s in old_slots do if s.occupied { - put(table, s.key, s.value); - } - - free(old_slots); - } -} - -// put :: proc(table: ^$T/Table, key: T.Key, value: T.Value) { -put :: proc(table: ^Table($Key, $Value), key: Key, value: Value) { - hash := get_hash(key); // Ad-hoc method which would fail in differentcope - index := find_index(table, key, hash); - if index < 0 { - if f64(table.count) >= 0.75*cast(f64)cap(table.slots) { - expand(table); - } - assert(table.count <= cap(table.slots)); - - hash := get_hash(key); - index = cast(int)(hash % cast(u32)cap(table.slots)); - - for table.slots[index].occupied { - index += 1; - if index >= cap(table.slots) { - index = 0; - } - } - - table.count += 1; - } - - slot := &table.slots[index]; - slot.occupied = true; - slot.hash = hash; - slot.key = key; - slot.value = value; -} - - -// find :: proc(table: ^$T/Table, key: T.Key) -> (T.Value, bool) { -find :: proc(table: ^Table($Key, $Value), key: Key) -> (Value, bool) { - hash := get_hash(key); - index := find_index(table, key, hash); - if index < 0 { - return Value{}, false; - } - return table.slots[index].value, true; -} - -find_index :: proc(table: ^Table($Key, $Value), key: Key, hash: u32) -> int { - if cap(table.slots) <= 0 do return -1; - - slot := int(hash % cast(u32)cap(table.slots)); - - index := slot; - for table.slots[index].occupied { - if table.slots[index].hash == hash { - if table.slots[index].key == key { - return index; - } - } - - if index += 1; index >= cap(table.slots) { - index = 0; - } - } - - return -1; -} - -get_hash :: proc(s: string) -> u32 { - // djb2 - hash: u32 = 5381; - for i in 0..len(s) do hash = (hash<<5) + hash + u32(s[i]); - return hash; -} - - - -Vector :: struct(N: int, T: type) #raw_union { - using e: [N]T; - when 0 < N && N <= 4 { - using v: struct { - when N >= 1 do x: T; - when N >= 2 do y: T; - when N >= 3 do z: T; - when N >= 4 do w: T; - }; - } -} - -Vector3 :: Vector(3, f32); - -add :: proc(a, b: $T/Vector) -> T { - c := a; - for i in 0..3 { - c[i] += b[i]; - } - return c; -} - -foo1 :: proc(a: type/Vector) { fmt.println("foo1", a{}); } -// foo2 :: proc(a: type/Vector(3, f32)) {} -foo3 :: proc(a: type/Vector(3, $T)) { fmt.println("foo3", a{}); } -// foo4 :: proc(a: type/Vector3) {} - +import "fmt.odin"; main :: proc() { - // Foo :: struct { - // a := 123; - // b := true; - // } - // v1 := Foo{}; - // fmt.println(v1); - - // foo1(Vector(3, f32)); - // foo1(Vector3); - // foo3(Vector(3, f32)); - // foo3(Vector3); - - - a, b: Vector3; - a[0] = 1; - a[1] = 4; - a[2] = 9; - - b.x = 3; - b.y = 4; - b.z = 5; - - v := add(a, b); - fmt.println(size_of(Vector3)); - fmt.println(v.e, v.v); - - // table: Table(string, int); - - // for i in 0..36 do put(&table, "Hellope", i); - // for i in 0..42 do put(&table, "World!", i); - - - // found, _ := find(&table, "Hellope"); - // fmt.printf("found is %v\n", found); - - // found, _ = find(&table, "World!"); - // fmt.printf("found is %v\n", found); + fmt.println("Hellope, World!"); } diff --git a/core/_preload.odin b/core/_preload.odin index 4c4d8f2b9..ae331d830 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -305,7 +305,7 @@ resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_AL copy :: proc(dst, src: $T/[]$E) -> int #cc_contextless { n := max(0, min(len(dst), len(src))); - if n > 0 do __mem_copy(&dst[0], &src[0], n*size_of(T)); + if n > 0 do __mem_copy(&dst[0], &src[0], n*size_of(E)); return n; } @@ -670,6 +670,7 @@ __string_decode_rune :: proc(s: string) -> (rune, int) #cc_contextless #inline { __mem_set :: proc(data: rawptr, value: i32, len: int) -> rawptr #cc_contextless { + if data == nil do return nil; when size_of(rawptr) == 8 { foreign __llvm_core llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) #link_name "llvm.memset.p0i8.i64" ---; } else { @@ -682,6 +683,7 @@ __mem_zero :: proc(data: rawptr, len: int) -> rawptr #cc_contextless { return __mem_set(data, 0, len); } __mem_copy :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless { + if src == nil do return dst; // NOTE(bill): This _must_ be implemented like C's memmove when size_of(rawptr) == 8 { foreign __llvm_core llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memmove.p0i8.p0i8.i64" ---; @@ -692,6 +694,7 @@ __mem_copy :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless { return dst; } __mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless { + if src == nil do return dst; // NOTE(bill): This _must_ be implemented like C's memcpy when size_of(rawptr) == 8 { foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i64" ---; diff --git a/core/os.odin b/core/os.odin index c15099e5b..8f87051ad 100644 --- a/core/os.odin +++ b/core/os.odin @@ -8,7 +8,7 @@ write_string :: proc(fd: Handle, str: string) -> (int, Errno) { return write(fd, cast([]u8)str); } -read_entire_file :: proc(name: string) -> ([]u8, bool) { +read_entire_file :: proc(name: string) -> (data: []u8, success: bool) { fd, err := open(name, O_RDONLY, 0); if err != 0 { return nil, false; @@ -37,7 +37,7 @@ read_entire_file :: proc(name: string) -> ([]u8, bool) { return data[0..bytes_read], true; } -write_entire_file :: proc(name: string, data: []u8) -> bool { +write_entire_file :: proc(name: string, data: []u8) -> (sucess: bool) { fd, err := open(name, O_WRONLY, 0); if err != 0 { return false; diff --git a/core/strings.odin b/core/strings.odin index a65f72382..dbe99f0e9 100644 --- a/core/strings.odin +++ b/core/strings.odin @@ -15,6 +15,7 @@ new_c_string :: proc(s: string) -> ^u8 { } to_odin_string :: proc(c: ^u8) -> string { + if c == nil do return ""; len := 0; for (c+len)^ != 0 do len+=1; return string(mem.slice_ptr(c, len)); |