diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-02-05 18:17:55 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-02-05 18:17:55 +0000 |
| commit | b1562edccf9ea972ec8caf5faebea07cf27559bb (patch) | |
| tree | b6a0dfa591b33b277c583f287643deaaa213284a /core | |
| parent | 2a5b674d33e4f483964da119f76038457cd9f1f2 (diff) | |
Add `types.odin`; Begin work on `map`
Diffstat (limited to 'core')
| -rw-r--r-- | core/_preload.odin | 12 | ||||
| -rw-r--r-- | core/hash.odin | 55 | ||||
| -rw-r--r-- | core/types.odin | 146 |
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; +} |