From d213f0362fdcaf06b52ef041f7aec9f8108d8b9c Mon Sep 17 00:00:00 2001 From: ryanfleury Date: Wed, 18 Aug 2021 01:46:55 -0600 Subject: [PATCH] string generation feature options + implementations + tests --- source/md.c | 117 ++++++++++++++++++++++++++++++++++--------- source/md.h | 22 +++++++- tests/sanity_tests.c | 28 +++++++++++ 3 files changed, 141 insertions(+), 26 deletions(-) diff --git a/source/md.c b/source/md.c index cc56f62..252f33e 100644 --- a/source/md.c +++ b/source/md.c @@ -2846,7 +2846,7 @@ MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags) //~ String Generation MD_FUNCTION_IMPL MD_String8List -MD_DebugStringListFromNode(MD_Arena *arena, MD_Node *node, int indent, MD_String8 indent_string) +MD_DebugStringListFromNode(MD_Arena *arena, MD_Node *node, int indent, MD_String8 indent_string, MD_GenerateFlags flags) { MD_String8List list = {0}; #define MD_PrintIndent(_indent_level) do\ @@ -2857,38 +2857,92 @@ MD_S8ListPush(arena, &list, indent_string);\ }\ }while(0) - //- rjf: tags of node - for(MD_EachNode(tag, node->first_tag)) + //- rjf: prev-comment + if(flags & MD_GenerateFlag_Comments && node->prev_comment.size != 0) { MD_PrintIndent(indent); - MD_S8ListPush(arena, &list, MD_S8Lit("@")); - MD_S8ListPush(arena, &list, tag->string); - if(!MD_NodeIsNil(tag->first_child)) + MD_S8ListPush(arena, &list, MD_S8Lit("/*\n")); + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, node->prev_comment); + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, MD_S8Lit("\n")); + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, MD_S8Lit("*/\n")); + } + + //- rjf: tags of node + if(flags & MD_GenerateFlag_Tags) + { + for(MD_EachNode(tag, node->first_tag)) { - int tag_arg_indent = indent + 1 + tag->string.size + 1; - MD_S8ListPush(arena, &list, MD_S8Lit("(")); - for(MD_EachNode(child, tag->first_child)) + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, MD_S8Lit("@")); + MD_S8ListPush(arena, &list, tag->string); + if(flags & MD_GenerateFlag_TagArguments && !MD_NodeIsNil(tag->first_child)) { - int child_indent = tag_arg_indent; - if(MD_NodeIsNil(child->prev)) + int tag_arg_indent = indent + 1 + tag->string.size + 1; + MD_S8ListPush(arena, &list, MD_S8Lit("(")); + for(MD_EachNode(child, tag->first_child)) { - child_indent = 0; - } - MD_String8List child_strings = MD_DebugStringListFromNode(arena, child, child_indent, MD_S8Lit(" ")); - MD_S8ListConcat(&list, &child_strings); - if(!MD_NodeIsNil(child->next)) - { - MD_S8ListPush(arena, &list, MD_S8Lit(",\n")); + int child_indent = tag_arg_indent; + if(MD_NodeIsNil(child->prev)) + { + child_indent = 0; + } + MD_String8List child_strings = MD_DebugStringListFromNode(arena, child, child_indent, MD_S8Lit(" "), flags); + MD_S8ListConcat(&list, &child_strings); + if(!MD_NodeIsNil(child->next)) + { + MD_S8ListPush(arena, &list, MD_S8Lit(",\n")); + } } + MD_S8ListPush(arena, &list, MD_S8Lit(")\n")); + } + else + { + MD_S8ListPush(arena, &list, MD_S8Lit("\n")); } - MD_S8ListPush(arena, &list, MD_S8Lit(")\n")); - } - else - { - MD_S8ListPush(arena, &list, MD_S8Lit("\n")); } } + //- rjf: node kind + if(flags & MD_GenerateFlag_NodeKind) + { + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, MD_S8Lit("// kind: \"")); + MD_S8ListPush(arena, &list, MD_StringFromNodeKind(node->kind)); + MD_S8ListPush(arena, &list, MD_S8Lit("\"\n")); + } + + //- rjf: node flags + if(flags & MD_GenerateFlag_NodeFlags) + { + MD_PrintIndent(indent); + MD_ArenaTemp scratch = MD_GetScratch(&arena, 1); + MD_String8List flag_strs = MD_StringListFromNodeFlags(scratch.arena, node->flags); + MD_StringJoin join = { MD_S8Lit(""), MD_S8Lit("|"), MD_S8Lit("") }; + MD_String8 flag_str = MD_S8ListJoin(arena, flag_strs, &join); + MD_S8ListPush(arena, &list, MD_S8Lit("// flags: \"")); + MD_S8ListPush(arena, &list, flag_str); + MD_S8ListPush(arena, &list, MD_S8Lit("\"\n")); + MD_ReleaseScratch(scratch); + } + + //- rjf: node string hash + if(flags & MD_GenerateFlag_StringHash) + { + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, MD_S8Fmt(arena, "// string hash: 0x%llx\n", node->string_hash)); + } + + if(flags & MD_GenerateFlag_Location) + { + MD_PrintIndent(indent); + MD_CodeLoc loc = MD_CodeLocFromNode(node); + MD_String8 string = MD_S8Fmt(arena, "// location: %.*s:%i:%i\n", loc.filename, (int)loc.line, (int)loc.column); + MD_S8ListPush(arena, &list, string); + } + //- rjf: name of node if(node->string.size != 0) { @@ -2906,7 +2960,7 @@ MD_S8ListPush(arena, &list, indent_string);\ } //- rjf: children list - if(!MD_NodeIsNil(node->first_child)) + if(flags & MD_GenerateFlag_Children && !MD_NodeIsNil(node->first_child)) { if(node->string.size != 0) { @@ -2916,7 +2970,7 @@ MD_S8ListPush(arena, &list, indent_string);\ MD_S8ListPush(arena, &list, MD_S8Lit("{\n")); for(MD_EachNode(child, node->first_child)) { - MD_String8List child_strings = MD_DebugStringListFromNode(arena, child, indent+1, indent_string); + MD_String8List child_strings = MD_DebugStringListFromNode(arena, child, indent+1, indent_string, flags); MD_S8ListConcat(&list, &child_strings); MD_S8ListPush(arena, &list, MD_S8Lit(",\n")); } @@ -2924,6 +2978,19 @@ MD_S8ListPush(arena, &list, indent_string);\ MD_S8ListPush(arena, &list, MD_S8Lit("}")); } + //- rjf: next-comment + if(flags & MD_GenerateFlag_Comments && node->next_comment.size != 0) + { + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, MD_S8Lit("\n/*\n")); + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, node->next_comment); + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, MD_S8Lit("\n")); + MD_PrintIndent(indent); + MD_S8ListPush(arena, &list, MD_S8Lit("*/\n")); + } + #undef MD_PrintIndent return list; } diff --git a/source/md.h b/source/md.h index 53a4729..cae0879 100644 --- a/source/md.h +++ b/source/md.h @@ -650,6 +650,26 @@ struct MD_ParseResult MD_MessageList errors; }; +//~ String Generation Types + +typedef MD_u32 MD_GenerateFlags; +enum +{ + MD_GenerateFlag_Tags = (1<<0), + MD_GenerateFlag_TagArguments = (1<<1), + MD_GenerateFlag_Children = (1<<2), + MD_GenerateFlag_Comments = (1<<3), + MD_GenerateFlag_NodeKind = (1<<4), + MD_GenerateFlag_NodeFlags = (1<<5), + MD_GenerateFlag_StringHash = (1<<6), + MD_GenerateFlag_Location = (1<<7), + + MD_GenerateFlags_Tree = (MD_GenerateFlag_Tags | + MD_GenerateFlag_TagArguments | + MD_GenerateFlag_Children), + MD_GenerateFlags_All = 0xffffffff, +}; + //~ Command line parsing helper types. typedef struct MD_CmdLineOption MD_CmdLineOption; @@ -963,7 +983,7 @@ MD_FUNCTION MD_b32 MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags) //~ String Generation -MD_FUNCTION MD_String8List MD_DebugStringListFromNode(MD_Arena *arena, MD_Node *node, int indent, MD_String8 indent_string); +MD_FUNCTION MD_String8List MD_DebugStringListFromNode(MD_Arena *arena, MD_Node *node, int indent, MD_String8 indent_string, MD_GenerateFlags flags); //~ Command Line Argument Helper diff --git a/tests/sanity_tests.c b/tests/sanity_tests.c index 40b07f1..6534336 100644 --- a/tests/sanity_tests.c +++ b/tests/sanity_tests.c @@ -898,5 +898,33 @@ int main(void) } } + Test("Debug Strings") + { + { + MD_String8 code = MD_S8Lit("@foo @bar @baz a: { b c d e f }"); + MD_String8 expected = MD_S8Lit("@foo\n@bar\n@baz\na:\n{\n b,\n c,\n d,\n e,\n f,\n}"); + MD_ParseResult parse = MD_ParseOneNode(arena, code, 0); + MD_String8List actual_strings = MD_DebugStringListFromNode(arena, parse.node, 0, MD_S8Lit(" "), MD_GenerateFlags_Tree); + MD_String8 actual = MD_S8ListJoin(arena, actual_strings, 0); + TestResult(MD_S8Match(expected, actual, 0)); + } + { + MD_String8 code = MD_S8Lit("@foo(1, 2, 3) a: { x y }"); + MD_String8 expected = MD_S8Lit("@foo(1,\n 2,\n 3)\na:\n{\n x,\n y,\n}"); + MD_ParseResult parse = MD_ParseOneNode(arena, code, 0); + MD_String8List actual_strings = MD_DebugStringListFromNode(arena, parse.node, 0, MD_S8Lit(" "), MD_GenerateFlags_Tree); + MD_String8 actual = MD_S8ListJoin(arena, actual_strings, 0); + TestResult(MD_S8Match(expected, actual, 0)); + } + { + MD_String8 code = MD_S8Lit("// foo\na"); + MD_String8 expected = MD_S8Lit("/*\n foo\n*/\na"); + MD_ParseResult parse = MD_ParseOneNode(arena, code, 0); + MD_String8List actual_strings = MD_DebugStringListFromNode(arena, parse.node, 0, MD_S8Lit(" "), MD_GenerateFlags_Tree|MD_GenerateFlag_Comments); + MD_String8 actual = MD_S8ListJoin(arena, actual_strings, 0); + TestResult(MD_S8Match(expected, actual, 0)); + } + } + return 0; }