From f15fc77bfa3e2feeef5fb20edd4cf5aeedafb65a Mon Sep 17 00:00:00 2001 From: ryanfleury Date: Wed, 30 Jun 2021 22:54:56 -0600 Subject: [PATCH] introspection helper docs; remove redundant node-sibling helper; ensure that any of the introspection APIs doing string matching take match flags --- docs/metadesk_reference.md | 183 ++++++++++++++---- samples/c_code_generation.c | 2 +- .../static_site_generator.c | 22 +-- samples/toy_language/toy_language.c | 2 +- source/md.h | 17 +- source/md_impl.c | 60 ++---- tests/grammar.c | 6 +- tests/sanity_tests.c | 8 +- 8 files changed, 196 insertions(+), 104 deletions(-) diff --git a/docs/metadesk_reference.md b/docs/metadesk_reference.md index ac4c21c..f4f168f 100644 --- a/docs/metadesk_reference.md +++ b/docs/metadesk_reference.md @@ -1319,15 +1319,21 @@ MD_ParseWholeFile: //~ Location Conversion @send(CodeLoc) -@func MD_CodeLocFromFileBaseOff: { +@doc("Calculates a position in a source code file in filename/line/column coordinates, provided a filename, a base pointer for the file's contents, and an offset into the file's contents.") +@see(MD_CodeLocFromNode) +@func MD_CodeLocFromFileBaseOffset: +{ filename: MD_String8, base: *MD_u8, - off: *MD_u8, + offset: MD_u64, return: MD_CodeLoc, }; @send(CodeLoc) -@func MD_CodeLocFromNode: { +@doc("Calculates a position in a source code file in filename/line/column coordinates, provided a parsed MD_Node.") +@see(MD_CodeLocFromFileBaseOffset) +@func MD_CodeLocFromNode: +{ node: *MD_Node, return: MD_CodeLoc, }; @@ -1336,29 +1342,36 @@ MD_ParseWholeFile: //~ Tree/List Building @send(Nodes) +@doc("Returns @code '1' if the @code 'node' is nil, or @code '0' otherwise. A nil node pointer is not equivalent to a null pointer. It can still be dereferenced, and is treated as a dummy placeholder node value.") +@see(MD_NilNode) @func MD_NodeIsNil: { node: *MD_Node, return: MD_b32, }; @send(Nodes) +@doc("Returns a nil node pointer.") +@see(MD_NodeIsNil) @func MD_NilNode: { return: *MD_Node, }; @send(Nodes) +@doc("Links @code 'new_child' up as being a child of @code 'parent', inserting it into the end of @code `parent`'s children list.") @func MD_PushChild: { parent: *MD_Node, new_child: *MD_Node, }; @send(Nodes) +@doc("Links @code 'tag' up as being a tag of @code 'node', inserting it into the end of @code `node`'s tag list.") @func MD_PushTag: { node: *MD_Node, tag: *MD_Node, }; @send(Nodes) +@doc("Creates a new reference node, pointing at @code 'target', and links it up as a child of @code 'list'.") @func MD_PushReference: { list: *MD_Node, target: *MD_Node, @@ -1369,91 +1382,191 @@ MD_ParseWholeFile: //~ Introspection Helpers @send(Nodes) +@doc("Finds a node in the range defined by @code 'first' and @code 'one_past_last', with the string matching @code 'string' in accordance with @code 'flags', or returns a nil node pointer if it is not found.") +@see(MD_NodeFromIndex) +@see(MD_StringMatch) @func MD_NodeFromString: { - first: *MD_Node, - last: *MD_Node, - string: MD_String8, - return: *MD_Node, + @doc("The first node in the range to search.") + first: *MD_Node, + @doc("One past the last node in the range to search. A nil node, if the entire available range starting with @code 'first' is to be searched.") + one_past_last: *MD_Node, + @doc("The string to search for.") + string: MD_String8, + @doc("Controls what is considered a match, when doing string matching.") + flags: MD_MatchFlags, + @doc("The found node, or a nil node pointer if no node was found.") + return: *MD_Node, }; @send(Nodes) +@doc("Finds the @code 'n'th node in the range defined by @code 'first' and @code 'one_past_last', or returns a nil node pointer if it is not found. @code '0' would match @code 'first', @code '1' would match @code 'first->next', and so on.") +@see(MD_NodeFromString) @func MD_NodeFromIndex: { - first: *MD_Node, - last: *MD_Node, - n: int, - return: *MD_Node, + @doc("The first node in the range to search.") + first: *MD_Node, + @doc("One past the last node in the range to search. A nil node, if the entire available range starting with @code 'first' is to be searched.") + one_past_last: *MD_Node, + @doc("The index to search for.") + n: int, + @doc("The found node, or a nil node pointer if no node was found.") + return: *MD_Node, }; @send(Nodes) +@doc("Finds the child index of @code 'node', with @code '0' being the first child, @code '1' being the second, and so on.") +@see(MD_NodeFromIndex) @func MD_IndexFromNode: { node: *MD_Node, return: int, }; @send(Nodes) -@func MD_NextNodeSibling: { - last: *MD_Node, - string: MD_String8, - return: *MD_Node, +@doc("Finds the highest-most node in the parent chain of @code 'node', starting with @code 'node'. If @code 'node' has no parent, then @code 'node' is returned.") +@func MD_RootFromNode: { + @doc("The node for which the root is to be found.") + node: *MD_Node, + @doc("The found root.") + return: *MD_Node, }; @send(Nodes) +@doc("Finds a child of @code 'node' with a string matching @code 'child_string', where the rules of matching are determined by @code 'flags'.") +@see(MD_NodeFromString) +@see(MD_TagFromString) @func MD_ChildFromString: { - node: *MD_Node, - child_string: MD_String8, - return: *MD_Node, + @doc("The parent whose children are to be searched.") + node: *MD_Node, + @doc("The string that the found child should match.") + child_string: MD_String8, + @doc("Controls what is considered a string match.") + flags: MD_MatchFlags, + @doc("The found node, or a nil node pointer if no node was found.") + return: *MD_Node, }; @send(Nodes) +@doc("Finds a tag on @code 'node' with a string matching @code 'tag_string', where the rules of matching are determined by @code 'flags'.") +@see(MD_NodeFromString) +@see(MD_ChildFromString) @func MD_TagFromString: { - node: *MD_Node, - tag_string: MD_String8, - return: *MD_Node, + @doc("The parent whose tags are to be searched.") + node: *MD_Node, + @doc("The string that the found tag should match.") + tag_string: MD_String8, + @doc("Controls what is considered a string match.") + flags: MD_MatchFlags, + @doc("The found node, or a nil node pointer if no node was found.") + return: *MD_Node, }; @send(Nodes) +@doc("Finds a child of @code 'node' with an index matching @code 'n'. Returns a nil node pointer if no such child is found.") +@see(MD_NodeFromIndex) +@see(MD_IndexFromNode) +@see(MD_TagFromIndex) @func MD_ChildFromIndex: { - node: *MD_Node, - n: int, - return: *MD_Node, + @doc("The node whose children are to be searched.") + node: *MD_Node, + @doc("The index that the return value should match.") + n: int, + @doc("The found node, or a nil node pointer if no such node was found.") + return: *MD_Node, }; @send(Nodes) +@doc("Finds a tag on @code 'node' with an index matching @code 'n'. Returns a nil node pointer if no such tag is found.") +@see(MD_NodeFromIndex) +@see(MD_IndexFromNode) +@see(MD_ChildFromIndex) @func MD_TagFromIndex: { - node: *MD_Node, - n: int, - return: *MD_Node, + @doc("The node whose tags are to be searched.") + node: *MD_Node, + @doc("The index that the return value should match.") + n: int, + @doc("The found node, or a nil node pointer if no such node was found.") + return: *MD_Node, }; @send(Nodes) +@doc("Finds the @code 'n'th tag argument of the tag matching @code 'tag_string' on @code 'node', with the matching on @code 'tag_string' being controlled by @code 'flags'. Returns a nil node pointer if no such node was found.") @func MD_TagArgFromIndex: { - node: *MD_Node, - tag_string: MD_String8, - n: int, - return: *MD_Node, + @doc("The node whose tags are to be searched.") + node: *MD_Node, + @doc("The string that the found tag should match.") + tag_string: MD_String8, + @doc("Controls what is considered a string match.") + flags: MD_MatchFlags, + @doc("The index that the return value should match.") + n: int, + @doc("The found node, or a nil node pointer if no such node was found.") + return: *MD_Node, }; @send(Nodes) +@doc("Finds the tag argument with a string matching @code 'arg_string', of the tag matching @code 'tag_string', on @code 'node'. Matching @code 'tag_string' is controlled by @code 'tag_str_flags'. Matching @code 'arg_string' is controlled by @code 'arg_str_flags'. Returns a nil node pointer if no such node was found.") +@func MD_TagArgFromString: { + @doc("The node whose tags are to be searched.") + node: *MD_Node, + @doc("The string that the found tag should match.") + tag_string: MD_String8, + @doc("Controls what is considered a string match, when finding the appropriate tag.") + tag_str_flags: MD_MatchFlags, + @doc("The string that the found tag argument should match.") + arg_string: int, + @doc("Controls what is considered a string match, when finding the appropriate tag argument.") + arg_str_flags: MD_MatchFlags, + @doc("The found node, or a nil node pointer if no such node was found.") + return: *MD_Node, +}; + +@send(Nodes) +@doc("Returns @code '1' if @code 'node' has a tag with a string matching @code 'tag_string', with the matching rules being controlled by @code 'flags', or @code '0' otherwise.") +@see(MD_TagFromIndex) +@see(MD_TagFromString) @func MD_NodeHasTag: { - node: *MD_Node, - tag_string: MD_String8, - return: MD_b32, + @doc("The node whose tags are to be searched.") + node: *MD_Node, + @doc("The string that should match a tag in @code 'node'.") + tag_string: MD_String8, + @doc("Controls what is considered a match, when comparing against @code 'tag_string'.") + flags: MD_MatchFlags, + @doc("@code '1' if a suitable tag was found, or @code '0' otherwise.") + return: MD_b32, }; @send(Nodes) +@doc("Returns the number of children of @code 'node'.") @func MD_ChildCountFromNode: { node: *MD_Node, return: MD_i64, }; @send(Nodes) +@doc("Returns the number of tags on @code 'node'.") @func MD_TagCountFromNode: { node: *MD_Node, return: MD_i64, }; @send(Nodes) -@macro MD_EachNode: { it, first, }; +@doc("A helper macro for building for-loops over entire lists of nodes. Place inside of the parentheses of a for-loop, e.g. @code 'for(MD_EachNode(child, node->first_child))', to use.") +@macro MD_EachNode: +{ + @doc("The name of the iterator node, as it will be available in the for-loop.") + it, + @doc("The first node to iterate on.") + first, +}; + +@send(Nodes) +@doc("A helper macro for building for-loops over entire lists of node references. Place inside of the parentheses of a for-loop, e.g. @code 'for(MD_EachNodeRef(child, node->first_child))', to use.") +@macro MD_EachNodeRef: +{ + @doc("The name of the dereferenced node from the iterator, as it will be available in the for-loop.") + it, + @doc("The first reference node to iterate on.") + first, +}; //////////////////////////////// //~ Error/Warning Helpers diff --git a/samples/c_code_generation.c b/samples/c_code_generation.c index be7d4d9..63053df 100644 --- a/samples/c_code_generation.c +++ b/samples/c_code_generation.c @@ -27,7 +27,7 @@ int main(int argument_count, char **arguments) printf("Generated C Code:\n"); for(MD_EachNode(node, code->first_child)) { - if(MD_NodeHasTag(node, MD_S8Lit("struct"))) + if(MD_NodeHasTag(node, MD_S8Lit("struct"), 0)) { MD_C_Generate_Struct(stdout, node); } diff --git a/samples/static_site_generator/static_site_generator.c b/samples/static_site_generator/static_site_generator.c index 61f3246..262b27f 100644 --- a/samples/static_site_generator/static_site_generator.c +++ b/samples/static_site_generator/static_site_generator.c @@ -382,17 +382,17 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf { char *html_tag = "p"; char *style = "paragraph"; - if(MD_NodeHasTag(node, MD_S8Lit("title"))) + if(MD_NodeHasTag(node, MD_S8Lit("title"), 0)) { html_tag = "h1"; style = "title"; } - else if(MD_NodeHasTag(node, MD_S8Lit("subtitle"))) + else if(MD_NodeHasTag(node, MD_S8Lit("subtitle"), 0)) { html_tag = "h2"; style = "subtitle"; } - else if(MD_NodeHasTag(node, MD_S8Lit("code"))) + else if(MD_NodeHasTag(node, MD_S8Lit("code"), 0)) { html_tag = "pre"; style = "code"; @@ -414,19 +414,19 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf MD_ParseResult parse = MD_ParseOneNode(MD_StringSubstring(strnode->string, i, strnode->string.size), 0); if(!MD_NodeIsNil(parse.node)) { - if(MD_NodeHasTag(node, MD_S8Lit("i"))) + if(MD_NodeHasTag(node, MD_S8Lit("i"), 0)) { fprintf(file, "%.*s", MD_StringExpand(parse.node->string)); } - else if(MD_NodeHasTag(node, MD_S8Lit("b"))) + else if(MD_NodeHasTag(node, MD_S8Lit("b"), 0)) { fprintf(file, "%.*s", MD_StringExpand(parse.node->string)); } - else if(MD_NodeHasTag(node, MD_S8Lit("code"))) + else if(MD_NodeHasTag(node, MD_S8Lit("code"), 0)) { fprintf(file, "%.*s", MD_StringExpand(parse.node->string)); } - else if(MD_NodeHasTag(node, MD_S8Lit("link"))) + else if(MD_NodeHasTag(node, MD_S8Lit("link"), 0)) { MD_Node *text = MD_ChildFromIndex(parse.node, 0); MD_Node *link = MD_ChildFromIndex(parse.node, 1); @@ -474,7 +474,7 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf if(!MD_NodeIsNil(node->first_child)) { - if(MD_NodeHasTag(node, MD_S8Lit("list"))) + if(MD_NodeHasTag(node, MD_S8Lit("list"), 0)) { fprintf(file, "\n"); } - else if(MD_NodeHasTag(node, MD_S8Lit("img"))) + else if(MD_NodeHasTag(node, MD_S8Lit("img"), 0)) { MD_Node *src = MD_ChildFromIndex(node, 0); MD_Node *alt = MD_ChildFromIndex(node, 1); fprintf(file, "
\n", MD_StringExpand(src->string)); } - else if(MD_NodeHasTag(node, MD_S8Lit("youtube"))) + else if(MD_NodeHasTag(node, MD_S8Lit("youtube"), 0)) { MD_Node *id = MD_ChildFromIndex(node, 0); fprintf(file, "\n", MD_StringExpand(id->string)); } - else if(MD_NodeHasTag(node, MD_S8Lit("lister"))) + else if(MD_NodeHasTag(node, MD_S8Lit("lister"), 0)) { static int lister_idx = 0; fprintf(file, "", lister_idx, lister_idx, lister_idx); diff --git a/samples/toy_language/toy_language.c b/samples/toy_language/toy_language.c index fd844bb..49d1fbf 100644 --- a/samples/toy_language/toy_language.c +++ b/samples/toy_language/toy_language.c @@ -194,7 +194,7 @@ int main(int argument_count, char **arguments) MD_Node *file = MD_Deref(file_ref); for(MD_EachNode(top_level, file->first_child)) { - if(MD_NodeHasTag(top_level, MD_S8Lit("proc"))) + if(MD_NodeHasTag(top_level, MD_S8Lit("proc"), 0)) { InsertValueToNamespace(&global_ns_node, top_level->string, MakeValue_Procedure(top_level)); } diff --git a/source/md.h b/source/md.h index d997a17..bb10b4b 100644 --- a/source/md.h +++ b/source/md.h @@ -727,7 +727,7 @@ MD_FUNCTION MD_ParseResult MD_ParseWholeFile(MD_String8 filename); //~ Location Conversion -MD_FUNCTION MD_CodeLoc MD_CodeLocFromFileBaseOff(MD_String8 filename, MD_u8 *base, MD_u8 *off); +MD_FUNCTION MD_CodeLoc MD_CodeLocFromFileBaseOffset(MD_String8 filename, MD_u8 *base, MD_u64 offset); MD_FUNCTION MD_CodeLoc MD_CodeLocFromNode(MD_Node *node); //~ Tree/List Building @@ -743,18 +743,17 @@ MD_FUNCTION MD_Node *MD_PushReference(MD_Node *list, MD_Node *target); //~ 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); +MD_FUNCTION MD_Node * MD_NodeFromString(MD_Node *first, MD_Node *one_past_last, MD_String8 string, MD_MatchFlags flags); +MD_FUNCTION MD_Node * MD_NodeFromIndex(MD_Node *first, MD_Node *one_past_last, int n); MD_FUNCTION int MD_IndexFromNode(MD_Node *node); MD_FUNCTION MD_Node * MD_RootFromNode(MD_Node *node); -MD_FUNCTION MD_Node * MD_NextNodeSibling(MD_Node *last, MD_String8 string); -MD_FUNCTION MD_Node * MD_ChildFromString(MD_Node *node, MD_String8 child_string); -MD_FUNCTION MD_Node * MD_TagFromString(MD_Node *node, MD_String8 tag_string); +MD_FUNCTION MD_Node * MD_ChildFromString(MD_Node *node, MD_String8 child_string, MD_MatchFlags flags); +MD_FUNCTION MD_Node * MD_TagFromString(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags); MD_FUNCTION MD_Node * MD_ChildFromIndex(MD_Node *node, int n); MD_FUNCTION MD_Node * MD_TagFromIndex(MD_Node *node, int n); -MD_FUNCTION MD_Node * MD_TagArgFromIndex(MD_Node *node, MD_String8 tag_string, int n); -MD_FUNCTION MD_Node * MD_TagArgFromString(MD_Node *node, MD_String8 tag_string, MD_String8 arg_string); -MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 tag_string); +MD_FUNCTION MD_Node * MD_TagArgFromIndex(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags, int n); +MD_FUNCTION MD_Node * MD_TagArgFromString(MD_Node *node, MD_String8 tag_string, MD_MatchFlags tag_str_flags, MD_String8 arg_string, MD_MatchFlags arg_str_flags); +MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags); MD_FUNCTION MD_i64 MD_ChildCountFromNode(MD_Node *node); MD_FUNCTION MD_i64 MD_TagCountFromNode(MD_Node *node); MD_FUNCTION MD_Node * MD_Deref(MD_Node *node); diff --git a/source/md_impl.c b/source/md_impl.c index d399124..9c36136 100644 --- a/source/md_impl.c +++ b/source/md_impl.c @@ -1923,7 +1923,7 @@ MD_ParseWholeFile(MD_String8 filename) //~ Location Conversions MD_FUNCTION_IMPL MD_CodeLoc -MD_CodeLocFromFileBaseOff(MD_String8 filename, MD_u8 *base, MD_u8 *at) +MD_CodeLocFromFileBaseOffset(MD_String8 filename, MD_u8 *base, MD_u64 offset) { MD_CodeLoc loc; loc.filename = filename; @@ -1931,6 +1931,7 @@ MD_CodeLocFromFileBaseOff(MD_String8 filename, MD_u8 *base, MD_u8 *at) loc.column = 1; if(base != 0) { + MD_u8 *at = base + offset; for(MD_u64 i = 0; base+i < at && base[i]; i += 1) { if(base[i] == '\n') @@ -1951,7 +1952,7 @@ MD_FUNCTION_IMPL MD_CodeLoc MD_CodeLocFromNode(MD_Node *node) { MD_Node *root = MD_RootFromNode(node); - MD_CodeLoc loc = MD_CodeLocFromFileBaseOff(root->string, root->whole_string.str, root->whole_string.str + node->offset); + MD_CodeLoc loc = MD_CodeLocFromFileBaseOffset(root->string, root->whole_string.str, node->offset); return loc; } @@ -2020,12 +2021,12 @@ MD_PushReference(MD_Node *list, MD_Node *target) //~ Introspection Helpers MD_FUNCTION_IMPL MD_Node * -MD_NodeFromString(MD_Node *first, MD_Node *last, MD_String8 string) +MD_NodeFromString(MD_Node *first, MD_Node *one_past_last, MD_String8 string, MD_MatchFlags flags) { MD_Node *result = MD_NilNode(); - for(MD_Node *node = first; !MD_NodeIsNil(node); node = node->next) + for(MD_Node *node = first; !MD_NodeIsNil(node) && node != one_past_last; node = node->next) { - if(MD_StringMatch(string, node->string, 0)) + if(MD_StringMatch(string, node->string, flags)) { result = node; break; @@ -2035,13 +2036,13 @@ MD_NodeFromString(MD_Node *first, MD_Node *last, MD_String8 string) } MD_FUNCTION_IMPL MD_Node * -MD_NodeFromIndex(MD_Node *first, MD_Node *last, int n) +MD_NodeFromIndex(MD_Node *first, MD_Node *one_past_last, int n) { MD_Node *result = MD_NilNode(); if(n >= 0) { int idx = 0; - for(MD_Node *node = first; !MD_NodeIsNil(node); node = node->next, idx += 1) + for(MD_Node *node = first; !MD_NodeIsNil(node) && node != one_past_last; node = node->next, idx += 1) { if(idx == n) { @@ -2057,10 +2058,7 @@ MD_FUNCTION_IMPL int MD_IndexFromNode(MD_Node *node) { int idx = 0; - if(node && !MD_NodeIsNil(node)) - { - for(MD_Node *last = node->prev; !MD_NodeIsNil(last); last = last->prev, idx += 1); - } + for(MD_Node *last = node->prev; !MD_NodeIsNil(last); last = last->prev, idx += 1); return idx; } @@ -2076,33 +2074,15 @@ MD_RootFromNode(MD_Node *node) } MD_FUNCTION_IMPL MD_Node * -MD_NextNodeSibling(MD_Node *last, MD_String8 string) +MD_ChildFromString(MD_Node *node, MD_String8 child_string, MD_MatchFlags flags) { - MD_Node *result = MD_NilNode(); - if(last) - { - for(MD_Node *node = last->next; node; node = node->next) - { - if(MD_StringMatch(string, node->string, 0)) - { - result = node; - break; - } - } - } - return result; + return MD_NodeFromString(node->first_child, MD_NilNode(), child_string, flags); } MD_FUNCTION_IMPL MD_Node * -MD_ChildFromString(MD_Node *node, MD_String8 child_string) +MD_TagFromString(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags) { - return MD_NodeFromString(node->first_child, node->last_child, child_string); -} - -MD_FUNCTION_IMPL MD_Node * -MD_TagFromString(MD_Node *node, MD_String8 tag_string) -{ - return MD_NodeFromString(node->first_tag, node->last_tag, tag_string); + return MD_NodeFromString(node->first_tag, MD_NilNode(), tag_string, flags); } MD_FUNCTION_IMPL MD_Node * @@ -2118,24 +2098,24 @@ MD_TagFromIndex(MD_Node *node, int n) } MD_FUNCTION_IMPL MD_Node * -MD_TagArgFromIndex(MD_Node *node, MD_String8 tag_string, int n) +MD_TagArgFromIndex(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags, int n) { - MD_Node *tag = MD_TagFromString(node, tag_string); + MD_Node *tag = MD_TagFromString(node, tag_string, flags); return MD_ChildFromIndex(tag, n); } MD_FUNCTION_IMPL MD_Node * -MD_TagArgFromString(MD_Node *node, MD_String8 tag_string, MD_String8 arg_string) +MD_TagArgFromString(MD_Node *node, MD_String8 tag_string, MD_MatchFlags tag_str_flags, MD_String8 arg_string, MD_MatchFlags arg_str_flags) { - MD_Node *tag = MD_TagFromString(node, tag_string); - MD_Node *arg = MD_ChildFromString(tag, arg_string); + MD_Node *tag = MD_TagFromString(node, tag_string, tag_str_flags); + MD_Node *arg = MD_ChildFromString(tag, arg_string, arg_str_flags); return arg; } MD_FUNCTION_IMPL MD_b32 -MD_NodeHasTag(MD_Node *node, MD_String8 tag_string) +MD_NodeHasTag(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags) { - return !MD_NodeIsNil(MD_TagFromString(node, tag_string)); + return !MD_NodeIsNil(MD_TagFromString(node, tag_string, flags)); } MD_FUNCTION_IMPL MD_i64 diff --git a/tests/grammar.c b/tests/grammar.c index 436e1f3..f9743f8 100644 --- a/tests/grammar.c +++ b/tests/grammar.c @@ -88,7 +88,7 @@ static void PrintRule(MD_Map *depth_map, MD_Node *rule) { MD_b32 is_literal_char = rule->flags & MD_NodeFlag_StringLiteral; - MD_b32 optional = MD_NodeHasTag(rule, MD_S8Lit(OPTIONAL_TAG)); + MD_b32 optional = MD_NodeHasTag(rule, MD_S8Lit(OPTIONAL_TAG), 0); if(optional) { @@ -163,7 +163,7 @@ static void ExpandRule(MD_Node *rule, MD_String8List *out_strings, MD_Node *cur_ for(MD_EachNode(rule_element, rule->first_child)) { MD_b32 expand = 1; - if(MD_NodeHasTag(rule_element, MD_S8Lit(OPTIONAL_TAG))) + if(MD_NodeHasTag(rule_element, MD_S8Lit(OPTIONAL_TAG), 0)) { expand = rand_U32(globals.random_series)%2; @@ -656,7 +656,7 @@ int main(int argument_count, char **arguments) ComputeElementDepth(depth_map, rule_element); MD_u64 depth = GET_DEPTH(depth_map, rule_element); - if(!MD_NodeHasTag(rule_element, MD_S8Lit(OPTIONAL_TAG))) + if(!MD_NodeHasTag(rule_element, MD_S8Lit(OPTIONAL_TAG), 0)) { MD_u64 depth = 0; MD_Assert(MD_NodeIsNil(rule_element->first_child)); diff --git a/tests/sanity_tests.c b/tests/sanity_tests.c index 80c6647..ab46c19 100644 --- a/tests/sanity_tests.c +++ b/tests/sanity_tests.c @@ -744,19 +744,19 @@ int main(void) { MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("@foo bar")); - TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("foo"))); + TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("foo"), 0)); } { MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("@+ bar")); - TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("+"))); + TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("+"), 0)); } { MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("@'a b c' bar")); - TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("a b c"))); + TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("a b c"), 0)); } { MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("@100 bar")); - TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("100"))); + TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("100"), 0)); } }