mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2025-10-20 09:40:51 -07:00
Compare commits
3 Commits
e49fc3964f
...
master
Author | SHA1 | Date | |
---|---|---|---|
9e4bc141d0 | |||
2bbe654047 | |||
f14ef07a98 |
@@ -401,7 +401,7 @@ void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
|
|||||||
#define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__))
|
#define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__))
|
||||||
|
|
||||||
#define farena_push(arena, type, ...) \
|
#define farena_push(arena, type, ...) \
|
||||||
cast(type*R_, farena__push(arena, size_of(type), 1, opt_args(Opts_farena, lit(stringify(type)), __VA_ARGS__))).ptr
|
cast(type*, farena__push(arena, size_of(type), 1, opt_args(Opts_farena, lit(stringify(type)), __VA_ARGS__))).ptr
|
||||||
|
|
||||||
#define farena_push_array(arena, type, amount, ...) \
|
#define farena_push_array(arena, type, amount, ...) \
|
||||||
(Slice ## type){ farena__push(arena, size_of(type), amount, opt_args(Opts_farena, lit(stringify(type)), __VA_ARGS__)).ptr, amount }
|
(Slice ## type){ farena__push(arena, size_of(type), amount, opt_args(Opts_farena, lit(stringify(type)), __VA_ARGS__)).ptr, amount }
|
||||||
@@ -504,7 +504,7 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
|
|||||||
#define arena_push_mem(arena, amount, ...) arena__push(arena, amount, 1, opt_args(Opts_arena, lit(stringify(B1)), __VA_ARGS__))
|
#define arena_push_mem(arena, amount, ...) arena__push(arena, amount, 1, opt_args(Opts_arena, lit(stringify(B1)), __VA_ARGS__))
|
||||||
|
|
||||||
#define arena_push(arena, type, ...) \
|
#define arena_push(arena, type, ...) \
|
||||||
cast(type*R_, arena__push(arena, 1, size_of(type), opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__) ).ptr)
|
cast(type*, arena__push(arena, 1, size_of(type), opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__) ).ptr)
|
||||||
|
|
||||||
#define arena_push_array(arena, type, amount, ...) \
|
#define arena_push_array(arena, type, amount, ...) \
|
||||||
(tmpl(Slice,type)){ arena__push(arena, size_of(type), amount, opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__)).ptr, amount }
|
(tmpl(Slice,type)){ arena__push(arena, size_of(type), amount, opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__)).ptr, amount }
|
||||||
@@ -570,10 +570,9 @@ def_struct(tmpl(KT1CX_Cell,type)) { \
|
|||||||
tmpl(KT1CX_Slot,type) slots[depth]; \
|
tmpl(KT1CX_Slot,type) slots[depth]; \
|
||||||
tmpl(KT1CX_Slot,type)* next; \
|
tmpl(KT1CX_Slot,type)* next; \
|
||||||
}
|
}
|
||||||
#define def_KT1CX(type) \
|
#define def_KT1CX(type) \
|
||||||
def_struct(tmpl(KT1CX,type)) { \
|
def_struct(tmpl(KT1CX,type)) { \
|
||||||
tmpl(Slice_KT1CX_Cell,type) cell_pool; \
|
tmpl(Slice_KT1CX_Cell,type) table; \
|
||||||
tmpl(Slice_KT1CX_Cell,type) table; \
|
|
||||||
}
|
}
|
||||||
typedef def_struct(KT1CX_Byte_Slot) {
|
typedef def_struct(KT1CX_Byte_Slot) {
|
||||||
U8 key;
|
U8 key;
|
||||||
@@ -584,7 +583,6 @@ typedef def_struct(KT1CX_Byte_Cell) {
|
|||||||
U8 next;
|
U8 next;
|
||||||
};
|
};
|
||||||
typedef def_struct(KT1CX_Byte) {
|
typedef def_struct(KT1CX_Byte) {
|
||||||
Slice_Mem cell_pool;
|
|
||||||
Slice_Mem table;
|
Slice_Mem table;
|
||||||
};
|
};
|
||||||
typedef def_struct(KT1CX_ByteMeta) {
|
typedef def_struct(KT1CX_ByteMeta) {
|
||||||
@@ -617,11 +615,10 @@ finline U8 kt1cx_slot_id(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta);
|
|||||||
U8 kt1cx_get (KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta);
|
U8 kt1cx_get (KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta);
|
||||||
U8 kt1cx_set (KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
U8 kt1cx_set (KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
||||||
|
|
||||||
#define kt1cx_assert(kt) do { \
|
#define kt1cx_assert(kt) do { \
|
||||||
slice_assert(kt.cell_pool); \
|
|
||||||
slice_assert(kt.table); \
|
slice_assert(kt.table); \
|
||||||
} while(0)
|
} while(0)
|
||||||
#define kt1cx_byte(kt) (KT1CX_Byte){slice_mem_s(kt.cell_pool), (Slice_Mem){u8_(kt.table.ptr), kt.table.len} }
|
#define kt1cx_byte(kt) (KT1CX_Byte){ (Slice_Mem){u8_(kt.table.ptr), kt.table.len} }
|
||||||
#pragma endregion KT1CX
|
#pragma endregion KT1CX
|
||||||
|
|
||||||
#pragma region String Operations
|
#pragma region String Operations
|
||||||
@@ -1484,8 +1481,7 @@ void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result) {
|
|||||||
assert(m.cell_pool_size >= kilo(4));
|
assert(m.cell_pool_size >= kilo(4));
|
||||||
assert(m.table_size >= kilo(4));
|
assert(m.table_size >= kilo(4));
|
||||||
assert(m.type_width > 0);
|
assert(m.type_width > 0);
|
||||||
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
|
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
|
||||||
result->cell_pool = mem_alloc(info.backing_cells, m.cell_size * m.cell_pool_size); slice_assert(result->cell_pool);
|
|
||||||
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
|
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
|
||||||
}
|
}
|
||||||
inline
|
inline
|
||||||
@@ -1677,38 +1673,38 @@ Str8 str8__fmt_kt1l(AllocatorInfo ainfo, Slice_Mem*R_ _buffer, KT1L_Str8 table,
|
|||||||
UTF8_R cursor_buffer = cast(UTF8_R, buffer.ptr);
|
UTF8_R cursor_buffer = cast(UTF8_R, buffer.ptr);
|
||||||
U8 buffer_remaining = buffer.len;
|
U8 buffer_remaining = buffer.len;
|
||||||
|
|
||||||
UTF8 curr_code = fmt_template.ptr[0];
|
|
||||||
UTF8_R cursor_fmt = fmt_template.ptr;
|
UTF8_R cursor_fmt = fmt_template.ptr;
|
||||||
U8 left_fmt = fmt_template.len;
|
U8 left_fmt = fmt_template.len;
|
||||||
while (left_fmt && buffer_remaining)
|
while (left_fmt && buffer_remaining)
|
||||||
{
|
{
|
||||||
// Forward until we hit the delimiter '<' or the template's contents are exhausted.
|
// Forward until we hit the delimiter '<' or the template's contents are exhausted.
|
||||||
while (curr_code && curr_code != '<' && cursor_fmt != slice_end(fmt_template)) {
|
U8 copy_offset = 0;
|
||||||
cursor_buffer[0] = cursor_fmt[0];
|
while (cursor_fmt[copy_offset] != '<' && (cursor_fmt + copy_offset) < slice_end(fmt_template)) {
|
||||||
++ cursor_buffer;
|
++ copy_offset;
|
||||||
++ cursor_fmt;
|
|
||||||
-- buffer_remaining;
|
|
||||||
-- left_fmt;
|
|
||||||
curr_code = cursor_fmt[0];
|
|
||||||
}
|
}
|
||||||
if (curr_code == '<')
|
memory_copy(u8_(cursor_buffer), u8_(cursor_fmt), copy_offset);
|
||||||
|
buffer_remaining -= copy_offset;
|
||||||
|
left_fmt -= copy_offset;
|
||||||
|
cursor_buffer += copy_offset;
|
||||||
|
cursor_fmt += copy_offset;
|
||||||
|
|
||||||
|
if (cursor_fmt[0] == '<')
|
||||||
{
|
{
|
||||||
UTF8_R cursor_potential_token = cursor_fmt + 1;
|
UTF8_R potential_token_cursor = cursor_fmt + 1;
|
||||||
U8 potential_token_length = 0;
|
U8 potential_token_len = 0;
|
||||||
B4 fmt_overflow = false;
|
B4 fmt_overflow = false;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
UTF8_R cursor = cursor_potential_token + potential_token_length;
|
UTF8_R cursor = potential_token_cursor + potential_token_len;
|
||||||
fmt_overflow = cursor >= slice_end(fmt_template);
|
fmt_overflow = cursor >= slice_end(fmt_template);
|
||||||
B4 found_terminator = (cursor_potential_token + potential_token_length)[0] == '>';
|
B4 found_terminator = potential_token_cursor[potential_token_len] == '>';
|
||||||
if (fmt_overflow || found_terminator) { break; }
|
if (fmt_overflow || found_terminator) { break; }
|
||||||
++ potential_token_length;
|
++ potential_token_len;
|
||||||
}
|
}
|
||||||
if (fmt_overflow) continue;
|
if (fmt_overflow) continue;
|
||||||
// Hashing the potential token and cross checking it with our token table
|
// Hashing the potential token and cross checking it with our token table
|
||||||
U8 key = 0; hash64_djb8(& key, slice_mem(u8_(cursor_potential_token), potential_token_length));
|
U8 key = 0; hash64_djb8(& key, slice_mem(u8_(potential_token_cursor), potential_token_len));
|
||||||
Str8_R value = nullptr;
|
Str8_R value = nullptr;
|
||||||
for (slice_iter(table, token))
|
for (slice_iter(table, token)) {
|
||||||
{
|
|
||||||
// We do a linear iteration instead of a hash table lookup because the user should be never substiuting with more than 100 unqiue tokens..
|
// We do a linear iteration instead of a hash table lookup because the user should be never substiuting with more than 100 unqiue tokens..
|
||||||
if (token->key == key) {
|
if (token->key == key) {
|
||||||
value = & token->value;
|
value = & token->value;
|
||||||
@@ -1718,32 +1714,26 @@ Str8 str8__fmt_kt1l(AllocatorInfo ainfo, Slice_Mem*R_ _buffer, KT1L_Str8 table,
|
|||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
// We're going to appending the string, make sure we have enough space in our buffer.
|
// We're going to appending the string, make sure we have enough space in our buffer.
|
||||||
if (ainfo.proc != nullptr && (buffer_remaining - potential_token_length) <= 0) {
|
if (ainfo.proc != nullptr && (buffer_remaining - potential_token_len) <= 0) {
|
||||||
buffer = mem_grow(ainfo, buffer, buffer.len + potential_token_length);
|
buffer = mem_grow(ainfo, buffer, buffer.len + potential_token_len);
|
||||||
buffer_remaining += potential_token_length;
|
buffer_remaining += potential_token_len;
|
||||||
}
|
|
||||||
U8 left = value->len;
|
|
||||||
U1_R cursor_value = value->ptr;
|
|
||||||
|
|
||||||
while (left && buffer_remaining) {
|
|
||||||
cursor_buffer[0] = cursor_value[0];
|
|
||||||
++ cursor_buffer;
|
|
||||||
++ cursor_value;
|
|
||||||
-- buffer_remaining;
|
|
||||||
-- left;
|
|
||||||
}
|
}
|
||||||
|
assert((buffer_remaining - potential_token_len) > 0);
|
||||||
|
memory_copy(u8_(cursor_buffer), u8_(value->ptr), value->len);
|
||||||
// Sync cursor format to after the processed token
|
// Sync cursor format to after the processed token
|
||||||
cursor_fmt = cursor_potential_token + potential_token_length + 1;
|
cursor_buffer += value->len;
|
||||||
curr_code = cursor_fmt[0];
|
buffer_remaining -= value->len;
|
||||||
left_fmt -= potential_token_length + 2; // The 2 here are the '<' & '>' delimiters being omitted.
|
cursor_fmt = potential_token_cursor + potential_token_len + 1;
|
||||||
|
left_fmt -= potential_token_len + 2; // The 2 here are the '<' & '>' delimiters being omitted.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// If not a subsitution, we do a single copy for the '<' and continue.
|
||||||
cursor_buffer[0] = cursor_fmt[0];
|
cursor_buffer[0] = cursor_fmt[0];
|
||||||
++ cursor_buffer;
|
++ cursor_buffer;
|
||||||
++ cursor_fmt;
|
++ cursor_fmt;
|
||||||
-- buffer_remaining;
|
-- buffer_remaining;
|
||||||
-- left_fmt;
|
-- left_fmt;
|
||||||
curr_code = cursor_fmt[0];
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_buffer[0] = buffer;
|
_buffer[0] = buffer;
|
||||||
@@ -2277,7 +2267,7 @@ int main(void)
|
|||||||
os_init();
|
os_init();
|
||||||
|
|
||||||
VArena_R vm_file = varena_make(.reserve_size = giga(4), .flags = VArenaFlag_NoLargePages);
|
VArena_R vm_file = varena_make(.reserve_size = giga(4), .flags = VArenaFlag_NoLargePages);
|
||||||
FileOpInfo file = file_read_contents(lit("watl.v0.msvc.c"), .backing = ainfo_varena(vm_file));
|
FileOpInfo file = file_read_contents(lit("watl.v0.llvm.lottes_hybrid.c"), .backing = ainfo_varena(vm_file));
|
||||||
slice_assert(file.content);
|
slice_assert(file.content);
|
||||||
|
|
||||||
Arena_R a_msgs = arena_make();
|
Arena_R a_msgs = arena_make();
|
||||||
|
@@ -464,10 +464,9 @@ def_struct(tmpl(KT1CX_Cell,type)) { \
|
|||||||
tmpl(KT1CX_Slot,type) slots[depth]; \
|
tmpl(KT1CX_Slot,type) slots[depth]; \
|
||||||
tmpl(KT1CX_Cell,type)* next; \
|
tmpl(KT1CX_Cell,type)* next; \
|
||||||
}
|
}
|
||||||
#define def_KT1CX(type) \
|
#define def_KT1CX(type) \
|
||||||
def_struct(tmpl(KT1CX,type)) { \
|
def_struct(tmpl(KT1CX,type)) { \
|
||||||
tmpl(Slice_KT1CX_Cell,type) cell_pool; \
|
tmpl(Slice_KT1CX_Cell,type) table; \
|
||||||
tmpl(Slice_KT1CX_Cell,type) table; \
|
|
||||||
}
|
}
|
||||||
typedef def_struct(KT1CX_Byte_Slot) {
|
typedef def_struct(KT1CX_Byte_Slot) {
|
||||||
U64 key;
|
U64 key;
|
||||||
@@ -478,7 +477,6 @@ typedef def_struct(KT1CX_Byte_Cell) {
|
|||||||
Byte* next;
|
Byte* next;
|
||||||
};
|
};
|
||||||
typedef def_struct(KT1CX_Byte) {
|
typedef def_struct(KT1CX_Byte) {
|
||||||
Slice_Byte cell_pool;
|
|
||||||
Slice_Byte table;
|
Slice_Byte table;
|
||||||
};
|
};
|
||||||
typedef def_struct(KT1CX_ByteMeta) {
|
typedef def_struct(KT1CX_ByteMeta) {
|
||||||
@@ -511,11 +509,10 @@ U64 kt1cx_slot_id(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
|||||||
Byte* kt1cx_get (KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
Byte* kt1cx_get (KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
||||||
Byte* kt1cx_set (KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
Byte* kt1cx_set (KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
||||||
|
|
||||||
#define kt1cx_assert(kt) do { \
|
#define kt1cx_assert(kt) do { \
|
||||||
slice_assert(kt.cell_pool); \
|
|
||||||
slice_assert(kt.table); \
|
slice_assert(kt.table); \
|
||||||
} while(0)
|
} while(0)
|
||||||
#define kt1cx_byte(kt) (KT1CX_Byte){slice_byte(kt.cell_pool), { cast(Byte*, kt.table.ptr), kt.table.len } }
|
#define kt1cx_byte(kt) (KT1CX_Byte){ { cast(Byte*, kt.table.ptr), kt.table.len } }
|
||||||
#pragma endregion KT1CX
|
#pragma endregion KT1CX
|
||||||
|
|
||||||
#pragma region String Operations
|
#pragma region String Operations
|
||||||
@@ -1389,8 +1386,7 @@ void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte* result) {
|
|||||||
assert(m.cell_pool_size >= kilo(4));
|
assert(m.cell_pool_size >= kilo(4));
|
||||||
assert(m.table_size >= kilo(4));
|
assert(m.table_size >= kilo(4));
|
||||||
assert(m.type_width > 0);
|
assert(m.type_width > 0);
|
||||||
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
|
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
|
||||||
result->cell_pool = mem_alloc(info.backing_cells, m.cell_size * m.cell_pool_size); slice_assert(result->cell_pool);
|
|
||||||
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
|
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
|
||||||
}
|
}
|
||||||
void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
|
void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
|
||||||
@@ -1585,7 +1581,7 @@ Str8 str8__fmt_kt1l(AllocatorInfo ainfo, Slice_Byte* _buffer, KT1L_Str8 table, S
|
|||||||
{
|
{
|
||||||
SSIZE copy_offset = 0;
|
SSIZE copy_offset = 0;
|
||||||
// Forward until we hit the delimiter '<' or the template's contents are exhausted.
|
// Forward until we hit the delimiter '<' or the template's contents are exhausted.
|
||||||
while (cursor_fmt[copy_offset] != cast(UTF8, '<') && (cursor_fmt + copy_offset) != slice_end(fmt_template)) {
|
while (cursor_fmt[copy_offset] != cast(UTF8, '<') && (cursor_fmt + copy_offset) < slice_end(fmt_template)) {
|
||||||
++ copy_offset;
|
++ copy_offset;
|
||||||
}
|
}
|
||||||
memory_copy(cursor_buffer, cursor_fmt, copy_offset);
|
memory_copy(cursor_buffer, cursor_fmt, copy_offset);
|
||||||
@@ -1598,11 +1594,11 @@ Str8 str8__fmt_kt1l(AllocatorInfo ainfo, Slice_Byte* _buffer, KT1L_Str8 table, S
|
|||||||
{
|
{
|
||||||
UTF8* potential_token_cursor = cursor_fmt + 1;
|
UTF8* potential_token_cursor = cursor_fmt + 1;
|
||||||
SSIZE potential_token_len = 0;
|
SSIZE potential_token_len = 0;
|
||||||
B32 fmt_overflow = false;
|
B32 fmt_overflow = false;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
UTF8* cursor = potential_token_cursor + potential_token_len;
|
UTF8* cursor = potential_token_cursor + potential_token_len;
|
||||||
fmt_overflow = cursor >= slice_end(fmt_template);
|
fmt_overflow = cursor >= slice_end(fmt_template);
|
||||||
B32 found_terminator = * (potential_token_cursor + potential_token_len) == '>';
|
B32 found_terminator = potential_token_cursor[potential_token_len] == '>';
|
||||||
if (fmt_overflow || found_terminator) { break; }
|
if (fmt_overflow || found_terminator) { break; }
|
||||||
++ potential_token_len;
|
++ potential_token_len;
|
||||||
}
|
}
|
||||||
@@ -1633,7 +1629,7 @@ Str8 str8__fmt_kt1l(AllocatorInfo ainfo, Slice_Byte* _buffer, KT1L_Str8 table, S
|
|||||||
left_fmt -= potential_token_len + 2; // The 2 here are the '<' & '>' delimiters being omitted.
|
left_fmt -= potential_token_len + 2; // The 2 here are the '<' & '>' delimiters being omitted.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// If not a value, we do a single copy for the '<' and continue.
|
// If not a subsitution, we do a single copy for the '<' and continue.
|
||||||
* cursor_buffer = * cursor_fmt;
|
* cursor_buffer = * cursor_fmt;
|
||||||
++ cursor_buffer;
|
++ cursor_buffer;
|
||||||
++ cursor_fmt;
|
++ cursor_fmt;
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
WATL Exercise
|
WATL Exercise
|
||||||
Version: 0 (From Scratch, 1-Stage Compilation, WinAPI Only, Win CRT Multi-threaded Static Linkage)
|
Version: 0 (From Scratch, 1-Stage Compilation, WinAPI Only, Win CRT Multi-threaded Static Linkage)
|
||||||
Host: Windows 11 (x86-64)
|
Host: Windows 11 (x86-64)
|
||||||
Toolchain: odin-lang/Odin dev-2025-07
|
Toolchain: odin-lang/Odin dev-2025-09
|
||||||
*/
|
*/
|
||||||
package odin
|
package odin
|
||||||
|
|
||||||
@@ -31,9 +31,9 @@ copy :: proc {
|
|||||||
slice_copy,
|
slice_copy,
|
||||||
string_copy,
|
string_copy,
|
||||||
}
|
}
|
||||||
copy_non_overlapping :: proc {
|
copy_overlapping :: proc {
|
||||||
memory_copy_non_overlapping,
|
memory_copy_overlapping,
|
||||||
slice_copy_non_overlapping,
|
slice_copy_overlapping,
|
||||||
}
|
}
|
||||||
cursor :: proc {
|
cursor :: proc {
|
||||||
ptr_cursor,
|
ptr_cursor,
|
||||||
@@ -95,29 +95,47 @@ Tera :: Giga * 1024
|
|||||||
|
|
||||||
ptr_cursor :: #force_inline proc "contextless" (ptr: ^$Type) -> [^]Type { return transmute([^]Type) ptr }
|
ptr_cursor :: #force_inline proc "contextless" (ptr: ^$Type) -> [^]Type { return transmute([^]Type) ptr }
|
||||||
|
|
||||||
align_pow2 :: proc(x: int, b: int) -> int {
|
align_pow2 :: #force_inline proc(x: int, b: int) -> int {
|
||||||
assert(b != 0)
|
assert(b != 0)
|
||||||
assert((b & (b - 1)) == 0) // Check power of 2
|
assert((b & (b - 1)) == 0) // Check power of 2
|
||||||
return ((x + b - 1) & ~(b - 1))
|
return ((x + b - 1) & ~(b - 1))
|
||||||
}
|
}
|
||||||
memory_zero :: proc "contextless" (data: rawptr, len: int) -> rawptr {
|
memory_zero :: #force_inline proc "contextless" (data: rawptr, len: int) -> rawptr {
|
||||||
intrinsics.mem_zero(data, len)
|
intrinsics.mem_zero(data, len)
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
memory_zero_explicit :: proc "contextless" (data: rawptr, len: int) -> rawptr {
|
memory_zero_explicit :: #force_inline proc "contextless" (data: rawptr, len: int) -> rawptr {
|
||||||
intrinsics.mem_zero_volatile(data, len) // Use the volatile mem_zero
|
intrinsics.mem_zero_volatile(data, len) // Use the volatile mem_zero
|
||||||
intrinsics.atomic_thread_fence(.Seq_Cst) // Prevent reordering
|
intrinsics.atomic_thread_fence(.Seq_Cst) // Prevent reordering
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
memory_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
memory_copy_overlapping :: #force_inline proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||||
intrinsics.mem_copy(dst, src, len)
|
intrinsics.mem_copy(dst, src, len)
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
memory_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
memory_copy :: #force_inline proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||||
intrinsics.mem_copy_non_overlapping(dst, src, len)
|
intrinsics.mem_copy_non_overlapping(dst, src, len)
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sll_stack_push_n :: proc "contextless" (curr, n, n_link: ^^$Type) {
|
||||||
|
(n_link ^) = (curr ^)
|
||||||
|
(curr ^) = (n ^)
|
||||||
|
}
|
||||||
|
sll_queue_push_nz :: proc "contextless" (first: ^$ParentType, last, n: ^^$Type, nil_val: ^Type) {
|
||||||
|
if (first ^) == nil_val {
|
||||||
|
(first ^) = n^
|
||||||
|
(last ^) = n^
|
||||||
|
n^.next = nil_val
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(last ^).next = n^
|
||||||
|
(last ^) = n^
|
||||||
|
n^.next = nil_val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sll_queue_push_n :: #force_inline proc "contextless" (first: $ParentType, last, n: ^^$Type) { sll_queue_push_nz(first, last, n, nil) }
|
||||||
|
|
||||||
SliceByte :: struct {
|
SliceByte :: struct {
|
||||||
data: [^]byte,
|
data: [^]byte,
|
||||||
len: int
|
len: int
|
||||||
@@ -137,39 +155,21 @@ slice_end :: #force_inline proc "contextless" (s : $SliceType / []$Type) -> ^Typ
|
|||||||
@(require_results) slice_to_bytes :: proc "contextless" (s: []$Type) -> []byte { return ([^]byte)(raw_data(s))[:len(s) * size_of(Type)] }
|
@(require_results) slice_to_bytes :: proc "contextless" (s: []$Type) -> []byte { return ([^]byte)(raw_data(s))[:len(s) * size_of(Type)] }
|
||||||
@(require_results) slice_raw :: proc "contextless" (s: []$Type) -> SliceRaw(Type) { return transmute(SliceRaw(Type)) s }
|
@(require_results) slice_raw :: proc "contextless" (s: []$Type) -> SliceRaw(Type) { return transmute(SliceRaw(Type)) s }
|
||||||
|
|
||||||
slice_zero :: proc "contextless" (data: $SliceType / []$Type) { memory_zero(raw_data(data), size_of(Type) * len(data)) }
|
slice_zero :: #force_inline proc "contextless" (data: $SliceType / []$Type) { memory_zero(raw_data(data), size_of(Type) * len(data)) }
|
||||||
slice_copy :: proc "contextless" (dst, src: $SliceType / []$Type) -> int {
|
slice_copy :: #force_inline proc "contextless" (dst, src: $SliceType / []$Type) -> int {
|
||||||
n := max(0, min(len(dst), len(src)))
|
|
||||||
if n > 0 {
|
|
||||||
intrinsics.mem_copy(raw_data(dst), raw_data(src), n * size_of(Type))
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
slice_copy_non_overlapping :: proc "contextless" (dst, src: $SliceType / []$Type) -> int {
|
|
||||||
n := max(0, min(len(dst), len(src)))
|
n := max(0, min(len(dst), len(src)))
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
intrinsics.mem_copy_non_overlapping(raw_data(dst), raw_data(src), n * size_of(Type))
|
intrinsics.mem_copy_non_overlapping(raw_data(dst), raw_data(src), n * size_of(Type))
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
slice_copy_overlapping :: #force_inline proc "contextless" (dst, src: $SliceType / []$Type) -> int {
|
||||||
sll_stack_push_n :: proc "contextless" (curr, n, n_link: ^^$Type) {
|
n := max(0, min(len(dst), len(src)))
|
||||||
(n_link ^) = (curr ^)
|
if n > 0 {
|
||||||
(curr ^) = (n ^)
|
intrinsics.mem_copy(raw_data(dst), raw_data(src), n * size_of(Type))
|
||||||
}
|
|
||||||
sll_queue_push_nz :: proc "contextless" (first: ^$ParentType, last, n: ^^$Type, nil_val: ^Type) {
|
|
||||||
if (first ^) == nil_val {
|
|
||||||
(first ^) = n^
|
|
||||||
(last ^) = n^
|
|
||||||
n^.next = nil_val
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
(last ^).next = n^
|
|
||||||
(last ^) = n^
|
|
||||||
n^.next = nil_val
|
|
||||||
}
|
}
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
sll_queue_push_n :: #force_inline proc "contextless" (first: $ParentType, last, n: ^^$Type) { sll_queue_push_nz(first, last, n, nil) }
|
|
||||||
//endregion Memory
|
//endregion Memory
|
||||||
|
|
||||||
//region Allocator Interface
|
//region Allocator Interface
|
||||||
@@ -975,8 +975,7 @@ KT1CX_Cell :: struct($type: typeid, $depth: int) {
|
|||||||
next: ^KT1CX_Cell(type, depth),
|
next: ^KT1CX_Cell(type, depth),
|
||||||
}
|
}
|
||||||
KT1CX :: struct($cell: typeid / KT1CX_Cell($type, $depth)) {
|
KT1CX :: struct($cell: typeid / KT1CX_Cell($type, $depth)) {
|
||||||
cell_pool: []cell,
|
table: []cell,
|
||||||
table: []cell,
|
|
||||||
}
|
}
|
||||||
KT1CX_Byte_Slot :: struct {
|
KT1CX_Byte_Slot :: struct {
|
||||||
key: u64,
|
key: u64,
|
||||||
@@ -986,8 +985,7 @@ KT1CX_Byte_Cell :: struct {
|
|||||||
next: ^byte,
|
next: ^byte,
|
||||||
}
|
}
|
||||||
KT1CX_Byte :: struct {
|
KT1CX_Byte :: struct {
|
||||||
cell_pool: []byte,
|
table: []byte,
|
||||||
table: []byte,
|
|
||||||
}
|
}
|
||||||
KT1CX_ByteMeta :: struct {
|
KT1CX_ByteMeta :: struct {
|
||||||
slot_size: int,
|
slot_size: int,
|
||||||
@@ -1021,10 +1019,8 @@ 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(SliceByte) 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_size * m.cell_pool_size)
|
|
||||||
slice_assert(result.cell_pool)
|
|
||||||
table_raw.len = m.table_size
|
table_raw.len = m.table_size
|
||||||
result.table = transmute([]byte) table_raw
|
result.table = transmute([]byte) table_raw
|
||||||
}
|
}
|
||||||
@@ -1126,10 +1122,11 @@ kt1cx_set :: proc(kt: KT1CX_Byte, key: u64, value: []byte, backing_cells: Alloca
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
kt1cx_assert :: proc(kt: $type / KT1CX) {
|
kt1cx_assert :: proc(kt: $type / KT1CX) {
|
||||||
slice_assert(kt.cell_pool)
|
|
||||||
slice_assert(kt.table)
|
slice_assert(kt.table)
|
||||||
}
|
}
|
||||||
kt1cx_byte :: proc(kt: $type / KT1CX) -> KT1CX_Byte { return { slice_to_bytes(kt.cell_pool), slice( transmute([^]byte) cursor(kt.table), len(kt.table)) } }
|
kt1cx_byte :: proc(kt: $type / KT1CX) -> KT1CX_Byte { return {
|
||||||
|
slice( transmute([^]byte) cursor(kt.table), len(kt.table))
|
||||||
|
} }
|
||||||
//endregion Key Table 1-Layer Chained-Chunked-Cells (KT1CX)
|
//endregion Key Table 1-Layer Chained-Chunked-Cells (KT1CX)
|
||||||
|
|
||||||
//region String Operations
|
//region String Operations
|
||||||
@@ -1220,35 +1217,36 @@ str8_fmt_kt1l :: proc(ainfo: AllocatorInfo, _buffer: ^[]byte, table: []KT1L_Slot
|
|||||||
cursor_buffer := cursor(buffer)
|
cursor_buffer := cursor(buffer)
|
||||||
buffer_remaining := len(buffer)
|
buffer_remaining := len(buffer)
|
||||||
|
|
||||||
curr_code := fmt_template[0]
|
|
||||||
cursor_fmt := cursor(transmute([]u8) fmt_template)
|
cursor_fmt := cursor(transmute([]u8) fmt_template)
|
||||||
left_fmt := len(fmt_template)
|
left_fmt := len(fmt_template)
|
||||||
for ; left_fmt > 0 && buffer_remaining > 0;
|
for ; left_fmt > 0 && buffer_remaining > 0;
|
||||||
{
|
{
|
||||||
// Forward until we hit the delimiter '<' or the template's contents are exhausted.
|
// Forward until we hit the delimiter '<' or the template's contents are exhausted.
|
||||||
for ; curr_code != '<' && cursor_fmt != end(fmt_template); {
|
copy_offset : int = 0
|
||||||
cursor_buffer[0] = cursor_fmt [0]
|
for ; cursor_fmt[copy_offset] != '<' && cursor_fmt[copy_offset:] != end(fmt_template); {
|
||||||
cursor_buffer = cursor_buffer[1:]
|
copy_offset += 1
|
||||||
cursor_fmt = cursor_fmt [1:]
|
|
||||||
curr_code = cursor_fmt [0]
|
|
||||||
buffer_remaining -= 1
|
|
||||||
left_fmt -= 1
|
|
||||||
}
|
}
|
||||||
if curr_code == '<'
|
copy(cursor_buffer, cursor_fmt, copy_offset)
|
||||||
|
buffer_remaining -= copy_offset
|
||||||
|
left_fmt -= copy_offset
|
||||||
|
cursor_buffer = cursor_buffer[copy_offset:]
|
||||||
|
cursor_fmt = cursor_fmt [copy_offset:]
|
||||||
|
|
||||||
|
if cursor_fmt[0] == '<'
|
||||||
{
|
{
|
||||||
cursor_potential_token := cursor_fmt[1:]
|
potential_token_cursor := cursor_fmt[1:]
|
||||||
potential_token_length := 0
|
potential_token_len := 0
|
||||||
fmt_overflow := b32(false)
|
fmt_overflow := b32(false)
|
||||||
for ;; {
|
for ;; {
|
||||||
cursor := cursor_potential_token[potential_token_length:]
|
cursor := potential_token_cursor[potential_token_len:]
|
||||||
fmt_overflow = cursor >= end(fmt_template)
|
fmt_overflow = cursor >= end(fmt_template)
|
||||||
found_terminator := cast(b32) (cursor_potential_token[potential_token_length] == '>')
|
found_terminator := cast(b32) (potential_token_cursor[potential_token_len] == '>')
|
||||||
if fmt_overflow || found_terminator do break
|
if fmt_overflow || found_terminator do break
|
||||||
potential_token_length += 1
|
potential_token_len += 1
|
||||||
}
|
}
|
||||||
if fmt_overflow do continue
|
if fmt_overflow do continue
|
||||||
// Hashing the potential token and cross checking it with our token table
|
// Hashing the potential token and cross checking it with our token table
|
||||||
key : u64 = 0; hash64_djb8(& key, slice(cursor_potential_token, potential_token_length))
|
key : u64 = 0; hash64_djb8(& key, slice(potential_token_cursor, potential_token_len))
|
||||||
value : ^string = nil
|
value : ^string = nil
|
||||||
for & token in table
|
for & token in table
|
||||||
{
|
{
|
||||||
@@ -1261,32 +1259,26 @@ str8_fmt_kt1l :: proc(ainfo: AllocatorInfo, _buffer: ^[]byte, table: []KT1L_Slot
|
|||||||
if value != nil
|
if value != nil
|
||||||
{
|
{
|
||||||
// We're going to appending the string, make sure we have enough space in our buffer.
|
// We're going to appending the string, make sure we have enough space in our buffer.
|
||||||
if ainfo.procedure != nil && (buffer_remaining - potential_token_length) <= 0 {
|
if ainfo.procedure != nil && (buffer_remaining - potential_token_len) <= 0 {
|
||||||
buffer = mem_grow(ainfo, buffer, len(buffer) + potential_token_length)
|
buffer = mem_grow(ainfo, buffer, len(buffer) + potential_token_len)
|
||||||
buffer_remaining += potential_token_length
|
buffer_remaining += potential_token_len
|
||||||
}
|
|
||||||
left := len(value)
|
|
||||||
cursor_value := cursor(transmute([]u8) value^)
|
|
||||||
for ; left > 0 && buffer_remaining > 0; {
|
|
||||||
cursor_buffer[0] = cursor_value [0]
|
|
||||||
cursor_buffer = cursor_buffer[1:]
|
|
||||||
cursor_value = cursor_value [1:]
|
|
||||||
cursor_fmt = cursor_fmt [1:]
|
|
||||||
buffer_remaining -= 1
|
|
||||||
left -= 1
|
|
||||||
}
|
}
|
||||||
|
assert((buffer_remaining - potential_token_len) > 0)
|
||||||
|
copy(cursor_buffer, cursor(value ^), len(value))
|
||||||
// Sync cursor format to after the processed token
|
// Sync cursor format to after the processed token
|
||||||
cursor_fmt = cursor_potential_token[potential_token_length + 1:]
|
cursor_buffer = cursor_buffer[len(value):]
|
||||||
curr_code = cursor_fmt[0]
|
buffer_remaining -= len(value)
|
||||||
left_fmt -= potential_token_length + 2 // The 2 here are the '<' & '>' delimiters being omitted.
|
cursor_fmt = potential_token_cursor[potential_token_len + 1:]
|
||||||
|
left_fmt -= potential_token_len + 2 // The 2 here are the '<' & '>' delimiters being omitted.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// If not a subsitution, we do a single copy for the '<' and continue.
|
||||||
cursor_buffer[0] = cursor_fmt [0]
|
cursor_buffer[0] = cursor_fmt [0]
|
||||||
cursor_buffer = cursor_buffer[1:]
|
cursor_buffer = cursor_buffer[1:]
|
||||||
cursor_fmt = cursor_fmt [1:]
|
cursor_fmt = cursor_fmt [1:]
|
||||||
curr_code = cursor_fmt [0]
|
|
||||||
buffer_remaining -= 1
|
buffer_remaining -= 1
|
||||||
left_fmt -= 1
|
left_fmt -= 1
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_buffer ^ = buffer
|
_buffer ^ = buffer
|
||||||
|
@@ -42,8 +42,8 @@ $flag_link_win_machine_64 = '/MACHINE:X64'
|
|||||||
$flag_link_win_path_output = '/OUT:'
|
$flag_link_win_path_output = '/OUT:'
|
||||||
$flag_link_win_rt_dll = '/MD'
|
$flag_link_win_rt_dll = '/MD'
|
||||||
$flag_link_win_rt_dll_debug = '/MDd'
|
$flag_link_win_rt_dll_debug = '/MDd'
|
||||||
$flag_link_win_rt_static = '/MT:STATIC'
|
$flag_link_win_rt_static = '/MT'
|
||||||
$flag_link_win_rt_static_debug = '/MTd:STATIC'
|
$flag_link_win_rt_static_debug = '/MTd'
|
||||||
$flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE'
|
$flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE'
|
||||||
$flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS'
|
$flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS'
|
||||||
$flag_no_optimization = '/Od'
|
$flag_no_optimization = '/Od'
|
||||||
|
@@ -126,7 +126,7 @@ $compiler_args += ($flag_define + 'BUILD_DEBUG')
|
|||||||
$compiler_args += $flag_debug
|
$compiler_args += $flag_debug
|
||||||
$compiler_args += ( $flag_path_debug + $path_build + '\' )
|
$compiler_args += ( $flag_path_debug + $path_build + '\' )
|
||||||
# Use the static, multithreaded, debug runtime library
|
# Use the static, multithreaded, debug runtime library
|
||||||
$compiler_args += $flag_link_win_rt_static_debug
|
# $compiler_args += $flag_link_win_rt_static_debug
|
||||||
|
|
||||||
# Include setup
|
# Include setup
|
||||||
$compiler_args += ($flag_include + $path_root)
|
$compiler_args += ($flag_include + $path_root)
|
||||||
|
@@ -85,7 +85,6 @@ msvc_link_default_base_address :: 0x180000000
|
|||||||
//endregion Script Grime
|
//endregion Script Grime
|
||||||
|
|
||||||
build :: proc(working_dir : string, args : []string) -> (stdout : string, stderr : string) {
|
build :: proc(working_dir : string, args : []string) -> (stdout : string, stderr : string) {
|
||||||
fmt.println("Building:", args)
|
|
||||||
res, errs : []byte; _, res, errs, _ = os.process_exec({ working_dir = working_dir, command = args}, context.allocator)
|
res, errs : []byte; _, res, errs, _ = os.process_exec({ working_dir = working_dir, command = args}, context.allocator)
|
||||||
return transmute(string)res, transmute(string)errs;
|
return transmute(string)res, transmute(string)errs;
|
||||||
}
|
}
|
||||||
@@ -106,8 +105,10 @@ main :: proc() {
|
|||||||
file_source,
|
file_source,
|
||||||
flag_file,
|
flag_file,
|
||||||
join_str(flag_output_path, file_exe),
|
join_str(flag_output_path, file_exe),
|
||||||
// flag_optimize_none,
|
flag_optimize_none,
|
||||||
falg_optimize_aggressive,
|
// flag_optimize_minimal,
|
||||||
|
// flag_optimize_speed,
|
||||||
|
// falg_optimize_aggressive,
|
||||||
flag_default_allocator_nil,
|
flag_default_allocator_nil,
|
||||||
flag_debug,
|
flag_debug,
|
||||||
flag_microarch_zen5,
|
flag_microarch_zen5,
|
||||||
@@ -117,6 +118,4 @@ main :: proc() {
|
|||||||
flag_use_lld,
|
flag_use_lld,
|
||||||
join_str(flag_subsystem, "console"),
|
join_str(flag_subsystem, "console"),
|
||||||
})
|
})
|
||||||
fmt.println(res)
|
|
||||||
fmt.println(errs)
|
|
||||||
}
|
}
|
||||||
|
@@ -44,5 +44,5 @@ $build_args += $flag_dyn_map_calls
|
|||||||
$build_args += $flag_default_allocator_nil
|
$build_args += $flag_default_allocator_nil
|
||||||
$build_args += $flag_output_path + $exe
|
$build_args += $flag_output_path + $exe
|
||||||
if ($need_rebuild) { & $odin $build_args }
|
if ($need_rebuild) { & $odin $build_args }
|
||||||
pop-location
|
|
||||||
& $exe
|
& $exe
|
||||||
|
pop-location
|
||||||
|
Reference in New Issue
Block a user