mirror of
https://github.com/Ed94/metadesk.git
synced 2026-08-06 15:48:47 +00:00
[impl] passing over parser implementation (pass 1)
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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 *
|
||||||
|
|||||||
Reference in New Issue
Block a user