[impl] passing over parser implementation (pass 1)

This commit is contained in:
Allen Webster
2021-06-05 23:39:26 -07:00
parent c3ec42c70c
commit dd445676f5
8 changed files with 96 additions and 51 deletions
+7
View File
@@ -1136,6 +1136,13 @@ main:
tag: *MD_Node, tag: *MD_Node,
}; };
@send(Nodes)
@func MD_PushReference: {
list: *MD_Node,
target: *MD_Node,
return: *MD_Node,
};
//////////////////////////////// ////////////////////////////////
//~ Introspection Helpers //~ Introspection Helpers
+2
View File
@@ -5,6 +5,8 @@
int main(int argument_count, char **arguments) int main(int argument_count, char **arguments)
{ {
// TODO(allen): use list system
// NOTE(rjf): Parse all the files passed in via command line. // NOTE(rjf): Parse all the files passed in via command line.
MD_Node *first = MD_NilNode(); MD_Node *first = MD_NilNode();
MD_Node *last = MD_NilNode(); MD_Node *last = MD_NilNode();
+2
View File
@@ -23,6 +23,8 @@ CleanUp(void)
int main(int argument_count, char **arguments) int main(int argument_count, char **arguments)
{ {
// TODO(allen): use list system
// NOTE(rjf): Parse all the files passed in via command line. // NOTE(rjf): Parse all the files passed in via command line.
MD_Node *first = MD_NilNode(); MD_Node *first = MD_NilNode();
MD_Node *last = MD_NilNode(); MD_Node *last = MD_NilNode();
+2
View File
@@ -58,6 +58,8 @@ static void PrintNode(MD_Node* node, FILE* file, int indent_count) {
int main(int argument_count, char **arguments) int main(int argument_count, char **arguments)
{ {
// TODO(allen): use list system
// NOTE(pmh): Parse all the files passed in via command line. // NOTE(pmh): Parse all the files passed in via command line.
MD_Node *first = MD_NilNode(); MD_Node *first = MD_NilNode();
MD_Node *last = MD_NilNode(); MD_Node *last = MD_NilNode();
@@ -55,6 +55,8 @@ int main(int argument_count, char **arguments)
site_info = ParseSiteInfo(site_info_file); site_info = ParseSiteInfo(site_info_file);
} }
// TODO(allen): use list system
//~ NOTE(rjf): Parse pages. //~ NOTE(rjf): Parse pages.
MD_Node *first_root = MD_NilNode(); MD_Node *first_root = MD_NilNode();
MD_Node *last_root = MD_NilNode(); MD_Node *last_root = MD_NilNode();
+2
View File
@@ -179,6 +179,8 @@ int main(int argument_count, char **arguments)
//- rjf: parse command line //- rjf: parse command line
MD_CommandLine cmdln = MD_CommandLineFromOptions(MD_StringListFromArgCV(argument_count, arguments)); MD_CommandLine cmdln = MD_CommandLineFromOptions(MD_StringListFromArgCV(argument_count, arguments));
// TODO(allen): use list system
//- rjf: parse all input files //- rjf: parse all input files
MD_Node *first_file = MD_NilNode(); MD_Node *first_file = MD_NilNode();
MD_Node *last_file = MD_NilNode(); MD_Node *last_file = MD_NilNode();
+3 -2
View File
@@ -334,6 +334,8 @@ enum
MD_NodeFlag_CharLiteral = (1<<13), MD_NodeFlag_CharLiteral = (1<<13),
}; };
#define MD_NodeFlag_AfterFromBefore(f) ((f) << 2)
typedef struct MD_Node MD_Node; typedef struct MD_Node MD_Node;
struct MD_Node struct MD_Node
{ {
@@ -708,12 +710,11 @@ MD_FUNCTION MD_Node *MD_NilNode(void);
MD_FUNCTION MD_Node *MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_FUNCTION MD_Node *MD_MakeNode(MD_NodeKind kind, MD_String8 string,
MD_String8 whole_string, MD_String8 filename, MD_String8 whole_string, MD_String8 filename,
MD_u8 *file_contents, MD_u8 *at); MD_u8 *file_contents, MD_u8 *at);
MD_FUNCTION MD_Node *MD_MakeNodeFromString(MD_NodeKind kind, MD_String8 filename, MD_u8 *file, MD_u8 *at, MD_String8 string);
MD_FUNCTION MD_Node *MD_MakeNodeReference(MD_Node *target);
MD_FUNCTION void MD_PushSibling(MD_Node **first, MD_Node **last, MD_Node *new_sibling); 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_PushChild(MD_Node *parent, MD_Node *new_child);
MD_FUNCTION void MD_PushTag(MD_Node *node, MD_Node *tag); MD_FUNCTION void MD_PushTag(MD_Node *node, MD_Node *tag);
MD_FUNCTION void MD_InsertToNamespace(MD_Node *ns, MD_Node *node); MD_FUNCTION void MD_InsertToNamespace(MD_Node *ns, MD_Node *node);
MD_FUNCTION MD_Node *MD_PushReference(MD_Node *list, MD_Node *target);
//~ Introspection Helpers //~ Introspection Helpers
MD_FUNCTION MD_Node * MD_NodeFromString(MD_Node *first, MD_Node *last, MD_String8 string); MD_FUNCTION MD_Node * MD_NodeFromString(MD_Node *first, MD_Node *last, MD_String8 string);
+76 -49
View File
@@ -1667,37 +1667,56 @@ MD_Parse_RequireKind(MD_ParseCtx *ctx, MD_TokenKind kind, MD_Token *out_token)
MD_FUNCTION_IMPL void MD_FUNCTION_IMPL void
MD_Parse_Set(MD_ParseCtx *ctx, MD_Node *parent, MD_ParseSetFlags flags) MD_Parse_Set(MD_ParseCtx *ctx, MD_Node *parent, MD_ParseSetFlags flags)
{ {
MD_b32 brace = 0;
MD_b32 paren = 0;
MD_b32 bracket = 0;
MD_b32 terminate_with_separator = (!!(flags & MD_ParseSetFlag_Implicit));
MD_Token initial_token = MD_Parse_PeekSkipSome(ctx, MD_TokenGroup_Comment|MD_TokenGroup_Whitespace); MD_Token initial_token = MD_Parse_PeekSkipSome(ctx, MD_TokenGroup_Comment|MD_TokenGroup_Whitespace);
// check for set opener
MD_u8 set_opener = 0;
if((flags & MD_ParseSetFlag_Brace) && if((flags & MD_ParseSetFlag_Brace) &&
MD_Parse_Require(ctx, MD_S8Lit("{"), MD_TokenKind_Symbol)) MD_Parse_Require(ctx, MD_S8Lit("{"), MD_TokenKind_Symbol))
{ {
parent->flags |= MD_NodeFlag_BraceLeft; set_opener = '{';
brace = 1;
terminate_with_separator = 0;
} }
else if((flags & MD_ParseSetFlag_Paren) && else if((flags & MD_ParseSetFlag_Paren) &&
MD_Parse_Require(ctx, MD_S8Lit("("), MD_TokenKind_Symbol)) MD_Parse_Require(ctx, MD_S8Lit("("), MD_TokenKind_Symbol))
{ {
parent->flags |= MD_NodeFlag_ParenLeft; set_opener = '(';
paren = 1;
terminate_with_separator = 0;
} }
else if((flags & MD_ParseSetFlag_Bracket) && else if((flags & MD_ParseSetFlag_Bracket) &&
MD_Parse_Require(ctx, MD_S8Lit("["), MD_TokenKind_Symbol)) MD_Parse_Require(ctx, MD_S8Lit("["), MD_TokenKind_Symbol))
{ {
parent->flags |= MD_NodeFlag_BracketLeft; set_opener = '[';
bracket = 1; }
terminate_with_separator = 0;
// something else
MD_b32 brace = 0;
MD_b32 paren = 0;
MD_b32 bracket = 0;
MD_b32 terminate_with_separator = 0;
switch (set_opener){
default:
{
terminate_with_separator = (!!(flags & MD_ParseSetFlag_Implicit));
}break;
case '{':
{
parent->flags |= MD_NodeFlag_BraceLeft;
brace = 1;
}break;
case '(':
{
parent->flags |= MD_NodeFlag_ParenLeft;
paren = 1;
}break;
case '[':
{
parent->flags |= MD_NodeFlag_BracketLeft;
bracket = 1;
}break;
} }
// NOTE(rjf): Parse children. // NOTE(rjf): Parse children.
if(brace || paren || bracket || terminate_with_separator) if((set_opener != 0) || terminate_with_separator)
{ {
MD_u8 *at_before_children = ctx->at; MD_u8 *at_before_children = ctx->at;
MD_NodeFlags next_child_flags = 0; MD_NodeFlags next_child_flags = 0;
@@ -1738,30 +1757,35 @@ MD_Parse_Set(MD_ParseCtx *ctx, MD_Node *parent, MD_ParseSetFlags flags)
} }
} }
// NOTE(allen): parse the next node
MD_ParseResult parse = MD_ParseOneNodeFromCtx(ctx); MD_ParseResult parse = MD_ParseOneNodeFromCtx(ctx);
MD_Node *child = parse.node; MD_Node *child = parse.node;
child->flags |= next_child_flags;
next_child_flags = 0;
if(MD_NodeIsNil(child)) if(MD_NodeIsNil(child))
{ {
if(brace || paren || bracket) if(set_opener != 0)
{ {
char delimiter_char = 0;
if(brace) delimiter_char = '{';
else if(paren) delimiter_char = '(';
else if(bracket) delimiter_char = '[';
MD_PushTokenErrorF(ctx, initial_token, MD_MessageKind_CatastrophicError, MD_PushTokenErrorF(ctx, initial_token, MD_MessageKind_CatastrophicError,
"Unbalanced \"%c\"", delimiter_char); "Unbalanced \"%c\"", set_opener);
} }
goto end_parse; goto end_parse;
} }
else
{ // connect node into graph
MD_PushSibling(&parent->first_child, &parent->last_child, child); MD_PushChild(parent, child);
child->parent = parent;
} // fill flags from surrounding context
child->flags |= next_child_flags;
// TODO(allen): I find it kind of concerning that ParseWholeString and
// ParseOneNode are both doing this. I did some refactors in the
// ParseWholeString to break it down into flatter blocks, not realizing
// very similar logic happens here too.
// I also see that these really are slightly different, but it seems
// like it should be possible to express the whole-string case as a
// special case of this and avoid the duplication.
// NOTE(rjf): Separators. // NOTE(rjf): Separators.
next_child_flags = 0;
{ {
MD_b32 result = 0; MD_b32 result = 0;
if(terminate_with_separator) if(terminate_with_separator)
@@ -2108,29 +2132,31 @@ MD_ParseWholeString(MD_String8 filename, MD_String8 contents)
// NOTE(allen): parse the next node // NOTE(allen): parse the next node
MD_ParseResult parse = MD_ParseOneNodeFromCtx(&ctx); MD_ParseResult parse = MD_ParseOneNodeFromCtx(&ctx);
MD_Node *child = parse.node; MD_Node *child = parse.node;
child->flags |= next_child_flags;
next_child_flags = 0;
if(MD_NodeIsNil(child)) if(MD_NodeIsNil(child))
{ {
break; break;
} }
else
{
MD_PushSibling(&root->first_child, &root->last_child, child);
child->parent = root;
MD_InsertToNamespace(selected_namespace, child);
}
// connect node into graph
MD_PushChild(root, child);
MD_InsertToNamespace(selected_namespace, child);
// check trailing symbol
MD_u32 symbol_flags = 0;
if(MD_Parse_Require(&ctx, MD_S8Lit(","), MD_TokenKind_Symbol)) if(MD_Parse_Require(&ctx, MD_S8Lit(","), MD_TokenKind_Symbol))
{ {
child->flags |= MD_NodeFlag_BeforeComma; symbol_flags = MD_NodeFlag_BeforeComma;
next_child_flags |= MD_NodeFlag_AfterComma;
} }
else if(MD_Parse_Require(&ctx, MD_S8Lit(";"), MD_TokenKind_Symbol)) else if(MD_Parse_Require(&ctx, MD_S8Lit(";"), MD_TokenKind_Symbol))
{ {
child->flags |= MD_NodeFlag_BeforeSemicolon; symbol_flags = MD_NodeFlag_BeforeSemicolon;
next_child_flags |= MD_NodeFlag_AfterSemicolon;
} }
// fill flags from surrounding context
child->flags |= next_child_flags|symbol_flags;
// setup next_child_flags
next_child_flags = MD_NodeFlag_AfterFromBefore(symbol_flags);
} }
result.namespaces = namespaces; result.namespaces = namespaces;
result.bytes_parsed = (MD_u64)(ctx.at - contents.str); result.bytes_parsed = (MD_u64)(ctx.at - contents.str);
@@ -2215,15 +2241,6 @@ MD_MakeNode(MD_NodeKind kind, MD_String8 string,
return node; return node;
} }
MD_FUNCTION_IMPL MD_Node *
MD_MakeNodeReference(MD_Node *target)
{
MD_String8 string = MD_S8Lit("`reference node`");
MD_Node *n = MD_MakeNode(MD_NodeKind_Reference, string, string, string, 0, 0);
n->ref_target = target;
return n;
}
MD_FUNCTION_IMPL void MD_FUNCTION_IMPL void
MD_PushSibling(MD_Node **firstp, MD_Node **lastp, MD_Node *node) MD_PushSibling(MD_Node **firstp, MD_Node **lastp, MD_Node *node)
{ {
@@ -2272,6 +2289,16 @@ MD_InsertToNamespace(MD_Node *ns, MD_Node *node)
MD_PushChild(ns, ref); MD_PushChild(ns, ref);
} }
MD_FUNCTION_IMPL MD_Node*
MD_PushReference(MD_Node *list, MD_Node *target)
{
MD_String8 string = MD_S8Lit("`reference node`");
MD_Node *n = MD_MakeNode(MD_NodeKind_Reference, string, string, string, 0, 0);
n->ref_target = target;
MD_PushChild(list, n);
return(n);
}
//~ Introspection Helpers //~ Introspection Helpers
MD_FUNCTION_IMPL MD_Node * MD_FUNCTION_IMPL MD_Node *