This commit is contained in:
Edward R. Gonzalez 2025-05-05 23:14:04 -04:00
parent 567ec7d6fd
commit 6bef824dce

View File

@ -440,6 +440,7 @@ enum WATL_TokKind {
WATL_Tok_Tab = '\t', WATL_Tok_Tab = '\t',
WATL_Tok_CarriageReturn = '\r', WATL_Tok_CarriageReturn = '\r',
WATL_Tok_LineFeed = '\n', WATL_Tok_LineFeed = '\n',
WATL_Tok_Text = 0xFFFFFFFF,
}; };
typedef struct WATL_Tok WATL_Tok; typedef struct WATL_Tok WATL_Tok;
@ -630,7 +631,7 @@ SliceMem slicemem_alloc(SSIZE amount)
}; };
return mem; return mem;
} }
void slicemem_free(SliceMem mem) { void slicemem_free(SliceMem mem) {
free(mem.ptr); free(mem.ptr);
} }
@ -653,6 +654,7 @@ int main()
/* /*
Next we'll parse these tokens into a rudimentary WATL Abstract Syntax Tree. Next we'll parse these tokens into a rudimentary WATL Abstract Syntax Tree.
* The tree will be top-level organized by lines consisting of linked slices of visble and non-visible tokens. * The tree will be top-level organized by lines consisting of linked slices of visble and non-visible tokens.
* Just as with the the lexical analysis, lines and nodes will be linearly allocated adjacent to each other. This allows us to utilize array operations.
*/ */
typedef struct WATL_ParseInfo WATL_ParseInfo; typedef struct WATL_ParseInfo WATL_ParseInfo;
@ -661,24 +663,6 @@ void api_watl_parse(WATL_ParseInfo* info, WATL_SliceTok tokens, Opts__
WATL_ParseInfo watl__parse ( WATL_SliceTok tokens, Opts__watl_parse* opts); WATL_ParseInfo watl__parse ( WATL_SliceTok 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__})
typedef struct WATL_Node WATL_Node;
struct WATL_Node {
WATL_Node* next;
Str8 entry;
};
typedef struct WATL_Line WATL_Line;
struct WATL_Line {
WATL_Line* next;
WATL_Node* ptr;
};
typedef struct WATL_SliceLine WATL_SliceLine;
struct WATL_SliceLine {
WATL_Line* ptr;
SSIZE len;
};
/* /*
For the sake of the exercise, we'll be eliminating the association with the file's strings and we'll need to instead cache them. For the sake of the exercise, we'll be eliminating the association with the file's strings and we'll need to instead cache them.
*/ */
@ -691,12 +675,12 @@ Str8Cache str8cache_init ( SliceMem mem_strs, SliceMem mem_s
// For these strings we'll be using a hash called djb8: // For these strings we'll be using a hash called djb8:
// Introducing a slice iterator: // Introducing a slice iterator:
#define slice_iter(container) typeof(container.ptr) iter = container.ptr; iter != (container.ptr + container.len); ++ iter #define slice_iter(container, iter) typeof(container.ptr) iter = container.ptr; iter != (container.ptr + container.len); ++ iter
inline inline
void hash64_djb8(U64* hash, SliceByte bytes) { void hash64_djb8(U64* hash, SliceByte bytes) {
for (slice_iter(bytes)) { for (slice_iter(bytes, elem)) {
*hash = (((*hash) << 8) + (*hash)) + (*iter); *hash = (((*hash) << 8) + (*hash)) + (*elem);
} }
} }
@ -744,15 +728,15 @@ void api_str8cache_init(Str8Cache* cache, SliceMem mem_strs, SliceMem mem_slots,
void str8cache_clear(Str8Cache* cache) void str8cache_clear(Str8Cache* cache)
{ {
for (slice_iter(cache->table)) for (slice_iter(cache->table, slot))
{ {
if (iter == nullptr) { if (slot == nullptr) {
continue; continue;
} }
for (Str8Cache_Slot* probe_slot = iter->next; probe_slot != nullptr; probe_slot = probe_slot->next) { for (Str8Cache_Slot* probe_slot = slot->next; probe_slot != nullptr; probe_slot = probe_slot->next) {
iter->occupied = false; slot->occupied = false;
} }
iter->occupied = false; slot->occupied = false;
} }
} }
@ -848,6 +832,23 @@ Str8 cache_str8(Str8Cache* cache, Str8 str)
return * result; return * result;
} }
typedef struct WATL_Node WATL_Node;
struct WATL_Node {
Str8 entry;
};
typedef struct WATL_Line WATL_Line;
struct WATL_Line {
WATL_Node* ptr;
SSIZE len;
};
typedef struct WATL_SliceLine WATL_SliceLine;
struct WATL_SliceLine {
WATL_Line* ptr;
SSIZE len;
};
#ifdef DEMO__WATL_PARSE_V1 #ifdef DEMO__WATL_PARSE_V1
struct Opts__watl_parse { struct Opts__watl_parse {
@ -870,23 +871,20 @@ void api_watl_parse(WATL_ParseInfo* info, WATL_SliceTok tokens, Opts__watl_parse
FArena a_nodes = farena_init(opts->backing_nodes); FArena a_nodes = farena_init(opts->backing_nodes);
WATL_Line* line = farena_push(a_lines, WATL_Line); WATL_Line* line = farena_push(a_lines, WATL_Line);
WATL_Node* curr = line->ptr->entry; WATL_Node* curr = farena_push(a_nodes, WATL_Node); // Preemtively allocate a node for the line (may not be used)
for (slice_iter(tokens)) line->ptr = curr;
line->len = 0;
info->lines.ptr = line;
info->lines.len = 0;
for (slice_iter(tokens, token))
{ {
switch (* iter->code) switch (* token->code)
{ {
case WATL_Tok_Space:
case WATL_Tok_Tab: {
line->ptr->entry = cache_str8(opts->str_cache, watl_tok_str8(tokens, iter));
continue;
}
break;
case WATL_Tok_CarriageReturn: {
++ iter;
}
case WATL_Tok_LineFeed: { case WATL_Tok_LineFeed: {
WATL_Line* new_line = farena_push(a_lines, WATL_Line); WATL_Line* new_line = farena_push(a_lines, WATL_Line);
line = new_line; line = new_line;
line->ptr = curr;
info->lines.len += 1;
continue; continue;
} }
@ -894,7 +892,10 @@ void api_watl_parse(WATL_ParseInfo* info, WATL_SliceTok tokens, Opts__watl_parse
break; break;
} }
curr->entry = watl_tok_str8(tokens, token);
curr = farena_push(a_nodes, WATL_Node);
line->len += 1;
continue;
} }
} }
@ -905,7 +906,7 @@ WATL_ParseInfo watl__parse(WATL_SliceTok tokens, Opts__watl_parse* opts) { WATL_
#ifdef DEMO__WATL_PARSE_V1 #ifdef DEMO__WATL_PARSE_V1
int main() int main()
{ {
// This will limit for our V1 read to 64kb at most. // This will limit for our V1 read to 64kb at most.
FMem_64KB read_mem = {0}; FMem_64KB read_mem = {0};
FileOpResult read_res = file_read_contents(lit("demo.str_cache.c"), .backing = fmem_slice(read_mem) ); FileOpResult read_res = file_read_contents(lit("demo.str_cache.c"), .backing = fmem_slice(read_mem) );