mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-11-03 15:26:12 -08:00 
			
		
		
		
	Code type coercion for builder_print in C11 library using generic selector.
This commit is contained in:
		@@ -50,6 +50,7 @@ struct Context
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// LoggerCallaback* log_callback; // TODO(Ed): Impl user logger callback as an option.
 | 
						// LoggerCallaback* log_callback; // TODO(Ed): Impl user logger callback as an option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Initalization config
 | 
				
			||||||
	u32 Max_CommentLineLength; // Used by def_comment
 | 
						u32 Max_CommentLineLength; // Used by def_comment
 | 
				
			||||||
	u32 Max_StrCacheLength;    // Any cached string longer than this is always allocated again.
 | 
						u32 Max_StrCacheLength;    // Any cached string longer than this is always allocated again.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1256,63 +1256,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
				
			|||||||
		break;
 | 
							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;
 | 
						s32 idx = 0;
 | 
				
			||||||
	CodeBody parsed_header_end = parse_file( path_base "components/header_end.hpp" );
 | 
						CodeBody parsed_header_end = parse_file( path_base "components/header_end.hpp" );
 | 
				
			||||||
	CodeBody header_end        = def_body(CT_Global_Body);
 | 
						CodeBody header_end        = def_body(CT_Global_Body);
 | 
				
			||||||
@@ -1351,6 +1294,111 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
#pragma endregion Resolve Components
 | 
					#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
 | 
					// Source Content : Reflection and Generation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma region Resolve Dependencies
 | 
					#pragma region Resolve Dependencies
 | 
				
			||||||
@@ -1559,6 +1607,26 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
#pragma endregion Resolve Components
 | 
					#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)
 | 
						// 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);
 | 
						CodeBody containers = def_body(CT_Global_Body);
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -1644,7 +1712,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
				
			|||||||
	CodeBody etoktype    = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv", helper_use_c_definition );
 | 
						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_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" ));
 | 
						Code rf_src_scanner = refactor_and_format( scan_file( path_base "auxiliary/scanner.cpp" ));
 | 
				
			||||||
#pragma endregion Refactored / Formatted
 | 
					#pragma endregion Refactored / Formatted
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -326,7 +326,7 @@ if ( $unreal )
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# C Library testing
 | 
					# C Library testing
 | 
				
			||||||
if ( $test -and $false )
 | 
					if ( $test -and $true )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	$path_test_c = join-path $path_test   c_library
 | 
						$path_test_c = join-path $path_test   c_library
 | 
				
			||||||
	$path_build  = join-path $path_test_c build
 | 
						$path_build  = join-path $path_test_c build
 | 
				
			||||||
@@ -368,7 +368,7 @@ if ( $test -and $false )
 | 
				
			|||||||
	Pop-Location
 | 
						Pop-Location
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ( $test -and $true )
 | 
					if ( $test -and $false )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	$path_test_c = join-path $path_test   c_library
 | 
						$path_test_c = join-path $path_test   c_library
 | 
				
			||||||
	$path_build  = join-path $path_test_c build
 | 
						$path_build  = join-path $path_test_c build
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,7 @@
 | 
				
			|||||||
 | 
					#if GEN_INTELLISENSE_DIRECTIVES
 | 
				
			||||||
 | 
					#include "../../gen_c_library/gen/gen_singleheader.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GEN_IMPLEMENTATION
 | 
					#define GEN_IMPLEMENTATION
 | 
				
			||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
 | 
					#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
 | 
				
			||||||
#include "gen_singleheader.h"
 | 
					#include "gen_singleheader.h"
 | 
				
			||||||
@@ -16,7 +20,7 @@ int main()
 | 
				
			|||||||
	gen_CodeVar hello_var = gen_parse_variable(code(
 | 
						gen_CodeVar hello_var = gen_parse_variable(code(
 | 
				
			||||||
		char const* hello_gencpp_str = "HELLO GENCPP C11 !";
 | 
							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_builder_write(& src_hello);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gen_CodeBody body = gen_parse_file("gen/hello.c");
 | 
						gen_CodeBody body = gen_parse_file("gen/hello.c");
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user