mirror of
https://github.com/Ed94/metadesk.git
synced 2026-06-23 20:25:00 -07:00
[namespaces] Build namespaces as lists of reference nodes.
This commit is contained in:
+10
-4
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user