adding arena (p2)

This commit is contained in:
Allen Webster
2021-07-20 21:48:44 -07:00
parent 5e39bc8f2e
commit ba20ee9b14
9 changed files with 172 additions and 127 deletions
+6
View File
@@ -921,6 +921,7 @@ main:
@see(MD_S8Fmt) @see(MD_S8Fmt)
@see(MD_S8Copy) @see(MD_S8Copy)
@func MD_S8FmtV: { @func MD_S8FmtV: {
arena: *MD_Arena,
fmt: *char, fmt: *char,
args: va_list, args: va_list,
return: MD_String8, return: MD_String8,
@@ -931,6 +932,7 @@ main:
@see(MD_S8FmtV) @see(MD_S8FmtV)
@see(MD_S8Copy) @see(MD_S8Copy)
@func MD_S8Fmt: { @func MD_S8Fmt: {
arena: *MD_Arena,
fmt: *char, fmt: *char,
"...", "...",
return: MD_String8, return: MD_String8,
@@ -1256,6 +1258,7 @@ MD_ParseResultZero:
@see(MD_ParseSetRule) @see(MD_ParseSetRule)
MD_ParseNodeSet: MD_ParseNodeSet:
{ {
arena: *MD_Arena,
@doc("The string containing the source text to parse.") @doc("The string containing the source text to parse.")
string: MD_String8; string: MD_String8;
@doc("The offset into @code 'string' where this function should start parsing.") @doc("The offset into @code 'string' where this function should start parsing.")
@@ -1282,6 +1285,7 @@ MD_ParseTagList:
@doc("Parses a single Metadesk subtree, starting at @code 'offset' bytes into @code 'string'.") @doc("Parses a single Metadesk subtree, starting at @code 'offset' bytes into @code 'string'.")
MD_ParseOneNode: MD_ParseOneNode:
{ {
arena: *MD_Arena,
@doc("The string containing the source text to parse.") @doc("The string containing the source text to parse.")
string: MD_String8; string: MD_String8;
@doc("The offset into @code 'string' where this function should start parsing.") @doc("The offset into @code 'string' where this function should start parsing.")
@@ -1294,6 +1298,7 @@ MD_ParseOneNode:
@see(MD_NodeKind) @see(MD_NodeKind)
MD_ParseWholeString: MD_ParseWholeString:
{ {
arena: *MD_Arena,
@doc("The filename to associate with the parse.") @doc("The filename to associate with the parse.")
filename: MD_String8; filename: MD_String8;
@doc("The string that contains the text to parse.") @doc("The string that contains the text to parse.")
@@ -1741,6 +1746,7 @@ MD_ParseWholeFile:
@send(FileSystemHelper) @send(FileSystemHelper)
@doc("Increments an MD_FileIter iterator, and returns the iterated-onto file metadata.") @doc("Increments an MD_FileIter iterator, and returns the iterated-onto file metadata.")
@func MD_FileIterIncrement: { @func MD_FileIterIncrement: {
arena: *MD_Arena,
@doc("The MD_FileIter to increment. To begin iterating and iterate to the first file, zero-initialize the iterator.") @doc("The MD_FileIter to increment. To begin iterating and iterate to the first file, zero-initialize the iterator.")
it: *MD_FileIter, it: *MD_FileIter,
@doc("The path to the folder that should be iterated.") @doc("The path to the folder that should be iterated.")
+3 -1
View File
@@ -9,6 +9,8 @@
int main(int argument_count, char **arguments) int main(int argument_count, char **arguments)
{ {
MD_Arena *arena = MD_ArenaNew(1ull << 40);
MD_String8 example_code = MD_S8Lit("@struct Foo:\n" MD_String8 example_code = MD_S8Lit("@struct Foo:\n"
"{\n" "{\n"
" a: S32,\n" " a: S32,\n"
@@ -19,7 +21,7 @@ int main(int argument_count, char **arguments)
" f: ([4 + 5]S32),\n" " f: ([4 + 5]S32),\n"
" g: ([FOO + BAR]I32),\n" " g: ([FOO + BAR]I32),\n"
"}\n\n"); "}\n\n");
MD_Node *code = MD_ParseWholeString(MD_S8Lit("Generated Test Code"), example_code).node; MD_Node *code = MD_ParseWholeString(arena, MD_S8Lit("Generated Test Code"), example_code).node;
printf("Source Metadesk Code:\n"); printf("Source Metadesk Code:\n");
printf("%.*s\n\n", MD_S8VArg(example_code)); printf("%.*s\n\n", MD_S8VArg(example_code));
+1 -1
View File
@@ -76,7 +76,7 @@ int main(int argument_count, char **arguments)
{ {
MD_Node *root = MD_NodeFromReference(ref); MD_Node *root = MD_NodeFromReference(ref);
MD_String8 code_filename = MD_PathChopLastPeriod(MD_PathSkipLastSlash(root->string)); MD_String8 code_filename = MD_PathChopLastPeriod(MD_PathSkipLastSlash(root->string));
MD_String8 info_filename = MD_S8Fmt("parsed_%.*s.txt", MD_S8VArg(code_filename)); MD_String8 info_filename = MD_S8Fmt(arena, "parsed_%.*s.txt", MD_S8VArg(code_filename));
printf("Parse Input -> Output: %.*s -> %.*s\n", MD_S8VArg(code_filename), MD_S8VArg(info_filename)); printf("Parse Input -> Output: %.*s -> %.*s\n", MD_S8VArg(code_filename), MD_S8VArg(info_filename));
FILE* file = fopen((char *)info_filename.str, "wb"); FILE* file = fopen((char *)info_filename.str, "wb");
@@ -30,9 +30,11 @@ static SiteInfo ParseSiteInfo(MD_Node *site);
static MD_String8 MakeDateString(MD_Node *date); static MD_String8 MakeDateString(MD_Node *date);
static void GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_info, FILE *file, MD_Node *node); static void GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_info, FILE *file, MD_Node *node);
static MD_Arena *arena = 0;
int main(int argument_count, char **arguments) int main(int argument_count, char **arguments)
{ {
MD_Arena *arena = MD_ArenaNew(1ull << 40); arena = MD_ArenaNew(1ull << 40);
//~ NOTE(rjf): Parse command line arguments. //~ NOTE(rjf): Parse command line arguments.
MD_CmdLine cmdln = MD_MakeCmdLineFromOptions(MD_StringListFromArgCV(argument_count, arguments)); MD_CmdLine cmdln = MD_MakeCmdLineFromOptions(MD_StringListFromArgCV(argument_count, arguments));
@@ -46,7 +48,8 @@ int main(int argument_count, char **arguments)
} }
//~ NOTE(rjf): Load JS. //~ NOTE(rjf): Load JS.
MD_String8 js_string = MD_LoadEntireFile(arena, MD_S8Fmt("%.*s/site.js", MD_S8VArg(page_dir_path))); MD_String8 js_path = MD_S8Fmt(arena, "%.*s/site.js", MD_S8VArg(page_dir_path));
MD_String8 js_string = MD_LoadEntireFile(arena, js_path);
//~ NOTE(rjf): Parse site info. //~ NOTE(rjf): Parse site info.
SiteInfo site_info = {0}; SiteInfo site_info = {0};
@@ -61,7 +64,7 @@ int main(int argument_count, char **arguments)
{ {
printf("Searching for site pages at \"%.*s\"...\n", MD_S8VArg(page_dir_path)); printf("Searching for site pages at \"%.*s\"...\n", MD_S8VArg(page_dir_path));
MD_FileInfo file_info = {0}; MD_FileInfo file_info = {0};
for(MD_FileIter it = {0}; MD_FileIterIncrement(&it, page_dir_path, &file_info);) for(MD_FileIter it = {0}; MD_FileIterIncrement(arena, &it, page_dir_path, &file_info);)
{ {
if(MD_S8Match(MD_PathSkipLastPeriod(file_info.filename), MD_S8Lit("md"), MD_StringMatchFlag_CaseInsensitive) && if(MD_S8Match(MD_PathSkipLastPeriod(file_info.filename), MD_S8Lit("md"), MD_StringMatchFlag_CaseInsensitive) &&
!MD_S8Match(MD_PathSkipLastSlash(MD_PathChopLastPeriod(file_info.filename)), !MD_S8Match(MD_PathSkipLastSlash(MD_PathChopLastPeriod(file_info.filename)),
@@ -71,9 +74,8 @@ int main(int argument_count, char **arguments)
{ {
printf("Processing site page at \"%.*s\"...\n", MD_S8VArg(file_info.filename)); printf("Processing site page at \"%.*s\"...\n", MD_S8VArg(file_info.filename));
MD_String8 folder = MD_PathChopLastSlash(page_dir_path); MD_String8 folder = MD_PathChopLastSlash(page_dir_path);
MD_String8 path = MD_S8Fmt("%.*s/%.*s", MD_String8 path = MD_S8Fmt(arena, "%.*s/%.*s",
MD_S8VArg(folder), MD_S8VArg(folder), MD_S8VArg(file_info.filename));
MD_S8VArg(file_info.filename));
MD_Node *node = MD_ParseWholeFile(arena, path).node; MD_Node *node = MD_ParseWholeFile(arena, path).node;
MD_PushNewReference(root_list, node); MD_PushNewReference(root_list, node);
} }
@@ -129,7 +131,8 @@ int main(int argument_count, char **arguments)
PageInfo page_info = ParsePageInfo(root); PageInfo page_info = ParsePageInfo(root);
MD_String8 name_without_extension = MD_PathSkipLastSlash(MD_PathChopLastPeriod(root->string)); MD_String8 name_without_extension = MD_PathSkipLastSlash(MD_PathChopLastPeriod(root->string));
FILE *file = fopen(MD_S8Fmt("%.*s.html", MD_S8VArg(name_without_extension)).str, "wb"); MD_String8 file_name = MD_S8Fmt(arena, "%.*s.html", MD_S8VArg(name_without_extension));
FILE *file = fopen(file_name.str, "wb");
if(file) if(file)
{ {
fprintf(file, "<!DOCTYPE html>\n"); fprintf(file, "<!DOCTYPE html>\n");
@@ -363,7 +366,7 @@ MakeDateString(MD_Node *date)
MD_u64 month_idx = MD_U64FromString(month->string, 10) - 1; MD_u64 month_idx = MD_U64FromString(month->string, 10) - 1;
if(month_idx >= 0 && month_idx < sizeof(month_names)/sizeof(month_names[0])) if(month_idx >= 0 && month_idx < sizeof(month_names)/sizeof(month_names[0]))
{ {
result = MD_S8Fmt("%.*s %s %.*s", result = MD_S8Fmt(arena, "%.*s %s %.*s",
MD_S8VArg(day->string), MD_S8VArg(day->string),
month_names[month_idx], month_names[month_idx],
MD_S8VArg(year->string)); MD_S8VArg(year->string));
@@ -412,7 +415,8 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf
{ {
if(strnode->string.str[i] == '@') if(strnode->string.str[i] == '@')
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Substring(strnode->string, i, strnode->string.size), 0); MD_String8 string_tail = MD_S8Skip(strnode->string, i);
MD_ParseResult parse = MD_ParseOneNode(arena, string_tail, 0);
if(!MD_NodeIsNil(parse.node)) if(!MD_NodeIsNil(parse.node))
{ {
if(MD_NodeHasTag(node, MD_S8Lit("i"), 0)) if(MD_NodeHasTag(node, MD_S8Lit("i"), 0))
@@ -525,7 +529,7 @@ GeneratePageContent(MD_Map *index_table, SiteInfo *site_info, PageInfo *page_inf
MD_String8 filename = root->string; MD_String8 filename = root->string;
MD_String8 filename_no_ext = MD_PathChopLastPeriod(MD_PathSkipLastSlash(filename)); MD_String8 filename_no_ext = MD_PathChopLastPeriod(MD_PathSkipLastSlash(filename));
MD_String8 link = MD_S8Fmt("%.*s.html", MD_S8VArg(filename_no_ext)); MD_String8 link = MD_S8Fmt(arena, "%.*s.html", MD_S8VArg(filename_no_ext));
MD_String8 name = info.title->string; MD_String8 name = info.title->string;
MD_String8 date = MakeDateString(info.date); MD_String8 date = MakeDateString(info.date);
+74 -45
View File
@@ -17,6 +17,9 @@
# define MD_NO_DEFAULT_IMPL 0 # define MD_NO_DEFAULT_IMPL 0
#endif #endif
// TODO(allen): not real! Don't put into API
MD_FUNCTION MD_Arena* MD_Scratch(void);
//~///////////////////////////////////////////////////////////////////////////// //~/////////////////////////////////////////////////////////////////////////////
///////////////////////// Default Implementation /////////////////////////////// ///////////////////////// Default Implementation ///////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -49,7 +52,8 @@ MD_MALLOC_Alloc(MD_u64 size)
#endif #endif
static MD_b32 static MD_b32
MD_WIN32_FileIterIncrement(MD_FileIter *it, MD_String8 path, MD_FileInfo *out_info) MD_WIN32_FileIterIncrement(MD_Arena *arena, MD_FileIter *it, MD_String8 path,
MD_FileInfo *out_info)
{ {
MD_b32 result = 0; MD_b32 result = 0;
@@ -63,7 +67,7 @@ MD_WIN32_FileIterIncrement(MD_FileIter *it, MD_String8 path, MD_FileInfo *out_in
{ {
need_star = 1; need_star = 1;
} }
MD_String8 cpath = need_star ? MD_S8Fmt("%.*s*", MD_S8VArg(path)) : path; MD_String8 cpath = need_star ? MD_S8Fmt(MD_Scratch(), "%.*s*", MD_S8VArg(path)) : path;
state = FindFirstFileA((char*)cpath.str, &find_data); state = FindFirstFileA((char*)cpath.str, &find_data);
result = !!state; result = !!state;
} }
@@ -80,7 +84,7 @@ MD_WIN32_FileIterIncrement(MD_FileIter *it, MD_String8 path, MD_FileInfo *out_in
{ {
out_info->flags |= MD_FileFlag_Directory; out_info->flags |= MD_FileFlag_Directory;
} }
out_info->filename = MD_S8Fmt("%s", find_data.cFileName); out_info->filename = MD_S8Fmt(arena, "%s", find_data.cFileName);
out_info->file_size = ((((MD_u64)find_data.nFileSizeHigh) << 32) | out_info->file_size = ((((MD_u64)find_data.nFileSizeHigh) << 32) |
((MD_u64)find_data.nFileSizeLow)); ((MD_u64)find_data.nFileSizeLow));
} }
@@ -155,7 +159,8 @@ struct MD_LINUX_FileIter
MD_StaticAssert(sizeof(MD_LINUX_FileIter) <= sizeof(MD_FileIter), file_iter_size_check); MD_StaticAssert(sizeof(MD_LINUX_FileIter) <= sizeof(MD_FileIter), file_iter_size_check);
static MD_b32 static MD_b32
MD_LINUX_FileIterIncrement(MD_FileIter *opaque_it, MD_String8 path, MD_FileInfo *out_info) MD_LINUX_FileIterIncrement(MD_Arena *arena, MD_FileIter *opaque_it, MD_String8 path,
MD_FileInfo *out_info)
{ {
MD_b32 result = 0; MD_b32 result = 0;
@@ -171,7 +176,7 @@ MD_LINUX_FileIterIncrement(MD_FileIter *opaque_it, MD_String8 path, MD_FileInfo
struct dirent *dir_entry = readdir(it->dir); struct dirent *dir_entry = readdir(it->dir);
if(dir_entry) if(dir_entry)
{ {
out_info->filename = MD_S8Fmt("%s", dir_entry->d_name); out_info->filename = MD_S8Fmt(arena, "%s", dir_entry->d_name);
out_info->flags = 0; out_info->flags = 0;
struct stat st; struct stat st;
@@ -385,13 +390,13 @@ MD_AllocZero(MD_u64 size)
//~ Arena Functions //~ Arena Functions
MD_FUNCTION void* MD_FUNCTION_IMPL void*
MD_ArenaPush(MD_Arena *arena, MD_u64 v){ MD_ArenaPush(MD_Arena *arena, MD_u64 v){
MD_IntPtr result = arena->func(arena, MD_ArenaOperation_Push, v); MD_IntPtr result = arena->func(arena, MD_ArenaOperation_Push, v);
return(result.ptr); return(result.ptr);
} }
MD_FUNCTION MD_ArenaTemp MD_FUNCTION_IMPL MD_ArenaTemp
MD_ArenaBeginTemp(MD_Arena *arena){ MD_ArenaBeginTemp(MD_Arena *arena){
MD_IntPtr pos = arena->func(arena, MD_ArenaOperation_GetPos, 0); MD_IntPtr pos = arena->func(arena, MD_ArenaOperation_GetPos, 0);
MD_ArenaTemp result = MD_ZERO_STRUCT; MD_ArenaTemp result = MD_ZERO_STRUCT;
@@ -400,37 +405,55 @@ MD_ArenaBeginTemp(MD_Arena *arena){
return(result); return(result);
} }
MD_FUNCTION void MD_FUNCTION_IMPL void
MD_ArenaEndTemp(MD_ArenaTemp temp){ MD_ArenaEndTemp(MD_ArenaTemp temp){
temp.arena->func(temp.arena, MD_ArenaOperation_PopTo, temp.pos); temp.arena->func(temp.arena, MD_ArenaOperation_PopTo, temp.pos);
} }
MD_FUNCTION void MD_FUNCTION_IMPL void
MD_ArenaSetAlign(MD_Arena *arena, MD_u64 v){ MD_ArenaSetAlign(MD_Arena *arena, MD_u64 v){
arena->func(arena, MD_ArenaOperation_SetAutoAlign, v); arena->func(arena, MD_ArenaOperation_SetAutoAlign, v);
} }
MD_FUNCTION void MD_FUNCTION_IMPL void
MD_ArenaPushAlign(MD_Arena *arena, MD_u64 v){ MD_ArenaPushAlign(MD_Arena *arena, MD_u64 v){
arena->func(arena, MD_ArenaOperation_PushAlign, v); arena->func(arena, MD_ArenaOperation_PushAlign, v);
} }
MD_FUNCTION void MD_FUNCTION_IMPL void
MD_ArenaClear(MD_Arena *arena){ MD_ArenaClear(MD_Arena *arena){
arena->func(arena, MD_ArenaOperation_PopTo, 0); arena->func(arena, MD_ArenaOperation_PopTo, 0);
} }
MD_FUNCTION MD_Arena* MD_FUNCTION_IMPL MD_Arena*
MD_ArenaNew(MD_u64 cap){ MD_ArenaNew(MD_u64 cap){
return(MD_IMPL_ArenaNew(cap)); return(MD_IMPL_ArenaNew(cap));
} }
MD_FUNCTION void MD_FUNCTION_IMPL void
MD_ArenaRelease(MD_Arena *arena){ MD_ArenaRelease(MD_Arena *arena){
MD_IMPL_ArenaRelease(arena); MD_IMPL_ArenaRelease(arena);
} }
// TODO(allen): // TODO(allen): // TODO(allen): // TODO(allen): FIX FIX FIX FIX
// TODO(allen): // TODO(allen): // TODO(allen): // TODO(allen): FIX FIX FIX FIX
// TODO(allen): // TODO(allen): // TODO(allen): // TODO(allen): FIX FIX FIX FIX
// TODO(allen): // TODO(allen): // TODO(allen): // TODO(allen): FIX FIX FIX FIX
// This is a hack to ease the transition complexity, it defines "scratch" as
// a single global arena that can be acquired anywhere without explicit pass
// through -- but it is not a real scratch system because it has no free mechanism!
MD_FUNCTION_IMPL MD_Arena*
MD_Scratch(void){
static MD_Arena *scratch = 0;
if (scratch == 0){
scratch = MD_ArenaNew(1ull << 40);
}
return(scratch);
}
//~ Characters //~ Characters
MD_FUNCTION_IMPL MD_b32 MD_FUNCTION_IMPL MD_b32
@@ -635,25 +658,25 @@ MD_S8Copy(MD_Arena *arena, MD_String8 string)
} }
MD_FUNCTION_IMPL MD_String8 MD_FUNCTION_IMPL MD_String8
MD_S8FmtV(char *fmt, va_list args) MD_S8FmtV(MD_Arena *arena, char *fmt, va_list args)
{ {
MD_String8 result = MD_ZERO_STRUCT; MD_String8 result = MD_ZERO_STRUCT;
va_list args2; va_list args2;
va_copy(args2, args); va_copy(args2, args);
MD_u64 needed_bytes = md_stbsp_vsnprintf(0, 0, fmt, args)+1; MD_u64 needed_bytes = md_stbsp_vsnprintf(0, 0, fmt, args)+1;
result.str = MD_PushArray(MD_u8, needed_bytes); result.str = MD_PushArrayAr(arena, MD_u8, needed_bytes);
result.size = needed_bytes - 1; result.size = needed_bytes - 1;
md_stbsp_vsnprintf((char*)result.str, needed_bytes, fmt, args2); md_stbsp_vsnprintf((char*)result.str, needed_bytes, fmt, args2);
return result; return result;
} }
MD_FUNCTION_IMPL MD_String8 MD_FUNCTION_IMPL MD_String8
MD_S8Fmt(char *fmt, ...) MD_S8Fmt(MD_Arena *arena, char *fmt, ...)
{ {
MD_String8 result = MD_ZERO_STRUCT; MD_String8 result = MD_ZERO_STRUCT;
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
result = MD_S8FmtV(fmt, args); result = MD_S8FmtV(arena, fmt, args);
va_end(args); va_end(args);
return result; return result;
} }
@@ -1841,7 +1864,8 @@ MD_ParseResultZero(void)
} }
MD_FUNCTION_IMPL MD_ParseResult MD_FUNCTION_IMPL MD_ParseResult
MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRule rule) MD_ParseNodeSet(MD_Arena *arena, MD_String8 string, MD_u64 offset, MD_Node *parent,
MD_ParseSetRule rule)
{ {
MD_ParseResult result = MD_ParseResultZero(); MD_ParseResult result = MD_ParseResultZero();
MD_u64 off = offset; MD_u64 off = offset;
@@ -2011,7 +2035,7 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu
} }
//- rjf: parse next child //- rjf: parse next child
MD_ParseResult child_parse = MD_ParseOneNode(string, off); MD_ParseResult child_parse = MD_ParseOneNode(arena, string, off);
MD_MessageListConcat(&result.errors, &child_parse.errors); MD_MessageListConcat(&result.errors, &child_parse.errors);
off += child_parse.string_advance; off += child_parse.string_advance;
@@ -2070,8 +2094,8 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu
if(set_opener != 0 && got_closer == 0) if(set_opener != 0 && got_closer == 0)
{ {
// NOTE(rjf): @error We didn't get a closer for the set // NOTE(rjf): @error We didn't get a closer for the set
MD_Message *error = MD_MakeTokenError(string, initial_token, MD_MessageKind_CatastrophicError, MD_String8 error_str = MD_S8Fmt(arena, "Unbalanced \"%c\"", set_opener);
MD_S8Fmt("Unbalanced \"%c\"", set_opener)); MD_Message *error = MD_MakeTokenError(string, initial_token, MD_MessageKind_CatastrophicError, error_str);
MD_MessageListPush(&result.errors, error); MD_MessageListPush(&result.errors, error);
} }
@@ -2094,7 +2118,7 @@ MD_ParseNodeSet(MD_String8 string, MD_u64 offset, MD_Node *parent, MD_ParseSetRu
// TODO(rjf): Inline this in the only place it is called // TODO(rjf): Inline this in the only place it is called
MD_FUNCTION_IMPL MD_ParseResult MD_FUNCTION_IMPL MD_ParseResult
_MD_ParseTagList(MD_String8 string, MD_u64 offset) _MD_ParseTagList(MD_Arena *arena, MD_String8 string, MD_u64 offset)
{ {
MD_ParseResult result = MD_ParseResultZero(); MD_ParseResult result = MD_ParseResultZero();
MD_u64 off = offset; MD_u64 off = offset;
@@ -2117,9 +2141,9 @@ _MD_ParseTagList(MD_String8 string, MD_u64 offset)
if((name.kind & MD_TokenGroup_Label) == 0) if((name.kind & MD_TokenGroup_Label) == 0)
{ {
// NOTE(rjf): @error Improper token for tag string // NOTE(rjf): @error Improper token for tag string
MD_Message *error = MD_MakeTokenError(string, name, MD_MessageKind_Error, MD_String8 error_str = MD_S8Fmt(arena, "\"%.*s\" is not a proper tag label",
MD_S8Fmt("\"%.*s\" is not a proper tag label", MD_S8VArg(name.raw_string));
MD_S8VArg(name.raw_string))); MD_Message *error = MD_MakeTokenError(string, name, MD_MessageKind_Error, error_str);
MD_MessageListPush(&result.errors, error); MD_MessageListPush(&result.errors, error);
break; break;
} }
@@ -2134,7 +2158,7 @@ _MD_ParseTagList(MD_String8 string, MD_u64 offset)
if(open_paren.kind == MD_TokenKind_Reserved && if(open_paren.kind == MD_TokenKind_Reserved &&
open_paren.string.str[0] == '(') open_paren.string.str[0] == '(')
{ {
args_parse = MD_ParseNodeSet(string, off, tag, MD_ParseSetRule_EndOnDelimiter); args_parse = MD_ParseNodeSet(arena, string, off, tag, MD_ParseSetRule_EndOnDelimiter);
MD_MessageListConcat(&result.errors, &args_parse.errors); MD_MessageListConcat(&result.errors, &args_parse.errors);
} }
off += args_parse.string_advance; off += args_parse.string_advance;
@@ -2150,7 +2174,7 @@ _MD_ParseTagList(MD_String8 string, MD_u64 offset)
} }
MD_FUNCTION_IMPL MD_ParseResult MD_FUNCTION_IMPL MD_ParseResult
MD_ParseOneNode(MD_String8 string, MD_u64 offset) MD_ParseOneNode(MD_Arena *arena, MD_String8 string, MD_u64 offset)
{ {
MD_ParseResult result = MD_ParseResultZero(); MD_ParseResult result = MD_ParseResultZero();
MD_u64 off = offset; MD_u64 off = offset;
@@ -2194,7 +2218,7 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset)
} }
//- rjf: parse tag list //- rjf: parse tag list
MD_ParseResult tags_parse = _MD_ParseTagList(string, off); MD_ParseResult tags_parse = _MD_ParseTagList(arena, string, off);
off += tags_parse.string_advance; off += tags_parse.string_advance;
MD_MessageListConcat(&result.errors, &tags_parse.errors); MD_MessageListConcat(&result.errors, &tags_parse.errors);
@@ -2213,25 +2237,26 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset)
{ {
parsed_node = MD_MakeNode(MD_NodeKind_Main, MD_S8Lit(""), MD_S8Lit(""), parsed_node = MD_MakeNode(MD_NodeKind_Main, MD_S8Lit(""), MD_S8Lit(""),
unnamed_set_opener.raw_string.str - string.str); unnamed_set_opener.raw_string.str - string.str);
children_parse = MD_ParseNodeSet(string, off, parsed_node, MD_ParseSetRule_EndOnDelimiter); children_parse = MD_ParseNodeSet(arena, string, off, parsed_node,
MD_ParseSetRule_EndOnDelimiter);
off += children_parse.string_advance; off += children_parse.string_advance;
MD_MessageListConcat(&result.errors, &children_parse.errors); MD_MessageListConcat(&result.errors, &children_parse.errors);
} }
else if (c == ')' || c == '}' || c == ']') else if (c == ')' || c == '}' || c == ']')
{ {
// NOTE(rjf): @error Unexpected set closing symbol // NOTE(rjf): @error Unexpected set closing symbol
MD_String8 error_str = MD_S8Fmt(arena, "Unbalanced \"%c\"", c);
MD_Message *error = MD_MakeTokenError(string, unnamed_set_opener, MD_Message *error = MD_MakeTokenError(string, unnamed_set_opener,
MD_MessageKind_CatastrophicError, MD_MessageKind_CatastrophicError, error_str);
MD_S8Fmt("Unbalanced \"%c\"", c));
MD_MessageListPush(&result.errors, error); MD_MessageListPush(&result.errors, error);
off += unnamed_set_opener.raw_string.size; off += unnamed_set_opener.raw_string.size;
} }
else else
{ {
// NOTE(rjf): @error Unexpected reserved symbol // NOTE(rjf): @error Unexpected reserved symbol
MD_String8 error_str = MD_S8Fmt(arena, "Unexpected reserved symbol \"%c\"", c);
MD_Message *error = MD_MakeTokenError(string, unnamed_set_opener, MD_Message *error = MD_MakeTokenError(string, unnamed_set_opener,
MD_MessageKind_Error, MD_MessageKind_Error, error_str);
MD_S8Fmt("Unexpected reserved symbol \"%c\"", c));
MD_MessageListPush(&result.errors, error); MD_MessageListPush(&result.errors, error);
off += unnamed_set_opener.raw_string.size; off += unnamed_set_opener.raw_string.size;
} }
@@ -2259,7 +2284,8 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset)
colon_check_off += colon.raw_string.size; colon_check_off += colon.raw_string.size;
off = colon_check_off; off = colon_check_off;
children_parse = MD_ParseNodeSet(string, off, parsed_node, MD_ParseSetRule_EndOnDelimiter); children_parse = MD_ParseNodeSet(arena, string, off, parsed_node,
MD_ParseSetRule_EndOnDelimiter);
off += children_parse.string_advance; off += children_parse.string_advance;
MD_MessageListConcat(&result.errors, &children_parse.errors); MD_MessageListConcat(&result.errors, &children_parse.errors);
} }
@@ -2287,8 +2313,10 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset)
MD_String8 byte_string = MD_S8ListJoin(bytes, &join); MD_String8 byte_string = MD_S8ListJoin(bytes, &join);
// NOTE(rjf): @error Bad character // NOTE(rjf): @error Bad character
MD_String8 error_str = MD_S8Fmt(arena, "Non-ASCII character \"%.*s\"",
MD_S8VArg(byte_string));
MD_Message *error = MD_MakeTokenError(string, bad_token, MD_MessageKind_Error, MD_Message *error = MD_MakeTokenError(string, bad_token, MD_MessageKind_Error,
MD_S8Fmt("Non-ASCII character \"%.*s\"", MD_S8VArg(byte_string))); error_str);
MD_MessageListPush(&result.errors, error); MD_MessageListPush(&result.errors, error);
}break; }break;
@@ -2360,10 +2388,10 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset)
} }
MD_FUNCTION_IMPL MD_ParseResult MD_FUNCTION_IMPL MD_ParseResult
MD_ParseWholeString(MD_String8 filename, MD_String8 contents) MD_ParseWholeString(MD_Arena *arena, MD_String8 filename, MD_String8 contents)
{ {
MD_Node *root = MD_MakeNode(MD_NodeKind_File, filename, contents, 0); MD_Node *root = MD_MakeNode(MD_NodeKind_File, filename, contents, 0);
MD_ParseResult result = MD_ParseNodeSet(contents, 0, root, MD_ParseSetRule_Global); MD_ParseResult result = MD_ParseNodeSet(arena, contents, 0, root, MD_ParseSetRule_Global);
result.node = result.last_node = root; result.node = result.last_node = root;
for(MD_Message *error = result.errors.first; error != 0; error = error->next) for(MD_Message *error = result.errors.first; error != 0; error = error->next)
{ {
@@ -2379,12 +2407,13 @@ MD_FUNCTION_IMPL MD_ParseResult
MD_ParseWholeFile(MD_Arena *arena, MD_String8 filename) MD_ParseWholeFile(MD_Arena *arena, MD_String8 filename)
{ {
MD_String8 file_contents = MD_LoadEntireFile(arena, filename); MD_String8 file_contents = MD_LoadEntireFile(arena, filename);
MD_ParseResult parse = MD_ParseWholeString(filename, file_contents); MD_ParseResult parse = MD_ParseWholeString(arena, filename, file_contents);
if(file_contents.str == 0) if(file_contents.str == 0)
{ {
// NOTE(rjf): @error File failing to load // NOTE(rjf): @error File failing to load
MD_String8 error_str = MD_S8Fmt(arena, "Could not read file \"%.*s\"", MD_S8VArg(filename));
MD_Message *error = MD_MakeNodeError(parse.node, MD_MessageKind_CatastrophicError, MD_Message *error = MD_MakeNodeError(parse.node, MD_MessageKind_CatastrophicError,
MD_S8Fmt("Could not read file \"%.*s\"", MD_S8VArg(filename))); error_str);
MD_MessageListPush(&parse.errors, error); MD_MessageListPush(&parse.errors, error);
} }
return parse; return parse;
@@ -2657,10 +2686,10 @@ MD_PrintMessage(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, MD_String8 str)
MD_FUNCTION_IMPL void MD_FUNCTION_IMPL void
MD_PrintMessageFmt(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...) MD_PrintMessageFmt(FILE *out, MD_CodeLoc loc, MD_MessageKind kind, char *fmt, ...)
{ {
// TODO(allen): use scratch
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
MD_PrintMessage(out, loc, kind, MD_S8FmtV(fmt, args)); MD_String8 string = MD_S8FmtV(MD_Scratch(), fmt, args);
MD_PrintMessage(out, loc, kind, string);
va_end(args); va_end(args);
} }
@@ -2674,10 +2703,10 @@ MD_PrintNodeMessage(FILE *out, MD_Node *node, MD_MessageKind kind, MD_String8 st
MD_FUNCTION_IMPL void MD_FUNCTION_IMPL void
MD_PrintNodeMessageFmt(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...) MD_PrintNodeMessageFmt(FILE *out, MD_Node *node, MD_MessageKind kind, char *fmt, ...)
{ {
// TODO(allen): use scratch
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
MD_PrintNodeMessage(out, node, kind, MD_S8FmtV(fmt, args)); MD_String8 string = MD_S8FmtV(MD_Scratch(), fmt, args);
MD_PrintNodeMessage(out, node, kind, string);
va_end(args); va_end(args);
} }
@@ -2991,12 +3020,12 @@ MD_LoadEntireFile(MD_Arena *arena, MD_String8 filename)
} }
MD_FUNCTION_IMPL MD_b32 MD_FUNCTION_IMPL MD_b32
MD_FileIterIncrement(MD_FileIter *it, MD_String8 path, MD_FileInfo *out_info) MD_FileIterIncrement(MD_Arena *arena, MD_FileIter *it, MD_String8 path, MD_FileInfo *out_info)
{ {
#if !defined(MD_IMPL_FileIterIncrement) #if !defined(MD_IMPL_FileIterIncrement)
return(0); return(0);
#else #else
return(MD_IMPL_FileIterIncrement(it, path, out_info)); return(MD_IMPL_FileIterIncrement(arena, it, path, out_info));
#endif #endif
} }
+5 -5
View File
@@ -755,9 +755,9 @@ MD_FUNCTION MD_u64 MD_S8FindSubstring(MD_String8 str, MD_String8 substri
MD_u64 start_pos, MD_MatchFlags flags); MD_u64 start_pos, MD_MatchFlags flags);
MD_FUNCTION MD_String8 MD_S8Copy(MD_Arena *arena, MD_String8 string); MD_FUNCTION MD_String8 MD_S8Copy(MD_Arena *arena, MD_String8 string);
MD_FUNCTION MD_String8 MD_S8FmtV(char *fmt, va_list args); MD_FUNCTION MD_String8 MD_S8FmtV(MD_Arena *arena, char *fmt, va_list args);
MD_FUNCTION MD_String8 MD_S8Fmt(char *fmt, ...); MD_FUNCTION MD_String8 MD_S8Fmt(MD_Arena *arena, char *fmt, ...);
#define MD_S8VArg(s) (int)(s).size, (s).str #define MD_S8VArg(s) (int)(s).size, (s).str
@@ -830,8 +830,8 @@ MD_FUNCTION MD_Message * MD_MakeTokenError(MD_String8 parse_contents, MD_Token
MD_FUNCTION void MD_MessageListPush(MD_MessageList *list, MD_Message *message); 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 void MD_MessageListConcat(MD_MessageList *list, MD_MessageList *to_push);
MD_FUNCTION MD_ParseResult MD_ParseResultZero(void); MD_FUNCTION MD_ParseResult MD_ParseResultZero(void);
MD_FUNCTION MD_ParseResult MD_ParseOneNode(MD_String8 string, MD_u64 offset); MD_FUNCTION MD_ParseResult MD_ParseOneNode(MD_Arena *arena, MD_String8 string, MD_u64 offset);
MD_FUNCTION MD_ParseResult MD_ParseWholeString(MD_String8 filename, MD_String8 contents); MD_FUNCTION MD_ParseResult MD_ParseWholeString(MD_Arena *arena, MD_String8 filename, MD_String8 contents);
MD_FUNCTION MD_ParseResult MD_ParseWholeFile(MD_Arena *arena, MD_String8 filename); MD_FUNCTION MD_ParseResult MD_ParseWholeFile(MD_Arena *arena, MD_String8 filename);
@@ -905,7 +905,7 @@ MD_FUNCTION MD_i64 MD_CmdLineI64FromString(MD_CmdLine cmdln, MD_String8 name);
//~ File System //~ File System
MD_FUNCTION MD_String8 MD_LoadEntireFile(MD_Arena *arena, MD_String8 filename); MD_FUNCTION MD_String8 MD_LoadEntireFile(MD_Arena *arena, MD_String8 filename);
MD_FUNCTION MD_b32 MD_FileIterIncrement(MD_FileIter *it, MD_String8 path, MD_FileInfo *out_info); MD_FUNCTION MD_b32 MD_FileIterIncrement(MD_Arena *arena, MD_FileIter *it, MD_String8 path, MD_FileInfo *out_info);
#endif // MD_H #endif // MD_H
+2 -2
View File
@@ -27,7 +27,7 @@ MD_POSIX_FileIterIncrement(MD_FileIter *opaque_it, MD_String8 path, MD_FileInfo
struct dirent *dir_entry = readdir(it->dir); struct dirent *dir_entry = readdir(it->dir);
if(dir_entry) if(dir_entry)
{ {
out_info->filename = MD_S8Fmt("%s", dir_entry->d_name); out_info->filename = MD_S8Fmt(arena, "%s", dir_entry->d_name);
out_info->flags = 0; out_info->flags = 0;
if(path.size > 1 && path.str[path.size-1] == '/') if(path.size > 1 && path.str[path.size-1] == '/')
@@ -36,7 +36,7 @@ MD_POSIX_FileIterIncrement(MD_FileIter *opaque_it, MD_String8 path, MD_FileInfo
} }
struct stat st; struct stat st;
MD_String8 cfile_path = MD_S8Fmt("%.*s/%s", MD_S8VArg(path), dir_entry->d_name); MD_String8 cfile_path = MD_S8Fmt(arena, "%.*s/%s", MD_S8VArg(path), dir_entry->d_name);
if(stat((char *)cfile_path.str, &st) == 0) if(stat((char *)cfile_path.str, &st) == 0)
{ {
if((st.st_mode & S_IFMT) == S_IFDIR) if((st.st_mode & S_IFMT) == S_IFDIR)
+3 -1
View File
@@ -3,11 +3,13 @@
int main(void) int main(void)
{ {
MD_Arena *arena = MD_ArenaNew(1ull << 40);
printf("%d\n", MD_CPP_VERSION); printf("%d\n", MD_CPP_VERSION);
MD_String8 foo = "foo"_md; MD_String8 foo = "foo"_md;
MD_String8 bar = "bar"_md; MD_String8 bar = "bar"_md;
MD_String8 str = MD_S8Fmt("%S%S", foo, bar); MD_String8 str = MD_S8Fmt(arena, "%S%S", foo, bar);
printf("%.*s", MD_S8VArg(str)); printf("%.*s", MD_S8VArg(str));
return 0; return 0;
} }
+64 -62
View File
@@ -4,6 +4,8 @@
#include "md.c" #include "md.c"
#include "md_c_helpers.c" #include "md_c_helpers.c"
MD_Arena *arena = 0;
static struct static struct
{ {
int number_of_tests; int number_of_tests;
@@ -90,14 +92,14 @@ TypeExpr(MD_C_ExprKind kind, MD_C_Expr *sub)
static MD_b32 static MD_b32
MatchParsedWithNode(MD_String8 string, MD_Node *tree) MatchParsedWithNode(MD_String8 string, MD_Node *tree)
{ {
MD_ParseResult parse = MD_ParseOneNode(string, 0); MD_ParseResult parse = MD_ParseOneNode(arena, string, 0);
return MD_NodeDeepMatch(tree, parse.node, MD_NodeMatchFlag_Tags | MD_NodeMatchFlag_TagArguments); return MD_NodeDeepMatch(tree, parse.node, MD_NodeMatchFlag_Tags | MD_NodeMatchFlag_TagArguments);
} }
static MD_b32 static MD_b32
MatchParsedWithExpr(MD_String8 string, MD_C_Expr *expr) MatchParsedWithExpr(MD_String8 string, MD_C_Expr *expr)
{ {
MD_ParseResult parse = MD_ParseOneNode(string, 0); MD_ParseResult parse = MD_ParseOneNode(arena, string, 0);
MD_C_Expr *parse_expr = MD_C_ParseAsExpr(parse.node->first_child, parse.node->last_child); MD_C_Expr *parse_expr = MD_C_ParseAsExpr(parse.node->first_child, parse.node->last_child);
return MD_C_ExprDeepMatch(expr, parse_expr, 0); return MD_C_ExprDeepMatch(expr, parse_expr, 0);
} }
@@ -105,7 +107,7 @@ MatchParsedWithExpr(MD_String8 string, MD_C_Expr *expr)
static MD_b32 static MD_b32
MatchParsedWithType(MD_String8 string, MD_C_Expr *expr) MatchParsedWithType(MD_String8 string, MD_C_Expr *expr)
{ {
MD_ParseResult parse = MD_ParseOneNode(string, 0); MD_ParseResult parse = MD_ParseOneNode(arena, string, 0);
MD_C_Expr *parse_expr = MD_C_ParseAsType(parse.node->first_child, parse.node->last_child); MD_C_Expr *parse_expr = MD_C_ParseAsType(parse.node->first_child, parse.node->last_child);
return MD_C_ExprDeepMatch(expr, parse_expr, 0); return MD_C_ExprDeepMatch(expr, parse_expr, 0);
} }
@@ -118,7 +120,7 @@ TokenMatch(MD_Token token, MD_String8 string, MD_TokenKind kind)
int main(void) int main(void)
{ {
MD_Arena *arena = MD_ArenaNew(1ull << 40); arena = MD_ArenaNew(1ull << 40);
Test("Lexer") Test("Lexer")
{ {
@@ -243,31 +245,31 @@ int main(void)
Test("Set Border Flags") Test("Set Border Flags")
{ {
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(0, 100)"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("(0, 100)"), 0);
TestResult(parse.node->flags & MD_NodeFlag_HasParenLeft && TestResult(parse.node->flags & MD_NodeFlag_HasParenLeft &&
parse.node->flags & MD_NodeFlag_HasParenRight); parse.node->flags & MD_NodeFlag_HasParenRight);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(0, 100]"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("(0, 100]"), 0);
TestResult(parse.node->flags & MD_NodeFlag_HasParenLeft && TestResult(parse.node->flags & MD_NodeFlag_HasParenLeft &&
parse.node->flags & MD_NodeFlag_HasBracketRight); parse.node->flags & MD_NodeFlag_HasBracketRight);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("[0, 100)"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("[0, 100)"), 0);
TestResult(parse.node->flags & MD_NodeFlag_HasBracketLeft && TestResult(parse.node->flags & MD_NodeFlag_HasBracketLeft &&
parse.node->flags & MD_NodeFlag_HasParenRight); parse.node->flags & MD_NodeFlag_HasParenRight);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("[0, 100]"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("[0, 100]"), 0);
TestResult(parse.node->flags & MD_NodeFlag_HasBracketLeft && TestResult(parse.node->flags & MD_NodeFlag_HasBracketLeft &&
parse.node->flags & MD_NodeFlag_HasBracketRight); parse.node->flags & MD_NodeFlag_HasBracketRight);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("{0, 100}"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("{0, 100}"), 0);
TestResult(parse.node->flags & MD_NodeFlag_HasBraceLeft && TestResult(parse.node->flags & MD_NodeFlag_HasBraceLeft &&
parse.node->flags & MD_NodeFlag_HasBraceRight); parse.node->flags & MD_NodeFlag_HasBraceRight);
} }
@@ -276,12 +278,12 @@ int main(void)
Test("Node Separator Flags") Test("Node Separator Flags")
{ {
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a, b)"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("(a, b)"), 0);
TestResult(parse.node->first_child->flags & MD_NodeFlag_IsBeforeComma); TestResult(parse.node->first_child->flags & MD_NodeFlag_IsBeforeComma);
TestResult(parse.node->first_child->next->flags & MD_NodeFlag_IsAfterComma); TestResult(parse.node->first_child->next->flags & MD_NodeFlag_IsAfterComma);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a; b)"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("(a; b)"), 0);
TestResult(parse.node->first_child->flags & MD_NodeFlag_IsBeforeSemicolon); TestResult(parse.node->first_child->flags & MD_NodeFlag_IsBeforeSemicolon);
TestResult(parse.node->first_child->next->flags & MD_NodeFlag_IsAfterSemicolon); TestResult(parse.node->first_child->next->flags & MD_NodeFlag_IsAfterSemicolon);
} }
@@ -289,41 +291,41 @@ int main(void)
Test("Node Text Flags") Test("Node Text Flags")
{ {
TestResult(MD_ParseOneNode(MD_S8Lit("123"), 0).node->flags & TestResult(MD_ParseOneNode(arena, MD_S8Lit("123"), 0).node->flags &
MD_NodeFlag_Numeric); MD_NodeFlag_Numeric);
TestResult(MD_ParseOneNode(MD_S8Lit("123_456_789"), 0).node->flags & TestResult(MD_ParseOneNode(arena, MD_S8Lit("123_456_789"), 0).node->flags &
MD_NodeFlag_Numeric); MD_NodeFlag_Numeric);
TestResult(MD_ParseOneNode(MD_S8Lit("abc"), 0).node->flags & TestResult(MD_ParseOneNode(arena, MD_S8Lit("abc"), 0).node->flags &
MD_NodeFlag_Identifier); MD_NodeFlag_Identifier);
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("\"foo\""), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("\"foo\""), 0);
TestResult(parse.node->flags & MD_NodeFlag_StringLiteral && TestResult(parse.node->flags & MD_NodeFlag_StringLiteral &&
parse.node->flags & MD_NodeFlag_StringDoubleQuote); parse.node->flags & MD_NodeFlag_StringDoubleQuote);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("'foo'"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("'foo'"), 0);
TestResult(parse.node->flags & MD_NodeFlag_StringLiteral && TestResult(parse.node->flags & MD_NodeFlag_StringLiteral &&
parse.node->flags & MD_NodeFlag_StringSingleQuote); parse.node->flags & MD_NodeFlag_StringSingleQuote);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("`foo`"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("`foo`"), 0);
TestResult(parse.node->flags & MD_NodeFlag_StringLiteral && TestResult(parse.node->flags & MD_NodeFlag_StringLiteral &&
parse.node->flags & MD_NodeFlag_StringTick); parse.node->flags & MD_NodeFlag_StringTick);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("\"\"\"foo\"\"\""), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("\"\"\"foo\"\"\""), 0);
TestResult(parse.node->flags & MD_NodeFlag_StringLiteral && TestResult(parse.node->flags & MD_NodeFlag_StringLiteral &&
parse.node->flags & MD_NodeFlag_StringDoubleQuote && parse.node->flags & MD_NodeFlag_StringDoubleQuote &&
parse.node->flags & MD_NodeFlag_StringTriplet); parse.node->flags & MD_NodeFlag_StringTriplet);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("'''foo'''"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("'''foo'''"), 0);
TestResult(parse.node->flags & MD_NodeFlag_StringLiteral && TestResult(parse.node->flags & MD_NodeFlag_StringLiteral &&
parse.node->flags & MD_NodeFlag_StringSingleQuote && parse.node->flags & MD_NodeFlag_StringSingleQuote &&
parse.node->flags & MD_NodeFlag_StringTriplet); parse.node->flags & MD_NodeFlag_StringTriplet);
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("```foo```"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("```foo```"), 0);
TestResult(parse.node->flags & MD_NodeFlag_StringLiteral && TestResult(parse.node->flags & MD_NodeFlag_StringLiteral &&
parse.node->flags & MD_NodeFlag_StringTick && parse.node->flags & MD_NodeFlag_StringTick &&
parse.node->flags & MD_NodeFlag_StringTriplet); parse.node->flags & MD_NodeFlag_StringTriplet);
@@ -456,17 +458,17 @@ int main(void)
// NOTE(rjf): Pre-Comments: // NOTE(rjf): Pre-Comments:
{ {
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("/*foobar*/ (a b c)"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("/*foobar*/ (a b c)"), 0);
TestResult(parse.node->kind == MD_NodeKind_Main && TestResult(parse.node->kind == MD_NodeKind_Main &&
MD_S8Match(parse.node->prev_comment, MD_S8Lit("foobar"), 0)); MD_S8Match(parse.node->prev_comment, MD_S8Lit("foobar"), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("// foobar\n(a b c)"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("// foobar\n(a b c)"), 0);
TestResult(parse.node->kind == MD_NodeKind_Main && TestResult(parse.node->kind == MD_NodeKind_Main &&
MD_S8Match(parse.node->prev_comment, MD_S8Lit(" foobar"), 0)); MD_S8Match(parse.node->prev_comment, MD_S8Lit(" foobar"), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("// foobar\n\n(a b c)"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("// foobar\n\n(a b c)"), 0);
TestResult(parse.node->kind == MD_NodeKind_Main && TestResult(parse.node->kind == MD_NodeKind_Main &&
MD_S8Match(parse.node->prev_comment, MD_S8Lit(""), 0)); MD_S8Match(parse.node->prev_comment, MD_S8Lit(""), 0));
} }
@@ -475,22 +477,22 @@ int main(void)
// NOTE(rjf): Post-Comments: // NOTE(rjf): Post-Comments:
{ {
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a b c) /*foobar*/"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("(a b c) /*foobar*/"), 0);
TestResult(parse.node->kind == MD_NodeKind_Main && TestResult(parse.node->kind == MD_NodeKind_Main &&
MD_S8Match(parse.node->next_comment, MD_S8Lit("foobar"), 0)); MD_S8Match(parse.node->next_comment, MD_S8Lit("foobar"), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a b c) // foobar"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("(a b c) // foobar"), 0);
TestResult(parse.node->kind == MD_NodeKind_Main && TestResult(parse.node->kind == MD_NodeKind_Main &&
MD_S8Match(parse.node->next_comment, MD_S8Lit(" foobar"), 0)); MD_S8Match(parse.node->next_comment, MD_S8Lit(" foobar"), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a b c)\n// foobar"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("(a b c)\n// foobar"), 0);
TestResult(parse.node->kind == MD_NodeKind_Main && TestResult(parse.node->kind == MD_NodeKind_Main &&
MD_S8Match(parse.node->next_comment, MD_S8Lit(""), 0)); MD_S8Match(parse.node->next_comment, MD_S8Lit(""), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("(a b c)\n\n// foobar"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("(a b c)\n\n// foobar"), 0);
TestResult(parse.node->kind == MD_NodeKind_Main && TestResult(parse.node->kind == MD_NodeKind_Main &&
MD_S8Match(parse.node->next_comment, MD_S8Lit(""), 0)); MD_S8Match(parse.node->next_comment, MD_S8Lit(""), 0));
} }
@@ -514,7 +516,7 @@ int main(void)
for(int i_test = 0; i_test < MD_ArrayCount(tests); ++i_test) for(int i_test = 0; i_test < MD_ArrayCount(tests); ++i_test)
{ {
MD_ParseResult parse = MD_ParseWholeString(MD_S8Lit("test.mdesk"), MD_S8CString(tests[i_test].s)); MD_ParseResult parse = MD_ParseWholeString(arena, MD_S8Lit("test.mdesk"), MD_S8CString(tests[i_test].s));
MD_b32 columns_match = 1; MD_b32 columns_match = 1;
{ {
@@ -593,7 +595,7 @@ int main(void)
MD_Node *nodes[MD_ArrayCount(samples)]; MD_Node *nodes[MD_ArrayCount(samples)];
for (int i = 0; i < MD_ArrayCount(samples); i += 1){ for (int i = 0; i < MD_ArrayCount(samples); i += 1){
MD_ParseResult result = MD_ParseOneNode(samples[i], 0); MD_ParseResult result = MD_ParseOneNode(arena, samples[i], 0);
nodes[i] = result.node; nodes[i] = result.node;
} }
@@ -615,41 +617,41 @@ int main(void)
Test("String escaping") Test("String escaping")
{ {
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("`\\``"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("`\\``"), 0);
TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\\`"), 0)); TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\\`"), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("``` \\``` ```"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("``` \\``` ```"), 0);
TestResult(MD_S8Match(parse.node->string, MD_S8Lit(" \\``` "), 0)); TestResult(MD_S8Match(parse.node->string, MD_S8Lit(" \\``` "), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("`````\\````"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("`````\\````"), 0);
TestResult(MD_S8Match(parse.node->string, MD_S8Lit("``\\`"), 0)); TestResult(MD_S8Match(parse.node->string, MD_S8Lit("``\\`"), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("`\\'`"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("`\\'`"), 0);
TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\\'"), 0)); TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\\'"), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("''' \\''' '''"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("''' \\''' '''"), 0);
TestResult(MD_S8Match(parse.node->string, MD_S8Lit(" \\''' "), 0)); TestResult(MD_S8Match(parse.node->string, MD_S8Lit(" \\''' "), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("'''''\\''''"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("'''''\\''''"), 0);
TestResult(MD_S8Match(parse.node->string, MD_S8Lit("''\\'"), 0)); TestResult(MD_S8Match(parse.node->string, MD_S8Lit("''\\'"), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("`\\\"`"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("`\\\"`"), 0);
TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\\\""), 0)); TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\\\""), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("\"\"\" \\\"\"\" \"\"\""), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("\"\"\" \\\"\"\" \"\"\""), 0);
TestResult(MD_S8Match(parse.node->string, MD_S8Lit(" \\\"\"\" "), 0)); TestResult(MD_S8Match(parse.node->string, MD_S8Lit(" \\\"\"\" "), 0));
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("\"\"\"\"\"\\\"\"\"\""), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("\"\"\"\"\"\\\"\"\"\""), 0);
TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\"\"\\\""), 0)); TestResult(MD_S8Match(parse.node->string, MD_S8Lit("\"\"\\\""), 0));
} }
} }
@@ -658,7 +660,7 @@ int main(void)
{ {
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("foo:{x y z; a b c}"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("foo:{x y z; a b c}"), 0);
MD_Node *node = parse.node; MD_Node *node = parse.node;
MD_Node *group_first = node->first_child; MD_Node *group_first = node->first_child;
MD_Node *group_opl = MD_NodeFromFlags(group_first->next, MD_NilNode(), MD_NodeFlag_IsAfterSemicolon); MD_Node *group_opl = MD_NodeFromFlags(group_first->next, MD_NilNode(), MD_NodeFlag_IsAfterSemicolon);
@@ -678,7 +680,7 @@ int main(void)
} }
{ {
MD_ParseResult parse = MD_ParseOneNode(MD_S8Lit("foo:{a b c , d e f , g h i}"), 0); MD_ParseResult parse = MD_ParseOneNode(arena, MD_S8Lit("foo:{a b c , d e f , g h i}"), 0);
MD_Node *node = parse.node; MD_Node *node = parse.node;
MD_Node *group_first = 0; MD_Node *group_first = 0;
MD_Node *group_opl = 0; MD_Node *group_opl = 0;
@@ -714,7 +716,7 @@ int main(void)
// finished unscoped set // finished unscoped set
{ {
MD_String8 text = MD_S8Lit("a:\nb:\nc"); MD_String8 text = MD_S8Lit("a:\nb:\nc");
MD_ParseResult result = MD_ParseWholeString(file_name, text); MD_ParseResult result = MD_ParseWholeString(arena, file_name, text);
TestResult(result.errors.first == 0); TestResult(result.errors.first == 0);
TestResult(result.node->first_child == result.node->last_child); TestResult(result.node->first_child == result.node->last_child);
} }
@@ -722,31 +724,31 @@ int main(void)
// unfinished unscoped set // unfinished unscoped set
{ {
MD_String8 text = MD_S8Lit("a:\nb:\n\n"); MD_String8 text = MD_S8Lit("a:\nb:\n\n");
MD_ParseResult result = MD_ParseWholeString(file_name, text); MD_ParseResult result = MD_ParseWholeString(arena, file_name, text);
TestResult(result.errors.first != 0); TestResult(result.errors.first != 0);
} }
{ {
MD_String8 text = MD_S8Lit("a:\nb:\n"); MD_String8 text = MD_S8Lit("a:\nb:\n");
MD_ParseResult result = MD_ParseWholeString(file_name, text); MD_ParseResult result = MD_ParseWholeString(arena, file_name, text);
TestResult(result.errors.first != 0); TestResult(result.errors.first != 0);
} }
{ {
MD_String8 text = MD_S8Lit("a:\nb:"); MD_String8 text = MD_S8Lit("a:\nb:");
MD_ParseResult result = MD_ParseWholeString(file_name, text); MD_ParseResult result = MD_ParseWholeString(arena, file_name, text);
TestResult(result.errors.first != 0); TestResult(result.errors.first != 0);
} }
// labeled scoped set in unscoped set // labeled scoped set in unscoped set
{ {
MD_String8 text = MD_S8Lit("a: b: {\nx\n} c"); MD_String8 text = MD_S8Lit("a: b: {\nx\n} c");
MD_ParseResult result = MD_ParseWholeString(file_name, text); MD_ParseResult result = MD_ParseWholeString(arena, file_name, text);
TestResult(result.errors.first == 0); TestResult(result.errors.first == 0);
TestResult(MD_ChildCountFromNode(result.node) == 1); TestResult(MD_ChildCountFromNode(result.node) == 1);
TestResult(MD_ChildCountFromNode(result.node->first_child) == 2); TestResult(MD_ChildCountFromNode(result.node->first_child) == 2);
} }
{ {
MD_String8 text = MD_S8Lit("a: b: {\nx\n}\nc"); MD_String8 text = MD_S8Lit("a: b: {\nx\n}\nc");
MD_ParseResult result = MD_ParseWholeString(file_name, text); MD_ParseResult result = MD_ParseWholeString(arena, file_name, text);
TestResult(result.errors.first == 0); TestResult(result.errors.first == 0);
TestResult(MD_ChildCountFromNode(result.node) == 2); TestResult(MD_ChildCountFromNode(result.node) == 2);
TestResult(MD_ChildCountFromNode(result.node->first_child) == 1); TestResult(MD_ChildCountFromNode(result.node->first_child) == 1);
@@ -755,7 +757,7 @@ int main(void)
// scoped set is not unscoped // scoped set is not unscoped
{ {
MD_String8 text = MD_S8Lit("a: {\nx\ny\n} c"); MD_String8 text = MD_S8Lit("a: {\nx\ny\n} c");
MD_ParseResult result = MD_ParseWholeString(file_name, text); MD_ParseResult result = MD_ParseWholeString(arena, file_name, text);
TestResult(result.errors.first == 0); TestResult(result.errors.first == 0);
TestResult(result.node->first_child != result.node->last_child); TestResult(result.node->first_child != result.node->last_child);
} }
@@ -766,19 +768,19 @@ int main(void)
MD_String8 file_name = MD_S8Lit("raw_text"); MD_String8 file_name = MD_S8Lit("raw_text");
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("@foo bar")); MD_ParseResult result = MD_ParseWholeString(arena, file_name, MD_S8Lit("@foo bar"));
TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("foo"), 0)); TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("foo"), 0));
} }
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("@+ bar")); MD_ParseResult result = MD_ParseWholeString(arena, file_name, MD_S8Lit("@+ bar"));
TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("+"), 0)); TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("+"), 0));
} }
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("@'a b c' bar")); MD_ParseResult result = MD_ParseWholeString(arena, file_name, MD_S8Lit("@'a b c' bar"));
TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("a b c"), 0)); TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("a b c"), 0));
} }
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("@100 bar")); MD_ParseResult result = MD_ParseWholeString(arena, file_name, MD_S8Lit("@100 bar"));
TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("100"), 0)); TestResult(MD_NodeHasTag(result.node->first_child, MD_S8Lit("100"), 0));
} }
} }
@@ -789,27 +791,27 @@ int main(void)
// tagged in scoped set always legal // tagged in scoped set always legal
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("foo:{@tag {bar}}\n")); MD_ParseResult result = MD_ParseWholeString(arena, file_name, MD_S8Lit("foo:{@tag {bar}}\n"));
TestResult(result.errors.first == 0); TestResult(result.errors.first == 0);
} }
// tagged label in unscoped set legal // tagged label in unscoped set legal
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("foo:@tag bar\n")); MD_ParseResult result = MD_ParseWholeString(arena, file_name, MD_S8Lit("foo:@tag bar\n"));
TestResult(result.errors.first == 0); TestResult(result.errors.first == 0);
} }
// unlabeled scoped set in unscoped set illegal // unlabeled scoped set in unscoped set illegal
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("foo:bar {bar}\n")); MD_ParseResult result = MD_ParseWholeString(arena, file_name, MD_S8Lit("foo:bar {bar}\n"));
TestResult(result.errors.first != 0); TestResult(result.errors.first != 0);
} }
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("foo:bar @tag {bar}\n")); MD_ParseResult result = MD_ParseWholeString(arena, file_name, MD_S8Lit("foo:bar @tag {bar}\n"));
TestResult(result.errors.first != 0); TestResult(result.errors.first != 0);
} }
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_S8Lit("foo:@tag {bar}\n")); MD_ParseResult result = MD_ParseWholeString(arena, file_name, MD_S8Lit("foo:@tag {bar}\n"));
TestResult(result.errors.first != 0); TestResult(result.errors.first != 0);
} }
} }
@@ -827,7 +829,7 @@ int main(void)
MD_String8 *string = test_strings; MD_String8 *string = test_strings;
for (int i = 0; i < MD_ArrayCount(test_strings); i += 1, string += 1){ for (int i = 0; i < MD_ArrayCount(test_strings); i += 1, string += 1){
MD_ParseResult result = MD_ParseWholeString(file_name, *string); MD_ParseResult result = MD_ParseWholeString(arena, file_name, *string);
TestResult((result.errors.first == 0) && TestResult((result.errors.first == 0) &&
(result.node->first_child == result.node->last_child) && (result.node->first_child == result.node->last_child) &&
(result.node->first_child->flags & MD_NodeFlag_Numeric)); (result.node->first_child->flags & MD_NodeFlag_Numeric));
@@ -852,7 +854,7 @@ int main(void)
MD_String8 *string = test_strings; MD_String8 *string = test_strings;
for (int i = 0; i < MD_ArrayCount(test_strings); i += 1, string += 1){ for (int i = 0; i < MD_ArrayCount(test_strings); i += 1, string += 1){
MD_ParseResult result = MD_ParseWholeString(file_name, *string); MD_ParseResult result = MD_ParseWholeString(arena, file_name, *string);
TestResult((result.errors.first == 0) && TestResult((result.errors.first == 0) &&
(result.node->first_child == result.node->last_child) && (result.node->first_child == result.node->last_child) &&
(result.node->first_child->flags & MD_NodeFlag_Numeric)); (result.node->first_child->flags & MD_NodeFlag_Numeric));
@@ -864,24 +866,24 @@ int main(void)
MD_String8 file_name = MD_S8Lit("raw_text"); MD_String8 file_name = MD_S8Lit("raw_text");
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_ParseResult result = MD_ParseWholeString(arena, file_name,
MD_S8Lit("foo: '(' )")); MD_S8Lit("foo: '(' )"));
TestResult(result.errors.first != 0); TestResult(result.errors.first != 0);
} }
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_ParseResult result = MD_ParseWholeString(arena, file_name,
MD_S8Lit("foo ':' ( )")); MD_S8Lit("foo ':' ( )"));
TestResult(result.errors.first == 0); TestResult(result.errors.first == 0);
TestResult(MD_ChildCountFromNode(result.node) == 3); TestResult(MD_ChildCountFromNode(result.node) == 3);
} }
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_ParseResult result = MD_ParseWholeString(arena, file_name,
MD_S8Lit("'@'bar foo")); MD_S8Lit("'@'bar foo"));
TestResult(result.errors.first == 0); TestResult(result.errors.first == 0);
TestResult(MD_ChildCountFromNode(result.node) == 3); TestResult(MD_ChildCountFromNode(result.node) == 3);
} }
{ {
MD_ParseResult result = MD_ParseWholeString(file_name, MD_ParseResult result = MD_ParseWholeString(arena, file_name,
MD_S8Lit("foo: '(' ')'")); MD_S8Lit("foo: '(' ')'"));
TestResult(result.errors.first == 0); TestResult(result.errors.first == 0);
TestResult(MD_ChildCountFromNode(result.node) == 1); TestResult(MD_ChildCountFromNode(result.node) == 1);