diff --git a/.vscode/settings.json b/.vscode/settings.json index fc55c5f..f3a91f7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -72,5 +72,5 @@ }, "autoHide.autoHidePanel": false, "autoHide.autoHideSideBar": false, - "dimmer.enabled": true + "dimmer.enabled": false } diff --git a/gen_c_library/c_library.cpp b/gen_c_library/c_library.cpp index d26a866..69ac6c1 100644 --- a/gen_c_library/c_library.cpp +++ b/gen_c_library/c_library.cpp @@ -77,7 +77,7 @@ void format_file( char const* path ) #undef cf_verbse } -Code dump_to_scratch_and_retireve( Code code ) +Code format_code_to_untyped( Code code ) { Builder ecode_file_temp = Builder::open("gen/scratch.hpp"); ecode_file_temp.print(code); @@ -120,857 +120,848 @@ int gen_main() Code pop_ignores = scan_file( project_dir "helpers/pop_ignores.inline.hpp" ); Code c_library_header_start = scan_file( "components/header_start.hpp" ); +// Header Content: Reflection and Generation + +#pragma region Resolve Dependencies + Code header_platform = scan_file( project_dir "dependencies/platform.hpp" ); + Code header_macros = scan_file( project_dir "dependencies/macros.hpp" ); + Code header_basic_types = scan_file( project_dir "dependencies/basic_types.hpp" ); + Code header_debug = scan_file( project_dir "dependencies/debug.hpp" ); + Code header_string_ops = scan_file( project_dir "dependencies/string_ops.hpp" ); + Code header_hashing = scan_file( project_dir "dependencies/hashing.hpp" ); + Code header_timing = scan_file( project_dir "dependencies/timing.hpp" ); + + CodeBody parsed_header_memory = parse_file( project_dir "dependencies/memory.hpp" ); + CodeBody header_memory = def_body(CT_Global_Body); + for ( Code entry = parsed_header_memory.begin(); entry != parsed_header_memory.end(); ++ entry ) switch (entry->Type) + { + case CT_Using: + { + log_fmt("REPLACE THIS MANUALLY: %SC\n", entry->Name); + CodeUsing using_ver = cast(CodeUsing, entry); + CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); + + header_memory.append(typedef_ver); + } + break; + case CT_Function_Fwd: + { + CodeFn fn = cast(CodeFn, entry); + header_memory.append(fn); + } + break; + case CT_Function: + { + CodeFn fn = cast(CodeFn, entry); + if (fn->Name.is_equal(txt("heap"))) + { + Code heap_def = untyped_str(txt("#define heap() (AllocatorInfo){ heap_allocator_proc, nullptr }")); + header_memory.append(heap_def); + continue; + } + + if (fn->Specs) { + s32 constexpr_found = fn->Specs.remove( Spec_Constexpr ); + if (constexpr_found > -1) { + //log_fmt("Found constexpr: %S\n", entry.to_string()); + fn->Specs.append(Spec_Inline); + } + } + header_memory.append(fn); + } + break; + case CT_Template: + { + CodeTemplate tmpl = cast(CodeTemplate, entry); + if ( tmpl->Declaration->Name.contains(txt("swap"))) + { + CodeBody macro_swap = parse_global_body( txt(R"( +#define swap( a, b ) \ +do \ +{ \ + typeof( a ) temp = ( a ); \ + ( a ) = ( b ); \ + ( b ) = temp; \ + } while ( 0 ) +)" + )); + header_memory.append(macro_swap); + } + } + break; + case CT_Enum: + { + convert_cpp_enum_to_c(cast(CodeEnum, entry), header_memory); + } + break; + case CT_Struct_Fwd: + { + CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); + header_memory.append(entry); + header_memory.append(tdef); + } + break; + case CT_Class: + case CT_Struct: + { + CodeBody body = cast(CodeBody, entry->Body); + CodeBody new_body = def_body( entry->Body->Type ); + for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch (body_entry->Type) + { + case CT_Preprocess_If: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), body_entry, body, new_body ); + if (found) break; + } + break; + + default: + new_body.append(body_entry); + break; + } + entry->Body = new_body; + + CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); + header_memory.append(entry); + header_memory.append(tdef); + } + break; + case CT_Preprocess_If: + { + b32 found = ignore_preprocess_cond_block(txt("! GEN_C_LIKE_CPP"), entry, parsed_header_memory, header_memory ); + if (found) break; + + header_memory.append(entry); + } + break; + case CT_Preprocess_IfDef: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_memory, header_memory ); + if (found) break; + + header_memory.append(entry); + } + break; + case CT_Preprocess_Pragma: + { + CodePragma pragma = cast(CodePragma, entry); + + b32 found = swap_pragma_region_implementation( txt("FixedArena"), gen_fixed_arenas, entry, header_memory); + if (found) break; + + header_memory.append(entry); + } + break; + default: { + header_memory.append(entry); + } + break; + } + + CodeBody parsed_header_printing = parse_file( project_dir "dependencies/printing.hpp" ); + CodeBody header_printing = def_body(CT_Global_Body); + for ( Code entry = parsed_header_printing.begin(); entry != parsed_header_printing.end(); ++ entry ) switch (entry->Type) + { + case CT_Preprocess_IfDef: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_printing, header_printing ); + if (found) break; + + header_printing.append(entry); + } + break; + case CT_Variable: + { + if ( strc_contains(entry->Name, txt("Msg_Invalid_Value"))) + { + CodeDefine define = def_define(entry->Name, entry->Value->Content); + header_printing.append(define); + continue; + } + header_printing.append(entry); + } + break; + default: + header_printing.append(entry); + break; + } + + Code array_ssize = gen_array(txt("ssize"), txt("Array_ssize")); + Code array_string_cached = gen_array(txt("StringCached"), txt("Array_StringCached")); + + CodeBody parsed_header_strings = parse_file( project_dir "dependencies/strings.hpp" ); + CodeBody header_strings = def_body(CT_Global_Body); + for ( Code entry = parsed_header_strings.begin(); entry != parsed_header_strings.end(); ++ entry ) switch (entry->Type) + { + case CT_Preprocess_If: + { + CodePreprocessCond cond = cast(CodePreprocessCond, entry); + if (cond->Content.is_equal(txt("GEN_COMPILER_C"))) + { + ++ entry; // Remove #if GEN_COMPILER_C + for ( ; entry->Type != CT_Preprocess_Else + && entry->Type != CT_Preprocess_EndIf; ++ entry ) { + header_strings.append(entry); // Preserve content + } + for ( ; entry->Type != CT_Preprocess_EndIf; ++ entry ) {} // Discard C++ + // #endif discarded by for loop + break; + } + + bool found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_header_strings, header_strings); + if (found) break; + + found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_header_strings, header_strings); + if (found) break; + } + break; + + case CT_Preprocess_IfDef: + { + ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_strings, header_strings ); + } + break; + + case CT_Preprocess_IfNotDef: + { + //log_fmt("\nIFNDEF: %SC\n", entry->Content); + header_strings.append(entry); + } + break; + + case CT_Struct_Fwd: + { + if ( entry->Name.is_equal(txt("String")) ) + { + CodeTypedef c_def = parse_typedef(code( typedef char* String; )); + header_strings.append(c_def); + header_strings.append(fmt_newline); + ++ entry; + continue; + } + else + { + CodeTypedef c_def = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); + header_strings.append(c_def); + } + header_strings.append(entry); + } + break; + + case CT_Struct: + { + CodeBody body = cast(CodeBody, entry->Body); + CodeBody new_body = def_body( entry->Body->Type ); + for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch (body_entry->Type) + { + case CT_Preprocess_If: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), body_entry, body, new_body ); + if (found) break; + + new_body.append(body_entry); + } + break; + default: + new_body.append(body_entry); + break; + } + entry->Body = new_body; + header_strings.append(entry); + } + break; + + case CT_Typedef: + { + StrC name_string_table = txt("StringTable"); + + CodeTypedef td = cast(CodeTypedef, entry); + if (td->Name.contains(name_string_table)) + { + CodeBody ht = gen_hashtable(txt("StrC"), name_string_table); + header_strings.append(ht); + break; + } + header_strings.append(td); + } + break; + + default: + header_strings.append(entry); + break; + } + + CodeBody array_u8 = gen_array(txt("u8"), txt("Array_u8")); + + CodeBody parsed_header_filesystem = parse_file( project_dir "dependencies/filesystem.hpp" ); + CodeBody header_filesystem = def_body(CT_Global_Body); + for ( Code entry = parsed_header_filesystem.begin(); entry != parsed_header_filesystem.end(); ++ entry ) switch (entry->Type) + { + case CT_Preprocess_IfDef: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_filesystem, header_filesystem ); + if (found) break; + + header_filesystem.append(entry); + } + break; + + case CT_Enum: + { + if (entry->Name.is_equal(txt("FileOperations"))) + continue; + convert_cpp_enum_to_c(cast(CodeEnum, entry), header_filesystem); + } + break; + + case CT_Enum_Fwd: + case CT_Struct_Fwd: + case CT_Struct: + case CT_Union: + case CT_Union_Fwd: + { + StrC type_str = codetype_to_keyword_str(entry->Type); + StrC formated_tmpl = token_fmt_impl( 3, + "type", type_str + , "name", entry->Name, + stringize( + typedef ; + )); + CodeTypedef tdef = parse_typedef(formated_tmpl); + header_filesystem.append(entry); + header_filesystem.append(tdef); + } + break; + + case CT_Variable: + { + CodeVar var = cast(CodeVar, entry); + if (var->Specs.has(Spec_Constexpr) > -1) + { + CodeDefine define = def_define(entry->Name, entry->Value->Content); + header_filesystem.append(define); + continue; + } + header_filesystem.append(entry); + } + break; + default: + header_filesystem.append(entry); + break; + } + + CodeBody array_adt_node = gen_array(txt("ADT_Node"), txt("Array_ADT_Node")); + + CodeBody parsed_header_parsing = parse_file( project_dir "dependencies/parsing.hpp" ); + CodeBody header_parsing = def_body(CT_Global_Body); + for ( Code entry = parsed_header_parsing.begin(); entry != parsed_header_parsing.end(); ++ entry ) switch (entry->Type) + { + case CT_Preprocess_Pragma: + { + if ( entry->Content.contains(txt("ADT")) ) + { + header_parsing.append(entry); + header_parsing.append(fmt_newline); + + // Add ADT_Node forward and typedef early. + CodeStruct adt_node_fwd = parse_struct(code( struct ADT_Node; )); + CodeTypedef adt_node_typedef = parse_typedef(code( typedef struct ADT_Node ADT_Node; )); + header_parsing.append(adt_node_fwd); + header_parsing.append(adt_node_typedef); + + // Skip typedef since we added it + b32 continue_for = true; + for (Code array_entry = array_adt_node.begin(); continue_for && array_entry != array_adt_node.end(); ++ array_entry) switch (array_entry->Type) + { + case CT_Typedef: + { + // pop the array entry + array_adt_node->NumEntries -= 1; + Code next = array_entry->Next; + Code prev = array_entry->Prev; + next->Prev = array_entry->Prev; + prev->Next = next; + if ( array_adt_node->Front == array_entry ) + array_adt_node->Front = next; + + header_parsing.append(array_entry); + continue_for = false; + } + break; + } + + } + } + break; + + case CT_Enum: + { + convert_cpp_enum_to_c(cast(CodeEnum, entry), header_parsing); + } + break; + + case CT_Struct: + { + CodeStruct struct_def = cast(CodeStruct, entry); + if ( struct_def->Name.is_equal(txt("ADT_Node") ) ) + { + header_parsing.append(entry); + + // We need to define the array for ADT_Node right here. + header_parsing.append(array_adt_node); + header_parsing.append(fmt_newline); + continue; + } + + StrC type_str = codetype_to_keyword_str(entry->Type); + StrC formated_tmpl = token_fmt_impl( 3, + "type", type_str + , "name", entry->Name, + stringize( + typedef ; + )); + CodeTypedef tdef = parse_typedef(formated_tmpl); + header_parsing.append(entry); + header_parsing.append(tdef); + } + break; + + default: + { + header_parsing.append(entry); + } + break; + } +#pragma endregion Resolve Dependencies + +#pragma region Resolve Components + // Only has operator overload definitions that C doesn't need. + // CodeBody ast_inlines = gen_ast_inlines(); + + Code inlines = scan_file( project_dir "components/inlines.hpp" ); + + CodeBody ecode = gen_ecode ( project_dir "enums/ECodeTypes.csv", helper_use_c_definition ); + CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv", helper_use_c_definition ); + CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv", helper_use_c_definition ); + + CodeBody parsed_types = parse_file( project_dir "components/types.hpp" ); + CodeBody types = def_body(CT_Global_Body); + for ( Code entry = parsed_types.begin(); entry != parsed_types.end(); ++ entry ) switch(entry->Type) + { + case CT_Using: + { + CodeUsing using_ver = cast(CodeUsing, entry); + + if (using_ver->UnderlyingType->ReturnType) + { + CodeTypename type = using_ver->UnderlyingType; + CodeTypedef typedef_ver = parse_typedef(token_fmt( + "ReturnType", to_string(type->ReturnType).to_strc() + , "Name" , using_ver->Name + , "Parameters", to_string(type->Params).to_strc() + , stringize( + typedef ( * )(); + ))); + types.append(typedef_ver); + break; + } + CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); + types.append(typedef_ver); + } + break; + + case CT_Enum: + { + if (entry->Name.is_equal(txt("ETypenameTag"))) + { +#pragma push_macro("enum_underlying") +#undef enum_underlying + entry->UnderlyingTypeMacro = untyped_str(token_fmt("type", entry->UnderlyingType->Name, stringize(enum_underlying()))); + entry->UnderlyingType = CodeTypename{nullptr}; + types.append(entry); +#pragma pop_macro("enum_underlying") + + CodeTypedef entry_td = parse_typedef(code( typedef u16 ETypenameTag; )); + types.append(entry_td); + continue; + } + //log_fmt("Detected ENUM: %S", entry->Name); + convert_cpp_enum_to_c(cast(CodeEnum, entry), types); + } + break; + + default: + types.append(entry); + break; + } + + CodeBody parsed_ast = parse_file( project_dir "components/ast.hpp" ); + CodeBody ast = def_body(CT_Global_Body); + for ( Code entry = parsed_ast.begin(); entry != parsed_ast.end(); ++ entry ) switch (entry->Type) + { + case CT_Preprocess_If: + { + CodePreprocessCond cond = cast(CodePreprocessCond, entry); + if (cond->Content.contains(txt("GEN_COMPILER_C"))) + { + //++ entry; // + //ast.append(entry) // typedef + //for ( ; entry != parsed_ast.end() && entry->Type != CT_Preprocess_EndIf; ++ entry) {} + //++ entry; // Consume endif + } + + b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_ast, ast); + if (found) break; + + ast.append(entry); + } + break; + + case CT_Struct_Fwd: + { + CodeStruct fwd = cast(CodeStruct, entry); + CodeTypedef tdef = parse_typedef(token_fmt("name", fwd->Name, stringize( typedef struct ; ))); + ast.append(fwd); + ast.append(tdef); + } + break; + + case CT_Struct: + { + CodeStruct struct_def = cast(CodeStruct, entry); + ast.append(struct_def); + if ( ! entry->Name.is_equal(txt("AST"))) + { + CodeTypedef tdef = parse_typedef(token_fmt("name", struct_def->Name, stringize( typedef struct ; ))); + ast.append(tdef); + } + } + break; + + case CT_Variable: + { + CodeVar var = cast(CodeVar, entry); + + s32 constexpr_found = var->Specs ? var->Specs.remove( Spec_Constexpr ) : - 1; + if (constexpr_found > -1) { + //log_fmt("Found constexpr: %S\n", entry.to_string()); + if (var->Name.contains(txt("AST_ArrSpecs_Cap"))) + { + Code def = untyped_str(txt( +R"(#define AST_ArrSpecs_Cap \ +( \ + AST_POD_Size \ + - sizeof(Code) \ + - sizeof(StringCached) \ + - sizeof(Code) * 2 \ + - sizeof(Token*) \ + - sizeof(Code) \ + - sizeof(CodeType) \ + - sizeof(ModuleFlag) \ + - sizeof(u32) \ +) \ +/ sizeof(Specifier) - 1 +)" + )); + ast.append(def); + break; + } + CodeDefine def = def_define(var->Name, var->Value.to_string()); + ast.append(def); + break; + } + ast.append(var); + } + break; + + default: + ast.append(entry); + break; + } + + CodeBody parsed_code_types = parse_file( project_dir "components/code_types.hpp" ); + CodeBody code_types = def_body(CT_Global_Body); + for ( Code entry = parsed_code_types.begin(); entry != parsed_code_types.end(); ++ entry ) switch( entry->Type ) + { + case CT_Preprocess_If: + case CT_Preprocess_IfDef: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_code_types, code_types ); + if (found) { + ++ entry; + break; + } + found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); + if (found) break; + + code_types.append(entry); + } + break; + + default: + code_types.append(entry); + break; + } + + CodeBody parsed_ast_types = parse_file( project_dir "components/ast_types.hpp" ); + CodeBody ast_types = def_body(CT_Global_Body); + for ( Code entry = parsed_ast_types.begin(); entry != parsed_ast_types.end(); ++ entry ) switch( entry->Type ) + { + case CT_Preprocess_If: + case CT_Preprocess_IfDef: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); + if (found) break; + + ast_types.append(entry); + } + break; + + case CT_Struct: + { + CodeBody body = cast(CodeBody, entry->Body); + for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch (body_entry->Type) + { + case CT_Union: + { + Code union_entry = body_entry->Body->Front; + if ( body_entry && union_entry->Name.is_equal(txt("_PAD_")) ) + { + char conversion_buf[32] = {}; + u64_to_str(size_of(AST_Body::_PAD_), conversion_buf, 10); + + StrC arr_exp = union_entry->ValueType->ArrExpr->Content; + StrC cpp_size = to_strc_from_c_str(conversion_buf); + union_entry->ValueType->ArrExpr = untyped_str( cpp_size ); + union_entry->InlineCmt = untyped_str(token_fmt("arr_exp", arr_exp, + "// Had to hardcode _PAD_ because () was 67 bytes in C (Injected C++ size_of(AST_::_PAD_) from C++ side)\n" + )); + } + } + } + CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); + ast_types.append(entry); + ast_types.append(tdef); + } + break; + + default: + ast_types.append(entry); + break; + } + + CodeBody parsed_interface = parse_file( project_dir "components/interface.hpp" ); + CodeBody interface = def_body(CT_Global_Body); + for ( Code entry = parsed_interface.begin(); entry != parsed_interface.end(); ++ entry ) switch( entry->Type ) + { + case CT_Preprocess_IfDef: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); + if (found) break; + + interface.append(entry); + } + break; + + case CT_Function_Fwd: + case CT_Function: + { + CodeFn fn = cast(CodeFn, entry); + Code prev = entry->Prev; + if (prev && prev->Name.is_equal(entry->Name)) { + String postfix_arr = String::fmt_buf(GlobalAllocator, "%SC_arr", entry->Name); + entry->Name = get_cached_string(postfix_arr.to_strc()); + postfix_arr.free(); + } + interface.append(fn); + } + break; + + case CT_Struct: + { + CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); + interface.append(entry); + interface.append(tdef); + interface.append(fmt_newline); + } + break; + + default: + interface.append(entry); + break; + } + + s32 idx = 0; + CodeBody parsed_header_end = parse_file( project_dir "components/header_end.hpp" ); + CodeBody header_end = def_body(CT_Global_Body); + for ( Code entry = parsed_header_end.begin(); entry != parsed_header_end.end(); ++ entry, ++ idx ) switch( entry->Type ) + { + case CT_Variable: + { + CodeVar var = cast(CodeVar, entry); + if (var->Specs) + { + s32 constexpr_found = var->Specs.remove( Spec_Constexpr ); + if (constexpr_found > -1) { + CodeDefine define = def_define(entry->Name, entry->Value->Content); + header_end.append(define); + continue; + } + } + header_end.append(entry); + } + break; + + default: + header_end.append(entry); + break; + } +#pragma endregion Resolve Components + +// Source Content : Reflection and Generation + +#pragma region Resolve Dependencies + Code src_impl_start = scan_file( project_dir "dependencies/src_start.cpp" ); + Code src_debug = scan_file( project_dir "dependencies/debug.cpp" ); + Code src_string_ops = scan_file( project_dir "dependencies/string_ops.cpp" ); + Code src_printing = scan_file( project_dir "dependencies/printing.cpp" ); + Code src_memory = scan_file( project_dir "dependencies/memory.cpp" ); + Code src_hashing = scan_file( project_dir "dependencies/hashing.cpp" ); + Code src_strings = scan_file( project_dir "dependencies/strings.cpp" ); + Code src_filesystem = scan_file( project_dir "dependencies/filesystem.cpp" ); + Code src_timing = scan_file( project_dir "dependencies/timing.cpp" ); +#pragma endregion Resolve Dependencies + +#pragma region Resolve Components + CodeBody array_arena = gen_array(txt("Arena"), txt("Array_Arena")); + CodeBody array_pool = gen_array(txt("Pool"), txt("Array_Pool")); + + Code src_static_data = scan_file( project_dir "components/static_data.cpp" ); + Code src_ast_case_macros = scan_file( project_dir "components/ast_case_macros.cpp" ); + Code src_ast = scan_file( project_dir "components/ast.cpp" ); + Code src_code = scan_file( project_dir "components/code_serialization.cpp" ); + Code src_interface = scan_file( project_dir "components/interface.cpp" ); + Code src_upfront = scan_file( project_dir "components/interface.upfront.cpp" ); + Code src_lexer = scan_file( project_dir "components/lexer.cpp" ); + Code src_parser = scan_file( project_dir "components/parser.cpp" ); + Code src_parsing_interface = scan_file( project_dir "components/interface.parsing.cpp" ); + Code src_untyped = scan_file( project_dir "components/interface.untyped.cpp" ); +#pragma endregion Resolve Components + + // THERE SHOULD BE NO NEW GENERIC CONTAINER DEFINTIONS PAST THIS POINT (It will not have slots for the generic selection generated macros) + CodeBody containers = def_body(CT_Global_Body); + { + containers.append( def_pragma(code(region Containers))); + + containers.append( gen_array_base() ); + + containers.append( gen_array_generic_selection_interface()); + containers.append( gen_hashtable_base() ); + containers.append( fmt_newline); + containers.append( gen_hashtable_generic_selection_interface()); + + containers.append( array_ssize); + containers.append( array_u8); + + containers.append( def_pragma(code(endregion Containers))); + containers.append( fmt_newline); + } + +// Printing : Everything below is jsut serialization & formatting ot a single-file. + Builder header = Builder::open( "gen/gen.h" ); header.print_fmt( generation_notice ); header.print_fmt("#pragma once\n\n"); header.print( push_ignores ); - // Headers + header.print( c_library_header_start ); + + // Header files { - header.print( c_library_header_start ); - -#pragma region Scan, Parse, and Generate Components - // Only has operator overload definitions that C doesn't need. - // CodeBody ast_inlines = gen_ast_inlines(); - - Code inlines = scan_file( project_dir "components/inlines.hpp" ); - - CodeBody ecode = gen_ecode ( project_dir "enums/ECodeTypes.csv", helper_use_c_definition ); - CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv", helper_use_c_definition ); - CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv", helper_use_c_definition ); - - // The following pattern will be used throughout parsing: - // for ( Code entry = parsed_.begin(); entry != parsed_.end(); ++ entry ) switch(entry->Type) - // it provides a concise scope for inspecting a file scope ast and nested code bodies (struct bodies, etc) - - CodeBody parsed_types = parse_file( project_dir "components/types.hpp" ); - CodeBody types = def_body(CT_Global_Body); - for ( Code entry = parsed_types.begin(); entry != parsed_types.end(); ++ entry ) switch(entry->Type) - { - case CT_Using: - { - CodeUsing using_ver = cast(CodeUsing, entry); - - if (using_ver->UnderlyingType->ReturnType) - { - CodeTypename type = using_ver->UnderlyingType; - CodeTypedef typedef_ver = parse_typedef(token_fmt( - "ReturnType", to_string(type->ReturnType).to_strc() - , "Name" , using_ver->Name - , "Parameters", to_string(type->Params).to_strc() - , stringize( - typedef ( * )(); - ))); - types.append(typedef_ver); - break; - } - CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); - types.append(typedef_ver); - } - break; - - case CT_Enum: - { - if (entry->Name.is_equal(txt("ETypenameTag"))) - { -#pragma push_macro("enum_underlying") -#undef enum_underlying - entry->UnderlyingTypeMacro = untyped_str(token_fmt("type", entry->UnderlyingType->Name, stringize(enum_underlying()))); - entry->UnderlyingType = CodeTypename{nullptr}; - types.append(entry); -#pragma pop_macro("enum_underlying") - - CodeTypedef entry_td = parse_typedef(code( typedef u16 ETypenameTag; )); - types.append(entry_td); - continue; - } - //log_fmt("Detected ENUM: %S", entry->Name); - convert_cpp_enum_to_c(cast(CodeEnum, entry), types); - } - break; - - default: - types.append(entry); - break; - } - - CodeBody parsed_ast = parse_file( project_dir "components/ast.hpp" ); - CodeBody ast = def_body(CT_Global_Body); - for ( Code entry = parsed_ast.begin(); entry != parsed_ast.end(); ++ entry ) switch (entry->Type) - { - case CT_Preprocess_If: - { - CodePreprocessCond cond = cast(CodePreprocessCond, entry); - if (cond->Content.contains(txt("GEN_COMPILER_C"))) - { - //++ entry; // - //ast.append(entry) // typedef - //for ( ; entry != parsed_ast.end() && entry->Type != CT_Preprocess_EndIf; ++ entry) {} - //++ entry; // Consume endif - } - - b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_ast, ast); - if (found) break; - - ast.append(entry); - } - break; - - case CT_Struct_Fwd: - { - CodeStruct fwd = cast(CodeStruct, entry); - CodeTypedef tdef = parse_typedef(token_fmt("name", fwd->Name, stringize( typedef struct ; ))); - ast.append(fwd); - ast.append(tdef); - } - break; - - case CT_Struct: - { - CodeStruct struct_def = cast(CodeStruct, entry); - ast.append(struct_def); - if ( ! entry->Name.is_equal(txt("AST"))) - { - CodeTypedef tdef = parse_typedef(token_fmt("name", struct_def->Name, stringize( typedef struct ; ))); - ast.append(tdef); - } - } - break; - - case CT_Variable: - { - CodeVar var = cast(CodeVar, entry); - - s32 constexpr_found = var->Specs ? var->Specs.remove( Spec_Constexpr ) : - 1; - if (constexpr_found > -1) { - //log_fmt("Found constexpr: %S\n", entry.to_string()); - if (var->Name.contains(txt("AST_ArrSpecs_Cap"))) - { - Code def = untyped_str(txt( -R"(#define AST_ArrSpecs_Cap \ -( \ - AST_POD_Size \ - - sizeof(Code) \ - - sizeof(StringCached) \ - - sizeof(Code) * 2 \ - - sizeof(Token*) \ - - sizeof(Code) \ - - sizeof(CodeType) \ - - sizeof(ModuleFlag) \ - - sizeof(u32) \ -) \ -/ sizeof(Specifier) - 1 -)" - )); - ast.append(def); - break; - } - CodeDefine def = def_define(var->Name, var->Value.to_string()); - ast.append(def); - break; - } - ast.append(var); - } - break; - - default: - ast.append(entry); - break; - } - - CodeBody parsed_code_types = parse_file( project_dir "components/code_types.hpp" ); - CodeBody code_types = def_body(CT_Global_Body); - for ( Code entry = parsed_code_types.begin(); entry != parsed_code_types.end(); ++ entry ) switch( entry->Type ) - { - case CT_Preprocess_If: - case CT_Preprocess_IfDef: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_code_types, code_types ); - if (found) { - ++ entry; - break; - } - found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); - if (found) break; - - code_types.append(entry); - } - break; - - default: - code_types.append(entry); - break; - } - - CodeBody parsed_ast_types = parse_file( project_dir "components/ast_types.hpp" ); - CodeBody ast_types = def_body(CT_Global_Body); - for ( Code entry = parsed_ast_types.begin(); entry != parsed_ast_types.end(); ++ entry ) switch( entry->Type ) - { - case CT_Preprocess_If: - case CT_Preprocess_IfDef: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); - if (found) break; - - ast_types.append(entry); - } - break; - - case CT_Struct: - { - CodeBody body = cast(CodeBody, entry->Body); - for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch (body_entry->Type) - { - case CT_Union: - { - Code union_entry = body_entry->Body->Front; - if ( body_entry && union_entry->Name.is_equal(txt("_PAD_")) ) - { - char conversion_buf[32] = {}; - u64_to_str(size_of(AST_Body::_PAD_), conversion_buf, 10); - - StrC arr_exp = union_entry->ValueType->ArrExpr->Content; - StrC cpp_size = to_strc_from_c_str(conversion_buf); - union_entry->ValueType->ArrExpr = untyped_str( cpp_size ); - union_entry->InlineCmt = untyped_str(token_fmt("arr_exp", arr_exp, - "// Had to hardcode _PAD_ because () was 67 bytes in C\n" - "// instead of 64 like C++'s AST_Body::_PAD_\n" - )); - } - } - } - CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); - ast_types.append(entry); - ast_types.append(tdef); - } - break; - - default: - ast_types.append(entry); - break; - } - - CodeBody parsed_interface = parse_file( project_dir "components/interface.hpp" ); - CodeBody interface = def_body(CT_Global_Body); - for ( Code entry = parsed_interface.begin(); entry != parsed_interface.end(); ++ entry ) switch( entry->Type ) - { - case CT_Preprocess_IfDef: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_code_types, code_types ); - if (found) break; - - interface.append(entry); - } - break; - - case CT_Function_Fwd: - case CT_Function: - { - CodeFn fn = cast(CodeFn, entry); - Code prev = entry->Prev; - if (prev && prev->Name.is_equal(entry->Name)) { - String postfix_arr = String::fmt_buf(GlobalAllocator, "%SC_arr", entry->Name); - entry->Name = get_cached_string(postfix_arr.to_strc()); - postfix_arr.free(); - } - interface.append(fn); - } - break; - - case CT_Struct: - { - CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); - interface.append(entry); - interface.append(tdef); - interface.append(fmt_newline); - } - break; - - default: - interface.append(entry); - break; - } - - s32 idx = 0; - CodeBody parsed_header_end = parse_file( project_dir "components/header_end.hpp" ); - CodeBody header_end = def_body(CT_Global_Body); - for ( Code entry = parsed_header_end.begin(); entry != parsed_header_end.end(); ++ entry, ++ idx ) switch( entry->Type ) - { - case CT_Variable: - { - CodeVar var = cast(CodeVar, entry); - if (var->Specs) - { - s32 constexpr_found = var->Specs.remove( Spec_Constexpr ); - if (constexpr_found > -1) { - CodeDefine define = def_define(entry->Name, entry->Value->Content); - header_end.append(define); - continue; - } - } - header_end.append(entry); - } - break; - - default: - header_end.append(entry); - break; - } -#pragma endregion Scan, Parse, and Generate Components - -#pragma region Scan, Parse, and Generate Dependencies - Code platform = scan_file( project_dir "dependencies/platform.hpp" ); - Code macros = scan_file( project_dir "dependencies/macros.hpp" ); - Code basic_types = scan_file( project_dir "dependencies/basic_types.hpp" ); - Code debug = scan_file( project_dir "dependencies/debug.hpp" ); - Code string_ops = scan_file( project_dir "dependencies/string_ops.hpp" ); - Code hashing = scan_file( project_dir "dependencies/hashing.hpp" ); - Code timing = scan_file( project_dir "dependencies/timing.hpp" ); - - CodeBody parsed_memory = parse_file( project_dir "dependencies/memory.hpp" ); - CodeBody memory = def_body(CT_Global_Body); - for ( Code entry = parsed_memory.begin(); entry != parsed_memory.end(); ++ entry ) switch (entry->Type) - { - case CT_Using: - { - log_fmt("REPLACE THIS MANUALLY: %SC\n", entry->Name); - CodeUsing using_ver = cast(CodeUsing, entry); - CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); - - memory.append(typedef_ver); - } - break; - case CT_Function_Fwd: - { - CodeFn fn = cast(CodeFn, entry); - // for ( StrC id : to_rename ) if (fn->Name.is_equal(id)) { - // rename_function_to_unique_symbol(fn); - // } - memory.append(fn); - } - break; - case CT_Function: - { - CodeFn fn = cast(CodeFn, entry); - if (fn->Specs) { - s32 constexpr_found = fn->Specs.remove( Spec_Constexpr ); - if (constexpr_found > -1) { - //log_fmt("Found constexpr: %S\n", entry.to_string()); - fn->Specs.append(Spec_Inline); - } - } - memory.append(fn); - } - break; - case CT_Template: - { - CodeTemplate tmpl = cast(CodeTemplate, entry); - if ( tmpl->Declaration->Name.contains(txt("swap"))) - { - CodeBody macro_swap = parse_global_body( txt(R"( -#define swap( a, b ) \ -do \ -{ \ - typeof( a ) temp = ( a ); \ - ( a ) = ( b ); \ - ( b ) = temp; \ -} while ( 0 ) -)" - )); - memory.append(macro_swap); - } - } - break; - case CT_Enum: - { - convert_cpp_enum_to_c(cast(CodeEnum, entry), memory); - } - break; - case CT_Struct_Fwd: - { - CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); - memory.append(entry); - memory.append(tdef); - } - break; - case CT_Class: - case CT_Struct: - { - CodeBody body = cast(CodeBody, entry->Body); - CodeBody new_body = def_body( entry->Body->Type ); - for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch - (body_entry->Type) { - case CT_Preprocess_If: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), body_entry, body, new_body ); - if (found) break; - } - break; - - default: - new_body.append(body_entry); - break; - } - entry->Body = new_body; - - CodeTypedef tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); - memory.append(entry); - memory.append(tdef); - } - break; - case CT_Preprocess_If: - { - b32 found = ignore_preprocess_cond_block(txt("! GEN_C_LIKE_CPP"), entry, parsed_memory, memory ); - if (found) break; - - memory.append(entry); - } - break; - case CT_Preprocess_IfDef: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_memory, memory ); - if (found) break; - - memory.append(entry); - } - break; - case CT_Preprocess_Pragma: - { - CodePragma pragma = cast(CodePragma, entry); - // if (pragma->Content.starts_with(txt("region Memory"))) { - // memory.append(generic_test); - // break; - // } - - b32 found = swap_pragma_region_implementation( txt("FixedArena"), gen_fixed_arenas, entry, memory); - if (found) break; - - memory.append(entry); - } - break; - default: { - memory.append(entry); - } - break; - } - - CodeBody printing_parsed = parse_file( project_dir "dependencies/printing.hpp" ); - CodeBody printing = def_body(CT_Global_Body); - for ( Code entry = printing_parsed.begin(); entry != printing_parsed.end(); ++ entry ) switch (entry->Type) - { - case CT_Preprocess_IfDef: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, printing_parsed, printing ); - if (found) break; - - printing.append(entry); - } - break; - case CT_Variable: - { - if ( strc_contains(entry->Name, txt("Msg_Invalid_Value"))) - { - CodeDefine define = def_define(entry->Name, entry->Value->Content); - printing.append(define); - continue; - } - printing.append(entry); - } - break; - default: - printing.append(entry); - break; - } - - CodeBody parsed_strings = parse_file( project_dir "dependencies/strings.hpp" ); - CodeBody strings = def_body(CT_Global_Body); - for ( Code entry = parsed_strings.begin(); entry != parsed_strings.end(); ++ entry ) switch (entry->Type) - { - case CT_Preprocess_If: - { - CodePreprocessCond cond = cast(CodePreprocessCond, entry); - if (cond->Content.is_equal(txt("GEN_COMPILER_C"))) - { - ++ entry; // Remove #if GEN_COMPILER_C - for ( ; entry->Type != CT_Preprocess_Else - && entry->Type != CT_Preprocess_EndIf; ++ entry ) { - strings.append(entry); // Preserve content - } - for ( ; entry->Type != CT_Preprocess_EndIf; ++ entry ) {} // Discard C++ - // #endif discarded by for loop - break; - } - - bool found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_strings, strings); - if (found) break; - - found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_strings, strings); - if (found) break; - } - break; - - case CT_Preprocess_IfDef: - { - ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_strings, strings ); - } - break; - - case CT_Preprocess_IfNotDef: - { - //log_fmt("\nIFNDEF: %SC\n", entry->Content); - strings.append(entry); - } - break; - - case CT_Struct_Fwd: - { - if ( entry->Name.is_equal(txt("String")) ) - { - CodeTypedef c_def = parse_typedef(code( typedef char* String; )); - strings.append(c_def); - strings.append(fmt_newline); - ++ entry; - continue; - } - else - { - CodeTypedef c_def = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct ; ))); - strings.append(c_def); - } - strings.append(entry); - } - break; - - case CT_Struct: - { - CodeBody body = cast(CodeBody, entry->Body); - CodeBody new_body = def_body( entry->Body->Type ); - for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch - (body_entry->Type) { - case CT_Preprocess_If: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), body_entry, body, new_body ); - if (found) break; - - new_body.append(body_entry); - } - break; - default: - new_body.append(body_entry); - break; - } - entry->Body = new_body; - strings.append(entry); - } - break; - - case CT_Typedef: - { - StrC name_string_table = txt("StringTable"); - - CodeTypedef td = cast(CodeTypedef, entry); - if (td->Name.contains(name_string_table)) - { - CodeBody ht = gen_hashtable(txt("StrC"), name_string_table); - strings.append(ht); - break; - } - strings.append(td); - } - break; - - default: - strings.append(entry); - break; - } - - CodeBody parsed_filesystem = parse_file( project_dir "dependencies/filesystem.hpp" ); - CodeBody filesystem = def_body(CT_Global_Body); - for ( Code entry = parsed_filesystem.begin(); entry != parsed_filesystem.end(); ++ entry ) switch (entry->Type) - { - case CT_Preprocess_IfDef: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_filesystem, filesystem ); - if (found) break; - - filesystem.append(entry); - } - break; - - case CT_Enum: - { - if (entry->Name.is_equal(txt("FileOperations"))) - continue; - convert_cpp_enum_to_c(cast(CodeEnum, entry), filesystem); - } - break; - - case CT_Enum_Fwd: - case CT_Struct_Fwd: - case CT_Struct: - case CT_Union: - case CT_Union_Fwd: - { - StrC type_str = codetype_to_keyword_str(entry->Type); - StrC formated_tmpl = token_fmt_impl( 3, - "type", type_str - , "name", entry->Name, - stringize( - typedef ; - )); - CodeTypedef tdef = parse_typedef(formated_tmpl); - filesystem.append(entry); - filesystem.append(tdef); - } - break; - - case CT_Variable: - { - CodeVar var = cast(CodeVar, entry); - if (var->Specs.has(Spec_Constexpr) > -1) - { - CodeDefine define = def_define(entry->Name, entry->Value->Content); - filesystem.append(define); - continue; - } - //if ( strc_contains(entry->Name, txt("Msg_Invalid_Value"))) - //{ - // CodeDefine define = def_define(entry->Name, entry->Value->Content); - // printing.append(define); - // continue; - //} - filesystem.append(entry); - } - break; - default: - filesystem.append(entry); - break; - } - - CodeBody array_adt_node = gen_array(txt("ADT_Node"), txt("Array_ADT_Node")); - - CodeBody parsed_parsing = parse_file( project_dir "dependencies/parsing.hpp" ); - CodeBody parsing = def_body(CT_Global_Body); - for ( Code entry = parsed_parsing.begin(); entry != parsed_parsing.end(); ++ entry ) switch (entry->Type) - { - case CT_Preprocess_Pragma: - { - if ( entry->Content.contains(txt("ADT")) ) - { - parsing.append(entry); - parsing.append(fmt_newline); - - // Add ADT_Node forward and typedef early. - CodeStruct adt_node_fwd = parse_struct(code( struct ADT_Node; )); - CodeTypedef adt_node_typedef = parse_typedef(code( typedef struct ADT_Node ADT_Node; )); - parsing.append(adt_node_fwd); - parsing.append(adt_node_typedef); - - // Skip typedef since we added it - b32 continue_for = true; - for (Code array_entry = array_adt_node.begin(); continue_for && array_entry != array_adt_node.end(); ++ array_entry) switch (array_entry->Type) - { - case CT_Typedef: - { - // pop the array entry - array_adt_node->NumEntries -= 1; - Code next = array_entry->Next; - Code prev = array_entry->Prev; - next->Prev = array_entry->Prev; - prev->Next = next; - if ( array_adt_node->Front == array_entry ) - array_adt_node->Front = next; - - parsing.append(array_entry); - continue_for = false; - } - break; - } - - } - } - break; - - case CT_Enum: - { - convert_cpp_enum_to_c(cast(CodeEnum, entry), parsing); - } - break; - - case CT_Struct: - { - CodeStruct struct_def = cast(CodeStruct, entry); - if ( struct_def->Name.is_equal(txt("ADT_Node") ) ) - { - parsing.append(entry); - - // We need to define the array for ADT_Node right here. - parsing.append(array_adt_node); - parsing.append(fmt_newline); - continue; - } - - StrC type_str = codetype_to_keyword_str(entry->Type); - StrC formated_tmpl = token_fmt_impl( 3, - "type", type_str - , "name", entry->Name, - stringize( - typedef ; - )); - CodeTypedef tdef = parse_typedef(formated_tmpl); - parsing.append(entry); - parsing.append(tdef); - } - break; - - default: - { - parsing.append(entry); - } - break; - } - - CodeBody array_string_cached = gen_array(txt("StringCached"), txt("Array_StringCached")); - - CodeBody containers = def_body(CT_Global_Body); - { - CodeBody array_ssize = gen_array(txt("ssize"), txt("Array_ssize")); - CodeBody array_u8 = gen_array(txt("u8"), txt("Array_u8")); - - containers.append( def_pragma(code(region Containers))); - - // At this point all arrays required should have been defined so its safe to generate the generic selectors. - containers.append( gen_array_base() ); - containers.append( gen_array_generic_selection_interface()); - containers.append( gen_hashtable_base() ); - containers.append(fmt_newline); - containers.append( gen_hashtable_generic_selection_interface()); - - containers.append(array_ssize); - containers.append(array_u8); - - containers.append( def_pragma(code(endregion Containers))); - containers.append(fmt_newline); - } -#pragma endregion Scan, Parse, and Generate Dependencies - -#pragma region Print Dependencies + #pragma region Print Dependencies header.print_fmt( roll_own_dependencies_guard_start ); - header.print( platform ); + header.print( header_platform ); header.print_fmt( "\nGEN_NS_BEGIN\n" ); - header.print( macros ); - header.print( basic_types ); - header.print( debug ); - header.print( dump_to_scratch_and_retireve(memory) ); - header.print( dump_to_scratch_and_retireve(printing)); - header.print( string_ops ); - header.print(fmt_newline); - header.print( dump_to_scratch_and_retireve(containers)); - header.print( hashing ); - header.print( dump_to_scratch_and_retireve(strings)); - header.print( dump_to_scratch_and_retireve(filesystem)); - header.print( timing ); - - // CodeStruct fwd = parse_struct(txt("struct ADT_Node;")); + header.print( header_macros ); + header.print( header_basic_types ); + header.print( header_debug ); + header.print( format_code_to_untyped(header_memory) ); + header.print( format_code_to_untyped(header_printing)); + header.print( header_string_ops ); + header.print( fmt_newline); + header.print( format_code_to_untyped(containers)); + header.print( header_hashing ); + header.print( format_code_to_untyped(header_strings)); + header.print( format_code_to_untyped(header_filesystem)); + header.print( header_timing ); header.print_fmt( "\n#pragma region Parsing\n" ); - - // header.print( fwd ); - // header.print( adt_node_typedef ); - // header.print( fmt_newline ); - // header.print(dump_to_scratch_and_retireve(array_adt_node)); - - header.print( dump_to_scratch_and_retireve(parsing) ); + header.print( format_code_to_untyped(header_parsing) ); header.print_fmt( "#pragma endregion Parsing\n\n" ); header.print_fmt( "\nGEN_NS_END\n" ); header.print_fmt( roll_own_dependencies_guard_end ); -#pragma endregion Print Dependencies + #pragma endregion Print Dependencies header.print(fmt_newline); -#pragma region region Print Components + #pragma region region Print Components header.print_fmt( "GEN_NS_BEGIN\n" ); header.print_fmt( "GEN_API_C_BEGIN\n\n" ); header.print_fmt("#pragma region Types\n"); - header.print( dump_to_scratch_and_retireve(types) ); + header.print( format_code_to_untyped(types) ); header.print( fmt_newline ); - header.print( dump_to_scratch_and_retireve( ecode )); + header.print( format_code_to_untyped( ecode )); header.print( fmt_newline ); - header.print( dump_to_scratch_and_retireve( eoperator )); + header.print( format_code_to_untyped( eoperator )); header.print( fmt_newline ); - header.print( dump_to_scratch_and_retireve( especifier )); + header.print( format_code_to_untyped( especifier )); header.print_fmt("#pragma endregion Types\n\n"); header.print_fmt("#pragma region AST\n"); - header.print( dump_to_scratch_and_retireve(ast) ); - header.print( dump_to_scratch_and_retireve(code_types) ); - header.print( dump_to_scratch_and_retireve(ast_types) ); + header.print( format_code_to_untyped(ast) ); + header.print( format_code_to_untyped(code_types) ); + header.print( format_code_to_untyped(ast_types) ); header.print_fmt("\n#pragma endregion AST\n"); - header.print( dump_to_scratch_and_retireve(interface) ); + header.print( format_code_to_untyped(interface) ); header.print_fmt("#pragma region Inlines\n"); header.print( inlines ); header.print_fmt("#pragma endregion Inlines\n"); header.print(fmt_newline); - header.print( dump_to_scratch_and_retireve(array_string_cached)); + header.print( format_code_to_untyped(array_string_cached)); header.print(fmt_newline); - header.print( dump_to_scratch_and_retireve(header_end) ); + header.print( format_code_to_untyped(header_end) ); header.print_fmt( "\nGEN_API_C_END\n" ); header.print_fmt( "GEN_NS_END\n\n" ); -#pragma endregion Print Compoennts + #pragma endregion Print Compoennts } - // Implementation + // Source files { header.print_fmt( implementation_guard_start ); -#pragma region Scan, Parse, and Generate Dependencies - Code impl_start = scan_file( project_dir "dependencies/src_start.cpp" ); - Code debug = scan_file( project_dir "dependencies/debug.cpp" ); - Code string_ops = scan_file( project_dir "dependencies/string_ops.cpp" ); - Code printing = scan_file( project_dir "dependencies/printing.cpp" ); - Code memory = scan_file( project_dir "dependencies/memory.cpp" ); - Code hashing = scan_file( project_dir "dependencies/hashing.cpp" ); - Code strings = scan_file( project_dir "dependencies/strings.cpp" ); - Code filesystem = scan_file( project_dir "dependencies/filesystem.cpp" ); - Code timing = scan_file( project_dir "dependencies/timing.cpp" ); -#pragma endregion Scan, Parse, and Generate Dependencies - -#pragma region Scan, Parse, and Generate Components - Code static_data = scan_file( project_dir "components/static_data.cpp" ); - Code ast_case_macros = scan_file( project_dir "components/ast_case_macros.cpp" ); - Code ast = scan_file( project_dir "components/ast.cpp" ); - Code code = scan_file( project_dir "components/code_serialization.cpp" ); - Code interface = scan_file( project_dir "components/interface.cpp" ); - Code upfront = scan_file( project_dir "components/interface.upfront.cpp" ); - Code lexer = scan_file( project_dir "components/lexer.cpp" ); - Code parser = scan_file( project_dir "components/parser.cpp" ); - Code parsing_interface = scan_file( project_dir "components/interface.parsing.cpp" ); - Code untyped = scan_file( project_dir "components/interface.untyped.cpp" ); -#pragma endregion Scan, Parse, and Generate Components - -#pragma region Print Dependencies + #pragma region Print Dependencies header.print_fmt( roll_own_dependencies_guard_start ); header.print_fmt( "GEN_NS_BEGIN\n\n"); - header.print( impl_start ); - header.print( debug ); - header.print( string_ops ); - header.print( printing ); - header.print( memory ); - header.print( hashing ); - header.print( strings ); - header.print( filesystem ); - header.print( timing ); + header.print( src_impl_start ); + header.print( src_debug ); + header.print( src_string_ops ); + header.print( src_printing ); + header.print( src_memory ); + header.print( src_hashing ); + header.print( src_strings ); + header.print( src_filesystem ); + header.print( src_timing ); header.print_fmt( "\n#pragma region Parsing\n" ); header.print( scan_file( project_dir "dependencies/parsing.cpp" ) ); @@ -978,47 +969,49 @@ do \ header.print_fmt( "GEN_NS_END\n"); header.print_fmt( roll_own_dependencies_guard_end ); + #pragma endregion Print Dependencies -#pragma endregion Print Dependencies - -#pragma region Print Components -#if 0 + #pragma region Print Components CodeBody etoktype = gen_etoktype( project_dir "enums/ETokType.csv", project_dir "enums/AttributeTokens.csv" ); header.print_fmt( "\nGEN_NS_BEGIN\n"); - header.print( static_data ); + + header.print( format_code_to_untyped(array_arena)); + header.print( fmt_newline); + header.print( format_code_to_untyped(array_pool)); + + header.print( src_static_data ); + header.print( fmt_newline); header.print_fmt( "#pragma region AST\n\n" ); - header.print( ast_case_macros ); - header.print( ast ); - header.print( code ); + header.print( src_ast_case_macros ); + header.print( src_ast ); + // header.print( src_code ); header.print_fmt( "#pragma endregion AST\n\n" ); - header.print_fmt( "#pragma region Interface\n" ); - header.print( interface ); - header.print( upfront ); - header.print_fmt( "\n#pragma region Parsing\n\n" ); - header.print( dump_to_scratch_and_retireve(parser_nspace) ); - header.print( lexer ); - header.print( parser ); - header.print( parsing_interface ); - header.print_fmt( "\n#pragma endregion Parsing\n" ); - header.print( untyped ); - header.print_fmt( "\n#pragma endregion Interface\n\n"); + // header.print_fmt( "#pragma region Interface\n" ); + // header.print( src_interface ); + // header.print( src_upfront ); + // header.print_fmt( "\n#pragma region Parsing\n\n" ); + // header.print( format_code_to_untyped(parser_nspace) ); + // header.print( lexer ); + // header.print( parser ); + // header.print( parsing_interface ); + // header.print_fmt( "\n#pragma endregion Parsing\n" ); + // header.print( untyped ); + // header.print_fmt( "\n#pragma endregion Interface\n\n"); - header.print_fmt( "#pragma region Builder\n" ); - header.print( scan_file( project_dir "auxillary/builder.cpp" ) ); - header.print_fmt( "\n#pragma endregion Builder\n\n" ); + // header.print_fmt( "#pragma region Builder\n" ); + // header.print( scan_file( project_dir "auxillary/builder.cpp" ) ); + // header.print_fmt( "\n#pragma endregion Builder\n\n" ); - header.print_fmt( "\n#pragma region Scanner\n" ); - header.print( scan_file( project_dir "auxillary/scanner.hpp" ) ); - header.print_fmt( "#pragma endregion Scanner\n\n" ); -#endif -#pragma endregion Print Components + // header.print_fmt( "\n#pragma region Scanner\n" ); + // header.print( scan_file( project_dir "auxillary/scanner.hpp" ) ); + // header.print_fmt( "#pragma endregion Scanner\n\n" ); + #pragma endregion Print Components header.print_fmt( implementation_guard_end ); } - header.print( pop_ignores ); header.write(); diff --git a/gen_c_library/components/containers.hashtable.hpp b/gen_c_library/components/containers.hashtable.hpp index b0d6b37..7401997 100644 --- a/gen_c_library/components/containers.hashtable.hpp +++ b/gen_c_library/components/containers.hashtable.hpp @@ -373,7 +373,7 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name ) #pragma pop_macro( "forceinline" ) ++ HashTable_DefinitionCounter; - StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", Array_DefinitionCounter).to_strc(); + StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", HashTable_DefinitionCounter).to_strc(); Code generic_interface_slot = untyped_str(token_fmt( "type", type, "tbl_type", (StrC)tbl_type, "slot", (StrC)slot_str, R"(#define GENERIC_SLOT___hashtable_init , _init diff --git a/gencpp.10x b/gencpp.10x index a73542d..a7d9e17 100644 --- a/gencpp.10x +++ b/gencpp.10x @@ -48,6 +48,7 @@ GEN_EXECUTION_EXPRESSION_SUPPORT GEN_BENCHMARK GEN_COMPILER_MSVC + GEN_IMPLEMENTATION diff --git a/project/components/ast.cpp b/project/components/ast.cpp index 1e93c7e..d6d4ece 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -7,20 +7,20 @@ global Code Code_Global; global Code Code_Invalid; // This serializes all the data-members in a "debug" format, where each member is printed with its associated value. -char const* code_debug_str(Code self) +StrC code_debug_str(Code self) { GEN_ASSERT(self != nullptr); String result_stack = string_make_reserve( GlobalAllocator, kilobytes(1) ); String* result = & result_stack; if ( self->Parent ) - string_append_fmt( result, "\n\tParent : %S %S", code_type_str(self->Parent), self->Name ? self->Name : "" ); + string_append_fmt( result, "\n\tParent : %SC %SC", code_type_str(self->Parent), self->Name.Len ? self->Name : txt("Null") ); else - string_append_fmt( result, "\n\tParent : %S", "Null" ); + string_append_fmt( result, "\n\tParent : %SC", txt("Null") ); - string_append_fmt( result, "\n\tName : %S", self->Name ? self->Name : "Null" ); - string_append_fmt( result, "\n\tType : %S", code_type_str(self) ); - string_append_fmt( result, "\n\tModule Flags : %S", module_flag_to_str( self->ModuleFlags ) ); + string_append_fmt( result, "\n\tName : %SC", self->Name.Len ? self->Name : txt("Null") ); + string_append_fmt( result, "\n\tType : %SC", code_type_str(self) ); + string_append_fmt( result, "\n\tModule Flags : %SC", module_flag_to_str( self->ModuleFlags ) ); switch ( self->Type ) { @@ -30,9 +30,9 @@ char const* code_debug_str(Code self) case CT_Access_Protected: case CT_Access_Public: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); break; case CT_Untyped: @@ -48,74 +48,74 @@ char const* code_debug_str(Code self) case CT_Preprocess_IfDef: case CT_Preprocess_IfNotDef: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tContent: %S", self->Content ); + string_append_fmt( result, "\n\tContent: %SC", self->Content ); break; case CT_Class: case CT_Struct: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? access_spec_to_str( self->ParentAccess ) : "No Parent" ); - string_append_fmt( result, "\n\tParentType : %s", self->ParentType ? code_type_str(self->ParentType) : "Null" ); - string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes : %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tParentAccess: %SC", self->ParentType ? access_spec_to_str( self->ParentAccess ) : txt("No Parent") ); + string_append_fmt( result, "\n\tParentType : %SC", self->ParentType ? code_type_str(self->ParentType) : txt("Null") ); + string_append_fmt( result, "\n\tBody : %SC", self->Body ? code_debug_str(self->Body) : txt("Null") ); break; case CT_Class_Fwd: case CT_Struct_Fwd: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? access_spec_to_str( self->ParentAccess ) : "No Parent" ); - string_append_fmt( result, "\n\tParentType : %s", self->ParentType ? code_type_str(self->ParentType) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes : %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tParentAccess: %SC", self->ParentType ? access_spec_to_str( self->ParentAccess ) : txt("No Parent") ); + string_append_fmt( result, "\n\tParentType : %SC", self->ParentType ? code_type_str(self->ParentType) : txt("Null") ); break; case CT_Constructor: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? code_to_string(self->InitializerList) : "Null" ); - string_append_fmt( result, "\n\tParams : %S", self->Params ? code_to_string(self->Params) : "Null" ); - string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs) ) : txt("Null") ); + string_append_fmt( result, "\n\tInitializerList: %SC", self->InitializerList ? string_to_strc( code_to_string(self->InitializerList) ) : txt("Null") ); + string_append_fmt( result, "\n\tParams : %SC", self->Params ? string_to_strc( code_to_string(self->Params) ) : txt("Null") ); + string_append_fmt( result, "\n\tBody : %SC", self->Body ? code_debug_str(self->Body) : txt("Null") ); break; case CT_Constructor_Fwd: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? code_to_string(self->InitializerList) : "Null" ); - string_append_fmt( result, "\n\tParams : %S", self->Params ? code_to_string(self->Params) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs) ) : txt("Null") ); + string_append_fmt( result, "\n\tInitializerList: %SC", self->InitializerList ? string_to_strc( code_to_string(self->InitializerList) ) : txt("Null") ); + string_append_fmt( result, "\n\tParams : %SC", self->Params ? string_to_strc( code_to_string(self->Params) ) : txt("Null") ); break; case CT_Destructor: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs) ) : txt("Null") ); + string_append_fmt( result, "\n\tBody : %SC", self->Body ? code_debug_str(self->Body) : txt("Null") ); break; case CT_Destructor_Fwd: @@ -124,142 +124,142 @@ char const* code_debug_str(Code self) case CT_Enum: case CT_Enum_Class: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? code_to_string(self->UnderlyingType) : "Null" ); - string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes : %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tUnderlying Type : %SC", self->UnderlyingType ? string_to_strc( code_to_string(self->UnderlyingType)) : txt("Null") ); + string_append_fmt( result, "\n\tBody : %SC", self->Body ? code_debug_str(self->Body) : txt("Null") ); break; case CT_Enum_Fwd: case CT_Enum_Class_Fwd: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? code_to_string(self->UnderlyingType) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes : %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tUnderlying Type : %SC", self->UnderlyingType ? string_to_strc( code_to_string(self->UnderlyingType)) : txt("Null") ); break; case CT_Extern_Linkage: case CT_Namespace: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tBody: %S", self->Body ? code_debug_str(self->Body) : "Null" ); + string_append_fmt( result, "\n\tBody: %SC", self->Body ? code_debug_str(self->Body) : txt("Null") ); break; case CT_Friend: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? code_to_string(self->Declaration) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tDeclaration: %SC", self->Declaration ? string_to_strc( code_to_string(self->Declaration)) : txt("Null") ); break; case CT_Function: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? code_to_string(self->ReturnType) : "Null" ); - string_append_fmt( result, "\n\tParams : %S", self->Params ? code_to_string(self->Params) : "Null" ); - string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes: %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs)) : txt("Null") ); + string_append_fmt( result, "\n\tReturnType: %SC", self->ReturnType ? string_to_strc( code_to_string(self->ReturnType)) : txt("Null") ); + string_append_fmt( result, "\n\tParams : %SC", self->Params ? string_to_strc( code_to_string(self->Params)) : txt("Null") ); + string_append_fmt( result, "\n\tBody : %SC", self->Body ? code_debug_str(self->Body) : txt("Null") ); break; case CT_Function_Fwd: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? code_to_string(self->ReturnType) : "Null" ); - string_append_fmt( result, "\n\tParams : %S", self->Params ? code_to_string(self->Params) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes: %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs)) : txt("Null") ); + string_append_fmt( result, "\n\tReturnType: %SC", self->ReturnType ? string_to_strc( code_to_string(self->ReturnType)) : txt("Null") ); + string_append_fmt( result, "\n\tParams : %SC", self->Params ? string_to_strc( code_to_string(self->Params)) : txt("Null") ); break; case CT_Module: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); break; case CT_Operator: case CT_Operator_Member: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? code_to_string(self->ReturnType) : "Null" ); - string_append_fmt( result, "\n\tParams : %S", self->Params ? code_to_string(self->Params) : "Null" ); - string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" ); - string_append_fmt( result, "\n\tOp : %S", operator_to_str( self->Op ) ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes: %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs)) : txt("Null") ); + string_append_fmt( result, "\n\tReturnType: %SC", self->ReturnType ? string_to_strc( code_to_string(self->ReturnType)) : txt("Null") ); + string_append_fmt( result, "\n\tParams : %SC", self->Params ? string_to_strc( code_to_string(self->Params)) : txt("Null") ); + string_append_fmt( result, "\n\tBody : %SC", self->Body ? code_debug_str(self->Body) : txt("Null") ); + string_append_fmt( result, "\n\tOp : %SC", operator_to_str( self->Op ) ); break; case CT_Operator_Fwd: case CT_Operator_Member_Fwd: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? code_to_string(self->ReturnType) : "Null" ); - string_append_fmt( result, "\n\tParams : %S", self->Params ? code_to_string(self->Params) : "Null" ); - string_append_fmt( result, "\n\tOp : %S", operator_to_str( self->Op ) ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes: %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs) ) : txt("Null") ); + string_append_fmt( result, "\n\tReturnType: %SC", self->ReturnType ? string_to_strc( code_to_string(self->ReturnType) ) : txt("Null") ); + string_append_fmt( result, "\n\tParams : %SC", self->Params ? string_to_strc( code_to_string(self->Params) ) : txt("Null") ); + string_append_fmt( result, "\n\tOp : %SC", operator_to_str( self->Op ) ); break; case CT_Operator_Cast: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tValueType : %S", self->ValueType ? code_to_string(self->ValueType) : "Null" ); - string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs)) : txt("Null") ); + string_append_fmt( result, "\n\tValueType : %SC", self->ValueType ? string_to_strc( code_to_string(self->ValueType)) : txt("Null") ); + string_append_fmt( result, "\n\tBody : %SC", self->Body ? code_debug_str(self->Body) : txt("Null") ); break; case CT_Operator_Cast_Fwd: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tValueType : %S", self->ValueType ? code_to_string(self->ValueType) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs)) : txt("Null") ); + string_append_fmt( result, "\n\tValueType : %SC", self->ValueType ? string_to_strc( code_to_string(self->ValueType)) : txt("Null") ); break; case CT_Parameters: string_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries ); - string_append_fmt( result, "\n\tLast : %S", self->Last->Name ); - string_append_fmt( result, "\n\tNext : %S", self->Next->Name ); - string_append_fmt( result, "\n\tValueType : %S", self->ValueType ? code_to_string(self->ValueType) : "Null" ); - string_append_fmt( result, "\n\tValue : %S", self->Value ? code_to_string(self->Value) : "Null" ); + string_append_fmt( result, "\n\tLast : %SC", self->Last->Name ); + string_append_fmt( result, "\n\tNext : %SC", self->Next->Name ); + string_append_fmt( result, "\n\tValueType : %SC", self->ValueType ? string_to_strc( code_to_string(self->ValueType)) : txt("Null") ); + string_append_fmt( result, "\n\tValue : %SC", self->Value ? string_to_strc( code_to_string(self->Value)) : txt("Null") ); break; case CT_Specifiers: @@ -275,57 +275,57 @@ char const* code_debug_str(Code self) string_append_fmt( result, "%.*s, ", spec.Len, spec.Ptr ); idx++; } - string_append_fmt( result, "\n\tNextSpecs: %S", self->NextSpecs ? code_debug_str(self->NextSpecs) : "Null" ); + string_append_fmt( result, "\n\tNextSpecs: %SC", self->NextSpecs ? code_debug_str(self->NextSpecs) : txt("Null") ); } break; case CT_Template: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tParams : %S", self->Params ? code_to_string(self->Params) : "Null" ); - string_append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? code_to_string(self->Declaration) : "Null" ); + string_append_fmt( result, "\n\tParams : %SC", self->Params ? string_to_strc( code_to_string(self->Params)) : txt("Null") ); + string_append_fmt( result, "\n\tDeclaration: %SC", self->Declaration ? string_to_strc( code_to_string(self->Declaration)) : txt("Null") ); break; case CT_Typedef: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? code_to_string(self->UnderlyingType) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tUnderlyingType: %SC", self->UnderlyingType ? string_to_strc( code_to_string(self->UnderlyingType)) : txt("Null") ); break; case CT_Typename: - string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tReturnType : %S", self->ReturnType ? code_to_string(self->ReturnType) : "Null" ); - string_append_fmt( result, "\n\tParams : %S", self->Params ? code_to_string(self->Params) : "Null" ); - string_append_fmt( result, "\n\tArrExpr : %S", self->ArrExpr ? code_to_string(self->ArrExpr) : "Null" ); + string_append_fmt( result, "\n\tAttributes : %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs)) : txt("Null") ); + string_append_fmt( result, "\n\tReturnType : %SC", self->ReturnType ? string_to_strc( code_to_string(self->ReturnType)) : txt("Null") ); + string_append_fmt( result, "\n\tParams : %SC", self->Params ? string_to_strc( code_to_string(self->Params)) : txt("Null") ); + string_append_fmt( result, "\n\tArrExpr : %SC", self->ArrExpr ? string_to_strc( code_to_string(self->ArrExpr)) : txt("Null") ); break; case CT_Union: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tBody : %S", self->Body ? code_debug_str(self->Body) : "Null" ); + string_append_fmt( result, "\n\tAttributes: %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tBody : %SC", self->Body ? code_debug_str(self->Body) : txt("Null") ); break; case CT_Using: if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? code_to_string(self->UnderlyingType) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes : %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tUnderlyingType: %SC", self->UnderlyingType ? string_to_strc( code_to_string(self->UnderlyingType)) : txt("Null") ); break; case CT_Variable: @@ -333,29 +333,29 @@ char const* code_debug_str(Code self) if ( self->Parent && self->Parent->Type == CT_Variable ) { // Its a NextVar - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tValue : %S", self->Value ? code_to_string(self->Value) : "Null" ); - string_append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? code_to_string(self->BitfieldSize) : "Null" ); - string_append_fmt( result, "\n\tNextVar : %S", self->NextVar ? code_debug_str(self->NextVar) : "Null" ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs)) : txt("Null") ); + string_append_fmt( result, "\n\tValue : %SC", self->Value ? string_to_strc( code_to_string(self->Value)) : txt("Null") ); + string_append_fmt( result, "\n\tBitfieldSize: %SC", self->BitfieldSize ? string_to_strc( code_to_string(self->BitfieldSize)) : txt("Null") ); + string_append_fmt( result, "\n\tNextVar : %SC", self->NextVar ? code_debug_str(self->NextVar) : txt("Null") ); break; } if ( self->Prev ) - string_append_fmt( result, "\n\tPrev: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tPrev: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); if ( self->Next ) - string_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + string_append_fmt( result, "\n\tNext: %SC %SC", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); - string_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); - string_append_fmt( result, "\n\tAttributes : %S", self->Attributes ? code_to_string(self->Attributes) : "Null" ); - string_append_fmt( result, "\n\tSpecs : %S", self->Specs ? code_to_string(self->Specs) : "Null" ); - string_append_fmt( result, "\n\tValueType : %S", self->ValueType ? code_to_string(self->ValueType) : "Null" ); - string_append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? code_to_string(self->BitfieldSize) : "Null" ); - string_append_fmt( result, "\n\tValue : %S", self->Value ? code_to_string(self->Value) : "Null" ); - string_append_fmt( result, "\n\tNextVar : %S", self->NextVar ? code_debug_str(self->NextVar) : "Null" ); + string_append_fmt( result, "\n\tInlineCmt : %SC", self->InlineCmt ? self->InlineCmt->Content : txt("Null") ); + string_append_fmt( result, "\n\tAttributes : %SC", self->Attributes ? string_to_strc( code_to_string(self->Attributes) ) : txt("Null") ); + string_append_fmt( result, "\n\tSpecs : %SC", self->Specs ? string_to_strc( code_to_string(self->Specs)) : txt("Null") ); + string_append_fmt( result, "\n\tValueType : %SC", self->ValueType ? string_to_strc( code_to_string(self->ValueType)) : txt("Null") ); + string_append_fmt( result, "\n\tBitfieldSize: %SC", self->BitfieldSize ? string_to_strc( code_to_string(self->BitfieldSize)) : txt("Null") ); + string_append_fmt( result, "\n\tValue : %SC", self->Value ? string_to_strc( code_to_string(self->Value)) : txt("Null") ); + string_append_fmt( result, "\n\tNextVar : %SC", self->NextVar ? code_debug_str(self->NextVar) : txt("Null") ); break; } - return * result; + return string_to_strc( * result ); } Code code_duplicate(Code self) @@ -366,7 +366,7 @@ Code code_duplicate(Code self) void* mem_self = rcast(void*, cast(AST*, self)); mem_copy( mem_result, mem_self, sizeof( AST ) ); - result->Parent = { nullptr }; + result->Parent = NullCode; return result; } @@ -387,7 +387,7 @@ void code_to_string_ptr( Code self, String* result ) { case CT_Invalid: #ifdef GEN_DONT_ALLOW_INVALID_CODE - log_failure("Attempted to serialize invalid code! - %S", Parent ? Parent->code_debug_str() : Name ); + log_failure("Attempted to serialize invalid code! - %SC", Parent ? Parent->code_debug_str() : Name ); #else string_append_fmt( result, "Invalid Code!" ); #endif @@ -604,13 +604,13 @@ bool code_is_equal( Code self, Code other ) */ if ( other == nullptr ) { - log_fmt( "AST::is_equal: other is null\nAST: %S", code_debug_str(self) ); + log_fmt( "AST::is_equal: other is null\nAST: %SC", code_debug_str(self) ); return false; } if ( self->Type != other->Type ) { - log_fmt("AST::is_equal: Type check failure with other\nAST: %S\nOther: %S" + log_fmt("AST::is_equal: Type check failure with other\nAST: %SC\nOther: %SC" , code_debug_str(self) ,code_debug_str(other) ); @@ -624,8 +624,8 @@ bool code_is_equal( Code self, Code other ) if ( self->val != other->val ) \ { \ log_fmt("\nAST::is_equal: Member - " #val " failed\n" \ - "AST : %S\n" \ - "Other: %S\n" \ + "AST : %SC\n" \ + "Other: %SC\n" \ , code_debug_str(self) \ ,code_debug_str(other) \ ); \ @@ -634,11 +634,11 @@ bool code_is_equal( Code self, Code other ) } #define check_member_str( str ) \ - if ( self->str != other->str ) \ + if ( ! strc_are_equal( self->str, other->str ) ) \ { \ log_fmt("\nAST::is_equal: Member string - "#str " failed\n" \ - "AST : %S\n" \ - "Other: %S\n" \ + "AST : %SC\n" \ + "Other: %SC\n" \ , code_debug_str(self) \ ,code_debug_str(other) \ ); \ @@ -647,19 +647,19 @@ bool code_is_equal( Code self, Code other ) } #define check_member_content( content ) \ - if ( self->content != other->content ) \ + if ( ! strc_are_equal( self->content, other->content )) \ { \ log_fmt("\nAST::is_equal: Member content - "#content " failed\n" \ - "AST : %S\n" \ - "Other: %S\n" \ + "AST : %SC\n" \ + "Other: %SC\n" \ , code_debug_str(self) \ , code_debug_str(other) \ ); \ \ log_fmt("Content cannot be trusted to be unique with this check " \ "so it must be verified by eye for now\n" \ - "AST Content:\n%S\n" \ - "Other Content:\n%S\n" \ + "AST Content:\n%SC\n" \ + "Other Content:\n%SC\n" \ , strc_visualize_whitespace(self->content, GlobalAllocator) \ , strc_visualize_whitespace(other->content, GlobalAllocator) \ ); \ @@ -671,9 +671,9 @@ bool code_is_equal( Code self, Code other ) if ( other->ast == nullptr ) \ { \ log_fmt("\nAST::is_equal: Failed for member " #ast " other equivalent param is null\n" \ - "AST : %s\n" \ - "Other: %s\n" \ - "For ast member: %s\n" \ + "AST : %SC\n" \ + "Other: %SC\n" \ + "For ast member: %SC\n" \ , code_debug_str(self) \ , code_debug_str(other) \ , code_debug_str(self->ast) \ @@ -685,10 +685,10 @@ bool code_is_equal( Code self, Code other ) if ( ! code_is_equal(self->ast, other->ast ) ) \ { \ log_fmt( "\nAST::is_equal: Failed for " #ast"\n" \ - "AST : %S\n" \ - "Other: %S\n" \ - "For ast member: %S\n" \ - "other's ast member: %S\n" \ + "AST : %SC\n" \ + "Other: %SC\n" \ + "For ast member: %SC\n" \ + "other's ast member: %SC\n" \ , code_debug_str(self) \ , code_debug_str(other) \ , code_debug_str(self->ast) \ @@ -918,22 +918,22 @@ bool code_is_equal( Code self, Code other ) if ( curr_other == nullptr ) { log_fmt("\nAST::is_equal: Failed for parameter, other equivalent param is null\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" + "AST : %SC\n" + "Other: %SC\n" + "For ast member: %SC\n" , code_debug_str(curr) ); return false; } - if ( curr->Name != curr_other->Name ) + if ( strc_are_equal(curr->Name, curr_other->Name) ) { log_fmt( "\nAST::is_equal: Failed for parameter name check\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" - "other's ast member: %S\n" + "AST : %SC\n" + "Other: %SC\n" + "For ast member: %SC\n" + "other's ast member: %SC\n" , code_debug_str(self) , code_debug_str(other) , code_debug_str(curr) @@ -945,10 +945,10 @@ bool code_is_equal( Code self, Code other ) if ( curr->ValueType && ! code_is_equal(curr->ValueType, curr_other->ValueType) ) { log_fmt( "\nAST::is_equal: Failed for parameter value type check\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" - "other's ast member: %S\n" + "AST : %SC\n" + "Other: %SC\n" + "For ast member: %SC\n" + "other's ast member: %SC\n" , code_debug_str(self) , code_debug_str(other) , code_debug_str(curr) @@ -960,10 +960,10 @@ bool code_is_equal( Code self, Code other ) if ( curr->Value && ! code_is_equal(curr->Value, curr_other->Value) ) { log_fmt( "\nAST::is_equal: Failed for parameter value check\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" - "other's ast member: %S\n" + "AST : %SC\n" + "Other: %SC\n" + "For ast member: %SC\n" + "other's ast member: %SC\n" , code_debug_str(self) , code_debug_str(other) , code_debug_str(curr) @@ -1117,10 +1117,10 @@ bool code_is_equal( Code self, Code other ) if ( curr_other == nullptr ) { log_fmt("\nAST::is_equal: Failed for body, other equivalent param is null\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" + "AST : %SC\n" + "Other: %SC\n" , code_debug_str(curr) + , code_debug_str(other) ); return false; @@ -1129,10 +1129,10 @@ bool code_is_equal( Code self, Code other ) if ( ! code_is_equal( curr, curr_other ) ) { log_fmt( "\nAST::is_equal: Failed for body\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" - "other's ast member: %S\n" + "AST : %SC\n" + "Other: %SC\n" + "For ast member: %SC\n" + "other's ast member: %SC\n" , code_debug_str(self) , code_debug_str(other) , code_debug_str(curr) @@ -1170,7 +1170,7 @@ bool code_validate_body(Code self) switch ( code_entry->Type ) \ { \ Unallowed_Types \ - log_failure( "AST::validate_body: Invalid entry in body %s", code_debug_str(code_entry) ); \ + log_failure( "AST::validate_body: Invalid entry in body %SC", code_debug_str(code_entry) ); \ return false; \ } \ } \ @@ -1191,7 +1191,7 @@ bool code_validate_body(Code self) { if ( entry->Type != CT_Untyped ) { - log_failure( "AST::validate_body: Invalid entry in enum body (needs to be untyped or comment) %s", GEN_NS code_debug_str(entry) ); + log_failure( "AST::validate_body: Invalid entry in enum body (needs to be untyped or comment) %SC", code_debug_str(entry) ); return false; } } @@ -1236,7 +1236,7 @@ bool code_validate_body(Code self) case CT_Specifiers: case CT_Struct_Body: case CT_Typename: - log_failure("AST::validate_body: Invalid entry in body %s", GEN_NS code_debug_str(entry)); + log_failure("AST::validate_body: Invalid entry in body %SC", code_debug_str(entry)); return false; } } @@ -1259,7 +1259,7 @@ bool code_validate_body(Code self) { if ( entry->Type != CT_Untyped ) { - log_failure( "AST::validate_body: Invalid entry in union body (needs to be untyped or comment) %s", GEN_NS code_debug_str(entry) ); + log_failure( "AST::validate_body: Invalid entry in union body (needs to be untyped or comment) %SC", code_debug_str(entry) ); return false; } } @@ -1267,7 +1267,7 @@ bool code_validate_body(Code self) break; default: - log_failure( "AST::validate_body: Invalid this AST does not have a body %s", code_debug_str(self) ); + log_failure( "AST::validate_body: Invalid this AST does not have a body %SC", code_debug_str(self) ); return false; } diff --git a/project/components/ast.hpp b/project/components/ast.hpp index 80fcb0e..545e4e0 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -187,19 +187,19 @@ template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( #pragma region Code C-Interface -void code_append (Code code, Code other ); -char const* code_debug_str (Code code); -Code code_duplicate (Code code); -Code* code_entry (Code code, u32 idx ); -bool code_has_entries (Code code); -bool code_is_body (Code code); -bool code_is_equal (Code code, Code other); -bool code_is_valid (Code code); -void code_set_global (Code code); -String code_to_string (Code self ); -void code_to_string_ptr(Code self, String* result ); -char const* code_type_str (Code self ); -bool code_validate_body(Code self ); +void code_append (Code code, Code other ); +StrC code_debug_str (Code code); +Code code_duplicate (Code code); +Code* code_entry (Code code, u32 idx ); +bool code_has_entries (Code code); +bool code_is_body (Code code); +bool code_is_equal (Code code, Code other); +bool code_is_valid (Code code); +void code_set_global (Code code); +String code_to_string (Code self ); +void code_to_string_ptr(Code self, String* result ); +StrC code_type_str (Code self ); +bool code_validate_body(Code self ); #pragma endregion Code C-Interface @@ -213,13 +213,13 @@ struct Code { AST* ast; -# define Using_Code( Typename ) \ - forceinline char const* debug_str() { return code_debug_str(* this); } \ - forceinline Code duplicate() { return code_duplicate(* this); } \ - forceinline bool is_equal( Code other ) { return code_is_equal(* this, other); } \ - forceinline bool is_body() { return code_is_body(* this); } \ - forceinline bool is_valid() { return code_is_valid(* this); } \ - forceinline void set_global() { return code_set_global(* this); } +# define Using_Code( Typename ) \ + forceinline StrC debug_str() { return code_debug_str(* this); } \ + forceinline Code duplicate() { return code_duplicate(* this); } \ + forceinline bool is_equal( Code other ) { return code_is_equal(* this, other); } \ + forceinline bool is_body() { return code_is_body(* this); } \ + forceinline bool is_valid() { return code_is_valid(* this); } \ + forceinline void set_global() { return code_set_global(* this); } # define Using_CodeOps( Typename ) \ forceinline Typename& operator = ( Code other ); \ @@ -231,13 +231,13 @@ struct Code #if ! GEN_C_LIKE_CPP Using_Code( Code ); - forceinline void append(Code other) { return code_append(* this, other); } - forceinline Code* entry(u32 idx) { return code_entry(* this, idx); } - forceinline bool has_entries() { return code_has_entries(* this); } - forceinline String to_string() { return code_to_string(* this); } - forceinline void to_string(String& result) { return code_to_string_ptr(* this, & result); } - forceinline char const* type_str() { return code_type_str(* this); } - forceinline bool validate_body() { return code_validate_body(*this); } + forceinline void append(Code other) { return code_append(* this, other); } + forceinline Code* entry(u32 idx) { return code_entry(* this, idx); } + forceinline bool has_entries() { return code_has_entries(* this); } + forceinline String to_string() { return code_to_string(* this); } + forceinline void to_string(String& result) { return code_to_string_ptr(* this, & result); } + forceinline StrC type_str() { return code_type_str(* this); } + forceinline bool validate_body() { return code_validate_body(*this); } #endif Using_CodeOps( Code ); @@ -313,15 +313,15 @@ constexpr int const AST_POD_Size = 128; constexpr static int AST_ArrSpecs_Cap = ( - AST_POD_Size - - sizeof(Code) - - sizeof(StringCached) - - sizeof(Code) * 2 - - sizeof(Token*) - - sizeof(Code) - - sizeof(CodeType) - - sizeof(ModuleFlag) - - sizeof(u32) + AST_POD_Size + - sizeof(Code) + - sizeof(StringCached) + - sizeof(Code) * 2 + - sizeof(Token*) + - sizeof(Code) + - sizeof(CodeType) + - sizeof(ModuleFlag) + - sizeof(u32) ) / sizeof(Specifier) - 1; diff --git a/project/components/inlines.hpp b/project/components/inlines.hpp index 2d81611..9239a54 100644 --- a/project/components/inlines.hpp +++ b/project/components/inlines.hpp @@ -101,10 +101,10 @@ Code& Code::operator ++() } #endif forceinline -char const* code_type_str(Code self) +StrC code_type_str(Code self) { GEN_ASSERT(self != nullptr); - return codetype_to_str( self->Type ).Ptr; + return codetype_to_str( self->Type ); } #pragma endregion Code diff --git a/project/components/interface.cpp b/project/components/interface.cpp index 2d4cb24..f7a9910 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -252,6 +252,25 @@ void init() array_append( Global_AllocatorBuckets, bucket ); } + if (Allocator_DataArrays.Proc == nullptr) { + Allocator_DataArrays = heap(); + } + if (Allocator_CodePool.Proc == nullptr ) { + Allocator_CodePool = heap(); + } + if (Allocator_Lexer.Proc == nullptr) { + Allocator_Lexer = heap(); + } + if (Allocator_StringArena.Proc == nullptr) { + Allocator_StringArena = heap(); + } + if (Allocator_StringTable.Proc == nullptr) { + Allocator_StringTable = heap(); + } + if (Allocator_TypeTable.Proc == nullptr) { + Allocator_TypeTable = heap(); + } + // Setup the arrays { CodePools = array_init_reserve( Allocator_DataArrays, InitSize_DataArrays ); diff --git a/project/components/interface.hpp b/project/components/interface.hpp index d23cccb..60cf6be 100644 --- a/project/components/interface.hpp +++ b/project/components/interface.hpp @@ -302,7 +302,7 @@ Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... ); /* Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string. - Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brakcets (you can change it in token_fmt_va) + Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brackets (you can change it in token_fmt_va) --------------------------------------------------------- Example - A string with: typedef ; @@ -310,7 +310,7 @@ Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... ); "type", strc_for_type, "name", strc_for_name, and: - stringize( typedef ; ) ) + stringize( typedef ; ) ----------------------------------------------------------- So the full call for this example would be: token_fmt( diff --git a/project/components/parser.cpp b/project/components/parser.cpp index b129139..d678309 100644 --- a/project/components/parser.cpp +++ b/project/components/parser.cpp @@ -5042,7 +5042,6 @@ CodeTypedef parse_typedef() Token pre_foward_tok = currtok; if ( (idx - 3 ) == tokens.Idx ) { - log_fmt("Identified forward typedef\n"); // Its a forward declaration only type = parse_forward_or_definition( which, from_typedef ); // typedef diff --git a/project/components/static_data.cpp b/project/components/static_data.cpp index c54cc66..e076031 100644 --- a/project/components/static_data.cpp +++ b/project/components/static_data.cpp @@ -7,22 +7,22 @@ // TODO : Convert global allocation strategy to use a slab allocation strategy. global AllocatorInfo GlobalAllocator; -global Array Global_AllocatorBuckets; +global Array( Arena ) Global_AllocatorBuckets; // TODO(Ed) : Make the code pool a dynamic arena -global Array< Pool > CodePools = { nullptr }; -global Array< Arena > StringArenas = { nullptr }; +global Array( Pool ) CodePools = { nullptr }; +global Array( Arena ) StringArenas = { nullptr }; global StringTable StringCache; global Arena LexArena; -global AllocatorInfo Allocator_DataArrays = heap(); -global AllocatorInfo Allocator_CodePool = heap(); -global AllocatorInfo Allocator_Lexer = heap(); -global AllocatorInfo Allocator_StringArena = heap(); -global AllocatorInfo Allocator_StringTable = heap(); -global AllocatorInfo Allocator_TypeTable = heap(); +global AllocatorInfo Allocator_DataArrays = {0}; +global AllocatorInfo Allocator_CodePool = {0}; +global AllocatorInfo Allocator_Lexer = {0}; +global AllocatorInfo Allocator_StringArena = {0}; +global AllocatorInfo Allocator_StringTable = {0}; +global AllocatorInfo Allocator_TypeTable = {0}; #pragma endregion StaticData diff --git a/project/components/types.hpp b/project/components/types.hpp index 7b8231f..6892be1 100644 --- a/project/components/types.hpp +++ b/project/components/types.hpp @@ -44,18 +44,19 @@ enum AccessSpec : u32 static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" ); inline -char const* access_spec_to_str( AccessSpec type ) +StrC access_spec_to_str( AccessSpec type ) { local_persist - char const* lookup[ (u32)AccessSpec_Num_AccessSpec ] = { - "", - "private", - "protected", - "public", + StrC lookup[ (u32)AccessSpec_Num_AccessSpec ] = { + { sizeof("") - 1, "" }, + { sizeof("prviate") - 1, "private" }, + { sizeof("protected") - 1, "private" }, + { sizeof("public") - 1, "public" }, }; + StrC invalid = { sizeof("Invalid") - 1, "Invalid" }; if ( type > AccessSpec_Public ) - return "Invalid"; + return invalid; return lookup[ (u32)type ]; } diff --git a/project/dependencies/macros.hpp b/project/dependencies/macros.hpp index e55e321..f7accf2 100644 --- a/project/dependencies/macros.hpp +++ b/project/dependencies/macros.hpp @@ -317,10 +317,11 @@ // The slot won't exist if that comma is not found. | // For the occastion where an expression didn't resolve to a selection option the "default: " wilbe set to: -struct NO_RESOLVED_GENERIC_SELECTION { - unsigned long long failure; +typedef struct GENCPP_NO_RESOLVED_GENERIC_SELECTION GENCPP_NO_RESOLVED_GENERIC_SELECTION; +struct GENCPP_NO_RESOLVED_GENERIC_SELECTION { + void* _THE_VOID_SLOT_; }; -struct NO_RESOLVED_GENERIC_SELECTION const gen_generic_selection_fail = {}; +GENCPP_NO_RESOLVED_GENERIC_SELECTION const gen_generic_selection_fail = {0}; // Which will provide the message: error: called object type 'struct NO_RESOLVED_GENERIC_SELECTION' is not a function or function pointer // ---------------------------------------------------------------------------------------------------------------------------------- diff --git a/project/dependencies/memory.hpp b/project/dependencies/memory.hpp index 1fb24c9..9f187ac 100644 --- a/project/dependencies/memory.hpp +++ b/project/dependencies/memory.hpp @@ -208,7 +208,7 @@ struct Arena // This id is defined by Unreal for asserts #pragma push_macro("check") #undef check - forceinline void check() { GEN_NS arena_check(this); } + forceinline void check() { arena_check(this); } #pragma pop_macro("check") #pragma endregion Member Mapping @@ -335,7 +335,7 @@ struct FixedArena #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP #pragma region Member Mapping - forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); } + forceinline operator AllocatorInfo() { return fixed_arena_allocator_info(this); } forceinline static FixedArena init() { FixedArena result; fixed_arena_init(result); return result; } forceinline ssize size_remaining(ssize alignment) { fixed_arena_size_remaining(this, alignment); }