big naming pass for main API

This commit is contained in:
ryanfleury
2021-07-02 17:15:51 -06:00
parent 33bde8cc2f
commit 9ff0392f04
24 changed files with 1226 additions and 1181 deletions
+157 -125
View File
@@ -259,49 +259,62 @@ struct MD_String8List
MD_String8Node *last;
};
// NOTE(rjf): @maintenance These three enums must not overlap, and must share a flag space.
typedef MD_u32 MD_MatchFlags;
typedef MD_u32 MD_StringMatchFlags;
typedef MD_u32 MD_NodeMatchFlags;
enum
{
MD_MatchFlag_CaseInsensitive = (1<<0),
MD_MatchFlag_RightSideSloppy = (1<<1),
MD_MatchFlag_FindLast = (1<<2),
MD_MatchFlag_SlashInsensitive = (1<<3),
MD_MatchFlag_Tags = (1<<4),
MD_MatchFlag_TagArguments = (1<<5),
MD_MatchFlag_FindLast = (1<<0),
};
enum
{
MD_StringMatchFlag_CaseInsensitive = (1<<4),
MD_StringMatchFlag_RightSideSloppy = (1<<5),
MD_StringMatchFlag_SlashInsensitive = (1<<6),
};
enum
{
MD_NodeMatchFlag_Tags = (1<<16),
MD_NodeMatchFlag_TagArguments = (1<<17),
};
typedef struct MD_UnicodeConsume MD_UnicodeConsume;
struct MD_UnicodeConsume
typedef struct MD_DecodedCodepoint MD_DecodedCodepoint;
struct MD_DecodedCodepoint
{
MD_u32 codepoint;
MD_u32 advance;
};
typedef enum MD_WordStyle
typedef enum MD_IdentifierStyle
{
MD_WordStyle_UpperCamelCase,
MD_WordStyle_LowerCamelCase,
MD_WordStyle_UpperCase,
MD_WordStyle_LowerCase,
MD_IdentifierStyle_UpperCamelCase,
MD_IdentifierStyle_LowerCamelCase,
MD_IdentifierStyle_UpperCase,
MD_IdentifierStyle_LowerCase,
}
MD_WordStyle;
MD_IdentifierStyle;
//~ Node types that are used to build all ASTs.
typedef enum MD_NodeKind
{
// NOTE(rjf): Must be kept in sync with MD_StringFromNodeKind.
// NOTE(rjf): @maintenance Must be kept in sync with MD_StringFromNodeKind.
MD_NodeKind_Nil,
// NOTE(rjf): Generated by parser
MD_NodeKind_File,
MD_NodeKind_ErrorMarker,
// NOTE(rjf): Parsed from user Metadesk code
MD_NodeKind_Main,
MD_NodeKind_Tag,
// NOTE(rjf): User-created data structures
MD_NodeKind_List,
MD_NodeKind_Reference,
// TODO(allen): Proposal names for "Label"
// String, Value, Content, Center, Trunk, Branch,
// Cell, Entity, Node, Code
MD_NodeKind_Label,
MD_NodeKind_Tag,
MD_NodeKind_ErrorMarker,
MD_NodeKind_COUNT,
}
MD_NodeKind;
@@ -310,25 +323,26 @@ typedef MD_u64 MD_NodeFlags;
#define MD_NodeFlag_AfterFromBefore(f) ((f) << 1)
enum
{
// NOTE(rjf): Must be kept in sync with MD_StringListFromNodeFlags.
// NOTE(rjf): @maintenance Must be kept in sync with MD_StringListFromNodeFlags.
// NOTE(rjf): Because of MD_NodeFlag_AfterFromBefore, it is *required* that
// every single pair of "Before*" or "After*" flags be in the correct order
// which is that the Before* flag comes first, and the After* flag comes
// immediately after (After* being the more significant bit).
// NOTE(rjf): @maintenance Because of MD_NodeFlag_AfterFromBefore, it is
// *required* that every single pair of "Before*" or "After*" flags be in
// the correct order which is that the Before* flag comes first, and the
// After* flag comes immediately after (After* being the more significant
// bit).
MD_NodeFlag_ParenLeft = (1<<0),
MD_NodeFlag_ParenRight = (1<<1),
MD_NodeFlag_BracketLeft = (1<<2),
MD_NodeFlag_BracketRight = (1<<3),
MD_NodeFlag_BraceLeft = (1<<4),
MD_NodeFlag_BraceRight = (1<<5),
MD_NodeFlag_HasParenLeft = (1<<0),
MD_NodeFlag_HasParenRight = (1<<1),
MD_NodeFlag_HasBracketLeft = (1<<2),
MD_NodeFlag_HasBracketRight = (1<<3),
MD_NodeFlag_HasBraceLeft = (1<<4),
MD_NodeFlag_HasBraceRight = (1<<5),
MD_NodeFlag_BeforeSemicolon = (1<<6),
MD_NodeFlag_AfterSemicolon = (1<<7),
MD_NodeFlag_IsBeforeSemicolon = (1<<6),
MD_NodeFlag_IsAfterSemicolon = (1<<7),
MD_NodeFlag_BeforeComma = (1<<8),
MD_NodeFlag_AfterComma = (1<<9),
MD_NodeFlag_IsBeforeComma = (1<<8),
MD_NodeFlag_IsAfterComma = (1<<9),
MD_NodeFlag_StringSingleQuote = (1<<10),
MD_NodeFlag_StringDoubleQuote = (1<<11),
@@ -358,12 +372,12 @@ struct MD_Node
MD_NodeKind kind;
MD_NodeFlags flags;
MD_String8 string;
MD_String8 whole_string;
MD_String8 raw_string;
MD_u64 string_hash;
// Comments.
MD_String8 comment_before;
MD_String8 comment_after;
MD_String8 prev_comment;
MD_String8 next_comment;
// Source code location information.
MD_u64 offset;
@@ -419,14 +433,14 @@ struct MD_Map
typedef MD_u32 MD_TokenKind;
enum
{
MD_TokenKind_Identifier = (1<<0),
MD_TokenKind_NumericLiteral = (1<<1),
MD_TokenKind_StringLiteral = (1<<2),
MD_TokenKind_Symbol = (1<<3),
MD_TokenKind_Reserved = (1<<4),
MD_TokenKind_Comment = (1<<5),
MD_TokenKind_Whitespace = (1<<6),
MD_TokenKind_Newline = (1<<7),
MD_TokenKind_Identifier = (1<<0),
MD_TokenKind_NumericLiteral = (1<<1),
MD_TokenKind_StringLiteral = (1<<2),
MD_TokenKind_Symbol = (1<<3),
MD_TokenKind_Reserved = (1<<4),
MD_TokenKind_Comment = (1<<5),
MD_TokenKind_Whitespace = (1<<6),
MD_TokenKind_Newline = (1<<7),
MD_TokenKind_BrokenComment = (1<<8),
MD_TokenKind_BrokenStringLiteral = (1<<9),
MD_TokenKind_BadCharacter = (1<<10),
@@ -456,36 +470,39 @@ struct MD_Token
MD_TokenKind kind;
MD_NodeFlags node_flags;
MD_String8 string;
MD_String8 outer_string;
MD_String8 raw_string;
};
//~ Parsing State
typedef enum MD_MessageKind
{
// NOTE(rjf): @maintenance This enum needs to be sorted in order of
// severity.
MD_MessageKind_Null,
MD_MessageKind_Note,
MD_MessageKind_Warning,
MD_MessageKind_Error,
MD_MessageKind_CatastrophicError,
}
MD_MessageKind;
typedef struct MD_Error MD_Error;
struct MD_Error
typedef struct MD_Message MD_Message;
struct MD_Message
{
MD_Error *next;
MD_Message *next;
MD_Node *node;
MD_MessageKind kind;
MD_String8 string;
};
typedef struct MD_ErrorList MD_ErrorList;
struct MD_ErrorList
typedef struct MD_MessageList MD_MessageList;
struct MD_MessageList
{
MD_MessageKind max_error_kind;
MD_MessageKind max_message_kind;
MD_u64 node_count;
MD_Error *first;
MD_Error *last;
MD_Message *first;
MD_Message *last;
};
typedef enum MD_ParseSetRule
@@ -499,28 +516,28 @@ typedef struct MD_ParseResult MD_ParseResult;
struct MD_ParseResult
{
MD_Node *node;
// TODO(rjf): Remove once we're not using it for ParseTagList
MD_Node *last_node;
MD_u64 bytes_parsed;
MD_ErrorList errors;
MD_u64 string_advance;
MD_MessageList errors;
};
//~ Command line parsing helper types.
typedef struct MD_CommandLineOption MD_CommandLineOption;
struct MD_CommandLineOption
typedef struct MD_CmdLineOption MD_CmdLineOption;
struct MD_CmdLineOption
{
MD_CommandLineOption *next;
MD_CmdLineOption *next;
MD_String8 name;
MD_String8List values;
};
typedef struct MD_CommandLine MD_CommandLine;
struct MD_CommandLine
typedef struct MD_CmdLine MD_CmdLine;
struct MD_CmdLine
{
MD_String8List arguments;
MD_String8List inputs;
MD_CommandLineOption *first_option;
MD_CommandLineOption *last_option;
MD_CmdLineOption *first_option;
MD_CmdLineOption *last_option;
};
//~ File system access types.
@@ -619,10 +636,12 @@ MD_FUNCTION MD_b32 MD_CharIsReservedSymbol(MD_u8 c);
MD_FUNCTION MD_b32 MD_CharIsSpace(MD_u8 c);
MD_FUNCTION MD_u8 MD_CharToUpper(MD_u8 c);
MD_FUNCTION MD_u8 MD_CharToLower(MD_u8 c);
MD_FUNCTION MD_u8 MD_CorrectSlash(MD_u8 c);
MD_FUNCTION MD_u8 MD_CharToForwardSlash(MD_u8 c);
//~ Strings
MD_FUNCTION MD_u64 MD_CalculateCStringLength(char *cstr);
MD_FUNCTION MD_String8 MD_S8(MD_u8 *str, MD_u64 size);
#define MD_S8CString(s) MD_S8((MD_u8 *)(s), MD_CalculateCStringLength(s))
@@ -631,8 +650,11 @@ MD_FUNCTION MD_String8 MD_S8(MD_u8 *str, MD_u64 size);
#elif MD_LANG_CPP
# define MD_S8Lit(s) MD_S8((MD_u8*)(s), sizeof(s) - 1)
#endif
#define MD_S8LitComp(s) {(MD_u8 *)(s), sizeof(s)-1}
#if MD_LANG_CPP
// TODO(rjf): @allen this is only supported in C++11 I think, we need a check
// for that in the context cracking
static inline MD_String8
operator "" _md(const char *s, size_t size)
{
@@ -641,37 +663,56 @@ operator "" _md(const char *s, size_t size)
}
#endif
MD_FUNCTION MD_String8 MD_S8Range(MD_u8 *str, MD_u8 *opl);
MD_FUNCTION MD_String8 MD_S8Range(MD_u8 *first, MD_u8 *opl);
MD_FUNCTION MD_String8 MD_StringSubstring(MD_String8 str, MD_u64 min, MD_u64 max);
MD_FUNCTION MD_String8 MD_StringSkip(MD_String8 str, MD_u64 min);
MD_FUNCTION MD_String8 MD_StringChop(MD_String8 str, MD_u64 nmax);
MD_FUNCTION MD_String8 MD_StringPrefix(MD_String8 str, MD_u64 size);
MD_FUNCTION MD_String8 MD_StringSuffix(MD_String8 str, MD_u64 size);
MD_FUNCTION MD_String8 MD_S8Substring(MD_String8 str, MD_u64 min, MD_u64 max);
MD_FUNCTION MD_String8 MD_S8Skip(MD_String8 str, MD_u64 min);
MD_FUNCTION MD_String8 MD_S8Chop(MD_String8 str, MD_u64 nmax);
MD_FUNCTION MD_String8 MD_S8Prefix(MD_String8 str, MD_u64 size);
MD_FUNCTION MD_String8 MD_S8Suffix(MD_String8 str, MD_u64 size);
MD_FUNCTION MD_b32 MD_StringMatch(MD_String8 a, MD_String8 b, MD_MatchFlags flags);
MD_FUNCTION MD_u64 MD_FindSubstring(MD_String8 str, MD_String8 substring,
MD_u64 start_pos, MD_MatchFlags flags);
MD_FUNCTION MD_b32 MD_S8Match(MD_String8 a, MD_String8 b, MD_MatchFlags flags);
MD_FUNCTION MD_u64 MD_S8FindSubstring(MD_String8 str, MD_String8 substring,
MD_u64 start_pos, MD_MatchFlags flags);
MD_FUNCTION MD_String8 MD_ChopExtension(MD_String8 string);
MD_FUNCTION MD_String8 MD_SkipFolder(MD_String8 string);
MD_FUNCTION MD_String8 MD_ExtensionFromPath(MD_String8 string);
MD_FUNCTION MD_String8 MD_FolderFromPath(MD_String8 string);
MD_FUNCTION MD_String8 MD_S8Copy(MD_String8 string);
MD_FUNCTION MD_String8 MD_S8FmtV(char *fmt, va_list args);
MD_FUNCTION MD_String8 MD_PushStringCopy(MD_String8 string);
MD_FUNCTION MD_String8 MD_PushStringFV(char *fmt, va_list args);
MD_FUNCTION MD_String8 MD_S8Fmt(char *fmt, ...);
MD_FUNCTION MD_String8 MD_PushStringF(char *fmt, ...);
#define MD_S8VArg(s) (int)(s).size, (s).str
#define MD_StringExpand(s) (int)(s).size, (s).str
MD_FUNCTION void MD_S8ListPush(MD_String8List *list, MD_String8 string);
MD_FUNCTION void MD_S8ListConcat(MD_String8List *list, MD_String8List *to_push);
MD_FUNCTION MD_String8List MD_S8Split(MD_String8 string, int split_count, MD_String8 *splits);
MD_FUNCTION MD_String8 MD_S8ListJoin(MD_String8List list, MD_String8 separator);
MD_FUNCTION void MD_PushStringToList(MD_String8List *list, MD_String8 string);
MD_FUNCTION void MD_PushStringListToList(MD_String8List *list, MD_String8List *to_push);
MD_FUNCTION MD_String8List MD_SplitString(MD_String8 string, int split_count, MD_String8 *splits);
MD_FUNCTION MD_String8 MD_JoinStringList(MD_String8List list, MD_String8 separator);
MD_FUNCTION MD_u64 MD_CalculateCStringLength(char *cstr);
MD_FUNCTION MD_String8 MD_S8Stylize(MD_String8 string, MD_IdentifierStyle word_style, MD_String8 separator);
MD_FUNCTION MD_String8 MD_StyledStringFromString(MD_String8 string, MD_WordStyle word_style, MD_String8 separator);
//~ Unicode Conversions
MD_FUNCTION MD_DecodedCodepoint MD_DecodeCodepointFromUtf8(MD_u8 *str, MD_u64 max);
MD_FUNCTION MD_DecodedCodepoint MD_DecodeCodepointFromUtf16(MD_u16 *str, MD_u64 max);
MD_FUNCTION MD_u32 MD_Utf8FromCodepoint(MD_u8 *out, MD_u32 codepoint);
MD_FUNCTION MD_u32 MD_Utf16FromCodepoint(MD_u16 *out, MD_u32 codepoint);
MD_FUNCTION MD_String8 MD_S8FromS16(MD_String16 str);
MD_FUNCTION MD_String16 MD_S16FromS8(MD_String8 str);
MD_FUNCTION MD_String8 MD_S8FromS32(MD_String32 str);
MD_FUNCTION MD_String32 MD_S32FromS8(MD_String8 str);
//~ File Name Strings
// This is intended for removing extensions.
MD_FUNCTION MD_String8 MD_PathChopLastPeriod(MD_String8 string);
// This is intended for removing everything but the filename.
MD_FUNCTION MD_String8 MD_PathSkipLastSlash(MD_String8 string);
// This is intended for getting an extension from a filename.
MD_FUNCTION MD_String8 MD_PathSkipLastPeriod(MD_String8 string);
// This is intended for getting the folder string from a full path.
MD_FUNCTION MD_String8 MD_PathChopLastSlash(MD_String8 string);
//~ Numeric Strings
@@ -684,21 +725,10 @@ MD_FUNCTION MD_f64 MD_F64FromString(MD_String8 string);
MD_FUNCTION MD_String8 MD_StringFromNodeKind(MD_NodeKind kind);
MD_FUNCTION MD_String8List MD_StringListFromNodeFlags(MD_NodeFlags flags);
//~ Unicode Conversions
MD_FUNCTION MD_UnicodeConsume MD_CodepointFromUtf8(MD_u8 *str, MD_u64 max);
MD_FUNCTION MD_UnicodeConsume MD_CodepointFromUtf16(MD_u16 *str, MD_u64 max);
MD_FUNCTION MD_u32 MD_Utf8FromCodepoint(MD_u8 *out, MD_u32 codepoint);
MD_FUNCTION MD_u32 MD_Utf16FromCodepoint(MD_u16 *out, MD_u32 codepoint);
MD_FUNCTION MD_String8 MD_S8FromS16(MD_String16 str);
MD_FUNCTION MD_String16 MD_S16FromS8(MD_String8 str);
MD_FUNCTION MD_String8 MD_S8FromS32(MD_String32 str);
MD_FUNCTION MD_String32 MD_S32FromS8(MD_String8 str);
//~ Map Table Data Structure
MD_FUNCTION MD_u64 MD_HashString(MD_String8 string);
MD_FUNCTION MD_u64 MD_HashPointer(void *p);
MD_FUNCTION MD_u64 MD_HashStr(MD_String8 string);
MD_FUNCTION MD_u64 MD_HashPtr(void *p);
MD_FUNCTION MD_Map MD_MapMakeBucketCount(MD_u64 bucket_count);
MD_FUNCTION MD_Map MD_MapMake(void);
@@ -711,15 +741,14 @@ MD_FUNCTION MD_MapSlot* MD_MapOverwrite(MD_Map *map, MD_MapKey key, void *val);
//~ Parsing
MD_FUNCTION MD_b32 MD_TokenGroupContainsKind(MD_TokenGroups groups, MD_TokenKind kind);
MD_FUNCTION MD_Token MD_TokenFromString(MD_String8 string);
MD_FUNCTION MD_u64 MD_LexAdvanceFromSkips(MD_String8 string, MD_TokenKind skip_kinds);
MD_FUNCTION MD_Error * MD_MakeNodeError(MD_Node *node, MD_MessageKind kind, MD_String8 str);
MD_FUNCTION MD_Error * MD_MakeTokenError(MD_String8 parse_contents, MD_Token token, MD_MessageKind kind, MD_String8 str);
MD_FUNCTION void MD_PushErrorToList(MD_ErrorList *list, MD_Error *error);
MD_FUNCTION void MD_PushErrorListToList(MD_ErrorList *list, MD_ErrorList *to_push);
MD_FUNCTION MD_Message * MD_MakeNodeError(MD_Node *node, MD_MessageKind kind, MD_String8 str);
MD_FUNCTION MD_Message * MD_MakeTokenError(MD_String8 parse_contents, MD_Token token, MD_MessageKind kind, MD_String8 str);
MD_FUNCTION void MD_MessageListPush(MD_MessageList *list, MD_Message *message);
MD_FUNCTION void MD_MessageListConcat(MD_MessageList *list, MD_MessageList *to_push);
MD_FUNCTION MD_ParseResult MD_ParseResultZero(void);
MD_FUNCTION MD_ParseResult MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRule rule);
MD_FUNCTION MD_ParseResult MD_ParseTagList(MD_String8 string, MD_u64 offset);
MD_FUNCTION MD_ParseResult MD_ParseOneNode(MD_String8 string, MD_u64 offset);
MD_FUNCTION MD_ParseResult MD_ParseWholeString(MD_String8 filename, MD_String8 contents);
@@ -727,24 +756,28 @@ MD_FUNCTION MD_ParseResult MD_ParseWholeFile(MD_String8 filename);
//~ Location Conversion
MD_FUNCTION MD_CodeLoc MD_CodeLocFromFileBaseOffset(MD_String8 filename, MD_u8 *base, MD_u64 offset);
MD_FUNCTION MD_CodeLoc MD_CodeLocFromFileOffset(MD_String8 filename, MD_u8 *base, MD_u64 offset);
MD_FUNCTION MD_CodeLoc MD_CodeLocFromNode(MD_Node *node);
//~ Tree/List Building
MD_FUNCTION MD_b32 MD_NodeIsNil(MD_Node *node);
MD_FUNCTION MD_Node *MD_NilNode(void);
MD_FUNCTION MD_Node *MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 whole_string, MD_u64 offset);
MD_FUNCTION MD_Node *MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 raw_string, MD_u64 offset);
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 MD_Node *MD_MakeList(void);
MD_FUNCTION MD_Node *MD_PushReference(MD_Node *list, MD_Node *target);
MD_FUNCTION MD_Node *MD_PushNewReference(MD_Node *list, MD_Node *target);
//~ Introspection Helpers
// These calls are for getting info from nodes, and introspecting
// on trees that are returned to you by the parser.
MD_FUNCTION MD_Node * MD_NodeFromString(MD_Node *first, MD_Node *one_past_last, MD_String8 string, MD_MatchFlags flags);
MD_FUNCTION MD_Node * MD_NodeFromIndex(MD_Node *first, MD_Node *one_past_last, int n);
MD_FUNCTION MD_Node * MD_NodeFromFlags(MD_Node *first, MD_Node *one_past_last, MD_NodeFlags flags);
MD_FUNCTION int MD_IndexFromNode(MD_Node *node);
MD_FUNCTION MD_Node * MD_RootFromNode(MD_Node *node);
MD_FUNCTION MD_Node * MD_ChildFromString(MD_Node *node, MD_String8 child_string, MD_MatchFlags flags);
@@ -756,21 +789,20 @@ MD_FUNCTION MD_Node * MD_TagArgFromString(MD_Node *node, MD_String8 tag_string,
MD_FUNCTION MD_b32 MD_NodeHasTag(MD_Node *node, MD_String8 tag_string, MD_MatchFlags flags);
MD_FUNCTION MD_i64 MD_ChildCountFromNode(MD_Node *node);
MD_FUNCTION MD_i64 MD_TagCountFromNode(MD_Node *node);
MD_FUNCTION MD_Node * MD_Deref(MD_Node *node);
MD_FUNCTION MD_Node * MD_SeekNodeWithFlags(MD_Node *start, MD_NodeFlags one_past_last_flags);
MD_FUNCTION MD_Node * MD_NodeFromReference(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); \
#define MD_EachNodeRef(it, first) MD_Node *it##_r = (first), *it = MD_NodeFromReference(it##_r); \
!MD_NodeIsNil(it##_r); \
it##_r = it##_r->next, it = MD_Deref(it##_r)
it##_r = it##_r->next, it = MD_NodeFromReference(it##_r)
//~ Error/Warning Helpers
MD_FUNCTION void MD_Message(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 str);
MD_FUNCTION void MD_MessageF(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...);
MD_FUNCTION void MD_NodeMessage(FILE *out, MD_Node *node, MD_MessageKind kind, MD_String8 str);
MD_FUNCTION void MD_NodeMessageF(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...);
MD_FUNCTION void MD_PrintMessage(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 str);
MD_FUNCTION void MD_PrintMessageFmt(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...);
MD_FUNCTION void MD_PrintNodeMessage(FILE *out, MD_Node *node, MD_MessageKind kind, MD_String8 str);
MD_FUNCTION void MD_PrintNodeMessageFmt(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...);
//~ Tree Comparison/Verification
@@ -779,15 +811,15 @@ MD_FUNCTION MD_b32 MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags)
//~ Generation
MD_FUNCTION void MD_OutputTree(FILE *file, MD_Node *node, int indent_spaces);
MD_FUNCTION void MD_DebugOutputTree(FILE *file, MD_Node *node, int indent_spaces);
//~ Command Line Argument Helper
MD_FUNCTION MD_String8List MD_StringListFromArgCV(int argument_count, char **arguments);
MD_FUNCTION MD_CommandLine MD_CommandLineFromOptions(MD_String8List options);
MD_FUNCTION MD_String8List MD_CommandLineOptionValues(MD_CommandLine cmdln, MD_String8 name);
MD_FUNCTION MD_b32 MD_CommandLineOptionPassed(MD_CommandLine cmdln, MD_String8 name);
MD_FUNCTION MD_i64 MD_CommandLineOptionI64(MD_CommandLine cmdln, MD_String8 name);
MD_FUNCTION MD_CmdLine MD_MakeCmdLineFromOptions(MD_String8List options);
MD_FUNCTION MD_String8List MD_CmdLineValuesFromString(MD_CmdLine cmdln, MD_String8 name);
MD_FUNCTION MD_b32 MD_CmdLineB32FromString(MD_CmdLine cmdln, MD_String8 name);
MD_FUNCTION MD_i64 MD_CmdLineI64FromString(MD_CmdLine cmdln, MD_String8 name);
//~ File System