aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-02-05 18:17:55 +0000
committerGinger Bill <bill@gingerbill.org>2017-02-05 18:17:55 +0000
commitb1562edccf9ea972ec8caf5faebea07cf27559bb (patch)
treeb6a0dfa591b33b277c583f287643deaaa213284a /core
parent2a5b674d33e4f483964da119f76038457cd9f1f2 (diff)
Add `types.odin`; Begin work on `map`
Diffstat (limited to 'core')
-rw-r--r--core/_preload.odin12
-rw-r--r--core/hash.odin55
-rw-r--r--core/types.odin146
3 files changed, 212 insertions, 1 deletions
diff --git a/core/_preload.odin b/core/_preload.odin
index 2bb00c7f6..093c5fcc4 100644
--- a/core/_preload.odin
+++ b/core/_preload.odin
@@ -4,6 +4,7 @@
#import "fmt.odin";
#import "mem.odin";
#import "utf8.odin";
+#import "hash.odin";
// IMPORTANT NOTE(bill): `type_info` & `type_info_val` cannot be used within a
// #shared_global_scope due to the internals of the compiler.
@@ -346,6 +347,16 @@ Raw_Dynamic_Array :: struct #ordered {
allocator: Allocator,
};
+Raw_Dynamic_Map :: struct #ordered {
+ hashes: [dynamic]int,
+ entries: Raw_Dynamic_Array,
+};
+
+__default_hash :: proc(data: rawptr, len: int) -> u64 {
+ return hash.murmur64(data, len);
+}
+
+
__dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, capacity: int) -> bool {
array := cast(^Raw_Dynamic_Array)array_;
@@ -398,3 +409,4 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
array.count += item_count;
return array.count;
}
+
diff --git a/core/hash.odin b/core/hash.odin
index b2d6f0226..66b6c1291 100644
--- a/core/hash.odin
+++ b/core/hash.odin
@@ -50,13 +50,66 @@ fnv32a :: proc(data: rawptr, len: int) -> u32 {
fnv64a :: proc(data: rawptr, len: int) -> u64 {
s := slice_ptr(cast(^u8)data, len);
- h :u64 = 0xcbf29ce484222325;
+ h: u64 = 0xcbf29ce484222325;
for i in 0..<len {
h = (h ~ cast(u64)s[i]) * 0x100000001b3;
}
return h;
}
+murmur32 :: proc(data: rawptr, len: int) -> u32 {
+ compile_assert(ODIN_ENDIAN == "little");
+
+ SEED :: 0x9747b28c;
+
+ key := cast(^u8)data;
+ h: u32 = SEED;
+
+ if len > 3 {
+ key_x4 := cast(^u32)key;
+ i := len>>2;
+ for {
+ k := key_x4^; key_x4 += 1;
+ k *= 0xcc9e2d51;
+ k = (k << 15) | (k >> 17);
+ k *= 0x1b873593;
+ h ~= k;
+ h = (h << 13) | (h >> 19);
+ h += (h << 2) + 0xe6546b64;
+ i -= 1;
+ if i == 0 {
+ break;
+ }
+ }
+ key = cast(^u8)key_x4;
+ }
+ if len&3 != 0 {
+ i := len&3;
+ k: u32 = 0;
+ key += i-1;
+ for {
+ k <<= 8;
+ k |= cast(u32)key^;
+ key -= 1;
+ i -= 1;
+ if i == 0 {
+ break;
+ }
+ }
+ k *= 0xcc9e2d51;
+ k = (k << 15) | (k >> 17);
+ k *= 0x1b873593;
+ h ~= k;
+ }
+
+ h ~= cast(u32)len;
+ h ~= h >> 16;
+ h *= 0x85ebca6b;
+ h ~= h >> 13;
+ h *= 0xc2b2ae35;
+ h ~= h >> 16;
+ return h;
+}
murmur64 :: proc(data_: rawptr, len: int) -> u64 {
SEED :: 0x9747b28c;
diff --git a/core/types.odin b/core/types.odin
new file mode 100644
index 000000000..5464346d1
--- /dev/null
+++ b/core/types.odin
@@ -0,0 +1,146 @@
+is_signed :: proc(info: ^Type_Info) -> bool {
+ if is_integer(info) {
+ i := cast(^Type_Info.Integer)info;
+ return i.signed;
+ }
+ if is_float(info) {
+ return true;
+ }
+ return false;
+}
+is_integer :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Integer: return true;
+ }
+ return false;
+}
+is_float :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Float: return true;
+ }
+ return false;
+}
+is_any :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Any: return true;
+ }
+ return false;
+}
+is_string :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.String: return true;
+ }
+ return false;
+}
+is_boolean :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Boolean: return true;
+ }
+ return false;
+}
+is_pointer :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Pointer: return true;
+ }
+ return false;
+}
+is_maybe :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Maybe: return true;
+ }
+ return false;
+}
+is_procedure :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Procedure: return true;
+ }
+ return false;
+}
+is_array :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Array: return true;
+ }
+ return false;
+}
+is_dynamic_array :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Dynamic_Array: return true;
+ }
+ return false;
+}
+is_slice :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Slice: return true;
+ }
+ return false;
+}
+is_vector :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Vector: return true;
+ }
+ return false;
+}
+is_tuple :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Tuple: return true;
+ }
+ return false;
+}
+is_struct :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Struct: return true;
+ }
+ return false;
+}
+is_union :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Union: return true;
+ }
+ return false;
+}
+is_raw_union :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Raw_Union: return true;
+ }
+ return false;
+}
+is_enum :: proc(info: ^Type_Info) -> bool {
+ if info == nil { return false; }
+
+ match type i in type_info_base(info) {
+ case Type_Info.Enum: return true;
+ }
+ return false;
+}