mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2025-08-04 22:32:43 -07:00
progress
This commit is contained in:
323
C/watl.v0.msvc.c
323
C/watl.v0.msvc.c
@@ -2,9 +2,16 @@
|
||||
WATL Exercise
|
||||
Version: 0 (From Scratch, 1-Stage Compilation, MSVC & WinAPI Only, Win CRT Multi-threaded Static Linkage)
|
||||
Host: Windows 11 (x86-64)
|
||||
Toolchain: MSVC 19.43
|
||||
Toolchain: MSVC 19.43, C-Stanard: 23
|
||||
*/
|
||||
|
||||
#pragma warning(disable: 4100)
|
||||
#pragma warning(disable: 4127)
|
||||
#pragma warning(disable: 4201)
|
||||
#pragma warning(disable: 4702)
|
||||
#pragma warning(disable: 4710)
|
||||
#pragma warning(disable: 5045)
|
||||
|
||||
#pragma region Header
|
||||
|
||||
#pragma region DSL
|
||||
@@ -23,8 +30,8 @@ typedef S8 B8;
|
||||
typedef S16 B16;
|
||||
typedef S32 B32;
|
||||
enum {
|
||||
false,
|
||||
true,
|
||||
false = 0,
|
||||
true = 1,
|
||||
true_overflow,
|
||||
};
|
||||
#define glue_impl(A, B) A ## B
|
||||
@@ -33,6 +40,7 @@ enum {
|
||||
#define stringify(S) stringify_impl(S)
|
||||
#define tmpl(prefix, type) prefix ## _ ## type
|
||||
|
||||
#define byte_pad(amount, ...) Byte glue(_PAD_, __VA_ARGS__) [amount]
|
||||
#define farray_len(array) (SSIZE)sizeof(array) / size_of( typeof((array)[0]))
|
||||
#define farray_init(type, ...) (type[]){__VA_ARGS__}
|
||||
#define def_farray(type, len) type A ## len ## _ ## type[len]
|
||||
@@ -47,7 +55,8 @@ enum {
|
||||
#define offset_of(type, member) cast(SSIZE, & (((type*) 0)->member))
|
||||
#define static_assert _Static_assert
|
||||
#define typeof __typeof__
|
||||
#define typeof_ptr(ptr) __typeof__(ptr[0])
|
||||
#define typeof_ptr(ptr) typeof(ptr[0])
|
||||
#define typeof_same(a, b) _Generic((a), typeof((b)): 1, default: 0)
|
||||
|
||||
#define cast(type, data) ((type)(data))
|
||||
#define pcast(type, data) * cast(type*, & (data))
|
||||
@@ -72,6 +81,8 @@ enum {
|
||||
typedef def_range(S32);
|
||||
typedef def_range(U32);
|
||||
typedef def_range(SSIZE);
|
||||
|
||||
typedef void fn(VoidFn) (void);
|
||||
#pragma endregion DSL
|
||||
|
||||
#pragma region Debug
|
||||
@@ -103,7 +114,8 @@ void assert_handler( char const* condition, char const* file, char const* functi
|
||||
#pragma endregion Debug
|
||||
|
||||
#pragma region Memory
|
||||
#define align_pow2(x, b) (((x) + (b) - 1) & ( ~((b) - 1)))
|
||||
inline SSIZE align_pow2(SSIZE x, SSIZE b);
|
||||
|
||||
#define align_struct(type_width) ((SSIZE)(((type_width) + 7) / 8 * 8))
|
||||
|
||||
#define assert_bounds(point, start, end) do { \
|
||||
@@ -129,13 +141,17 @@ def_struct(tmpl(Slice,type)) { \
|
||||
|
||||
typedef def_Slice(void);
|
||||
typedef def_Slice(Byte);
|
||||
#define slice_byte(slice) (Slice_Byte){cast(Byte*, (slice).ptr), (slice).len * size_of_slice_type(slice)}
|
||||
#define slice_fmem(mem) (Slice_Byte){ mem, size_of(mem) }
|
||||
#define slice_byte(slice) ((Slice_Byte){cast(Byte*, (slice).ptr), (slice).len * size_of_slice_type(slice)})
|
||||
#define slice_fmem(mem) ((Slice_Byte){ mem, size_of(mem) })
|
||||
|
||||
void slice__copy(Slice_Byte dest, SSIZE dest_typewidth, Slice_Byte src, SSIZE src_typewidth);
|
||||
void slice__zero(Slice_Byte mem, SSIZE typewidth);
|
||||
#define slice_copy(dest, src) slice__copy(slice_byte(dest), size_of_slice_type(dest), slice_byte(src), size_of_slice_type(src))
|
||||
#define slice_zero(slice) slice__zero(slice_byte(slice), size_of_slice_type(slice))
|
||||
#define slice_copy(dest, src) do { \
|
||||
static_assert(typeof_same(dest, src)); \
|
||||
slice__copy(slice_byte(dest), size_of_slice_type(dest), slice_byte(src), size_of_slice_type(src)); \
|
||||
} while (0)
|
||||
#define slice_zero(slice) slice__zero(slice_byte(slice), size_of_slice_type(slice))
|
||||
|
||||
#define slice_iter(container, iter) \
|
||||
typeof((container).ptr) iter = (container).ptr; \
|
||||
iter != slice_end(container); \
|
||||
@@ -176,7 +192,7 @@ typedef unsigned char UTF8;
|
||||
typedef def_Slice(UTF8);
|
||||
typedef Slice_UTF8 Str8;
|
||||
typedef def_Slice(Str8);
|
||||
#define lit(string_literal) (Str8){ string_literal, size_of(string_literal) - 1 }
|
||||
#define lit(string_literal) (Str8){ (UTF8*) string_literal, size_of(string_literal) - 1 }
|
||||
#pragma endregion Strings
|
||||
|
||||
#pragma region Allocator Interface
|
||||
@@ -204,18 +220,21 @@ typedef def_enum(U64, AllocatorQueryFlags) {
|
||||
// Ability to rewind to a save point (ex: arenas, stack), must also be able to save such a point
|
||||
AllocatorQuery_Rewind = (1 << 6),
|
||||
};
|
||||
typedef def_struct(AllocatorSP) {
|
||||
void* type_sig;
|
||||
SSIZE slot;
|
||||
};
|
||||
typedef def_struct(AllocatorProc_In) {
|
||||
void* data;
|
||||
AllocatorOp op;
|
||||
SSIZE requested_size;
|
||||
SSIZE alignment;
|
||||
Slice_Byte old_allocation;
|
||||
AllocatorOp op;
|
||||
byte_pad(4);
|
||||
};
|
||||
typedef def_struct(AllocatorProc_Out) {
|
||||
typedef struct AllocatorProc_Out AllocatorProc_Out;
|
||||
typedef void fn(AllocatorProc) (AllocatorProc_In In, AllocatorProc_Out* Out);
|
||||
typedef def_struct(AllocatorSP) {
|
||||
AllocatorProc* type_sig;
|
||||
SSIZE slot;
|
||||
};
|
||||
struct AllocatorProc_Out {
|
||||
union {
|
||||
Slice_Byte allocation;
|
||||
AllocatorSP save_point;
|
||||
@@ -225,13 +244,12 @@ typedef def_struct(AllocatorProc_Out) {
|
||||
SSIZE max_alloc;
|
||||
SSIZE min_alloc;
|
||||
B32 continuity_break; // Whether this allocation broke continuity with the previous (address space wise)
|
||||
byte_pad(4);
|
||||
};
|
||||
typedef void fn(AllocatorProc) (AllocatorProc_In In, AllocatorProc_Out* Out);
|
||||
typedef def_struct(AllocatorInfo) {
|
||||
AllocatorProc* proc;
|
||||
void* data;
|
||||
};
|
||||
|
||||
static_assert(size_of(AllocatorSP) <= size_of(Slice_Byte));
|
||||
|
||||
#define MEMORY_ALIGNMENT_DEFAULT (2 * size_of(void*))
|
||||
@@ -243,10 +261,10 @@ void mem_reset (AllocatorInfo ainfo);
|
||||
void mem_rewind (AllocatorInfo ainfo, AllocatorSP save_point);
|
||||
AllocatorSP mem_save_point(AllocatorInfo ainfo);
|
||||
|
||||
typedef def_struct(Opts_mem_alloc) { SSIZE alignment; B32 no_zero; };
|
||||
typedef def_struct(Opts_mem_grow) { SSIZE alignment; B32 no_zero; };
|
||||
typedef def_struct(Opts_mem_alloc) { SSIZE alignment; B32 no_zero; byte_pad(4); };
|
||||
typedef def_struct(Opts_mem_grow) { SSIZE alignment; B32 no_zero; byte_pad(4); };
|
||||
typedef def_struct(Opts_mem_shrink) { SSIZE alignment; };
|
||||
typedef def_struct(Opts_mem_resize) { SSIZE alignment; B32 no_zero; };
|
||||
typedef def_struct(Opts_mem_resize) { SSIZE alignment; B32 no_zero; byte_pad(4); };
|
||||
|
||||
Slice_Byte mem__alloc (AllocatorInfo ainfo, SSIZE size, Opts_mem_alloc* opts);
|
||||
Slice_Byte mem__grow (AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_grow* opts);
|
||||
@@ -296,9 +314,10 @@ typedef def_struct(OS_SystemInfo) {
|
||||
typedef def_struct(Opts_vmem) {
|
||||
SSIZE base_addr;
|
||||
B32 no_large_pages;
|
||||
byte_pad(4);
|
||||
};
|
||||
void os_init();
|
||||
OS_SystemInfo* os_system_info();
|
||||
void os_init(void);
|
||||
OS_SystemInfo* os_system_info(void);
|
||||
|
||||
inline B32 os__vmem_commit(void* vm, SSIZE size, Opts_vmem* opts);
|
||||
inline Byte* os__vmem_reserve(SSIZE size, Opts_vmem* opts);
|
||||
@@ -320,12 +339,14 @@ typedef def_struct(VArena) {
|
||||
SSIZE committed;
|
||||
SSIZE commit_used;
|
||||
VArenaFlags flags;
|
||||
byte_pad(4);
|
||||
};
|
||||
typedef def_struct(Opts_varena_make) {
|
||||
SSIZE base_addr;
|
||||
SSIZE reserve_size;
|
||||
SSIZE commit_size;
|
||||
VArenaFlags flags;
|
||||
byte_pad(4);
|
||||
};
|
||||
VArena* varena__make(Opts_varena_make* opts);
|
||||
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
|
||||
@@ -359,6 +380,7 @@ typedef def_struct(Arena) {
|
||||
SSIZE base_pos;
|
||||
SSIZE pos;
|
||||
ArenaFlags flags;
|
||||
byte_pad(4);
|
||||
};
|
||||
typedef Opts_varena_make Opts_arena_make;
|
||||
Arena* arena__make (Opts_arena_make* opts);
|
||||
@@ -427,6 +449,7 @@ def_struct(tmpl(KT1CX_Slot,type)) { \
|
||||
type value; \
|
||||
U64 key; \
|
||||
B32 occupied; \
|
||||
byte_pad(4); \
|
||||
}
|
||||
#define def_KT1CX_Cell(type, depth) \
|
||||
def_struct(tmpl(KT1CX_Cell,type)) { \
|
||||
@@ -442,6 +465,10 @@ def_struct(tmpl(KT1CX,type)) { \
|
||||
typedef def_struct(KT1CX_Byte_Slot) {
|
||||
U64 key;
|
||||
B32 occupied;
|
||||
byte_pad(4);
|
||||
};
|
||||
typedef def_struct(KT1CX_Byte_Cell) {
|
||||
Byte* next;
|
||||
};
|
||||
typedef def_struct(KT1CX_Byte) {
|
||||
Slice_Byte cell_pool;
|
||||
@@ -470,10 +497,16 @@ typedef def_struct(KT1CX_Info) {
|
||||
Str8 type_name;
|
||||
};
|
||||
void kt1cx__init (KT1CX_Info info, KT1CX_Byte* result);
|
||||
void kt1cx__clear (KT1CX_Byte kt, KT1CX_ByteMeta meta);
|
||||
U64 kt1cx__slot_id(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
||||
Slice_Byte kt1cx__get (KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
||||
Slice_Byte kt1cx__set (KT1CX_Byte* kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
||||
void kt1cx__clear (KT1CX_Byte kt, KT1CX_ByteMeta meta);
|
||||
U64 kt1cx__slot_id(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
||||
Slice_Byte kt1cx__get (KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
||||
Slice_Byte kt1cx__set (KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
||||
|
||||
#define kt1cx_assert(kt) do { \
|
||||
slice_assert(kt.cell_pool); \
|
||||
slice_assert(kt.table); \
|
||||
} while(0)
|
||||
#define kt1cx_byte(kt) (KT1CX_Byte){slice_byte(kt.cell_pool), { cast(Byte*, kt.table.ptr), kt.table.len } }
|
||||
#pragma endregion KT1CX
|
||||
|
||||
#pragma region String Operations
|
||||
@@ -524,12 +557,12 @@ Str8Cache str8cache__make( Opts_str8cache_init* opts);
|
||||
|
||||
#define str8gen_slice_byte(gen) (Slice_Byte){ cast(Byte*, (gen).ptr), (gen).cap }
|
||||
|
||||
#define str8cache_init(cache, ...) str8cache__init(cache, opt_args(Opts_str8cache_init))
|
||||
#define str8cache_make(...) str8cache__make( opt_args(Opts_str8cache_init))
|
||||
#define str8cache_init(cache, ...) str8cache__init(cache, opt_args(Opts_str8cache_init, __VA_ARGS__))
|
||||
#define str8cache_make(...) str8cache__make( opt_args(Opts_str8cache_init, __VA_ARGS__))
|
||||
|
||||
void str8cache_clear(KT1CX_Str8 kt);
|
||||
Str8 str8cache_get (KT1CX_Str8 kt, U64 key);
|
||||
Str8 str8cache_set (KT1CX_Str8* kt, U64 key, Str8 value, AllocatorInfo str_reserve, AllocatorInfo backing_cells);
|
||||
void str8cache_clear(KT1CX_Str8 kt);
|
||||
Str8 str8cache_get (KT1CX_Str8 kt, U64 key);
|
||||
Str8 str8cache_set (KT1CX_Str8 kt, U64 key, Str8 value, AllocatorInfo str_reserve, AllocatorInfo backing_cells);
|
||||
|
||||
Str8 cache_str8(Str8Cache* cache, Str8 str);
|
||||
|
||||
@@ -557,6 +590,7 @@ typedef def_struct(FileOpInfo) {
|
||||
typedef def_struct(Opts_read_file_contents) {
|
||||
AllocatorInfo backing;
|
||||
B32 zero_backing;
|
||||
byte_pad(4);
|
||||
};
|
||||
void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_read_file_contents opts);
|
||||
void file_write_str8 (Str8 path, Str8 content);
|
||||
@@ -578,11 +612,10 @@ typedef def_struct(WATL_Tok) {
|
||||
};
|
||||
typedef def_Slice(WATL_Tok);
|
||||
typedef def_enum(U32, WATL_LexStatus) {
|
||||
WATL_LexStatus_MemFail_Alloc = (1 << 0),
|
||||
WATL_LexStatus_MemFail_SliceConstraintFail = (1 << 1),
|
||||
WATL_LexStatus_PosUntrackable = (1 << 2),
|
||||
WATL_LexStatus_UnsupportedCodepoints = (1 << 3),
|
||||
WATL_LexStatus_MessageOverflow = (1 << 4),
|
||||
WATL_LexStatus_MemFail_SliceConstraintFail = (1 << 0),
|
||||
// WATL_LexStatus_PosUntrackable = (1 << 1),
|
||||
// WATL_LexStatus_UnsupportedCodepoints = (1 << 2),
|
||||
// WATL_LexStatus_MessageOverflow = (1 << 3),
|
||||
};
|
||||
typedef def_struct(WATL_Pos) {
|
||||
S32 line;
|
||||
@@ -598,6 +631,7 @@ typedef def_struct(WATL_LexInfo) {
|
||||
WATL_LexMsg* msgs;
|
||||
Slice_WATL_Tok toks;
|
||||
WATL_LexStatus signal;
|
||||
byte_pad(4);
|
||||
};
|
||||
typedef def_struct(Opts_watl_lex) {
|
||||
AllocatorInfo ainfo_msgs;
|
||||
@@ -605,6 +639,7 @@ typedef def_struct(Opts_watl_lex) {
|
||||
B8 failon_unsupported_codepoints;
|
||||
B8 failon_pos_untrackable;
|
||||
B8 failon_slice_constraint_fail;
|
||||
byte_pad(5);
|
||||
};
|
||||
void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts);
|
||||
WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex* opts);
|
||||
@@ -622,23 +657,24 @@ typedef def_struct(WATL_ParseMsg) {
|
||||
WATL_Pos pos;
|
||||
};
|
||||
typedef def_enum(U32, WATL_ParseStatus) {
|
||||
WATL_ParseStatus_MemFail_Alloc = (1 << 0),
|
||||
WATL_ParseStatus_MemFail_SliceConstraintFail = (1 << 1),
|
||||
WATL_ParseStatus_PosUntrackable = (1 << 2),
|
||||
WATL_ParseStatus_UnsupportedTokens = (1 << 3),
|
||||
WATL_ParseStatus_MessageOverflow = (1 << 4),
|
||||
WATL_ParseStatus_MemFail_SliceConstraintFail = (1 << 0),
|
||||
// WATL_ParseStatus_PosUntrackable = (1 << 1),
|
||||
// WATL_ParseStatus_UnsupportedTokens = (1 << 2),
|
||||
// WATL_ParseStatus_MessageOverflow = (1 << 3),
|
||||
};
|
||||
typedef def_struct(WATL_ParseInfo) {
|
||||
Slice_WATL_Line lines;
|
||||
WATL_ParseMsg* msgs;
|
||||
WATL_ParseStatus signal;
|
||||
byte_pad(4);
|
||||
};
|
||||
typedef def_struct(Opts_watl_parse) {
|
||||
AllocatorInfo ainfo_msgs;
|
||||
AllocatorInfo ainfo_nodes;
|
||||
AllocatorInfo ainfo_lines;
|
||||
Str8Cache* str_cache;
|
||||
B8 failon_slice_constraint_fail;
|
||||
B32 failon_slice_constraint_fail;
|
||||
byte_pad(4);
|
||||
};
|
||||
void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse* opts);
|
||||
WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse* opts);
|
||||
@@ -657,23 +693,28 @@ void* __cdecl memcpy (void* _Dst, void const* _Src, USIZE _Size);
|
||||
void* __cdecl memmove(void* _Dst, void const* _Src, USIZE _Size);
|
||||
void* __cdecl memset (void* _Dst, int _Val, USIZE _Size);
|
||||
|
||||
inline
|
||||
SSIZE align_pow2(SSIZE x, SSIZE b) {
|
||||
assert(b != 0);
|
||||
assert((b & (b - 1)) == 0); // Check power of 2
|
||||
return ((x + b - 1) & (~(b - 1)));
|
||||
}
|
||||
|
||||
inline
|
||||
void* memory_copy(void* restrict dest, void const* restrict src, USIZE length) {
|
||||
if (dest == nullptr || src == nullptr || length == 0) { return nullptr; }
|
||||
if (dest == nullptr || src == nullptr) { return nullptr; }
|
||||
memcpy(dest, src, length);
|
||||
return dest;
|
||||
}
|
||||
inline
|
||||
void* memory_copy_overlapping(void* restrict dest, void const* restrict src, USIZE length) {
|
||||
if (dest == nullptr || src == nullptr || length == 0) { return nullptr; }
|
||||
if (dest == nullptr || src == nullptr) { return nullptr; }
|
||||
memmove(dest, src, length);
|
||||
return dest;
|
||||
}
|
||||
inline
|
||||
B32 memory_zero(void* dest, USIZE length) {
|
||||
if (dest == nullptr || length <= 0) {
|
||||
return false;
|
||||
}
|
||||
if (dest == nullptr) return false;
|
||||
memset((unsigned char*)dest, 0, length);
|
||||
return true;
|
||||
}
|
||||
@@ -719,7 +760,7 @@ AllocatorSP mem_save_point(AllocatorInfo ainfo) {
|
||||
assert(ainfo.proc != nullptr);
|
||||
AllocatorProc_Out out;
|
||||
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_SavePoint}, & out);
|
||||
return * cast(AllocatorSP*, & out.allocation);
|
||||
return out.save_point;
|
||||
}
|
||||
|
||||
inline
|
||||
@@ -812,14 +853,14 @@ Slice_Byte farena__push(FArena* arena, SSIZE amount, SSIZE type_width, Opts_fare
|
||||
inline void farena_reset(FArena* arena) { arena->used = 0; }
|
||||
inline
|
||||
void farena_rewind(FArena* arena, AllocatorSP save_point) {
|
||||
assert(save_point.type_sig == farena_allocator_proc);
|
||||
assert(save_point.type_sig == & farena_allocator_proc);
|
||||
Byte* end = cast(Byte*, cast(SSIZE, arena->start) + arena->used);
|
||||
assert_bounds(save_point.slot, arena->start, end);
|
||||
arena->used -= save_point.slot - cast(SSIZE, arena->start);
|
||||
}
|
||||
inline
|
||||
AllocatorSP farena_save (FArena arena) {
|
||||
AllocatorSP sp = { .type_sig = farena_allocator_proc, .slot = cast(SSIZE, arena.used) };
|
||||
AllocatorSP sp = { .type_sig = & farena_allocator_proc, .slot = cast(SSIZE, arena.used) };
|
||||
return sp;
|
||||
}
|
||||
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||
@@ -872,6 +913,8 @@ void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||
#pragma endregion FArena
|
||||
|
||||
#pragma region OS
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4820)
|
||||
#pragma comment(lib, "Kernel32.lib")
|
||||
#pragma comment(lib, "Advapi32.lib")
|
||||
#define MS_INVALID_HANDLE_VALUE ((MS_HANDLE)(__int64)-1)
|
||||
@@ -919,16 +962,17 @@ __declspec(dllimport) MS_BOOL __stdcall LookupPrivilegeValueW(MS_LPWSTR lpSyst
|
||||
__declspec(dllimport) MS_BOOL __stdcall OpenProcessToken(MS_HANDLE ProcessHandle, MS_DWORD DesiredAccess, MS_PHANDLE TokenHandle);
|
||||
__declspec(dllimport) MS_LPVOID __stdcall VirtualAlloc(MS_LPVOID lpAddress, USIZE dwSize, MS_DWORD flAllocationType, MS_DWORD flProtect);
|
||||
__declspec(dllimport) MS_BOOL __stdcall VirtualFree (MS_LPVOID lpAddress, USIZE dwSize, MS_DWORD dwFreeType);
|
||||
#pragma warning(pop)
|
||||
|
||||
typedef def_struct(OS_Windows_State) {
|
||||
OS_SystemInfo system_info;
|
||||
};
|
||||
global OS_Windows_State os__windows_info;
|
||||
|
||||
OS_SystemInfo* os_system_info() {
|
||||
OS_SystemInfo* os_system_info(void) {
|
||||
return & os__windows_info.system_info;
|
||||
}
|
||||
void os__enable_large_pages() {
|
||||
void os__enable_large_pages(void) {
|
||||
MS_HANDLE token;
|
||||
if (OpenProcessToken(GetCurrentProcess(), MS_TOKEN_ADJUST_PRIVILEGES | MS_TOKEN_QUERY, &token))
|
||||
{
|
||||
@@ -945,7 +989,7 @@ void os__enable_large_pages() {
|
||||
}
|
||||
}
|
||||
inline
|
||||
void os_init() {
|
||||
void os_init(void) {
|
||||
os__enable_large_pages();
|
||||
OS_SystemInfo* info = & os__windows_info.system_info;
|
||||
info->target_page_size = (SSIZE)GetLargePageMinimum();
|
||||
@@ -1010,21 +1054,21 @@ Slice_Byte varena__push(VArena* vm, SSIZE amount, SSIZE type_width, Opts_varena*
|
||||
if (next_commit_size) {
|
||||
Byte* next_commit_start = cast(Byte*, cast(SSIZE, vm) + vm->committed);
|
||||
B32 no_large_pages = (vm->flags & VArenaFlag_NoLargePages) != 0;
|
||||
B32 commit_result = os_vmem_commit(next_commit_start, next_commit_size);
|
||||
B32 commit_result = os_vmem_commit(next_commit_start, next_commit_size, .no_large_pages = no_large_pages);
|
||||
if (commit_result == false) {
|
||||
return (Slice_Byte){0};
|
||||
}
|
||||
vm->committed += next_commit_size;
|
||||
}
|
||||
}
|
||||
vm->commit_used += to_be_used;
|
||||
vm->commit_used = to_be_used;
|
||||
return (Slice_Byte){.ptr = cast(Byte*, current_offset), .len = requested_size};
|
||||
}
|
||||
inline void varena_release(VArena* arena) { os_vmem_release(arena, arena->reserve); }
|
||||
inline
|
||||
void varena_rewind(VArena* vm, AllocatorSP sp) {
|
||||
assert(vm != nullptr);
|
||||
assert(sp.type_sig == varena_allocator_proc);
|
||||
assert(sp.type_sig == & varena_allocator_proc);
|
||||
vm->commit_used = sp.slot;
|
||||
}
|
||||
inline AllocatorSP varena_save(VArena* vm) { return (AllocatorSP){varena_allocator_proc, vm->commit_used}; }
|
||||
@@ -1048,7 +1092,10 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||
case AllocatorOp_Grow_NoZero:
|
||||
case AllocatorOp_Grow: {
|
||||
SSIZE grow_amount = in.requested_size - in.old_allocation.len;
|
||||
assert(grow_amount >= 0);
|
||||
if (grow_amount == 0) {
|
||||
out->allocation = in.old_allocation;
|
||||
return;
|
||||
}
|
||||
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
||||
assert(in.old_allocation.ptr == cast(Byte*, current_offset));
|
||||
Slice_Byte allocation = varena_push_array(vm, Byte, grow_amount, .alignment = in.alignment);
|
||||
@@ -1059,8 +1106,11 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||
break;
|
||||
case AllocatorOp_Shrink: {
|
||||
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
||||
SSIZE shrink_amount = in.old_allocation.len - in.requested_size;
|
||||
assert(shrink_amount >= 0);
|
||||
SSIZE shrink_amount = in.old_allocation.len - in.requested_size;
|
||||
if (shrink_amount < 0) {
|
||||
out->allocation = in.old_allocation;
|
||||
return;
|
||||
}
|
||||
assert(in.old_allocation.ptr == cast(Byte*, current_offset));
|
||||
vm->commit_used -= shrink_amount;
|
||||
out->allocation = (Slice_Byte){ in.old_allocation.ptr, in.requested_size };
|
||||
@@ -1154,14 +1204,13 @@ void arena_rewind(Arena* arena, AllocatorSP save_point) {
|
||||
assert(save_point.type_sig == arena_allocator_proc);
|
||||
SSIZE header_size = align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT);
|
||||
Arena* curr = arena->current;
|
||||
VArena* backing = arena->backing;
|
||||
SSIZE big_pos = clamp_bot(header_size, save_point.slot);
|
||||
for (Arena* prev = nullptr; curr->base_pos >= big_pos; curr = prev) {
|
||||
prev = curr->prev;
|
||||
varena_release(curr->backing);
|
||||
}
|
||||
arena->current = curr;
|
||||
SSIZE new_pos = big_pos - curr->pos;
|
||||
SSIZE new_pos = big_pos - curr->base_pos;
|
||||
assert(new_pos <= curr->pos);
|
||||
curr->pos = new_pos;
|
||||
varena_rewind(curr->backing, (AllocatorSP){varena_allocator_proc, curr->pos});
|
||||
@@ -1218,7 +1267,7 @@ SSIZE kt1l__populate_slice_a2(KT1L_Byte* kt, KT1L_Info info, Slice_Byte values,
|
||||
* kt = alloc_slice(info.backing, Byte, info.slot_size * num_values );
|
||||
slice_assert(* kt);
|
||||
SSIZE num_bytes = 0;
|
||||
for (range_iter(U32, iter, 0, <, num_values)) {
|
||||
for (range_iter(SSIZE, iter, 0, <, num_values)) {
|
||||
SSIZE slot_offset = iter.cursor * info.slot_size;
|
||||
Byte* slot_cursor = & kt->ptr[slot_offset];
|
||||
Byte* a2_cursor = & values.ptr[iter.cursor * info.type_width * 2];
|
||||
@@ -1229,7 +1278,7 @@ SSIZE kt1l__populate_slice_a2(KT1L_Byte* kt, KT1L_Info info, Slice_Byte values,
|
||||
Slice_Byte a2_key = { a2_cursor, info.type_width };
|
||||
Slice_Byte a2_value = { a2_cursor + info.type_width, info.type_width };
|
||||
slice_copy(slot_value, a2_value);
|
||||
hash64_djb8(slot_key, a2_key);
|
||||
* slot_key = 0; hash64_djb8(slot_key, a2_key);
|
||||
|
||||
num_bytes += slot_value.len;
|
||||
}
|
||||
@@ -1294,10 +1343,10 @@ Slice_Byte kt1cx__get(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta m) {
|
||||
return slot_value;
|
||||
}
|
||||
}
|
||||
Byte* next = slot_cursor + m.cell_next_offset;
|
||||
if (next != nullptr) {
|
||||
slots.ptr = next;
|
||||
slot_cursor = next;
|
||||
Byte* slot_next = slot_cursor + m.cell_next_offset;
|
||||
if (slot_next != nullptr) {
|
||||
slots.ptr = slot_next;
|
||||
slot_cursor = slot_next;
|
||||
goto process_slots;
|
||||
}
|
||||
else {
|
||||
@@ -1305,9 +1354,9 @@ Slice_Byte kt1cx__get(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta m) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Slice_Byte kt1cx__set(KT1CX_Byte* kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta m) {
|
||||
U64 hash_index = kt1cx__slot_id(* kt, key, m);
|
||||
Slice_Byte cell = { & kt->table.ptr[hash_index], m.cell_size};
|
||||
Slice_Byte kt1cx__set(KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta m) {
|
||||
U64 hash_index = kt1cx__slot_id(kt, key, m);
|
||||
Slice_Byte cell = { & kt.table.ptr[hash_index], m.cell_size};
|
||||
{
|
||||
Slice_Byte slots = {cell.ptr, m.cell_depth * m.slot_size};
|
||||
Byte* slot_cursor = slots.ptr;
|
||||
@@ -1325,19 +1374,21 @@ Slice_Byte kt1cx__set(KT1CX_Byte* kt, U64 key, Slice_Byte value, AllocatorInfo b
|
||||
return slot_value;
|
||||
}
|
||||
}
|
||||
Byte* next = slot_cursor + m.cell_next_offset;
|
||||
if (next != nullptr) {
|
||||
slots.ptr = next;
|
||||
slot_cursor = next;
|
||||
KT1CX_Byte_Cell curr_cell = { slot_cursor + m.cell_next_offset };
|
||||
if ( curr_cell.next != nullptr) {
|
||||
slots.ptr = curr_cell.next;
|
||||
slot_cursor = curr_cell.next;
|
||||
cell.ptr = curr_cell.next;
|
||||
goto process_slots;
|
||||
}
|
||||
else {
|
||||
cell = mem_alloc(backing_cells, m.cell_size);
|
||||
KT1CX_Byte_Slot* slot = cast(KT1CX_Byte_Slot*, cell.ptr + m.slot_key_offset);
|
||||
Slice_Byte new_cell = mem_alloc(backing_cells, m.cell_size);
|
||||
curr_cell.next = new_cell.ptr;
|
||||
KT1CX_Byte_Slot* slot = cast(KT1CX_Byte_Slot*, new_cell.ptr + m.slot_key_offset);
|
||||
slot->occupied = true;
|
||||
slot->key = key;
|
||||
Slice_Byte slot_value = {cell.ptr, m.type_width};
|
||||
return slot_value;
|
||||
Slice_Byte slot_value = {new_cell.ptr, m.type_width};
|
||||
return slot_value;
|
||||
}
|
||||
}
|
||||
assert_msg(false, "impossible path");
|
||||
@@ -1348,10 +1399,10 @@ Slice_Byte kt1cx__set(KT1CX_Byte* kt, U64 key, Slice_Byte value, AllocatorInfo b
|
||||
#pragma region String Operations
|
||||
inline
|
||||
char* str8_to_cstr_capped(Str8 content, Slice_Byte mem) {
|
||||
assert(mem.len > content.len);
|
||||
memory_copy(mem.ptr, content.ptr, content.len);
|
||||
mem.ptr[content.len] = '\0';
|
||||
return mem.ptr;
|
||||
SSIZE copy_len = min(content.len, mem.len - 1);
|
||||
memory_copy(mem.ptr, content.ptr, copy_len);
|
||||
mem.ptr[copy_len] = '\0';
|
||||
return cast(char*, mem.ptr);
|
||||
}
|
||||
Str8 str8_from_u32(AllocatorInfo ainfo, U32 num, U32 radix, U8 min_digits, U8 digit_group_separator)
|
||||
{
|
||||
@@ -1402,7 +1453,7 @@ Str8 str8_from_u32(AllocatorInfo ainfo, U32 num, U32 radix, U8 min_digits, U8 di
|
||||
{
|
||||
U32 num_reduce = num;
|
||||
U32 digits_until_separator = digit_group_size;
|
||||
for (U32 idx = 0; idx < result.len; idx += 1)
|
||||
for (SSIZE idx = 0; idx < result.len; idx += 1)
|
||||
{
|
||||
SSIZE separator_pos = result.len - idx - 1;
|
||||
if (digits_until_separator == 0 && digit_group_separator != 0) {
|
||||
@@ -1410,7 +1461,7 @@ Str8 str8_from_u32(AllocatorInfo ainfo, U32 num, U32 radix, U8 min_digits, U8 di
|
||||
digits_until_separator = digit_group_size + 1;
|
||||
}
|
||||
else {
|
||||
result.ptr[separator_pos] = char_to_lower(integer_symbols(num_reduce % radix));
|
||||
result.ptr[separator_pos] = char_to_lower(integer_symbols(cast(U8, num_reduce % radix)));
|
||||
num_reduce /= radix;
|
||||
}
|
||||
digits_until_separator -= 1;
|
||||
@@ -1455,9 +1506,15 @@ Str8 str8__fmt_kt1l(AllocatorInfo ainfo, Slice_Byte buffer, KT1L_Str8 table, Str
|
||||
{
|
||||
UTF8* cursor_potential_token = cursor_fmt + 1;
|
||||
SSIZE potential_token_length = 0;
|
||||
while (* (cursor_potential_token + potential_token_length) != '>') {
|
||||
B32 fmt_overflow = false;
|
||||
for (;;) {
|
||||
UTF8* cursor = cursor_potential_token + potential_token_length;
|
||||
fmt_overflow = cursor >= slice_end(fmt_template);
|
||||
B32 found_terminator = * (cursor_potential_token + potential_token_length) != '>';
|
||||
if (fmt_overflow || found_terminator) { break; }
|
||||
++ potential_token_length;
|
||||
}
|
||||
if (fmt_overflow) continue;
|
||||
// Hashing the potential token and cross checking it with our token table
|
||||
U64 key = 0; hash64_djb8(& key, (Slice_Byte){ cast(void*, cursor_fmt + 1), potential_token_length});
|
||||
Str8* value = nullptr;
|
||||
@@ -1475,8 +1532,8 @@ Str8 str8__fmt_kt1l(AllocatorInfo ainfo, Slice_Byte buffer, KT1L_Str8 table, Str
|
||||
if (ainfo.proc != nullptr && (buffer_remaining - potential_token_length) <= 0) {
|
||||
buffer = mem_grow(ainfo, buffer, buffer.len + potential_token_length);
|
||||
}
|
||||
SSIZE left = value->len;
|
||||
char const* cursor_value = value->ptr;
|
||||
SSIZE left = value->len;
|
||||
U8* cursor_value = value->ptr;
|
||||
|
||||
while (left && buffer_remaining) {
|
||||
* cursor_buffer = * cursor_value;
|
||||
@@ -1513,7 +1570,7 @@ Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8
|
||||
Str8 str8__fmt(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 buf_mem[kilo(128)];
|
||||
KT1L_Str8 kt = {0}; SSIZE num_bytes = kt1l_populate_slice_a2(Str8, kt, ainfo_farena(tbl_arena), *entries );
|
||||
KT1L_Str8 kt = {0}; kt1l_populate_slice_a2(Str8, kt, ainfo_farena(tbl_arena), *entries );
|
||||
Str8 result = str8__fmt_kt1l((AllocatorInfo){0}, slice_fmem(buf_mem), kt, fmt_template);
|
||||
return result;
|
||||
}
|
||||
@@ -1547,7 +1604,8 @@ void str8cache__init(Str8Cache* cache, Opts_str8cache_init* opts) {
|
||||
inline Str8Cache str8cache__make(Opts_str8cache_init* opts) { Str8Cache cache; str8cache__init(& cache, opts); return cache; }
|
||||
inline
|
||||
void str8cache_clear(KT1CX_Str8 kt) {
|
||||
kt1cx__clear(pcast(KT1CX_Byte, kt), (KT1CX_ByteMeta){
|
||||
kt1cx_assert(kt);
|
||||
kt1cx__clear(kt1cx_byte(kt), (KT1CX_ByteMeta){
|
||||
.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),
|
||||
@@ -1559,7 +1617,8 @@ void str8cache_clear(KT1CX_Str8 kt) {
|
||||
}
|
||||
inline
|
||||
Str8 str8cache_get(KT1CX_Str8 kt, U64 key) {
|
||||
Slice_Byte result = kt1cx__get(pcast(KT1CX_Byte, kt), key
|
||||
kt1cx_assert(kt);
|
||||
Slice_Byte result = kt1cx__get(kt1cx_byte(kt), key
|
||||
, (KT1CX_ByteMeta){
|
||||
.slot_size = size_of(KT1CX_Slot_Str8),
|
||||
.slot_key_offset = offset_of(KT1CX_Slot_Str8, key),
|
||||
@@ -1572,12 +1631,12 @@ Str8 str8cache_get(KT1CX_Str8 kt, U64 key) {
|
||||
return pcast(Str8, result);
|
||||
}
|
||||
inline
|
||||
Str8 str8cache_set(KT1CX_Str8* kt, U64 key, Str8 value, AllocatorInfo str_reserve, AllocatorInfo backing_cells) {
|
||||
assert(kt != nullptr);
|
||||
Str8 str8cache_set(KT1CX_Str8 kt, U64 key, Str8 value, AllocatorInfo str_reserve, AllocatorInfo backing_cells) {
|
||||
kt1cx_assert(kt);
|
||||
slice_assert(value);
|
||||
assert(str_reserve.proc != nullptr);
|
||||
assert(backing_cells.proc != nullptr);
|
||||
slice_assert(value);
|
||||
Slice_Byte entry = kt1cx__set(pcast(KT1CX_Byte*, kt), key, slice_byte(value), backing_cells, (KT1CX_ByteMeta){
|
||||
Slice_Byte entry = kt1cx__set(kt1cx_byte(kt), key, slice_byte(value), backing_cells, (KT1CX_ByteMeta){
|
||||
.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),
|
||||
@@ -1597,8 +1656,9 @@ Str8 str8cache_set(KT1CX_Str8* kt, U64 key, Str8 value, AllocatorInfo str_reserv
|
||||
}
|
||||
inline
|
||||
Str8 cache_str8(Str8Cache* cache, Str8 str) {
|
||||
assert(cache != nullptr);
|
||||
U64 key = 0; hash64_djb8(& key, slice_byte(str));
|
||||
Str8 result = str8cache_set(& cache->kt, key, str, cache->str_reserve, cache->cell_reserve);
|
||||
Str8 result = str8cache_set(cache->kt, key, str, cache->str_reserve, cache->cell_reserve);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1618,15 +1678,18 @@ void str8gen_append_str8(Str8Gen* gen, Str8 str){
|
||||
Slice_Byte result = mem_grow(gen->backing, str8gen_slice_byte(* gen), str.len + gen->len);
|
||||
slice_assert(result);
|
||||
Slice_Byte to_copy = { result.ptr + gen->len, result.len - gen->len };
|
||||
slice_copy(to_copy, str);
|
||||
slice_copy(to_copy, slice_byte(str));
|
||||
gen->ptr = cast(UTF8*, result.ptr); gen->len = result.len;
|
||||
}
|
||||
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));
|
||||
KT1L_Str8 kt = {0}; SSIZE num_bytes = kt1l_populate_slice_a2(Str8, kt, ainfo_farena(tbl_arena), *entries );
|
||||
KT1L_Str8 kt = {0}; kt1l_populate_slice_a2(Str8, kt, ainfo_farena(tbl_arena), *entries );
|
||||
Slice_Byte buffer = { gen->ptr + gen->len, gen->cap - gen->len };
|
||||
if (buffer.len < kilo(16)) {
|
||||
Slice_Byte result = mem_grow(gen->backing, str8gen_slice_byte(* gen), kilo(16) + gen->cap );
|
||||
slice_assert(result);
|
||||
gen->ptr = result.ptr;
|
||||
gen->cap = result.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);
|
||||
@@ -1681,7 +1744,7 @@ void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_read_file_conten
|
||||
// Backing is required at this point
|
||||
assert(opts.backing.proc != nullptr);
|
||||
// This will limit a path for V1 to be 32kb worth of codepoints.
|
||||
local_persist U8 scratch[kilo(32)];
|
||||
local_persist U8 scratch[kilo(64)];
|
||||
char const* path_cstr = str8_to_cstr_capped(path, slice_fmem(scratch) );
|
||||
MS_HANDLE id_file = CreateFileA(
|
||||
path_cstr,
|
||||
@@ -1718,7 +1781,7 @@ void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_read_file_conten
|
||||
MS_BOOL read_result = ReadFile(
|
||||
id_file,
|
||||
buffer.ptr,
|
||||
file_size.QuadPart,
|
||||
cast(MS_DWORD, file_size.QuadPart),
|
||||
& amount_read,
|
||||
nullptr
|
||||
);
|
||||
@@ -1736,7 +1799,7 @@ void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_read_file_conten
|
||||
void file_write_str8(Str8 path, Str8 content)
|
||||
{
|
||||
slice_assert(path);
|
||||
Byte scratch[kilo(16)] = {0};
|
||||
Byte scratch[kilo(64)] = {0};
|
||||
char const* path_cstr = str8_to_cstr_capped(path, slice_fmem(scratch));
|
||||
MS_HANDLE id_file = CreateFileA(
|
||||
path_cstr,
|
||||
@@ -1756,7 +1819,7 @@ void file_write_str8(Str8 path, Str8 content)
|
||||
MS_DWORD bytes_written = 0;
|
||||
B32 status = WriteFile(id_file
|
||||
, cast(void*, content.ptr)
|
||||
, cast(USIZE, content.len)
|
||||
, cast(MS_DWORD, content.len)
|
||||
, & bytes_written
|
||||
, nullptr
|
||||
);
|
||||
@@ -1825,8 +1888,8 @@ void assert_handler( char const* condition, char const* file, char const* functi
|
||||
#pragma region WATL
|
||||
void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
||||
{
|
||||
if (source.len == 0) { return; }
|
||||
assert(info != nullptr);
|
||||
slice_assert(source);
|
||||
assert(opts != nullptr);
|
||||
assert(opts->ainfo_msgs.proc != nullptr);
|
||||
assert(opts->ainfo_toks.proc != nullptr);
|
||||
@@ -1835,7 +1898,7 @@ void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
||||
|
||||
UTF8* end = source.ptr + source.len;
|
||||
UTF8* cursor = source.ptr;
|
||||
UTF8* prev = source.ptr;
|
||||
UTF8* prev = source.ptr - 1;
|
||||
UTF8 code = * cursor;
|
||||
B32 was_formatting = true;
|
||||
WATL_Tok* tok = nullptr;
|
||||
@@ -1895,35 +1958,38 @@ void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
||||
if (num_bytes > start_snapshot.left) {
|
||||
info->signal |= WATL_LexStatus_MemFail_SliceConstraintFail;
|
||||
WATL_LexMsg* msg = alloc_type(opts->ainfo_msgs, WATL_LexMsg);
|
||||
assert(msg != nullptr);
|
||||
msg->pos = (WATL_Pos){ -1, -1 };
|
||||
msg->tok = tok;
|
||||
msg->content = lit("Token slice allocation was not contiguous");
|
||||
sll_queue_push_n(info->msgs, msg_last, msg, next);
|
||||
assert(opts->failon_slice_constraint_fail == false);
|
||||
}
|
||||
assert(tok != nullptr);
|
||||
assert(num > 0);
|
||||
info->toks.ptr = tok - num;
|
||||
info->toks.len = num;
|
||||
}
|
||||
WATL_LexInfo watl__lex(Str8 source, Opts_watl_lex* opts) { WATL_LexInfo info; api_watl_lex(& info, source, opts); return info; }
|
||||
WATL_LexInfo watl__lex(Str8 source, Opts_watl_lex* opts) { WATL_LexInfo info = {0}; api_watl_lex(& info, source, opts); return info; }
|
||||
|
||||
Str8 watl_tok_str8(Slice_WATL_Tok toks, WATL_Tok* tok) {
|
||||
WATL_Tok* next = tok + 1;
|
||||
USIZE start = cast(USIZE, toks.ptr->code);
|
||||
USIZE curr = cast(USIZE, tok->code);
|
||||
USIZE offset = curr - start;
|
||||
SSIZE left = toks.len - offset;
|
||||
B32 last_tok = (start + toks.len) == (curr + left);
|
||||
Str8 str8_from_watl_tok(Slice_WATL_Tok toks, WATL_Tok* tok) {
|
||||
SSIZE start = cast(SSIZE, toks.ptr->code);
|
||||
SSIZE curr = cast(SSIZE, tok->code);
|
||||
SSIZE offset = curr - start;
|
||||
SSIZE left = cast(SSIZE, toks.ptr + toks.len) - offset;
|
||||
B32 last_tok = tok == & toks.ptr[toks.len - 1]; // Check to see if this token's end is also the end of the slice:
|
||||
Str8 text = {0};
|
||||
text.ptr = tok->code;
|
||||
text.len = next > (toks.ptr + toks.len) ?
|
||||
text.len = last_tok ?
|
||||
left
|
||||
// Othwerise its the last minus the curr.
|
||||
: cast(SSIZE, next->code - tok->code);
|
||||
// Othwerise its the next minus the curr.
|
||||
: cast(SSIZE, (tok + 1)->code - tok->code);
|
||||
return text;
|
||||
}
|
||||
|
||||
void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse* opts)
|
||||
{
|
||||
if (tokens.len == 0) { return; }
|
||||
assert(opts != nullptr);
|
||||
assert(opts->ainfo_lines.proc != nullptr);
|
||||
assert(opts->ainfo_msgs.proc != nullptr);
|
||||
@@ -1946,12 +2012,12 @@ void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse
|
||||
case WATL_Tok_LineFeed:
|
||||
{
|
||||
AllocatorProc_Out end_nodes_snapshot; { opts->ainfo_nodes.proc((AllocatorProc_In){.op = AllocatorOp_Query}, & end_nodes_snapshot); }
|
||||
SSIZE distance_nodes = end_nodes_snapshot.left - end_nodes_snapshot.save_point.slot;
|
||||
SSIZE distance_nodes = end_nodes_snapshot.save_point.slot - start_nodes_snapshot.save_point.slot;
|
||||
if (distance_nodes > start_lines_snapshot.left) {
|
||||
info->signal |= WATL_ParseStatus_MemFail_SliceConstraintFail;
|
||||
WATL_ParseMsg* msg = alloc_type(opts->ainfo_msgs, WATL_ParseMsg);
|
||||
msg->content = lit("Nodes slice allocation was not contiguous");
|
||||
msg->pos = (WATL_Pos){info->lines.len, line->len};
|
||||
msg->pos = (WATL_Pos){cast(S32, info->lines.len), cast(S32, line->len)};
|
||||
msg->line = line;
|
||||
msg->tok = token;
|
||||
sll_queue_push_n(info->msgs, msg_last, msg, next);
|
||||
@@ -1969,7 +2035,7 @@ void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Str8 tok_str = watl_tok_str8(tokens, token);
|
||||
Str8 tok_str = str8_from_watl_tok(tokens, token);
|
||||
* curr = cache_str8(opts->str_cache, tok_str);
|
||||
curr = alloc_type(opts->ainfo_nodes, WATL_Node);
|
||||
* curr = (WATL_Node){0};
|
||||
@@ -1978,7 +2044,7 @@ void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse
|
||||
}
|
||||
AllocatorProc_Out end_lines_snapshot; { opts->ainfo_lines.proc((AllocatorProc_In){.op = AllocatorOp_Query}, & end_lines_snapshot); }
|
||||
|
||||
SSIZE distance_lines = end_lines_snapshot.left - start_lines_snapshot.save_point.slot;
|
||||
SSIZE distance_lines = end_lines_snapshot.save_point.slot - start_lines_snapshot.save_point.slot;
|
||||
if (distance_lines > start_lines_snapshot.left) {
|
||||
info->signal |= WATL_ParseStatus_MemFail_SliceConstraintFail;
|
||||
WATL_ParseMsg* msg = alloc_type(opts->ainfo_msgs, WATL_ParseMsg);
|
||||
@@ -1989,7 +2055,7 @@ void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse
|
||||
return;
|
||||
}
|
||||
}
|
||||
WATL_ParseInfo watl__parse(Slice_WATL_Tok tokens, Opts_watl_parse* opts) { WATL_ParseInfo info; api_watl_parse(& info, tokens, opts); return info; }
|
||||
WATL_ParseInfo watl__parse(Slice_WATL_Tok tokens, Opts_watl_parse* opts) { WATL_ParseInfo info = {0}; api_watl_parse(& info, tokens, opts); return info; }
|
||||
|
||||
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
||||
{
|
||||
@@ -2002,7 +2068,7 @@ Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
||||
#define fmt_entry(label, value) { lit(label), value }
|
||||
++ line_num;
|
||||
Str8 str_line_num = str8_from_u32(sinfo, line_num, 10, 0, 0);
|
||||
Str8 str_chunk_num = str8_from_u32(sinfo, line->len, 10, 0, 0);
|
||||
Str8 str_chunk_num = str8_from_u32(sinfo, cast(U32, line->len), 10, 0, 0);
|
||||
str8gen_append_fmt(& result, "Line <line_num> - Chunks <chunk_num>:\n"
|
||||
, fmt_entry("line_num", str_line_num)
|
||||
, fmt_entry("chunk_num", str_chunk_num)
|
||||
@@ -2016,7 +2082,7 @@ Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
||||
case WATL_Tok_Tab: id = lit("Tab"); break;
|
||||
default: id = lit("Visible"); break;
|
||||
}
|
||||
Str8 str_chunk_len = str8_from_u32(sinfo, chunk->len, 10, 0, 0);
|
||||
Str8 str_chunk_len = str8_from_u32(sinfo, cast(U32, chunk->len), 10, 0, 0);
|
||||
str8gen_append_fmt(& result, "\t<id>(<size>): '<chunk>'\n"
|
||||
, fmt_entry("id", id)
|
||||
, fmt_entry("size", str_chunk_len)
|
||||
@@ -2024,7 +2090,6 @@ Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
||||
);
|
||||
}
|
||||
farena_reset(& sarena);
|
||||
#undef push_str8_u32
|
||||
#undef fmt_entry_u32
|
||||
}
|
||||
return (Str8){ result.ptr, result.len };
|
||||
@@ -2033,12 +2098,15 @@ Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
||||
|
||||
#pragma endregion Implementation
|
||||
|
||||
int main()
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4101)
|
||||
int main(void)
|
||||
{
|
||||
os_init();
|
||||
|
||||
VArena* 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));
|
||||
slice_assert(file.content);
|
||||
|
||||
Arena* a_msgs = arena_make();
|
||||
Arena* a_toks = arena_make();
|
||||
@@ -2046,14 +2114,14 @@ int main()
|
||||
.ainfo_msgs = ainfo_arena(a_msgs),
|
||||
.ainfo_toks = ainfo_arena(a_toks),
|
||||
);
|
||||
assert(lex_res.signal & WATL_LexStatus_MemFail_SliceConstraintFail);
|
||||
assert((lex_res.signal & WATL_LexStatus_MemFail_SliceConstraintFail) == 0);
|
||||
|
||||
Arena* str_cache_kt1_ainfo = arena_make();
|
||||
Str8Cache str_cache = str8cache_make(
|
||||
.str_reserve = ainfo_arena(arena_make()),
|
||||
.cell_reserve = ainfo_arena(str_cache_kt1_ainfo),
|
||||
.tbl_backing = ainfo_arena(str_cache_kt1_ainfo),
|
||||
.cell_pool_amnt = kilo(4),
|
||||
.cell_pool_size = kilo(4),
|
||||
.table_size = kilo(32),
|
||||
);
|
||||
|
||||
@@ -2064,10 +2132,11 @@ int main()
|
||||
.ainfo_lines = ainfo_arena(a_lines),
|
||||
.str_cache = & str_cache
|
||||
);
|
||||
assert(parse_res.signal & WATL_ParseStatus_MemFail_SliceConstraintFail);
|
||||
assert((parse_res.signal & WATL_ParseStatus_MemFail_SliceConstraintFail) == 0);
|
||||
|
||||
arena_reset(a_msgs);
|
||||
arena_reset(a_toks);
|
||||
Str8 listing = watl_dump_listing(ainfo_arena(a_msgs), parse_res.lines);
|
||||
return 0;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
@@ -11,6 +11,7 @@ if ($IsWindows) {
|
||||
# https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170
|
||||
$flag_all_c = '/TC'
|
||||
$flag_c11 = '/std:c11'
|
||||
$flag_c23 = '/std:c23'
|
||||
$flag_all_cpp = '/TP'
|
||||
$flag_compile = '/c'
|
||||
$flag_charset_utf8 = '/utf-8'
|
||||
@@ -84,7 +85,14 @@ $compiler_args += $flag_RTTI_disabled
|
||||
$compiler_args += $flag_preprocess_conform
|
||||
$compiler_args += $flag_sanitize_address
|
||||
|
||||
$compiler_args += $flag_wall
|
||||
|
||||
# Set charset encoding for both execution and source to UTF-8
|
||||
$compiler_args += $flag_charset_utf8
|
||||
|
||||
# Specifing output pathing
|
||||
$compiler_args += ( $flag_path_interm + $path_build + '\' )
|
||||
$compiler_args += ( $flag_path_output + $path_build + '\' )
|
||||
|
||||
# Dump preprocess file
|
||||
if ($false) {
|
||||
@@ -95,15 +103,12 @@ if ($false) {
|
||||
# Diagnostic logging
|
||||
$compiler_args += $flag_full_src_path
|
||||
|
||||
# Specifing output pathing
|
||||
$compiler_args += ( $flag_path_interm + $path_build + '\' )
|
||||
$compiler_args += ( $flag_path_output + $path_build + '\' )
|
||||
|
||||
$compiler_args += $flag_no_optimization
|
||||
$compiler_args += $flag_optimize_intrinsics
|
||||
# $compiler_args += $flag_no_optimization
|
||||
|
||||
# Debug setup
|
||||
$compiler_args += $flag_debug
|
||||
$compiler_args += ($flag_define + 'BUILD_DEBUG')
|
||||
$compiler_args += $flag_debug
|
||||
$compiler_args += ( $flag_path_debug + $path_build + '\' )
|
||||
$compiler_args += $flag_link_win_rt_static_debug
|
||||
|
||||
@@ -118,9 +123,6 @@ $compiler_args += $flag_compile, $unit
|
||||
$compiler_args | ForEach-Object { Write-Host $_ }
|
||||
write-host
|
||||
|
||||
# $compiler_args += ( $flag_define + 'DEMO_STR_SLICE' )
|
||||
# $compiler_args += ( $flag_define + 'DEMO__FILE_READ_CONTENTS_V1' )
|
||||
|
||||
# Compile the unit
|
||||
& $compiler $compiler_args
|
||||
|
||||
|
Reference in New Issue
Block a user