mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2025-08-06 07:12:42 -07:00
ready for testing
This commit is contained in:
288
C/watl.v0.msvc.c
288
C/watl.v0.msvc.c
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
WATL Exercise
|
WATL Exercise
|
||||||
Version: 0 (From Scratch, 1-Stage Compilation, Zero-Dependencies)
|
Version: 0 (From Scratch, 1-Stage Compilation, MSVC & WinAPI Only)
|
||||||
Host: Windows 11
|
Host: Windows 11
|
||||||
Toolchain: MSVC 19.43
|
Toolchain: MSVC 19.43
|
||||||
*/
|
*/
|
||||||
@@ -153,19 +153,26 @@ void slice__zero(Slice_Byte mem, SSIZE typewidth);
|
|||||||
|
|
||||||
#define sll_stack_push_n(f, n, next) do { (n)->next = (f); (f) = (n); } while(0)
|
#define sll_stack_push_n(f, n, next) do { (n)->next = (f); (f) = (n); } while(0)
|
||||||
|
|
||||||
#define sll_queue_push_nz(nil, f, l, n, next) \
|
inline void
|
||||||
( \
|
sll__queue_push_nz(
|
||||||
check_nil(nil, f) ? ( \
|
void* nil,
|
||||||
(f) = (l) = (n), \
|
void** f,
|
||||||
set_nil(nil, (n)->next) \
|
void** l, void** l_next,
|
||||||
) \
|
void* n, void** n_next
|
||||||
: ( \
|
|
||||||
(l)->next=(n), \
|
|
||||||
(l) = (n), \
|
|
||||||
set_nil(nil,(n)->next) \
|
|
||||||
) \
|
|
||||||
)
|
)
|
||||||
#define sll_queue_push_n(f, l, n, next) sll_queue_push_nz(0, f, l, n, next)
|
{
|
||||||
|
if (check_nil(nil, *f)) {
|
||||||
|
*f = n;
|
||||||
|
*l = n;
|
||||||
|
*n_next = nil;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*l_next = n;
|
||||||
|
*l = n;
|
||||||
|
*n_next = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define sll_queue_push_n(f, l, n, next) sll__queue_push_nz(0, &f, &l, &l->next, n, &n->next)
|
||||||
#pragma endregion Memory
|
#pragma endregion Memory
|
||||||
|
|
||||||
#pragma region Math
|
#pragma region Math
|
||||||
@@ -549,7 +556,7 @@ inline Str8 str8_from_str8gen(Str8Gen gen) { return (Str8){gen.ptr, gen.len}; }
|
|||||||
void str8gen_append_str8(Str8Gen* gen, Str8 str);
|
void str8gen_append_str8(Str8Gen* gen, Str8 str);
|
||||||
void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* tokens);
|
void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* tokens);
|
||||||
|
|
||||||
#define str8gen_append_fmt(gen, fmt_template, ...) str8gen__append_fmt(gen, fmt_template, slice_from_array(A2_Str8, __VA_ARGS__))
|
#define str8gen_append_fmt(gen, fmt_template, ...) str8gen__append_fmt(gen, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
||||||
#pragma endregion String Operations
|
#pragma endregion String Operations
|
||||||
|
|
||||||
#pragma region File System
|
#pragma region File System
|
||||||
@@ -580,11 +587,11 @@ typedef def_struct(WATL_Tok) {
|
|||||||
};
|
};
|
||||||
typedef def_Slice(WATL_Tok);
|
typedef def_Slice(WATL_Tok);
|
||||||
typedef def_enum(U32, WATL_LexStatus) {
|
typedef def_enum(U32, WATL_LexStatus) {
|
||||||
WATL_LexStatus_MemFail_Alloc,
|
WATL_LexStatus_MemFail_Alloc = (1 << 0),
|
||||||
WATL_LexStatus_MemFail_SliceConstraintFail,
|
WATL_LexStatus_MemFail_SliceConstraintFail = (1 << 1),
|
||||||
WATL_LexStatus_PosUntrackable,
|
WATL_LexStatus_PosUntrackable = (1 << 2),
|
||||||
WATL_LexStatus_UnsupportedCodepoints,
|
WATL_LexStatus_UnsupportedCodepoints = (1 << 3),
|
||||||
WATL_LexStatus_MessageOverflow,
|
WATL_LexStatus_MessageOverflow = (1 << 4),
|
||||||
};
|
};
|
||||||
typedef def_struct(WATL_Pos) {
|
typedef def_struct(WATL_Pos) {
|
||||||
S32 line;
|
S32 line;
|
||||||
@@ -604,10 +611,9 @@ typedef def_struct(WATL_LexInfo) {
|
|||||||
typedef def_struct(Opts_watl_lex) {
|
typedef def_struct(Opts_watl_lex) {
|
||||||
AllocatorInfo ainfo_msgs;
|
AllocatorInfo ainfo_msgs;
|
||||||
AllocatorInfo ainfo_toks;
|
AllocatorInfo ainfo_toks;
|
||||||
S32 max_msgs;
|
B8 failon_unsupported_codepoints;
|
||||||
B8 failon_unsupported_codepoints;
|
B8 failon_pos_untrackable;
|
||||||
B8 failon_pos_untrackable;
|
B8 failon_slice_constraint_fail;
|
||||||
B8 failon_slice_constraint_fail;
|
|
||||||
};
|
};
|
||||||
void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts);
|
void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts);
|
||||||
WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex* opts);
|
WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex* opts);
|
||||||
@@ -618,32 +624,36 @@ typedef def_Slice(WATL_Node);
|
|||||||
typedef Slice_WATL_Node WATL_Line;
|
typedef Slice_WATL_Node WATL_Line;
|
||||||
typedef def_Slice(WATL_Line);
|
typedef def_Slice(WATL_Line);
|
||||||
typedef def_struct(WATL_ParseMsg) {
|
typedef def_struct(WATL_ParseMsg) {
|
||||||
|
WATL_ParseMsg* next;
|
||||||
Str8 content;
|
Str8 content;
|
||||||
WATL_Line line;
|
WATL_Line* line;
|
||||||
WATL_Tok* tok;
|
WATL_Tok* tok;
|
||||||
WATL_Pos pos;
|
WATL_Pos pos;
|
||||||
};
|
};
|
||||||
typedef def_Slice(WATL_ParseMsg);
|
|
||||||
typedef def_enum(U32, WATL_ParseStatus) {
|
typedef def_enum(U32, WATL_ParseStatus) {
|
||||||
WATL_ParseStatus_MemFail_Alloc,
|
WATL_ParseStatus_MemFail_Alloc = (1 << 0),
|
||||||
WATL_ParseStatus_MemFail_SliceConstraintFail,
|
WATL_ParseStatus_MemFail_SliceConstraintFail = (1 << 1),
|
||||||
WATL_ParseStatus_PosUntrackable,
|
WATL_ParseStatus_PosUntrackable = (1 << 2),
|
||||||
WATL_ParseStatus_UnsupportedTokens,
|
WATL_ParseStatus_UnsupportedTokens = (1 << 3),
|
||||||
WATL_ParseStatus_MessageOverflow,
|
WATL_ParseStatus_MessageOverflow = (1 << 4),
|
||||||
};
|
};
|
||||||
typedef def_struct(WATL_ParseInfo) {
|
typedef def_struct(WATL_ParseInfo) {
|
||||||
Slice_WATL_Line lines;
|
Slice_WATL_Line lines;
|
||||||
Slice_WATL_ParseMsg msgs;
|
WATL_ParseMsg msgs;
|
||||||
WATL_ParseStatus signal;
|
WATL_ParseStatus signal;
|
||||||
};
|
};
|
||||||
typedef def_struct(Opts_watl_parse) {
|
typedef def_struct(Opts_watl_parse) {
|
||||||
AllocatorInfo backing_nodes;
|
AllocatorInfo ainfo_msgs;
|
||||||
AllocatorInfo backing_lines;
|
AllocatorInfo ainfo_nodes;
|
||||||
|
AllocatorInfo ainfo_lines;
|
||||||
Str8Cache* str_cache;
|
Str8Cache* str_cache;
|
||||||
|
B8 failon_slice_constraint_fail;
|
||||||
};
|
};
|
||||||
void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse* opts);
|
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);
|
WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse* opts);
|
||||||
#define watl_parse(tokens, ...) watl__parse(tokens, &(Opts_watl_parse){__VA_ARGS__})
|
#define watl_parse(tokens, ...) watl__parse(tokens, &(Opts_watl_parse){__VA_ARGS__})
|
||||||
|
|
||||||
|
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines);
|
||||||
#pragma endregion WATL
|
#pragma endregion WATL
|
||||||
|
|
||||||
#pragma endregion Header
|
#pragma endregion Header
|
||||||
@@ -839,7 +849,7 @@ void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
|||||||
case AllocatorOp_Grow:
|
case AllocatorOp_Grow:
|
||||||
case AllocatorOp_Grow_NoZero:
|
case AllocatorOp_Grow_NoZero:
|
||||||
case AllocatorOp_Shrink:
|
case AllocatorOp_Shrink:
|
||||||
asser_msg("not implemented");
|
assert_msg(false, "not implemented");
|
||||||
break;
|
break;
|
||||||
case AllocatorOp_Reset:
|
case AllocatorOp_Reset:
|
||||||
farena_reset(arena);
|
farena_reset(arena);
|
||||||
@@ -1021,7 +1031,7 @@ void varena_rewind(VArena* vm, AllocatorSP sp) {
|
|||||||
vm->commit_used = sp.slot;
|
vm->commit_used = sp.slot;
|
||||||
}
|
}
|
||||||
inline AllocatorSP varena_save(VArena* vm) { return (AllocatorSP){varena_allocator_proc, vm->commit_used}; }
|
inline AllocatorSP varena_save(VArena* vm) { return (AllocatorSP){varena_allocator_proc, vm->commit_used}; }
|
||||||
void varena__allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||||
{
|
{
|
||||||
VArena* vm = cast(VArena*, in.data);
|
VArena* vm = cast(VArena*, in.data);
|
||||||
switch (in.op)
|
switch (in.op)
|
||||||
@@ -1150,6 +1160,7 @@ void arena_release(Arena* arena) {
|
|||||||
varena_release(curr->backing);
|
varena_release(curr->backing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inline void arena_reset(Arena* arena) { arena_rewind(arena, (AllocatorSP){.type_sig = arena_allocator_proc, .slot = 0}); }
|
||||||
void arena_rewind(Arena* arena, AllocatorSP save_point) {
|
void arena_rewind(Arena* arena, AllocatorSP save_point) {
|
||||||
assert(arena);
|
assert(arena);
|
||||||
assert(save_point.type_sig == arena_allocator_proc);
|
assert(save_point.type_sig == arena_allocator_proc);
|
||||||
@@ -1183,7 +1194,7 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
|||||||
case AllocatorOp_Free:
|
case AllocatorOp_Free:
|
||||||
break;
|
break;
|
||||||
case AllocatorOp_Reset:
|
case AllocatorOp_Reset:
|
||||||
arena_rest(arena);
|
arena_reset(arena);
|
||||||
break;
|
break;
|
||||||
case AllocatorOp_Grow:
|
case AllocatorOp_Grow:
|
||||||
case AllocatorOp_Grow_NoZero:
|
case AllocatorOp_Grow_NoZero:
|
||||||
@@ -1794,31 +1805,11 @@ void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
|||||||
assert(info != nullptr);
|
assert(info != nullptr);
|
||||||
slice_assert(source);
|
slice_assert(source);
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
S32 max_msgs = opts->max_msgs ? opts->max_msgs : 10;
|
assert(opts->ainfo_msgs.proc != nullptr);
|
||||||
|
assert(opts->ainfo_toks.proc != nullptr);
|
||||||
|
AllocatorProc_Out start_snapshot; { opts->ainfo_toks.proc((AllocatorProc_In){.op = AllocatorOp_Query}, & start_snapshot); }
|
||||||
WATL_LexMsg* msg_last = nullptr;
|
WATL_LexMsg* msg_last = nullptr;
|
||||||
|
|
||||||
enum {
|
|
||||||
a_msg_unspecified = 1,
|
|
||||||
a_toks_unspecified = 2,
|
|
||||||
a_both_unspecifeid = 3,
|
|
||||||
};
|
|
||||||
AllocatorInfo a_msg = opts->ainfo_msgs;
|
|
||||||
AllocatorInfo a_toks = opts->ainfo_toks; {
|
|
||||||
S32 alloc_option_status = 0;
|
|
||||||
if (a_msg.proc == nullptr) { alloc_option_status += a_msg_unspecified; }
|
|
||||||
if (a_toks.proc == nullptr) { alloc_option_status += a_toks_unspecified; }
|
|
||||||
Arena* arena = nullptr;
|
|
||||||
if (alloc_option_status > 0) { arena = arena_make(); }
|
|
||||||
switch (alloc_option_status) {
|
|
||||||
case 0: break;
|
|
||||||
case a_msg_unspecified: a_msg = ainfo_arena(arena); break;
|
|
||||||
case a_toks_unspecified: a_toks = ainfo_arena(arena); break;
|
|
||||||
case a_both_unspecifeid: a_msg = ainfo_arena(arena); a_toks = ainfo_arena(arena); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AllocatorProc_Out start_snapshot; {
|
|
||||||
a_toks.proc((AllocatorProc_In){.op = AllocatorOp_Query}, & start_snapshot);
|
|
||||||
}
|
|
||||||
UTF8* end = source.ptr + source.len;
|
UTF8* end = source.ptr + source.len;
|
||||||
UTF8* cursor = source.ptr;
|
UTF8* cursor = source.ptr;
|
||||||
UTF8* prev = source.ptr;
|
UTF8* prev = source.ptr;
|
||||||
@@ -1834,7 +1825,7 @@ void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
|||||||
case WATL_Tok_Tab:
|
case WATL_Tok_Tab:
|
||||||
{
|
{
|
||||||
if (* prev != * cursor) {
|
if (* prev != * cursor) {
|
||||||
tok = alloc_type(a_toks, WATL_Tok);
|
tok = alloc_type(opts->ainfo_toks, WATL_Tok);
|
||||||
tok->code = cursor;
|
tok->code = cursor;
|
||||||
was_formatting = true;
|
was_formatting = true;
|
||||||
++ num;
|
++ num;
|
||||||
@@ -1843,7 +1834,7 @@ void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WATL_Tok_LineFeed: {
|
case WATL_Tok_LineFeed: {
|
||||||
tok = alloc_type(a_toks, WATL_Tok);
|
tok = alloc_type(opts->ainfo_toks, WATL_Tok);
|
||||||
tok->code = cursor;
|
tok->code = cursor;
|
||||||
cursor += 1;
|
cursor += 1;
|
||||||
was_formatting = true;
|
was_formatting = true;
|
||||||
@@ -1852,7 +1843,7 @@ void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
|||||||
break;
|
break;
|
||||||
// Assuming what comes after is line feed.
|
// Assuming what comes after is line feed.
|
||||||
case WATL_Tok_CarriageReturn: {
|
case WATL_Tok_CarriageReturn: {
|
||||||
tok = alloc_type(a_toks, WATL_Tok);
|
tok = alloc_type(opts->ainfo_toks, WATL_Tok);
|
||||||
tok->code = cursor;
|
tok->code = cursor;
|
||||||
cursor += 2;
|
cursor += 2;
|
||||||
was_formatting = true;
|
was_formatting = true;
|
||||||
@@ -1862,7 +1853,7 @@ void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (was_formatting) {
|
if (was_formatting) {
|
||||||
tok = alloc_type(a_toks, WATL_Tok);
|
tok = alloc_type(opts->ainfo_toks, WATL_Tok);
|
||||||
tok->code = cursor;
|
tok->code = cursor;
|
||||||
was_formatting = false;
|
was_formatting = false;
|
||||||
++ num;
|
++ num;
|
||||||
@@ -1875,21 +1866,146 @@ void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
|||||||
code = * cursor;
|
code = * cursor;
|
||||||
}
|
}
|
||||||
AllocatorProc_Out end_snapshot; {
|
AllocatorProc_Out end_snapshot; {
|
||||||
a_toks.proc((AllocatorProc_In){.op = AllocatorOp_Query}, & end_snapshot);
|
opts->ainfo_toks.proc((AllocatorProc_In){.op = AllocatorOp_Query}, & end_snapshot);
|
||||||
}
|
}
|
||||||
SSIZE num_bytes = end_snapshot.save_point.slot - start_snapshot.save_point.slot;
|
SSIZE num_bytes = end_snapshot.save_point.slot - start_snapshot.save_point.slot;
|
||||||
if (num_bytes <= start_snapshot.left) {
|
if (num_bytes > start_snapshot.left) {
|
||||||
WATL_LexMsg* msg = alloc_type(a_msg, WATL_LexMsg);
|
info->signal |= WATL_LexStatus_MemFail_SliceConstraintFail;
|
||||||
|
WATL_LexMsg* msg = alloc_type(opts->ainfo_msgs, WATL_LexMsg);
|
||||||
msg->pos = (WATL_Pos){ -1, -1 };
|
msg->pos = (WATL_Pos){ -1, -1 };
|
||||||
msg->tok = tok;
|
msg->tok = tok;
|
||||||
msg->content = lit("Token slice allocation was not contiguous");
|
msg->content = lit("Token slice allocation was not contiguous");
|
||||||
info->signal = WATL_LexStatus_MemFail_SliceConstraintFail;
|
|
||||||
sll_queue_push_n(info->msgs, msg_last, msg, next);
|
sll_queue_push_n(info->msgs, msg_last, msg, next);
|
||||||
assert(opts->failon_slice_constraint_fail == false);
|
assert(opts->failon_slice_constraint_fail == false);
|
||||||
}
|
}
|
||||||
info->toks.ptr = tok - num;
|
info->toks.ptr = tok - num;
|
||||||
info->toks.len = 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; }
|
||||||
|
|
||||||
|
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 text = {0};
|
||||||
|
text.ptr = tok->code;
|
||||||
|
text.len = next > (toks.ptr + toks.len) ?
|
||||||
|
left
|
||||||
|
// Othwerise its the last minus the curr.
|
||||||
|
: cast(SSIZE, next->code - tok->code);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse* opts)
|
||||||
|
{
|
||||||
|
assert(opts != nullptr);
|
||||||
|
assert(opts->ainfo_lines.proc != nullptr);
|
||||||
|
assert(opts->ainfo_msgs.proc != nullptr);
|
||||||
|
assert(opts->ainfo_nodes.proc != nullptr);
|
||||||
|
assert(opts->str_cache != nullptr);
|
||||||
|
AllocatorProc_Out start_lines_snapshot; { opts->ainfo_lines.proc((AllocatorProc_In){.op = AllocatorOp_Query}, & start_lines_snapshot); }
|
||||||
|
AllocatorProc_Out start_nodes_snapshot; { opts->ainfo_nodes.proc((AllocatorProc_In){.op = AllocatorOp_Query}, & start_nodes_snapshot); }
|
||||||
|
WATL_ParseMsg* msg_last = nullptr;
|
||||||
|
|
||||||
|
WATL_Line* line = alloc_type(opts->ainfo_lines, WATL_Line);
|
||||||
|
WATL_Node* curr = alloc_type(opts->ainfo_nodes, WATL_Node);
|
||||||
|
* curr = (WATL_Node){0};
|
||||||
|
* line = (WATL_Line){ curr, 0 };
|
||||||
|
info->lines = (Slice_WATL_Line){ line, 0 };
|
||||||
|
for (slice_iter(tokens, token))
|
||||||
|
{
|
||||||
|
switch(* token->code)
|
||||||
|
{
|
||||||
|
case WATL_Tok_CarriageReturn:
|
||||||
|
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;
|
||||||
|
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->line = line;
|
||||||
|
msg->tok = token;
|
||||||
|
sll_queue_push_n(info->msgs, msg_last, msg, next);
|
||||||
|
assert(opts->failon_slice_constraint_fail == false);
|
||||||
|
}
|
||||||
|
opts->ainfo_nodes.proc((AllocatorProc_In){.op = AllocatorOp_Query}, & start_nodes_snapshot);
|
||||||
|
WATL_Line* new_line = alloc_type(opts->ainfo_lines, WATL_Line);
|
||||||
|
line = new_line;
|
||||||
|
line->ptr = curr;
|
||||||
|
line->len = 0;
|
||||||
|
info->lines.len += 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Str8 tok_str = watl_tok_str8(tokens, token);
|
||||||
|
* curr = cache_str8(opts->str_cache, tok_str);
|
||||||
|
curr = alloc_type(opts->ainfo_nodes, WATL_Node);
|
||||||
|
* curr = (WATL_Node){0};
|
||||||
|
line->len += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
if (distance_lines > start_lines_snapshot.left) {
|
||||||
|
info->signal |= WATL_ParseStatus_MemFail_SliceConstraintFail;
|
||||||
|
WATL_ParseMsg* msg = alloc_type(opts->ainfo_msgs, WATL_ParseMsg);
|
||||||
|
msg->content = lit("Line slice allocation was not contiguous");
|
||||||
|
msg->pos = (WATL_Pos){-1, -1};
|
||||||
|
sll_queue_push_n(info->msgs, msg_last, msg, next);
|
||||||
|
assert(opts->failon_slice_constraint_fail == false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WATL_ParseInfo watl__parse(Slice_WATL_Tok tokens, Opts_watl_parse* opts);
|
||||||
|
|
||||||
|
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
||||||
|
{
|
||||||
|
local_persist Byte scratch[kilo(64)] = {0}; FArena sarena = farena_make(slice_fmem(scratch)); AllocatorInfo sinfo = ainfo_farena(sarena);
|
||||||
|
|
||||||
|
Str8Gen result = str8gen_make(buffer);
|
||||||
|
U32 line_num = 0;
|
||||||
|
for (slice_iter(lines, line))
|
||||||
|
{
|
||||||
|
#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);
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
for (slice_iter(* line, chunk))
|
||||||
|
{
|
||||||
|
Str8 id;
|
||||||
|
switch (* chunk->ptr)
|
||||||
|
{
|
||||||
|
case WATL_Tok_Space: id = lit("Space"); break;
|
||||||
|
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);
|
||||||
|
str8gen_append_fmt(& result, "\t<id>(<size>): '<chunk>'\n"
|
||||||
|
, fmt_entry("id", id)
|
||||||
|
, fmt_entry("size", str_chunk_len)
|
||||||
|
, fmt_entry("chunk", * chunk)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
farena_reset(& sarena);
|
||||||
|
#undef push_str8_u32
|
||||||
|
#undef fmt_entry_u32
|
||||||
|
}
|
||||||
|
return (Str8){ result.ptr, result.len };
|
||||||
|
}
|
||||||
#pragma endregion WATL
|
#pragma endregion WATL
|
||||||
|
|
||||||
#pragma endregion Implementation
|
#pragma endregion Implementation
|
||||||
@@ -1898,5 +2014,37 @@ int main()
|
|||||||
{
|
{
|
||||||
os_init();
|
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(vm_file));
|
||||||
|
|
||||||
|
Arena* a_msgs = arena_make();
|
||||||
|
Arena* a_toks = arena_make();
|
||||||
|
WATL_LexInfo lex_res = watl_lex(pcast(Str8, file.content),
|
||||||
|
.ainfo_msgs = ainfo_arena(a_msgs),
|
||||||
|
.ainfo_toks = ainfo_arena(a_toks),
|
||||||
|
);
|
||||||
|
assert(lex_res.signal & WATL_LexStatus_MemFail_SliceConstraintFail);
|
||||||
|
|
||||||
|
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),
|
||||||
|
.table_size = kilo(32),
|
||||||
|
);
|
||||||
|
|
||||||
|
Arena* a_lines = arena_make();
|
||||||
|
WATL_ParseInfo parse_res = watl_parse(lex_res.toks,
|
||||||
|
.ainfo_msgs = ainfo_arena(a_msgs),
|
||||||
|
.ainfo_nodes = ainfo_arena(a_toks),
|
||||||
|
.ainfo_lines = ainfo_arena(a_lines),
|
||||||
|
.str_cache = & str_cache
|
||||||
|
);
|
||||||
|
assert(parse_res.signal & WATL_ParseStatus_MemFail_SliceConstraintFail);
|
||||||
|
|
||||||
|
arena_reset(a_msgs);
|
||||||
|
arena_reset(a_toks);
|
||||||
|
Str8 listing = watl_dump_listing(ainfo_arena(a_msgs), parse_res.lines);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user