mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2025-08-06 07:12:42 -07:00
finished translating string operations to odin (next is file system)
This commit is contained in:
@@ -1783,7 +1783,9 @@ void str8gen_append_str8(Str8Gen* gen, Str8 str){
|
|||||||
slice_assert(result);
|
slice_assert(result);
|
||||||
Slice_Byte to_copy = { result.ptr + gen->len, result.len - gen->len };
|
Slice_Byte to_copy = { result.ptr + gen->len, result.len - gen->len };
|
||||||
slice_copy(to_copy, slice_byte(str));
|
slice_copy(to_copy, slice_byte(str));
|
||||||
gen->ptr = cast(UTF8*, result.ptr); gen->len = result.len;
|
gen->ptr = cast(UTF8*, result.ptr);
|
||||||
|
gen->len += str.len;
|
||||||
|
gen->cap = max(gen->len , gen->cap); // TODO(Ed): Arenas currently hide total capacity before growth. Problably better todo classic append to actually track this.
|
||||||
}
|
}
|
||||||
void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* entries){
|
void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* entries){
|
||||||
local_persist Byte tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
local_persist Byte tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
||||||
@@ -1793,7 +1795,7 @@ void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* entries
|
|||||||
Slice_Byte result = mem_grow(gen->backing, str8gen_slice_byte(* gen), kilo(16) + gen->cap );
|
Slice_Byte result = mem_grow(gen->backing, str8gen_slice_byte(* gen), kilo(16) + gen->cap );
|
||||||
slice_assert(result);
|
slice_assert(result);
|
||||||
gen->ptr = result.ptr;
|
gen->ptr = result.ptr;
|
||||||
gen->cap = result.len;
|
gen->cap += kilo(16);
|
||||||
buffer = (Slice_Byte){ cast(Byte*, gen->ptr + gen->len), gen->cap - gen->len };
|
buffer = (Slice_Byte){ cast(Byte*, gen->ptr + gen->len), gen->cap - gen->len };
|
||||||
}
|
}
|
||||||
Str8 result = str8__fmt_kt1l(gen->backing, & buffer, kt, fmt_template);
|
Str8 result = str8__fmt_kt1l(gen->backing, & buffer, kt, fmt_template);
|
||||||
|
@@ -13,6 +13,7 @@ main :: proc()
|
|||||||
|
|
||||||
import "base:builtin"
|
import "base:builtin"
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
import "base:runtime"
|
||||||
|
|
||||||
//region Package Mappings
|
//region Package Mappings
|
||||||
abs :: builtin.abs
|
abs :: builtin.abs
|
||||||
@@ -20,6 +21,11 @@ min :: builtin.min
|
|||||||
max :: builtin.max
|
max :: builtin.max
|
||||||
clamp :: builtin.clamp
|
clamp :: builtin.clamp
|
||||||
|
|
||||||
|
ainfo :: proc {
|
||||||
|
farena_ainfo,
|
||||||
|
varena_ainfo,
|
||||||
|
arena_ainfo,
|
||||||
|
}
|
||||||
alloc :: proc {
|
alloc :: proc {
|
||||||
mem_alloc,
|
mem_alloc,
|
||||||
alloc_type,
|
alloc_type,
|
||||||
@@ -109,7 +115,7 @@ memory_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
SliceBytes :: struct {
|
SliceByte :: struct {
|
||||||
data: [^]byte,
|
data: [^]byte,
|
||||||
len: int
|
len: int
|
||||||
}
|
}
|
||||||
@@ -319,7 +325,7 @@ alloc_type :: proc(ainfo: AllocatorInfo, $Type: typeid, alignment: int = MEMORY
|
|||||||
ainfo.procedure(input, & output)
|
ainfo.procedure(input, & output)
|
||||||
return transmute(^Type) raw_data(output.allocation)
|
return transmute(^Type) raw_data(output.allocation)
|
||||||
}
|
}
|
||||||
alloc_slice :: proc(ainfo: AllocatorInfo, $SliceType: []$Type, num : int) -> []Type {
|
alloc_slice :: proc(ainfo: AllocatorInfo, $SliceType: typeid / []$Type, num : int, alignment: int = MEMORY_ALIGNMENT_DEFAULT, no_zero: b32 = false) -> []Type {
|
||||||
assert(ainfo.procedure != nil)
|
assert(ainfo.procedure != nil)
|
||||||
input := AllocatorProc_In {
|
input := AllocatorProc_In {
|
||||||
data = ainfo.data,
|
data = ainfo.data,
|
||||||
@@ -329,7 +335,7 @@ alloc_slice :: proc(ainfo: AllocatorInfo, $SliceType: []$Type, num : int) -> []T
|
|||||||
}
|
}
|
||||||
output: AllocatorProc_Out
|
output: AllocatorProc_Out
|
||||||
ainfo.procedure(input, & output)
|
ainfo.procedure(input, & output)
|
||||||
return transmute([]Type) Raw_Slice { raw_data(output.allocation), num }
|
return transmute([]Type) slice(raw_data(output.allocation), num)
|
||||||
}
|
}
|
||||||
//endregion Allocator Interface
|
//endregion Allocator Interface
|
||||||
|
|
||||||
@@ -459,6 +465,7 @@ farena_allocator_proc :: proc(input: AllocatorProc_In, output: ^AllocatorProc_Ou
|
|||||||
output.save_point = farena_save(arena^)
|
output.save_point = farena_save(arena^)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
farena_ainfo :: #force_inline proc "contextless" (arena : ^FArena) -> AllocatorInfo { return AllocatorInfo{farena_allocator_proc, arena} }
|
||||||
//endregion FArena
|
//endregion FArena
|
||||||
|
|
||||||
//region OS
|
//region OS
|
||||||
@@ -709,6 +716,7 @@ varena_allocator_proc :: proc(input: AllocatorProc_In, output: ^AllocatorProc_Ou
|
|||||||
output.save_point = varena_save(vm)
|
output.save_point = varena_save(vm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
varena_ainfo :: #force_inline proc "contextless" (arena : ^VArena) -> AllocatorInfo { return AllocatorInfo{varena_allocator_proc, arena} }
|
||||||
//endregion VArena
|
//endregion VArena
|
||||||
|
|
||||||
//region Arena (Chained Arena)
|
//region Arena (Chained Arena)
|
||||||
@@ -850,7 +858,7 @@ arena_allocator_proc :: proc(input: AllocatorProc_In, output: ^AllocatorProc_Out
|
|||||||
if input.op == .Grow {
|
if input.op == .Grow {
|
||||||
zero(cursor(new_alloc)[len(input.old_allocation):], input.requested_size - len(input.old_allocation))
|
zero(cursor(new_alloc)[len(input.old_allocation):], input.requested_size - len(input.old_allocation))
|
||||||
}
|
}
|
||||||
output.allocation = slice_to_bytes(new_alloc)
|
output.allocation = new_alloc
|
||||||
output.continuity_break = true
|
output.continuity_break = true
|
||||||
|
|
||||||
case .Shrink:
|
case .Shrink:
|
||||||
@@ -888,6 +896,7 @@ arena_allocator_proc :: proc(input: AllocatorProc_In, output: ^AllocatorProc_Out
|
|||||||
output.save_point = arena_save(arena)
|
output.save_point = arena_save(arena)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
arena_ainfo :: #force_inline proc "contextless" (arena : ^Arena) -> AllocatorInfo { return AllocatorInfo{arena_allocator_proc, arena} }
|
||||||
//endregion Arena (Casey-Ryan Composite Arena)
|
//endregion Arena (Casey-Ryan Composite Arena)
|
||||||
|
|
||||||
//region Hashing
|
//region Hashing
|
||||||
@@ -907,7 +916,7 @@ KT1L_Meta :: struct {
|
|||||||
slot_size: uintptr,
|
slot_size: uintptr,
|
||||||
kt_value_offset: uintptr,
|
kt_value_offset: uintptr,
|
||||||
type_width: uintptr,
|
type_width: uintptr,
|
||||||
type_name: string,
|
type: typeid,
|
||||||
}
|
}
|
||||||
kt1l_populate_slice_a2_Slice_Byte :: proc(kt: ^[]byte, backing: AllocatorInfo, values: []byte, num_values: int, m: KT1L_Meta) {
|
kt1l_populate_slice_a2_Slice_Byte :: proc(kt: ^[]byte, backing: AllocatorInfo, values: []byte, num_values: int, m: KT1L_Meta) {
|
||||||
assert(kt != nil)
|
assert(kt != nil)
|
||||||
@@ -915,14 +924,14 @@ kt1l_populate_slice_a2_Slice_Byte :: proc(kt: ^[]byte, backing: AllocatorInfo, v
|
|||||||
table_size_bytes := num_values * int(m.slot_size)
|
table_size_bytes := num_values * int(m.slot_size)
|
||||||
kt^ = mem_alloc(backing, table_size_bytes)
|
kt^ = mem_alloc(backing, table_size_bytes)
|
||||||
slice_assert(kt ^)
|
slice_assert(kt ^)
|
||||||
kt_raw : SliceBytes = transmute(SliceBytes) kt^
|
kt_raw : SliceByte = transmute(SliceByte) kt^
|
||||||
for cursor in 0 ..< cast(uintptr) num_values {
|
for id in 0 ..< cast(uintptr) num_values {
|
||||||
slot_offset := cursor * m.slot_size // slot id
|
slot_offset := id * m.slot_size // slot id
|
||||||
slot_cursor := kt_raw.data[slot_offset:] // slots[id] type: KT1L_<Type>
|
slot_cursor := kt_raw.data[slot_offset:] // slots[id] type: KT1L_<Type>
|
||||||
slot_key := cast(^u64) slot_cursor // slots[id].key type: U64
|
slot_key := cast(^u64) slot_cursor // slots[id].key type: U64
|
||||||
slot_value := slice(slot_cursor[m.kt_value_offset:], m.type_width) // slots[id].value type: <Type>
|
slot_value := slice(slot_cursor[m.kt_value_offset:], m.type_width) // slots[id].value type: <Type>
|
||||||
a2_offset := cursor * m.type_width * 2 // a2 entry id
|
a2_offset := id * m.type_width * 2 // a2 entry id
|
||||||
a2_cursor := slice_cursor(values)[a2_offset:] // a2_entries[id] type: A2_<Type>
|
a2_cursor := cursor(values)[a2_offset:] // a2_entries[id] type: A2_<Type>
|
||||||
a2_key := (transmute(^[]byte) a2_cursor) ^ // a2_entries[id].key type: <Type>
|
a2_key := (transmute(^[]byte) a2_cursor) ^ // a2_entries[id].key type: <Type>
|
||||||
a2_value := slice(a2_cursor[m.type_width:], m.type_width) // a2_entries[id].value type: <Type>
|
a2_value := slice(a2_cursor[m.type_width:], m.type_width) // a2_entries[id].value type: <Type>
|
||||||
copy(slot_value, a2_value) // slots[id].value = a2_entries[id].value
|
copy(slot_value, a2_value) // slots[id].value = a2_entries[id].value
|
||||||
@@ -932,12 +941,12 @@ kt1l_populate_slice_a2_Slice_Byte :: proc(kt: ^[]byte, backing: AllocatorInfo, v
|
|||||||
}
|
}
|
||||||
kt1l_populate_slice_a2 :: proc($Type: typeid, kt: ^[]KT1L_Slot(Type), backing: AllocatorInfo, values: [][2]Type) {
|
kt1l_populate_slice_a2 :: proc($Type: typeid, kt: ^[]KT1L_Slot(Type), backing: AllocatorInfo, values: [][2]Type) {
|
||||||
assert(kt != nil)
|
assert(kt != nil)
|
||||||
values_bytes := transmute([]byte) SliceBytes{data = raw_data(values), len = len(values) * size_of([2]Type)}
|
values_bytes := slice(transmute([^]u8) raw_data(values), len(values) * size_of([2]Type))
|
||||||
kt1l_populate_slice_a2_Slice_Byte(transmute(^[]byte) kt, backing, values_bytes, len(values), {
|
kt1l_populate_slice_a2_Slice_Byte(transmute(^[]byte) kt, backing, values_bytes, len(values), {
|
||||||
slot_size = size_of(KT1L_Slot(Type)),
|
slot_size = size_of(KT1L_Slot(Type)),
|
||||||
kt_value_offset = offset_of(KT1L_Slot(Type), KT1L_Slot(Type).value),
|
kt_value_offset = offset_of(KT1L_Slot(Type), value),
|
||||||
type_width = size_of(Type),
|
type_width = size_of(Type),
|
||||||
type_name = #type_string(Type),
|
type = Type,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//endregion Key Table 1-Layer Linear (KT1L)
|
//endregion Key Table 1-Layer Linear (KT1L)
|
||||||
@@ -974,7 +983,7 @@ KT1CX_ByteMeta :: struct {
|
|||||||
cell_depth: int,
|
cell_depth: int,
|
||||||
cell_size: int,
|
cell_size: int,
|
||||||
type_width: int,
|
type_width: int,
|
||||||
type_name: string,
|
type: typeid,
|
||||||
}
|
}
|
||||||
KT1CX_InfoMeta :: struct {
|
KT1CX_InfoMeta :: struct {
|
||||||
cell_pool_size: int,
|
cell_pool_size: int,
|
||||||
@@ -985,7 +994,7 @@ KT1CX_InfoMeta :: struct {
|
|||||||
cell_depth: int,
|
cell_depth: int,
|
||||||
cell_size: int,
|
cell_size: int,
|
||||||
type_width: int,
|
type_width: int,
|
||||||
type_name: string,
|
type: typeid,
|
||||||
}
|
}
|
||||||
KT1CX_Info :: struct {
|
KT1CX_Info :: struct {
|
||||||
backing_table: AllocatorInfo,
|
backing_table: AllocatorInfo,
|
||||||
@@ -999,7 +1008,7 @@ kt1cx_init :: proc(info: KT1CX_Info, m: KT1CX_InfoMeta, result: ^KT1CX_Byte) {
|
|||||||
assert(m.cell_pool_size >= 4 * Kilo)
|
assert(m.cell_pool_size >= 4 * Kilo)
|
||||||
assert(m.table_size >= 4 * Kilo)
|
assert(m.table_size >= 4 * Kilo)
|
||||||
assert(m.type_width > 0)
|
assert(m.type_width > 0)
|
||||||
table_raw := transmute(SliceBytes) mem_alloc(info.backing_table, m.table_size * m.cell_size)
|
table_raw := transmute(SliceByte) mem_alloc(info.backing_table, m.table_size * m.cell_size)
|
||||||
slice_assert(transmute([]byte) table_raw)
|
slice_assert(transmute([]byte) table_raw)
|
||||||
result.cell_pool = mem_alloc(info.backing_cells, m.cell_pool_size * m.cell_size)
|
result.cell_pool = mem_alloc(info.backing_cells, m.cell_pool_size * m.cell_size)
|
||||||
slice_assert(result.cell_pool)
|
slice_assert(result.cell_pool)
|
||||||
@@ -1011,7 +1020,7 @@ kt1cx_clear :: proc(kt: KT1CX_Byte, m: KT1CX_ByteMeta) {
|
|||||||
table_len := len(kt.table) * m.cell_size
|
table_len := len(kt.table) * m.cell_size
|
||||||
for ; cell_cursor != end(kt.table); cell_cursor = cell_cursor[m.cell_size:] // for cell, cell_id in kt.table.cells
|
for ; cell_cursor != end(kt.table); cell_cursor = cell_cursor[m.cell_size:] // for cell, cell_id in kt.table.cells
|
||||||
{
|
{
|
||||||
slots := SliceBytes { cell_cursor, m.cell_depth * m.slot_size } // slots = cell.slots
|
slots := SliceByte { cell_cursor, m.cell_depth * m.slot_size } // slots = cell.slots
|
||||||
slot_cursor := slots.data
|
slot_cursor := slots.data
|
||||||
for;; {
|
for;; {
|
||||||
slot := slice(slot_cursor, m.slot_size) // slot = slots[slot_id]
|
slot := slice(slot_cursor, m.slot_size) // slot = slots[slot_id]
|
||||||
@@ -1065,9 +1074,9 @@ kt1cx_get :: proc(kt: KT1CX_Byte, key: u64, m: KT1CX_ByteMeta) -> ^byte {
|
|||||||
kt1cx_set :: proc(kt: KT1CX_Byte, key: u64, value: []byte, backing_cells: AllocatorInfo, m: KT1CX_ByteMeta) -> ^byte {
|
kt1cx_set :: proc(kt: KT1CX_Byte, key: u64, value: []byte, backing_cells: AllocatorInfo, m: KT1CX_ByteMeta) -> ^byte {
|
||||||
hash_index := kt1cx_slot_id(kt, key, m)
|
hash_index := kt1cx_slot_id(kt, key, m)
|
||||||
cell_offset := uintptr(hash_index) * uintptr(m.cell_size)
|
cell_offset := uintptr(hash_index) * uintptr(m.cell_size)
|
||||||
cell := SliceBytes{& kt.table[cell_offset], m.cell_size}
|
cell_cursor := cursor(kt.table)[cell_offset:] // KT1CX_Cell(Type) cell = kt.table[hash_index]
|
||||||
{
|
{
|
||||||
slots := SliceBytes {cell.data, m.cell_depth * m.slot_size}
|
slots := SliceByte {cell_cursor, m.cell_depth * m.slot_size} // cell.slots
|
||||||
slot_cursor := slots.data
|
slot_cursor := slots.data
|
||||||
for ;;
|
for ;;
|
||||||
{
|
{
|
||||||
@@ -1081,11 +1090,11 @@ kt1cx_set :: proc(kt: KT1CX_Byte, key: u64, value: []byte, backing_cells: Alloca
|
|||||||
return cast(^byte) slot_cursor
|
return cast(^byte) slot_cursor
|
||||||
}
|
}
|
||||||
if slot_cursor == end(transmute([]byte) slots) {
|
if slot_cursor == end(transmute([]byte) slots) {
|
||||||
curr_cell := transmute(^KT1CX_Byte_Cell) (uintptr(cell.data) + m.cell_next_offset)
|
curr_cell := transmute(^KT1CX_Byte_Cell) (uintptr(cell_cursor) + m.cell_next_offset) // curr_cell = cell
|
||||||
if curr_cell != nil {
|
if curr_cell != nil {
|
||||||
slots.data = curr_cell.next
|
slots.data = curr_cell.next
|
||||||
slot_cursor = curr_cell.next
|
slot_cursor = curr_cell.next
|
||||||
cell.data = curr_cell.next
|
cell_cursor = curr_cell.next
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1271,10 +1280,18 @@ str8_fmt_kt1l :: proc(ainfo: AllocatorInfo, _buffer: ^[]byte, table: []KT1L_Slot
|
|||||||
}
|
}
|
||||||
|
|
||||||
str8_fmt_backed :: proc(tbl_ainfo, buf_ainfo: AllocatorInfo, fmt_template: string, entries: [][2]string) -> string {
|
str8_fmt_backed :: proc(tbl_ainfo, buf_ainfo: AllocatorInfo, fmt_template: string, entries: [][2]string) -> string {
|
||||||
return {}
|
kt: []KT1L_Slot(string); kt1l_populate_slice_a2(string, & kt, tbl_ainfo, entries)
|
||||||
|
buf_size := Kilo * 64
|
||||||
|
buffer := mem_alloc(buf_ainfo, buf_size)
|
||||||
|
result := str8_fmt_kt1l(buf_ainfo, & buffer, kt, fmt_template)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
str8_fmt_tmp :: proc(fmt_template: string, entries: [][2]string) -> string {
|
str8_fmt_tmp :: proc(fmt_template: string, entries: [][2]string) -> string {
|
||||||
return {}
|
@static tbl_mem: [Kilo * 32]byte; tbl_arena := farena_make(tbl_mem[:])
|
||||||
|
@static buf_mem: [Kilo * 64]byte; buffer := buf_mem[:]
|
||||||
|
kt: []KT1L_Slot(string); kt1l_populate_slice_a2(string, & kt, ainfo(& tbl_arena), entries)
|
||||||
|
result := str8_fmt_kt1l({}, & buffer, kt, fmt_template)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
Str8Cache_CELL_DEPTH :: 4
|
Str8Cache_CELL_DEPTH :: 4
|
||||||
@@ -1288,39 +1305,129 @@ Str8Cache :: struct {
|
|||||||
tbl_backing: AllocatorInfo,
|
tbl_backing: AllocatorInfo,
|
||||||
kt: KT1CX_Str8,
|
kt: KT1CX_Str8,
|
||||||
}
|
}
|
||||||
str8cache_init :: proc(cache: ^Str8Cache, str_reserve, cell_reserve, tbl_backing: AllocatorInfo, cell_pool_size, table_size: int) {
|
str8cache_init :: proc(cache: ^Str8Cache, str_reserve, cell_reserve, tbl_backing: AllocatorInfo, cell_pool_size := Kilo, table_size := Kilo) {
|
||||||
|
assert(cache != nil)
|
||||||
|
assert(str_reserve.procedure != nil)
|
||||||
|
assert(cell_reserve.procedure != nil)
|
||||||
|
assert(tbl_backing.procedure != nil)
|
||||||
|
cache.str_reserve = str_reserve
|
||||||
|
cache.cell_reserve = cell_reserve
|
||||||
|
cache.tbl_backing = tbl_backing
|
||||||
|
info := KT1CX_Info {
|
||||||
|
backing_cells = cell_reserve,
|
||||||
|
backing_table = tbl_backing,
|
||||||
|
}
|
||||||
|
m := KT1CX_InfoMeta {
|
||||||
|
cell_pool_size = cell_pool_size,
|
||||||
|
table_size = table_size,
|
||||||
|
slot_size = size_of(KT1CX_Slot_Str8),
|
||||||
|
slot_key_offset = offset_of(KT1CX_Slot_Str8, key),
|
||||||
|
cell_next_offset = offset_of(KT1CX_Cell_Str8, next),
|
||||||
|
cell_depth = Str8Cache_CELL_DEPTH,
|
||||||
|
type_width = size_of(string),
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
kt1cx_init(info, m, transmute(^KT1CX_Byte) & cache.kt)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
str8cache_make :: proc(str_reserve, cell_reserve, tbl_backing: AllocatorInfo, cell_pool_size, table_size: int) -> Str8Cache {
|
str8cache_make :: proc(str_reserve, cell_reserve, tbl_backing: AllocatorInfo, cell_pool_size, table_size: int) -> Str8Cache {
|
||||||
cache : Str8Cache; str8cache_init(& cache, str_reserve, cell_reserve, tbl_backing, cell_pool_size, table_size); return cache
|
cache : Str8Cache; str8cache_init(& cache, str_reserve, cell_reserve, tbl_backing, cell_pool_size, table_size); return cache
|
||||||
}
|
}
|
||||||
str8cache_clear :: proc(kt: KT1CX_Str8) {
|
str8cache_clear :: proc(kt: KT1CX_Str8) {
|
||||||
|
kt1cx_assert(kt)
|
||||||
|
kt1cx_clear(kt1cx_byte(kt), {
|
||||||
|
slot_size = size_of(KT1CX_Slot_Str8),
|
||||||
|
slot_key_offset = offset_of(KT1CX_Slot_Str8, key),
|
||||||
|
cell_next_offset = offset_of(KT1CX_Cell_Str8, next),
|
||||||
|
cell_depth = Str8Cache_CELL_DEPTH,
|
||||||
|
cell_size = size_of(KT1CX_Cell_Str8),
|
||||||
|
type_width = size_of(string),
|
||||||
|
type = string,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
str8cache_get :: proc(kt: KT1CX_Str8, key: u64) -> ^string {
|
str8cache_get :: proc(kt: KT1CX_Str8, key: u64) -> ^string {
|
||||||
return nil
|
kt1cx_assert(kt)
|
||||||
|
result := kt1cx_get(kt1cx_byte(kt), key, {
|
||||||
|
slot_size = size_of(KT1CX_Slot_Str8),
|
||||||
|
slot_key_offset = offset_of(KT1CX_Slot_Str8, key),
|
||||||
|
cell_next_offset = offset_of(KT1CX_Cell_Str8, next),
|
||||||
|
cell_depth = Str8Cache_CELL_DEPTH,
|
||||||
|
cell_size = size_of(KT1CX_Cell_Str8),
|
||||||
|
type_width = size_of(string),
|
||||||
|
type = string,
|
||||||
|
})
|
||||||
|
return transmute(^string) result
|
||||||
}
|
}
|
||||||
str8cache_set :: proc(kt: KT1CX_Str8, key: u64, value: string, str_reserve, cell_reserve: AllocatorInfo) -> ^string {
|
str8cache_set :: proc(kt: KT1CX_Str8, key: u64, value: string, str_reserve, cell_reserve: AllocatorInfo) -> ^string {
|
||||||
return nil
|
kt1cx_assert(kt)
|
||||||
|
slice_assert(transmute([]byte) value)
|
||||||
|
assert(str_reserve.procedure != nil)
|
||||||
|
assert(cell_reserve.procedure != nil)
|
||||||
|
entry := kt1cx_set(kt1cx_byte(kt), key, transmute([]byte) value, cell_reserve, {
|
||||||
|
slot_size = size_of(KT1CX_Slot_Str8),
|
||||||
|
slot_key_offset = offset_of(KT1CX_Slot_Str8, key),
|
||||||
|
cell_next_offset = offset_of(KT1CX_Cell_Str8, next),
|
||||||
|
cell_depth = Str8Cache_CELL_DEPTH,
|
||||||
|
cell_size = size_of(KT1CX_Cell_Str8),
|
||||||
|
type_width = size_of(string),
|
||||||
|
type = string,
|
||||||
|
})
|
||||||
|
assert(entry != nil)
|
||||||
|
result := transmute(^string) entry
|
||||||
|
is_empty := len(result) == 0
|
||||||
|
if is_empty {
|
||||||
|
result ^ = transmute(string) alloc_slice(str_reserve, []u8, len(value))
|
||||||
|
copy(result ^, value)
|
||||||
}
|
}
|
||||||
cache_str8 :: proc(cache: ^Str8Cache, str: string) -> ^string {
|
return result
|
||||||
return nil
|
}
|
||||||
|
cache_str8 :: proc(cache: ^Str8Cache, str: string) -> string {
|
||||||
|
assert(cache != nil)
|
||||||
|
key: u64 = 0; hash64_djb8(& key, transmute([]byte) str)
|
||||||
|
result := str8cache_set(cache.kt, key, str, cache.str_reserve, cache.cell_reserve)
|
||||||
|
return result ^
|
||||||
}
|
}
|
||||||
|
|
||||||
Str8Gen :: struct {
|
Str8Gen :: struct {
|
||||||
backing: AllocatorInfo,
|
backing: AllocatorInfo,
|
||||||
ptr: ^u8,
|
ptr: [^]u8,
|
||||||
len: int,
|
len: int,
|
||||||
cap: int,
|
cap: int,
|
||||||
}
|
}
|
||||||
str8gen_init :: proc(gen: ^Str8Gen, ainfo: AllocatorInfo) {
|
str8gen_init :: proc(gen: ^Str8Gen, ainfo: AllocatorInfo) {
|
||||||
|
assert(gen != nil)
|
||||||
|
gen.backing = ainfo
|
||||||
|
gen.ptr = raw_data(mem_alloc(ainfo, Kilo * 4))
|
||||||
|
assert(gen.ptr != nil)
|
||||||
|
gen.len = 0
|
||||||
|
gen.cap = Kilo * 4
|
||||||
}
|
}
|
||||||
str8gen_make :: proc(ainfo: AllocatorInfo) -> Str8Gen { gen: Str8Gen; str8gen_init(& gen, ainfo); return gen }
|
str8gen_make :: proc(ainfo: AllocatorInfo) -> Str8Gen { gen: Str8Gen; str8gen_init(& gen, ainfo); return gen }
|
||||||
str8gen_to_bytes :: proc(gen: Str8Gen) -> []byte { return transmute([]byte) SliceBytes {data = gen.ptr, len = gen.len} }
|
str8gen_to_bytes :: proc(gen: Str8Gen) -> []byte { return transmute([]byte) SliceByte {data = gen.ptr, len = gen.len} }
|
||||||
str8_from_str8gen :: proc(gen: Str8Gen) -> string { return transmute(string) SliceBytes {data = gen.ptr, len = gen.len} }
|
str8_from_str8gen :: proc(gen: Str8Gen) -> string { return transmute(string) SliceByte {data = gen.ptr, len = gen.len} }
|
||||||
|
|
||||||
str8gen_append_str8 :: proc(gen: ^Str8Gen, str: string) {
|
str8gen_append_str8 :: proc(gen: ^Str8Gen, str: string) {
|
||||||
|
result := mem_grow(gen.backing, str8gen_to_bytes(gen ^), len(str) + gen.len)
|
||||||
|
slice_assert(result)
|
||||||
|
to_copy := slice(cursor(result)[gen.len:], len(result) - gen.len)
|
||||||
|
copy(to_copy, transmute([]byte) str)
|
||||||
|
gen.ptr = transmute(^u8) raw_data(result)
|
||||||
|
gen.len = len(result)
|
||||||
|
gen.cap = max(gen.len, gen.cap) // TODO(Ed): Arenas currently hide total capacity before growth. Problably better todo classic append to actually track this.
|
||||||
}
|
}
|
||||||
str8gen_append_fmt :: proc(gen: ^Str8Gen, fmt_template: string, tokens: [][2]string) {
|
str8gen_append_fmt :: proc(gen: ^Str8Gen, fmt_template: string, tokens: [][2]string) {
|
||||||
|
@static tbl_mem: [Kilo * 32]byte; tbl_arena := farena_make(tbl_mem[:])
|
||||||
|
kt: []KT1L_Slot(string); kt1l_populate_slice_a2(string, & kt, ainfo(& tbl_arena), tokens)
|
||||||
|
buffer := slice(gen.ptr[gen.len:], gen.cap - gen.len)
|
||||||
|
if len(buffer) < Kilo * 16 {
|
||||||
|
result := mem_grow(gen.backing, str8gen_to_bytes(gen ^), Kilo * 16 + gen.cap)
|
||||||
|
slice_assert(result)
|
||||||
|
gen.ptr = raw_data(result)
|
||||||
|
gen.cap += Kilo * 16
|
||||||
|
buffer = slice(gen.ptr[gen.len:], gen.cap - gen.len)
|
||||||
|
}
|
||||||
|
result := str8_fmt_kt1l(gen.backing, & buffer, kt, fmt_template)
|
||||||
|
gen.len += len(result)
|
||||||
}
|
}
|
||||||
//#endregion String Operations
|
//#endregion String Operations
|
||||||
|
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
// raddbg 0.9.18 project file
|
|
||||||
|
|
||||||
recent_file: path: "c/watl.v0.msvc.c"
|
|
||||||
target:
|
|
||||||
{
|
|
||||||
executable: "build/watl.v0.msvc.exe"
|
|
||||||
working_directory: C
|
|
||||||
enabled: 1
|
|
||||||
}
|
|
||||||
breakpoint:
|
|
||||||
{
|
|
||||||
source_location: "c/watl.v0.msvc.c:2227:1"
|
|
||||||
hit_count: 0
|
|
||||||
}
|
|
@@ -1,154 +0,0 @@
|
|||||||
// raddbg 0.9.18 user file
|
|
||||||
|
|
||||||
recent_project: path: "watl_exercise.proj"
|
|
||||||
window:
|
|
||||||
{
|
|
||||||
size: 2048.000000 1152.000000
|
|
||||||
pos: 234 234
|
|
||||||
monitor: "\\\\.\\DISPLAY1"
|
|
||||||
maximized
|
|
||||||
panels:
|
|
||||||
{
|
|
||||||
0.683614: selected getting_started text:
|
|
||||||
{
|
|
||||||
selected
|
|
||||||
expression: "file:\"C:/projects/WATL_Exercise/c/watl.v0.msvc.c\".data"
|
|
||||||
auto: 1
|
|
||||||
query: input: ""
|
|
||||||
cursor_line: 2227
|
|
||||||
cursor_column: 1
|
|
||||||
mark_line: 2227
|
|
||||||
mark_column: 1
|
|
||||||
}
|
|
||||||
0.316386:
|
|
||||||
{
|
|
||||||
watch: expression: "query:targets"
|
|
||||||
watch:
|
|
||||||
{
|
|
||||||
selected
|
|
||||||
expression: ""
|
|
||||||
watch: "listing.ptr.text()"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
keybindings:
|
|
||||||
{
|
|
||||||
{ kill_all f5 shift }
|
|
||||||
{ step_into_inst f11 alt }
|
|
||||||
{ step_over_inst f10 alt }
|
|
||||||
{ step_out f11 shift }
|
|
||||||
{ halt x ctrl shift }
|
|
||||||
{ halt pause }
|
|
||||||
{ run f5 }
|
|
||||||
{ restart f5 ctrl shift }
|
|
||||||
{ step_into f11 }
|
|
||||||
{ step_over f10 }
|
|
||||||
{ run_to_line f10 ctrl }
|
|
||||||
{ set_next_statement f10 ctrl shift }
|
|
||||||
{ inc_window_font_size equal alt }
|
|
||||||
{ dec_window_font_size minus alt }
|
|
||||||
{ window n ctrl shift }
|
|
||||||
{ toggle_fullscreen return ctrl }
|
|
||||||
{ new_panel_right p ctrl }
|
|
||||||
{ new_panel_down minus ctrl }
|
|
||||||
{ rotate_panel_columns 2 ctrl }
|
|
||||||
{ next_panel comma ctrl }
|
|
||||||
{ prev_panel comma ctrl shift }
|
|
||||||
{ focus_panel_right right ctrl alt }
|
|
||||||
{ focus_panel_left left ctrl alt }
|
|
||||||
{ focus_panel_up up ctrl alt }
|
|
||||||
{ focus_panel_down down ctrl alt }
|
|
||||||
{ undo z ctrl }
|
|
||||||
{ redo y ctrl }
|
|
||||||
{ go_back left alt }
|
|
||||||
{ go_forward right alt }
|
|
||||||
{ close_panel p ctrl shift alt }
|
|
||||||
{ next_tab page_down ctrl }
|
|
||||||
{ prev_tab page_up ctrl }
|
|
||||||
{ next_tab tab ctrl }
|
|
||||||
{ prev_tab tab ctrl shift }
|
|
||||||
{ move_tab_right page_down ctrl shift }
|
|
||||||
{ move_tab_left page_up ctrl shift }
|
|
||||||
{ close_tab w ctrl }
|
|
||||||
{ tab_bar_top up ctrl shift alt }
|
|
||||||
{ tab_bar_bottom down ctrl shift alt }
|
|
||||||
{ open_tab t ctrl }
|
|
||||||
{ open o ctrl }
|
|
||||||
{ switch i ctrl }
|
|
||||||
{ switch_to_partner_file o alt }
|
|
||||||
{ open_user n ctrl shift alt }
|
|
||||||
{ open_project n ctrl alt }
|
|
||||||
{ open_user o ctrl shift alt }
|
|
||||||
{ open_project o ctrl alt }
|
|
||||||
{ save_user s ctrl shift alt }
|
|
||||||
{ save_project s ctrl shift }
|
|
||||||
{ edit f2 }
|
|
||||||
{ accept return }
|
|
||||||
{ accept space }
|
|
||||||
{ cancel esc }
|
|
||||||
{ move_left left }
|
|
||||||
{ move_right right }
|
|
||||||
{ move_up up }
|
|
||||||
{ move_down down }
|
|
||||||
{ move_left_select left shift }
|
|
||||||
{ move_right_select right shift }
|
|
||||||
{ move_up_select up shift }
|
|
||||||
{ move_down_select down shift }
|
|
||||||
{ move_left_chunk left ctrl }
|
|
||||||
{ move_right_chunk right ctrl }
|
|
||||||
{ move_up_chunk up ctrl }
|
|
||||||
{ move_down_chunk down ctrl }
|
|
||||||
{ move_up_page page_up }
|
|
||||||
{ move_down_page page_down }
|
|
||||||
{ move_up_whole home ctrl }
|
|
||||||
{ move_down_whole end ctrl }
|
|
||||||
{ move_left_chunk_select left ctrl shift }
|
|
||||||
{ move_right_chunk_select right ctrl shift }
|
|
||||||
{ move_up_chunk_select up ctrl shift }
|
|
||||||
{ move_down_chunk_select down ctrl shift }
|
|
||||||
{ move_up_page_select page_up shift }
|
|
||||||
{ move_down_page_select page_down shift }
|
|
||||||
{ move_up_whole_select home ctrl shift }
|
|
||||||
{ move_down_whole_select end ctrl shift }
|
|
||||||
{ move_up_reorder up alt }
|
|
||||||
{ move_down_reorder down alt }
|
|
||||||
{ move_home home }
|
|
||||||
{ move_end end }
|
|
||||||
{ move_home_select home shift }
|
|
||||||
{ move_end_select end shift }
|
|
||||||
{ select_all a ctrl }
|
|
||||||
{ delete_single delete }
|
|
||||||
{ delete_chunk delete ctrl }
|
|
||||||
{ backspace_single backspace }
|
|
||||||
{ backspace_chunk backspace ctrl }
|
|
||||||
{ copy c ctrl }
|
|
||||||
{ copy insert ctrl }
|
|
||||||
{ cut x ctrl }
|
|
||||||
{ paste v ctrl }
|
|
||||||
{ paste insert shift }
|
|
||||||
{ insert_text null }
|
|
||||||
{ move_next tab }
|
|
||||||
{ move_prev tab shift }
|
|
||||||
{ goto_line g ctrl }
|
|
||||||
{ goto_address g alt }
|
|
||||||
{ search f ctrl }
|
|
||||||
{ search_backwards r ctrl }
|
|
||||||
{ find_next f3 }
|
|
||||||
{ find_prev f3 ctrl }
|
|
||||||
{ find_selected_thread f4 }
|
|
||||||
{ goto_name j ctrl }
|
|
||||||
{ goto_name_at_cursor f12 }
|
|
||||||
{ toggle_watch_expr_at_cursor w alt }
|
|
||||||
{ toggle_watch_expr_at_mouse d ctrl }
|
|
||||||
{ toggle_watch_pin f9 ctrl }
|
|
||||||
{ toggle_breakpoint f9 }
|
|
||||||
{ add_address_breakpoint f9 shift }
|
|
||||||
{ add_function_breakpoint f9 ctrl shift }
|
|
||||||
{ attach f6 shift }
|
|
||||||
{ open_palette f1 }
|
|
||||||
{ open_palette p ctrl shift }
|
|
||||||
{ log_marker m ctrl shift alt }
|
|
||||||
{ toggle_dev_menu d ctrl shift alt }
|
|
||||||
}
|
|
||||||
current_path: "C:/projects/WATL_Exercise/build"
|
|
Reference in New Issue
Block a user