aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-07-18 20:39:53 +0100
committerGinger Bill <bill@gingerbill.org>2017-07-18 20:39:53 +0100
commit4db462a703d506f2ef23a16921a23a10115feacb (patch)
treec8119bf1324e62a95faffbd6a2157c36c321cb38
parenta22c6d6c0ca7b58e4942efa62937ee2242ba7b1d (diff)
Fix `copy`
-rw-r--r--code/demo.odin198
-rw-r--r--core/_preload.odin5
-rw-r--r--core/os.odin4
-rw-r--r--core/strings.odin1
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));