From 39b30d92764020d1c941fc90346f8b0394f81e9f Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 10 Sep 2021 15:26:21 -0700 Subject: [PATCH] [examples] finish first draft commentary in parse_check.c --- examples/parse_check.c | 24 +++++++++++++++++++++--- intro_notes.txt | 22 ++++++++++++++++++++-- source/md.h | 3 ++- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/examples/parse_check.c b/examples/parse_check.c index 6e1ea43..50f43c0 100644 --- a/examples/parse_check.c +++ b/examples/parse_check.c @@ -73,13 +73,31 @@ int main(int argument_count, char **arguments) } // print the verbose parse results + // @notes The Metadesk library provides a few macros for iterating MD_Node + // lists as shown here. The first parameter to the macro becomes an + // MD_Node pointer in the scope of the for loop that visits each node in + // the list in order. The second parameter is a pointer to the first node + // in the list. Generally we past the `first_child` of a list or parent + // MD_Node, but we don't always have to. + // + // MD_EachNode is used to iterate a list of children. + // MD_EachNodeRef is used to iterate a list of references like the list + // of roots from the parses we have built. Underneath the surface this + // macro automatically resolves the reference at the beginning of each + // loop step. for(MD_EachNodeRef(root, list->first_child)) { for(MD_EachNode(node, root->first_child)) { - MD_String8List strs = - MD_DebugStringListFromNode(arena, node, 0, MD_S8Lit(" "), MD_GenerateFlags_Tree); - MD_String8 str = MD_S8ListJoin(arena, strs, 0); + // @notes The Metadesk library likes to use MD_String8List for + // functions that build and return big strings. This simplifies + // memory management for big strings, and means a series of string + // builders can be called back to back and gathered into one list. + // When the string needs to be finalized into a single contiguous + // block a user can just call `MD_S8ListJoin` as shown here. + MD_String8List stream = {0}; + MD_DebugStringListFromNode(arena, &stream, node, 0, MD_S8Lit(" "), MD_GenerateFlags_Tree); + MD_String8 str = MD_S8ListJoin(arena, stream, 0); fwrite(str.str, str.size, 1, stdout); fwrite("\n", 1, 1, stdout); } diff --git a/intro_notes.txt b/intro_notes.txt index b3c8ef6..d9adb3b 100644 --- a/intro_notes.txt +++ b/intro_notes.txt @@ -4,9 +4,9 @@ string helpers immutable tree model nil -Examples: +Example Programs: [ ] Metadesk hello world -[ ] Metadesk parse checker +[x] Metadesk parse checker [ ] Example of helpers: string helpers, linked lists, map type printing errors, cmd line, file iter [x] Datadesk-like setup @@ -17,3 +17,21 @@ Examples: [ ] Example memory clearing in long-running program [ ] Example multi-threaded parsing +Example Metadesk Files: +[ ] Hello world + + +Allen's Final Tweak Notes (September 10th 2021): + +*** MD_EachNodeRef seems bad to me. *** + +Using it is equivalent to: +for (MD_EachNode(it, first_child) +{ + MD_Node *node = MD_ResolveFromReference(it); // this line is saved by the macro +} + +Explaning this concept seems more difficult with the extra macro. I think it'd be +clearer and basically just as maintenance efficient to live without this. + + diff --git a/source/md.h b/source/md.h index 0052247..5f46969 100644 --- a/source/md.h +++ b/source/md.h @@ -1099,7 +1099,8 @@ MD_FUNCTION MD_String8 MD_NextCommentFromNode(MD_Node *node); // NOTE(rjf): For-Loop Helpers #define MD_EachNode(it, first) MD_Node *it = (first); !MD_NodeIsNil(it); it = it->next -#define MD_EachNodeRef(it, first) MD_Node *it##_r = (first), *it = MD_NodeFromReference(it##_r); \ +#define MD_EachNodeRef(it, first) \ +MD_Node *it##_r = (first), *it = MD_NodeFromReference(it##_r); \ !MD_NodeIsNil(it##_r); \ it##_r = it##_r->next, it = MD_NodeFromReference(it##_r)