mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2026-04-29 09:40:13 -07:00
updated odin's str8_fmt_kt1l
This commit is contained in:
@@ -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(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, ...) \
|
||||
(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(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, ...) \
|
||||
(tmpl(Slice,type)){ arena__push(arena, size_of(type), amount, opt_args(Opts_arena, lit(stringify(type)), __VA_ARGS__)).ptr, amount }
|
||||
|
||||
+56
-61
@@ -2,7 +2,7 @@
|
||||
WATL Exercise
|
||||
Version: 0 (From Scratch, 1-Stage Compilation, WinAPI Only, Win CRT Multi-threaded Static Linkage)
|
||||
Host: Windows 11 (x86-64)
|
||||
Toolchain: odin-lang/Odin dev-2025-07
|
||||
Toolchain: odin-lang/Odin dev-2025-09
|
||||
*/
|
||||
package odin
|
||||
|
||||
@@ -31,9 +31,9 @@ copy :: proc {
|
||||
slice_copy,
|
||||
string_copy,
|
||||
}
|
||||
copy_non_overlapping :: proc {
|
||||
memory_copy_non_overlapping,
|
||||
slice_copy_non_overlapping,
|
||||
copy_overlapping :: proc {
|
||||
memory_copy_overlapping,
|
||||
slice_copy_overlapping,
|
||||
}
|
||||
cursor :: proc {
|
||||
ptr_cursor,
|
||||
@@ -109,15 +109,33 @@ memory_zero_explicit :: proc "contextless" (data: rawptr, len: int) -> rawptr {
|
||||
intrinsics.atomic_thread_fence(.Seq_Cst) // Prevent reordering
|
||||
return data
|
||||
}
|
||||
memory_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
memory_copy_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
intrinsics.mem_copy(dst, src, len)
|
||||
return dst
|
||||
}
|
||||
memory_copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
memory_copy :: proc "contextless" (dst, src: rawptr, len: int) -> rawptr {
|
||||
intrinsics.mem_copy_non_overlapping(dst, src, len)
|
||||
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 {
|
||||
data: [^]byte,
|
||||
len: int
|
||||
@@ -139,37 +157,19 @@ slice_end :: #force_inline proc "contextless" (s : $SliceType / []$Type) -> ^Typ
|
||||
|
||||
slice_zero :: proc "contextless" (data: $SliceType / []$Type) { memory_zero(raw_data(data), size_of(Type) * len(data)) }
|
||||
slice_copy :: 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)))
|
||||
if n > 0 {
|
||||
intrinsics.mem_copy_non_overlapping(raw_data(dst), raw_data(src), n * size_of(Type))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
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
|
||||
slice_copy_overlapping :: 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
|
||||
}
|
||||
sll_queue_push_n :: #force_inline proc "contextless" (first: $ParentType, last, n: ^^$Type) { sll_queue_push_nz(first, last, n, nil) }
|
||||
//endregion Memory
|
||||
|
||||
//region Allocator Interface
|
||||
@@ -1220,35 +1220,36 @@ str8_fmt_kt1l :: proc(ainfo: AllocatorInfo, _buffer: ^[]byte, table: []KT1L_Slot
|
||||
cursor_buffer := cursor(buffer)
|
||||
buffer_remaining := len(buffer)
|
||||
|
||||
curr_code := fmt_template[0]
|
||||
cursor_fmt := cursor(transmute([]u8) fmt_template)
|
||||
left_fmt := len(fmt_template)
|
||||
for ; left_fmt > 0 && buffer_remaining > 0;
|
||||
{
|
||||
// Forward until we hit the delimiter '<' or the template's contents are exhausted.
|
||||
for ; curr_code != '<' && cursor_fmt != end(fmt_template); {
|
||||
cursor_buffer[0] = cursor_fmt [0]
|
||||
cursor_buffer = cursor_buffer[1:]
|
||||
cursor_fmt = cursor_fmt [1:]
|
||||
curr_code = cursor_fmt [0]
|
||||
buffer_remaining -= 1
|
||||
left_fmt -= 1
|
||||
copy_offset : int = 0
|
||||
for ; cursor_fmt[copy_offset] != '<' && cursor_fmt[copy_offset:] != end(fmt_template); {
|
||||
copy_offset += 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_length := 0
|
||||
potential_token_cursor := cursor_fmt[1:]
|
||||
potential_token_len := 0
|
||||
fmt_overflow := b32(false)
|
||||
for ;; {
|
||||
cursor := cursor_potential_token[potential_token_length:]
|
||||
cursor := potential_token_cursor[potential_token_len:]
|
||||
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
|
||||
potential_token_length += 1
|
||||
potential_token_len += 1
|
||||
}
|
||||
if fmt_overflow do continue
|
||||
// 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
|
||||
for & token in table
|
||||
{
|
||||
@@ -1261,32 +1262,26 @@ str8_fmt_kt1l :: proc(ainfo: AllocatorInfo, _buffer: ^[]byte, table: []KT1L_Slot
|
||||
if value != nil
|
||||
{
|
||||
// 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 {
|
||||
buffer = mem_grow(ainfo, buffer, len(buffer) + potential_token_length)
|
||||
buffer_remaining += potential_token_length
|
||||
}
|
||||
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
|
||||
if ainfo.procedure != nil && (buffer_remaining - potential_token_len) <= 0 {
|
||||
buffer = mem_grow(ainfo, buffer, len(buffer) + potential_token_len)
|
||||
buffer_remaining += potential_token_len
|
||||
}
|
||||
assert((buffer_remaining - potential_token_len) > 0)
|
||||
copy(cursor_buffer, cursor(value ^), len(value))
|
||||
// Sync cursor format to after the processed token
|
||||
cursor_fmt = cursor_potential_token[potential_token_length + 1:]
|
||||
curr_code = cursor_fmt[0]
|
||||
left_fmt -= potential_token_length + 2 // The 2 here are the '<' & '>' delimiters being omitted.
|
||||
cursor_buffer = cursor_buffer[len(value):]
|
||||
buffer_remaining -= len(value)
|
||||
cursor_fmt = potential_token_cursor[potential_token_len + 1:]
|
||||
left_fmt -= potential_token_len + 2 // The 2 here are the '<' & '>' delimiters being omitted.
|
||||
continue
|
||||
}
|
||||
// If not a subsitution, we do a single copy for the '<' and continue.
|
||||
cursor_buffer[0] = cursor_fmt [0]
|
||||
cursor_buffer = cursor_buffer[1:]
|
||||
cursor_fmt = cursor_fmt [1:]
|
||||
curr_code = cursor_fmt [0]
|
||||
buffer_remaining -= 1
|
||||
left_fmt -= 1
|
||||
continue
|
||||
}
|
||||
}
|
||||
_buffer ^ = buffer
|
||||
|
||||
@@ -126,7 +126,7 @@ $compiler_args += ($flag_define + 'BUILD_DEBUG')
|
||||
$compiler_args += $flag_debug
|
||||
$compiler_args += ( $flag_path_debug + $path_build + '\' )
|
||||
# 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
|
||||
$compiler_args += ($flag_include + $path_root)
|
||||
|
||||
@@ -85,7 +85,6 @@ msvc_link_default_base_address :: 0x180000000
|
||||
//endregion Script Grime
|
||||
|
||||
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)
|
||||
return transmute(string)res, transmute(string)errs;
|
||||
}
|
||||
@@ -106,8 +105,8 @@ main :: proc() {
|
||||
file_source,
|
||||
flag_file,
|
||||
join_str(flag_output_path, file_exe),
|
||||
// flag_optimize_none,
|
||||
falg_optimize_aggressive,
|
||||
flag_optimize_none,
|
||||
// falg_optimize_aggressive,
|
||||
flag_default_allocator_nil,
|
||||
flag_debug,
|
||||
flag_microarch_zen5,
|
||||
@@ -117,6 +116,4 @@ main :: proc() {
|
||||
flag_use_lld,
|
||||
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_output_path + $exe
|
||||
if ($need_rebuild) { & $odin $build_args }
|
||||
pop-location
|
||||
& $exe
|
||||
pop-location
|
||||
|
||||
Reference in New Issue
Block a user