mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 22:40:54 -07:00 
			
		
		
		
	C-library gen progress: Header files mostly done, starting dep c impl and fixes to generic selection generation
This commit is contained in:
		
							
								
								
									
										2
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @@ -72,5 +72,5 @@ | ||||
| 	}, | ||||
| 	"autoHide.autoHidePanel": false, | ||||
| 	"autoHide.autoHideSideBar": false, | ||||
| 	"dimmer.enabled": true | ||||
| 	"dimmer.enabled": false | ||||
| } | ||||
|   | ||||
							
								
								
									
										8
									
								
								gen_c_library/.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								gen_c_library/.editorconfig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| [*.c] | ||||
| indent_style = tab | ||||
| indent_size  = 4 | ||||
|  | ||||
| [*.cpp] | ||||
| indent_style = tab | ||||
| indent_size  = 2 | ||||
|  | ||||
| @@ -1,3 +1,5 @@ | ||||
| #include <cstdlib>   // for system() | ||||
|  | ||||
| #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS | ||||
| #define GEN_ENFORCE_STRONG_CODE_TYPES | ||||
| #define GEN_EXPOSE_BACKEND | ||||
| @@ -16,7 +18,6 @@ GEN_NS_END | ||||
| #include "auxillary/builder.cpp" | ||||
| #include "auxillary/scanner.hpp" | ||||
|  | ||||
| #include <cstdlib>   // for system() | ||||
|  | ||||
| #include "components/memory.fixed_arena.hpp" | ||||
| #include "components/misc.hpp" | ||||
| @@ -113,6 +114,7 @@ int gen_main() | ||||
| 	PreprocessorDefines.append(txt("GEN_OPTIMIZE_MAPPINGS_BEGIN")); | ||||
| 	PreprocessorDefines.append(txt("GEN_OPITMIZE_MAPPINGS_END")); | ||||
| 	//PreprocessorDefines.append(txt("GEN_EXECUTION_EXPRESSION_SUPPORT")); | ||||
| 	PreprocessorDefines.append(txt("GEN_PARAM_DEFAULT")); | ||||
|  | ||||
| 	Code push_ignores           = scan_file( project_dir "helpers/push_ignores.inline.hpp" ); | ||||
| 	Code pop_ignores            = scan_file( project_dir "helpers/pop_ignores.inline.hpp" ); | ||||
| @@ -132,58 +134,57 @@ int gen_main() | ||||
| 		// Only has operator overload definitions that C doesn't need. | ||||
| 		// CodeBody ast_inlines = gen_ast_inlines(); | ||||
|  | ||||
| 		Code interface  = scan_file( project_dir "components/interface.hpp" ); | ||||
| 		Code inlines 	= scan_file( project_dir "components/inlines.hpp" ); | ||||
| 		Code header_end = scan_file( project_dir "components/header_end.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_<name_of_file>.begin(); entry != parsed_<name_of_file>.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 ) | ||||
| 		for ( Code entry = parsed_types.begin(); entry != parsed_types.end(); ++ entry ) switch(entry->Type) | ||||
| 		{ | ||||
| 			switch(entry->Type) | ||||
| 			case CT_Using: | ||||
| 			{ | ||||
| 				case CT_Using: | ||||
| 				{ | ||||
| 					CodeUsing using_ver = cast(CodeUsing, entry); | ||||
| 				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 <ReturnType>( * <Name>)(<Parameters>); | ||||
| 						))); | ||||
| 						types.append(typedef_ver); | ||||
| 						break; | ||||
| 					} | ||||
| 					CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); | ||||
| 				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 <ReturnType>( * <Name>)(<Parameters>); | ||||
| 					))); | ||||
| 					types.append(typedef_ver); | ||||
| 					break; | ||||
| 				} | ||||
| 				break; | ||||
|  | ||||
| 				case CT_Enum: | ||||
| 				{ | ||||
| 					log_fmt("Detected ENUM: %S", entry->Name); | ||||
| 					convert_cpp_enum_to_c(cast(CodeEnum, entry), types); | ||||
| 				} | ||||
| 				break; | ||||
|  | ||||
| 				default: | ||||
| 					types.append(entry); | ||||
| 				break; | ||||
| 				CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); | ||||
| 				types.append(typedef_ver); | ||||
| 			} | ||||
| 			break; | ||||
|  | ||||
| 			case CT_Enum: | ||||
| 			{ | ||||
| 				//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) | ||||
| 		for ( Code entry = parsed_ast.begin(); entry != parsed_ast.end(); ++ entry ) switch (entry->Type) | ||||
| 		{ | ||||
| 			case CT_Preprocess_If: | ||||
| 			{ | ||||
| @@ -230,21 +231,22 @@ int gen_main() | ||||
|  | ||||
| 				s32 constexpr_found = var->Specs ? var->Specs.remove( Spec_Constexpr ) : - 1; | ||||
| 				if (constexpr_found > -1) { | ||||
| 					log_fmt("Found constexpr: %S\n", entry.to_string()); | ||||
| 					//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(StringCached)    \ | ||||
| 		- sizeof(AST*) * 3        \ | ||||
| 		- sizeof(Token*)          \ | ||||
| 		- sizeof(AST*)            \ | ||||
| 		- sizeof(CodeType)        \ | ||||
| 		- sizeof(ModuleFlag)      \ | ||||
| 		- sizeof(u32)             \ | ||||
| )                                 \ | ||||
| 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 | ||||
| )" | ||||
| 						)); | ||||
| @@ -263,6 +265,7 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
| 				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 ) | ||||
| @@ -286,6 +289,7 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
| 				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 ) | ||||
| @@ -302,9 +306,29 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
|  | ||||
| 			case CT_Struct: | ||||
| 			{ | ||||
| 				CodeStruct struct_def = cast(CodeStruct, entry); | ||||
| 				CodeTypedef tdef = parse_typedef(token_fmt("name", struct_def->Name, stringize( typedef struct <name> <name>; ))); | ||||
| 				ast_types.append(struct_def); | ||||
| 				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 (<arr_exp>) 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 <name> <name>; ))); | ||||
| 				ast_types.append(entry); | ||||
| 				ast_types.append(tdef); | ||||
| 			} | ||||
| 			break; | ||||
| @@ -313,6 +337,73 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
| 				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 <name> <name>; ))); | ||||
| 				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 | ||||
| @@ -326,163 +417,157 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
|  | ||||
| 		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 ) | ||||
| 		for ( Code entry = parsed_memory.begin(); entry != parsed_memory.end(); ++ entry ) switch (entry->Type) | ||||
| 		{ | ||||
| 			switch (entry->Type) | ||||
| 			case CT_Using: | ||||
| 			{ | ||||
| 				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); | ||||
| 				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 <name> <name>; ))); | ||||
| 					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 <name> <name>; ))); | ||||
| 					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; | ||||
| 				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 <name> <name>; ))); | ||||
| 				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 <name> <name>; ))); | ||||
| 				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 ) | ||||
| 		for ( Code entry = printing_parsed.begin(); entry != printing_parsed.end(); ++ entry ) switch (entry->Type) | ||||
| 		{ | ||||
| 			switch (entry->Type) | ||||
| 			case CT_Preprocess_IfDef: | ||||
| 			{ | ||||
| 				case CT_Preprocess_IfDef: | ||||
| 				{ | ||||
| 					b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, printing_parsed, printing ); | ||||
| 					if (found) break; | ||||
| 				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; | ||||
| 				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" ); | ||||
| @@ -520,7 +605,7 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
|  | ||||
| 			case CT_Preprocess_IfNotDef: | ||||
| 			{ | ||||
| 				log_fmt("\nIFNDEF: %SC\n", entry->Content); | ||||
| 				//log_fmt("\nIFNDEF: %SC\n", entry->Content); | ||||
| 				strings.append(entry); | ||||
| 			} | ||||
| 			break; | ||||
| @@ -589,73 +674,73 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
|  | ||||
| 		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 ) | ||||
| 		for ( Code entry = parsed_filesystem.begin(); entry != parsed_filesystem.end(); ++ entry ) switch (entry->Type) | ||||
| 		{ | ||||
| 			switch (entry->Type) | ||||
| 			case CT_Preprocess_IfDef: | ||||
| 			{ | ||||
| 				case CT_Preprocess_IfDef: | ||||
| 				{ | ||||
| 					b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_filesystem, filesystem ); | ||||
| 					if (found) break; | ||||
| 				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 <type> <name> <name>; | ||||
| 					)); | ||||
| 					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; | ||||
| 				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 <type> <name> <name>; | ||||
| 				)); | ||||
| 				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_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))); | ||||
|  | ||||
| @@ -667,6 +752,7 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
| 			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); | ||||
| @@ -684,6 +770,7 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
| 		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)); | ||||
| @@ -695,7 +782,6 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
|  | ||||
| 		header.print(fmt_newline); | ||||
|  | ||||
| #if 1 | ||||
| #pragma region region Print Components | ||||
| 		header.print_fmt( "GEN_NS_BEGIN\n" ); | ||||
| 		header.print_fmt( "GEN_API_C_BEGIN\n\n" ); | ||||
| @@ -716,17 +802,87 @@ R"(#define AST_ArrSpecs_Cap       \ | ||||
| 		header.print( dump_to_scratch_and_retireve(ast_types) ); | ||||
| 		header.print_fmt("\n#pragma endregion AST\n"); | ||||
|  | ||||
| 		header.print( dump_to_scratch_and_retireve(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(fmt_newline); | ||||
|  | ||||
| 		header.print( dump_to_scratch_and_retireve(header_end) ); | ||||
|  | ||||
| 		header.print_fmt( "\nGEN_API_C_END\n" ); | ||||
|  | ||||
| 		header.print_fmt( "GEN_NS_END\n\n" ); | ||||
| #pragma endregion Print Compoennts | ||||
| #endif | ||||
| 	} | ||||
|  | ||||
| 	// Implementation | ||||
| 	{ | ||||
| 		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 region 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 | ||||
| 		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_fmt( "\n#pragma region Parsing\n" ); | ||||
| 		header.print( scan_file( project_dir "dependencies/parsing.cpp" ) ); | ||||
| 		header.print_fmt( "#pragma endregion Parsing\n\n" ); | ||||
|  | ||||
| 		header.print_fmt( "GEN_NS_END\n"); | ||||
| 		header.print_fmt( roll_own_dependencies_guard_end ); | ||||
|  | ||||
| #pragma endregion Print Dependencies | ||||
|  | ||||
| #pragma region Print Components | ||||
|  | ||||
| #pragma endregion Print Components | ||||
|  | ||||
| 		header.print_fmt( implementation_guard_end ); | ||||
| 	} | ||||
|  | ||||
| 	header.print( pop_ignores ); | ||||
| 	header.write(); | ||||
|  | ||||
| 	// format_file( "gen/gen.h" ); | ||||
| 	//k | ||||
|  | ||||
| 	gen::deinit(); | ||||
| 	return 0; | ||||
|   | ||||
| @@ -21,8 +21,9 @@ CodeBody gen_array_base() | ||||
|  | ||||
| 	Code grow_formula = untyped_str( txt( "#define array_grow_formula( value ) ( 2 * value + 8 )\n" )); | ||||
| 	Code get_header   = untyped_str( txt( "#define array_get_header( self ) ( (ArrayHeader*)( self ) - 1)\n" )); | ||||
| 	Code type_define  = untyped_str( txt( "#define Array(Type) Array_##Type\n")); | ||||
|  | ||||
| 	return def_global_body( args( fmt_newline, td_header, header, grow_formula, get_header, fmt_newline ) ); | ||||
| 	return def_global_body( args( fmt_newline, td_header, header, type_define, grow_formula, get_header, fmt_newline ) ); | ||||
| }; | ||||
|  | ||||
| CodeBody gen_array( StrC type, StrC array_name ) | ||||
| @@ -68,7 +69,7 @@ CodeBody gen_array( StrC type, StrC array_name ) | ||||
| 		<array_type> <fn>_init( AllocatorInfo allocator ) | ||||
| 		{ | ||||
| 			size_t initial_size = array_grow_formula(0); | ||||
| 			return array_init_reserve( <array_type>, allocator, initial_size ); | ||||
| 			return array_init_reserve( <type>, allocator, initial_size ); | ||||
| 		} | ||||
|  | ||||
| 		inline | ||||
| @@ -362,24 +363,24 @@ CodeBody gen_array( StrC type, StrC array_name ) | ||||
| 	++ Array_DefinitionCounter; | ||||
| 	StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", Array_DefinitionCounter).to_strc(); | ||||
|  | ||||
| 	Code generic_interface_slot = untyped_str(token_fmt( "type_delimiter", (StrC)array_type, "slot", (StrC)slot_str, | ||||
| R"(#define GENERIC_SLOT_<slot>__array_init         <type_delimiter>,  <type_delimiter>_init | ||||
| #define GENERIC_SLOT_<slot>__array_init_reserve    <type_delimiter>,  <type_delimiter>_init_reserve | ||||
| #define GENERIC_SLOT_<slot>__array_append          <type_delimiter>,  <type_delimiter>_append | ||||
| #define GENERIC_SLOT_<slot>__array_append_items    <type_delimiter>,  <type_delimiter>_append_items | ||||
| #define GENERIC_SLOT_<slot>__array_append_at       <type_delimiter>,  <type_delimiter>_append_at | ||||
| #define GENERIC_SLOT_<slot>__array_append_items_at <type_delimiter>,  <type_delimiter>_append_items_at | ||||
| #define GENERIC_SLOT_<slot>__array_back            <type_delimiter>,  <type_delimiter>_back | ||||
| #define GENERIC_SLOT_<slot>__array_clear           <type_delimiter>,  <type_delimiter>_clear | ||||
| #define GENERIC_SLOT_<slot>__array_fill            <type_delimiter>,  <type_delimiter>_fill | ||||
| #define GENERIC_SLOT_<slot>__array_free            <type_delimiter>,  <type_delimiter>_free | ||||
| #define GENERIC_SLOT_<slot>__array_grow            <type_delimiter>*, <type_delimiter>_grow | ||||
| #define GENERIC_SLOT_<slot>__array_num             <type_delimiter>,  <type_delimiter>_num | ||||
| #define GENERIC_SLOT_<slot>__array_pop             <type_delimiter>,  <type_delimiter>_pop | ||||
| #define GENERIC_SLOT_<slot>__array_remove_at       <type_delimiter>,  <type_delimiter>_remove_at | ||||
| #define GENERIC_SLOT_<slot>__array_reserve         <type_delimiter>,  <type_delimiter>_reserve | ||||
| #define GENERIC_SLOT_<slot>__array_resize          <type_delimiter>,  <type_delimiter>_resize | ||||
| #define GENERIC_SLOT_<slot>__array_set_capacity    <type_delimiter>*, <type_delimiter>_set_capacity | ||||
| 	Code generic_interface_slot = untyped_str(token_fmt( "type", type, "array_type", (StrC)array_type, "slot", (StrC)slot_str, | ||||
| R"(#define GENERIC_SLOT_<slot>__array_init         <type>,        <array_type>_init | ||||
| #define GENERIC_SLOT_<slot>__array_init_reserve    <type>,        <array_type>_init_reserve | ||||
| #define GENERIC_SLOT_<slot>__array_append          <array_type>,  <array_type>_append | ||||
| #define GENERIC_SLOT_<slot>__array_append_items    <array_type>,  <array_type>_append_items | ||||
| #define GENERIC_SLOT_<slot>__array_append_at       <array_type>,  <array_type>_append_at | ||||
| #define GENERIC_SLOT_<slot>__array_append_items_at <array_type>,  <array_type>_append_items_at | ||||
| #define GENERIC_SLOT_<slot>__array_back            <array_type>,  <array_type>_back | ||||
| #define GENERIC_SLOT_<slot>__array_clear           <array_type>,  <array_type>_clear | ||||
| #define GENERIC_SLOT_<slot>__array_fill            <array_type>,  <array_type>_fill | ||||
| #define GENERIC_SLOT_<slot>__array_free            <array_type>,  <array_type>_free | ||||
| #define GENERIC_SLOT_<slot>__array_grow            <array_type>*, <array_type>_grow | ||||
| #define GENERIC_SLOT_<slot>__array_num             <array_type>,  <array_type>_num | ||||
| #define GENERIC_SLOT_<slot>__array_pop             <array_type>,  <array_type>_pop | ||||
| #define GENERIC_SLOT_<slot>__array_remove_at       <array_type>,  <array_type>_remove_at | ||||
| #define GENERIC_SLOT_<slot>__array_reserve         <array_type>,  <array_type>_reserve | ||||
| #define GENERIC_SLOT_<slot>__array_resize          <array_type>,  <array_type>_resize | ||||
| #define GENERIC_SLOT_<slot>__array_set_capacity    <array_type>*, <array_type>_set_capacity | ||||
| )" | ||||
| 	)); | ||||
|  | ||||
|   | ||||
| @@ -109,19 +109,19 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name ) | ||||
|  | ||||
| 		<tbl_type> <fn>init( AllocatorInfo allocator ) | ||||
| 		{ | ||||
| 			<tbl_type> result = hashtable_init_reserve(<tbl_type>, allocator, 8); | ||||
| 			<tbl_type> result = hashtable_init_reserve(<type>, allocator, 8); | ||||
| 			return result; | ||||
| 		} | ||||
|  | ||||
| 		<tbl_type> <fn>_init_reserve( AllocatorInfo allocator, ssize num ) | ||||
| 		{ | ||||
| 			<tbl_type> result = { NULL, NULL }; | ||||
| 			result.Hashes  = array_init_reserve(Array_ssize, allocator, num ); | ||||
| 			result.Hashes  = array_init_reserve(ssize, allocator, num ); | ||||
| 			array_get_header(result.Hashes)->Num = num; | ||||
| 			array_resize(result.Hashes, num); | ||||
| 			array_fill(result.Hashes, 0, num, -1); | ||||
|  | ||||
| 			result.Entries = array_init_reserve(<array_entry>, allocator, num ); | ||||
| 			result.Entries = array_init_reserve(<entry_type>, allocator, num ); | ||||
| 			return result; | ||||
| 		} | ||||
|  | ||||
| @@ -199,7 +199,7 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name ) | ||||
| 			ArrayHeader* old_hash_header    = array_get_header( self->Hashes ); | ||||
| 			ArrayHeader* old_entries_header = array_get_header( self->Entries ); | ||||
|  | ||||
| 			<tbl_type> new_tbl = hashtable_init_reserve( <tbl_type>, old_hash_header->Allocator, old_hash_header->Num ); | ||||
| 			<tbl_type> new_tbl = hashtable_init_reserve( <type>, old_hash_header->Allocator, old_hash_header->Num ); | ||||
|  | ||||
| 			ArrayHeader* new_hash_header = array_get_header( new_tbl.Hashes ); | ||||
|  | ||||
| @@ -375,24 +375,24 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name ) | ||||
| 	++ HashTable_DefinitionCounter; | ||||
| 	StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", Array_DefinitionCounter).to_strc(); | ||||
|  | ||||
| 	Code generic_interface_slot = untyped_str(token_fmt( "type_delimiter", (StrC)tbl_type, "slot", (StrC)slot_str, | ||||
| R"(#define GENERIC_SLOT_<slot>__hashtable_init          <type_delimiter>,  <type_delimiter>_init | ||||
| #define GENERIC_SLOT_<slot>__hashtable_init_reserve     <type_delimiter>,  <type_delimiter>_init_reserve | ||||
| #define GENERIC_SLOT_<slot>__hashtable_clear            <type_delimiter>,  <type_delimiter>_clear | ||||
| #define GENERIC_SLOT_<slot>__hashtable_destroy          <type_delimiter>*, <type_delimiter>_destroy | ||||
| #define GENERIC_SLOT_<slot>__hashtable_get              <type_delimiter>,  <type_delimiter>_get | ||||
| #define GENERIC_SLOT_<slot>__hashtable_map              <type_delimiter>,  <type_delimiter>_map | ||||
| #define GENERIC_SLOT_<slot>__hashtable_map_mut          <type_delimiter>,  <type_delimiter>_map_mut | ||||
| #define GENERIC_SLOT_<slot>__hashtable_grow             <type_delimiter>*, <type_delimiter>_grow | ||||
| #define GENERIC_SLOT_<slot>__hashtable_rehash           <type_delimiter>*, <type_delimiter>_rehash | ||||
| #define GENERIC_SLOT_<slot>__hashtable_rehash_fast      <type_delimiter>,  <type_delimiter>_rehash_fast | ||||
| #define GENERIC_SLOT_<slot>__hashtable_remove_entry     <type_delimiter>,  <type_delimiter>_remove_entry | ||||
| #define GENERIC_SLOT_<slot>__hashtable_set              <type_delimiter>*, <type_delimiter>_set | ||||
| #define GENERIC_SLOT_<slot>__hashtable_slot             <type_delimiter>,  <type_delimiter>_slot | ||||
| 	Code generic_interface_slot = untyped_str(token_fmt( "type", type, "tbl_type", (StrC)tbl_type, "slot", (StrC)slot_str, | ||||
| R"(#define GENERIC_SLOT_<slot>__hashtable_init          <type>,      <tbl_type>_init | ||||
| #define GENERIC_SLOT_<slot>__hashtable_init_reserve     <type>,      <tbl_type>_init_reserve | ||||
| #define GENERIC_SLOT_<slot>__hashtable_clear            <tbl_type>,  <tbl_type>_clear | ||||
| #define GENERIC_SLOT_<slot>__hashtable_destroy          <tbl_type>*, <tbl_type>_destroy | ||||
| #define GENERIC_SLOT_<slot>__hashtable_get              <tbl_type>,  <tbl_type>_get | ||||
| #define GENERIC_SLOT_<slot>__hashtable_map              <tbl_type>,  <tbl_type>_map | ||||
| #define GENERIC_SLOT_<slot>__hashtable_map_mut          <tbl_type>,  <tbl_type>_map_mut | ||||
| #define GENERIC_SLOT_<slot>__hashtable_grow             <tbl_type>*, <tbl_type>_grow | ||||
| #define GENERIC_SLOT_<slot>__hashtable_rehash           <tbl_type>*, <tbl_type>_rehash | ||||
| #define GENERIC_SLOT_<slot>__hashtable_rehash_fast      <tbl_type>,  <tbl_type>_rehash_fast | ||||
| #define GENERIC_SLOT_<slot>__hashtable_remove_entry     <tbl_type>,  <tbl_type>_remove_entry | ||||
| #define GENERIC_SLOT_<slot>__hashtable_set              <tbl_type>*, <tbl_type>_set | ||||
| #define GENERIC_SLOT_<slot>__hashtable_slot             <tbl_type>,  <tbl_type>_slot | ||||
|  | ||||
| #define GENERIC_SLOT_<slot>__hashtable__add_entry       <type_delimiter>*, <type_delimiter>__add_entry | ||||
| #define GENERIC_SLOT_<slot>__hashtable__find            <type_delimiter>,  <type_delimiter>__find | ||||
| #define GENERIC_SLOT_<slot>__hashtable__full            <type_delimiter>,  <type_delimiter>__full | ||||
| #define GENERIC_SLOT_<slot>__hashtable__add_entry       <tbl_type>*, <tbl_type>__add_entry | ||||
| #define GENERIC_SLOT_<slot>__hashtable__find            <tbl_type>,  <tbl_type>__find | ||||
| #define GENERIC_SLOT_<slot>__hashtable__full            <tbl_type>,  <tbl_type>__full | ||||
| )" | ||||
| 	)); | ||||
|  | ||||
|   | ||||
| @@ -4,16 +4,20 @@ | ||||
| 	See Readme.md for more information from the project repository. | ||||
|  | ||||
| 	Public Address: | ||||
| 	https://github.com/Ed94/gencpp | ||||
|  | ||||
| 	This is a single header C-Library variant. | ||||
| 	Define GEN_IMPLEMENTATION before including this file in a single compilation unit. | ||||
|  | ||||
| 	! ----------------------------------------------------------------------- VERSION: v0.20-Alpha ! | ||||
| 	! ============================================================================================ ! | ||||
| 	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                 ! | ||||
| 	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL ! | ||||
| 	! ============================================================================================ ! | ||||
| 	https://github.com/Ed94/gencpp  ---------------------------------------------------------------. | ||||
| 	|   _____                               _____ _                       _      ___   __     __    | | ||||
| 	|  / ____)                             / ____} |                     | |   / ,__} /  |   /  |   | | ||||
| 	| | / ___  ___ _ __   ___ _ __  _ __  | {___ | l_ __ _  __ _, ___  __| |  | |    '-l |  '-l |   | | ||||
| 	| | |{_  \/ __\ '_ \ / __} '_ l| '_ l  \___ \| __/ _` |/ _` |/ __\/ _` |  | |      | |    | |   | | ||||
| 	| | l__j | ___/ | | | {__; ;_l } ;_l } ____} | l| (_} | {_| | ___j {_; |  | l___  _J l_  _J l_  | | ||||
| 	|  \_____|\___}_l |_|\___} .__/| .__/ {_____/ \__\__/_l\__. |\___/\__,_l   \____}{_____}{_____} | | ||||
| 	|                        | |   | |                      __} |                                   | | ||||
| 	|                        l_l   l_l                     {___/                                    | | ||||
| 	! ----------------------------------------------------------------------- VERSION: v0.20-Alpha  | | ||||
| 	! ============================================================================================= | | ||||
| 	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                  | | ||||
| 	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL  | | ||||
| 	! ============================================================================================= / | ||||
| */ | ||||
| #if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME) | ||||
| #	error Gen.hpp : GEN_TIME not defined | ||||
|   | ||||
| @@ -24,7 +24,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& par | ||||
| 	CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter); | ||||
| 	if ( cond->Content.is_equal(cond_sig) ) | ||||
| 	{ | ||||
| 		log_fmt("Preprocess cond found: %SC\n", cond->Content); | ||||
| 		//log_fmt("Preprocess cond found: %SC\n", cond->Content); | ||||
| 		found = true; | ||||
|  | ||||
| 		s32 depth = 1; | ||||
| @@ -105,7 +105,7 @@ R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \ | ||||
| 	for ( s32 slot = 1; slot <= num_slots; ++ slot ) | ||||
| 	{ | ||||
| 		StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", slot).to_strc(); | ||||
| 		if (slot == num_slots) | ||||
| 		if (slot == num_slots && false) | ||||
| 		{ | ||||
| 			define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str, | ||||
| R"(		GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST(  GENERIC_SLOT_<slot>__<macro_name> ) \ | ||||
| @@ -128,6 +128,8 @@ R"(		GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_<slot>__<macro_name> ) | ||||
| 		)); | ||||
| 	} | ||||
|  | ||||
| 	define_builder.append( txt("default: gen_generic_selection_fail") ); | ||||
|  | ||||
| 	if ( ! one_arg ) | ||||
| 	{ | ||||
| 		if (opts == GenericSel_By_Ref) | ||||
|   | ||||
| @@ -6,6 +6,18 @@ | ||||
| #include "gen/especifier.hpp" | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|   ______   ______  ________      __    __       ______                 __ | ||||
|  /      \ /      \|        \    |  \  |  \     /      \               |  \ | ||||
| |  ▓▓▓▓▓▓\  ▓▓▓▓▓▓\\▓▓▓▓▓▓▓▓    | ▓▓\ | ▓▓    |  ▓▓▓▓▓▓\ ______   ____| ▓▓ ______ | ||||
| | ▓▓__| ▓▓ ▓▓___\▓▓  | ▓▓       | ▓▓▓\| ▓▓    | ▓▓   \▓▓/      \ /      ▓▓/      \ | ||||
| | ▓▓    ▓▓\▓▓    \   | ▓▓       | ▓▓▓▓\ ▓▓    | ▓▓     |  ▓▓▓▓▓▓\  ▓▓▓▓▓▓▓  ▓▓▓▓▓▓\ | ||||
| | ▓▓▓▓▓▓▓▓_\▓▓▓▓▓▓\  | ▓▓       | ▓▓\▓▓ ▓▓    | ▓▓   __| ▓▓  | ▓▓ ▓▓  | ▓▓ ▓▓    ▓▓ | ||||
| | ▓▓  | ▓▓  \__| ▓▓  | ▓▓       | ▓▓ \▓▓▓▓    | ▓▓__/  \ ▓▓__/ ▓▓ ▓▓__| ▓▓ ▓▓▓▓▓▓▓▓ | ||||
| | ▓▓  | ▓▓\▓▓    ▓▓  | ▓▓       | ▓▓  \▓▓▓     \▓▓    ▓▓\▓▓    ▓▓\▓▓    ▓▓\▓▓     \ | ||||
|  \▓▓   \▓▓ \▓▓▓▓▓▓    \▓▓        \▓▓   \▓▓      \▓▓▓▓▓▓  \▓▓▓▓▓▓  \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ | ||||
| */ | ||||
|  | ||||
| struct AST; | ||||
| struct AST_Body; | ||||
| struct AST_Attributes; | ||||
| @@ -84,6 +96,7 @@ typedef AST* Code; | ||||
| #else | ||||
| struct Code; | ||||
| #endif | ||||
|  | ||||
| Define_Code(Body); | ||||
| // These are to offer ease of use and optionally strong type safety for the AST. | ||||
| Define_Code(Attributes); | ||||
| @@ -150,6 +163,7 @@ Define_Code(Typedef); | ||||
| Define_Code(Union); | ||||
| Define_Code(Using); | ||||
| Define_Code(Var); | ||||
|  | ||||
| #undef Define_Code | ||||
|  | ||||
| GEN_NS_PARSER_BEGIN | ||||
| @@ -172,6 +186,7 @@ template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( | ||||
| #endif | ||||
|  | ||||
| #pragma region Code C-Interface | ||||
|  | ||||
| void        code_append       (Code code, Code other ); | ||||
| char const* code_debug_str    (Code code); | ||||
| Code        code_duplicate    (Code code); | ||||
| @@ -185,6 +200,7 @@ 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 ); | ||||
|  | ||||
| #pragma endregion Code C-Interface | ||||
|  | ||||
| #if GEN_COMPILER_CPP | ||||
| @@ -298,10 +314,11 @@ constexpr static | ||||
| int AST_ArrSpecs_Cap = | ||||
| ( | ||||
| 		AST_POD_Size | ||||
| 		- sizeof(Code) | ||||
| 		- sizeof(StringCached) | ||||
| 		- sizeof(AST*) * 3 | ||||
| 		- sizeof(Code) * 2 | ||||
| 		- sizeof(Token*) | ||||
| 		- sizeof(AST*) | ||||
| 		- sizeof(Code) | ||||
| 		- sizeof(CodeType) | ||||
| 		- sizeof(ModuleFlag) | ||||
| 		- sizeof(u32) | ||||
|   | ||||
| @@ -4,6 +4,22 @@ | ||||
| #endif | ||||
|  | ||||
| #pragma region AST Types | ||||
|  | ||||
| /* | ||||
|   ______   ______  ________      ________ | ||||
|  /      \ /      \|        \    |        \ | ||||
| |  ▓▓▓▓▓▓\  ▓▓▓▓▓▓\\▓▓▓▓▓▓▓▓     \▓▓▓▓▓▓▓▓__    __  ______   ______   _______ | ||||
| | ▓▓__| ▓▓ ▓▓___\▓▓  | ▓▓          | ▓▓  |  \  |  \/      \ /      \ /       \ | ||||
| | ▓▓    ▓▓\▓▓    \   | ▓▓          | ▓▓  | ▓▓  | ▓▓  ▓▓▓▓▓▓\  ▓▓▓▓▓▓\  ▓▓▓▓▓▓▓ | ||||
| | ▓▓▓▓▓▓▓▓_\▓▓▓▓▓▓\  | ▓▓          | ▓▓  | ▓▓  | ▓▓ ▓▓  | ▓▓ ▓▓    ▓▓\▓▓    \ | ||||
| | ▓▓  | ▓▓  \__| ▓▓  | ▓▓          | ▓▓  | ▓▓__/ ▓▓ ▓▓__/ ▓▓ ▓▓▓▓▓▓▓▓_\▓▓▓▓▓▓\ | ||||
| | ▓▓  | ▓▓\▓▓    ▓▓  | ▓▓          | ▓▓   \▓▓    ▓▓ ▓▓    ▓▓\▓▓     \       ▓▓ | ||||
|  \▓▓   \▓▓ \▓▓▓▓▓▓    \▓▓           \▓▓   _\▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓  \▓▓▓▓▓▓▓\▓▓▓▓▓▓▓ | ||||
|                                          |  \__| ▓▓ ▓▓ | ||||
|                                           \▓▓    ▓▓ ▓▓ | ||||
|                                            \▓▓▓▓▓▓ \▓▓ | ||||
| */ | ||||
|  | ||||
| /* | ||||
| 	Show only relevant members of the AST for its type. | ||||
| 	AST* fields are replaced with Code types. | ||||
| @@ -12,7 +28,9 @@ | ||||
|  | ||||
| struct AST_Body | ||||
| { | ||||
| 	char              _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; | ||||
| 	union { | ||||
| 		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; | ||||
| 	}; | ||||
| 	StringCached      Name; | ||||
| 	Code              Front; | ||||
| 	Code              Back; | ||||
| @@ -550,7 +568,9 @@ static_assert( sizeof(AST_Fn) == sizeof(AST), "ERROR: AST_Fn is not the same siz | ||||
|  | ||||
| struct AST_Module | ||||
| { | ||||
| 	char              _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; | ||||
| 	union { | ||||
| 		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; | ||||
| 	}; | ||||
| 	StringCached      Name; | ||||
| 	Code              Prev; | ||||
| 	Code              Next; | ||||
| @@ -693,7 +713,7 @@ static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_Preprocess | ||||
|  | ||||
| struct AST_Specifiers | ||||
| { | ||||
| 	Specifier        ArrSpecs[ AST_ArrSpecs_Cap ]; | ||||
| 	Specifier         ArrSpecs[ AST_ArrSpecs_Cap ]; | ||||
| 	StringCached      Name; | ||||
| 	CodeSpecifiers    NextSpecs; | ||||
| 	Code              Prev; | ||||
|   | ||||
| @@ -3,7 +3,20 @@ | ||||
| #include "ast.hpp" | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|   ______                 __               ______            __                        ______ | ||||
|  /      \               |  \             |      \          |  \                      /      \ | ||||
| |  ▓▓▓▓▓▓\ ______   ____| ▓▓ ______       \▓▓▓▓▓▓_______  _| ▓▓_    ______   ______ |  ▓▓▓▓▓▓\ ______   _______  ______ | ||||
| | ▓▓   \▓▓/      \ /      ▓▓/      \       | ▓▓ |       \|   ▓▓ \  /      \ /      \| ▓▓_  \▓▓|      \ /       \/      \ | ||||
| | ▓▓     |  ▓▓▓▓▓▓\  ▓▓▓▓▓▓▓  ▓▓▓▓▓▓\      | ▓▓ | ▓▓▓▓▓▓▓\\▓▓▓▓▓▓ |  ▓▓▓▓▓▓\  ▓▓▓▓▓▓\ ▓▓ \     \▓▓▓▓▓▓\  ▓▓▓▓▓▓▓  ▓▓▓▓▓▓\ | ||||
| | ▓▓   __| ▓▓  | ▓▓ ▓▓  | ▓▓ ▓▓    ▓▓      | ▓▓ | ▓▓  | ▓▓ | ▓▓ __| ▓▓    ▓▓ ▓▓   \▓▓ ▓▓▓▓    /      ▓▓ ▓▓     | ▓▓    ▓▓ | ||||
| | ▓▓__/  \ ▓▓__/ ▓▓ ▓▓__| ▓▓ ▓▓▓▓▓▓▓▓     _| ▓▓_| ▓▓  | ▓▓ | ▓▓|  \ ▓▓▓▓▓▓▓▓ ▓▓     | ▓▓     |  ▓▓▓▓▓▓▓ ▓▓_____| ▓▓▓▓▓▓▓▓ | ||||
|  \▓▓    ▓▓\▓▓    ▓▓\▓▓    ▓▓\▓▓     \    |   ▓▓ \ ▓▓  | ▓▓  \▓▓  ▓▓\▓▓     \ ▓▓     | ▓▓      \▓▓    ▓▓\▓▓     \\▓▓     \ | ||||
|   \▓▓▓▓▓▓  \▓▓▓▓▓▓  \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓     \▓▓▓▓▓▓\▓▓   \▓▓   \▓▓▓▓  \▓▓▓▓▓▓▓\▓▓      \▓▓       \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ | ||||
| */ | ||||
|  | ||||
| #pragma region Code Type C-Interface | ||||
|  | ||||
| void   body_append          ( CodeBody body, Code     other ); | ||||
| void   body_append_body     ( CodeBody body, CodeBody other ); | ||||
| String body_to_string       ( CodeBody body ); | ||||
| @@ -14,7 +27,7 @@ Code begin_CodeBody( CodeBody body); | ||||
| Code end_CodeBody  ( CodeBody body ); | ||||
| Code next_CodeBody ( CodeBody body, Code entry_iter ); | ||||
|  | ||||
| void   class_add_interface( CodeClass self, CodeType interface ); | ||||
| void   class_add_interface( CodeClass self, CodeTypename interface ); | ||||
| String class_to_string    ( CodeClass self ); | ||||
| void   class_to_string_def( CodeClass self, String* result ); | ||||
| void   class_to_string_fwd( CodeClass self, String* result ); | ||||
| @@ -39,7 +52,7 @@ Specifier* begin_CodeSpecifiers(CodeSpecifiers specifiers); | ||||
| Specifier* end_CodeSpecifiers  (CodeSpecifiers specifiers); | ||||
| Specifier* next_CodeSpecifiers (CodeSpecifiers specifiers, Specifier* spec_iter); | ||||
|  | ||||
| void   struct_add_interface(CodeStruct self, CodeType interface); | ||||
| void   struct_add_interface(CodeStruct self, CodeTypename interface); | ||||
| String struct_to_string    (CodeStruct self); | ||||
| void   struct_to_string_fwd(CodeStruct self, String* result); | ||||
| void   struct_to_string_def(CodeStruct self, String* result); | ||||
| @@ -126,6 +139,7 @@ void   using_to_string_ns (CodeUsing op_cast, String* result ); | ||||
|  | ||||
| String var_to_string    (CodeVar self); | ||||
| void   var_to_string_ref(CodeVar self, String* result); | ||||
|  | ||||
| #pragma endregion Code Type C-Interface | ||||
|  | ||||
| #if GEN_COMPILER_CPP | ||||
| @@ -214,24 +228,6 @@ struct CodeSpecifiers | ||||
| 	AST_Specifiers* ast; | ||||
| }; | ||||
|  | ||||
| struct CodeStruct | ||||
| { | ||||
| #if ! GEN_C_LIKE_CPP | ||||
| 	Using_Code( CodeStruct ); | ||||
| 	forceinline void add_interface( CodeType interface ) { return struct_add_interface(* this, interface); } | ||||
| 	forceinline String to_string()                       { return struct_to_string(* this); } | ||||
| 	forceinline void   to_string_fwd( String& result )   { return struct_to_string_fwd(* this, & result); } | ||||
| 	forceinline void   to_string_def( String& result )   { return struct_to_string_def(* this, & result); } | ||||
| #endif | ||||
| 	Using_CodeOps( CodeStruct ); | ||||
| 	forceinline operator Code() { return * rcast( Code*, this ); } | ||||
| 	forceinline AST_Struct* operator->() { | ||||
| 		GEN_ASSERT(ast); | ||||
| 		return ast; | ||||
| 	} | ||||
| 	AST_Struct* ast; | ||||
| }; | ||||
|  | ||||
| struct CodeAttributes | ||||
| { | ||||
| #if ! GEN_C_LIKE_CPP | ||||
| @@ -907,6 +903,24 @@ struct CodeVar | ||||
| 	AST_Var* ast; | ||||
| }; | ||||
|  | ||||
| struct CodeStruct | ||||
| { | ||||
| #if ! GEN_C_LIKE_CPP | ||||
| 	Using_Code( CodeStruct ); | ||||
| 	forceinline void   add_interface( CodeTypename interface ) { return struct_add_interface(* this, interface); } | ||||
| 	forceinline String to_string()                             { return struct_to_string(* this); } | ||||
| 	forceinline void   to_string_fwd( String& result )         { return struct_to_string_fwd(* this, & result); } | ||||
| 	forceinline void   to_string_def( String& result )         { return struct_to_string_def(* this, & result); } | ||||
| #endif | ||||
| 	Using_CodeOps( CodeStruct ); | ||||
| 	forceinline operator Code() { return * rcast( Code*, this ); } | ||||
| 	forceinline AST_Struct* operator->() { | ||||
| 		GEN_ASSERT(ast); | ||||
| 		return ast; | ||||
| 	} | ||||
| 	AST_Struct* ast; | ||||
| }; | ||||
|  | ||||
| #undef Define_CodeType | ||||
| #undef Using_Code | ||||
| #undef Using_CodeOps | ||||
| @@ -982,6 +996,7 @@ struct NullCode_ImplicitCaster | ||||
|  | ||||
| #if ! GEN_C_LIKE_CPP | ||||
| GEN_OPTIMIZE_MAPPINGS_BEGIN | ||||
|  | ||||
| forceinline void   append          ( CodeBody body, Code     other ) { return body_append(body, other); } | ||||
| forceinline void   append          ( CodeBody body, CodeBody other ) { return body_append_body(body, other); } | ||||
| forceinline String to_string       ( CodeBody body )                 { return body_to_string(body); } | ||||
| @@ -992,7 +1007,7 @@ forceinline Code begin( CodeBody body)                   { return begin_CodeBody | ||||
| forceinline Code end  ( CodeBody body )                  { return end_CodeBody(body); } | ||||
| forceinline Code next ( CodeBody body, Code entry_iter ) { return next_CodeBody(body, entry_iter); } | ||||
|  | ||||
| forceinline void   add_interface( CodeClass self, CodeType interface ) { return class_add_interface(self, interface); } | ||||
| forceinline void   add_interface( CodeClass self, CodeTypename interface ) { return class_add_interface(self, interface); } | ||||
| forceinline String to_string    ( CodeClass self )                     { return class_to_string(self); } | ||||
| forceinline void   to_string_def( CodeClass self, String& result )     { return class_to_string_def(self, & result); } | ||||
| forceinline void   to_string_fwd( CodeClass self, String& result )     { return class_to_string_fwd(self, & result); } | ||||
| @@ -1017,10 +1032,10 @@ forceinline Specifier* begin(CodeSpecifiers specifiers)                       { | ||||
| forceinline Specifier* end  (CodeSpecifiers specifiers)                       { return end_CodeSpecifiers(specifiers); } | ||||
| forceinline Specifier* next (CodeSpecifiers specifiers, Specifier& spec_iter) { return next_CodeSpecifiers(specifiers, & spec_iter); } | ||||
|  | ||||
| forceinline void   add_interface(CodeStruct self, CodeType interface) { return struct_add_interface(self, interface); } | ||||
| forceinline String to_string    (CodeStruct self)                     { return struct_to_string(self); } | ||||
| forceinline void   to_string_fwd(CodeStruct self, String& result)     { return struct_to_string_fwd(self, & result); } | ||||
| forceinline void   to_string_def(CodeStruct self, String& result)     { return struct_to_string_def(self, & result); } | ||||
| forceinline void   add_interface(CodeStruct self, CodeTypename interface) { return struct_add_interface(self, interface); } | ||||
| forceinline String to_string    (CodeStruct self)                         { return struct_to_string(self); } | ||||
| forceinline void   to_string_fwd(CodeStruct self, String& result)         { return struct_to_string_fwd(self, & result); } | ||||
| forceinline void   to_string_def(CodeStruct self, String& result)         { return struct_to_string_def(self, & result); } | ||||
|  | ||||
| forceinline String to_string(CodeAttributes attributes)                 { return attributes_to_string(attributes); } | ||||
| forceinline void   to_string(CodeAttributes attributes, String& result) { return attributes_to_string_ref(attributes, & result); } | ||||
| @@ -1104,6 +1119,7 @@ forceinline void   to_string_ns(CodeUsing op_cast, String& result ) { return usi | ||||
|  | ||||
| forceinline String to_string(CodeVar self)                 { return var_to_string(self); } | ||||
| forceinline void   to_string(CodeVar self, String& result) { return var_to_string_ref(self, & result); } | ||||
|  | ||||
| GEN_OPITMIZE_MAPPINGS_END | ||||
| #endif //if GEN_C_LIKE_CPP | ||||
|  | ||||
|   | ||||
| @@ -68,7 +68,8 @@ enum CodeType : u32 | ||||
| 	CT_Using, | ||||
| 	CT_Using_Namespace, | ||||
| 	CT_Variable, | ||||
| 	CT_NumTypes | ||||
| 	CT_NumTypes, | ||||
| 	CT_UnderlyingType = GEN_U32_MAX | ||||
| }; | ||||
|  | ||||
| inline StrC codetype_to_str( CodeType type ) | ||||
|   | ||||
| @@ -54,7 +54,8 @@ enum Operator : u32 | ||||
| 	Op_NewArray, | ||||
| 	Op_Delete, | ||||
| 	Op_DeleteArray, | ||||
| 	NumOps | ||||
| 	Op_NumOps, | ||||
| 	Op_UnderlyingType = 0xffffffffu | ||||
| }; | ||||
|  | ||||
| inline StrC operator_to_str( Operator op ) | ||||
|   | ||||
| @@ -33,7 +33,8 @@ enum Specifier : u32 | ||||
| 	Spec_Override, | ||||
| 	Spec_Pure, | ||||
| 	Spec_Volatile, | ||||
| 	Spec_NumSpecifiers | ||||
| 	Spec_NumSpecifiers, | ||||
| 	Spec_UnderlyingType = 0xffffffffu | ||||
| }; | ||||
|  | ||||
| inline StrC spec_to_str( Specifier type ) | ||||
|   | ||||
| @@ -6,13 +6,20 @@ | ||||
| 	See Readme.md for more information from the project repository. | ||||
|  | ||||
| 	Public Address: | ||||
| 	https://github.com/Ed94/gencpp | ||||
|  | ||||
| 	! ----------------------------------------------------------------------- VERSION: v0.20-Alpha ! | ||||
| 	! ============================================================================================ ! | ||||
| 	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                 ! | ||||
| 	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL ! | ||||
| 	! ============================================================================================ ! | ||||
| 	https://github.com/Ed94/gencpp  --------------------------------------------------------------. | ||||
| 	|   _____                               _____ _                       _                        | | ||||
| 	|  / ____)                             / ____} |                     | |                       | | ||||
| 	| | / ___  ___ _ __   ___ _ __  _ __  | {___ | |__ _ _, __ _, ___  __| |                       | | ||||
| 	| | |{_  |/ _ \ '_ \ / __} '_ l| '_ l `\___ \| __/ _` |/ _` |/ _ \/ _` |                       | | ||||
| 	| | l__j | ___/ | | | {__; |+l } |+l | ____) | l| (_| | {_| | ___/ (_| |                       | | ||||
| 	|  \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l                       | | ||||
| 	|                        | |   | |                      __} |                                  | | ||||
| 	|                        l_l   l_l                     {___/                                   | | ||||
| 	! ----------------------------------------------------------------------- VERSION: v0.20-Alpha | | ||||
| 	! ============================================================================================ | | ||||
| 	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                 | | ||||
| 	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL | | ||||
| 	! ============================================================================================ / | ||||
| */ | ||||
| #if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME) | ||||
| #	error Gen.hpp : GEN_TIME not defined | ||||
|   | ||||
| @@ -104,7 +104,7 @@ forceinline | ||||
| char const* code_type_str(Code self) | ||||
| { | ||||
| 	GEN_ASSERT(self != nullptr); | ||||
| 	return codetype_to_str( self->Type ); | ||||
| 	return codetype_to_str( self->Type ).Ptr; | ||||
| } | ||||
| #pragma endregion Code | ||||
|  | ||||
| @@ -138,7 +138,8 @@ Code begin_CodeBody( CodeBody body) { | ||||
| 	GEN_ASSERT(body); | ||||
| 	if ( body != nullptr ) | ||||
| 		return body->Front; | ||||
| 	return { nullptr }; | ||||
|  | ||||
| 	return NullCode; | ||||
| } | ||||
| forceinline | ||||
| Code end_CodeBody(CodeBody body ){ | ||||
| @@ -170,7 +171,7 @@ void class_add_interface( CodeClass self, CodeTypename type ) | ||||
|  | ||||
| 	while ( possible_slot != nullptr ) | ||||
| 	{ | ||||
| 		possible_slot = possible_slot->Next; | ||||
| 		possible_slot = cast(CodeTypename, possible_slot->Next); | ||||
| 	} | ||||
|  | ||||
| 	possible_slot = type; | ||||
| @@ -212,7 +213,7 @@ CodeParam params_get(CodeParam self, s32 idx ) | ||||
| 	do | ||||
| 	{ | ||||
| 		if ( ++ param != nullptr ) | ||||
| 			return { nullptr }; | ||||
| 			return NullCode; | ||||
|  | ||||
| 		param = cast(CodeParam, cast(Code, param)->Next); | ||||
| 	} | ||||
| @@ -246,7 +247,7 @@ forceinline | ||||
| CodeParam end_CodeParam(CodeParam params) | ||||
| { | ||||
| 	// return { (AST_Param*) rcast( AST*, ast)->Last }; | ||||
| 	return { nullptr }; | ||||
| 	return NullCode; | ||||
| } | ||||
| forceinline | ||||
| CodeParam next_CodeParam(CodeParam params, CodeParam param_iter) | ||||
| @@ -347,7 +348,7 @@ Specifier* next_CodeSpecifiers(CodeSpecifiers self, Specifier* spec_iter) | ||||
|  | ||||
| #pragma region CodeStruct | ||||
| inline | ||||
| void add_interface(CodeStruct self, CodeTypename type ) | ||||
| void struct_add_interface(CodeStruct self, CodeTypename type ) | ||||
| { | ||||
| 	CodeTypename possible_slot = self->ParentType; | ||||
| 	if ( possible_slot != nullptr ) | ||||
| @@ -360,7 +361,7 @@ void add_interface(CodeStruct self, CodeTypename type ) | ||||
|  | ||||
| 	while ( possible_slot != nullptr ) | ||||
| 	{ | ||||
| 		possible_slot = possible_slot->Next; | ||||
| 		possible_slot = cast(CodeTypename, possible_slot->Next); | ||||
| 	} | ||||
|  | ||||
| 	possible_slot = type; | ||||
| @@ -385,7 +386,7 @@ CodeBody def_body( CodeType type ) | ||||
| 			break; | ||||
|  | ||||
| 		default: | ||||
| 			log_failure( "def_body: Invalid type %s", (char const*)codetype_to_str(type) ); | ||||
| 			log_failure( "def_body: Invalid type %s", codetype_to_str(type).Ptr ); | ||||
| 			return (CodeBody)Code_Invalid; | ||||
| 	} | ||||
|  | ||||
| @@ -407,6 +408,7 @@ StrC token_fmt_impl( ssize num, ... ) | ||||
| 	ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va); | ||||
| 	va_end(va); | ||||
|  | ||||
| 	return { result, buf }; | ||||
| 	StrC str = { result, buf }; | ||||
| 	return str; | ||||
| } | ||||
| #pragma endregion Interface | ||||
|   | ||||
| @@ -4,6 +4,16 @@ | ||||
| #endif | ||||
|  | ||||
| #pragma region Gen Interface | ||||
| /* | ||||
|  /      \                       |      \          |  \                      /      \ | ||||
| |  ▓▓▓▓▓▓\ ______  _______       \▓▓▓▓▓▓_______  _| ▓▓_    ______   ______ |  ▓▓▓▓▓▓\ ______   _______  ______ | ||||
| | ▓▓ __\▓▓/      \|       \       | ▓▓ |       \|   ▓▓ \  /      \ /      \| ▓▓_  \▓▓|      \ /       \/      \ | ||||
| | ▓▓|    \  ▓▓▓▓▓▓\ ▓▓▓▓▓▓▓\      | ▓▓ | ▓▓▓▓▓▓▓\\▓▓▓▓▓▓ |  ▓▓▓▓▓▓\  ▓▓▓▓▓▓\ ▓▓ \     \▓▓▓▓▓▓\  ▓▓▓▓▓▓▓  ▓▓▓▓▓▓\ | ||||
| | ▓▓ \▓▓▓▓ ▓▓    ▓▓ ▓▓  | ▓▓      | ▓▓ | ▓▓  | ▓▓ | ▓▓ __| ▓▓    ▓▓ ▓▓   \▓▓ ▓▓▓▓    /      ▓▓ ▓▓     | ▓▓    ▓▓ | ||||
| | ▓▓__| ▓▓ ▓▓▓▓▓▓▓▓ ▓▓  | ▓▓     _| ▓▓_| ▓▓  | ▓▓ | ▓▓|  \ ▓▓▓▓▓▓▓▓ ▓▓     | ▓▓     |  ▓▓▓▓▓▓▓ ▓▓_____| ▓▓▓▓▓▓▓▓ | ||||
|  \▓▓    ▓▓\▓▓     \ ▓▓  | ▓▓    |   ▓▓ \ ▓▓  | ▓▓  \▓▓  ▓▓\▓▓     \ ▓▓     | ▓▓      \▓▓    ▓▓\▓▓     \\▓▓     \ | ||||
|   \▓▓▓▓▓▓  \▓▓▓▓▓▓▓\▓▓   \▓▓     \▓▓▓▓▓▓\▓▓   \▓▓   \▓▓▓▓  \▓▓▓▓▓▓▓\▓▓      \▓▓       \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ | ||||
| */ | ||||
|  | ||||
| // Initialize the library. | ||||
| // This currently just initializes the CodePool. | ||||
| @@ -164,7 +174,7 @@ struct Opts_def_variable | ||||
| CodeVar def_variable( CodeTypename type, StrC name, Opts_def_variable opts GEN_PARAM_DEFAULT ); | ||||
|  | ||||
| // Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries. | ||||
| CodeBody def_body( CodeTypename type ); | ||||
| CodeBody def_body( CodeType type ); | ||||
|  | ||||
| // There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num, | ||||
| /// or provide as an array of Code objects. | ||||
| @@ -199,23 +209,23 @@ CodeBody       def_union_body      ( s32 num, Code* codes ); | ||||
| // TODO(Ed) : Implmeent the new parser API design. | ||||
|  | ||||
| #if 0 | ||||
| namespace parser { | ||||
| 	struct StackNode | ||||
| 	{ | ||||
| 		StackNode* Prev; | ||||
| GEN_NS_PARSER_BEGIN | ||||
| struct StackNode | ||||
| { | ||||
| 	StackNode* Prev; | ||||
|  | ||||
| 		Token Start; | ||||
| 		Token Name;       // The name of the AST node (if parsed) | ||||
| 		StrC  FailedProc; // The name of the procedure that failed | ||||
| 	}; | ||||
| 	// Stack nodes are allocated the error's allocator | ||||
| 	Token Start; | ||||
| 	Token Name;       // The name of the AST node (if parsed) | ||||
| 	StrC  FailedProc; // The name of the procedure that failed | ||||
| }; | ||||
| // Stack nodes are allocated the error's allocator | ||||
|  | ||||
| 	struct Error | ||||
| 	{ | ||||
| 		String     message; | ||||
| 		StackNode* context_stack; | ||||
| 	}; | ||||
| } | ||||
| struct Error | ||||
| { | ||||
| 	String     message; | ||||
| 	StackNode* context_stack; | ||||
| }; | ||||
| GEN_NS_PARSER_END | ||||
|  | ||||
| struct ParseInfo | ||||
| { | ||||
| @@ -223,9 +233,9 @@ struct ParseInfo | ||||
| 	Arena TokMem; | ||||
| 	Arena CodeMem; | ||||
|  | ||||
| 	FileContents         FileContent; | ||||
| 	Array<parser::Token> Tokens; | ||||
| 	Array<parser::Error> Errors; | ||||
| 	FileContents FileContent; | ||||
| 	Array<Token> Tokens; | ||||
| 	Array<Error> Errors; | ||||
| 	// Errors are allocated to a dedicated general arena. | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1224,7 +1224,7 @@ CodeStruct def_struct( StrC name, Opts_def_struct p ) | ||||
| 	{ | ||||
| 		for (s32 idx = 0; idx < num_interfaces; idx++ ) | ||||
| 		{ | ||||
| 			add_interface(result, interfaces[idx] ); | ||||
| 			struct_add_interface(result, interfaces[idx] ); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -3010,15 +3010,21 @@ Code parse_simple_preprocess( TokType which, bool dont_consume_braces ) | ||||
| 				eat( Tok_Statement_End ); | ||||
| 				// <Macro>; | ||||
|  | ||||
| 				tok.Length += prevtok.Length; | ||||
|  | ||||
| 				// TODO(Ed): Reveiw the context for this? (ESPECIALLY THIS) | ||||
| 				if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line ) | ||||
| 				{ | ||||
| 					eat( Tok_Comment ); | ||||
| 					// <Macro>; <InlineCmt> | ||||
|  | ||||
| 					tok.Length += prevtok.Length; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		else if ( | ||||
| 				strc_contains(calling_proc, txt("parse_global_nspace")) | ||||
| 			&&	strc_contains(calling_proc, txt("parse_class_struct_body")) | ||||
| 			||	strc_contains(calling_proc, txt("parse_class_struct_body")) | ||||
| 		) | ||||
| 		{ | ||||
| 			if (peektok.Type == Tok_Statement_End) | ||||
| @@ -3026,10 +3032,11 @@ Code parse_simple_preprocess( TokType which, bool dont_consume_braces ) | ||||
| 				Token stmt_end = currtok; | ||||
| 				eat( Tok_Statement_End ); | ||||
| 				// <Macro>; | ||||
| 				tok.Length += prevtok.Length; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		tok.Length = ( (sptr)currtok_noskip.Text + currtok_noskip.Length ) - (sptr)tok.Text; | ||||
| 		} | ||||
| 		// tok.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)tok.Text; | ||||
| 	} | ||||
|  | ||||
| Leave_Scope_Early: | ||||
|   | ||||
| @@ -3,6 +3,22 @@ | ||||
| #include "header_start.hpp" | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  ________                                              __    __      ________ | ||||
| |        \                                            |  \  |  \    |        \ | ||||
| | ▓▓▓▓▓▓▓▓_______  __    __ ______ ____   _______     | ▓▓\ | ▓▓     \▓▓▓▓▓▓▓▓__    __  ______   ______   _______ | ||||
| | ▓▓__   |       \|  \  |  \      \    \ /       \    | ▓▓▓\| ▓▓       | ▓▓  |  \  |  \/      \ /      \ /       \ | ||||
| | ▓▓  \  | ▓▓▓▓▓▓▓\ ▓▓  | ▓▓ ▓▓▓▓▓▓\▓▓▓▓\  ▓▓▓▓▓▓▓    | ▓▓▓▓\ ▓▓       | ▓▓  | ▓▓  | ▓▓  ▓▓▓▓▓▓\  ▓▓▓▓▓▓\  ▓▓▓▓▓▓▓ | ||||
| | ▓▓▓▓▓  | ▓▓  | ▓▓ ▓▓  | ▓▓ ▓▓ | ▓▓ | ▓▓\▓▓    \     | ▓▓\▓▓ ▓▓       | ▓▓  | ▓▓  | ▓▓ ▓▓  | ▓▓ ▓▓    ▓▓\▓▓    \ | ||||
| | ▓▓_____| ▓▓  | ▓▓ ▓▓__/ ▓▓ ▓▓ | ▓▓ | ▓▓_\▓▓▓▓▓▓\    | ▓▓ \▓▓▓▓       | ▓▓  | ▓▓__/ ▓▓ ▓▓__/ ▓▓ ▓▓▓▓▓▓▓▓_\▓▓▓▓▓▓\ | ||||
| | ▓▓     \ ▓▓  | ▓▓\▓▓    ▓▓ ▓▓ | ▓▓ | ▓▓       ▓▓    | ▓▓  \▓▓▓       | ▓▓   \▓▓    ▓▓ ▓▓    ▓▓\▓▓     \       ▓▓ | ||||
|  \▓▓▓▓▓▓▓▓\▓▓   \▓▓ \▓▓▓▓▓▓ \▓▓  \▓▓  \▓▓\▓▓▓▓▓▓▓      \▓▓   \▓▓        \▓▓   _\▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓  \▓▓▓▓▓▓▓\▓▓▓▓▓▓▓ | ||||
|                                                                              |  \__| ▓▓ ▓▓ | ||||
|                                                                               \▓▓    ▓▓ ▓▓ | ||||
|                                                                                \▓▓▓▓▓▓ \▓▓ | ||||
|  | ||||
| */ | ||||
|  | ||||
| using LogFailType = ssize(*)(char const*, ...); | ||||
|  | ||||
| // By default this library will either crash or exit if an error is detected while generating codes. | ||||
|   | ||||
| @@ -459,6 +459,7 @@ FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| typedef struct _memory_fd _memory_fd; | ||||
| struct _memory_fd | ||||
| { | ||||
| 	u8            magic; | ||||
| @@ -505,7 +506,7 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator ) | ||||
| 	d->allocator = allocator; | ||||
| 	d->flags     = EFileStream_CLONE_WRITABLE; | ||||
| 	d->cap       = 0; | ||||
| 	d->buf       = array_init<u8>( allocator ); | ||||
| 	d->buf       = array_init( u8, allocator ); | ||||
|  | ||||
| 	if ( ! d->buf ) | ||||
| 		return false; | ||||
| @@ -531,7 +532,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize | ||||
| 	d->flags     = flags; | ||||
| 	if ( d->flags & EFileStream_CLONE_WRITABLE ) | ||||
| 	{ | ||||
| 		Array<u8> arr = array_init_reserve<u8>( allocator, size ); | ||||
| 		Array(u8) arr = array_init_reserve(u8, allocator, size ); | ||||
| 		d->buf = arr; | ||||
|  | ||||
| 		if ( ! d->buf ) | ||||
| @@ -608,9 +609,9 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write ) | ||||
|  | ||||
| 	if ( d->flags & EFileStream_CLONE_WRITABLE ) | ||||
| 	{ | ||||
| 		Array<u8> arr = { d->buf }; | ||||
| 		Array(u8) arr = { d->buf }; | ||||
|  | ||||
| 		if ( array_get_header(arr)->Capacity < usize(new_cap) ) | ||||
| 		if ( array_get_header(arr)->Capacity < scast(usize, new_cap) ) | ||||
| 		{ | ||||
| 			if ( ! array_grow( & arr, ( s64 )( new_cap ) ) ) | ||||
| 				return false; | ||||
| @@ -622,7 +623,7 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write ) | ||||
|  | ||||
| 	if ( ( d->flags & EFileStream_CLONE_WRITABLE ) && extralen > 0 ) | ||||
| 	{ | ||||
| 		Array<u8> arr = { d->buf }; | ||||
| 		Array(u8) arr = { d->buf }; | ||||
|  | ||||
| 		mem_copy( d->buf + offset + rwlen, pointer_add_const( buffer, rwlen ), extralen ); | ||||
| 		d->cap = new_cap; | ||||
| @@ -646,7 +647,7 @@ GEN_FILE_CLOSE_PROC( _memory_file_close ) | ||||
|  | ||||
| 	if ( d->flags & EFileStream_CLONE_WRITABLE ) | ||||
| 	{ | ||||
| 		Array<u8> arr = { d->buf }; | ||||
| 		Array(u8) arr = { d->buf }; | ||||
| 		array_free(arr); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -284,14 +284,15 @@ | ||||
| #endif | ||||
|  | ||||
| #if GEN_COMPILER_C | ||||
| // ------------------------ _Generic function overloading ----------------------------------------- | ||||
| // This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in: | ||||
| // https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md | ||||
| // Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unopaque as possible. | ||||
| // Extensive effort was put in below to make this as easy as possible to understand what is going on with this mess of a preoprocessor. | ||||
|  | ||||
| // Where the signature would be defined using: | ||||
| #define GEN_TYPE_TO_EXP(type) (* (type*)NULL) | ||||
| //   ____                       _        ______                _   _                ____                  _                 __ _ | ||||
| //  / ___}                     (_)      |  ____}              | | (_)              / __ \                | |               | |(_) | ||||
| // | | ___  ___ _ __   ___ _ __ _  ___  | |__ _   _ _ __   ___| |_ _  ___  _ __   | |  | |_   _____ _ __ | | ___   __ _  __| | _ _ __   __ _ | ||||
| // | |{__ |/ _ \ '_ \ / _ \ '__} |/ __| |  __} | | | '_ \ / __} __} |/ _ \| '_ \  | |  | \ \ / / _ \ '_ \| |/ _ \ / _` |/ _` || | '_ \ / _` | | ||||
| // | |__j |  __/ | | |  __/ |  | | (__  | |  | |_| | | | | (__| l_| | (_) | | | | | l__| |\ V /  __/ | | | | (_) | (_| | (_| || | | | | (_| | | ||||
| //  \____/ \___}_l l_l\___}_l  l_l\___| l_l   \__,_l_l l_l\___}\__}_l\___/l_l l_l  \____/  \_/ \___}_l l_l_l\___/ \__,_l\__,_l|_|_| |_|\__, | | ||||
| // This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in:                                            __| | | ||||
| // https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md                            {___/ | ||||
| // Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unobfuscated as possible. | ||||
|  | ||||
| #define GEN_COMMA_OPERATOR , // The comma operator is used by preprocessor macros to delimit arguments, so we have to represent it via a macro to prevent parsing incorrectly. | ||||
|  | ||||
| @@ -314,25 +315,23 @@ | ||||
| #define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ) GEN_COMMA_OPERATOR, , ) | ||||
| //                                                          ^ Selects the comma                              ^ is the type                             ^ is the function                             ^ Insert a comma | ||||
| // The slot won't exist if that comma is not found.                                                                                                                                                  | | ||||
| //                                                                                                                                                                                                   | | ||||
| // This  is the same as above but it does not insert a comma                                                                                                                                         V no comma here. | ||||
| #define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ), , ) | ||||
| // Needed for the last slot as they don't allow trailing commas. | ||||
|  | ||||
| // For the occastion where an expression didn't resolve to a selection option the "default: <value>" wilbe set to: | ||||
| struct NO_RESOLVED_GENERIC_SELECTION { | ||||
| 	unsigned long long failure; | ||||
| }; | ||||
| struct NO_RESOLVED_GENERIC_SELECTION const gen_generic_selection_fail = {}; | ||||
| // Which will provide the message:  error: called object type 'struct NO_RESOLVED_GENERIC_SELECTION' is not a function or function pointer | ||||
| // ---------------------------------------------------------------------------------------------------------------------------------- | ||||
|  | ||||
| // Below are generated on demand for an overlaod depdendent on a type: | ||||
| // ---------------------------------------------------------------------------------------------------------------------------------- | ||||
| #define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic(           \ | ||||
| (selector_arg), /* Select Via Expression*/                               \ | ||||
|   /* Extendibility slots: */                                             \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )     \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )     \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )     \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )     \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )     \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )     \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )     \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST(FunctionID__ARGS_SIG_1 ) \ | ||||
| // -----------------------------------------------------------------------------------------------------#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic(       k | ||||
| #define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic(       \ | ||||
| (selector_arg), /* Select Via Expression*/                           \ | ||||
|   /* Extendibility slots: */                                         \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ | ||||
| 	default: gen_generic_selection_fail                              \ | ||||
| ) GEN_RESOLVED_FUNCTION_CALL( selector_arg ) | ||||
| // ---------------------------------------------------------------------------------------------------------------------------------- | ||||
|  | ||||
| @@ -355,17 +354,18 @@ size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761u | ||||
|  | ||||
| // If using an Editor with support for syntax hightlighting macros: HASH__ARGS_SIG_1 and HASH_ARGS_SIG_2 should show color highlighting indicating the slot is enabled, | ||||
| // or, "defined" for usage during the compilation pass that handles the _Generic instrinsic. | ||||
| #define hash( function_arguments ) _Generic(                        \ | ||||
| (function_arguments), /* Select Via Expression*/                    \ | ||||
|   /* Extendibility slots: */                                        \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_1 )      \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_2 )      \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_3 )      \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_4 )      \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_5 )      \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_6 )      \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_7 )      \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST( HASH__ARGS_SIG_8 ) \ | ||||
| #define hash( function_arguments ) _Generic(                   \ | ||||
| (function_arguments), /* Select Via Expression*/               \ | ||||
|   /* Extendibility slots: */                                   \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_1 ) \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_2 ) \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_3 ) \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_4 ) \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_5 ) \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_6 ) \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_7 ) \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_8 ) \ | ||||
| 	default: gen_generic_selection_fail                        \ | ||||
| ) GEN_RESOLVED_FUNCTION_CALL( function_arguments ) | ||||
|  | ||||
| // Additional Variations: | ||||
| @@ -376,7 +376,8 @@ size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761u | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )        \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 )        \ | ||||
| 	...                                                                     \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST(FunctionID__ARGS_SIG_N )    \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N )         \ | ||||
| 	default: gen_generic_selection_fail                                     \ | ||||
| ) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ ) | ||||
|  | ||||
| // If the function does not take the arugment as a parameter: | ||||
| @@ -385,9 +386,13 @@ size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761u | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )       \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 )       \ | ||||
| 	/* ... */                                                              \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST(FunctionID__ARGS_SIG_N )   \ | ||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N )        \ | ||||
| 	default: gen_generic_selection_fail                                    \ | ||||
| ) GEN_RESOLVED_FUNCTION_CALL() | ||||
|  | ||||
| // Used to keep the _Generic keyword happy as bare types are not considered "expressions" | ||||
| #define GEN_TYPE_TO_EXP(type) (* (type*)NULL) | ||||
|  | ||||
| // typedef void* GEN_GenericExampleType; | ||||
| // GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( GEN_GenericExampleType ); | ||||
|  | ||||
|   | ||||
| @@ -46,6 +46,7 @@ void const* mem_find( void const* data, u8 c, ssize n ) | ||||
|  | ||||
| #define GEN_HEAP_STATS_MAGIC 0xDEADC0DE | ||||
|  | ||||
| typedef struct _heap_stats _heap_stats; | ||||
| struct _heap_stats | ||||
| { | ||||
| 	u32 magic; | ||||
| @@ -80,6 +81,7 @@ void heap_stats_check( void ) | ||||
| 	GEN_ASSERT( _heap_stats_info.alloc_count == 0 ); | ||||
| } | ||||
|  | ||||
| typedef struct _heap_alloc_info _heap_alloc_info; | ||||
| struct _heap_alloc_info | ||||
| { | ||||
| 	ssize    size; | ||||
|   | ||||
| @@ -33,6 +33,7 @@ enum | ||||
| 	GEN_FMT_INTS = GEN_FMT_CHAR | GEN_FMT_SHORT | GEN_FMT_INT | GEN_FMT_LONG | GEN_FMT_LLONG | GEN_FMT_SIZE | GEN_FMT_INTPTR | ||||
| }; | ||||
|  | ||||
| typedef struct _format_info _format_info; | ||||
| struct _format_info | ||||
| { | ||||
| 	s32 base; | ||||
| @@ -429,7 +430,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis | ||||
| 					break; | ||||
| 				} | ||||
|  | ||||
| 				String gen_str = String { va_arg( va, char*) }; | ||||
| 				String gen_str = { va_arg( va, char*) }; | ||||
|  | ||||
| 				info.precision = string_length(gen_str); | ||||
| 				len            = _print_string( text, remaining, &info, gen_str ); | ||||
|   | ||||
| @@ -7,17 +7,21 @@ | ||||
|  | ||||
| String string_make_length( AllocatorInfo allocator, char const* str, ssize length ) | ||||
| { | ||||
| 	constexpr ssize header_size = sizeof( StringHeader ); | ||||
| 	ssize const header_size = sizeof( StringHeader ); | ||||
|  | ||||
| 	s32   alloc_size = header_size + length + 1; | ||||
| 	void* allocation = alloc( allocator, alloc_size ); | ||||
|  | ||||
| 	if ( allocation == nullptr ) | ||||
| 		return { nullptr }; | ||||
| 	if ( allocation == nullptr ) { | ||||
| 		String null_string = {nullptr}; | ||||
| 		return null_string; | ||||
| 	} | ||||
|  | ||||
| 	StringHeader& | ||||
| 	header = * rcast(StringHeader*, allocation); | ||||
| 	header = { allocator, length, length }; | ||||
| 	StringHeader* | ||||
| 	header = rcast(StringHeader*, allocation); | ||||
| 	header->Allocator = allocator; | ||||
| 	header->Capacity  = length; | ||||
| 	header->Length    = length; | ||||
|  | ||||
| 	String  result = { rcast( char*, allocation) + header_size }; | ||||
|  | ||||
| @@ -33,14 +37,15 @@ String string_make_length( AllocatorInfo allocator, char const* str, ssize lengt | ||||
|  | ||||
| String string_make_reserve( AllocatorInfo allocator, ssize capacity ) | ||||
| { | ||||
| 	constexpr ssize header_size = sizeof( StringHeader ); | ||||
| 	ssize const header_size = sizeof( StringHeader ); | ||||
|  | ||||
| 	s32   alloc_size = header_size + capacity + 1; | ||||
| 	void* allocation = alloc( allocator, alloc_size ); | ||||
|  | ||||
| 	if ( allocation == nullptr ) | ||||
| 		return { nullptr }; | ||||
|  | ||||
| 	if ( allocation == nullptr ) { | ||||
| 		String null_string = {nullptr}; | ||||
| 		return null_string; | ||||
| 	} | ||||
| 	mem_set( allocation, 0, alloc_size ); | ||||
|  | ||||
| 	StringHeader* | ||||
|   | ||||
| @@ -7,12 +7,12 @@ | ||||
|  | ||||
| struct StrC; | ||||
|  | ||||
| StrC        to_strc_from_c_str       (char const* bad_string); | ||||
| bool        strc_are_equal           (StrC lhs, StrC rhs); | ||||
| char const* strc_back                (StrC str); | ||||
| bool        strc_contains            (StrC str, StrC substring); | ||||
| StrC        strc_duplicate           (StrC str, AllocatorInfo allocator); | ||||
| b32         strc_starts_with         (StrC str, StrC substring); | ||||
| StrC        strc_to_str              (char const* bad_string); | ||||
| StrC        strc_visualize_whitespace(StrC str, AllocatorInfo allocator); | ||||
|  | ||||
| // Constant string with length. | ||||
|   | ||||
| @@ -41,13 +41,13 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false ) | ||||
| 	if (use_c_definition) | ||||
| 	{ | ||||
| 		enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries), | ||||
| 			"enum CodeType enum_underlying(u32) { <entries> CT_NumTypes };" | ||||
| 			"enum CodeType enum_underlying(u32) { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };" | ||||
| 		)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries), | ||||
| 			"enum CodeType : u32 { <entries> CT_NumTypes };" | ||||
| 			"enum CodeType : u32 { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };" | ||||
| 		)); | ||||
| 	} | ||||
|  | ||||
| @@ -140,7 +140,8 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | ||||
| 			enum Operator enum_underlying(u32) | ||||
| 			{ | ||||
| 				<entries> | ||||
| 				NumOps | ||||
| 				Op_NumOps, | ||||
| 				Op_UnderlyingType = GEN_U32_MAX | ||||
| 			}; | ||||
| 		))); | ||||
| 	#pragma pop_macro("enum_underlying") | ||||
| @@ -151,7 +152,8 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | ||||
| 			enum Operator : u32 | ||||
| 			{ | ||||
| 				<entries> | ||||
| 				NumOps | ||||
| 				Op_NumOps, | ||||
| 				Op_UnderlyingType = GEN_U32_MAX | ||||
| 			}; | ||||
| 		))); | ||||
| 	} | ||||
| @@ -233,7 +235,8 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | ||||
| 			enum Specifier enum_underlying(u32) | ||||
| 			{ | ||||
| 				<entries> | ||||
| 				Spec_NumSpecifiers | ||||
| 				Spec_NumSpecifiers, | ||||
| 				Spec_UnderlyingType = GEN_U32_MAX | ||||
| 			}; | ||||
| 		))); | ||||
| 	#pragma pop_macro("enum_underlying") | ||||
| @@ -244,7 +247,8 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | ||||
| 			enum Specifier : u32 | ||||
| 			{ | ||||
| 				<entries> | ||||
| 				Spec_NumSpecifiers | ||||
| 				Spec_NumSpecifiers, | ||||
| 				Spec_UnderlyingType = GEN_U32_MAX | ||||
| 			}; | ||||
| 		))); | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user