[namespaces] Build namespaces as lists of reference nodes.

This commit is contained in:
Miguel Lechon
2021-03-29 17:51:36 +02:00
parent 230fd4043c
commit c38bc6de30
3 changed files with 49 additions and 17 deletions
+10 -4
View File
@@ -298,7 +298,8 @@ typedef enum MD_NodeKind
{
MD_NodeKind_Nil,
MD_NodeKind_File,
MD_NodeKind_Namespace,
MD_NodeKind_List,
MD_NodeKind_Reference,
MD_NodeKind_Label,
MD_NodeKind_Tag,
MD_NodeKind_ErrorMarker,
@@ -355,6 +356,7 @@ struct MD_Node
MD_String8 string;
MD_String8 whole_string;
MD_u64 string_hash;
MD_Node *ref_target;
// Comments.
MD_String8 comment_before;
@@ -501,8 +503,6 @@ struct MD_ParseCtx
MD_u8 *at;
MD_String8 filename;
MD_String8 file_contents;
MD_Map namespace_table;
MD_Node *selected_namespace;
MD_MessageKind error_level;
};
@@ -512,6 +512,7 @@ struct MD_ParseResult
MD_Node *node;
MD_Error *first_error;
MD_u64 bytes_parsed;
MD_Node *namespaces;
};
//~ Expression and Type-Expression parser helper types.
@@ -728,6 +729,7 @@ MD_FUNCTION MD_Node *MD_MakeNodeFromString(MD_NodeKind kind, MD_String8 filename
MD_FUNCTION void MD_PushSibling(MD_Node **first, MD_Node **last, MD_Node *parent, MD_Node *new_sibling);
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_InsertToNamespace(MD_Node *ns, MD_Node *node);
//~ Introspection Helpers
MD_FUNCTION MD_Node * MD_NodeFromString(MD_Node *first, MD_Node *last, MD_String8 string);
@@ -743,8 +745,12 @@ MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 tag_string);
MD_FUNCTION MD_CodeLoc MD_CodeLocFromNode(MD_Node *node);
MD_FUNCTION MD_i64 MD_ChildCountFromNode(MD_Node *node);
MD_FUNCTION MD_i64 MD_TagCountFromNode(MD_Node *node);
// NOTE(rjf): For-Loop Helper
MD_FUNCTION MD_Node * MD_Deref(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_Deref(it##_r); \
!MD_NodeIsNil(it##_r); \
it##_r = it##_r->next, it = MD_Deref(it##_r)
//~ Error/Warning Helpers
MD_FUNCTION void MD_NodeMessage(MD_Node *node, MD_MessageKind kind, MD_String8 str);
+38 -12
View File
@@ -24,7 +24,8 @@ static MD_Node _md_nil_node =
0, // flags
MD_ZERO_STRUCT, // string
MD_ZERO_STRUCT, // whole_string
0xdeadffffffffffull,
0xdeadffffffffffull, // string_hash
&_md_nil_node, // ref_target
{(MD_u8*)"`NIL DD NODE`", 13},
0,
0,
@@ -666,9 +667,11 @@ MD_StringFromNodeKind(MD_NodeKind kind)
{
"Nil",
"File",
"Namespace",
"List",
"Reference",
"Label",
"Tag",
"ErrorMarker",
};
return MD_S8CString(cstrs[kind]);
}
@@ -1603,7 +1606,7 @@ _MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 whole_string, MD_St
node->kind = kind;
node->string = string;
node->whole_string = whole_string;
node->next = node->prev = node->parent = node->first_child = node->last_child = node->first_tag = node->last_tag = MD_NilNode();
node->next = node->prev = node->parent = node->first_child = node->last_child = node->first_tag = node->last_tag = node->ref_target = MD_NilNode();
node->filename = filename;
node->file_contents = file_contents;
node->at = at;
@@ -2060,10 +2063,13 @@ MD_ParseOneNode(MD_String8 filename, MD_String8 contents)
return _MD_ParseOneNode(&ctx);
}
// TODO(mal): Make this public once the full story for namespaces is in place
MD_PRIVATE_FUNCTION_IMPL void
_MD_InsertToNamespace(MD_Node *ns, MD_Node *node)
MD_InsertToNamespace(MD_Node *ns, MD_Node *node)
{
MD_Node *ref = _MD_MakeNode(MD_NodeKind_Reference, node->string, node->whole_string, node->filename,
node->file_contents, node->at);
ref->ref_target = node;
MD_PushChild(ns, ref);
}
MD_FUNCTION MD_ParseResult
@@ -2076,6 +2082,14 @@ MD_ParseWholeString(MD_String8 filename, MD_String8 contents)
// NOTE(mal): Parse the content of the file as the inside of a set
MD_ParseCtx ctx = MD_Parse_InitializeCtx(filename, contents);
MD_NodeFlags next_child_flags = 0;
MD_Node *namespaces = _MD_MakeNodeFromString_Ctx(&ctx, MD_NodeKind_List, MD_S8Lit(""), ctx.at);
MD_Node *default_namespace = _MD_MakeNodeFromString_Ctx(&ctx, MD_NodeKind_List, MD_S8Lit(""), ctx.at);
MD_PushChild(namespaces, default_namespace);
MD_Node *selected_namespace = default_namespace;
MD_Map namespace_table = {0};
MD_StringMap_Insert(&namespace_table, MD_MapCollisionRule_Overwrite, default_namespace->string, default_namespace);
for(MD_u64 child_idx = 0;; child_idx += 1)
{
// NOTE(rjf): #-things (just namespaces right now, but can be used for other such
@@ -2088,19 +2102,20 @@ MD_ParseWholeString(MD_String8 filename, MD_String8 contents)
MD_Token token = MD_ZERO_STRUCT;
if(MD_Parse_RequireKind(&ctx, MD_TokenKind_Identifier, &token))
{
MD_MapSlot *existing_namespace_slot = MD_StringMap_Lookup(&ctx.namespace_table, token.string);
MD_MapSlot *existing_namespace_slot = MD_StringMap_Lookup(&namespace_table, token.string);
if(existing_namespace_slot == 0)
{
MD_Node *ns = _MD_MakeNodeFromString_Ctx(&ctx, MD_NodeKind_Namespace, token.string,
MD_Node *ns = _MD_MakeNodeFromString_Ctx(&ctx, MD_NodeKind_List, token.string,
token.outer_string.str);
MD_StringMap_Insert(&ctx.namespace_table, MD_MapCollisionRule_Overwrite, token.string, ns);
existing_namespace_slot = MD_StringMap_Lookup(&ctx.namespace_table, token.string);
MD_StringMap_Insert(&namespace_table, MD_MapCollisionRule_Overwrite, token.string, ns);
existing_namespace_slot = MD_StringMap_Lookup(&namespace_table, token.string);
MD_PushChild(namespaces, ns);
}
ctx.selected_namespace = (MD_Node *)existing_namespace_slot->value;
selected_namespace = (MD_Node *)existing_namespace_slot->value;
}
else
{
ctx.selected_namespace = 0;
selected_namespace = default_namespace;
}
}
// NOTE(rjf): Not a valid hash thing
@@ -2123,7 +2138,7 @@ MD_ParseWholeString(MD_String8 filename, MD_String8 contents)
else
{
_MD_PushNodeToList(&root->first_child, &root->last_child, root, child);
_MD_InsertToNamespace(ctx.selected_namespace, child);
MD_InsertToNamespace(selected_namespace, child);
}
if(MD_Parse_Require(&ctx, MD_S8Lit(","), MD_TokenKind_Symbol))
@@ -2137,6 +2152,7 @@ MD_ParseWholeString(MD_String8 filename, MD_String8 contents)
next_child_flags |= MD_NodeFlag_AfterSemicolon;
}
}
result.namespaces = namespaces;
result.bytes_parsed = (MD_u64)(ctx.at - contents.str);
result.first_error = ctx.first_error;
}
@@ -2417,6 +2433,16 @@ MD_TagCountFromNodeAndString(MD_Node *node, MD_String8 string, MD_StringMatchFla
return result;
}
MD_FUNCTION_IMPL MD_Node * MD_Deref(MD_Node *node)
{
MD_Node *result = node;
while(result->kind == MD_NodeKind_Reference)
{
result = result->ref_target;
}
return result;
}
MD_FUNCTION_IMPL void
MD_NodeMessage(MD_Node *node, MD_MessageKind kind, MD_String8 str)
{
+1 -1
View File
@@ -500,7 +500,7 @@ FirstBadNodeAtPointer(MD_Node *node)
}
}
} break;
case MD_NodeKind_Namespace:
case MD_NodeKind_List:
case MD_NodeKind_Tag:
{
if(node->at != node->whole_string.str)