From c8cb9f39953ac0e759fa20a8ba2694249707880a Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 9 Feb 2025 11:51:50 -0500 Subject: [PATCH] prepping to collapse Arena receiving functions to those that receive AllocatorInfo perf impact of the indirection should be minimal, reduces code duplication. Ideally we'd use gencpp to just have the user specify what they want, then modify which proc is avail by doing the refactors required for using either However, it can't process execution bodies yet or expressions so thats not possible. The other way is to just utilize _Generic to generalize the codepath so that it collapses neater but that leads to a ton of implementation getting lifted to preprocessing... so no. --- bin/build.ps1 | 12 +++ code/base/arena.h | 13 ++- code/base/entry_point.c | 2 - code/base/logger.c | 1 - code/base/strings.c | 30 +++--- code/base/thread_context.h | 8 ++ code/mdesk/mdesk.c | 196 +++++++++++++++++++++++++++++----- code/mdesk/mdesk.h | 50 +++++++-- code/os/linux/os_linux.c | 2 +- code/os/win32/os_win32.h | 2 +- gen_c11/c11.refactor | 5 +- tests/code_sanity.c | 8 ++ third_party/stb/stb_sprintf.h | 2 +- 13 files changed, 268 insertions(+), 63 deletions(-) diff --git a/bin/build.ps1 b/bin/build.ps1 index 000c68f..e07ccdb 100644 --- a/bin/build.ps1 +++ b/bin/build.ps1 @@ -139,6 +139,18 @@ if ($code_sanity) $executable = join-path $path_build 'code_sanity.exe' $result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable + + Push-Location $path_build + if ( Test-Path( $executable ) ) { + write-host "`nRunning test/code_sanity" + $time_taken = Measure-Command { & $executable + | ForEach-Object { + write-host `t $_ -ForegroundColor Green + } + } + write-host "`ntest/code_sanity completed in $($time_taken.TotalMilliseconds) ms" + } + Pop-Location } Pop-Location # $path_root diff --git a/code/base/arena.h b/code/base/arena.h index ea3f197..0b14182 100644 --- a/code/base/arena.h +++ b/code/base/arena.h @@ -68,10 +68,15 @@ struct TempArena MD_API void* arena_allocator_proc(void* allocator_data, AllocatorMode mode, SSIZE size, SSIZE alignment, void* old_memory, SSIZE old_size, U64 flags); -force_inline AllocatorInfo -arena_allocator(Arena* arena) { - AllocatorInfo info = { arena_allocator_proc, arena}; - return info; +force_inline AllocatorInfo arena_allocator(Arena* arena) { AllocatorInfo info = { arena_allocator_proc, arena}; return info; } + +// Useful for providing an arena to scratch_begin_alloc +force_inline Arena* +extract_arena(AllocatorInfo ainfo) { + if (allocator_type(ainfo) == AllocatorType_Arena) { + return (Arena*) ainfo.data; + } + return nullptr; } //- rjf: arena creation/destruction diff --git a/code/base/entry_point.c b/code/base/entry_point.c index df5a801..dad247d 100644 --- a/code/base/entry_point.c +++ b/code/base/entry_point.c @@ -19,7 +19,6 @@ void main_thread_base_entry_point(MainThread_EntryPointProc* entry_point, char** #endif thread_namef("[main thread]"); - // TODO(Ed): Review? TempArena scratch = scratch_begin(0, 0); String8List command_line_argument_strings = os_string_list_from_argcv(scratch.arena, (int)arguments_count, arguments); @@ -41,7 +40,6 @@ void main_thread_base_entry_point(MainThread_EntryPointProc* entry_point, char** void supplement_thread_base_entry_point(SupplementThread_EntryPointProc* entry_point, void* params) { - // TODO(Ed): Review? TCTX tctx; tctx_init_and_equip(&tctx); entry_point(params); diff --git a/code/base/logger.c b/code/base/logger.c index 082a239..31c79d5 100644 --- a/code/base/logger.c +++ b/code/base/logger.c @@ -49,7 +49,6 @@ log_msgf(LogMsgKind kind, char *fmt, ...) { } } - //////////////////////////////// //~ rjf: Log Scopes diff --git a/code/base/strings.c b/code/base/strings.c index 748bcaa..5614a87 100644 --- a/code/base/strings.c +++ b/code/base/strings.c @@ -1444,22 +1444,20 @@ alloc_file_name_date_time_string(AllocatorInfo ainfo, DateTime* date_time) { String8 string_from_elapsed_time_alloc(AllocatorInfo ainfo, DateTime dt) { - U8 bytes[KB(8)]; - FArena arena = farena_from_memory(bytes, size_of(bytes)); - AllocatorInfo scratch = farena_allocator(arena); + TempArena scratch = scratch_begin_alloc(ainfo); String8List list = {0}; if (dt.year) { - str8_list_allocf(scratch, &list, "%dy", dt.year); - str8_list_allocf(scratch, &list, "%um", dt.mon); - str8_list_allocf(scratch, &list, "%ud", dt.day); + str8_list_pushf(scratch.arena, &list, "%dy", dt.year); + str8_list_pushf(scratch.arena, &list, "%um", dt.mon); + str8_list_pushf(scratch.arena, &list, "%ud", dt.day); } else if (dt.mon) { - str8_list_allocf(scratch, &list, "%um", dt.mon); - str8_list_allocf(scratch, &list, "%ud", dt.day); + str8_list_pushf(scratch.arena, &list, "%um", dt.mon); + str8_list_pushf(scratch.arena, &list, "%ud", dt.day); } else if (dt.day) { - str8_list_allocf(scratch, &list, "%ud", dt.day); + str8_list_pushf(scratch.arena, &list, "%ud", dt.day); } - str8_list_allocf(scratch, &list, "%u:%u:%u:%u ms", dt.hour, dt.min, dt.sec, dt.msec); + str8_list_pushf(scratch.arena, &list, "%u:%u:%u:%u ms", dt.hour, dt.min, dt.sec, dt.msec); StringJoin join = { str8_lit_comp(""), str8_lit_comp(" "), str8_lit_comp("") }; String8 result = str8_list_join_alloc(ainfo, &list, &join); @@ -1520,7 +1518,7 @@ try_guid_from_string(String8 string, Guid *guid_out) String8 indented_from_string(Arena* arena, String8 string) { -#if 1 // Better than enforcing abstract allocator for this case. +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL TempArena scratch = scratch_begin(&arena, 1); read_only local_persist U8 indentation_bytes[] = " "; @@ -1560,7 +1558,7 @@ indented_from_string(Arena* arena, String8 string) String8 indented_from_string_alloc(AllocatorInfo ainfo, String8 string) { - TempArena scratch = scratch_begin(0, 0); + TempArena scratch = scratch_begin_alloc(ainfo); read_only local_persist U8 indentation_bytes[] = " "; String8List indented_strings = {0}; @@ -1600,7 +1598,7 @@ indented_from_string_alloc(AllocatorInfo ainfo, String8 string) String8 escaped_from_raw_str8(Arena* arena, String8 string) { -#if 1 // Better than enforcing abstract allocator for this case. +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL TempArena scratch = scratch_begin(&arena, 1); String8List parts = {0}; @@ -1650,7 +1648,7 @@ escaped_from_raw_str8(Arena* arena, String8 string) String8 escaped_from_raw_str8_alloc(AllocatorInfo ainfo, String8 string) { - TempArena scratch = scratch_begin(0, 0); + TempArena scratch = scratch_begin_alloc(ainfo); String8List parts = {0}; U64 start_split_idx = 0; @@ -1747,7 +1745,7 @@ raw_from_escaped_str8(Arena* arena, String8 string) String8 raw_from_escaped_str8_alloc(AllocatorInfo ainfo, String8 string) { - TempArena scratch = scratch_begin(0, 0); + TempArena scratch = scratch_begin_alloc(ainfo); String8List strs = {0}; U64 start = 0; @@ -2003,7 +2001,7 @@ fuzzy_match_find(Arena *arena, String8 needle, String8 haystack) FuzzyMatchRangeList fuzzy_match_find_alloc(AllocatorInfo ainfo, String8 needle, String8 haystack) { - TempArena scratch = scratch_begin(0, 0); + TempArena scratch = scratch_begin_alloc(ainfo); String8List needles = str8_split(scratch.arena, needle, (U8*)" ", 1, 0); FuzzyMatchRangeList result = {0}; diff --git a/code/base/thread_context.h b/code/base/thread_context.h index ebdcdeb..d5a64f0 100644 --- a/code/base/thread_context.h +++ b/code/base/thread_context.h @@ -39,6 +39,14 @@ void tctx_write_srcloc(char* file_name, U64 line_number); void tctx_read_srcloc (char** file_name, U64* line_number); #define tctx_write_this_srcloc() tctx_write_srcloc(__FILE__, __LINE__) +inline TempArena +scratch__begin_alloc(AllocatorInfo ainfo) { + Arena* arena = extract_arena(ainfo); + TempArena scratch = temp_begin(tctx_get_scratch(arena, arena != nullptr)); + return scratch; +} + +#define scratch_begin_alloc(ainfo) scratch__begin_alloc(ainfo) #define scratch_begin(conflicts, count) temp_begin(tctx_get_scratch((conflicts), (count))) #define scratch_end(scratch) temp_end(scratch) diff --git a/code/mdesk/mdesk.c b/code/mdesk/mdesk.c index 7a448f2..260e5d3 100644 --- a/code/mdesk/mdesk.c +++ b/code/mdesk/mdesk.c @@ -17,9 +17,9 @@ void init(Context* ctx) } -void deinit(Context* ctx) -{ -} +// void deinit(Context* ctx) +// { +// } //////////////////////////////// //~ rjf: Message Type Functions @@ -27,6 +27,7 @@ void deinit(Context* ctx) void msg_list_push(Arena* arena, MsgList* msgs, Node* node, MsgKind kind, String8 string) { +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL Msg* msg = push_array(arena, Msg, 1); msg->node = node; @@ -35,6 +36,24 @@ msg_list_push(Arena* arena, MsgList* msgs, Node* node, MsgKind kind, String8 str sll_queue_push(msgs->first, msgs->last, msg); + msgs->count += 1; + msgs->worst_message_kind = md_max(kind, msgs->worst_message_kind); +#else + msg_list_alloc(arena_allocator(arena), msgs, node, kind, string); +#endif +} + +void +msg_list_alloc(AllocatorInfo ainfo, MsgList* msgs, Node* node, MsgKind kind, String8 string) +{ + Msg* + msg = alloc_array(ainfo, Msg, 1); + msg->node = node; + msg->kind = kind; + msg->string = string; + + sll_queue_push(msgs->first, msgs->last, msg); + msgs->count += 1; msgs->worst_message_kind = md_max(kind, msgs->worst_message_kind); } @@ -80,6 +99,7 @@ content_string_from_token_flags_str8(TokenFlags flags, String8 string) String8List string_list_from_token_flags(Arena* arena, TokenFlags flags) { +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL String8List strs = {0}; if (flags & TokenFlag_Identifier ){ str8_list_push(arena, &strs, str8_lit("Identifier" )); } if (flags & TokenFlag_Numeric ){ str8_list_push(arena, &strs, str8_lit("Numeric" )); } @@ -93,11 +113,33 @@ string_list_from_token_flags(Arena* arena, TokenFlags flags) if (flags & TokenFlag_BrokenStringLiteral ){ str8_list_push(arena, &strs, str8_lit("BrokenStringLiteral")); } if (flags & TokenFlag_BadCharacter ){ str8_list_push(arena, &strs, str8_lit("BadCharacter" )); } return strs; +#else + return string_list_from_token_flags_alloc(arena_allocator(arena), flags); +#endif +} + +String8List +string_list_from_token_flags_alloc(AllocatorInfo ainfo, TokenFlags flags) +{ + String8List strs = {0}; + if (flags & TokenFlag_Identifier ){ str8_list_alloc(ainfo, &strs, str8_lit("Identifier" )); } + if (flags & TokenFlag_Numeric ){ str8_list_alloc(ainfo, &strs, str8_lit("Numeric" )); } + if (flags & TokenFlag_StringLiteral ){ str8_list_alloc(ainfo, &strs, str8_lit("StringLiteral" )); } + if (flags & TokenFlag_Symbol ){ str8_list_alloc(ainfo, &strs, str8_lit("Symbol" )); } + if (flags & TokenFlag_Reserved ){ str8_list_alloc(ainfo, &strs, str8_lit("Reserved" )); } + if (flags & TokenFlag_Comment ){ str8_list_alloc(ainfo, &strs, str8_lit("Comment" )); } + if (flags & TokenFlag_Whitespace ){ str8_list_alloc(ainfo, &strs, str8_lit("Whitespace" )); } + if (flags & TokenFlag_Newline ){ str8_list_alloc(ainfo, &strs, str8_lit("Newline" )); } + if (flags & TokenFlag_BrokenComment ){ str8_list_alloc(ainfo, &strs, str8_lit("BrokenComment" )); } + if (flags & TokenFlag_BrokenStringLiteral ){ str8_list_alloc(ainfo, &strs, str8_lit("BrokenStringLiteral")); } + if (flags & TokenFlag_BadCharacter ){ str8_list_alloc(ainfo, &strs, str8_lit("BadCharacter" )); } + return strs; } void token_chunk_list_push(Arena* arena, TokenChunkList* list, U64 cap, Token token) { +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL TokenChunkNode* node = list->last; if (node == 0 || node->count >= node->cap) { node = push_array(arena, TokenChunkNode, 1); @@ -109,11 +151,31 @@ token_chunk_list_push(Arena* arena, TokenChunkList* list, U64 cap, Token token) memory_copy_struct(&node->v[node->count], &token); node->count += 1; list->total_token_count += 1; +#else + token_chunk_list_alloc(arena_allocator(arena), list, cap, token); +#endif +} + +void +token_chunk_list_alloc(AllocatorInfo ainfo, TokenChunkList* list, U64 cap, Token token) +{ + TokenChunkNode* node = list->last; + if (node == 0 || node->count >= node->cap) { + node = alloc_array(ainfo, TokenChunkNode, 1); + node->cap = cap; + node->v = alloc_array_no_zero(ainfo, Token, cap); + sll_queue_push(list->first, list->last, node); + list->chunk_count += 1; + } + memory_copy_struct(&node->v[node->count], &token); + node->count += 1; + list->total_token_count += 1; } TokenArray token_array_from_chunk_list(Arena* arena, TokenChunkList* chunks) { +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL TokenArray result = {0}; result.count = chunks->total_token_count; result.v = push_array_no_zero(arena, Token, result.count); @@ -124,6 +186,24 @@ token_array_from_chunk_list(Arena* arena, TokenChunkList* chunks) write_idx += n->count; } return result; +#else + return token_array_from_chunk_list_alloc(arena_allocator(arena), chunks); +#endif +} + +TokenArray +token_array_from_chunk_list_alloc(AllocatorInfo ainfo, TokenChunkList* chunks) +{ + TokenArray result = {0}; + result.count = chunks->total_token_count; + result.v = alloc_array_no_zero(ainfo, Token, result.count); + U64 write_idx = 0; + for(TokenChunkNode *n = chunks->first; n != 0; n = n->next) + { + memory_copy(result.v + write_idx, n->v, size_of(Token) * n->count); + write_idx += n->count; + } + return result; } //////////////////////////////// @@ -226,7 +306,7 @@ node_match(Node* a, Node* b, StringMatchFlags flags) } B32 -tree_match(Node *a, Node *b, StringMatchFlags flags) +tree_match(Node* a, Node* b, StringMatchFlags flags) { B32 result = node_match(a, b, flags); if (result) @@ -248,6 +328,7 @@ tree_match(Node *a, Node *b, StringMatchFlags flags) Node* tree_copy(Arena* arena, Node* src_root) { +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL Node* dst_root = nil_node(); Node* dst_parent = dst_root; { @@ -280,15 +361,60 @@ tree_copy(Arena* arena, Node* src_root) } } return dst_root; +#else + tree_copy_alloc(arena_allocator(arena), src_root); +#endif +} + +Node* +tree_copy_alloc(AllocatorInfo ainfo, Node* src_root) +{ + Node* dst_root = nil_node(); + Node* dst_parent = dst_root; + { + NodeRec rec = {0}; + for(Node* src = src_root; !node_is_nil(src); src = rec.next) + { + Node* dst = alloc_array(ainfo, Node, 1); + dst->first = dst->last = dst->parent = dst->next = dst->prev = nil_node(); + dst->first_tag = dst->last_tag = nil_node(); + dst->kind = src->kind; + dst->flags = src->flags; + dst->string = alloc_str8_copy(ainfo, src->string); + dst->raw_string = alloc_str8_copy(ainfo, src->raw_string); + dst->src_offset = src->src_offset; + dst->parent = dst_parent; + if (dst_parent != nil_node()) { + dll_push_back_npz(nil_node(), dst_parent->first, dst_parent->last, dst, next, prev); + } + else { + dst_root = dst_parent = dst; + } + + rec = node_rec_depth_first_pre(src, src_root); + if (rec.push_count != 0) { + dst_parent = dst; + } + else for (U64 idx = 0; idx < rec.pop_count; idx += 1) { + dst_parent = dst_parent->parent; + } + } + } + return dst_root; } //////////////////////////////// //~ rjf: Text -> Tokens Functions TokenizeResult -tokenize_from_text(Arena* arena, String8 text) +tokenize_from_text(Arena* arena, String8 text) { + tokenize_from_text_alloc(arena_allocator(arena), text); +} + +TokenizeResult +tokenize_from_text_alloc(AllocatorInfo ainfo, String8 text) { - TempArena scratch = scratch_begin(&arena, 1); + TempArena scratch = scratch_begin_alloc(ainfo); TokenChunkList tokens = {0}; MsgList msgs = {0}; @@ -593,22 +719,22 @@ tokenize_from_text(Arena* arena, String8 text) //- rjf: push errors on unterminated comments if (token_flags & TokenFlag_BrokenComment) { - Node* error = push_node(arena, NodeKind_ErrorMarker, 0, str8_lit(""), str8_lit(""), token_start - byte_first); + Node* error = alloc_node(ainfo, NodeKind_ErrorMarker, 0, str8_lit(""), str8_lit(""), token_start - byte_first); String8 error_string = str8_lit("Unterminated comment."); - msg_list_push(arena, &msgs, error, MsgKind_Error, error_string); + msg_list_alloc(ainfo, &msgs, error, MsgKind_Error, error_string); } //- rjf: push errors on unterminated strings if (token_flags & TokenFlag_BrokenStringLiteral) { - Node* error = push_node(arena, NodeKind_ErrorMarker, 0, str8_lit(""), str8_lit(""), token_start - byte_first); + Node* error = alloc_node(ainfo, NodeKind_ErrorMarker, 0, str8_lit(""), str8_lit(""), token_start - byte_first); String8 error_string = str8_lit("Unterminated string literal."); - msg_list_push(arena, &msgs, error, MsgKind_Error, error_string); + msg_list_alloc(ainfo, &msgs, error, MsgKind_Error, error_string); } } //- rjf: bake, fill & return TokenizeResult result = {0}; { - result.tokens = token_array_from_chunk_list(arena, &tokens); + result.tokens = token_array_from_chunk_list_alloc(ainfo, &tokens); result.msgs = msgs; } scratch_end(scratch); @@ -665,13 +791,18 @@ void parse__work_pop(ParseWorkNode* work_top, ParseWorkNode* broken_work) { } ParseResult -parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray tokens) +parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray tokens) { + return parse_from_text_tokens_alloc(arena_allocator(arena), filename, text, tokens); +} + +ParseResult +parse_from_text_tokens(AllocatorInfo ainfo, String8 filename, String8 text, TokenArray tokens) { - TempArena scratch = scratch_begin(&arena, 1); + TempArena scratch = scratch_begin_alloc(ainfo); //- rjf: set up outputs MsgList msgs = {0}; - Node* root = push_node(arena, NodeKind_File, 0, filename, text, 0); + Node* root = alloc_node(ainfo, NodeKind_File, 0, filename, text, 0); //- rjf: set up parse rule stack ParseWorkNode first_work = { 0, ParseWorkKind_Main, root }; @@ -766,9 +897,9 @@ parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray //- rjf: [main, main_implicit] unexpected reserved tokens if (mode_main_or_main_implict && found_unexpected) { - Node* error = push_node(arena, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min); - String8 error_string = push_str8f(arena, "Unexpected reserved symbol \"%S\".", token_string); - msg_list_push(arena, &msgs, error, MsgKind_Error, error_string); + Node* error = alloc_node(ainfo, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min); + String8 error_string = alloc_str8f(ainfo, "Unexpected reserved symbol \"%S\".", token_string); + msg_list_alloc(ainfo, &msgs, error, MsgKind_Error, error_string); token += 1; goto end_consume; } @@ -781,9 +912,9 @@ parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray // Token after should be label. if (token + 1 >= tokens_opl || !(token[1].flags & TokenFlagGroup_Label)) { - Node* error = push_node(arena, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min); + Node* error = alloc_node(ainfo, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min); String8 error_string = str8_lit("Tag label expected after @ symbol."); - msg_list_push(arena, &msgs, error, MsgKind_Error, error_string); + msg_list_alloc(ainfo, &msgs, error, MsgKind_Error, error_string); token += 1; goto end_consume; @@ -794,7 +925,7 @@ parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray String8 tag_name_raw = str8_substr(text, token[1].range); String8 tag_name = content_string_from_token_flags_str8(token[1].flags, tag_name_raw); - Node* node = push_node(arena, NodeKind_Tag, node_flags_from_token_flags(token[1].flags), tag_name, tag_name_raw, token[0].range.min); + Node* node = alloc_node(ainfo, NodeKind_Tag, node_flags_from_token_flags(token[1].flags), tag_name, tag_name_raw, token[0].range.min); dll_push_back_npz(nil_node(), work_top->first_gathered_tag, work_top->last_gathered_tag, node, next, prev); B32 found_argument_paren = token[2].flags & TokenFlag_Reserved && str8_match(str8_substr(text, token[2].range), str8_lit("("), 0); @@ -821,7 +952,7 @@ parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray work_top->gathered_node_flags = 0; - Node* node = push_node(arena, NodeKind_Main, flags, node_string, node_string_raw, token[0].range.min); + Node* node = ainfo_node(ainfo, NodeKind_Main, flags, node_string, node_string_raw, token[0].range.min); node->first_tag = work_top->first_gathered_tag; node->last_tag = work_top->last_gathered_tag; for (Node* tag = work_top->first_gathered_tag; !node_is_nil(tag); tag = tag->next) { @@ -852,7 +983,7 @@ parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray work_top->gathered_node_flags = 0; Node* - node = push_node(arena, NodeKind_Main, flags, str8_lit(""), str8_lit(""), token[0].range.min); + node = alloc_node(ainfo, NodeKind_Main, flags, str8_lit(""), str8_lit(""), token[0].range.min); node->first_tag = work_top->first_gathered_tag; node->last_tag = work_top->last_gathered_tag; for (Node* tag = work_top->first_gathered_tag; !node_is_nil(tag); tag = tag->next) { @@ -907,9 +1038,9 @@ parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray if (work_top->counted_newlines >= 2) { Node* node = work_top->parent; - Node* error = push_node(arena, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min); - String8 error_string = push_str8f(arena, "More than two newlines following \"%S\", which has implicitly-delimited children, resulting in an empty list of children.", node->string); - msg_list_push(arena, &msgs, error, MsgKind_Warning, error_string); + Node* error = alloc_node(ainfo, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min); + String8 error_string = alloc_str8f(ainfo, "More than two newlines following \"%S\", which has implicitly-delimited children, resulting in an empty list of children.", node->string); + msg_list_alloc(ainfo, &msgs, error, MsgKind_Warning, error_string); parse_work_pop(); } else @@ -956,9 +1087,9 @@ parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray //- rjf: no consumption -> unexpected token! we don't know what to do with this. { - Node* error = push_node(arena, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min); - String8 error_string = push_str8f(arena, "Unexpected \"%S\" token.", token_string); - msg_list_push(arena, &msgs, error, MsgKind_Error, error_string); + Node* error = alloc_node(ainfo, NodeKind_ErrorMarker, 0, token_string, token_string, token->range.min); + String8 error_string = alloc_str8f(ainfo, "Unexpected \"%S\" token.", token_string); + msg_list_alloc(ainfo, &msgs, error, MsgKind_Error, error_string); token += 1; // ??? } @@ -989,6 +1120,15 @@ parse_from_text(Arena* arena, String8 filename, String8 text) { return parse; } +ParseResult +parse_from_text(AllocatorInfo ainfo, String8 filename, String8 text) { + TempArena scratch = scratch_begin_alloc(ainfo); + TokenizeResult tokenize = tokenize_from_text(scratch.arena, text); + ParseResult parse = parse_from_text_tokens_alloc(ainfo, filename, text, tokenize.tokens); + scratch_end(scratch); + return parse; +} + //////////////////////////////// //~ rjf: Tree -> Text Functions diff --git a/code/mdesk/mdesk.h b/code/mdesk/mdesk.h index 4bef3ba..13168b3 100644 --- a/code/mdesk/mdesk.h +++ b/code/mdesk/mdesk.h @@ -276,8 +276,10 @@ MD_API void init (Context* ctx); //////////////////////////////// //~ rjf: Message Type Functions -MD_API void msg_list_push (Arena* arena, MsgList* msgs, Node* node, MsgKind kind, String8 string); - void msg_list_pushf(Arena* arena, MsgList* msgs, Node* node, MsgKind kind, char *fmt, ...); +MD_API void msg_list_push (Arena* arena, MsgList* msgs, Node* node, MsgKind kind, String8 string); +MD_API void msg_list_alloc (AllocatorInfo ainfo, MsgList* msgs, Node* node, MsgKind kind, String8 string); + void msg_list_pushf (Arena* arena, MsgList* msgs, Node* node, MsgKind kind, char *fmt, ...); + void msg_list_allocf(AllocatorInfo ainfo, MsgList* msgs, Node* node, MsgKind kind, char *fmt, ...); MD_API void msg_list_concat_in_place(MsgList* dst, MsgList* to_push); @@ -290,6 +292,15 @@ msg_list_pushf(Arena* arena, MsgList* msgs, Node* node, MsgKind kind, char* fmt, va_end(args); } +inline void +msg_list_allocf(AllocatorInfo ainfo, MsgList* msgs, Node* node, MsgKind kind, char* fmt, ...) { + va_list args; + va_start(args, fmt); + String8 string = alloc_str8fv(ainfo, fmt, args); + msg_list_alloc(ainfo, msgs, node, kind, string); + va_end(args); +} + //////////////////////////////// //~ rjf: Token Type Functions @@ -361,6 +372,7 @@ void unhook (Node* node); inline Node* push_node(Arena* arena, NodeKind kind, NodeFlags flags, String8 string, String8 raw_string, U64 src_offset) { +#if MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL Node* node = push_array(arena, Node, 1); node->first = node->last = node->parent = node->next = node->prev = node->first_tag = node->last_tag = nil_node(); node->kind = kind; @@ -369,6 +381,21 @@ push_node(Arena* arena, NodeKind kind, NodeFlags flags, String8 string, String8 node->raw_string = raw_string; node->src_offset = src_offset; return node; +#else + alloc_node(arena_allocator(arena), kind, flags, string, raw_string, src_offset); +#endif +} + +inline Node* +alloc_node(AllocatorInfo ainfo, NodeKind kind, NodeFlags flags, String8 string, String8 raw_string, U64 src_offset) { + Node* node = alloc_array(ainfo, Node, 1); + node->first = node->last = node->parent = node->next = node->prev = node->first_tag = node->last_tag = nil_node(); + node->kind = kind; + node->flags = flags; + node->string = string; + node->raw_string = raw_string; + node->src_offset = src_offset; + return node; } inline void @@ -522,25 +549,32 @@ MD_API B32 node_match(Node* a, Node* b, StringMatchFlags flags); //- rjf: tree duplication -MD_API Node* tree_copy(Arena* arena, Node* src_root); +MD_API Node* tree_copy (Arena* arena, Node* src_root); +MD_API Node* tree_copy_alloc(AllocatorInfo ainfo, Node* src_root); //////////////////////////////// //~ rjf: Text -> Tokens Functions -MD_API TokenizeResult tokenize_from_text(Arena* arena, String8 text); +MD_API TokenizeResult tokenize_from_text (Arena* arena, String8 text); +MD_API TokenizeResult tokenize_from_text_alloc(AllocatorInfo ainfo, String8 text); //////////////////////////////// //~ rjf: Tokens -> Tree Functions -MD_API ParseResult parse_from_text_tokens(Arena* arena, String8 filename, String8 text, TokenArray tokens); +MD_API ParseResult parse_from_text_tokens (Arena* arena, String8 filename, String8 text, TokenArray tokens); +MD_API ParseResult parse_from_text_tokens_alloc(AllocatorInfo ainfo, String8 filename, String8 text, TokenArray tokens); //////////////////////////////// //~ rjf: Bundled Text -> Tree Functions -MD_API ParseResult parse_from_text(Arena* arena, String8 filename, String8 text); -#define tree_from_string(arena, string) (parse_from_text((arena), str8_zero(), (string)).root) +MD_API ParseResult parse_from_text (Arena* arena, String8 filename, String8 text); +MD_API ParseResult parse_from_text_alloc(AllocatorInfo ainfo, String8 filename, String8 text); + +#define tree_from_string(arena, string) (parse_from_text ((arena), str8_zero(), (string)).root) +#define tree_from_string_alloc(ainfo, string) (parse_from_text_alloc((ainfo), str8_zero(), (string)).root) //////////////////////////////// //~ rjf: Tree -> Text Functions -MD_API String8List debug_string_list_from_tree(Arena* arena, Node* root); +MD_API String8List debug_string_list_from_tree (Arena* arena, Node* root); +MD_API String8List debug_string_list_from_tree_alloc(AllocatorInfo ainfo, Node* root); diff --git a/code/os/linux/os_linux.c b/code/os/linux/os_linux.c index d7af33e..63d8b24 100644 --- a/code/os/linux/os_linux.c +++ b/code/os/linux/os_linux.c @@ -290,7 +290,7 @@ String8 os_full_path_from_path_alloc(AllocatorInfo ainfo, String8 path) { char buffer[PATH_MAX] = {0}; - TempArena scratch = scratch_begin(0, 0); { + TempArena scratch = scratch_begin_alloc(ainfo); { String8 path_copy = push_str8_copy(scratch.arena, path); realpath((char *)path_copy.str, buffer); } diff --git a/code/os/win32/os_win32.h b/code/os/win32/os_win32.h index 8c763a5..6d78309 100644 --- a/code/os/win32/os_win32.h +++ b/code/os/win32/os_win32.h @@ -166,7 +166,7 @@ MD_API DWORD os_w32_thread_entry_point(void* ptr); inline String8 os_get_current_path_alloc(AllocatorInfo ainfo) { String8 name; - TempArena scratch = scratch_begin(0, 0); + TempArena scratch = scratch_begin_alloc(ainfo); { DWORD length = GetCurrentDirectoryW(0, 0); U16* memory = push_array_no_zero(scratch.arena, U16, length + 1); diff --git a/gen_c11/c11.refactor b/gen_c11/c11.refactor index 4cbc1ee..52d0880 100644 --- a/gen_c11/c11.refactor +++ b/gen_c11/c11.refactor @@ -503,6 +503,8 @@ word TempArena, MD_TempArena namespace arena_, md_arena_ namespace push_array, md_push_array_ +word extract_arena, md_extract_arena + word temp_begin, md_temp_begin word temp_end, md_temp_end @@ -933,7 +935,8 @@ word TCTX, MD_TCTX namespace tctx, md_tctx -word scratch_begin, md_scratch_begin +word scratch_begin, md_scratch_begin +word scratch_begin_alloc, md_scratch_begin_alloc // base/command_line.h diff --git a/tests/code_sanity.c b/tests/code_sanity.c index f315d8a..a215586 100644 --- a/tests/code_sanity.c +++ b/tests/code_sanity.c @@ -1,13 +1,21 @@ // This is test strictly for the granular (non-generated) version of the library to make sure it operates correctly +// #define MD_DONT_MAP_ANREA_TO_ALLOCATOR_IMPL #include "metadesk.c" +// This program expects to be run from the build directory (where it would be after being built) +#define path_examples "../examples" +#define path_intro path_examples "/intro" +#define path_hello_world_medesk path_intro "/hello_world.mdesk" + int main() { Context ctx = {0}; ctx.os_ctx.enable_large_pages = true; init(& ctx); + + printf("metadesk: got past init!"); deinit(& ctx); diff --git a/third_party/stb/stb_sprintf.h b/third_party/stb/stb_sprintf.h index a630870..7fa753e 100644 --- a/third_party/stb/stb_sprintf.h +++ b/third_party/stb/stb_sprintf.h @@ -2175,7 +2175,7 @@ static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, c *decimal_pos = tens; *start = out; *len = e; - return ng; + return ng; } #undef stbsp__ddmulthi