From ca7ff99a790b79f85542fabbd4cda0d99466f659 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 17 Dec 2024 10:03:50 -0500 Subject: [PATCH] Code type coercion for builder_print in C11 library using generic selector. --- base/components/interface.hpp | 1 + gen_c_library/c_library.cpp | 184 +++++++++++++++++++++++----------- scripts/build.ci.ps1 | 4 +- test/c_library/test.c | 6 +- 4 files changed, 134 insertions(+), 61 deletions(-) diff --git a/base/components/interface.hpp b/base/components/interface.hpp index f945a56..a697201 100644 --- a/base/components/interface.hpp +++ b/base/components/interface.hpp @@ -50,6 +50,7 @@ struct Context // LoggerCallaback* log_callback; // TODO(Ed): Impl user logger callback as an option. +// Initalization config u32 Max_CommentLineLength; // Used by def_comment u32 Max_StrCacheLength; // Any cached string longer than this is always allocated again. diff --git a/gen_c_library/c_library.cpp b/gen_c_library/c_library.cpp index 9fc7cc5..f03a8d6 100644 --- a/gen_c_library/c_library.cpp +++ b/gen_c_library/c_library.cpp @@ -1256,63 +1256,6 @@ R"(#define ( code ) _Generic( (code), \ break; } - CodeBody parsed_header_builder = parse_file( path_base "auxiliary/builder.hpp" ); - CodeBody header_builder = def_body(CT_Global_Body); - for ( Code entry = parsed_header_builder.begin(); entry != parsed_header_builder.end(); ++ entry ) switch( entry->Type ) - { - case CT_Preprocess_IfDef: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_builder, header_builder ); - if (found) break; - - header_builder.append(entry); - } - break; - - case CT_Preprocess_If: - { - b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_header_builder, header_builder ); - if (found) break; - - found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_header_builder, header_builder ); - if (found) break; - - header_builder.append(entry); - } - break; - - case CT_Struct: - { - CodeBody body = cast(CodeBody, entry->Body); - CodeBody new_body = def_body(CT_Struct_Body); - 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; - - new_body.append(body_entry); - } - break; - - default: - new_body.append(body_entry); - break; - } - if ( new_body->NumEntries > 0 ) { - entry->Body = new_body; - } - - header_builder.append(entry); - } - break; - - default: - header_builder.append(entry); - break; - } - s32 idx = 0; CodeBody parsed_header_end = parse_file( path_base "components/header_end.hpp" ); CodeBody header_end = def_body(CT_Global_Body); @@ -1351,6 +1294,111 @@ R"(#define ( code ) _Generic( (code), \ } #pragma endregion Resolve Components +#pragma region Resolve Aux + CodeDefine gsel_builder_print = NullCode; + CodeBody parsed_header_builder = parse_file( path_base "auxiliary/builder.hpp" ); + CodeBody header_builder = def_body(CT_Global_Body); + for ( Code entry = parsed_header_builder.begin(); entry != parsed_header_builder.end(); ++ entry ) switch( entry->Type ) + { + case CT_Preprocess_IfDef: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_builder, header_builder ); + if (found) break; + + header_builder.append(entry); + } + break; + + case CT_Preprocess_If: + { + b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_header_builder, header_builder ); + if (found) break; + + found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_header_builder, header_builder ); + if (found) break; + + header_builder.append(entry); + } + break; + + case CT_Function_Fwd: + { + CodeFn fn = cast(CodeFn, entry); + + if (! fn->Name.is_equal(txt("builder_print")) ) { + header_builder.append(fn); + continue; + } + + fn->Name = cache_str(txt("builder__print")); + + StrBuilder generic_selector = StrBuilder::make(_ctx->Allocator_Temp, + "#define builder_print(builder, code) _Generic( (code), \\\n" + ); + // Append slots + for(Str type : code_typenames ) { + generic_selector.append_fmt("%S : %S,\\\n", type, fn->Name ); + } + generic_selector.append(txt("default: gen_generic_selection_fail \\\n")); + generic_selector.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( builder, (Code)code )")); + + // We need to register this as an identifier macro now sot that parsing the source wont break. + register_macro({ txt("builder_print"), MT_Statement, MF_Functional | MF_Allow_As_Identifier }); + + // We'll be adding this selector after builder_print_fmt + gsel_builder_print = parse_define(generic_selector); + + header_builder.append(fn); + } + break; + + case CT_Function: + { + CodeFn fn = cast(CodeFn, entry); + + if ( fn->Name.is_equal(txt("builder_print_fmt")) ) { + header_builder.append(fn); + + // Add the selector right after + header_builder.append(fmt_newline); + header_builder.append(gsel_builder_print); + } + } + break; + + case CT_Struct: + { + CodeBody body = cast(CodeBody, entry->Body); + CodeBody new_body = def_body(CT_Struct_Body); + 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; + + new_body.append(body_entry); + } + break; + + default: + new_body.append(body_entry); + break; + } + if ( new_body->NumEntries > 0 ) { + entry->Body = new_body; + } + + header_builder.append(entry); + } + break; + + default: + header_builder.append(entry); + break; + } +#pragma endregion Aux + // Source Content : Reflection and Generation #pragma region Resolve Dependencies @@ -1559,6 +1607,26 @@ R"(#define ( code ) _Generic( (code), \ } #pragma endregion Resolve Components +#pragma region Resolve Aux + CodeBody parsed_src_builder = parse_file( path_base "auxiliary/builder.cpp" ); + CodeBody src_builder = def_body(CT_Global_Body); + for ( Code entry = parsed_src_builder.begin(); entry != parsed_src_builder.end(); ++ entry ) switch( entry->Type ) + { + case CT_Function: + { + if (entry->Name.is_equal(txt("builder_print"))) { + entry->Name = cache_str(txt("builder__print")); + } + src_builder.append(entry); + } + break; + + default: + src_builder.append(entry); + break; + } +#pragma endregion ResolveAux + // THERE SHOULD BE NO NEW GENERIC CONTAINER DEFINITIONS PAST THIS POINT (It will not have slots for the generic selection generated macros) CodeBody containers = def_body(CT_Global_Body); { @@ -1644,7 +1712,7 @@ R"(#define ( code ) _Generic( (code), \ CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv", helper_use_c_definition ); Code rf_etoktype = refactor_and_format(etoktype); - Code rf_src_builder = refactor_and_format( scan_file( path_base "auxiliary/builder.cpp" )); + Code rf_src_builder = refactor_and_format( src_builder ); Code rf_src_scanner = refactor_and_format( scan_file( path_base "auxiliary/scanner.cpp" )); #pragma endregion Refactored / Formatted diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index 32fa51b..8dfea77 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -326,7 +326,7 @@ if ( $unreal ) } # C Library testing -if ( $test -and $false ) +if ( $test -and $true ) { $path_test_c = join-path $path_test c_library $path_build = join-path $path_test_c build @@ -368,7 +368,7 @@ if ( $test -and $false ) Pop-Location } -if ( $test -and $true ) +if ( $test -and $false ) { $path_test_c = join-path $path_test c_library $path_build = join-path $path_test_c build diff --git a/test/c_library/test.c b/test/c_library/test.c index 85288ef..89f7487 100644 --- a/test/c_library/test.c +++ b/test/c_library/test.c @@ -1,3 +1,7 @@ +#if GEN_INTELLISENSE_DIRECTIVES +#include "../../gen_c_library/gen/gen_singleheader.h" +#endif + #define GEN_IMPLEMENTATION #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #include "gen_singleheader.h" @@ -16,7 +20,7 @@ int main() gen_CodeVar hello_var = gen_parse_variable(code( char const* hello_gencpp_str = "HELLO GENCPP C11 !"; )); - gen_builder_print( & src_hello, (gen_Code)hello_var ); + gen_builder_print( & src_hello, hello_var ); gen_builder_write(& src_hello); gen_CodeBody body = gen_parse_file("gen/hello.c");