From aba3c9a164d3713a27e292284e6f13138b3f6992 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 12 Jun 2021 12:02:44 -0700 Subject: [PATCH] [api] introduced linked list macros with z-check z-set upgrade --- docs/metadesk_reference.md | 1 + source/md.h | 48 ++++++++++++++++++++++++++++- source/md_impl.c | 63 ++++++++++++-------------------------- 3 files changed, 67 insertions(+), 45 deletions(-) diff --git a/docs/metadesk_reference.md b/docs/metadesk_reference.md index c6b7bb1..d321ecc 100644 --- a/docs/metadesk_reference.md +++ b/docs/metadesk_reference.md @@ -1166,6 +1166,7 @@ MD_MapOverwrite: { return: *MD_Node, }; +// TODO(allen): eliminate @send(Nodes) @func MD_PushSibling: { first: **MD_Node, diff --git a/source/md.h b/source/md.h index 41eb0d4..ecfdef3 100644 --- a/source/md.h +++ b/source/md.h @@ -228,6 +228,7 @@ typedef int64_t MD_b64; typedef float MD_f32; typedef double MD_f64; + //~ Basic UTF-8 string types. typedef struct MD_String8 MD_String8; @@ -575,6 +576,49 @@ struct MD_FileIter #define MD_StaticAssert(c,label) MD_u8 MD_static_assert_##label[(c)?(1):(-1)] #define MD_ArrayCount(a) (sizeof(a) / sizeof((a)[0])) +//~ Linked List Macros. + +// terminator modes +#define MD_CheckNull(p) ((p)==0) +#define MD_SetNull(p) ((p)=0) +#define MD_CheckNil(p) (MD_NodeIsNil(p)) +#define MD_SetNil(p) ((p)=MD_NilNode()) + +// implementations +#define MD_QueuePush_NZ(f,l,n,next,zchk,zset) (zchk(f)?\ +(f)=(l)=(n):\ +((l)->next=(n),(l)=(n),zset((n)->next))) +#define MD_QueuePop_NZ(f,l,next,zset) ((f)==(l)?\ +(zset(f),zset(l)):\ +(f)=(f)->next) +#define MD_StackPush_N(f,n,next) ((n)->next=(f),(f)=(n)) +#define MD_StackPop_NZ(f,next,zchk) (zchk(f)?0:(f)=(f)->next) + +#define MD_DblPushBack_NPZ(f,l,n,next,prev,zchk,zset) \ +(zchk(f)?\ +((f)=(l)=(n),zset((n)->next),zset((n)->prev)):\ +((n)->prev=(l),(l)->next=(n),(l)=(n),zset((n)->next))) +#define MD_DblRemove_NPZ(f,l,n,next,prev,zset) (((f)==(n)?\ +((f)=(f)->next,zset((f)->prev)):\ +(l)==(n)?\ +((l)=(l)->prev,zset((l)->next)):\ +((n)->next->prev=(n)->prev,\ +(n)->prev->next=(n)->next))) + +// compositions +#define MD_QueuePush(f,l,n) MD_QueuePush_NZ(f,l,n,next,MD_CheckNull,MD_SetNull) +#define MD_QueuePop(f,l) MD_QueuePop_NZ(f,l,next,MD_SetNull) +#define MD_StackPush(f,n) MD_StackPush_N(f,n,next) +#define MD_StackPop(f) MD_StackPop_NZ(f,next,MD_CheckNull) +#define MD_DblPushBack(f,l,n) MD_DblPushBack_NPZ(f,l,n,next,prev,MD_CheckNull,MD_SetNull) +#define MD_DblPushFront(f,l,n) MD_DblPushBack_NPZ(l,f,n,prev,next,MD_CheckNull,MD_SetNull) +#define MD_DblRemove(f,l,n) MD_DblRemove_NPZ(f,l,n,next,prev,MD_SetNull) + +#define MD_NodeDblPushBack(f,l,n) MD_DblPushBack_NPZ(f,l,n,next,prev,MD_CheckNil,MD_SetNil) +#define MD_NodeDblPushFront(f,l,n) MD_DblPushBack_NPZ(l,f,n,prev,next,MD_CheckNil,MD_SetNil) +#define MD_NodeDblRemove(f,l,n) MD_DblRemove_NPZ(f,l,n,next,prev,MD_SetNil) + + //~ Memory Operations MD_FUNCTION void MD_MemoryZero(void *memory, MD_u64 size); MD_FUNCTION void MD_MemoryCopy(void *dst, void *src, MD_u64 size); @@ -702,11 +746,13 @@ MD_FUNCTION MD_Node *MD_NilNode(void); MD_FUNCTION MD_Node *MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 whole_string, MD_String8 filename, MD_u8 *file_contents, MD_u8 *at); -MD_FUNCTION void MD_PushSibling(MD_Node **first, MD_Node **last, MD_Node *new_sibling); MD_FUNCTION void MD_PushChild(MD_Node *parent, MD_Node *new_child); MD_FUNCTION void MD_PushTag(MD_Node *node, MD_Node *tag); MD_FUNCTION MD_Node *MD_PushReference(MD_Node *list, MD_Node *target); +// TODO(allen): eliminate +MD_FUNCTION void MD_PushSibling(MD_Node **first, MD_Node **last, MD_Node *new_sibling); + //~ Introspection Helpers MD_FUNCTION MD_Node * MD_NodeFromString(MD_Node *first, MD_Node *last, MD_String8 string); MD_FUNCTION MD_Node * MD_NodeFromIndex(MD_Node *first, MD_Node *last, int n); diff --git a/source/md_impl.c b/source/md_impl.c index 1c07170..21ebcd3 100644 --- a/source/md_impl.c +++ b/source/md_impl.c @@ -313,7 +313,7 @@ MD_PushStringFV(char *fmt, va_list args) va_copy(args2, args); MD_u64 needed_bytes = vsnprintf(0, 0, fmt, args)+1; result.str = MD_PushArray(MD_u8, needed_bytes); - result.size = needed_bytes-1; + result.size = needed_bytes - 1; vsnprintf((char*)result.str, needed_bytes, fmt, args2); return result; } @@ -332,21 +332,12 @@ MD_PushStringF(char *fmt, ...) MD_FUNCTION_IMPL void MD_PushStringToList(MD_String8List *list, MD_String8 string) { + MD_String8Node *node = MD_PushArray(MD_String8Node, 1); + node->string = string; + + MD_QueuePush(list->first, list->last, node); list->node_count += 1; list->total_size += string.size; - - MD_String8Node *node = MD_PushArray(MD_String8Node, 1); - node->next = 0; - node->string = string; - if(list->last == 0) - { - list->first = list->last = node; - } - else - { - list->last->next = node; - list->last = list->last->next; - } } MD_FUNCTION_IMPL void @@ -1027,16 +1018,8 @@ MD_MapInsert(MD_Map *map, MD_MapKey key, void *val){ // TODO(allen): again, memory? permanent arena? scratch arena? // should definitely match the table's memory "object" MD_MapSlot *slot = MD_PushArray(MD_MapSlot, 1); - // TODO(allen): queue push MD_MapBucket *bucket = &map->buckets[index]; - if (bucket->first == 0){ - bucket->first = slot; - } - else{ - bucket->last->next = slot; - } - bucket->last = slot; - slot->next = 0; + MD_QueuePush(bucket->first, bucket->last, slot); slot->key = key; slot->val = val; result = slot; @@ -1131,7 +1114,7 @@ _MD_ParseTagList(MD_ParseCtx *ctx, MD_Node **first_out, MD_Node **last_out) { MD_Parse_Set(ctx, tag, MD_ParseSetFlag_Paren); } - MD_PushSibling(&first, &last, tag); + MD_NodeDblPushBack(first, last, tag); } else { @@ -2120,42 +2103,34 @@ MD_MakeNode(MD_NodeKind kind, MD_String8 string, return node; } +// TODO(allen): eliminate MD_FUNCTION_IMPL void MD_PushSibling(MD_Node **firstp, MD_Node **lastp, MD_Node *node) { if(!MD_NodeIsNil(node)) { - MD_Node *first = *firstp; - MD_Node *last = *lastp; - if(MD_NodeIsNil(last)) - { - first = last = node; - node->next = node->prev = MD_NilNode(); - } - else - { - last->next = node; - node->next = MD_NilNode(); - node->prev = last; - last = last->next; - } - *firstp = first; - *lastp = last; + MD_NodeDblPushBack(*firstp, *lastp, node); } } MD_FUNCTION_IMPL void MD_PushChild(MD_Node *parent, MD_Node *new_child) { - MD_PushSibling(&parent->first_child, &parent->last_child, new_child); - new_child->parent = parent; + if (!MD_NodeIsNil(new_child)) + { + MD_NodeDblPushBack(parent->first_child, parent->last_child, new_child); + new_child->parent = parent; + } } MD_FUNCTION_IMPL void MD_PushTag(MD_Node *node, MD_Node *tag) { - MD_PushSibling(&node->first_tag, &node->last_tag, tag); - tag->parent = node; + if (!MD_NodeIsNil(tag)) + { + MD_NodeDblPushBack(node->first_tag, node->last_tag, tag); + tag->parent = node; + } } MD_FUNCTION_IMPL MD_Node*