mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-31 06:50:53 -07:00 
			
		
		
		
	Compare commits
	
		
			10 Commits
		
	
	
		
			9e88cb8724
			...
			c38b077c37
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c38b077c37 | |||
| f9b5029e64 | |||
| 2b24511f7d | |||
| 5cd69e1742 | |||
| 007bfa0cb0 | |||
| 37c33ffb3e | |||
| 937235b776 | |||
| f9c21ebc04 | |||
| fec709cc76 | |||
| 80cb3f4eca | 
| @@ -25,6 +25,8 @@ This library was written in a subset of C++ where the following are not used at | |||||||
| * Exceptions | * Exceptions | ||||||
|  |  | ||||||
| Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.   | Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.   | ||||||
|  | The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C (WIP). | ||||||
|  |  | ||||||
| There are only 4 template definitions in the entire library. (`Array<Type>`, `Hashtable<Type>`, `swap<Type>`, and `AST/Code::cast<Type>`) | There are only 4 template definitions in the entire library. (`Array<Type>`, `Hashtable<Type>`, `swap<Type>`, and `AST/Code::cast<Type>`) | ||||||
|  |  | ||||||
| Two generic templated containers are used throughout the library: | Two generic templated containers are used throughout the library: | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| #define GEN_ENFORCE_STRONG_CODE_TYPES | #define GEN_ENFORCE_STRONG_CODE_TYPES | ||||||
| #define GEN_EXPOSE_BACKEND | #define GEN_EXPOSE_BACKEND | ||||||
| #define GEN_SUPPORT_CPP_MEMBER_FEATURES 1 | #define GEN_SUPPORT_CPP_MEMBER_FEATURES 1 | ||||||
|  | #define GEN_SUPPORT_CPP_REFERENCES      1 | ||||||
| #include "../project/gen.cpp" | #include "../project/gen.cpp" | ||||||
|  |  | ||||||
| #include "helpers/push_ignores.inline.hpp" | #include "helpers/push_ignores.inline.hpp" | ||||||
| @@ -135,26 +136,40 @@ int gen_main() | |||||||
| 				case ECode::Using: | 				case ECode::Using: | ||||||
| 				{ | 				{ | ||||||
| 					log_fmt("REPLACE THIS MANUALLY: %S\n", entry->Name); | 					log_fmt("REPLACE THIS MANUALLY: %S\n", entry->Name); | ||||||
| 					CodeUsing   using_ver   = entry.cast<CodeUsing>(); | 					CodeUsing   using_ver   = entry.code_cast<CodeUsing>(); | ||||||
| 					CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); | 					CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); | ||||||
|  |  | ||||||
| 					memory.append(typedef_ver); | 					memory.append(typedef_ver); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
|  | 				case ECode::Function_Fwd: | ||||||
|  | 				{ | ||||||
|  | 					CodeFn fn = entry.code_cast<CodeFn>(); | ||||||
|  | 					if ( fn->Name.is_equal(txt("free")) ) | ||||||
|  | 					{ | ||||||
|  | 						fn->Name = get_cached_string(txt("gen_free_ptr")); | ||||||
|  | 					} | ||||||
|  | 					memory.append(entry); | ||||||
|  | 				} | ||||||
|  | 				break; | ||||||
| 				case ECode::Function: | 				case ECode::Function: | ||||||
| 				{ | 				{ | ||||||
| 					CodeFn fn = entry.cast<CodeFn>(); | 					CodeFn fn = entry.code_cast<CodeFn>(); | ||||||
| 					s32 constexpr_found = fn->Specs.remove( ESpecifier::Constexpr ); | 					s32 constexpr_found = fn->Specs.remove( ESpecifier::Constexpr ); | ||||||
| 					if (constexpr_found > -1) { | 					if (constexpr_found > -1) { | ||||||
| 						log_fmt("Found constexpr: %S\n", entry->to_string()); | 						log_fmt("Found constexpr: %S\n", entry->to_string()); | ||||||
| 						fn->Specs.append(ESpecifier::Inline); | 						fn->Specs.append(ESpecifier::Inline); | ||||||
| 					} | 					} | ||||||
|  | 					if ( fn->Name.is_equal(txt("free")) ) | ||||||
|  | 					{ | ||||||
|  | 						fn->Name = get_cached_string(txt("gen_free_ptr")); | ||||||
|  | 					} | ||||||
| 					memory.append(entry); | 					memory.append(entry); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 				case ECode::Template: | 				case ECode::Template: | ||||||
| 				{ | 				{ | ||||||
| 					CodeTemplate tmpl = entry.cast<CodeTemplate>(); | 					CodeTemplate tmpl = entry.code_cast<CodeTemplate>(); | ||||||
| 					if ( tmpl->Declaration->Name.contains(txt("swap"))) | 					if ( tmpl->Declaration->Name.contains(txt("swap"))) | ||||||
| 					{ | 					{ | ||||||
| 						CodeBody macro_swap = parse_global_body( txt(R"( | 						CodeBody macro_swap = parse_global_body( txt(R"( | ||||||
| @@ -297,7 +312,7 @@ int gen_main() | |||||||
| 				{ | 				{ | ||||||
| 					if ( entry->Name.is_equal(txt("String")) ) | 					if ( entry->Name.is_equal(txt("String")) ) | ||||||
| 					{ | 					{ | ||||||
| 						CodeTypedef c_def = parse_typedef(code( typedef Type* String; )); | 						CodeTypedef c_def = parse_typedef(code( typedef char* String; )); | ||||||
| 						strings.append(c_def); | 						strings.append(c_def); | ||||||
| 						strings.append(fmt_newline); | 						strings.append(fmt_newline); | ||||||
| 						++ entry; | 						++ entry; | ||||||
| @@ -307,6 +322,29 @@ int gen_main() | |||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
|  | 				case ECode::Struct: | ||||||
|  | 				{ | ||||||
|  | 					CodeBody body     = entry->Body->operator CodeBody(); | ||||||
|  | 					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 ECode::Preprocess_If: | ||||||
|  | 						{ | ||||||
|  | 							b32 found = ignore_preprocess_cond_block(txt("! GEN_COMPILER_C"), body_entry, body ); | ||||||
|  | 							if (found) break; | ||||||
|  |  | ||||||
|  | 							new_body.append(body_entry); | ||||||
|  | 						} | ||||||
|  | 						break; | ||||||
|  | 						default: | ||||||
|  | 							new_body.append(body_entry); | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  | 					entry->Body = rcast(AST*, new_body.ast); | ||||||
|  | 					strings.append(entry); | ||||||
|  | 				} | ||||||
|  | 				break; | ||||||
|  |  | ||||||
| 				default: | 				default: | ||||||
| 					strings.append(entry); | 					strings.append(entry); | ||||||
| 				break; | 				break; | ||||||
| @@ -316,8 +354,8 @@ int gen_main() | |||||||
|  |  | ||||||
| 		Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" ); | 		Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" ); | ||||||
| 		Code timing = scan_file( project_dir "dependencies/timing.hpp" ); | 		Code timing = scan_file( project_dir "dependencies/timing.hpp" ); | ||||||
| 		header.print( filesystem ); | 		// header.print( filesystem ); | ||||||
| 		header.print( timing ); | 		// header.print( timing ); | ||||||
|  |  | ||||||
| 		header.print_fmt( "\nGEN_NS_END\n" ); | 		header.print_fmt( "\nGEN_NS_END\n" ); | ||||||
| 		header.print_fmt( roll_own_dependencies_guard_end ); | 		header.print_fmt( roll_own_dependencies_guard_end ); | ||||||
| @@ -335,6 +373,7 @@ int gen_main() | |||||||
| 		CodeBody especifier  = gen_especifier( project_dir "enums/ESpecifier.csv" ); | 		CodeBody especifier  = gen_especifier( project_dir "enums/ESpecifier.csv" ); | ||||||
| 		CodeBody ast_inlines = gen_ast_inlines(); | 		CodeBody ast_inlines = gen_ast_inlines(); | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
| 		header.print_fmt("#pragma region Types\n"); | 		header.print_fmt("#pragma region Types\n"); | ||||||
| 		header.print( types ); | 		header.print( types ); | ||||||
| 		header.print( fmt_newline ); | 		header.print( fmt_newline ); | ||||||
| @@ -345,6 +384,7 @@ int gen_main() | |||||||
| 		header.print( dump_to_scratch_and_retireve( especifier )); | 		header.print( dump_to_scratch_and_retireve( especifier )); | ||||||
| 		header.print( fmt_newline ); | 		header.print( fmt_newline ); | ||||||
| 		header.print_fmt("#pragma endregion Types\n\n"); | 		header.print_fmt("#pragma endregion Types\n\n"); | ||||||
|  | 	#endif | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	header.print( pop_ignores ); | 	header.print( pop_ignores ); | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ CodeBody gen_fixed_arenas() | |||||||
| 		inline | 		inline | ||||||
| 		void fixed_arena_init_<Name>(FixedArena_<Name>* result) { | 		void fixed_arena_init_<Name>(FixedArena_<Name>* result) { | ||||||
| 			zero_size(& result->memory[0], <Size>); | 			zero_size(& result->memory[0], <Size>); | ||||||
| 			result.arena = arena_init_from_memory(& result->memory[0], <Size>); | 			result->arena = arena_init_from_memory(& result->memory[0], <Size>); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		inline | 		inline | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ using SwapContentProc = CodeBody(void); | |||||||
| b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body ) | b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& body ) | ||||||
| { | { | ||||||
| 	b32 found = false; | 	b32 found = false; | ||||||
| 	CodePreprocessCond cond = entry_iter.cast<CodePreprocessCond>(); | 	CodePreprocessCond cond = entry_iter.code_cast<CodePreprocessCond>(); | ||||||
| 	if ( cond->Content.contains(cond_sig) ) | 	if ( cond->Content.contains(cond_sig) ) | ||||||
| 	{ | 	{ | ||||||
| 		log_fmt("Preprocess cond found: %S\n", cond->Content); | 		log_fmt("Preprocess cond found: %S\n", cond->Content); | ||||||
| @@ -44,7 +44,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& bod | |||||||
| bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body ) | bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body ) | ||||||
| { | { | ||||||
| 	bool found = false; | 	bool found = false; | ||||||
| 	CodePragma possible_region = entry_iter.cast<CodePragma>(); | 	CodePragma possible_region = entry_iter.code_cast<CodePragma>(); | ||||||
|  |  | ||||||
| 	String region_sig    = string_fmt_buf(GlobalAllocator, "region %s",    region_name.Ptr); | 	String region_sig    = string_fmt_buf(GlobalAllocator, "region %s",    region_name.Ptr); | ||||||
| 	String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr); | 	String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr); | ||||||
| @@ -58,7 +58,7 @@ bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_ | |||||||
| 		(entry_iter->Type) { | 		(entry_iter->Type) { | ||||||
| 			case ECode::Preprocess_Pragma: | 			case ECode::Preprocess_Pragma: | ||||||
| 			{ | 			{ | ||||||
| 				CodePragma possible_end_region = entry_iter.cast<CodePragma>(); | 				CodePragma possible_end_region = entry_iter.code_cast<CodePragma>(); | ||||||
| 				if ( possible_end_region->Content.contains(endregion_sig) ) { | 				if ( possible_end_region->Content.contains(endregion_sig) ) { | ||||||
| 					// body.append(possible_end_region); | 					// body.append(possible_end_region); | ||||||
| 					continue_for = false; | 					continue_for = false; | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								gen_c_library/gen.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								gen_c_library/gen.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | #define GEN_IMPLEMENTATION | ||||||
|  | #include "gen/gen.h" | ||||||
|  |  | ||||||
|  | int main() | ||||||
|  | { | ||||||
|  | 	// init(); | ||||||
|  | } | ||||||
| @@ -30,6 +30,13 @@ Feature Macros: | |||||||
| * `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves. | * `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves. | ||||||
| * `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized. | * `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized. | ||||||
|  |  | ||||||
|  | By default the base library implementation strictly uses a C-like interface. This is to allow for the generation of a C-variant of the library using [gen_c_library](../gen_c_library/). However, the library was written in C++ and supports some of its features: | ||||||
|  |  | ||||||
|  | * `GEN_SUPPORT_CPP_REFERENCES` : Will enable support for reference interface on some definitions | ||||||
|  | * `GEN_SUPPORT_CPP_MEMBER_FEATURES` : Will enable support for definitions to have their interface as members. | ||||||
|  |  | ||||||
|  | *Note: A variant of the C++ library could be generated where those additonal support features are removed (see gen_c_library implementation for an idea of how)* | ||||||
|  |  | ||||||
| ## On multi-threading | ## On multi-threading | ||||||
|  |  | ||||||
| Currently unsupported. I want the library to be *stable* and *correct*, with the addition of exhausting all basic single-threaded optimizations before I consider multi-threading. | Currently unsupported. I want the library to be *stable* and *correct*, with the addition of exhausting all basic single-threaded optimizations before I consider multi-threading. | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ Builder Builder::open( char const* path ) | |||||||
|  |  | ||||||
| void Builder::pad_lines( s32 num ) | void Builder::pad_lines( s32 num ) | ||||||
| { | { | ||||||
| 	append( Buffer,  "\n" ); | 	append( & Buffer,  "\n" ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Builder::print( Code code ) | void Builder::print( Code code ) | ||||||
| @@ -29,7 +29,7 @@ void Builder::print( Code code ) | |||||||
| 	String   str = code->to_string(); | 	String   str = code->to_string(); | ||||||
| 	// const ssize len = str.length(); | 	// const ssize len = str.length(); | ||||||
| 	// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data ); | 	// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data ); | ||||||
| 	append( Buffer, str ); | 	append( & Buffer, str ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Builder::print_fmt( char const* fmt, ... ) | void Builder::print_fmt( char const* fmt, ... ) | ||||||
| @@ -43,7 +43,7 @@ void Builder::print_fmt( char const* fmt, ... ) | |||||||
| 	va_end( va ); | 	va_end( va ); | ||||||
|  |  | ||||||
| 	// log_fmt( "$%s - print_fmt: %.*s\n", File.filename, res > 80 ? 80 : res, buf ); | 	// log_fmt( "$%s - print_fmt: %.*s\n", File.filename, res > 80 ? 80 : res, buf ); | ||||||
| 	append( Buffer, buf, res ); | 	append( & Buffer, buf, res ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Builder::write() | void Builder::write() | ||||||
| @@ -55,5 +55,5 @@ void Builder::write() | |||||||
|  |  | ||||||
| 	log_fmt( "Generated: %s\n", File.filename ); | 	log_fmt( "Generated: %s\n", File.filename ); | ||||||
| 	file_close( & File ); | 	file_close( & File ); | ||||||
| 	free(Buffer); | 	free(& Buffer); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ Code scan_file( char const* path ) | |||||||
|  |  | ||||||
| 	String str = string_make_reserve( GlobalAllocator, fsize ); | 	String str = string_make_reserve( GlobalAllocator, fsize ); | ||||||
| 		file_read( & file, str, fsize ); | 		file_read( & file, str, fsize ); | ||||||
| 		get_header(str).Length = fsize; | 		get_header(str)->Length = fsize; | ||||||
|  |  | ||||||
| 	// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks | 	// Skip GEN_INTELLISENSE_DIRECTIVES preprocessor blocks | ||||||
| 	// Its designed so that the directive should be the first thing in the file. | 	// Its designed so that the directive should be the first thing in the file. | ||||||
| @@ -97,12 +97,12 @@ Code scan_file( char const* path ) | |||||||
| 					if ( (scanner + 2) >= ( str.Data + fsize ) ) | 					if ( (scanner + 2) >= ( str.Data + fsize ) ) | ||||||
| 					{ | 					{ | ||||||
| 						mem_move( str, scanner, left ); | 						mem_move( str, scanner, left ); | ||||||
| 						get_header(str).Length = left; | 						get_header(str)->Length = left; | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					mem_move( str, scanner, left ); | 					mem_move( str, scanner, left ); | ||||||
| 					get_header(str).Length = left; | 					get_header(str)->Length = left; | ||||||
|  |  | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS | #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS | ||||||
| #define GEN_ENFORCE_STRONG_CODE_TYPES | #define GEN_ENFORCE_STRONG_CODE_TYPES | ||||||
| #define GEN_EXPOSE_BACKEND | #define GEN_EXPOSE_BACKEND | ||||||
| #define GEN_SUPPORT_CPP_MEMBER_FEATURES 0 | #define GEN_SUPPORT_CPP_MEMBER_FEATURES 1 | ||||||
|  | #define GEN_SUPPORT_CPP_REFERENCES      0 | ||||||
| #include "gen.cpp" | #include "gen.cpp" | ||||||
|  |  | ||||||
| #include "helpers/push_ignores.inline.hpp" | #include "helpers/push_ignores.inline.hpp" | ||||||
| @@ -28,17 +29,17 @@ void format_file( char const* path ) | |||||||
| 	String resolved_path = string_make(GlobalAllocator, to_str(path)); | 	String resolved_path = string_make(GlobalAllocator, to_str(path)); | ||||||
|  |  | ||||||
| 	String style_arg = string_make(GlobalAllocator, txt("-style=file:")); | 	String style_arg = string_make(GlobalAllocator, txt("-style=file:")); | ||||||
| 	append( style_arg, "../scripts/.clang-format "); | 	append( & style_arg, "../scripts/.clang-format "); | ||||||
|  |  | ||||||
| 	// Need to execute clang format on the generated file to get it to match the original. | 	// Need to execute clang format on the generated file to get it to match the original. | ||||||
| 	#define clang_format      "clang-format " | 	#define clang_format      "clang-format " | ||||||
| 	#define cf_format_inplace "-i " | 	#define cf_format_inplace "-i " | ||||||
| 	#define cf_verbose        "-verbose " | 	#define cf_verbose        "-verbose " | ||||||
| 	String command = string_make( GlobalAllocator, clang_format ); | 	String command = string_make( GlobalAllocator, clang_format ); | ||||||
| 	append( command, cf_format_inplace ); | 	append( & command, cf_format_inplace ); | ||||||
| 	append( command, cf_verbose ); | 	append( & command, cf_verbose ); | ||||||
| 	append( command, style_arg ); | 	append( & command, style_arg ); | ||||||
| 	append( command, resolved_path ); | 	append( & command, resolved_path ); | ||||||
| 		log_fmt("\tRunning clang-format on file:\n"); | 		log_fmt("\tRunning clang-format on file:\n"); | ||||||
| 		system( command ); | 		system( command ); | ||||||
| 		log_fmt("\tclang-format finished reformatting.\n"); | 		log_fmt("\tclang-format finished reformatting.\n"); | ||||||
| @@ -63,6 +64,8 @@ int gen_main() | |||||||
| { | { | ||||||
| 	gen::init(); | 	gen::init(); | ||||||
|  |  | ||||||
|  | 	// PreprocessorDefines.append("GEN_NS"); | ||||||
|  |  | ||||||
| 	Code push_ignores = scan_file( "helpers/push_ignores.inline.hpp" ); | 	Code push_ignores = scan_file( "helpers/push_ignores.inline.hpp" ); | ||||||
| 	Code pop_ignores  = scan_file( "helpers/pop_ignores.inline.hpp" ); | 	Code pop_ignores  = scan_file( "helpers/pop_ignores.inline.hpp" ); | ||||||
|  |  | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -146,6 +146,19 @@ namespace parser | |||||||
| 	struct Token; | 	struct Token; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | template< class Type> forceinline Type tmpl_cast( Code* self ) { return * rcast( Type*, self ); } | ||||||
|  | #if ! GEN_COMPILER_C && 0 | ||||||
|  | template< class Type> forceinline Type tmpl_cast( Code& self ) { return * rcast( Type*, & self ); } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | char const* debug_str (Code code); | ||||||
|  | Code        duplicate (Code code); | ||||||
|  | bool        is_equal  (Code code, Code other); | ||||||
|  | bool        is_body   (Code code); | ||||||
|  | bool        is_valid  (Code code); | ||||||
|  | void        set_global(Code code); | ||||||
|  | String      to_string (Code code); | ||||||
|  |  | ||||||
| /* | /* | ||||||
| 	AST* wrapper | 	AST* wrapper | ||||||
| 	- Not constantly have to append the '*' as this is written often.. | 	- Not constantly have to append the '*' as this is written often.. | ||||||
| @@ -153,32 +166,26 @@ namespace parser | |||||||
| */ | */ | ||||||
| struct Code | struct Code | ||||||
| { | { | ||||||
| #	pragma region Statics | 	AST* ast; | ||||||
| 	// Used to identify ASTs that should always be duplicated. (Global constant ASTs) |  | ||||||
| 	static Code Global; |  | ||||||
|  |  | ||||||
| 	// Used to identify invalid generated code. |  | ||||||
| 	static Code Invalid; |  | ||||||
| #	pragma endregion Statics |  | ||||||
|  |  | ||||||
| #	define Using_Code( Typename )          \ | #	define Using_Code( Typename )          \ | ||||||
| 	char const* debug_str();               \ | 	char const* debug_str()                { return GEN_NS debug_str(* this); } \ | ||||||
| 	Code        duplicate();			   \ | 	Code        duplicate()                { return GEN_NS duplicate(* this); }	\ | ||||||
| 	bool        is_equal( Code other );    \ | 	bool        is_equal( Code other )     { return GEN_NS is_equal(* this, other); } \ | ||||||
| 	bool        is_body();                 \ | 	bool        is_body()                  { return GEN_NS is_body(* this); } \ | ||||||
| 	bool        is_valid();                \ | 	bool        is_valid()                 { return GEN_NS is_valid(* this); } \ | ||||||
| 	void        set_global();              \ | 	void        set_global()               { return GEN_NS set_global(* this); } \ | ||||||
| 	String      to_string();               \ | 	String      to_string();               \ | ||||||
| 	Typename&   operator = ( AST* other ); \ | 	Typename&   operator = ( AST* other ); \ | ||||||
| 	Typename&   operator = ( Code other ); \ | 	Typename&   operator = ( Code other ); \ | ||||||
| 	bool        operator ==( Code other ); \ | 	bool        operator ==( Code other ) { return (AST*)ast == other.ast; } \ | ||||||
| 	bool        operator !=( Code other ); \ | 	bool        operator !=( Code other ) { return (AST*)ast != other.ast; } \ | ||||||
| 	operator bool(); | 	operator bool(); | ||||||
|  |  | ||||||
| 	Using_Code( Code ); | 	Using_Code( Code ); | ||||||
|  |  | ||||||
| 	template< class Type > | 	template< class Type > | ||||||
| 	forceinline Type cast() | 	forceinline Type code_cast() | ||||||
| 	{ | 	{ | ||||||
| 		return * rcast( Type*, this ); | 		return * rcast( Type*, this ); | ||||||
| 	} | 	} | ||||||
| @@ -201,8 +208,6 @@ struct Code | |||||||
| 		return *this; | 		return *this; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	AST* ast; |  | ||||||
|  |  | ||||||
| #ifdef GEN_ENFORCE_STRONG_CODE_TYPES | #ifdef GEN_ENFORCE_STRONG_CODE_TYPES | ||||||
| #	define operator explicit operator | #	define operator explicit operator | ||||||
| #endif | #endif | ||||||
| @@ -238,6 +243,14 @@ struct Code | |||||||
| 	#undef operator | 	#undef operator | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | #pragma region Statics | ||||||
|  | // Used to identify ASTs that should always be duplicated. (Global constant ASTs) | ||||||
|  | extern Code Code_Global; | ||||||
|  |  | ||||||
|  | // Used to identify invalid generated code. | ||||||
|  | extern Code Code_Invalid; | ||||||
|  | #pragma endregion Statics | ||||||
|  |  | ||||||
| struct Code_POD | struct Code_POD | ||||||
| { | { | ||||||
| 	AST* ast; | 	AST* ast; | ||||||
| @@ -248,33 +261,55 @@ static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" ); | |||||||
| // Desired width of the AST data structure. | // Desired width of the AST data structure. | ||||||
| constexpr int const AST_POD_Size = 128; | constexpr int const AST_POD_Size = 128; | ||||||
|  |  | ||||||
|  | void        append     ( AST* self, AST* other ); | ||||||
|  | char const* debug_str  ( AST* self ); | ||||||
|  | AST*        duplicate  ( AST* self ); | ||||||
|  | Code*       entry      ( AST* self, u32 idx ); | ||||||
|  | bool        has_entries( AST* self ); | ||||||
|  | bool        is_body    ( AST* self ); | ||||||
|  | bool        is_equal   ( AST* self, AST* other ); | ||||||
|  | String      to_string  ( AST* self ); | ||||||
|  | char const* type_str   ( AST* self ); | ||||||
|  |  | ||||||
|  | #if GEN_CPP_SUPPORT_REFERENCES | ||||||
|  | void        append   ( AST& self, AST& other ) { return append(& self, & other); } | ||||||
|  | bool        is_body  ( AST& self )             { return is_body(& self); } | ||||||
|  | bool        is_equal ( AST& self, AST& other ) { return is_equal(& self, & other); } | ||||||
|  | char const* debug_str( AST& self )             { return debug_str( & self ); } | ||||||
|  | String      to_string( AST& self )             { return to_string( & self ); } | ||||||
|  | char const* type_str ( AST& self )             { return type_str( & self ); } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| /* | /* | ||||||
| 	Simple AST POD with functionality to seralize into C++ syntax. | 	Simple AST POD with functionality to seralize into C++ syntax. | ||||||
| */ | */ | ||||||
| struct AST | struct AST | ||||||
| { | { | ||||||
|  | #if GEN_SUPPORT_CPP_MEMBER_FEATURES | ||||||
| #	pragma region Member Functions | #	pragma region Member Functions | ||||||
| 	void        append     ( AST* other ); | 	void        append     ( AST* other ) { GEN_NS append(this, other); } | ||||||
| 	char const* debug_str  (); | 	char const* debug_str  ()             { return GEN_NS debug_str(this); } | ||||||
| 	AST*        duplicate  (); | 	AST*        duplicate  ()             { return GEN_NS duplicate(this); } | ||||||
| 	Code&       entry      ( u32 idx ); | 	Code*       entry      ( u32 idx )    { return GEN_NS entry(this, idx); } | ||||||
| 	bool        has_entries(); | 	bool        has_entries(); | ||||||
| 	bool        is_equal   ( AST* other ); | 	bool        is_equal   ( AST* other )  { return GEN_NS is_equal(this, other); } | ||||||
| 	bool        is_body(); | 	bool        is_body()                  { return GEN_NS is_body(this); } | ||||||
| 	char const* type_str(); | 	char const* type_str()                 { return GEN_NS type_str(this); } | ||||||
| 	bool        validate_body(); | 	bool        validate_body(); | ||||||
|  |  | ||||||
| 	String to_string(); | 	String to_string(); //{ return GEN_NS to_string(this); } | ||||||
|  |  | ||||||
| 	neverinline |  | ||||||
| 	void to_string( String& result ); |  | ||||||
|  |  | ||||||
| 	template< class Type > | 	template< class Type > | ||||||
| 	forceinline Type cast() | 	forceinline Type code_cast() | ||||||
| 	{ | 	{ | ||||||
| 		return * this; | 		return * this; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	neverinline | ||||||
|  | 	void to_string( String& result ); | ||||||
|  | #	pragma endregion Member Functions | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	operator Code(); | 	operator Code(); | ||||||
| 	operator CodeBody(); | 	operator CodeBody(); | ||||||
| 	operator CodeAttributes(); | 	operator CodeAttributes(); | ||||||
| @@ -305,7 +340,6 @@ struct AST | |||||||
| 	operator CodeUnion(); | 	operator CodeUnion(); | ||||||
| 	operator CodeUsing(); | 	operator CodeUsing(); | ||||||
| 	operator CodeVar(); | 	operator CodeVar(); | ||||||
| #	pragma endregion Member Functions |  | ||||||
|  |  | ||||||
| 	constexpr static | 	constexpr static | ||||||
| 	int ArrSpecs_Cap = | 	int ArrSpecs_Cap = | ||||||
| @@ -446,12 +480,9 @@ struct AST_POD | |||||||
| 	}; | 	}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct test { |  | ||||||
| 	SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers |  | ||||||
| 	AST* NextSpecs;                         // Specifiers; If ArrSpecs is full, then NextSpecs is used. |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| constexpr int pls = sizeof(test); | // TODO(Ed): Convert | ||||||
|  | String      to_string  ( AST* self ) { return self->to_string(); } | ||||||
|  |  | ||||||
| // Its intended for the AST to have equivalent size to its POD. | // Its intended for the AST to have equivalent size to its POD. | ||||||
| // All extra functionality within the AST namespace should just be syntatic sugar. | // All extra functionality within the AST namespace should just be syntatic sugar. | ||||||
| @@ -460,4 +491,4 @@ static_assert( sizeof(AST_POD) == AST_POD_Size,    "ERROR: AST POD is not size o | |||||||
|  |  | ||||||
| // Used when the its desired when omission is allowed in a definition. | // Used when the its desired when omission is allowed in a definition. | ||||||
| #define NoCode      { nullptr } | #define NoCode      { nullptr } | ||||||
| #define CodeInvalid (* Code::Invalid.ast) // Uses an implicitly overloaded cast from the AST to the desired code type. | #define InvalidCode (* Code_Invalid.ast) // Uses an implicitly overloaded cast from the AST to the desired code type. | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -11,37 +11,30 @@ struct CodeBody | |||||||
|  |  | ||||||
| 	void append( Code other ) | 	void append( Code other ) | ||||||
| 	{ | 	{ | ||||||
| 		if (other.is_body()) | 		GEN_ASSERT(other.ast != nullptr); | ||||||
| 		{ |  | ||||||
| 			append( other.cast<CodeBody>() ); | 		if (other.is_body()) { | ||||||
|  | 			append( cast(CodeBody, & other) ); | ||||||
| 		} | 		} | ||||||
| 		raw()->append( other.ast ); |  | ||||||
|  | 		GEN_NS append( raw(), other.ast ); | ||||||
| 	} | 	} | ||||||
| 	void append( CodeBody body ) | 	void append( CodeBody body ) | ||||||
| 	{ | 	{ | ||||||
| 		for ( Code entry : body ) | 		for ( Code entry : body ) { | ||||||
| 		{ |  | ||||||
| 			append( entry ); | 			append( entry ); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	bool has_entries() | 	bool has_entries() { return GEN_NS has_entries(rcast( AST*, ast )); } | ||||||
| 	{ | 	AST* raw()         { return rcast( AST*, ast ); } | ||||||
| 		return rcast( AST*, ast )->has_entries(); |  | ||||||
| 	} |  | ||||||
| 	void to_string( String& result ); | 	void to_string( String& result ); | ||||||
| 	void to_string_export( String& result ); | 	void to_string_export( String& result ); | ||||||
| 	AST* raw() |  | ||||||
| 	{ | 	AST_Body* operator->() { return ast; } | ||||||
| 		return rcast( AST*, ast ); |  | ||||||
| 	} | 	operator Code() { return * rcast( Code*, this ); } | ||||||
| 	AST_Body* operator->() |  | ||||||
| 	{ |  | ||||||
| 		return ast; |  | ||||||
| 	} |  | ||||||
| 	operator Code() |  | ||||||
| 	{ |  | ||||||
| 		return * rcast( Code*, this ); |  | ||||||
| 	} |  | ||||||
| #pragma region Iterator | #pragma region Iterator | ||||||
| 	Code begin() | 	Code begin() | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -4,56 +4,62 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void AST::append( AST* other ) | void append( AST* self, AST* other ) | ||||||
| { | { | ||||||
|  | 	GEN_ASSERT(self  != nullptr); | ||||||
|  | 	GEN_ASSERT(other != nullptr); | ||||||
|  |  | ||||||
| 	if ( other->Parent ) | 	if ( other->Parent ) | ||||||
| 		other = other->duplicate(); | 		other = duplicate(other); | ||||||
|  |  | ||||||
| 	other->Parent = this; | 	other->Parent = self; | ||||||
|  |  | ||||||
| 	if ( Front == nullptr ) | 	if ( self->Front == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		Front = other; | 		self->Front = other; | ||||||
| 		Back  = other; | 		self->Back  = other; | ||||||
|  |  | ||||||
| 		NumEntries++; | 		self->NumEntries++; | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	AST* | 	AST* | ||||||
| 	Current       = Back; | 	Current       = self->Back; | ||||||
| 	Current->Next = other; | 	Current->Next = other; | ||||||
| 	other->Prev   = Current; | 	other->Prev   = Current; | ||||||
| 	Back          = other; | 	self->Back    = other; | ||||||
| 	NumEntries++; | 	self->NumEntries++; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| Code& AST::entry( u32 idx ) | Code* entry( AST* self, u32 idx ) | ||||||
| { | { | ||||||
| 	AST** current = & Front; | 	GEN_ASSERT(self != nullptr); | ||||||
|  | 	AST** current = & self->Front; | ||||||
| 	while ( idx >= 0 && current != nullptr ) | 	while ( idx >= 0 && current != nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		if ( idx == 0 ) | 		if ( idx == 0 ) | ||||||
| 			return * rcast( Code*, current); | 			return rcast( Code*, current); | ||||||
|  |  | ||||||
| 		current = & ( * current )->Next; | 		current = & ( * current )->Next; | ||||||
| 		idx--; | 		idx--; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return * rcast( Code*, current); | 	return rcast( Code*, current); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool AST::has_entries() | bool has_entries(AST* self) | ||||||
| { | { | ||||||
| 	return NumEntries > 0; | 	GEN_ASSERT(self != nullptr); | ||||||
|  | 	return self->NumEntries > 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool AST::is_body() | bool is_body(AST* self) | ||||||
| { | { | ||||||
| 	switch (Type) | 	GEN_ASSERT(self != nullptr); | ||||||
|  | 	switch (self->Type) | ||||||
| 	{ | 	{ | ||||||
| 		case ECode::Enum_Body: | 		case ECode::Enum_Body: | ||||||
| 		case ECode::Class_Body: | 		case ECode::Class_Body: | ||||||
| @@ -70,9 +76,10 @@ bool AST::is_body() | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| char const* AST::type_str() | char const* type_str(AST* self) | ||||||
| { | { | ||||||
| 	return ECode::to_str( Type ); | 	GEN_ASSERT(self != nullptr); | ||||||
|  | 	return ECode::to_str( self->Type ); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| @@ -81,6 +88,69 @@ AST::operator Code() | |||||||
| 	return { this }; | 	return { this }; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #pragma region Code | ||||||
|  |  | ||||||
|  | inline | ||||||
|  | char const* debug_str( Code code ) | ||||||
|  | { | ||||||
|  | 	if ( code.ast == nullptr ) | ||||||
|  | 		return "Code::debug_str: AST is null!"; | ||||||
|  |  | ||||||
|  | 	return debug_str( code.ast ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | inline | ||||||
|  | Code duplicate( Code code ) | ||||||
|  | { | ||||||
|  | 	if ( code.ast == nullptr ) | ||||||
|  | 	{ | ||||||
|  | 		log_failure("Code::duplicate: Cannot duplicate code, AST is null!"); | ||||||
|  | 		return Code_Invalid; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return { duplicate(code.ast) }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | inline | ||||||
|  | bool is_body(Code code) | ||||||
|  | { | ||||||
|  | 	if ( code.ast == nullptr ) | ||||||
|  | 	{ | ||||||
|  | 		return is_body(code.ast); | ||||||
|  | 	} | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | inline | ||||||
|  | bool is_equal( Code self, Code other ) | ||||||
|  | { | ||||||
|  | 	if ( self.ast == nullptr || other.ast == nullptr ) | ||||||
|  | 	{ | ||||||
|  | 		// Just check if they're both null. | ||||||
|  | 		// log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); | ||||||
|  | 		return self.ast == nullptr && other.ast == nullptr; | ||||||
|  | 	} | ||||||
|  | 	return is_equal( self.ast, other.ast ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | inline | ||||||
|  | bool is_valid(Code self) | ||||||
|  | { | ||||||
|  | 	return self.ast != nullptr && self.ast->Type != CodeT::Invalid; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | inline | ||||||
|  | void set_global(Code self) | ||||||
|  | { | ||||||
|  | 	if ( self.ast == nullptr ) | ||||||
|  | 	{ | ||||||
|  | 		log_failure("Code::set_global: Cannot set code as global, AST is null!"); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	self->Parent = Code_Global.ast; | ||||||
|  | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| Code& Code::operator ++() | Code& Code::operator ++() | ||||||
| { | { | ||||||
| @@ -90,6 +160,8 @@ Code& Code::operator ++() | |||||||
| 	return *this; | 	return *this; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #pragma endregion Code | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void CodeClass::add_interface( CodeType type ) | void CodeClass::add_interface( CodeType type ) | ||||||
| { | { | ||||||
| @@ -117,7 +189,7 @@ void CodeParam::append( CodeParam other ) | |||||||
| 	AST* entry = (AST*) other.ast; | 	AST* entry = (AST*) other.ast; | ||||||
|  |  | ||||||
| 	if ( entry->Parent ) | 	if ( entry->Parent ) | ||||||
| 		entry = entry->duplicate(); | 		entry = GEN_NS duplicate( entry ); | ||||||
|  |  | ||||||
| 	entry->Parent = self; | 	entry->Parent = self; | ||||||
|  |  | ||||||
| @@ -202,7 +274,7 @@ CodeBody def_body( CodeT type ) | |||||||
|  |  | ||||||
| 		default: | 		default: | ||||||
| 			log_failure( "def_body: Invalid type %s", (char const*)ECode::to_str(type) ); | 			log_failure( "def_body: Invalid type %s", (char const*)ECode::to_str(type) ); | ||||||
| 			return (CodeBody)Code::Invalid; | 			return (CodeBody)Code_Invalid; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Code | 	Code | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ internal void deinit(); | |||||||
| internal | internal | ||||||
| void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) | void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) | ||||||
| { | { | ||||||
| 	Arena* last = & back(Global_AllocatorBuckets); | 	Arena* last = back(& Global_AllocatorBuckets); | ||||||
|  |  | ||||||
| 	switch ( type ) | 	switch ( type ) | ||||||
| 	{ | 	{ | ||||||
| @@ -24,13 +24,13 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s | |||||||
| 				if ( bucket.PhysicalStart == nullptr ) | 				if ( bucket.PhysicalStart == nullptr ) | ||||||
| 					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets"); | 					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets"); | ||||||
|  |  | ||||||
| 				if ( ! append( Global_AllocatorBuckets, bucket ) ) | 				if ( ! append( & Global_AllocatorBuckets, bucket ) ) | ||||||
| 					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); | 					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); | ||||||
|  |  | ||||||
| 				last = & back(Global_AllocatorBuckets); | 				last = back(& Global_AllocatorBuckets); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			return alloc_align( allocator_info(* last), size, alignment ); | 			return alloc_align( allocator_info(last), size, alignment ); | ||||||
| 		} | 		} | ||||||
| 		case EAllocation_FREE: | 		case EAllocation_FREE: | ||||||
| 		{ | 		{ | ||||||
| @@ -51,10 +51,10 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s | |||||||
| 				if ( bucket.PhysicalStart == nullptr ) | 				if ( bucket.PhysicalStart == nullptr ) | ||||||
| 					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets"); | 					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets"); | ||||||
|  |  | ||||||
| 				if ( ! append( Global_AllocatorBuckets, bucket ) ) | 				if ( ! append( & Global_AllocatorBuckets, bucket ) ) | ||||||
| 					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); | 					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets"); | ||||||
|  |  | ||||||
| 				last = & back(Global_AllocatorBuckets); | 				last = back(& Global_AllocatorBuckets); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			void* result = alloc_align( last->Backing, size, alignment ); | 			void* result = alloc_align( last->Backing, size, alignment ); | ||||||
| @@ -74,12 +74,12 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s | |||||||
| internal | internal | ||||||
| void define_constants() | void define_constants() | ||||||
| { | { | ||||||
| 	Code::Global                         = make_code(); | 	Code_Global                         = make_code(); | ||||||
| 	scast(String, Code::Global->Name)    = get_cached_string( txt("Global Code") ); | 	scast(String, Code_Global->Name)    = get_cached_string( txt("Global Code") ); | ||||||
| 	scast(String, Code::Global->Content) = Code::Global->Name; | 	scast(String, Code_Global->Content) = Code_Global->Name; | ||||||
|  |  | ||||||
| 	Code::Invalid = make_code(); | 	Code_Invalid = make_code(); | ||||||
| 	Code::Invalid.set_global(); | 	Code_Invalid.set_global(); | ||||||
|  |  | ||||||
| 	t_empty       = (CodeType) make_code(); | 	t_empty       = (CodeType) make_code(); | ||||||
| 	t_empty->Type = ECode::Typename; | 	t_empty->Type = ECode::Typename; | ||||||
| @@ -249,7 +249,7 @@ void init() | |||||||
| 		if ( bucket.PhysicalStart == nullptr ) | 		if ( bucket.PhysicalStart == nullptr ) | ||||||
| 			GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets"); | 			GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets"); | ||||||
|  |  | ||||||
| 		append( Global_AllocatorBuckets, bucket ); | 		append( & Global_AllocatorBuckets, bucket ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Setup the arrays | 	// Setup the arrays | ||||||
| @@ -272,7 +272,7 @@ void init() | |||||||
| 		if ( code_pool.PhysicalStart == nullptr ) | 		if ( code_pool.PhysicalStart == nullptr ) | ||||||
| 			GEN_FATAL( "gen::init: Failed to initialize the code pool" ); | 			GEN_FATAL( "gen::init: Failed to initialize the code pool" ); | ||||||
|  |  | ||||||
| 		append(CodePools, code_pool ); | 		append( & CodePools, code_pool ); | ||||||
|  |  | ||||||
| 		LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size ); | 		LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size ); | ||||||
|  |  | ||||||
| @@ -281,7 +281,7 @@ void init() | |||||||
| 		if ( string_arena.PhysicalStart == nullptr ) | 		if ( string_arena.PhysicalStart == nullptr ) | ||||||
| 			GEN_FATAL( "gen::init: Failed to initialize the string arena" ); | 			GEN_FATAL( "gen::init: Failed to initialize the string arena" ); | ||||||
|  |  | ||||||
| 		append(StringArenas, string_arena ); | 		append( & StringArenas, string_arena ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Setup the hash tables | 	// Setup the hash tables | ||||||
| @@ -306,7 +306,7 @@ void deinit() | |||||||
| 	do | 	do | ||||||
| 	{ | 	{ | ||||||
| 		Pool* code_pool = & CodePools[index]; | 		Pool* code_pool = & CodePools[index]; | ||||||
| 		free(* code_pool); | 		free(code_pool); | ||||||
| 		index++; | 		index++; | ||||||
| 	} | 	} | ||||||
| 	while ( left--, left ); | 	while ( left--, left ); | ||||||
| @@ -316,26 +316,26 @@ void deinit() | |||||||
| 	do | 	do | ||||||
| 	{ | 	{ | ||||||
| 		Arena* string_arena = & StringArenas[index]; | 		Arena* string_arena = & StringArenas[index]; | ||||||
| 		free(* string_arena); | 		free(string_arena); | ||||||
| 		index++; | 		index++; | ||||||
| 	} | 	} | ||||||
| 	while ( left--, left ); | 	while ( left--, left ); | ||||||
|  |  | ||||||
| 	destroy(StringCache); | 	destroy(& StringCache); | ||||||
|  |  | ||||||
| 	free(CodePools); | 	free( & CodePools); | ||||||
| 	free(StringArenas); | 	free( & StringArenas); | ||||||
|  |  | ||||||
| 	free(LexArena); | 	free(& LexArena); | ||||||
|  |  | ||||||
| 	free(PreprocessorDefines); | 	free(& PreprocessorDefines); | ||||||
|  |  | ||||||
| 	index = 0; | 	index = 0; | ||||||
| 	left  = num(Global_AllocatorBuckets); | 	left  = num(Global_AllocatorBuckets); | ||||||
| 	do | 	do | ||||||
| 	{ | 	{ | ||||||
| 		Arena* bucket = & Global_AllocatorBuckets[ index ]; | 		Arena* bucket = & Global_AllocatorBuckets[ index ]; | ||||||
| 		free(* bucket); | 		free(bucket); | ||||||
| 		index++; | 		index++; | ||||||
| 	} | 	} | ||||||
| 	while ( left--, left ); | 	while ( left--, left ); | ||||||
| @@ -373,7 +373,7 @@ void reset() | |||||||
|  |  | ||||||
| AllocatorInfo get_string_allocator( s32 str_length ) | AllocatorInfo get_string_allocator( s32 str_length ) | ||||||
| { | { | ||||||
| 	Arena* last = & back(StringArenas); | 	Arena* last = back(& StringArenas); | ||||||
|  |  | ||||||
| 	usize size_req = str_length + sizeof(StringHeader) + sizeof(char*); | 	usize size_req = str_length + sizeof(StringHeader) + sizeof(char*); | ||||||
|  |  | ||||||
| @@ -381,13 +381,13 @@ AllocatorInfo get_string_allocator( s32 str_length ) | |||||||
| 	{ | 	{ | ||||||
| 		Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); | 		Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); | ||||||
|  |  | ||||||
| 		if ( ! append(StringArenas, new_arena ) ) | 		if ( ! append( & StringArenas, new_arena ) ) | ||||||
| 			GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" ); | 			GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" ); | ||||||
|  |  | ||||||
| 		last = & back(StringArenas); | 		last = back(& StringArenas); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return allocator_info(* last); | 	return allocator_info(last); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Will either make or retrive a code string. | // Will either make or retrive a code string. | ||||||
| @@ -403,7 +403,7 @@ StringCached get_cached_string( StrC str ) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	String result = string_make( get_string_allocator( str.Len ), str ); | 	String result = string_make( get_string_allocator( str.Len ), str ); | ||||||
| 	set<StringCached>(StringCache, key, result ); | 	set<StringCached>(& StringCache, key, result ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| @@ -411,7 +411,7 @@ StringCached get_cached_string( StrC str ) | |||||||
| // Used internally to retireve a Code object form the CodePool. | // Used internally to retireve a Code object form the CodePool. | ||||||
| Code make_code() | Code make_code() | ||||||
| { | { | ||||||
| 	Pool* allocator = & back(CodePools); | 	Pool* allocator = back( & CodePools); | ||||||
| 	if ( allocator->FreeList == nullptr ) | 	if ( allocator->FreeList == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) ); | 		Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) ); | ||||||
| @@ -419,13 +419,13 @@ Code make_code() | |||||||
| 		if ( code_pool.PhysicalStart == nullptr ) | 		if ( code_pool.PhysicalStart == nullptr ) | ||||||
| 			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." ); | 			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." ); | ||||||
|  |  | ||||||
| 		if ( ! append( CodePools, code_pool ) ) | 		if ( ! append( & CodePools, code_pool ) ) | ||||||
| 			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." ); | 			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." ); | ||||||
|  |  | ||||||
| 		allocator = & back(CodePools); | 		allocator = back( & CodePools); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Code result { rcast( AST*, alloc( allocator_info(* allocator), sizeof(AST) )) }; | 	Code result { rcast( AST*, alloc( allocator_info(allocator), sizeof(AST) )) }; | ||||||
| 	mem_set( result.ast, 0, sizeof(AST) ); | 	mem_set( result.ast, 0, sizeof(AST) ); | ||||||
| 	// result->Type = ECode::Invalid; | 	// result->Type = ECode::Invalid; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ CodeClass parse_class( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	push_scope(); | 	push_scope(); | ||||||
| @@ -31,7 +31,7 @@ CodeConstructor parse_constructor( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	// TODO(Ed): Constructors can have prefix attributes | 	// TODO(Ed): Constructors can have prefix attributes | ||||||
|  |  | ||||||
| @@ -61,7 +61,7 @@ CodeConstructor parse_constructor( StrC def ) | |||||||
| 			default : | 			default : | ||||||
| 				log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() ); | 				log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() ); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Every specifier after would be considered part of the type type signature | 		// Every specifier after would be considered part of the type type signature | ||||||
| @@ -91,7 +91,7 @@ CodeDestructor parse_destructor( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	// TODO(Ed): Destructors can have prefix attributes | 	// TODO(Ed): Destructors can have prefix attributes | ||||||
| 	// TODO(Ed): Destructors can have virtual | 	// TODO(Ed): Destructors can have virtual | ||||||
| @@ -110,7 +110,7 @@ CodeEnum parse_enum( StrC def ) | |||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| @@ -124,7 +124,7 @@ CodeBody parse_export_body( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_export_body(); | 	return parse_export_body(); | ||||||
| @@ -137,7 +137,7 @@ CodeExtern parse_extern_link( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_extern_link(); | 	return parse_extern_link(); | ||||||
| @@ -150,7 +150,7 @@ CodeFriend parse_friend( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_friend(); | 	return parse_friend(); | ||||||
| @@ -163,7 +163,7 @@ CodeFn parse_function( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return (CodeFn) parse_function(); | 	return (CodeFn) parse_function(); | ||||||
| @@ -176,7 +176,7 @@ CodeBody parse_global_body( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	push_scope(); | 	push_scope(); | ||||||
| @@ -192,7 +192,7 @@ CodeNS parse_namespace( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_namespace(); | 	return parse_namespace(); | ||||||
| @@ -205,7 +205,7 @@ CodeOperator parse_operator( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return (CodeOperator) parse_operator(); | 	return (CodeOperator) parse_operator(); | ||||||
| @@ -218,7 +218,7 @@ CodeOpCast parse_operator_cast( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_operator_cast(); | 	return parse_operator_cast(); | ||||||
| @@ -231,7 +231,7 @@ CodeStruct parse_struct( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	push_scope(); | 	push_scope(); | ||||||
| @@ -247,7 +247,7 @@ CodeTemplate parse_template( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_template(); | 	return parse_template(); | ||||||
| @@ -260,7 +260,7 @@ CodeType parse_type( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_type(); | 	return parse_type(); | ||||||
| @@ -273,7 +273,7 @@ CodeTypedef parse_typedef( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_typedef(); | 	return parse_typedef(); | ||||||
| @@ -286,7 +286,7 @@ CodeUnion parse_union( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_union(); | 	return parse_union(); | ||||||
| @@ -299,7 +299,7 @@ CodeUsing parse_using( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_using(); | 	return parse_using(); | ||||||
| @@ -312,7 +312,7 @@ CodeVar parse_variable( StrC def ) | |||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Tokens = toks; | 	Context.Tokens = toks; | ||||||
| 	return parse_variable(); | 	return parse_variable(); | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va ) | |||||||
| 		char tok_map_mem[ TokenFmt_TokenMap_MemSize ]; | 		char tok_map_mem[ TokenFmt_TokenMap_MemSize ]; | ||||||
|  |  | ||||||
| 		tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) ); | 		tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) ); | ||||||
| 		tok_map       = hashtable_init<StrC>( allocator_info(tok_map_arena) ); | 		tok_map       = hashtable_init<StrC>( allocator_info(& tok_map_arena) ); | ||||||
|  |  | ||||||
| 		s32 left = num_tokens - 1; | 		s32 left = num_tokens - 1; | ||||||
|  |  | ||||||
| @@ -27,8 +27,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va ) | |||||||
| 			StrC        value = va_arg( va, StrC ); | 			StrC        value = va_arg( va, StrC ); | ||||||
|  |  | ||||||
| 			u32 key = crc32( token, str_len(token) ); | 			u32 key = crc32( token, str_len(token) ); | ||||||
|  | 			set(& tok_map, key, value ); | ||||||
| 			set(tok_map, key, value ); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -95,7 +94,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va ) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	clear(tok_map); | 	clear(tok_map); | ||||||
| 	free(tok_map_arena); | 	free(& tok_map_arena); | ||||||
|  |  | ||||||
| 	ssize result = buf_size - remaining; | 	ssize result = buf_size - remaining; | ||||||
|  |  | ||||||
| @@ -107,7 +106,7 @@ Code untyped_str( StrC content ) | |||||||
| 	if ( content.Len == 0 ) | 	if ( content.Len == 0 ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "untyped_str: empty string" ); | 		log_failure( "untyped_str: empty string" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Code | 	Code | ||||||
| @@ -119,7 +118,7 @@ Code untyped_str( StrC content ) | |||||||
| 	if ( result->Name == nullptr ) | 	if ( result->Name == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "untyped_str: could not cache string" ); | 		log_failure( "untyped_str: could not cache string" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -130,7 +129,7 @@ Code untyped_fmt( char const* fmt, ...) | |||||||
| 	if ( fmt == nullptr ) | 	if ( fmt == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "untyped_fmt: null format string" ); | 		log_failure( "untyped_fmt: null format string" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	local_persist thread_local | 	local_persist thread_local | ||||||
| @@ -150,7 +149,7 @@ Code untyped_fmt( char const* fmt, ...) | |||||||
| 	if ( result->Name == nullptr ) | 	if ( result->Name == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "untyped_fmt: could not cache string" ); | 		log_failure( "untyped_fmt: could not cache string" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -161,7 +160,7 @@ Code untyped_token_fmt( s32 num_tokens, ... ) | |||||||
| 	if ( num_tokens == 0 ) | 	if ( num_tokens == 0 ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "untyped_token_fmt: zero tokens" ); | 		log_failure( "untyped_token_fmt: zero tokens" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	local_persist thread_local | 	local_persist thread_local | ||||||
| @@ -181,7 +180,7 @@ Code untyped_token_fmt( s32 num_tokens, ... ) | |||||||
| 	if ( result->Name == nullptr ) | 	if ( result->Name == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "untyped_fmt: could not cache string" ); | 		log_failure( "untyped_fmt: could not cache string" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
|   | |||||||
| @@ -381,13 +381,13 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy | |||||||
| 	if ( Name_.Len <= 0 )                                                                             \ | 	if ( Name_.Len <= 0 )                                                                             \ | ||||||
| 	{                                                                                                 \ | 	{                                                                                                 \ | ||||||
| 		log_failure( "gen::" stringize(Context_) ": Invalid name length provided - %d",  Name_.Len ); \ | 		log_failure( "gen::" stringize(Context_) ": Invalid name length provided - %d",  Name_.Len ); \ | ||||||
| 		return CodeInvalid;                                                                           \ | 		return InvalidCode;                                                                           \ | ||||||
| 	}                                                                                                 \ | 	}                                                                                                 \ | ||||||
| 																									  \ | 																									  \ | ||||||
| 	if ( Name_.Ptr == nullptr )                                                                       \ | 	if ( Name_.Ptr == nullptr )                                                                       \ | ||||||
| 	{                                                                                                 \ | 	{                                                                                                 \ | ||||||
| 		log_failure( "gen::" stringize(Context_) ": name is null" );                                  \ | 		log_failure( "gen::" stringize(Context_) ": name is null" );                                  \ | ||||||
| 		return CodeInvalid;                                                                           \ | 		return InvalidCode;                                                                           \ | ||||||
| 	}                                                                                                 \ | 	}                                                                                                 \ | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -395,7 +395,7 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy | |||||||
| 	if ( ! Code_ )                                                                            \ | 	if ( ! Code_ )                                                                            \ | ||||||
| 	{                                                                                         \ | 	{                                                                                         \ | ||||||
| 		log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \ | 		log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" ); \ | ||||||
| 		return CodeInvalid;                                                                   \ | 		return InvalidCode;                                                                   \ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #define null_or_invalid_check( Context_, Code_ )                                                \ | #define null_or_invalid_check( Context_, Code_ )                                                \ | ||||||
| @@ -403,19 +403,19 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy | |||||||
| 	if ( ! Code_ )                                                                              \ | 	if ( ! Code_ )                                                                              \ | ||||||
| 	{                                                                                           \ | 	{                                                                                           \ | ||||||
| 		log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" );   \ | 		log_failure( "gen::" stringize(Context_) ": " stringize(Code_) " provided is null" );   \ | ||||||
| 		return CodeInvalid;                                                                     \ | 		return InvalidCode;                                                                     \ | ||||||
| 	}                                                                                           \ | 	}                                                                                           \ | ||||||
| 																								\ | 																								\ | ||||||
| 	if ( Code_->is_invalid() )                                                                  \ | 	if ( Code_->is_invalid() )                                                                  \ | ||||||
| 	{                                                                                           \ | 	{                                                                                           \ | ||||||
| 		log_failure("gen::" stringize(Context_) ": " stringize(Code_) " provided is invalid" ); \ | 		log_failure("gen::" stringize(Context_) ": " stringize(Code_) " provided is invalid" ); \ | ||||||
| 		return CodeInvalid;                                                                     \ | 		return InvalidCode;                                                                     \ | ||||||
| 	}                                                                                           \ | 	}                                                                                           \ | ||||||
| } | } | ||||||
|  |  | ||||||
| #define not_implemented( Context_ )                             \ | #define not_implemented( Context_ )                             \ | ||||||
| 	log_failure( "gen::%s: This function is not implemented" ); \ | 	log_failure( "gen::%s: This function is not implemented" ); \ | ||||||
| 	return CodeInvalid; | 	return InvalidCode; | ||||||
| #pragma endregion Helper Marcos | #pragma endregion Helper Marcos | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -436,7 +436,7 @@ CodeAttributes def_attributes( StrC content ) | |||||||
| 	if ( content.Len <= 0 || content.Ptr == nullptr ) | 	if ( content.Len <= 0 || content.Ptr == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_attributes: Invalid attributes provided" ); | 		log_failure( "gen::def_attributes: Invalid attributes provided" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Code | 	Code | ||||||
| @@ -453,7 +453,7 @@ CodeComment def_comment( StrC content ) | |||||||
| 	if ( content.Len <= 0 || content.Ptr == nullptr ) | 	if ( content.Len <= 0 || content.Ptr == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_comment: Invalid comment provided:" ); | 		log_failure( "gen::def_comment: Invalid comment provided:" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	static char line[ MaxCommentLineLength ]; | 	static char line[ MaxCommentLineLength ]; | ||||||
| @@ -474,15 +474,15 @@ CodeComment def_comment( StrC content ) | |||||||
| 		length++; | 		length++; | ||||||
|  |  | ||||||
| 		str_copy( line, scanner, length ); | 		str_copy( line, scanner, length ); | ||||||
| 		append_fmt(cmt_formatted, "//%.*s", length, line ); | 		append_fmt(& cmt_formatted, "//%.*s", length, line ); | ||||||
| 		mem_set( line, 0, MaxCommentLineLength ); | 		mem_set( line, 0, MaxCommentLineLength ); | ||||||
|  |  | ||||||
| 		scanner += length; | 		scanner += length; | ||||||
| 	} | 	} | ||||||
| 	while ( scanner <= end ); | 	while ( scanner <= end ); | ||||||
|  |  | ||||||
| 	if ( back(cmt_formatted) != '\n' ) | 	if ( * back(& cmt_formatted) != '\n' ) | ||||||
| 		append( cmt_formatted, "\n" ); | 		append( & cmt_formatted, "\n" ); | ||||||
|  |  | ||||||
| 	Code | 	Code | ||||||
| 	result          = make_code(); | 	result          = make_code(); | ||||||
| @@ -490,7 +490,7 @@ CodeComment def_comment( StrC content ) | |||||||
| 	result->Name    = get_cached_string( cmt_formatted ); | 	result->Name    = get_cached_string( cmt_formatted ); | ||||||
| 	result->Content = result->Name; | 	result->Content = result->Name; | ||||||
|  |  | ||||||
| 	free(cmt_formatted); | 	free(& cmt_formatted); | ||||||
|  |  | ||||||
| 	return (CodeComment) result; | 	return (CodeComment) result; | ||||||
| } | } | ||||||
| @@ -502,7 +502,7 @@ CodeConstructor def_constructor( CodeParam params, Code initializer_list, Code b | |||||||
| 	if ( params && params->Type != Parameters ) | 	if ( params && params->Type != Parameters ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure("gen::def_constructor: params must be of Parameters type - %s", params.debug_str()); | 		log_failure("gen::def_constructor: params must be of Parameters type - %s", params.debug_str()); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeConstructor | 	CodeConstructor | ||||||
| @@ -528,7 +528,7 @@ CodeConstructor def_constructor( CodeParam params, Code initializer_list, Code b | |||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 				log_failure("gen::def_constructor: body must be either of Function_Body or Untyped type - %s", body.debug_str()); | 				log_failure("gen::def_constructor: body must be either of Function_Body or Untyped type - %s", body.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result->Type = Constructor; | 		result->Type = Constructor; | ||||||
| @@ -556,13 +556,13 @@ CodeClass def_class( StrC name | |||||||
| 	if ( attributes && attributes->Type != PlatformAttributes ) | 	if ( attributes && attributes->Type != PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", attributes.debug_str() ); | 		log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( parent && ( parent->Type != Class && parent->Type != Struct && parent->Type != Typename && parent->Type != Untyped ) ) | 	if ( parent && ( parent->Type != Class && parent->Type != Struct && parent->Type != Typename && parent->Type != Untyped ) ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_class: parent provided is not type 'Class', 'Struct', 'Typeanme', or 'Untyped': %s", parent.debug_str() ); | 		log_failure( "gen::def_class: parent provided is not type 'Class', 'Struct', 'Typeanme', or 'Untyped': %s", parent.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeClass | 	CodeClass | ||||||
| @@ -580,7 +580,7 @@ CodeClass def_class( StrC name | |||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 				log_failure("gen::def_class: body must be either of Class_Body or Untyped type - %s", body.debug_str()); | 				log_failure("gen::def_class: body must be either of Class_Body or Untyped type - %s", body.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result->Type = Class; | 		result->Type = Class; | ||||||
| @@ -623,7 +623,7 @@ CodeDefine def_define( StrC name, StrC content ) | |||||||
| 	if ( content.Len <= 0 || content.Ptr == nullptr ) | 	if ( content.Len <= 0 || content.Ptr == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_define: Invalid value provided" ); | 		log_failure( "gen::def_define: Invalid value provided" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -648,7 +648,7 @@ CodeDestructor def_destructor( Code body, CodeSpecifiers specifiers ) | |||||||
| 	if ( specifiers && specifiers->Type != Specifiers ) | 	if ( specifiers && specifiers->Type != Specifiers ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_destructor: specifiers was not a 'Specifiers' type: %s", specifiers.debug_str() ); | 		log_failure( "gen::def_destructor: specifiers was not a 'Specifiers' type: %s", specifiers.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeDestructor result = (CodeDestructor) make_code(); | 	CodeDestructor result = (CodeDestructor) make_code(); | ||||||
| @@ -666,7 +666,7 @@ CodeDestructor def_destructor( Code body, CodeSpecifiers specifiers ) | |||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 				log_failure("gen::def_destructor: body must be either of Function_Body or Untyped type - %s", body.debug_str()); | 				log_failure("gen::def_destructor: body must be either of Function_Body or Untyped type - %s", body.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result->Type = Destructor; | 		result->Type = Destructor; | ||||||
| @@ -692,13 +692,13 @@ CodeEnum def_enum( StrC name | |||||||
| 	if ( type && type->Type != Typename ) | 	if ( type && type->Type != Typename ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_enum: enum underlying type provided was not of type Typename: %s", type.debug_str() ); | 		log_failure( "gen::def_enum: enum underlying type provided was not of type Typename: %s", type.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( attributes && attributes->Type != PlatformAttributes ) | 	if ( attributes && attributes->Type != PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_enum: attributes was not a 'PlatformAttributes' type: %s", attributes.debug_str() ); | 		log_failure( "gen::def_enum: attributes was not a 'PlatformAttributes' type: %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeEnum | 	CodeEnum | ||||||
| @@ -716,7 +716,7 @@ CodeEnum def_enum( StrC name | |||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 				log_failure( "gen::def_enum: body must be of Enum_Body or Untyped type %s", body.debug_str()); | 				log_failure( "gen::def_enum: body must be of Enum_Body or Untyped type %s", body.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result->Type = specifier == EnumDecl_Class ? | 		result->Type = specifier == EnumDecl_Class ? | ||||||
| @@ -740,7 +740,7 @@ CodeEnum def_enum( StrC name | |||||||
| 	else if ( result->Type != Enum_Class_Fwd && result->Type != Enum_Fwd ) | 	else if ( result->Type != Enum_Class_Fwd && result->Type != Enum_Fwd ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_enum: enum forward declaration must have an underlying type" ); | 		log_failure( "gen::def_enum: enum forward declaration must have an underlying type" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -751,7 +751,7 @@ CodeExec def_execution( StrC content ) | |||||||
| 	if ( content.Len <= 0 || content.Ptr == nullptr ) | 	if ( content.Len <= 0 || content.Ptr == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_execution: Invalid execution provided" ); | 		log_failure( "gen::def_execution: Invalid execution provided" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Code | 	Code | ||||||
| @@ -773,7 +773,7 @@ CodeExtern def_extern_link( StrC name, Code body ) | |||||||
| 	if ( body->Type != Extern_Linkage_Body && body->Type != Untyped ) | 	if ( body->Type != Extern_Linkage_Body && body->Type != Untyped ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure("gen::def_extern_linkage: body is not of extern_linkage or untyped type %s", body->debug_str()); | 		log_failure("gen::def_extern_linkage: body is not of extern_linkage or untyped type %s", body->debug_str()); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeExtern | 	CodeExtern | ||||||
| @@ -805,7 +805,7 @@ CodeFriend def_friend( Code declaration ) | |||||||
|  |  | ||||||
| 		default: | 		default: | ||||||
| 			log_failure("gen::def_friend: requires declartion to have class, function, operator, or struct - %s", declaration->debug_str()); | 			log_failure("gen::def_friend: requires declartion to have class, function, operator, or struct - %s", declaration->debug_str()); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeFriend | 	CodeFriend | ||||||
| @@ -829,25 +829,25 @@ CodeFn def_function( StrC name | |||||||
| 	if ( params && params->Type != Parameters ) | 	if ( params && params->Type != Parameters ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_function: params was not a `Parameters` type: %s", params.debug_str() ); | 		log_failure( "gen::def_function: params was not a `Parameters` type: %s", params.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( ret_type && ret_type->Type != Typename ) | 	if ( ret_type && ret_type->Type != Typename ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_function: ret_type was not a Typename: %s", ret_type.debug_str() ); | 		log_failure( "gen::def_function: ret_type was not a Typename: %s", ret_type.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( specifiers && specifiers->Type != Specifiers ) | 	if ( specifiers && specifiers->Type != Specifiers ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_function: specifiers was not a `Specifiers` type: %s", specifiers.debug_str() ); | 		log_failure( "gen::def_function: specifiers was not a `Specifiers` type: %s", specifiers.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( attributes && attributes->Type != PlatformAttributes ) | 	if ( attributes && attributes->Type != PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_function: attributes was not a `PlatformAttributes` type: %s", attributes.debug_str() ); | 		log_failure( "gen::def_function: attributes was not a `PlatformAttributes` type: %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeFn | 	CodeFn | ||||||
| @@ -867,7 +867,7 @@ CodeFn def_function( StrC name | |||||||
| 			default: | 			default: | ||||||
| 			{ | 			{ | ||||||
| 				log_failure("gen::def_function: body must be either of Function_Body, Execution, or Untyped type. %s", body->debug_str()); | 				log_failure("gen::def_function: body must be either of Function_Body, Execution, or Untyped type. %s", body->debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -905,7 +905,7 @@ CodeInclude def_include( StrC path, bool foreign ) | |||||||
| 	if ( path.Len <= 0 || path.Ptr == nullptr ) | 	if ( path.Len <= 0 || path.Ptr == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_include: Invalid path provided - %d" ); | 		log_failure( "gen::def_include: Invalid path provided - %d" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	StrC content = foreign ? | 	StrC content = foreign ? | ||||||
| @@ -945,7 +945,7 @@ CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags ) | |||||||
| 	if ( body->Type != Namespace_Body && body->Type != Untyped ) | 	if ( body->Type != Namespace_Body && body->Type != Untyped ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body.debug_str()); | 		log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body.debug_str()); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeNS | 	CodeNS | ||||||
| @@ -968,20 +968,20 @@ CodeOperator def_operator( OperatorT op, StrC nspace | |||||||
| 	if ( attributes && attributes->Type != PlatformAttributes ) | 	if ( attributes && attributes->Type != PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_operator: PlatformAttributes was provided but its not of attributes type: %s", attributes.debug_str() ); | 		log_failure( "gen::def_operator: PlatformAttributes was provided but its not of attributes type: %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( specifiers && specifiers->Type != Specifiers ) | 	if ( specifiers && specifiers->Type != Specifiers ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_operator: Specifiers was provided but its not of specifiers type: %s", specifiers.debug_str() ); | 		log_failure( "gen::def_operator: Specifiers was provided but its not of specifiers type: %s", specifiers.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	OpValidateResult check_result = operator__validate( op, params_code, ret_type, specifiers ); | 	OpValidateResult check_result = operator__validate( op, params_code, ret_type, specifiers ); | ||||||
|  |  | ||||||
| 	if ( check_result == OpValidateResult::Fail ) | 	if ( check_result == OpValidateResult::Fail ) | ||||||
| 	{ | 	{ | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	char const* name = nullptr; | 	char const* name = nullptr; | ||||||
| @@ -1009,7 +1009,7 @@ CodeOperator def_operator( OperatorT op, StrC nspace | |||||||
| 			default: | 			default: | ||||||
| 			{ | 			{ | ||||||
| 				log_failure("gen::def_operator: body must be either of Function_Body, Execution, or Untyped type. %s", body->debug_str()); | 				log_failure("gen::def_operator: body must be either of Function_Body, Execution, or Untyped type. %s", body->debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -1046,7 +1046,7 @@ CodeOpCast def_operator_cast( CodeType type, Code body, CodeSpecifiers const_spe | |||||||
| 	if ( type->Type != Typename ) | 	if ( type->Type != Typename ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_operator_cast: type is not a typename - %s", type.debug_str() ); | 		log_failure( "gen::def_operator_cast: type is not a typename - %s", type.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeOpCast result = (CodeOpCast) make_code(); | 	CodeOpCast result = (CodeOpCast) make_code(); | ||||||
| @@ -1058,7 +1058,7 @@ CodeOpCast def_operator_cast( CodeType type, Code body, CodeSpecifiers const_spe | |||||||
| 		if ( body->Type != Function_Body && body->Type != Execution ) | 		if ( body->Type != Function_Body && body->Type != Execution ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "gen::def_operator_cast: body is not of function body or execution type - %s", body.debug_str() ); | 			log_failure( "gen::def_operator_cast: body is not of function body or execution type - %s", body.debug_str() ); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result->Body = body; | 		result->Body = body; | ||||||
| @@ -1087,13 +1087,13 @@ CodeParam def_param( CodeType type, StrC name, Code value ) | |||||||
| 	if ( type->Type != Typename ) | 	if ( type->Type != Typename ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_param: type is not a typename - %s", type.debug_str() ); | 		log_failure( "gen::def_param: type is not a typename - %s", type.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( value && value->Type != Untyped ) | 	if ( value && value->Type != Untyped ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_param: value is not untyped - %s", value.debug_str() ); | 		log_failure( "gen::def_param: value is not untyped - %s", value.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeParam | 	CodeParam | ||||||
| @@ -1118,7 +1118,7 @@ CodePragma def_pragma( StrC directive ) | |||||||
| 	if ( directive.Len <= 0 || directive.Ptr == nullptr ) | 	if ( directive.Len <= 0 || directive.Ptr == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_comment: Invalid comment provided:" ); | 		log_failure( "gen::def_comment: Invalid comment provided:" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodePragma | 	CodePragma | ||||||
| @@ -1136,7 +1136,7 @@ CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC expr ) | |||||||
| 	if ( expr.Len <= 0 || expr.Ptr == nullptr ) | 	if ( expr.Len <= 0 || expr.Ptr == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_comment: Invalid comment provided:" ); | 		log_failure( "gen::def_comment: Invalid comment provided:" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodePreprocessCond | 	CodePreprocessCond | ||||||
| @@ -1184,19 +1184,19 @@ CodeStruct def_struct( StrC name | |||||||
| 	if ( attributes && attributes->Type != PlatformAttributes ) | 	if ( attributes && attributes->Type != PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_struct: attributes was not a `PlatformAttributes` type - %s", attributes.debug_str() ); | 		log_failure( "gen::def_struct: attributes was not a `PlatformAttributes` type - %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( parent && parent->Type != Typename ) | 	if ( parent && parent->Type != Typename ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_struct: parent was not a `Struct` type - %s", parent.debug_str() ); | 		log_failure( "gen::def_struct: parent was not a `Struct` type - %s", parent.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( body && body->Type != Struct_Body ) | 	if ( body && body->Type != Struct_Body ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_struct: body was not a Struct_Body type - %s", body.debug_str() ); | 		log_failure( "gen::def_struct: body was not a Struct_Body type - %s", body.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeStruct | 	CodeStruct | ||||||
| @@ -1243,7 +1243,7 @@ CodeTemplate def_template( CodeParam params, Code declaration, ModuleFlag mflags | |||||||
| 	if ( params && params->Type != ECode::Parameters ) | 	if ( params && params->Type != ECode::Parameters ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_template: params is not of parameters type - %s", params.debug_str() ); | 		log_failure( "gen::def_template: params is not of parameters type - %s", params.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	switch (declaration->Type ) | 	switch (declaration->Type ) | ||||||
| @@ -1276,19 +1276,19 @@ CodeType def_type( StrC name, Code arrayexpr, CodeSpecifiers specifiers, CodeAtt | |||||||
| 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_type: attributes is not of attributes type - %s", attributes.debug_str() ); | 		log_failure( "gen::def_type: attributes is not of attributes type - %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( specifiers && specifiers->Type != ECode::Specifiers ) | 	if ( specifiers && specifiers->Type != ECode::Specifiers ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_type: specifiers is not of specifiers type - %s", specifiers.debug_str() ); | 		log_failure( "gen::def_type: specifiers is not of specifiers type - %s", specifiers.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( arrayexpr && arrayexpr->Type != ECode::Untyped ) | 	if ( arrayexpr && arrayexpr->Type != ECode::Untyped ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", arrayexpr->debug_str() ); | 		log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", arrayexpr->debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeType | 	CodeType | ||||||
| @@ -1330,13 +1330,13 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module | |||||||
| 			break; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			log_failure( "gen::def_typedef: type was not a Class, Enum, Function Forward, Struct, Typename, or Union - %s", type.debug_str() ); | 			log_failure( "gen::def_typedef: type was not a Class, Enum, Function Forward, Struct, Typename, or Union - %s", type.debug_str() ); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_typedef: attributes was not a PlatformAttributes - %s", attributes.debug_str() ); | 		log_failure( "gen::def_typedef: attributes was not a PlatformAttributes - %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Registering the type. | 	// Registering the type. | ||||||
| @@ -1345,7 +1345,7 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module | |||||||
| 	if ( ! registered_type ) | 	if ( ! registered_type ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_typedef: failed to register type" ); | 		log_failure( "gen::def_typedef: failed to register type" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeTypedef | 	CodeTypedef | ||||||
| @@ -1360,7 +1360,7 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module | |||||||
| 		if (type->Type != Untyped) | 		if (type->Type != Untyped) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "gen::def_typedef: name was empty and type was not untyped (indicating its a function typedef) - %s", type.debug_str() ); | 			log_failure( "gen::def_typedef: name was empty and type was not untyped (indicating its a function typedef) - %s", type.debug_str() ); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result->Name       = get_cached_string( type->Name ); | 		result->Name       = get_cached_string( type->Name ); | ||||||
| @@ -1382,13 +1382,13 @@ CodeUnion def_union( StrC name, Code body, CodeAttributes attributes, ModuleFlag | |||||||
| 	if ( body->Type != ECode::Union_Body ) | 	if ( body->Type != ECode::Union_Body ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_union: body was not a Union_Body type - %s", body.debug_str() ); | 		log_failure( "gen::def_union: body was not a Union_Body type - %s", body.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_union: attributes was not a PlatformAttributes type - %s", attributes.debug_str() ); | 		log_failure( "gen::def_union: attributes was not a PlatformAttributes type - %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeUnion | 	CodeUnion | ||||||
| @@ -1419,13 +1419,13 @@ CodeUsing def_using( StrC name, CodeType type | |||||||
| 	if ( ! register_type ) | 	if ( ! register_type ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_using: failed to register type" ); | 		log_failure( "gen::def_using: failed to register type" ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_using: attributes was not a PlatformAttributes type - %s", attributes.debug_str() ); | 		log_failure( "gen::def_using: attributes was not a PlatformAttributes type - %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeUsing | 	CodeUsing | ||||||
| @@ -1465,25 +1465,25 @@ CodeVar def_variable( CodeType type, StrC name, Code value | |||||||
| 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | 	if ( attributes && attributes->Type != ECode::PlatformAttributes ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_variable: attributes was not a `PlatformAttributes` type - %s", attributes.debug_str() ); | 		log_failure( "gen::def_variable: attributes was not a `PlatformAttributes` type - %s", attributes.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( specifiers && specifiers->Type != ECode::Specifiers ) | 	if ( specifiers && specifiers->Type != ECode::Specifiers ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_variable: specifiers was not a `Specifiers` type - %s", specifiers.debug_str() ); | 		log_failure( "gen::def_variable: specifiers was not a `Specifiers` type - %s", specifiers.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( type->Type != ECode::Typename ) | 	if ( type->Type != ECode::Typename ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_variable: type was not a Typename - %s", type.debug_str() ); | 		log_failure( "gen::def_variable: type was not a Typename - %s", type.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( value && value->Type != ECode::Untyped ) | 	if ( value && value->Type != ECode::Untyped ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_variable: value was not a `Untyped` type - %s", value.debug_str() ); | 		log_failure( "gen::def_variable: value was not a `Untyped` type - %s", value.debug_str() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeVar | 	CodeVar | ||||||
| @@ -1513,7 +1513,7 @@ using namespace ECode;                                                        \ | |||||||
| if ( num <= 0 )                                                               \ | if ( num <= 0 )                                                               \ | ||||||
| {                                                                             \ | {                                                                             \ | ||||||
| 	log_failure("gen::" stringize(Name_) ": num cannot be zero or negative"); \ | 	log_failure("gen::" stringize(Name_) ": num cannot be zero or negative"); \ | ||||||
| 	return CodeInvalid;                                                       \ | 	return InvalidCode;                                                       \ | ||||||
| } | } | ||||||
|  |  | ||||||
| #define def_body_code_array_start( Name_ )                                     \ | #define def_body_code_array_start( Name_ )                                     \ | ||||||
| @@ -1522,13 +1522,13 @@ using namespace ECode;                                                         \ | |||||||
| if ( num <= 0 )                                                                \ | if ( num <= 0 )                                                                \ | ||||||
| {                                                                              \ | {                                                                              \ | ||||||
| 	log_failure("gen::" stringize(Name_) ": num cannot be zero or negative");  \ | 	log_failure("gen::" stringize(Name_) ": num cannot be zero or negative");  \ | ||||||
| 	return CodeInvalid;                                                        \ | 	return InvalidCode;                                                        \ | ||||||
| }                                                                              \ | }                                                                              \ | ||||||
| 																			   \ | 																			   \ | ||||||
| if ( codes == nullptr )                                                        \ | if ( codes == nullptr )                                                        \ | ||||||
| {                                                                              \ | {                                                                              \ | ||||||
| 	log_failure("gen::" stringize(Name_)" : Provided a null array of codes");  \ | 	log_failure("gen::" stringize(Name_)" : Provided a null array of codes");  \ | ||||||
| 	return CodeInvalid;                                                        \ | 	return InvalidCode;                                                        \ | ||||||
| } | } | ||||||
|  |  | ||||||
| #pragma endregion Helper Macros for def_**_body functions | #pragma endregion Helper Macros for def_**_body functions | ||||||
| @@ -1552,14 +1552,14 @@ CodeBody def_class_body( s32 num, ... ) | |||||||
| 			log_failure("gen::" | 			log_failure("gen::" | ||||||
| 						"def_class_body" | 						"def_class_body" | ||||||
| 						": Provided an null entry"); | 						": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_CLASS_UNALLOWED_TYPES | 			GEN_AST_BODY_CLASS_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_class_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_class_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -1589,14 +1589,14 @@ CodeBody def_class_body( s32 num, Code* codes ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_class_body" ": Provided an null entry"); | 			log_failure("gen::" "def_class_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_CLASS_UNALLOWED_TYPES | 			GEN_AST_BODY_CLASS_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_class_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_class_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -1627,13 +1627,13 @@ CodeBody def_enum_body( s32 num, ... ) | |||||||
| 		if ( ! entry ) | 		if ( ! entry ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_enum_body: Provided a null entry"); | 			log_failure("gen::def_enum_body: Provided a null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( entry->Type != Untyped && entry->Type != Comment ) | 		if ( entry->Type != Untyped && entry->Type != Comment ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_enum_body: Entry type is not allowed - %s. Must be of untyped or comment type.", entry.debug_str() ); | 			log_failure("gen::def_enum_body: Entry type is not allowed - %s. Must be of untyped or comment type.", entry.debug_str() ); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result.append( entry ); | 		result.append( entry ); | ||||||
| @@ -1659,13 +1659,13 @@ CodeBody def_enum_body( s32 num, Code* codes ) | |||||||
| 		if ( ! entry ) | 		if ( ! entry ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_enum_body: Provided a null entry"); | 			log_failure("gen::def_enum_body: Provided a null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( entry->Type != Untyped && entry->Type != Comment ) | 		if ( entry->Type != Untyped && entry->Type != Comment ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_enum_body: Entry type is not allowed: %s", entry.debug_str() ); | 			log_failure("gen::def_enum_body: Entry type is not allowed: %s", entry.debug_str() ); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result.append( entry ); | 		result.append( entry ); | ||||||
| @@ -1693,14 +1693,14 @@ CodeBody def_export_body( s32 num, ... ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_export_body" ": Provided an null entry"); | 			log_failure("gen::" "def_export_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_EXPORT_UNALLOWED_TYPES | 			GEN_AST_BODY_EXPORT_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_export_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_export_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -1730,14 +1730,14 @@ CodeBody def_export_body( s32 num, Code* codes ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_export_body" ": Provided an null entry"); | 			log_failure("gen::" "def_export_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_EXPORT_UNALLOWED_TYPES | 			GEN_AST_BODY_EXPORT_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_export_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_export_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -1768,14 +1768,14 @@ CodeBody def_extern_link_body( s32 num, ... ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry"); | 			log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | 			GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_extern_linkage_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_extern_linkage_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -1805,14 +1805,14 @@ CodeBody def_extern_link_body( s32 num, Code* codes ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry"); | 			log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | 			GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_extern_linkage_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_extern_linkage_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -1844,7 +1844,7 @@ CodeBody def_function_body( s32 num, ... ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" stringize(def_function_body) ": Provided an null entry"); | 			log_failure("gen::" stringize(def_function_body) ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| @@ -1852,7 +1852,7 @@ CodeBody def_function_body( s32 num, ... ) | |||||||
|  |  | ||||||
| 			GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES | 			GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" stringize(def_function_body) ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" stringize(def_function_body) ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -1882,14 +1882,14 @@ CodeBody def_function_body( s32 num, Code* codes ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_function_body" ": Provided an null entry"); | 			log_failure("gen::" "def_function_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES | 			GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_function_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_function_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -1919,18 +1919,18 @@ CodeBody def_global_body( s32 num, ... ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_global_body" ": Provided an null entry"); | 			log_failure("gen::" "def_global_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			case Global_Body: | 			case Global_Body: | ||||||
| 				result.append( entry.cast<CodeBody>() ) ; | 				result.append( entry.code_cast<CodeBody>() ) ; | ||||||
| 				continue; | 				continue; | ||||||
|  |  | ||||||
| 			GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | 			GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_global_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_global_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return (*Code::Invalid.ast); | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -1960,18 +1960,18 @@ CodeBody def_global_body( s32 num, Code* codes ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_global_body" ": Provided an null entry"); | 			log_failure("gen::" "def_global_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			case Global_Body: | 			case Global_Body: | ||||||
| 				result.append( entry.cast<CodeBody>() ) ; | 				result.append( entry.code_cast<CodeBody>() ) ; | ||||||
| 				continue; | 				continue; | ||||||
|  |  | ||||||
| 			GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | 			GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_global_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_global_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -2002,14 +2002,14 @@ CodeBody def_namespace_body( s32 num, ... ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_namespace_body" ": Provided an null entry"); | 			log_failure("gen::" "def_namespace_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES | 			GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_namespace_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_namespace_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -2039,14 +2039,14 @@ CodeBody def_namespace_body( s32 num, Code* codes ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_namespace_body" ": Provided an null entry"); | 			log_failure("gen::" "def_namespace_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES | 			GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_namespace_body" ": Entry type is not allowed: %s", entry.debug_str() ); | 				log_failure("gen::" "def_namespace_body" ": Entry type is not allowed: %s", entry.debug_str() ); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: break; | 			default: break; | ||||||
| 		} | 		} | ||||||
| @@ -2073,7 +2073,7 @@ CodeParam def_params( s32 num, ... ) | |||||||
| 	if ( param->Type != Parameters ) | 	if ( param->Type != Parameters ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 ); | 		log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeParam result = (CodeParam) param.duplicate(); | 	CodeParam result = (CodeParam) param.duplicate(); | ||||||
| @@ -2086,7 +2086,7 @@ CodeParam def_params( s32 num, ... ) | |||||||
| 		if ( param->Type != Parameters ) | 		if ( param->Type != Parameters ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 ); | 			log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 ); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result.append( param ); | 		result.append( param ); | ||||||
| @@ -2104,13 +2104,13 @@ CodeParam def_params( s32 num, CodeParam* codes ) | |||||||
| 	if ( current.ast == nullptr )                                                                               \ | 	if ( current.ast == nullptr )                                                                               \ | ||||||
| 	{                                                                                                           \ | 	{                                                                                                           \ | ||||||
| 		log_failure("gen::def_params: Provide a null code in codes array");                                     \ | 		log_failure("gen::def_params: Provide a null code in codes array");                                     \ | ||||||
| 		return CodeInvalid;                                                                                     \ | 		return InvalidCode;                                                                                     \ | ||||||
| 	}                                                                                                           \ | 	}                                                                                                           \ | ||||||
| 																												\ | 																												\ | ||||||
| 	if (current->Type != Parameters )                                                                           \ | 	if (current->Type != Parameters )                                                                           \ | ||||||
| 	{                                                                                                           \ | 	{                                                                                                           \ | ||||||
| 		log_failure("gen::def_params: Code in coes array is not of paramter type - %s", current.debug_str() );  \ | 		log_failure("gen::def_params: Code in coes array is not of paramter type - %s", current.debug_str() );  \ | ||||||
| 		return CodeInvalid;                                                                                     \ | 		return InvalidCode;                                                                                     \ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeParam current = (CodeParam) codes->duplicate(); | 	CodeParam current = (CodeParam) codes->duplicate(); | ||||||
| @@ -2137,13 +2137,13 @@ CodeSpecifiers def_specifiers( s32 num, ... ) | |||||||
| 	if ( num <= 0 ) | 	if ( num <= 0 ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure("gen::def_specifiers: num cannot be zero or less"); | 		log_failure("gen::def_specifiers: num cannot be zero or less"); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( num > AST::ArrSpecs_Cap ) | 	if ( num > AST::ArrSpecs_Cap ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num); | 		log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeSpecifiers | 	CodeSpecifiers | ||||||
| @@ -2169,13 +2169,13 @@ CodeSpecifiers def_specifiers( s32 num, SpecifierT* specs ) | |||||||
| 	if ( num <= 0 ) | 	if ( num <= 0 ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure("gen::def_specifiers: num cannot be zero or less"); | 		log_failure("gen::def_specifiers: num cannot be zero or less"); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( num > AST::ArrSpecs_Cap ) | 	if ( num > AST::ArrSpecs_Cap ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num); | 		log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeSpecifiers | 	CodeSpecifiers | ||||||
| @@ -2211,14 +2211,14 @@ CodeBody def_struct_body( s32 num, ... ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_struct_body" ": Provided an null entry"); | 			log_failure("gen::" "def_struct_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_STRUCT_UNALLOWED_TYPES | 			GEN_AST_BODY_STRUCT_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_struct_body" ": Entry type is not allowed: %s", entry.debug_str()); | 				log_failure("gen::" "def_struct_body" ": Entry type is not allowed: %s", entry.debug_str()); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -2248,14 +2248,14 @@ CodeBody def_struct_body( s32 num, Code* codes ) | |||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::" "def_struct_body" ": Provided an null entry"); | 			log_failure("gen::" "def_struct_body" ": Provided an null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (entry->Type) | 		switch (entry->Type) | ||||||
| 		{ | 		{ | ||||||
| 			GEN_AST_BODY_STRUCT_UNALLOWED_TYPES | 			GEN_AST_BODY_STRUCT_UNALLOWED_TYPES | ||||||
| 				log_failure("gen::" "def_struct_body" ": Entry type is not allowed: %s", entry.debug_str() ); | 				log_failure("gen::" "def_struct_body" ": Entry type is not allowed: %s", entry.debug_str() ); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 			break; | 			break; | ||||||
| @@ -2286,13 +2286,13 @@ CodeBody def_union_body( s32 num, ... ) | |||||||
| 		if ( ! entry ) | 		if ( ! entry ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_union_body: Provided a null entry"); | 			log_failure("gen::def_union_body: Provided a null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( entry->Type != Untyped && entry->Type != Comment ) | 		if ( entry->Type != Untyped && entry->Type != Comment ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_union_body: Entry type is not allowed - %s. Must be of untyped or comment type.", entry.debug_str() ); | 			log_failure("gen::def_union_body: Entry type is not allowed - %s. Must be of untyped or comment type.", entry.debug_str() ); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result.append( entry ); | 		result.append( entry ); | ||||||
| @@ -2318,13 +2318,13 @@ CodeBody def_union_body( s32 num, CodeUnion* codes ) | |||||||
| 		if ( ! entry ) | 		if ( ! entry ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_union_body: Provided a null entry"); | 			log_failure("gen::def_union_body: Provided a null entry"); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( entry->Type != Untyped && entry->Type != Comment ) | 		if ( entry->Type != Untyped && entry->Type != Comment ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_union_body: Entry type is not allowed: %s", entry.debug_str() ); | 			log_failure("gen::def_union_body: Entry type is not allowed: %s", entry.debug_str() ); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result.append( entry ); | 		result.append( entry ); | ||||||
|   | |||||||
| @@ -93,7 +93,7 @@ struct Token | |||||||
|  |  | ||||||
| 		StrC type_str = ETokType::to_str( Type ); | 		StrC type_str = ETokType::to_str( Type ); | ||||||
|  |  | ||||||
| 		append_fmt( result, "Line: %d Column: %d, Type: %.*s Content: %.*s" | 		append_fmt( & result, "Line: %d Column: %d, Type: %.*s Content: %.*s" | ||||||
| 			, Line, Column | 			, Line, Column | ||||||
| 			, type_str.Len, type_str.Ptr | 			, type_str.Len, type_str.Ptr | ||||||
| 			, Length, Text | 			, Length, Text | ||||||
| @@ -222,7 +222,7 @@ s32 lex_preprocessor_directive( | |||||||
| 	, Token&           token ) | 	, Token&           token ) | ||||||
| { | { | ||||||
| 	char const* hash = scanner; | 	char const* hash = scanner; | ||||||
| 	append(Tokens, { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } ); | 	append( & Tokens, { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } ); | ||||||
|  |  | ||||||
| 	move_forward(); | 	move_forward(); | ||||||
| 	SkipWhitespace(); | 	SkipWhitespace(); | ||||||
| @@ -298,14 +298,14 @@ s32 lex_preprocessor_directive( | |||||||
|  |  | ||||||
| 		token.Length = token.Length + token.Text - hash; | 		token.Length = token.Length + token.Text - hash; | ||||||
| 		token.Text   = hash; | 		token.Text   = hash; | ||||||
| 		append(Tokens, token ); | 		append( & Tokens, token ); | ||||||
| 		return Lex_Continue; // Skip found token, its all handled here. | 		return Lex_Continue; // Skip found token, its all handled here. | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( token.Type == TokType::Preprocess_Else || token.Type == TokType::Preprocess_EndIf ) | 	if ( token.Type == TokType::Preprocess_Else || token.Type == TokType::Preprocess_EndIf ) | ||||||
| 	{ | 	{ | ||||||
| 		token.Flags |= TF_Preprocess_Cond; | 		token.Flags |= TF_Preprocess_Cond; | ||||||
| 		append(Tokens, token ); | 		append( & Tokens, token ); | ||||||
| 		end_line(); | 		end_line(); | ||||||
| 		return Lex_Continue; | 		return Lex_Continue; | ||||||
| 	} | 	} | ||||||
| @@ -314,7 +314,7 @@ s32 lex_preprocessor_directive( | |||||||
| 		token.Flags |= TF_Preprocess_Cond; | 		token.Flags |= TF_Preprocess_Cond; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	append(Tokens, token ); | 	append( & Tokens, token ); | ||||||
|  |  | ||||||
| 	SkipWhitespace(); | 	SkipWhitespace(); | ||||||
|  |  | ||||||
| @@ -338,10 +338,10 @@ s32 lex_preprocessor_directive( | |||||||
| 			name.Length++; | 			name.Length++; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		append(Tokens, name ); | 		append( & Tokens, name ); | ||||||
|  |  | ||||||
| 		u64 key = crc32( name.Text, name.Length ); | 		u64 key = crc32( name.Text, name.Length ); | ||||||
| 		set<StrC>(defines, key, name ); | 		set<StrC>(& defines, key, name ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Token preprocess_content = { scanner, 0, TokType::Preprocess_Content, line, column, TF_Preprocess }; | 	Token preprocess_content = { scanner, 0, TokType::Preprocess_Content, line, column, TF_Preprocess }; | ||||||
| @@ -384,7 +384,7 @@ s32 lex_preprocessor_directive( | |||||||
| 			move_forward(); | 			move_forward(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		append(Tokens, preprocess_content ); | 		append( & Tokens, preprocess_content ); | ||||||
| 		return Lex_Continue; // Skip found token, its all handled here. | 		return Lex_Continue; // Skip found token, its all handled here. | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -446,7 +446,7 @@ s32 lex_preprocessor_directive( | |||||||
| 		preprocess_content.Length++; | 		preprocess_content.Length++; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	append(Tokens, preprocess_content ); | 	append( & Tokens, preprocess_content ); | ||||||
| 	return Lex_Continue; // Skip found token, its all handled here. | 	return Lex_Continue; // Skip found token, its all handled here. | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -461,7 +461,7 @@ void lex_found_token( StrC& content | |||||||
| { | { | ||||||
| 	if ( token.Type != TokType::Invalid ) | 	if ( token.Type != TokType::Invalid ) | ||||||
| 	{ | 	{ | ||||||
| 		append(Tokens, token ); | 		append( & Tokens, token ); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -488,7 +488,7 @@ void lex_found_token( StrC& content | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		token.Type = type; | 		token.Type = type; | ||||||
| 		append(Tokens, token ); | 		append( & Tokens, token ); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -498,7 +498,7 @@ void lex_found_token( StrC& content | |||||||
| 	{ | 	{ | ||||||
| 		token.Type   = type; | 		token.Type   = type; | ||||||
| 		token.Flags |= TF_Specifier; | 		token.Flags |= TF_Specifier; | ||||||
| 		append(Tokens, token ); | 		append( & Tokens, token ); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -506,7 +506,7 @@ void lex_found_token( StrC& content | |||||||
| 	if ( type != TokType::Invalid ) | 	if ( type != TokType::Invalid ) | ||||||
| 	{ | 	{ | ||||||
| 		token.Type = type; | 		token.Type = type; | ||||||
| 		append(Tokens, token ); | 		append( & Tokens, token ); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -558,7 +558,7 @@ void lex_found_token( StrC& content | |||||||
| 		token.Type = TokType::Identifier; | 		token.Type = TokType::Identifier; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	append(Tokens, token ); | 	append( & Tokens, token ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -579,7 +579,7 @@ TokArray lex( StrC content ) | |||||||
| 	if ( left <= 0 ) | 	if ( left <= 0 ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "gen::lex: no tokens found (only whitespace provided)" ); | 		log_failure( "gen::lex: no tokens found (only whitespace provided)" ); | ||||||
| 		return { { nullptr }, 0 }; | 		return { {}, 0 }; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	foreach( StringCached, entry, PreprocessorDefines ) | 	foreach( StringCached, entry, PreprocessorDefines ) | ||||||
| @@ -597,7 +597,7 @@ TokArray lex( StrC content ) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		u64 key = crc32( entry.Data, length ); | 		u64 key = crc32( entry.Data, length ); | ||||||
| 		set<StrC>(defines, key, entry ); | 		set<StrC>(& defines, key, entry ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	clear(Tokens); | 	clear(Tokens); | ||||||
| @@ -630,7 +630,7 @@ TokArray lex( StrC content ) | |||||||
| 				token.Type = TokType::NewLine; | 				token.Type = TokType::NewLine; | ||||||
| 				token.Length++; | 				token.Length++; | ||||||
|  |  | ||||||
| 				append(Tokens, token ); | 				append( & Tokens, token ); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -652,7 +652,7 @@ TokArray lex( StrC content ) | |||||||
| 						continue; | 						continue; | ||||||
|  |  | ||||||
| 					case Lex_ReturnNull: | 					case Lex_ReturnNull: | ||||||
| 						return { { nullptr }, 0 }; | 						return { {}, 0 }; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			case '.': | 			case '.': | ||||||
| @@ -1099,7 +1099,7 @@ TokArray lex( StrC content ) | |||||||
| 							move_forward(); | 							move_forward(); | ||||||
| 							token.Length++; | 							token.Length++; | ||||||
| 						} | 						} | ||||||
| 						append(Tokens, token ); | 						append( & Tokens, token ); | ||||||
| 						continue; | 						continue; | ||||||
| 					} | 					} | ||||||
| 					else if ( current == '*' ) | 					else if ( current == '*' ) | ||||||
| @@ -1135,7 +1135,7 @@ TokArray lex( StrC content ) | |||||||
| 							move_forward(); | 							move_forward(); | ||||||
| 							token.Length++; | 							token.Length++; | ||||||
| 						} | 						} | ||||||
| 						append(Tokens, token ); | 						append( & Tokens, token ); | ||||||
| 						// end_line(); | 						// end_line(); | ||||||
| 						continue; | 						continue; | ||||||
| 					} | 					} | ||||||
| @@ -1256,7 +1256,7 @@ TokArray lex( StrC content ) | |||||||
| 	if ( num(Tokens) == 0 ) | 	if ( num(Tokens) == 0 ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Failed to lex any tokens" ); | 		log_failure( "Failed to lex any tokens" ); | ||||||
| 		return { { nullptr }, 0 }; | 		return { {}, 0 }; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	clear(defines); | 	clear(defines); | ||||||
|   | |||||||
| @@ -52,24 +52,24 @@ struct ParseContext | |||||||
|  |  | ||||||
| 		sptr        length  = scope_start.Length; | 		sptr        length  = scope_start.Length; | ||||||
| 		char const* current = scope_start.Text + length; | 		char const* current = scope_start.Text + length; | ||||||
| 		while ( current <= back(Tokens.Arr).Text && *current != '\n' && length < 74 ) | 		while ( current <= back( & Tokens.Arr)->Text && *current != '\n' && length < 74 ) | ||||||
| 		{ | 		{ | ||||||
| 			current++; | 			current++; | ||||||
| 			length++; | 			length++; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		String line = string_make( GlobalAllocator, { length, scope_start.Text } ); | 		String line = string_make( GlobalAllocator, { length, scope_start.Text } ); | ||||||
| 		append_fmt( result, "\tScope    : %s\n", line ); | 		append_fmt( & result, "\tScope    : %s\n", line ); | ||||||
| 		free(line); | 		free(& line); | ||||||
|  |  | ||||||
| 		sptr   dist            = (sptr)last_valid.Text - (sptr)scope_start.Text + 2; | 		sptr   dist            = (sptr)last_valid.Text - (sptr)scope_start.Text + 2; | ||||||
| 		sptr   length_from_err = dist; | 		sptr   length_from_err = dist; | ||||||
| 		String line_from_err   = string_make( GlobalAllocator, { length_from_err, last_valid.Text } ); | 		String line_from_err   = string_make( GlobalAllocator, { length_from_err, last_valid.Text } ); | ||||||
|  |  | ||||||
| 		if ( length_from_err < 100 ) | 		if ( length_from_err < 100 ) | ||||||
| 			append_fmt(result, "\t(%d, %d):%*c\n", last_valid.Line, last_valid.Column, length_from_err, '^' ); | 			append_fmt(& result, "\t(%d, %d):%*c\n", last_valid.Line, last_valid.Column, length_from_err, '^' ); | ||||||
| 		else | 		else | ||||||
| 			append_fmt(result, "\t(%d, %d)\n", last_valid.Line, last_valid.Column ); | 			append_fmt(& result, "\t(%d, %d)\n", last_valid.Line, last_valid.Column ); | ||||||
|  |  | ||||||
| 		StackNode* curr_scope = Scope; | 		StackNode* curr_scope = Scope; | ||||||
| 		s32 level = 0; | 		s32 level = 0; | ||||||
| @@ -77,11 +77,11 @@ struct ParseContext | |||||||
| 		{ | 		{ | ||||||
| 			if ( curr_scope->Name ) | 			if ( curr_scope->Name ) | ||||||
| 			{ | 			{ | ||||||
| 				append_fmt(result, "\t%d: %s, AST Name: %.*s\n", level, curr_scope->ProcName.Ptr, curr_scope->Name.Length, curr_scope->Name.Text ); | 				append_fmt(& result, "\t%d: %s, AST Name: %.*s\n", level, curr_scope->ProcName.Ptr, curr_scope->Name.Length, curr_scope->Name.Text ); | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				append_fmt(result, "\t%d: %s\n", level, curr_scope->ProcName.Ptr ); | 				append_fmt(& result, "\t%d: %s\n", level, curr_scope->ProcName.Ptr ); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			curr_scope = curr_scope->Prev; | 			curr_scope = curr_scope->Prev; | ||||||
| @@ -132,12 +132,12 @@ bool TokArray::__eat( TokType type ) | |||||||
| internal | internal | ||||||
| void init() | void init() | ||||||
| { | { | ||||||
| 	Tokens = array_init_reserve<Token>( allocator_info(LexArena) | 	Tokens = array_init_reserve<Token>( allocator_info( & LexArena) | ||||||
| 		, ( LexAllocator_Size - sizeof( ArrayHeader ) ) / sizeof(Token) | 		, ( LexAllocator_Size - sizeof( ArrayHeader ) ) / sizeof(Token) | ||||||
| 	); | 	); | ||||||
|  |  | ||||||
| 	fixed_arena_init(defines_map_arena); | 	fixed_arena_init(& defines_map_arena); | ||||||
| 	defines = hashtable_init_reserve<StrC>( allocator_info(defines_map_arena), 256 ); | 	defines = hashtable_init_reserve<StrC>( allocator_info( & defines_map_arena), 256 ); | ||||||
| } | } | ||||||
|  |  | ||||||
| internal | internal | ||||||
| @@ -153,13 +153,13 @@ if ( def.Len <= 0 )                                                            \ | |||||||
| {                                                                              \ | {                                                                              \ | ||||||
| 	log_failure( "gen::" stringize(__func__) ": length must greater than 0" ); \ | 	log_failure( "gen::" stringize(__func__) ": length must greater than 0" ); \ | ||||||
| 	parser::Context.pop();                                                     \ | 	parser::Context.pop();                                                     \ | ||||||
| 	return CodeInvalid;                                                        \ | 	return InvalidCode;                                                        \ | ||||||
| }                                                                              \ | }                                                                              \ | ||||||
| if ( def.Ptr == nullptr )                                                      \ | if ( def.Ptr == nullptr )                                                      \ | ||||||
| {                                                                              \ | {                                                                              \ | ||||||
| 	log_failure( "gen::" stringize(__func__) ": def was null" );               \ | 	log_failure( "gen::" stringize(__func__) ": def was null" );               \ | ||||||
| 	parser::Context.pop();                                                     \ | 	parser::Context.pop();                                                     \ | ||||||
| 	return CodeInvalid;                                                        \ | 	return InvalidCode;                                                        \ | ||||||
| } | } | ||||||
|  |  | ||||||
| #	define currtok_noskip Context.Tokens.current( dont_skip_formatting ) | #	define currtok_noskip Context.Tokens.current( dont_skip_formatting ) | ||||||
| @@ -290,7 +290,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
| 			if ( tokleft ) | 			if ( tokleft ) | ||||||
| 				move_fwd(); | 				move_fwd(); | ||||||
|  |  | ||||||
| 			append( content, cut_ptr, cut_length ); | 			append( & content, cut_ptr, cut_length ); | ||||||
| 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| @@ -312,7 +312,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
| 			if ( tokleft ) | 			if ( tokleft ) | ||||||
| 				move_fwd(); | 				move_fwd(); | ||||||
|  |  | ||||||
| 			append( content, cut_ptr, cut_length ); | 			append( & content, cut_ptr, cut_length ); | ||||||
| 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| @@ -326,7 +326,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
| 			scanner += 2; | 			scanner += 2; | ||||||
| 			tokleft -= 2; | 			tokleft -= 2; | ||||||
|  |  | ||||||
| 			append( content,  cut_ptr, cut_length ); | 			append( & content,  cut_ptr, cut_length ); | ||||||
| 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| @@ -345,7 +345,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
| 			if (tokleft) | 			if (tokleft) | ||||||
| 				move_fwd(); | 				move_fwd(); | ||||||
|  |  | ||||||
| 			append( content,  cut_ptr, cut_length ); | 			append( & content,  cut_ptr, cut_length ); | ||||||
| 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| @@ -354,10 +354,10 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
| 		if (scanner[0] == '\t') | 		if (scanner[0] == '\t') | ||||||
| 		{ | 		{ | ||||||
| 			if (pos > last_cut) | 			if (pos > last_cut) | ||||||
| 				append( content, cut_ptr, cut_length); | 				append( & content, cut_ptr, cut_length); | ||||||
|  |  | ||||||
| 			if ( back( content ) != ' ' ) | 			if ( * back( & content ) != ' ' ) | ||||||
| 				append( content, ' '); | 				append( & content, ' '); | ||||||
|  |  | ||||||
| 			move_fwd(); | 			move_fwd(); | ||||||
| 			last_cut = sptr(scanner) - sptr(raw_text.Ptr); | 			last_cut = sptr(scanner) - sptr(raw_text.Ptr); | ||||||
| @@ -373,17 +373,17 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
| 				scanner += 2; | 				scanner += 2; | ||||||
| 				tokleft -= 2; | 				tokleft -= 2; | ||||||
|  |  | ||||||
| 				append( content,  cut_ptr, cut_length ); | 				append( & content,  cut_ptr, cut_length ); | ||||||
| 				last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | 				last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if ( pos > last_cut ) | 			if ( pos > last_cut ) | ||||||
| 				append( content,  cut_ptr, cut_length ); | 				append( & content,  cut_ptr, cut_length ); | ||||||
|  |  | ||||||
| 			// Replace with a space | 			// Replace with a space | ||||||
| 			if ( back( content ) != ' ' ) | 			if ( * back( & content ) != ' ' ) | ||||||
| 				append( content,  ' ' ); | 				append( & content,  ' ' ); | ||||||
|  |  | ||||||
| 			scanner += 2; | 			scanner += 2; | ||||||
| 			tokleft -= 2; | 			tokleft -= 2; | ||||||
| @@ -400,17 +400,17 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
|  |  | ||||||
| 				move_fwd(); | 				move_fwd(); | ||||||
|  |  | ||||||
| 				append( content,  cut_ptr, cut_length ); | 				append( & content,  cut_ptr, cut_length ); | ||||||
| 				last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | 				last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if ( pos > last_cut ) | 			if ( pos > last_cut ) | ||||||
| 				append( content,  cut_ptr, cut_length ); | 				append( & content,  cut_ptr, cut_length ); | ||||||
|  |  | ||||||
| 			// Replace with a space | 			// Replace with a space | ||||||
| 			if ( back( content ) != ' ' ) | 			if ( * back( & content ) != ' ' ) | ||||||
| 				append( content,  ' ' ); | 				append( & content,  ' ' ); | ||||||
|  |  | ||||||
| 			move_fwd(); | 			move_fwd(); | ||||||
|  |  | ||||||
| @@ -421,7 +421,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
| 		// Escaped newlines | 		// Escaped newlines | ||||||
| 		if ( scanner[0] == '\\' ) | 		if ( scanner[0] == '\\' ) | ||||||
| 		{ | 		{ | ||||||
| 			append( content,  cut_ptr, cut_length ); | 			append( & content,  cut_ptr, cut_length ); | ||||||
|  |  | ||||||
| 			s32 amount_to_skip = 1; | 			s32 amount_to_skip = 1; | ||||||
| 			if ( tokleft > 1 && scanner[1] == '\n' ) | 			if ( tokleft > 1 && scanner[1] == '\n' ) | ||||||
| @@ -448,7 +448,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
| 		// Consectuive spaces | 		// Consectuive spaces | ||||||
| 		if ( tokleft > 1 && char_is_space( scanner[0] ) && char_is_space( scanner[ 1 ] ) ) | 		if ( tokleft > 1 && char_is_space( scanner[0] ) && char_is_space( scanner[ 1 ] ) ) | ||||||
| 		{ | 		{ | ||||||
| 			append( content,  cut_ptr, cut_length ); | 			append( & content,  cut_ptr, cut_length ); | ||||||
| 			do | 			do | ||||||
| 			{ | 			{ | ||||||
| 				move_fwd(); | 				move_fwd(); | ||||||
| @@ -458,8 +458,9 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
| 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | 			last_cut = sptr( scanner ) - sptr( raw_text.Ptr ); | ||||||
|  |  | ||||||
| 			// Preserve only 1 space of formattting | 			// Preserve only 1 space of formattting | ||||||
| 			if ( back( content ) != ' ' ) | 			char* last = back(& content); | ||||||
| 				append( content,  ' ' ); | 			if ( last == nullptr || * last != ' ' ) | ||||||
|  | 				append( & content,  ' ' ); | ||||||
|  |  | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| @@ -469,7 +470,7 @@ String strip_formatting( StrC raw_text, bool preserve_newlines = true ) | |||||||
|  |  | ||||||
| 	if ( last_cut < raw_text.Len ) | 	if ( last_cut < raw_text.Len ) | ||||||
| 	{ | 	{ | ||||||
| 		append( content,  cut_ptr, raw_text.Len - last_cut ); | 		append( & content,  cut_ptr, raw_text.Len - last_cut ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #undef cut_ptr | #undef cut_ptr | ||||||
| @@ -504,14 +505,14 @@ Code parse_array_decl() | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Error, unexpected end of array declaration ( '[]' scope started )\n%s", Context.to_string() ); | 			log_failure( "Error, unexpected end of array declaration ( '[]' scope started )\n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( currtok.Type == TokType::BraceSquare_Close ) | 		if ( currtok.Type == TokType::BraceSquare_Close ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Error, empty array expression in definition\n%s", Context.to_string() ); | 			log_failure( "Error, empty array expression in definition\n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		Token untyped_tok = currtok; | 		Token untyped_tok = currtok; | ||||||
| @@ -530,14 +531,14 @@ Code parse_array_decl() | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Error, unexpected end of array declaration, expected ]\n%s", Context.to_string() ); | 			log_failure( "Error, unexpected end of array declaration, expected ]\n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( currtok.Type != TokType::BraceSquare_Close ) | 		if ( currtok.Type != TokType::BraceSquare_Close ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "%s: Error, expected ] in array declaration, not %s\n%s", ETokType::to_str( currtok.Type ), Context.to_string() ); | 			log_failure( "%s: Error, expected ] in array declaration, not %s\n%s", ETokType::to_str( currtok.Type ), Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		eat( TokType::BraceSquare_Close ); | 		eat( TokType::BraceSquare_Close ); | ||||||
| @@ -677,7 +678,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | |||||||
| 	if ( which != TokType::Decl_Class && which != TokType::Decl_Struct ) | 	if ( which != TokType::Decl_Class && which != TokType::Decl_Struct ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Error, expected class or struct, not %s\n%s", ETokType::to_str( which ), Context.to_string() ); | 		log_failure( "Error, expected class or struct, not %s\n%s", ETokType::to_str( which ), Context.to_string() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Token name { nullptr, 0, TokType::Invalid }; | 	Token name { nullptr, 0, TokType::Invalid }; | ||||||
| @@ -688,7 +689,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | |||||||
| 	CodeAttributes attributes = { nullptr }; | 	CodeAttributes attributes = { nullptr }; | ||||||
| 	ModuleFlag     mflags     = ModuleFlag_None; | 	ModuleFlag     mflags     = ModuleFlag_None; | ||||||
|  |  | ||||||
| 	CodeClass result = CodeInvalid; | 	CodeClass result = InvalidCode; | ||||||
|  |  | ||||||
| 	if ( check(TokType::Module_Export) ) | 	if ( check(TokType::Module_Export) ) | ||||||
| 	{ | 	{ | ||||||
| @@ -714,7 +715,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | |||||||
| 	char interface_arr_mem[ kilobytes(4) ] {0}; | 	char interface_arr_mem[ kilobytes(4) ] {0}; | ||||||
| 	Array<CodeType> interfaces; { | 	Array<CodeType> interfaces; { | ||||||
| 		Arena arena = arena_init_from_memory( interface_arr_mem, kilobytes(4) ); | 		Arena arena = arena_init_from_memory( interface_arr_mem, kilobytes(4) ); | ||||||
| 		interfaces  = array_init_reserve<CodeType>( allocator_info(arena), 4 ); | 		interfaces  = array_init_reserve<CodeType>( allocator_info(& arena), 4 ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// TODO(Ed) : Make an AST_DerivedType, we'll store any arbitary derived type into there as a linear linked list of them. | 	// TODO(Ed) : Make an AST_DerivedType, we'll store any arbitary derived type into there as a linear linked list of them. | ||||||
| @@ -745,7 +746,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | |||||||
| 			} | 			} | ||||||
| 			Token interface_tok = parse_identifier(); | 			Token interface_tok = parse_identifier(); | ||||||
|  |  | ||||||
| 			append(interfaces, def_type( interface_tok ) ); | 			append( & interfaces, def_type( interface_tok ) ); | ||||||
| 			// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... | 			// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -777,7 +778,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) | |||||||
| 	if ( inline_cmt ) | 	if ( inline_cmt ) | ||||||
| 		result->InlineCmt = inline_cmt; | 		result->InlineCmt = inline_cmt; | ||||||
|  |  | ||||||
| 	free(interfaces); | 	free(& interfaces); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -801,7 +802,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
|  |  | ||||||
| 	while ( left && currtok_noskip.Type != TokType::BraceCurly_Close ) | 	while ( left && currtok_noskip.Type != TokType::BraceCurly_Close ) | ||||||
| 	{ | 	{ | ||||||
| 		Code           member     = Code::Invalid; | 		Code           member     = Code_Invalid; | ||||||
| 		CodeAttributes attributes = { nullptr }; | 		CodeAttributes attributes = { nullptr }; | ||||||
| 		CodeSpecifiers specifiers = { nullptr }; | 		CodeSpecifiers specifiers = { nullptr }; | ||||||
|  |  | ||||||
| @@ -900,7 +901,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
| 				if ( currtok.Text[0] != '~' ) | 				if ( currtok.Text[0] != '~' ) | ||||||
| 				{ | 				{ | ||||||
| 					log_failure( "Operator token found in global body but not destructor unary negation\n%s", Context.to_string() ); | 					log_failure( "Operator token found in global body but not destructor unary negation\n%s", Context.to_string() ); | ||||||
| 					return CodeInvalid; | 					return InvalidCode; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				member = parse_destructor(); | 				member = parse_destructor(); | ||||||
| @@ -1014,7 +1015,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
| 						default: | 						default: | ||||||
| 							log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str(spec), Context.to_string() ); | 							log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str(spec), Context.to_string() ); | ||||||
| 							Context.pop(); | 							Context.pop(); | ||||||
| 							return CodeInvalid; | 							return InvalidCode; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					// Every specifier after would be considered part of the type type signature | 					// Every specifier after would be considered part of the type type signature | ||||||
| @@ -1040,7 +1041,7 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
| 					if ( attributes ) | 					if ( attributes ) | ||||||
| 					{ | 					{ | ||||||
| 						String fused = string_make_reserve( GlobalAllocator, length(attributes->Content) + length(more_attributes->Content) ); | 						String fused = string_make_reserve( GlobalAllocator, length(attributes->Content) + length(more_attributes->Content) ); | ||||||
| 						append_fmt( fused, "%S %S", attributes->Content, more_attributes->Content ); | 						append_fmt( & fused, "%S %S", attributes->Content, more_attributes->Content ); | ||||||
|  |  | ||||||
| 						attributes->Name    = get_cached_string(fused); | 						attributes->Name    = get_cached_string(fused); | ||||||
| 						attributes->Content = attributes->Name; | 						attributes->Content = attributes->Name; | ||||||
| @@ -1107,11 +1108,11 @@ CodeBody parse_class_struct_body( TokType which, Token name ) | |||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( member == Code::Invalid ) | 		if ( member == Code_Invalid ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Failed to parse member\n%s", Context.to_string() ); | 			log_failure( "Failed to parse member\n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		result.append( member ); | 		result.append( member ); | ||||||
| @@ -1199,7 +1200,7 @@ Code parse_complicated_definition( TokType which ) | |||||||
|  |  | ||||||
| 		log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() ); | 		log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
| 	if ( tok.Type == TokType::Identifier ) | 	if ( tok.Type == TokType::Identifier ) | ||||||
| 	{ | 	{ | ||||||
| @@ -1244,7 +1245,7 @@ Code parse_complicated_definition( TokType which ) | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() ); | 			log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		Code result = parse_operator_function_or_variable( false, { nullptr }, { nullptr } ); | 		Code result = parse_operator_function_or_variable( false, { nullptr }, { nullptr } ); | ||||||
| @@ -1263,7 +1264,7 @@ Code parse_complicated_definition( TokType which ) | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() ); | 			log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Its a forward declaration of an enum class | 		// Its a forward declaration of an enum class | ||||||
| @@ -1293,7 +1294,7 @@ Code parse_complicated_definition( TokType which ) | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Unsupported or bad member definition after %s declaration\n%S", to_str(which).Ptr, Context.to_string() ); | 		log_failure( "Unsupported or bad member definition after %s declaration\n%S", to_str(which).Ptr, Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1312,7 +1313,7 @@ CodeDefine parse_define() | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Error, expected identifier after #define\n%s", Context.to_string() ); | 		log_failure( "Error, expected identifier after #define\n%s", Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Context.Scope->Name = currtok; | 	Context.Scope->Name = currtok; | ||||||
| @@ -1324,7 +1325,7 @@ CodeDefine parse_define() | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Error, expected content after #define %s\n%s", define->Name, Context.to_string() ); | 		log_failure( "Error, expected content after #define %s\n%s", define->Name, Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( currtok.Length == 0 ) | 	if ( currtok.Length == 0 ) | ||||||
| @@ -1359,7 +1360,7 @@ Code parse_assignment_expression() | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Expected expression after assignment operator\n%s", Context.to_string() ); | 		log_failure( "Expected expression after assignment operator\n%s", Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	s32 level = 0; | 	s32 level = 0; | ||||||
| @@ -1386,7 +1387,7 @@ Code parse_assignment_expression() | |||||||
| internal inline | internal inline | ||||||
| Code parse_forward_or_definition( TokType which, bool is_inplace ) | Code parse_forward_or_definition( TokType which, bool is_inplace ) | ||||||
| { | { | ||||||
| 	Code result = CodeInvalid; | 	Code result = InvalidCode; | ||||||
|  |  | ||||||
| 	switch ( which ) | 	switch ( which ) | ||||||
| 	{ | 	{ | ||||||
| @@ -1411,7 +1412,7 @@ Code parse_forward_or_definition( TokType which, bool is_inplace ) | |||||||
| 				"(only supports class, enum, struct, union) \n%s" | 				"(only supports class, enum, struct, union) \n%s" | ||||||
| 				, Context.to_string() ); | 				, Context.to_string() ); | ||||||
|  |  | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1449,10 +1450,10 @@ CodeFn parse_function_after_name( | |||||||
| 	if ( check( TokType::BraceCurly_Open ) ) | 	if ( check( TokType::BraceCurly_Open ) ) | ||||||
| 	{ | 	{ | ||||||
| 		body = parse_function_body(); | 		body = parse_function_body(); | ||||||
| 		if ( body == Code::Invalid ) | 		if ( body == Code_Invalid ) | ||||||
| 		{ | 		{ | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
| 		// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> { <Body> } | 		// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> { <Body> } | ||||||
| 	} | 	} | ||||||
| @@ -1504,7 +1505,7 @@ CodeFn parse_function_after_name( | |||||||
| 			{ | 			{ | ||||||
| 				log_failure("Body must be either of Function_Body or Untyped type, %s\n%s", body.debug_str(), Context.to_string()); | 				log_failure("Body must be either of Function_Body or Untyped type, %s\n%s", body.debug_str(), Context.to_string()); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -1584,7 +1585,7 @@ CodeBody parse_global_nspace( CodeT which ) | |||||||
| 	push_scope(); | 	push_scope(); | ||||||
|  |  | ||||||
| 	if ( which != Namespace_Body && which != Global_Body && which != Export_Body && which != Extern_Linkage_Body ) | 	if ( which != Namespace_Body && which != Global_Body && which != Export_Body && which != Extern_Linkage_Body ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	if ( which != Global_Body ) | 	if ( which != Global_Body ) | ||||||
| 		eat( TokType::BraceCurly_Open ); | 		eat( TokType::BraceCurly_Open ); | ||||||
| @@ -1596,7 +1597,7 @@ CodeBody parse_global_nspace( CodeT which ) | |||||||
|  |  | ||||||
| 	while ( left && currtok_noskip.Type != TokType::BraceCurly_Close ) | 	while ( left && currtok_noskip.Type != TokType::BraceCurly_Close ) | ||||||
| 	{ | 	{ | ||||||
| 		Code           member     = Code::Invalid; | 		Code           member     = Code_Invalid; | ||||||
| 		CodeAttributes attributes = { nullptr }; | 		CodeAttributes attributes = { nullptr }; | ||||||
| 		CodeSpecifiers specifiers = { nullptr }; | 		CodeSpecifiers specifiers = { nullptr }; | ||||||
|  |  | ||||||
| @@ -1797,7 +1798,7 @@ CodeBody parse_global_nspace( CodeT which ) | |||||||
|  |  | ||||||
| 							log_failure( "Invalid specifier %.*s for variable\n%s", spec_str.Len, spec_str, Context.to_string() ); | 							log_failure( "Invalid specifier %.*s for variable\n%s", spec_str.Len, spec_str, Context.to_string() ); | ||||||
| 							Context.pop(); | 							Context.pop(); | ||||||
| 							return CodeInvalid; | 							return InvalidCode; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					if (ignore_spec) | 					if (ignore_spec) | ||||||
| @@ -1869,11 +1870,11 @@ CodeBody parse_global_nspace( CodeT which ) | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( member == Code::Invalid ) | 		if ( member == Code_Invalid ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Failed to parse member\n%s", Context.to_string() ); | 			log_failure( "Failed to parse member\n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// log_fmt("Global Body Member: %s", member->debug_str()); | 		// log_fmt("Global Body Member: %s", member->debug_str()); | ||||||
| @@ -2107,7 +2108,7 @@ CodeInclude parse_include() | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Error, expected include string after #include\n%s", Context.to_string() ); | 		log_failure( "Error, expected include string after #include\n%s", Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Context.Scope->Name = currtok; | 	Context.Scope->Name = currtok; | ||||||
| @@ -2156,7 +2157,7 @@ CodeOperator parse_operator_after_ret_type( | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Expected operator after 'operator' keyword\n%s", Context.to_string() ); | 		log_failure( "Expected operator after 'operator' keyword\n%s", Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Context.Scope->Name = currtok; | 	Context.Scope->Name = currtok; | ||||||
| @@ -2409,7 +2410,7 @@ CodeOperator parse_operator_after_ret_type( | |||||||
| 				{ | 				{ | ||||||
| 					log_failure( "Invalid operator '%s'\n%s", prevtok.Text, Context.to_string() ); | 					log_failure( "Invalid operator '%s'\n%s", prevtok.Text, Context.to_string() ); | ||||||
| 					Context.pop(); | 					Context.pop(); | ||||||
| 					return CodeInvalid; | 					return InvalidCode; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -2419,7 +2420,7 @@ CodeOperator parse_operator_after_ret_type( | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Invalid operator '%s'\n%s", currtok.Text, Context.to_string() ); | 		log_failure( "Invalid operator '%s'\n%s", currtok.Text, Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( ! was_new_or_delete) | 	if ( ! was_new_or_delete) | ||||||
| @@ -2453,10 +2454,10 @@ CodeOperator parse_operator_after_ret_type( | |||||||
| 	if ( check( TokType::BraceCurly_Open ) ) | 	if ( check( TokType::BraceCurly_Open ) ) | ||||||
| 	{ | 	{ | ||||||
| 		body = parse_function_body(); | 		body = parse_function_body(); | ||||||
| 		if ( body == Code::Invalid ) | 		if ( body == Code_Invalid ) | ||||||
| 		{ | 		{ | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
| 		// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers> { ... } | 		// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers> { ... } | ||||||
| 	} | 	} | ||||||
| @@ -2486,7 +2487,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes | |||||||
| { | { | ||||||
| 	push_scope(); | 	push_scope(); | ||||||
|  |  | ||||||
| 	Code result = CodeInvalid; | 	Code result = InvalidCode; | ||||||
|  |  | ||||||
| #ifndef GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES | #ifndef GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES | ||||||
| 	if ( currtok.Type == TokType::Preprocess_Macro ) | 	if ( currtok.Type == TokType::Preprocess_Macro ) | ||||||
| @@ -2502,10 +2503,10 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes | |||||||
| 	CodeType type = parse_type(); | 	CodeType type = parse_type(); | ||||||
| 	// <Attributes> <Specifiers> <ReturnType/ValueType> | 	// <Attributes> <Specifiers> <ReturnType/ValueType> | ||||||
|  |  | ||||||
| 	if ( type == CodeInvalid ) | 	if ( type == InvalidCode ) | ||||||
| 	{ | 	{ | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool found_operator = false; | 	bool found_operator = false; | ||||||
| @@ -2561,7 +2562,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes | |||||||
| 			{ | 			{ | ||||||
| 				log_failure( "Expected function declaration (consteval was used)\n%s", Context.to_string() ); | 				log_failure( "Expected function declaration (consteval was used)\n%s", Context.to_string() ); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// Dealing with a variable | 			// Dealing with a variable | ||||||
| @@ -2589,7 +2590,7 @@ CodePragma parse_pragma() | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Error, expected content after #pragma\n%s", Context.to_string() ); | 		log_failure( "Error, expected content after #pragma\n%s", Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Context.Scope->Name = currtok; | 	Context.Scope->Name = currtok; | ||||||
| @@ -2666,10 +2667,10 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 	if ( currtok.Type != TokType::Comma ) | 	if ( currtok.Type != TokType::Comma ) | ||||||
| 	{ | 	{ | ||||||
| 		type = parse_type( use_template_capture ); | 		type = parse_type( use_template_capture ); | ||||||
| 		if ( type == Code::Invalid ) | 		if ( type == Code_Invalid ) | ||||||
| 		{ | 		{ | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
| 		// ( <Macro> <ValueType> | 		// ( <Macro> <ValueType> | ||||||
|  |  | ||||||
| @@ -2703,7 +2704,7 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 			{ | 			{ | ||||||
| 				log_failure( "Expected value after assignment operator\n%s.", Context.to_string() ); | 				log_failure( "Expected value after assignment operator\n%s.", Context.to_string() ); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			s32 capture_level  = 0; | 			s32 capture_level  = 0; | ||||||
| @@ -2776,10 +2777,10 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 		if ( currtok.Type != TokType::Comma ) | 		if ( currtok.Type != TokType::Comma ) | ||||||
| 		{ | 		{ | ||||||
| 			type = parse_type( use_template_capture ); | 			type = parse_type( use_template_capture ); | ||||||
| 			if ( type == Code::Invalid ) | 			if ( type == Code_Invalid ) | ||||||
| 			{ | 			{ | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 			} | 			} | ||||||
| 			// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> | 			// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> | ||||||
|  |  | ||||||
| @@ -2815,7 +2816,7 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 				{ | 				{ | ||||||
| 					log_failure( "Expected value after assignment operator\n%s", Context.to_string() ); | 					log_failure( "Expected value after assignment operator\n%s", Context.to_string() ); | ||||||
| 					Context.pop(); | 					Context.pop(); | ||||||
| 					return CodeInvalid; | 					return InvalidCode; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				s32 capture_level  = 0; | 				s32 capture_level  = 0; | ||||||
| @@ -2876,7 +2877,7 @@ CodeParam parse_params( bool use_template_capture ) | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Expected '<' after 'template' keyword\n%s", Context.to_string() ); | 			log_failure( "Expected '<' after 'template' keyword\n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
| 		eat( TokType::Operator ); | 		eat( TokType::Operator ); | ||||||
| 		// < <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, .. > | 		// < <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, .. > | ||||||
| @@ -2896,7 +2897,7 @@ CodePreprocessCond parse_preprocess_cond() | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Error, expected preprocess conditional\n%s", Context.to_string() ); | 		log_failure( "Error, expected preprocess conditional\n%s", Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodePreprocessCond | 	CodePreprocessCond | ||||||
| @@ -2909,7 +2910,7 @@ CodePreprocessCond parse_preprocess_cond() | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Error, expected content after #define\n%s", Context.to_string() ); | 		log_failure( "Error, expected content after #define\n%s", Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Context.Scope->Name = currtok; | 	Context.Scope->Name = currtok; | ||||||
| @@ -3167,7 +3168,7 @@ CodeVar parse_variable_after_name( | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Expected expression after bitfield \n%s", Context.to_string() ); | 			log_failure( "Expected expression after bitfield \n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		while ( left && currtok.Type != TokType::Statement_End ) | 		while ( left && currtok.Type != TokType::Statement_End ) | ||||||
| @@ -3465,7 +3466,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers ) | |||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Expected destructor '~' token\n%s", Context.to_string() ); | 		log_failure( "Expected destructor '~' token\n%s", Context.to_string() ); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
| 	// <Virtual Specifier> ~ | 	// <Virtual Specifier> ~ | ||||||
|  |  | ||||||
| @@ -3502,7 +3503,7 @@ CodeDestructor parse_destructor( CodeSpecifiers specifiers ) | |||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Pure or default specifier expected due to '=' token\n%s", Context.to_string() ); | 			log_failure( "Pure or default specifier expected due to '=' token\n%s", Context.to_string() ); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		pure_virtual = true; | 		pure_virtual = true; | ||||||
| @@ -3597,11 +3598,11 @@ CodeEnum parse_enum( bool inplace_def ) | |||||||
| 		// enum <class> <Attributes> <Name> : | 		// enum <class> <Attributes> <Name> : | ||||||
|  |  | ||||||
| 		type = parse_type(); | 		type = parse_type(); | ||||||
| 		if ( type == Code::Invalid ) | 		if ( type == Code_Invalid ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Failed to parse enum classifier\n%s", Context.to_string() ); | 			log_failure( "Failed to parse enum classifier\n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
| 		// enum <class> <Attributes> <Name> : <UnderlyingType> | 		// enum <class> <Attributes> <Name> : <UnderlyingType> | ||||||
| 	} | 	} | ||||||
| @@ -3627,7 +3628,7 @@ CodeEnum parse_enum( bool inplace_def ) | |||||||
| 		eat( TokType::BraceCurly_Open ); | 		eat( TokType::BraceCurly_Open ); | ||||||
| 		// enum <class> <Attributes> <Name> : <UnderlyingType> { | 		// enum <class> <Attributes> <Name> : <UnderlyingType> { | ||||||
|  |  | ||||||
| 		Code member = CodeInvalid; | 		Code member = InvalidCode; | ||||||
|  |  | ||||||
| 		bool expects_entry = true; | 		bool expects_entry = true; | ||||||
| 		while ( left && currtok_noskip.Type != TokType::BraceCurly_Close ) | 		while ( left && currtok_noskip.Type != TokType::BraceCurly_Close ) | ||||||
| @@ -3735,11 +3736,11 @@ CodeEnum parse_enum( bool inplace_def ) | |||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if ( member == Code::Invalid ) | 			if ( member == Code_Invalid ) | ||||||
| 			{ | 			{ | ||||||
| 				log_failure( "Failed to parse member\n%s", Context.to_string() ); | 				log_failure( "Failed to parse member\n%s", Context.to_string() ); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			body.append( member ); | 			body.append( member ); | ||||||
| @@ -3838,7 +3839,7 @@ CodeExtern parse_extern_link() | |||||||
| 	result->Name = get_cached_string( name ); | 	result->Name = get_cached_string( name ); | ||||||
|  |  | ||||||
| 	Code entry = parse_extern_link_body(); | 	Code entry = parse_extern_link_body(); | ||||||
| 	if ( entry == Code::Invalid ) | 	if ( entry == Code_Invalid ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Failed to parse body\n%s", Context.to_string() ); | 		log_failure( "Failed to parse body\n%s", Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| @@ -3865,10 +3866,10 @@ CodeFriend parse_friend() | |||||||
|  |  | ||||||
| 	// Type declaration or return type | 	// Type declaration or return type | ||||||
| 	CodeType type = parse_type(); | 	CodeType type = parse_type(); | ||||||
| 	if ( type == Code::Invalid ) | 	if ( type == Code_Invalid ) | ||||||
| 	{ | 	{ | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
| 	// friend <Type> | 	// friend <Type> | ||||||
|  |  | ||||||
| @@ -3965,7 +3966,7 @@ CodeFn parse_function() | |||||||
| 			default: | 			default: | ||||||
| 				log_failure( "Invalid specifier %s for functon\n%s", ESpecifier::to_str(spec), Context.to_string() ); | 				log_failure( "Invalid specifier %s for functon\n%s", ESpecifier::to_str(spec), Context.to_string() ); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( spec == ESpecifier::Const ) | 		if ( spec == ESpecifier::Const ) | ||||||
| @@ -3983,10 +3984,10 @@ CodeFn parse_function() | |||||||
| 	// <export> <Attributes> <Specifiers> | 	// <export> <Attributes> <Specifiers> | ||||||
|  |  | ||||||
| 	CodeType ret_type = parse_type(); | 	CodeType ret_type = parse_type(); | ||||||
| 	if ( ret_type == Code::Invalid ) | 	if ( ret_type == Code_Invalid ) | ||||||
| 	{ | 	{ | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
| 	// <export> <Attributes> <Specifiers> <ReturnType> | 	// <export> <Attributes> <Specifiers> <ReturnType> | ||||||
|  |  | ||||||
| @@ -3995,7 +3996,7 @@ CodeFn parse_function() | |||||||
| 	if ( ! name ) | 	if ( ! name ) | ||||||
| 	{ | 	{ | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
| 	// <export> <Attributes> <Specifiers> <ReturnType> <Name> | 	// <export> <Attributes> <Specifiers> <ReturnType> <Name> | ||||||
|  |  | ||||||
| @@ -4019,10 +4020,10 @@ CodeNS parse_namespace() | |||||||
| 	// namespace <Name> | 	// namespace <Name> | ||||||
|  |  | ||||||
| 	CodeBody body = parse_global_nspace( ECode::Namespace_Body ); | 	CodeBody body = parse_global_nspace( ECode::Namespace_Body ); | ||||||
| 	if ( body == Code::Invalid ) | 	if ( body == Code_Invalid ) | ||||||
| 	{ | 	{ | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
| 	// namespace <Name> { <Body> } | 	// namespace <Name> { <Body> } | ||||||
|  |  | ||||||
| @@ -4076,7 +4077,7 @@ CodeOperator parse_operator() | |||||||
| 			default: | 			default: | ||||||
| 				log_failure( "Invalid specifier " "%s" " for operator\n%s", ESpecifier::to_str(spec), Context.to_string() ); | 				log_failure( "Invalid specifier " "%s" " for operator\n%s", ESpecifier::to_str(spec), Context.to_string() ); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( spec == ESpecifier::Const ) | 		if ( spec == ESpecifier::Const ) | ||||||
| @@ -4245,10 +4246,10 @@ CodeTemplate parse_template() | |||||||
| 	// <export> template | 	// <export> template | ||||||
|  |  | ||||||
| 	Code params = parse_params( UseTemplateCapture ); | 	Code params = parse_params( UseTemplateCapture ); | ||||||
| 	if ( params == Code::Invalid ) | 	if ( params == Code_Invalid ) | ||||||
| 	{ | 	{ | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
| 	// <export> template< <Parameters> > | 	// <export> template< <Parameters> > | ||||||
|  |  | ||||||
| @@ -4327,7 +4328,7 @@ CodeTemplate parse_template() | |||||||
| 					default : | 					default : | ||||||
| 						log_failure( "Invalid specifier %s for variable or function\n%s", ESpecifier::to_str( spec ), Context.to_string() ); | 						log_failure( "Invalid specifier %s for variable or function\n%s", ESpecifier::to_str( spec ), Context.to_string() ); | ||||||
| 						Context.pop(); | 						Context.pop(); | ||||||
| 						return CodeInvalid; | 						return InvalidCode; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				// Ignore const it will be handled by the type | 				// Ignore const it will be handled by the type | ||||||
| @@ -4450,7 +4451,7 @@ CodeType parse_type( bool from_template, bool* typedef_is_function ) | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() ); | 			log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		specs_found[ NumSpecifiers ] = spec; | 		specs_found[ NumSpecifiers ] = spec; | ||||||
| @@ -4463,7 +4464,7 @@ CodeType parse_type( bool from_template, bool* typedef_is_function ) | |||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Error, unexpected end of type definition\n%s", Context.to_string() ); | 		log_failure( "Error, unexpected end of type definition\n%s", Context.to_string() ); | ||||||
| 		Context.pop(); | 		Context.pop(); | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( from_template && currtok.Type == TokType::Decl_Class ) | 	if ( from_template && currtok.Type == TokType::Decl_Class ) | ||||||
| @@ -4547,7 +4548,7 @@ else if ( currtok.Type == TokType::DeclType ) | |||||||
| 			{ | 			{ | ||||||
| 				log_failure( "Error, failed to type signature\n%s", Context.to_string() ); | 				log_failure( "Error, failed to type signature\n%s", Context.to_string() ); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -4561,7 +4562,7 @@ else if ( currtok.Type == TokType::DeclType ) | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Error, failed to type signature\n%s", Context.to_string() ); | 			log_failure( "Error, failed to type signature\n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
| 		// <Attributes> <Specifiers> <Qualifier ::> <Identifier> | 		// <Attributes> <Specifiers> <Qualifier ::> <Identifier> | ||||||
| 		// <Attributes> <Specifiers> <Identifier> | 		// <Attributes> <Specifiers> <Identifier> | ||||||
| @@ -4576,7 +4577,7 @@ else if ( currtok.Type == TokType::DeclType ) | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() ); | 			log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		specs_found[ NumSpecifiers ] = spec; | 		specs_found[ NumSpecifiers ] = spec; | ||||||
| @@ -4709,7 +4710,7 @@ else if ( currtok.Type == TokType::DeclType ) | |||||||
| 				{ | 				{ | ||||||
| 					log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() ); | 					log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() ); | ||||||
| 					Context.pop(); | 					Context.pop(); | ||||||
| 					return CodeInvalid; | 					return InvalidCode; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				specs_found[ NumSpecifiers ] = spec; | 				specs_found[ NumSpecifiers ] = spec; | ||||||
| @@ -4779,7 +4780,7 @@ else if ( currtok.Type == TokType::DeclType ) | |||||||
| 			{ | 			{ | ||||||
| 				log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() ); | 				log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() ); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			specs_found[ NumSpecifiers ] = spec; | 			specs_found[ NumSpecifiers ] = spec; | ||||||
| @@ -4910,10 +4911,12 @@ CodeTypedef parse_typedef() | |||||||
| 			||	currtok.Type == TokType::Decl_Struct | 			||	currtok.Type == TokType::Decl_Struct | ||||||
| 			||	currtok.Type == TokType::Decl_Union; | 			||	currtok.Type == TokType::Decl_Union; | ||||||
|  |  | ||||||
|  |  | ||||||
| 		// This code is highly correlated with parse_complicated_definition | 		// This code is highly correlated with parse_complicated_definition | ||||||
| 		if ( is_complicated ) | 		if ( is_complicated ) | ||||||
| 		{ | 		{ | ||||||
| 			TokArray tokens = Context.Tokens; | 			TokArray tokens = Context.Tokens; | ||||||
|  | 			TokType  which  = currtok.Type; | ||||||
|  |  | ||||||
| 			s32 idx = tokens.Idx; | 			s32 idx = tokens.Idx; | ||||||
| 			s32 level = 0; | 			s32 level = 0; | ||||||
| @@ -4929,39 +4932,45 @@ CodeTypedef parse_typedef() | |||||||
| 					break; | 					break; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if ( (idx - 2 ) == tokens.Idx ) | 			Token pre_foward_tok = currtok; | ||||||
|  | 			if ( (idx - 3 ) == tokens.Idx ) | ||||||
| 			{ | 			{ | ||||||
|  | 				log_fmt("Identified forward typedef\n"); | ||||||
| 				// Its a forward declaration only | 				// Its a forward declaration only | ||||||
| 				type = parse_forward_or_definition( currtok.Type, from_typedef ); | 				type = parse_forward_or_definition( which, from_typedef ); | ||||||
| 				// <ModuleFalgs> typedef <UnderlyingType: Forward Decl> | 				// <ModuleFalgs> typedef <UnderlyingType: Forward Decl> | ||||||
| 			} | 			} | ||||||
|  | 			else | ||||||
| 			Token tok = tokens[ idx - 1 ]; | 			{ | ||||||
|  | 				Token tok = tokens.Arr[ idx - 1 ]; | ||||||
| 				if ( tok.Type == TokType::Identifier ) | 				if ( tok.Type == TokType::Identifier ) | ||||||
| 				{ | 				{ | ||||||
| 				tok = tokens[ idx - 2 ]; | 					log_fmt("Found id\n"); | ||||||
|  | 					tok = tokens.Arr[ idx - 2 ]; | ||||||
|  |  | ||||||
| 					bool is_indirection = tok.Type == TokType::Ampersand | 					bool is_indirection = tok.Type == TokType::Ampersand | ||||||
| 					||                    tok.Type == TokType::Star; | 					||                    tok.Type == TokType::Star; | ||||||
|  |  | ||||||
| 					bool ok_to_parse = false; | 					bool ok_to_parse = false; | ||||||
|  |  | ||||||
|  | 					Token temp_3 = tokens.Arr[ idx - 3 ]; | ||||||
|  |  | ||||||
| 					if ( tok.Type == TokType::BraceCurly_Close ) | 					if ( tok.Type == TokType::BraceCurly_Close ) | ||||||
| 					{ | 					{ | ||||||
| 						// Its an inplace definition | 						// Its an inplace definition | ||||||
| 					// typdef <which> <type_identifier> { ... } <identifier>; | 						// typedef <which> <type_identifier> { ... } <identifier>; | ||||||
| 						ok_to_parse = true; | 						ok_to_parse = true; | ||||||
| 					} | 					} | ||||||
| 				else if ( tok.Type == TokType::Identifier && tokens[ idx - 3 ].Type == TokType::Decl_Struct ) | 					else if ( tok.Type == TokType::Identifier && tokens.Arr[ idx - 3 ].Type == which ) | ||||||
| 					{ | 					{ | ||||||
| 					// Its a variable with type ID using struct namespace. | 						// Its a variable with type ID using which namespace. | ||||||
| 					// <which> <type_identifier> <identifier>; | 						// typedef <which> <type_identifier> <identifier>; | ||||||
| 						ok_to_parse = true; | 						ok_to_parse = true; | ||||||
| 					} | 					} | ||||||
| 					else if ( is_indirection ) | 					else if ( is_indirection ) | ||||||
| 					{ | 					{ | ||||||
| 						// Its a indirection type with type ID using struct namespace. | 						// Its a indirection type with type ID using struct namespace. | ||||||
| 					// <which> <type_identifier>* <identifier>; | 						// typedef <which> <type_identifier>* <identifier>; | ||||||
| 						ok_to_parse = true; | 						ok_to_parse = true; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -4969,12 +4978,12 @@ CodeTypedef parse_typedef() | |||||||
| 					{ | 					{ | ||||||
| 						log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() ); | 						log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() ); | ||||||
| 						Context.pop(); | 						Context.pop(); | ||||||
| 					return CodeInvalid; | 						return InvalidCode; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					// TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type. | 					// TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type. | ||||||
| 					// type = parse_type(); | 					// type = parse_type(); | ||||||
| 				type = parse_forward_or_definition( currtok.Type, from_typedef ); | 					type = parse_forward_or_definition( which, from_typedef ); | ||||||
| 					// <ModuleFalgs> typedef <UnderlyingType> | 					// <ModuleFalgs> typedef <UnderlyingType> | ||||||
| 				} | 				} | ||||||
| 				else if ( tok.Type == TokType::BraceCurly_Close ) | 				else if ( tok.Type == TokType::BraceCurly_Close ) | ||||||
| @@ -4995,7 +5004,8 @@ CodeTypedef parse_typedef() | |||||||
| 				{ | 				{ | ||||||
| 					log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() ); | 					log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() ); | ||||||
| 					Context.pop(); | 					Context.pop(); | ||||||
| 				return CodeInvalid; | 					return InvalidCode; | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| @@ -5015,7 +5025,7 @@ CodeTypedef parse_typedef() | |||||||
| 		{ | 		{ | ||||||
| 			log_failure( "Error, expected identifier for typedef\n%s", Context.to_string() ); | 			log_failure( "Error, expected identifier for typedef\n%s", Context.to_string() ); | ||||||
| 			Context.pop(); | 			Context.pop(); | ||||||
| 			return CodeInvalid; | 			return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		array_expr = parse_array_decl(); | 		array_expr = parse_array_decl(); | ||||||
| @@ -5057,7 +5067,7 @@ CodeTypedef parse_typedef() | |||||||
| 	// Type needs to be aware of its parent so that it can be serialized properly. | 	// Type needs to be aware of its parent so that it can be serialized properly. | ||||||
|  |  | ||||||
| 	if ( type->Type == Typename && array_expr && array_expr->Type != Invalid ) | 	if ( type->Type == Typename && array_expr && array_expr->Type != Invalid ) | ||||||
| 		type.cast<CodeType>()->ArrExpr = array_expr; | 		type.code_cast<CodeType>()->ArrExpr = array_expr; | ||||||
|  |  | ||||||
| 	if ( inline_cmt ) | 	if ( inline_cmt ) | ||||||
| 		result->InlineCmt = inline_cmt; | 		result->InlineCmt = inline_cmt; | ||||||
| @@ -5350,7 +5360,7 @@ CodeVar parse_variable() | |||||||
| 			default: | 			default: | ||||||
| 				log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() ); | 				log_failure( "Invalid specifier %s for variable\n%s", ESpecifier::to_str( spec ), Context.to_string() ); | ||||||
| 				Context.pop(); | 				Context.pop(); | ||||||
| 				return CodeInvalid; | 				return InvalidCode; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Ignore const specifiers, they're handled by the type | 		// Ignore const specifiers, they're handled by the type | ||||||
| @@ -5371,8 +5381,8 @@ CodeVar parse_variable() | |||||||
| 	CodeType type = parse_type(); | 	CodeType type = parse_type(); | ||||||
| 	// <ModuleFlags> <Attributes> <Specifiers> <ValueType> | 	// <ModuleFlags> <Attributes> <Specifiers> <ValueType> | ||||||
|  |  | ||||||
| 	if ( type == Code::Invalid ) | 	if ( type == Code_Invalid ) | ||||||
| 		return CodeInvalid; | 		return InvalidCode; | ||||||
|  |  | ||||||
| 	Context.Scope->Name = parse_identifier(); | 	Context.Scope->Name = parse_identifier(); | ||||||
| 	// <ModuleFlags> <Attributes> <Specifiers> <ValueType> <Name> | 	// <ModuleFlags> <Attributes> <Specifiers> <ValueType> <Name> | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ enum AccessSpec enum_underlying(u32) | |||||||
|  |  | ||||||
| 	AccessSpec_SizeDef = GEN_U32_MAX, | 	AccessSpec_SizeDef = GEN_U32_MAX, | ||||||
| }; | }; | ||||||
| static_assert( size_of(AccessSpec) == size_of(u32)); | static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" ); | ||||||
|  |  | ||||||
| inline | inline | ||||||
| char const* to_str( AccessSpec type ) | char const* to_str( AccessSpec type ) | ||||||
| @@ -54,7 +54,7 @@ enum CodeFlag enum_underlying(u32) | |||||||
|  |  | ||||||
| 	CodeFlag_SizeDef = GEN_U32_MAX, | 	CodeFlag_SizeDef = GEN_U32_MAX, | ||||||
| }; | }; | ||||||
| static_assert( size_of(CodeFlag) == size_of(u32)); | static_assert( size_of(CodeFlag) == size_of(u32), "CodeFlag not u32 size" ); | ||||||
|  |  | ||||||
| // Used to indicate if enum definitoin is an enum class or regular enum. | // Used to indicate if enum definitoin is an enum class or regular enum. | ||||||
| enum EnumDecl enum_underlying(u8) | enum EnumDecl enum_underlying(u8) | ||||||
| @@ -77,7 +77,7 @@ enum ModuleFlag enum_underlying(u32) | |||||||
|  |  | ||||||
| 	ModuleFlag_SizeDef = GEN_U32_MAX, | 	ModuleFlag_SizeDef = GEN_U32_MAX, | ||||||
| }; | }; | ||||||
| static_assert( size_of(ModuleFlag) == size_of(u32)); | static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" ); | ||||||
|  |  | ||||||
| inline | inline | ||||||
| StrC to_str( ModuleFlag flag ) | StrC to_str( ModuleFlag flag ) | ||||||
| @@ -110,4 +110,4 @@ enum EPreprocessCond enum_underlying(u32) | |||||||
|  |  | ||||||
| 	EPreprocessCond_SizeDef = GEN_U32_MAX, | 	EPreprocessCond_SizeDef = GEN_U32_MAX, | ||||||
| }; | }; | ||||||
| static_assert( size_of(EPreprocessCond) == size_of(u32)); | static_assert( size_of(EPreprocessCond) == size_of(u32), "EPreprocessCond not u32 size" ); | ||||||
|   | |||||||
| @@ -29,29 +29,25 @@ struct ArrayHeader; | |||||||
|  |  | ||||||
| usize array_grow_formula(ssize value); | usize array_grow_formula(ssize value); | ||||||
|  |  | ||||||
| template<class Type> Array<Type>  array_init(AllocatorInfo allocator); | template<class Type> Array(Type)  array_init        (AllocatorInfo allocator); | ||||||
| template<class Type> Array<Type>  array_init_reserve(AllocatorInfo allocator, ssize capacity); | template<class Type> Array(Type)  array_init_reserve(AllocatorInfo allocator, ssize capacity); | ||||||
| template<class Type> bool         append(Array<Type>& array, Array<Type> other); | template<class Type> bool         append            (Array(Type)* array, Array(Type) other); | ||||||
| template<class Type> bool         append(Array<Type>& array, Type value); | template<class Type> bool         append            (Array(Type)* array, Type value); | ||||||
| template<class Type> bool         append(Array<Type>& array, Type* items, usize item_num); | template<class Type> bool         append            (Array(Type)* array, Type* items, usize item_num); | ||||||
| template<class Type> bool         append_at(Array<Type>& array, Type item, usize idx); | template<class Type> bool         append_at         (Array(Type)* array, Type item, usize idx); | ||||||
| template<class Type> bool         append_at(Array<Type>& array, Type* items, usize item_num, usize idx); | template<class Type> bool         append_at         (Array(Type)* array, Type* items, usize item_num, usize idx); | ||||||
| template<class Type> Type&        back(Array<Type>& array); | template<class Type> Type*        back              (Array(Type)  array); | ||||||
| template<class Type> void         clear(Array<Type>& array); | template<class Type> void         clear             (Array(Type)  array); | ||||||
| template<class Type> bool         fill(Array<Type>& array, usize begin, usize end, Type value); | template<class Type> bool         fill              (Array(Type)  array, usize begin, usize end, Type value); | ||||||
| template<class Type> void         free(Array<Type>& array); | template<class Type> void         free              (Array(Type)* array); | ||||||
| template<class Type> bool         grow(Array<Type>& array, usize min_capacity); | template<class Type> bool         grow              (Array(Type)* array, usize min_capacity); | ||||||
| template<class Type> usize        num(Array<Type>& array); | template<class Type> usize        num               (Array(Type)  array); | ||||||
| template<class Type> void         pop(Array<Type>& array); | template<class Type> void         pop               (Array(Type)  array); | ||||||
| template<class Type> void         remove_at(Array<Type>& array, usize idx); | template<class Type> void         remove_at         (Array(Type)  array, usize idx); | ||||||
| template<class Type> bool         reserve(Array<Type>& array, usize new_capacity); | template<class Type> bool         reserve           (Array(Type)* array, usize new_capacity); | ||||||
| template<class Type> bool         resize(Array<Type>& array, usize num); | template<class Type> bool         resize            (Array(Type)* array, usize num); | ||||||
| template<class Type> bool         set_capacity(Array<Type>& array, usize new_capacity); | template<class Type> bool         set_capacity      (Array(Type)* array, usize new_capacity); | ||||||
| template<class Type> ArrayHeader* get_header(Array<Type>& array); | template<class Type> ArrayHeader* get_header        (Array(Type)  array); | ||||||
|  |  | ||||||
| template<class Type> forceinline Type* begin(Array<Type>& array)             { return array;      } |  | ||||||
| template<class Type> forceinline Type* end(Array<Type>& array)               { return array + get_header(array)->Num; } |  | ||||||
| template<class Type> forceinline Type* next(Array<Type>& array, Type* entry) { return entry + 1; } |  | ||||||
|  |  | ||||||
| struct ArrayHeader { | struct ArrayHeader { | ||||||
| 	AllocatorInfo Allocator; | 	AllocatorInfo Allocator; | ||||||
| @@ -70,32 +66,56 @@ struct Array | |||||||
| 	forceinline static Array  init_reserve(AllocatorInfo allocator, ssize capacity) { return GEN_NS array_init_reserve<Type>(allocator, capacity); } | 	forceinline static Array  init_reserve(AllocatorInfo allocator, ssize capacity) { return GEN_NS array_init_reserve<Type>(allocator, capacity); } | ||||||
| 	forceinline static usize  grow_formula(ssize value)                             { return GEN_NS array_grow_formula<Type>(value); } | 	forceinline static usize  grow_formula(ssize value)                             { return GEN_NS array_grow_formula<Type>(value); } | ||||||
|  |  | ||||||
| 	forceinline bool         append(Array other)                               { return GEN_NS append<Type>(*this, other); } | 	forceinline bool         append(Array other)                               { return GEN_NS append<Type>(this, other); } | ||||||
| 	forceinline bool         append(Type value)                                { return GEN_NS append<Type>(*this, value); } | 	forceinline bool         append(Type value)                                { return GEN_NS append<Type>(this, value); } | ||||||
| 	forceinline bool         append(Type* items, usize item_num)               { return GEN_NS append<Type>(*this, items, item_num); } | 	forceinline bool         append(Type* items, usize item_num)               { return GEN_NS append<Type>(this, items, item_num); } | ||||||
| 	forceinline bool         append_at(Type item, usize idx)                   { return GEN_NS append_at<Type>(*this, item, idx); } | 	forceinline bool         append_at(Type item, usize idx)                   { return GEN_NS append_at<Type>(this, item, idx); } | ||||||
| 	forceinline bool         append_at(Type* items, usize item_num, usize idx) { return GEN_NS append_at<Type>(*this, items, item_num, idx); } | 	forceinline bool         append_at(Type* items, usize item_num, usize idx) { return GEN_NS append_at<Type>(this, items, item_num, idx); } | ||||||
| 	forceinline Type&        back()                                            { return GEN_NS back<Type>(*this); } | 	forceinline Type*        back()                                            { return GEN_NS back<Type>(* this); } | ||||||
| 	forceinline void         clear()                                           { GEN_NS clear<Type>(*this); } | 	forceinline void         clear()                                           { GEN_NS clear<Type>(* this); } | ||||||
| 	forceinline bool         fill(usize begin, usize end, Type value)          { return GEN_NS fill<Type>(*this, begin, end, value); } | 	forceinline bool         fill(usize begin, usize end, Type value)          { return GEN_NS fill<Type>(* this, begin, end, value); } | ||||||
| 	forceinline void         free()                                            { GEN_NS free<Type>(*this); } | 	forceinline void         free()                                            { GEN_NS free<Type>(this); } | ||||||
| 	forceinline ArrayHeader* get_header()                                      { return GEN_NS get_header<Type>(*this); } | 	forceinline ArrayHeader* get_header()                                      { return GEN_NS get_header<Type>(* this); } | ||||||
| 	forceinline bool         grow(usize min_capacity)                          { return GEN_NS grow<Type>(*this, min_capacity); } | 	forceinline bool         grow(usize min_capacity)                          { return GEN_NS grow<Type>(this, min_capacity); } | ||||||
| 	forceinline usize        num()                                             { return GEN_NS num<Type>(*this); } | 	forceinline usize        num()                                             { return GEN_NS num<Type>(*this); } | ||||||
| 	forceinline void         pop()                                             { GEN_NS pop<Type>(*this); } | 	forceinline void         pop()                                             { GEN_NS pop<Type>(* this); } | ||||||
| 	forceinline void         remove_at(usize idx)                              { GEN_NS remove_at<Type>(*this, idx); } | 	forceinline void         remove_at(usize idx)                              { GEN_NS remove_at<Type>(* this, idx); } | ||||||
| 	forceinline bool         reserve(usize new_capacity)                       { return GEN_NS reserve<Type>(*this, new_capacity); } | 	forceinline bool         reserve(usize new_capacity)                       { return GEN_NS reserve<Type>(this, new_capacity); } | ||||||
| 	forceinline bool         resize(usize num)                                 { return GEN_NS resize<Type>(*this, num); } | 	forceinline bool         resize(usize num)                                 { return GEN_NS resize<Type>(this, num); } | ||||||
| 	forceinline bool         set_capacity(usize new_capacity)                  { return GEN_NS set_capacity<Type>(*this, new_capacity); } | 	forceinline bool         set_capacity(usize new_capacity)                  { return GEN_NS set_capacity<Type>(this, new_capacity); } | ||||||
|  | #pragma endregion Member Mapping | ||||||
|  |  | ||||||
| 	forceinline operator Type*()             { return Data; } | 	forceinline operator Type*()             { return Data; } | ||||||
| 	forceinline operator Type const*() const { return Data; } | 	forceinline operator Type const*() const { return Data; } | ||||||
| 	forceinline Type* begin()                { return Data; } | 	forceinline Type* begin()                { return Data; } | ||||||
| 	forceinline Type* end()                  { return Data + get_header()->Num; } | 	forceinline Type* end()                  { return Data + get_header()->Num; } | ||||||
| #pragma endregion Member Mapping |  | ||||||
|  | 	forceinline Type&       operator[](ssize index)       { return Data[index]; } | ||||||
|  | 	forceinline Type const& operator[](ssize index) const { return Data[index]; } | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #if GEN_SUPPORT_CPP_REFERENCES | ||||||
|  | template<class Type> bool         append(Array<Type>& array, Array<Type> other)                         { return GEN_NS append( & array, other ); } | ||||||
|  | template<class Type> bool         append(Array<Type>& array, Type value)                                { return GEN_NS append( & array, value ); } | ||||||
|  | template<class Type> bool         append(Array<Type>& array, Type* items, usize item_num)               { return GEN_NS append( & array, items, item_num ); } | ||||||
|  | template<class Type> bool         append_at(Array<Type>& array, Type item, usize idx)                   { return GEN_NS append_at( & array, item, idx ); } | ||||||
|  | template<class Type> bool         append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return GEN_NS append_at( & array, items, item_num, idx ); } | ||||||
|  | template<class Type> void         free(Array<Type>& array)                                              { return GEN_NS free( & array ); } | ||||||
|  | template<class Type> bool         grow(Array<Type>& array, usize min_capacity)                          { return GEN_NS grow( & array, min_capacity); } | ||||||
|  | template<class Type> bool         reserve(Array<Type>& array, usize new_capacity)                       { return GEN_NS reserve( & array, new_capacity); } | ||||||
|  | template<class Type> bool         resize(Array<Type>& array, usize num)                                 { return GEN_NS resize( & array, num); } | ||||||
|  | template<class Type> bool         set_capacity(Array<Type>& array, usize new_capacity)                  { return GEN_NS set_capacity( & array, new_capacity); } | ||||||
|  |  | ||||||
|  | template<class Type> forceinline Type* begin(Array<Type>& array)             { return array;      } | ||||||
|  | template<class Type> forceinline Type* end(Array<Type>& array)               { return array + get_header(array)->Num; } | ||||||
|  | template<class Type> forceinline Type* next(Array<Type>& array, Type* entry) { return entry + 1; } | ||||||
|  | #else | ||||||
|  | template<class Type> forceinline Type* begin(Array<Type> array)             { return array;      } | ||||||
|  | template<class Type> forceinline Type* end(Array<Type> array)               { return array + get_header(array)->Num; } | ||||||
|  | template<class Type> forceinline Type* next(Array<Type> array, Type* entry) { return entry + 1; } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| Array<Type> array_init(AllocatorInfo allocator) { | Array<Type> array_init(AllocatorInfo allocator) { | ||||||
| 	return array_init_reserve<Type>(allocator, array_grow_formula(0)); | 	return array_init_reserve<Type>(allocator, array_grow_formula(0)); | ||||||
| @@ -121,30 +141,30 @@ usize array_grow_formula(ssize value) { | |||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool append(Array<Type>& array, Array<Type> other) { | bool append(Array<Type>* array, Array<Type> other) { | ||||||
| 	return append(array, other, num(other)); | 	return append(array, other, num(other)); | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool append(Array<Type>& array, Type value) | bool append(Array<Type>* array, Type value) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(* array); | ||||||
|  |  | ||||||
| 	if (header->Num == header->Capacity) | 	if (header->Num == header->Capacity) | ||||||
| 	{ | 	{ | ||||||
| 		if (!grow(array, header->Capacity)) | 		if (!grow(array, header->Capacity)) | ||||||
| 			return false; | 			return false; | ||||||
| 		header = get_header(array); | 		header = get_header(* array); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	array[header->Num] = value; | 	(*array)[ header->Num] = value; | ||||||
| 	header->Num++; | 	header->Num++; | ||||||
|  |  | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool append(Array<Type>& array, Type* items, usize item_num) | bool append(Array<Type>* array, Type* items, usize item_num) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(array); | ||||||
|  |  | ||||||
| @@ -162,34 +182,37 @@ bool append(Array<Type>& array, Type* items, usize item_num) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool append_at(Array<Type>& array, Type item, usize idx) | bool append_at(Array<Type>* array, Type item, usize idx) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(* array); | ||||||
|  |  | ||||||
| 	if (idx >= header->Num) | 	ssize slot = idx; | ||||||
| 	 	idx = header->Num - 1; | 	if (slot >= header->Num) | ||||||
|  | 	 	slot = header->Num - 1; | ||||||
|  |  | ||||||
| 	if (idx < 0) | 	if (slot < 0) | ||||||
|  		idx = 0; |  		slot = 0; | ||||||
|  |  | ||||||
| 	if (header->Capacity < header->Num + 1) | 	if (header->Capacity < header->Num + 1) | ||||||
| 	{ | 	{ | ||||||
| 		if (!grow(array, header->Capacity + 1)) | 		if ( ! grow(array, header->Capacity + 1)) | ||||||
| 			return false; | 			return false; | ||||||
|  |  | ||||||
| 		header = get_header(array); | 		header = get_header(* array); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Type* target = array + idx; | 	Type* target = array->Data + slot; | ||||||
|  |  | ||||||
| 	mem_move(target + 1, target, (header->Num - idx) * sizeof(Type)); | 	mem_move(target + 1, target, (header->Num - slot) * sizeof(Type)); | ||||||
| 	header->Num++; | 	header->Num++; | ||||||
|  |  | ||||||
|  | 	header = get_header(* array); | ||||||
|  |  | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) | bool append_at(Array<Type>* array, Type* items, usize item_num, usize idx) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(array); | ||||||
|  |  | ||||||
| @@ -200,7 +223,7 @@ bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) | |||||||
|  |  | ||||||
| 	if (item_num > header->Capacity) | 	if (item_num > header->Capacity) | ||||||
| 	{ | 	{ | ||||||
| 		if (!grow(array, header->Capacity + item_num)) | 		if (! grow(array, header->Capacity + item_num)) | ||||||
| 			return false; | 			return false; | ||||||
|  |  | ||||||
| 		header = get_header(array); | 		header = get_header(array); | ||||||
| @@ -217,19 +240,25 @@ bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| Type& back(Array<Type>& array) { | Type* back(Array<Type>* array) | ||||||
| 	ArrayHeader* header = get_header(array); | { | ||||||
| 	return array[header->Num - 1]; | 	GEN_ASSERT(array != nullptr); | ||||||
|  |  | ||||||
|  | 	ArrayHeader* header = get_header(* array); | ||||||
|  | 	if (header->Num <= 0) | ||||||
|  | 		return nullptr; | ||||||
|  |  | ||||||
|  | 	return & (*array)[header->Num - 1]; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| void clear(Array<Type>& array) { | void clear(Array<Type> array) { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(array); | ||||||
| 	header->Num = 0; | 	header->Num = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool fill(Array<Type>& array, usize begin, usize end, Type value) | bool fill(Array<Type> array, usize begin, usize end, Type value) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(array); | ||||||
|  |  | ||||||
| @@ -245,24 +274,24 @@ bool fill(Array<Type>& array, usize begin, usize end, Type value) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| void free(Array<Type>& array) { | void free(Array<Type>* array) { | ||||||
| 	ArrayHeader* header = get_header(array); | 	GEN_ASSERT(array != nullptr); | ||||||
|  | 	ArrayHeader* header = get_header(* array); | ||||||
| 	GEN_NS free(header->Allocator, header); | 	GEN_NS free(header->Allocator, header); | ||||||
| 	Type*& Data = rcast(Type*&, array); | 	array->Data = nullptr; | ||||||
| 	Data = nullptr; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> forceinline | ||||||
| ArrayHeader* get_header(Array<Type>& array) { | ArrayHeader* get_header(Array<Type> array) { | ||||||
|  |     Type* Data = array; | ||||||
|  |  | ||||||
| 	using NonConstType = TRemoveConst<Type>; | 	using NonConstType = TRemoveConst<Type>; | ||||||
| 	Type* Data = array; // This should do nothing in C but in C++ gets member Data struct. |  | ||||||
|     return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1; |     return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool grow(Array<Type>& array, usize min_capacity) | bool grow(Array<Type>* array, usize min_capacity) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header       = get_header(* array); | ||||||
| 	usize        new_capacity = array_grow_formula(header->Capacity); | 	usize        new_capacity = array_grow_formula(header->Capacity); | ||||||
|  |  | ||||||
| 	if (new_capacity < min_capacity) | 	if (new_capacity < min_capacity) | ||||||
| @@ -272,19 +301,19 @@ bool grow(Array<Type>& array, usize min_capacity) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| usize num(Array<Type>& array) { | usize num(Array<Type> array) { | ||||||
| 	return get_header(array)->Num; | 	return get_header(array)->Num; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| void pop(Array<Type>& array) { | void pop(Array<Type> array) { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(array); | ||||||
| 	GEN_ASSERT(header->Num > 0); | 	GEN_ASSERT(header->Num > 0); | ||||||
| 	header->Num--; | 	header->Num--; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| void remove_at(Array<Type>& array, usize idx) | void remove_at(Array<Type> array, usize idx) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(array); | ||||||
| 	GEN_ASSERT(idx < header->Num); | 	GEN_ASSERT(idx < header->Num); | ||||||
| @@ -294,7 +323,7 @@ void remove_at(Array<Type>& array, usize idx) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool reserve(Array<Type>& array, usize new_capacity) | bool reserve(Array<Type>* array, usize new_capacity) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(array); | ||||||
|  |  | ||||||
| @@ -305,14 +334,14 @@ bool reserve(Array<Type>& array, usize new_capacity) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool resize(Array<Type>& array, usize num) | bool resize(Array<Type>* array, usize num) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(* array); | ||||||
|  |  | ||||||
| 	if (header->Capacity < num) { | 	if (header->Capacity < num) { | ||||||
| 		if (!grow(array, num)) | 		if (! grow( array, num)) | ||||||
| 			return false; | 			return false; | ||||||
| 		header = get_header(array); | 		header = get_header(* array); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	header->Num = num; | 	header->Num = num; | ||||||
| @@ -320,9 +349,9 @@ bool resize(Array<Type>& array, usize num) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<class Type> inline | template<class Type> inline | ||||||
| bool set_capacity(Array<Type>& array, usize new_capacity) | bool set_capacity(Array<Type>* array, usize new_capacity) | ||||||
| { | { | ||||||
| 	ArrayHeader* header = get_header(array); | 	ArrayHeader* header = get_header(* array); | ||||||
|  |  | ||||||
| 	if (new_capacity == header->Capacity) | 	if (new_capacity == header->Capacity) | ||||||
| 	return true; | 	return true; | ||||||
| @@ -345,32 +374,10 @@ bool set_capacity(Array<Type>& array, usize new_capacity) | |||||||
|  |  | ||||||
| 	GEN_NS free(header->Allocator, header); | 	GEN_NS free(header->Allocator, header); | ||||||
|  |  | ||||||
| 	Type*& Data = rcast(Type*&, array); | 	array->Data = rcast(Type*, new_header + 1); | ||||||
| 	Data = rcast(Type*, new_header + 1); |  | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| #define array_init(Type, allocator)                            array_init<Type>(allocator) |  | ||||||
| #define array_init(Type, allocator)                            array_init<Type>(allocator) |  | ||||||
| #define array_init_reserve(Type, allocator, capacity)          array_init_reserve<Type>(allocator, capacity) |  | ||||||
| #define array_append(Type, array, other)                       append<Type>(array, other) |  | ||||||
| #define array_append_value(Type, array, value)                 append<Type>(array, value) |  | ||||||
| #define array_append_items(Type, array, items, item_num)       append<Type>(array, items, item_num) |  | ||||||
| #define array_append_at(Type, array, item, idx)                append_at<Type>(array, item, idx) |  | ||||||
| #define array_append_items_at(Type, array, items, num, idx)    append_at<Type>(array, items, num, idx) |  | ||||||
| #define array_back(Type, array)                                back<Type>(array) |  | ||||||
| #define array_clear(Type, array)                               clear<Type>(array) |  | ||||||
| #define array_fill(Type, array, begin, end, value)             fill<Type>(array, begin, end, value) |  | ||||||
| #define array_free(Type, array)                                free<Type>(array) |  | ||||||
| #define array_grow(Type, array, min_capacity)                  grow<Type>(array, min_capacity) |  | ||||||
| #define array_num(Type, array)                                 num<Type>(array) |  | ||||||
| #define array_pop(Type, array)                                 pop<Type>(array) |  | ||||||
| #define array_remove_at(Type, array, idx)                      remove_at<Type>(array, idx) |  | ||||||
| #define array_reserve(Type, array, new_capacity)               reserve<Type>(array, new_capacity) |  | ||||||
| #define array_resize(Type, array, num)                         resize<Type>(array, num) |  | ||||||
| #define array_set_capacity(Type, array, new_capacity)          set_capacity<Type>(array, new_capacity) |  | ||||||
| #define array_get_header(array)                                get_header(array) |  | ||||||
|  |  | ||||||
| #pragma endregion Array | #pragma endregion Array | ||||||
|  |  | ||||||
| // TODO(Ed) : This thing needs ALOT of work. | // TODO(Ed) : This thing needs ALOT of work. | ||||||
| @@ -395,21 +402,21 @@ struct HashTableEntry { | |||||||
|  |  | ||||||
| template<class Type> HashTable<Type>       hashtable_init(AllocatorInfo allocator); | template<class Type> HashTable<Type>       hashtable_init(AllocatorInfo allocator); | ||||||
| template<class Type> HashTable<Type>       hashtable_init_reserve(AllocatorInfo allocator, usize num); | template<class Type> HashTable<Type>       hashtable_init_reserve(AllocatorInfo allocator, usize num); | ||||||
| template<class Type> void                  clear(HashTable<Type>& table); | template<class Type> void                  clear        (HashTable<Type>  table); | ||||||
| template<class Type> void                  destroy(HashTable<Type>& table); | template<class Type> void                  destroy      (HashTable<Type>* table); | ||||||
| template<class Type> Type*                 get(HashTable<Type>& table, u64 key); | template<class Type> Type*                 get          (HashTable<Type>  table, u64 key); | ||||||
| template<class Type> void                  grow(HashTable<Type>& table); | template<class Type> void                  grow         (HashTable<Type>* table); | ||||||
| template<class Type> void                  rehash(HashTable<Type>& table, ssize new_num); | template<class Type> void                  rehash       (HashTable<Type>* table, ssize new_num); | ||||||
| template<class Type> void                  rehash_fast(HashTable<Type>& table); | template<class Type> void                  rehash_fast  (HashTable<Type>  table); | ||||||
| template<class Type> void                  remove(HashTable<Type>& table, u64 key); | template<class Type> void                  remove       (HashTable<Type>  table, u64 key); | ||||||
| template<class Type> void                  remove_entry(HashTable<Type>& table, ssize idx); | template<class Type> void                  remove_entry (HashTable<Type>  table, ssize idx); | ||||||
| template<class Type> void                  set(HashTable<Type>& table, u64 key, Type value); | template<class Type> void                  set          (HashTable<Type>* table, u64 key, Type value); | ||||||
| template<class Type> ssize                 slot(HashTable<Type>& table, u64 key); | template<class Type> ssize                 slot         (HashTable<Type>  table, u64 key); | ||||||
| template<class Type> ssize                 add_entry(HashTable<Type>& table, u64 key); | template<class Type> ssize                 add_entry    (HashTable<Type>* table, u64 key); | ||||||
| template<class Type> HashTableFindResult   find(HashTable<Type>& table, u64 key); | template<class Type> HashTableFindResult   find         (HashTable<Type>  table, u64 key); | ||||||
| template<class Type> bool                  full(HashTable<Type>& table); | template<class Type> bool                  full         (HashTable<Type>  table); | ||||||
| template<class Type> void                  map(HashTable<Type>& table, void (*map_proc)(u64 key, Type value)); | template<class Type> void                  map          (HashTable<Type>  table, void (*map_proc)(u64 key, Type value)); | ||||||
| template<class Type> void                  map_mut(HashTable<Type>& table, void (*map_proc)(u64 key, Type* value)); | template<class Type> void                  map_mut      (HashTable<Type>  table, void (*map_proc)(u64 key, Type* value)); | ||||||
|  |  | ||||||
| static constexpr f32 HashTable_CriticalLoadScale = 0.7f; | static constexpr f32 HashTable_CriticalLoadScale = 0.7f; | ||||||
|  |  | ||||||
| @@ -440,6 +447,14 @@ struct HashTable | |||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | #if GEN_SUPPORT_CPP_REFERENCES | ||||||
|  | template<class Type> void  destroy  (HashTable<Type>& table)                      { destroy(& table); } | ||||||
|  | template<class Type> void  grow     (HashTable<Type>& table)                      { grow(& table); } | ||||||
|  | template<class Type> void  rehash   (HashTable<Type>& table, ssize new_num)       { rehash(& table, new_num); } | ||||||
|  | template<class Type> void  set      (HashTable<Type>& table, u64 key, Type value) { set(& table, key, value); } | ||||||
|  | template<class Type> ssize add_entry(HashTable<Type>& table, u64 key)             { add_entry(& table, key); } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| HashTable<Type> hashtable_init(AllocatorInfo allocator) { | HashTable<Type> hashtable_init(AllocatorInfo allocator) { | ||||||
| 	HashTable<Type> result = hashtable_init_reserve<Type>(allocator, 8); | 	HashTable<Type> result = hashtable_init_reserve<Type>(allocator, 8); | ||||||
| @@ -453,7 +468,7 @@ HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num) | |||||||
|  |  | ||||||
| 	result.Hashes = array_init_reserve<ssize>(allocator, num); | 	result.Hashes = array_init_reserve<ssize>(allocator, num); | ||||||
| 	get_header(result.Hashes)->Num = num; | 	get_header(result.Hashes)->Num = num; | ||||||
| 	resize(result.Hashes, num); | 	resize(& result.Hashes, num); | ||||||
| 	fill<ssize>(result.Hashes, 0, num, -1); | 	fill<ssize>(result.Hashes, 0, num, -1); | ||||||
|  |  | ||||||
| 	result.Entries = array_init_reserve<HashTableEntry<Type>>(allocator, num); | 	result.Entries = array_init_reserve<HashTableEntry<Type>>(allocator, num); | ||||||
| @@ -461,65 +476,65 @@ HashTable<Type> hashtable_init_reserve(AllocatorInfo allocator, usize num) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void clear(HashTable<Type>& table) { | void clear(HashTable<Type> table) { | ||||||
| 	clear(table.Entries); | 	clear(table.Entries); | ||||||
| 	fill<ssize>(table.Hashes, 0, num(table.Hashes), -1); | 	fill<ssize>(table.Hashes, 0, num(table.Hashes), -1); | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void destroy(HashTable<Type>& table) { | void destroy(HashTable<Type>* table) { | ||||||
| 	if (table.Hashes && get_header(table.Hashes)->Capacity) { | 	if (table->Hashes && get_header(table->Hashes)->Capacity) { | ||||||
| 		free(table.Hashes); | 		free(& table->Hashes); | ||||||
| 		free(table.Entries); | 		free(& table->Entries); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| Type* get(HashTable<Type>& table, u64 key) { | Type* get(HashTable<Type> table, u64 key) { | ||||||
| 	ssize idx = find(table, key).EntryIndex; | 	ssize idx = find(table, key).EntryIndex; | ||||||
| 	if (idx >= 0) | 	if (idx >= 0) | ||||||
| 		return &table.Entries[idx].Value; | 		return & table.Entries[idx].Value; | ||||||
|  |  | ||||||
| 	return nullptr; | 	return nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void map(HashTable<Type>& table, void (*map_proc)(u64 key, Type value)) { | void map(HashTable<Type> table, void (*map_proc)(u64 key, Type value)) { | ||||||
| 	GEN_ASSERT_NOT_NULL(map_proc); | 	GEN_ASSERT_NOT_NULL(map_proc); | ||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx < ssize(table.Entries.num()); ++idx) { | 	for (ssize idx = 0; idx < ssize(num(table.Entries)); ++idx) { | ||||||
| 		map_proc(table.Entries[idx].Key, table.Entries[idx].Value); | 		map_proc(table.Entries[idx].Key, table.Entries[idx].Value); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void map_mut(HashTable<Type>& table, void (*map_proc)(u64 key, Type* value)) { | void map_mut(HashTable<Type> table, void (*map_proc)(u64 key, Type* value)) { | ||||||
| 	GEN_ASSERT_NOT_NULL(map_proc); | 	GEN_ASSERT_NOT_NULL(map_proc); | ||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx < ssize(table.Entries.num()); ++idx) { | 	for (ssize idx = 0; idx < ssize(num(table.Entries)); ++idx) { | ||||||
| 		map_proc(table.Entries[idx].Key, &table.Entries[idx].Value); | 		map_proc(table.Entries[idx].Key, & table.Entries[idx].Value); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void grow(HashTable<Type>& table) { | void grow(HashTable<Type>* table) { | ||||||
| 	ssize new_num = array_grow_formula(num(table.Entries)); | 	ssize new_num = array_grow_formula(num(table->Entries)); | ||||||
| 	rehash(table, new_num); | 	rehash(table, new_num); | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void rehash(HashTable<Type>& table, ssize new_num) | void rehash(HashTable<Type>* table, ssize new_num) | ||||||
| { | { | ||||||
| 	ssize last_added_index; | 	ssize last_added_index; | ||||||
| 	HashTable<Type> new_ht = hashtable_init_reserve<Type>(get_header(table.Hashes)->Allocator, new_num); | 	HashTable<Type> new_ht = hashtable_init_reserve<Type>(get_header(table->Hashes)->Allocator, new_num); | ||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx < ssize(num(table.Entries)); ++idx) | 	for (ssize idx = 0; idx < ssize(num(table->Entries)); ++idx) | ||||||
| 	{ | 	{ | ||||||
| 		HashTableFindResult find_result; | 		HashTableFindResult find_result; | ||||||
| 		HashTableEntry<Type>& entry = table.Entries[idx]; | 		HashTableEntry<Type>& entry = table->Entries[idx]; | ||||||
|  |  | ||||||
| 		find_result = find(new_ht, entry.Key); | 		find_result = find(new_ht, entry.Key); | ||||||
| 		last_added_index = add_entry(new_ht, entry.Key); | 		last_added_index = add_entry(& new_ht, entry.Key); | ||||||
|  |  | ||||||
| 		if (find_result.PrevIndex < 0) | 		if (find_result.PrevIndex < 0) | ||||||
| 			new_ht.Hashes[find_result.HashIndex] = last_added_index; | 			new_ht.Hashes[find_result.HashIndex] = last_added_index; | ||||||
| @@ -531,21 +546,21 @@ void rehash(HashTable<Type>& table, ssize new_num) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	destroy(table); | 	destroy(table); | ||||||
| 	table = new_ht; | 	* table = new_ht; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void rehash_fast(HashTable<Type>& table) | void rehash_fast(HashTable<Type> table) | ||||||
| { | { | ||||||
| 	ssize idx; | 	ssize idx; | ||||||
|  |  | ||||||
| 	for (idx = 0; idx < ssize(table.Entries.num()); idx++) | 	for (idx = 0; idx < ssize(num(table.Entries)); idx++) | ||||||
| 		table.Entries[idx].Next = -1; | 		table.Entries[idx].Next = -1; | ||||||
|  |  | ||||||
| 	for (idx = 0; idx < ssize(table.Hashes.num()); idx++) | 	for (idx = 0; idx < ssize(num(table.Hashes)); idx++) | ||||||
| 		table.Hashes[idx] = -1; | 		table.Hashes[idx] = -1; | ||||||
|  |  | ||||||
| 	for (idx = 0; idx < ssize(table.Entries.num()); idx++) | 	for (idx = 0; idx < ssize(num(table.Entries)); idx++) | ||||||
| 	{ | 	{ | ||||||
| 		HashTableEntry<Type>* entry; | 		HashTableEntry<Type>* entry; | ||||||
| 		HashTableFindResult find_result; | 		HashTableFindResult find_result; | ||||||
| @@ -561,30 +576,30 @@ void rehash_fast(HashTable<Type>& table) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void remove(HashTable<Type>& table, u64 key) { | void remove(HashTable<Type> table, u64 key) { | ||||||
| 	HashTableFindResult find_result = find(table, key); | 	HashTableFindResult find_result = find(table, key); | ||||||
|  |  | ||||||
| 	if (find_result.EntryIndex >= 0) { | 	if (find_result.EntryIndex >= 0) { | ||||||
| 		table.Entries.remove_at(find_result.EntryIndex); | 		remove_at(table.Entries, find_result.EntryIndex); | ||||||
| 		rehash_fast(table); | 		rehash_fast(table); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void remove_entry(HashTable<Type>& table, ssize idx) { | void remove_entry(HashTable<Type> table, ssize idx) { | ||||||
| 	table.Entries.remove_at(idx); | 	remove_at(table.Entries, idx); | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| void set(HashTable<Type>& table, u64 key, Type value) | void set(HashTable<Type>* table, u64 key, Type value) | ||||||
| { | { | ||||||
| 	ssize idx; | 	ssize idx; | ||||||
| 	HashTableFindResult find_result; | 	HashTableFindResult find_result; | ||||||
|  |  | ||||||
| 	if (full(table)) | 	if (full(* table)) | ||||||
| 		grow(table); | 		grow(table); | ||||||
|  |  | ||||||
| 	find_result = find(table, key); | 	find_result = find(* table, key); | ||||||
| 	if (find_result.EntryIndex >= 0) { | 	if (find_result.EntryIndex >= 0) { | ||||||
| 		idx = find_result.EntryIndex; | 		idx = find_result.EntryIndex; | ||||||
| 	} | 	} | ||||||
| @@ -593,22 +608,22 @@ void set(HashTable<Type>& table, u64 key, Type value) | |||||||
| 		idx = add_entry(table, key); | 		idx = add_entry(table, key); | ||||||
|  |  | ||||||
| 		if (find_result.PrevIndex >= 0) { | 		if (find_result.PrevIndex >= 0) { | ||||||
| 			table.Entries[find_result.PrevIndex].Next = idx; | 			table->Entries[find_result.PrevIndex].Next = idx; | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			table.Hashes[find_result.HashIndex] = idx; | 			table->Hashes[find_result.HashIndex] = idx; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	table.Entries[idx].Value = value; | 	table->Entries[idx].Value = value; | ||||||
|  |  | ||||||
| 	if (full(table)) | 	if (full(* table)) | ||||||
| 		grow(table); | 		grow(table); | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| ssize slot(HashTable<Type>& table, u64 key) { | ssize slot(HashTable<Type> table, u64 key) { | ||||||
| 	for (ssize idx = 0; idx < ssize(table.Hashes.num()); ++idx) | 	for (ssize idx = 0; idx < ssize(num(table.Hashes)); ++idx) | ||||||
| 		if (table.Hashes[idx] == key) | 		if (table.Hashes[idx] == key) | ||||||
| 			return idx; | 			return idx; | ||||||
|  |  | ||||||
| @@ -616,17 +631,17 @@ ssize slot(HashTable<Type>& table, u64 key) { | |||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| ssize add_entry(HashTable<Type>& table, u64 key) { | ssize add_entry(HashTable<Type>* table, u64 key) { | ||||||
| 	ssize idx; | 	ssize idx; | ||||||
| 	HashTableEntry<Type> entry = { key, -1 }; | 	HashTableEntry<Type> entry = { key, -1 }; | ||||||
|  |  | ||||||
| 	idx = num(table.Entries); | 	idx = num(table->Entries); | ||||||
| 	append(table.Entries, entry); | 	append( & table->Entries, entry); | ||||||
| 	return idx; | 	return idx; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| HashTableFindResult find(HashTable<Type>& table, u64 key) | HashTableFindResult find(HashTable<Type> table, u64 key) | ||||||
| { | { | ||||||
| 	HashTableFindResult result = { -1, -1, -1 }; | 	HashTableFindResult result = { -1, -1, -1 }; | ||||||
|  |  | ||||||
| @@ -649,7 +664,7 @@ HashTableFindResult find(HashTable<Type>& table, u64 key) | |||||||
| } | } | ||||||
|  |  | ||||||
| template<typename Type> inline | template<typename Type> inline | ||||||
| bool full(HashTable<Type>& table) { | bool full(HashTable<Type> table) { | ||||||
| 	usize critical_load = usize(HashTable_CriticalLoadScale * f32(num(table.Hashes))); | 	usize critical_load = usize(HashTable_CriticalLoadScale * f32(num(table.Hashes))); | ||||||
| 	b32 result = num(table.Entries) > critical_load; | 	b32 result = num(table.Entries) > critical_load; | ||||||
| 	return result; | 	return result; | ||||||
|   | |||||||
| @@ -612,7 +612,7 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write ) | |||||||
|  |  | ||||||
| 		if ( get_header(arr)->Capacity < usize(new_cap) ) | 		if ( get_header(arr)->Capacity < usize(new_cap) ) | ||||||
| 		{ | 		{ | ||||||
| 			if ( ! grow( arr, ( s64 )( new_cap ) ) ) | 			if ( ! grow( & arr, ( s64 )( new_cap ) ) ) | ||||||
| 				return false; | 				return false; | ||||||
| 			d->buf = arr; | 			d->buf = arr; | ||||||
| 		} | 		} | ||||||
| @@ -647,7 +647,7 @@ GEN_FILE_CLOSE_PROC( _memory_file_close ) | |||||||
| 	if ( d->flags & EFileStream_CLONE_WRITABLE ) | 	if ( d->flags & EFileStream_CLONE_WRITABLE ) | ||||||
| 	{ | 	{ | ||||||
| 		Array<u8> arr = { d->buf }; | 		Array<u8> arr = { d->buf }; | ||||||
| 		free(arr); | 		free(& arr); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	free( allocator, d ); | 	free( allocator, d ); | ||||||
|   | |||||||
| @@ -23,7 +23,11 @@ | |||||||
| #define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) ) | #define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) ) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| #if ! GEN_C_COMPILER | #if ! GEN_C_COMPILER | ||||||
|  | #	ifndef cast | ||||||
|  | #	define cast( type, value ) (tmpl_cast<type>( value )) | ||||||
|  | #	endif | ||||||
| #	ifndef ccast | #	ifndef ccast | ||||||
| #	define ccast( type, value ) ( const_cast< type >( (value) ) ) | #	define ccast( type, value ) ( const_cast< type >( (value) ) ) | ||||||
| #	endif | #	endif | ||||||
| @@ -37,11 +41,14 @@ | |||||||
| #	define scast( type, value ) static_cast< type >( value ) | #	define scast( type, value ) static_cast< type >( value ) | ||||||
| #	endif | #	endif | ||||||
| #else | #else | ||||||
|  | #	ifndef cast | ||||||
|  | #	define cast( type, value )  ( (type)(value) ) | ||||||
|  | #	endif | ||||||
| #	ifndef ccast | #	ifndef ccast | ||||||
| #	define ccast( type, value ) ( (type)(value) ) | #	define ccast( type, value ) ( (type)(value) ) | ||||||
| #	endif | #	endif | ||||||
| #	ifndef pcast | #	ifndef pcast | ||||||
| #	define pcast( type, value ) ( (type)(value) ) | #	define pcast( type, value ) ( * (type*)(value) ) | ||||||
| #	endif | #	endif | ||||||
| #	ifndef rcast | #	ifndef rcast | ||||||
| #	define rcast( type, value ) ( (type)(value) ) | #	define rcast( type, value ) ( (type)(value) ) | ||||||
| @@ -181,7 +188,13 @@ | |||||||
| #	endif | #	endif | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if !defined(GEN_SUPPORT_CPP_MEMBER_FEATURES) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L) | #if !defined(GEN_SUPPORT_CPP_REFERENCES) && (GEN_COMPILER_C || __STDC_VERSION__ < 202311L) | ||||||
|  | #	undef    GEN_SUPPORT_CPP_REFERENCES | ||||||
|  | #	define   GEN_SUPPORT_CPP_REFERENCES 0 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if !defined(GEN_SUPPORT_CPP_MEMBER_FEATURES) && (GEN_COMPILER_C || __STDC_VERSION__ < 202311L) | ||||||
|  | #	undef    GEN_SUPPORT_CPP_MEMBER_FEATURES | ||||||
| #	define   GEN_SUPPORT_CPP_MEMBER_FEATURES 0 | #	define   GEN_SUPPORT_CPP_MEMBER_FEATURES 0 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -215,4 +228,10 @@ | |||||||
| #	define enum_underlying(type) : type | #	define enum_underlying(type) : type | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #if GEN_COMPILER_C | ||||||
|  | #	ifndef nullptr | ||||||
|  | #		define nullptr NULL | ||||||
|  | #	endif | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #pragma endregion Macros | #pragma endregion Macros | ||||||
|   | |||||||
| @@ -62,21 +62,23 @@ void zero_size( void* ptr, ssize size ); | |||||||
| //! Clears up an array. | //! Clears up an array. | ||||||
| #define zero_array( a, count ) zero_size( ( a ), size_of( *( a ) ) * count ) | #define zero_array( a, count ) zero_size( ( a ), size_of( *( a ) ) * count ) | ||||||
|  |  | ||||||
| enum AllocType : u8 | enum AllocType_Def //enum_underlying(u8) | ||||||
| { | { | ||||||
| 	EAllocation_ALLOC, | 	EAllocation_ALLOC, | ||||||
| 	EAllocation_FREE, | 	EAllocation_FREE, | ||||||
| 	EAllocation_FREE_ALL, | 	EAllocation_FREE_ALL, | ||||||
| 	EAllocation_RESIZE, | 	EAllocation_RESIZE, | ||||||
| }; | }; | ||||||
|  | typedef enum AllocType_Def AllocType; | ||||||
|  |  | ||||||
| typedef void*(AllocatorProc)( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); | typedef void*(AllocatorProc)( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); | ||||||
|  |  | ||||||
| struct AllocatorInfo | struct AllocatorInfo_Def | ||||||
| { | { | ||||||
| 	AllocatorProc* Proc; | 	AllocatorProc* Proc; | ||||||
| 	void*          Data; | 	void*          Data; | ||||||
| }; | }; | ||||||
|  | typedef struct AllocatorInfo_Def AllocatorInfo; | ||||||
|  |  | ||||||
| enum AllocFlag | enum AllocFlag | ||||||
| { | { | ||||||
| @@ -132,7 +134,7 @@ void* default_resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize ne | |||||||
| void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); | void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); | ||||||
|  |  | ||||||
| //! The heap allocator backed by operating system's memory manager. | //! The heap allocator backed by operating system's memory manager. | ||||||
| constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr }; } | constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; } | ||||||
|  |  | ||||||
| //! Helper to allocate memory using heap allocator. | //! Helper to allocate memory using heap allocator. | ||||||
| #define malloc( sz ) alloc( heap(), sz ) | #define malloc( sz ) alloc( heap(), sz ) | ||||||
| @@ -170,26 +172,26 @@ ssize gen_virtual_memory_page_size( ssize* alignment_out ); | |||||||
| #pragma region Arena | #pragma region Arena | ||||||
| struct Arena; | struct Arena; | ||||||
|  |  | ||||||
| AllocatorInfo allocator_info( Arena& arena ); | AllocatorInfo allocator_info( Arena* arena ); | ||||||
|  |  | ||||||
| // Remove static keyword and rename allocator_proc | // Remove static keyword and rename allocator_proc | ||||||
| void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); | void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); | ||||||
|  |  | ||||||
| // Add these declarations after the Arena struct | // Add these declarations after the Arena struct | ||||||
| Arena arena_init_from_allocator(AllocatorInfo backing, ssize size); | Arena arena_init_from_allocator(AllocatorInfo backing, ssize size); | ||||||
| Arena arena_init_from_memory( void* start, ssize size ); | Arena arena_init_from_memory   ( void* start, ssize size ); | ||||||
| Arena init_sub(Arena& parent, ssize size); |  | ||||||
| ssize alignment_of(Arena& arena, ssize alignment); | Arena init_sub      (Arena* parent, ssize size); | ||||||
|  | ssize alignment_of  (Arena* arena, ssize alignment); | ||||||
|  | void  free          (Arena* arena); | ||||||
|  | ssize size_remaining(Arena* arena, ssize alignment); | ||||||
|  |  | ||||||
| // This id is defined by Unreal for asserts | // This id is defined by Unreal for asserts | ||||||
| #pragma push_macro("check") | #pragma push_macro("check") | ||||||
| #undef check | #undef check | ||||||
| void   check(Arena& arena); | void   check(Arena* arena); | ||||||
| #pragma pop_macro("check") | #pragma pop_macro("check") | ||||||
|  |  | ||||||
| void  free(Arena& arena); |  | ||||||
| ssize size_remaining(Arena& arena, ssize alignment); |  | ||||||
|  |  | ||||||
| struct Arena | struct Arena | ||||||
| { | { | ||||||
| 	AllocatorInfo Backing; | 	AllocatorInfo Backing; | ||||||
| @@ -200,29 +202,45 @@ struct Arena | |||||||
|  |  | ||||||
| #if GEN_SUPPORT_CPP_MEMBER_FEATURES | #if GEN_SUPPORT_CPP_MEMBER_FEATURES | ||||||
| #pragma region Member Mapping | #pragma region Member Mapping | ||||||
| 	forceinline operator AllocatorInfo() { return GEN_NS allocator_info(* this); } | 	forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); } | ||||||
|  |  | ||||||
| 	forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return GEN_NS arena_allocator_proc( allocator_data, type, size, alignment, old_memory, old_size, flags ); } | 	forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return GEN_NS arena_allocator_proc( allocator_data, type, size, alignment, old_memory, old_size, flags ); } | ||||||
| 	forceinline static Arena init_from_memory( void* start, ssize size )                                                                                      { return GEN_NS arena_init_from_memory( start, size ); } | 	forceinline static Arena init_from_memory( void* start, ssize size )                                                                                      { return GEN_NS arena_init_from_memory( start, size ); } | ||||||
| 	forceinline static Arena init_from_allocator( AllocatorInfo backing, ssize size )                                                                         { return GEN_NS arena_init_from_allocator( backing, size ); } | 	forceinline static Arena init_from_allocator( AllocatorInfo backing, ssize size )                                                                         { return GEN_NS arena_init_from_allocator( backing, size ); } | ||||||
| 	forceinline static Arena init_sub( Arena& parent, ssize size )                                                                                            { return GEN_NS arena_init_from_allocator( parent.Backing, size ); } | 	forceinline static Arena init_sub( Arena& parent, ssize size )                                                                                            { return GEN_NS arena_init_from_allocator( parent.Backing, size ); } | ||||||
| 	forceinline        ssize alignment_of( ssize alignment )                                                                                                  { return GEN_NS alignment_of(* this, alignment); } | 	forceinline        ssize alignment_of( ssize alignment )                                                                                                  { return GEN_NS alignment_of(this, alignment); } | ||||||
| 	forceinline        void  free()                                                                                                                           { return GEN_NS free(* this);  } | 	forceinline        void  free()                                                                                                                           { return GEN_NS free(this);  } | ||||||
| 	forceinline        ssize size_remaining( ssize alignment )                                                                                                { return GEN_NS size_remaining(* this, alignment); } | 	forceinline        ssize size_remaining( ssize alignment )                                                                                                { return GEN_NS size_remaining(this, alignment); } | ||||||
|  |  | ||||||
| // This id is defined by Unreal for asserts | // This id is defined by Unreal for asserts | ||||||
| #pragma push_macro("check") | #pragma push_macro("check") | ||||||
| #undef check | #undef check | ||||||
| 	forceinline void check() { GEN_NS check(* this); } | 	forceinline void check() { GEN_NS check(this); } | ||||||
| #pragma pop_macro("check") | #pragma pop_macro("check") | ||||||
|  |  | ||||||
| #pragma endregion Member Mapping | #pragma endregion Member Mapping | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | #if GEN_SUPPORT_CPP_REFERENCES | ||||||
|  | forceinline AllocatorInfo allocator_info(Arena& arena )                 { return allocator_info(& arena); } | ||||||
|  | forceinline Arena         init_sub      (Arena& parent, ssize size)     { return init_sub( & parent, size); } | ||||||
|  | forceinline ssize         alignment_of  (Arena& arena, ssize alignment) { return alignment_of( & arena, alignment); } | ||||||
|  | forceinline void          free          (Arena& arena)                  { return free(& arena); } | ||||||
|  | forceinline ssize         size_remaining(Arena& arena, ssize alignment) { return size_remaining(& arena, alignment); } | ||||||
|  |  | ||||||
|  | // This id is defined by Unreal for asserts | ||||||
|  | #pragma push_macro("check") | ||||||
|  | #undef check | ||||||
|  | forceinline void check(Arena& arena) { return check(& arena); }; | ||||||
|  | #pragma pop_macro("check") | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| inline | inline | ||||||
| AllocatorInfo allocator_info( Arena& arena ) { | AllocatorInfo allocator_info( Arena* arena ) { | ||||||
| 	return { arena_allocator_proc, &arena }; | 	GEN_ASSERT(arena != nullptr); | ||||||
|  | 	return { arena_allocator_proc, arena }; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| @@ -251,18 +269,20 @@ Arena arena_init_from_allocator(AllocatorInfo backing, ssize size) { | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| Arena init_sub(Arena& parent, ssize size) { | Arena init_sub(Arena* parent, ssize size) { | ||||||
| 	return arena_init_from_allocator(parent.Backing, size); | 	GEN_ASSERT(parent != nullptr); | ||||||
|  | 	return arena_init_from_allocator(parent->Backing, size); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| ssize alignment_of(Arena& arena, ssize alignment) | ssize alignment_of(Arena* arena, ssize alignment) | ||||||
| { | { | ||||||
|  | 	GEN_ASSERT(arena != nullptr); | ||||||
| 	ssize alignment_offset, result_pointer, mask; | 	ssize alignment_offset, result_pointer, mask; | ||||||
| 	GEN_ASSERT(is_power_of_two(alignment)); | 	GEN_ASSERT(is_power_of_two(alignment)); | ||||||
|  |  | ||||||
| 	alignment_offset = 0; | 	alignment_offset = 0; | ||||||
| 	result_pointer  = (ssize)arena.PhysicalStart + arena.TotalUsed; | 	result_pointer  = (ssize)arena->PhysicalStart + arena->TotalUsed; | ||||||
| 	mask            = alignment - 1; | 	mask            = alignment - 1; | ||||||
|  |  | ||||||
| 	if (result_pointer & mask) | 	if (result_pointer & mask) | ||||||
| @@ -274,26 +294,29 @@ ssize alignment_of(Arena& arena, ssize alignment) | |||||||
| #pragma push_macro("check") | #pragma push_macro("check") | ||||||
| #undef check | #undef check | ||||||
| inline | inline | ||||||
| void check(Arena& arena) | void check(Arena* arena) | ||||||
| { | { | ||||||
|     GEN_ASSERT(arena.TempCount == 0); |     GEN_ASSERT(arena != nullptr ); | ||||||
|  |     GEN_ASSERT(arena->TempCount == 0); | ||||||
| } | } | ||||||
| #pragma pop_macro("check") | #pragma pop_macro("check") | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void free(Arena& arena) | void free(Arena* arena) | ||||||
| { | { | ||||||
| 	if (arena.Backing.Proc) | 	GEN_ASSERT(arena != nullptr); | ||||||
|  | 	if (arena->Backing.Proc) | ||||||
| 	{ | 	{ | ||||||
| 		GEN_NS free(arena.Backing, arena.PhysicalStart); | 		GEN_NS free(arena->Backing, arena->PhysicalStart); | ||||||
| 		arena.PhysicalStart = nullptr; | 		arena->PhysicalStart = nullptr; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| ssize size_remaining(Arena& arena, ssize alignment) | ssize size_remaining(Arena* arena, ssize alignment) | ||||||
| { | { | ||||||
| 	ssize result = arena.TotalSize - (arena.TotalUsed + alignment_of(arena, alignment)); | 	GEN_ASSERT(arena != nullptr); | ||||||
|  | 	ssize result = arena->TotalSize - (arena->TotalUsed + alignment_of(arena, alignment)); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| #pragma endregion Arena | #pragma endregion Arena | ||||||
| @@ -302,9 +325,14 @@ ssize size_remaining(Arena& arena, ssize alignment) | |||||||
| template<s32 Size> | template<s32 Size> | ||||||
| struct FixedArena; | struct FixedArena; | ||||||
|  |  | ||||||
| template<s32 Size> AllocatorInfo    allocator_info( FixedArena<Size>& fixed_arena ); |  | ||||||
| template<s32 Size> FixedArena<Size> fixed_arena_init(); | template<s32 Size> FixedArena<Size> fixed_arena_init(); | ||||||
| template<s32 Size> ssize            size_remaining(FixedArena<Size>& fixed_arena, ssize alignment); | template<s32 Size> AllocatorInfo    allocator_info(FixedArena<Size>* fixed_arena ); | ||||||
|  | template<s32 Size> ssize            size_remaining(FixedArena<Size>* fixed_arena, ssize alignment); | ||||||
|  |  | ||||||
|  | #if GEN_SUPPORT_CPP_REFERENCES | ||||||
|  | template<s32 Size> AllocatorInfo    allocator_info( FixedArena<Size>& fixed_arena )                { return allocator_info(& fixed_arena); } | ||||||
|  | template<s32 Size> ssize            size_remaining(FixedArena<Size>& fixed_arena, ssize alignment) { return size_remaining( & fixed_arena, alignment); } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| // Just a wrapper around using an arena with memory associated with its scope instead of from an allocator. | // Just a wrapper around using an arena with memory associated with its scope instead of from an allocator. | ||||||
| // Used for static segment or stack allocations. | // Used for static segment or stack allocations. | ||||||
| @@ -316,26 +344,29 @@ struct FixedArena | |||||||
|  |  | ||||||
| #if GEN_SUPPORT_CPP_MEMBER_FEATURES | #if GEN_SUPPORT_CPP_MEMBER_FEATURES | ||||||
| #pragma region Member Mapping | #pragma region Member Mapping | ||||||
| 	forceinline operator AllocatorInfo() { return GEN_NS allocator_info(* this); } | 	forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); } | ||||||
|  |  | ||||||
| 	forceinline static FixedArena init()                          { FixedArena result; GEN_NS fixed_arena_init<Size>(result); return result; } | 	forceinline static FixedArena init()                          { FixedArena result; GEN_NS fixed_arena_init<Size>(result); return result; } | ||||||
| 	forceinline ssize             size_remaining(ssize alignment) { GEN_NS size_remaining(*this, alignment); } | 	forceinline ssize             size_remaining(ssize alignment) { GEN_NS size_remaining(this, alignment); } | ||||||
| #pragma endregion Member Mapping | #pragma endregion Member Mapping | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template<s32 Size> inline | template<s32 Size> inline | ||||||
| AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena ) { return { arena_allocator_proc, & fixed_arena.arena }; } | AllocatorInfo allocator_info( FixedArena<Size>* fixed_arena ) { | ||||||
|  | 	GEN_ASSERT(fixed_arena); | ||||||
| template<s32 Size> inline | 	return { arena_allocator_proc, & fixed_arena->arena }; | ||||||
| void fixed_arena_init(FixedArena<Size>& result) { |  | ||||||
|     zero_size(& result.memory[0], Size); |  | ||||||
|     result.arena = arena_init_from_memory(& result.memory[0], Size); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| template<s32 Size> inline | template<s32 Size> inline | ||||||
| ssize size_remaining(FixedArena<Size>& fixed_arena, ssize alignment) { | void fixed_arena_init(FixedArena<Size>* result) { | ||||||
|     return size_remaining(fixed_arena.arena, alignment); |     zero_size(& result->memory[0], Size); | ||||||
|  |     result->arena = arena_init_from_memory(& result->memory[0], Size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template<s32 Size> inline | ||||||
|  | ssize size_remaining(FixedArena<Size>* fixed_arena, ssize alignment) { | ||||||
|  |     return size_remaining(fixed_arena->arena, alignment); | ||||||
| } | } | ||||||
|  |  | ||||||
| using Arena_1KB   = FixedArena< kilobytes( 1 ) >; | using Arena_1KB   = FixedArena< kilobytes( 1 ) >; | ||||||
| @@ -355,12 +386,19 @@ using Arena_4MB   = FixedArena< megabytes( 4 ) >; | |||||||
| #pragma region Pool | #pragma region Pool | ||||||
| struct Pool; | struct Pool; | ||||||
|  |  | ||||||
| AllocatorInfo allocator_info(Pool& pool); |  | ||||||
| void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); | void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); | ||||||
|  |  | ||||||
| Pool          pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size); | Pool          pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size); | ||||||
| Pool          pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align); | Pool          pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align); | ||||||
|  | AllocatorInfo allocator_info(Pool* pool); | ||||||
|  | void          clear(Pool* pool); | ||||||
|  | void          free(Pool* pool); | ||||||
|  |  | ||||||
|  | #if GEN_SUPPORT_CPP_REFERENCES | ||||||
|  | AllocatorInfo allocator_info(Pool& pool); | ||||||
| void          clear(Pool& pool); | void          clear(Pool& pool); | ||||||
| void          free(Pool& pool); | void          free(Pool& pool); | ||||||
|  | #endif | ||||||
|  |  | ||||||
| struct Pool | struct Pool | ||||||
| { | { | ||||||
| @@ -374,20 +412,20 @@ struct Pool | |||||||
|  |  | ||||||
| #if GEN_SUPPORT_CPP_MEMBER_FEATURES | #if GEN_SUPPORT_CPP_MEMBER_FEATURES | ||||||
| #pragma region Member Mapping | #pragma region Member Mapping | ||||||
|     forceinline operator AllocatorInfo() { return GEN_NS allocator_info(* this); } |     forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); } | ||||||
|  |  | ||||||
|     forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return GEN_NS pool_allocator_proc(allocator_data, type, size, alignment, old_memory, old_size, flags); } |     forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return GEN_NS pool_allocator_proc(allocator_data, type, size, alignment, old_memory, old_size, flags); } | ||||||
|     forceinline static Pool  init(AllocatorInfo backing, ssize num_blocks, ssize block_size)                                                                { return GEN_NS pool_init(backing, num_blocks, block_size); } |     forceinline static Pool  init(AllocatorInfo backing, ssize num_blocks, ssize block_size)                                                                { return GEN_NS pool_init(backing, num_blocks, block_size); } | ||||||
|     forceinline static Pool  init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align)                                       { return GEN_NS pool_init_align(backing, num_blocks, block_size, block_align); } |     forceinline static Pool  init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align)                                       { return GEN_NS pool_init_align(backing, num_blocks, block_size, block_align); } | ||||||
|     forceinline        void  clear() { GEN_NS clear(* this); } |     forceinline        void  clear() { GEN_NS clear( this); } | ||||||
|     forceinline        void  free()  { GEN_NS free(* this); } |     forceinline        void  free()  { GEN_NS free( this); } | ||||||
| #pragma endregion | #pragma endregion | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
| inline | inline | ||||||
| AllocatorInfo allocator_info(Pool& pool) { | AllocatorInfo allocator_info(Pool* pool) { | ||||||
|    return { pool_allocator_proc, &pool }; |    return { pool_allocator_proc, pool }; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| @@ -396,9 +434,9 @@ Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size) { | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void free(Pool& pool) { | void free(Pool* pool) { | ||||||
|    if(pool.Backing.Proc) { |    if(pool->Backing.Proc) { | ||||||
|        GEN_NS free(pool.Backing, pool.PhysicalStart); |        GEN_NS free(pool->Backing, pool->PhysicalStart); | ||||||
|    } |    } | ||||||
| } | } | ||||||
| #pragma endregion Pool | #pragma endregion Pool | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ u8 adt_destroy_branch( ADT_Node* node ) | |||||||
| 			adt_destroy_branch( node->nodes + i ); | 			adt_destroy_branch( node->nodes + i ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		free(node->nodes); | 		free(& node->nodes); | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| @@ -287,10 +287,11 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index ) | |||||||
|  |  | ||||||
| 	ADT_Node o = { 0 }; | 	ADT_Node o = { 0 }; | ||||||
| 	o.parent   = parent; | 	o.parent   = parent; | ||||||
| 	if ( ! append_at( parent->nodes, o, index ) ) | 	if ( ! append_at( & parent->nodes, o, index ) ) | ||||||
| 		return NULL; | 		return NULL; | ||||||
|  |  | ||||||
| 	return parent->nodes + index; | 	ADT_Node* node = & parent->nodes[index]; | ||||||
|  | 	return node; | ||||||
| } | } | ||||||
|  |  | ||||||
| ADT_Node* adt_alloc( ADT_Node* parent ) | ADT_Node* adt_alloc( ADT_Node* parent ) | ||||||
| @@ -402,7 +403,9 @@ ADT_Node* adt_append_arr( ADT_Node* parent, char const* name ) | |||||||
| 	ADT_Node* o = adt_alloc( parent ); | 	ADT_Node* o = adt_alloc( parent ); | ||||||
| 	if ( ! o ) | 	if ( ! o ) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	if ( adt_set_arr( o, name, get_header(parent->nodes)->Allocator ) ) |  | ||||||
|  | 	ArrayHeader* node_header = get_header(parent->nodes); | ||||||
|  | 	if ( adt_set_arr( o, name, node_header->Allocator ) ) | ||||||
| 	{ | 	{ | ||||||
| 		adt_remove_node( o ); | 		adt_remove_node( o ); | ||||||
| 		return NULL; | 		return NULL; | ||||||
| @@ -951,7 +954,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | |||||||
| 			adt_append_arr( root, NULL ); | 			adt_append_arr( root, NULL ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		append(root->nodes[ columnIndex ].nodes, rowItem ); | 		append( & root->nodes[ columnIndex ].nodes, rowItem ); | ||||||
|  |  | ||||||
| 		if ( delimiter == delim ) | 		if ( delimiter == delim ) | ||||||
| 		{ | 		{ | ||||||
|   | |||||||
| @@ -83,7 +83,7 @@ struct ADT_Node | |||||||
| 	union | 	union | ||||||
| 	{ | 	{ | ||||||
| 		char const*     string; | 		char const*     string; | ||||||
| 		Array<ADT_Node> nodes;    ///< zpl_array | 		Array(ADT_Node) nodes;    ///< zpl_array | ||||||
|  |  | ||||||
| 		struct | 		struct | ||||||
| 		{ | 		{ | ||||||
|   | |||||||
| @@ -125,9 +125,13 @@ | |||||||
| #		include <intrin.h> | #		include <intrin.h> | ||||||
| #	endif | #	endif | ||||||
|  |  | ||||||
|  | #if GEN_COMPILER_C | ||||||
|  | #include <assert.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #pragma endregion Mandatory Includes | #pragma endregion Mandatory Includes | ||||||
|  |  | ||||||
| #if GEN_DONT_USE_NAMESPACE | #if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C | ||||||
| #	if GEN_COMPILER_C | #	if GEN_COMPILER_C | ||||||
| #		define GEN_NS_ENUM_BEGIN | #		define GEN_NS_ENUM_BEGIN | ||||||
| #		define GEN_NS_ENUM_END | #		define GEN_NS_ENUM_END | ||||||
|   | |||||||
| @@ -33,40 +33,41 @@ StrC to_str( char const* str ) { | |||||||
| struct StringHeader; | struct StringHeader; | ||||||
| struct String; | struct String; | ||||||
|  |  | ||||||
| String        string_make(AllocatorInfo allocator, char const* str); |  | ||||||
| String        string_make(AllocatorInfo allocator, StrC str); |  | ||||||
| String        string_make_reserve(AllocatorInfo allocator, ssize capacity); |  | ||||||
| String        string_make_length(AllocatorInfo allocator, char const* str, ssize length); |  | ||||||
| String        string_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...); |  | ||||||
| String        string_fmt_buf(AllocatorInfo allocator, char const* fmt, ...); |  | ||||||
| String        string_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue); |  | ||||||
| usize string_grow_formula(usize value); | usize string_grow_formula(usize value); | ||||||
| bool          are_equal(String const& lhs, String const& rhs); |  | ||||||
| bool          are_equal(String const& lhs, StrC rhs); | String        string_make         (AllocatorInfo allocator, char const*  str); | ||||||
| bool          make_space_for(String& str, char const* to_append, ssize add_len); | String        string_make         (AllocatorInfo allocator, StrC         str); | ||||||
| bool          append(String& str, char c); | String        string_make_reserve (AllocatorInfo allocator, ssize        capacity); | ||||||
| bool          append(String& str, char const* str_to_append); | String        string_make_length  (AllocatorInfo allocator, char const*  str,   ssize length); | ||||||
| bool          append(String& str, char const* str_to_append, ssize length); | String        string_fmt          (AllocatorInfo allocator, char*        buf,   ssize buf_size,  char const* fmt, ...); | ||||||
| bool          append(String& str, StrC str_to_append); | String        string_fmt_buf      (AllocatorInfo allocator, char const*  fmt, ...); | ||||||
| bool          append(String& str, const String other); | String        string_join         (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue); | ||||||
| bool          append_fmt(String& str, char const* fmt, ...); | bool          are_equal           (String const lhs, String const rhs); | ||||||
| ssize         avail_space(String const& str); | bool          are_equal           (String const lhs, StrC rhs); | ||||||
| char&         back(String& str); | bool          make_space_for      (String*      str, char const*  to_append, ssize add_len); | ||||||
| bool          contains(String const& str, StrC substring); | bool          append              (String*      str, char         c); | ||||||
| bool          contains(String const& str, String const& substring); | bool          append              (String*      str, char const*  str_to_append); | ||||||
| ssize         capacity(String const& str); | bool          append              (String*      str, char const*  str_to_append, ssize length); | ||||||
| void          clear(String& str); | bool          append              (String*      str, StrC         str_to_append); | ||||||
| String        duplicate(String const& str, AllocatorInfo allocator); | bool          append              (String*      str, String const other); | ||||||
| void          free(String& str); | bool          append_fmt          (String*      str, char const*  fmt, ...); | ||||||
| StringHeader& get_header(String& str); | ssize         avail_space         (String const str); | ||||||
| ssize         length(String const& str); | char*         back                (String       str); | ||||||
| b32           starts_with(String const& str, StrC substring); | bool          contains            (String const str, StrC         substring); | ||||||
| b32           starts_with(String const& str, String substring); | bool          contains            (String const str, String const substring); | ||||||
| void          skip_line(String& str); | ssize         capacity            (String const str); | ||||||
| void          strip_space(String& str); | void          clear               (String       str); | ||||||
| void          trim(String& str, char const* cut_set); | String        duplicate           (String const str, AllocatorInfo allocator); | ||||||
| void          trim_space(String& str); | void          free                (String*      str); | ||||||
| String        visualize_whitespace(String const& str); | StringHeader* get_header          (String       str); | ||||||
|  | ssize         length              (String const str); | ||||||
|  | b32           starts_with         (String const str, StrC   substring); | ||||||
|  | b32           starts_with         (String const str, String substring); | ||||||
|  | void          skip_line           (String       str); | ||||||
|  | void          strip_space         (String       str); | ||||||
|  | void          trim                (String       str, char const* cut_set); | ||||||
|  | void          trim_space          (String       str); | ||||||
|  | String        visualize_whitespace(String const str); | ||||||
|  |  | ||||||
| struct StringHeader { | struct StringHeader { | ||||||
| 	AllocatorInfo Allocator; | 	AllocatorInfo Allocator; | ||||||
| @@ -129,31 +130,31 @@ struct String | |||||||
| 		return GEN_NS string_make(allocator, buf); | 		return GEN_NS string_make(allocator, buf); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	forceinline bool          make_space_for(char const* str, ssize add_len) { return GEN_NS make_space_for(*this, str, add_len); } | 	forceinline bool          make_space_for(char const* str, ssize add_len) { return GEN_NS make_space_for(this, str, add_len); } | ||||||
| 	forceinline bool          append(char c)                                 { return GEN_NS append(*this, c); } | 	forceinline bool          append(char c)                                 { return GEN_NS append(this, c); } | ||||||
| 	forceinline bool          append(char const* str)                        { return GEN_NS append(*this, str); } | 	forceinline bool          append(char const* str)                        { return GEN_NS append(this, str); } | ||||||
| 	forceinline bool          append(char const* str, ssize length)          { return GEN_NS append(*this, str, length); } | 	forceinline bool          append(char const* str, ssize length)          { return GEN_NS append(this, str, length); } | ||||||
| 	forceinline bool          append(StrC str)                               { return GEN_NS append(*this, str); } | 	forceinline bool          append(StrC str)                               { return GEN_NS append(this, str); } | ||||||
| 	forceinline bool          append(const String other)                     { return GEN_NS append(*this, other); } | 	forceinline bool          append(const String other)                     { return GEN_NS append(this, other); } | ||||||
| 	forceinline ssize         avail_space() const                            { return GEN_NS avail_space(*this); } | 	forceinline ssize         avail_space() const                            { return GEN_NS avail_space(* this); } | ||||||
| 	forceinline char&         back()                                         { return GEN_NS back(*this); } | 	forceinline char*         back()                                         { return GEN_NS back(* this); } | ||||||
| 	forceinline bool          contains(StrC substring) const                 { return GEN_NS contains(*this, substring); } | 	forceinline bool          contains(StrC substring) const                 { return GEN_NS contains(* this, substring); } | ||||||
| 	forceinline bool          contains(String const& substring) const        { return GEN_NS contains(*this, substring); } | 	forceinline bool          contains(String const& substring) const        { return GEN_NS contains(* this, substring); } | ||||||
| 	forceinline ssize         capacity() const                               { return GEN_NS capacity(*this); } | 	forceinline ssize         capacity() const                               { return GEN_NS capacity(* this); } | ||||||
| 	forceinline void          clear()                                        { GEN_NS clear(*this); } | 	forceinline void          clear()                                        { GEN_NS clear(* this); } | ||||||
| 	forceinline String        duplicate(AllocatorInfo allocator) const       { return GEN_NS duplicate(*this, allocator); } | 	forceinline String        duplicate(AllocatorInfo allocator) const       { return GEN_NS duplicate(* this, allocator); } | ||||||
| 	forceinline void          free()                                         { GEN_NS free(*this); } | 	forceinline void          free()                                         { GEN_NS free(this); } | ||||||
| 	forceinline bool          is_equal(String const& other) const            { return GEN_NS are_equal(* this, other); } | 	forceinline bool          is_equal(String const& other) const            { return GEN_NS are_equal(* this, other); } | ||||||
| 	forceinline bool          is_equal(StrC other) const                     { return GEN_NS are_equal(* this, other); } | 	forceinline bool          is_equal(StrC other) const                     { return GEN_NS are_equal(* this, other); } | ||||||
| 	forceinline ssize         length() const                                 { return GEN_NS length(*this); } | 	forceinline ssize         length() const                                 { return GEN_NS length(* this); } | ||||||
| 	forceinline b32           starts_with(StrC substring) const              { return GEN_NS starts_with(*this, substring); } | 	forceinline b32           starts_with(StrC substring) const              { return GEN_NS starts_with(* this, substring); } | ||||||
| 	forceinline b32           starts_with(String substring) const            { return GEN_NS starts_with(*this, substring); } | 	forceinline b32           starts_with(String substring) const            { return GEN_NS starts_with(* this, substring); } | ||||||
| 	forceinline void          skip_line()                                    { GEN_NS skip_line(*this); } | 	forceinline void          skip_line()                                    { GEN_NS skip_line(* this); } | ||||||
| 	forceinline void          strip_space()                                  { GEN_NS strip_space(*this); } | 	forceinline void          strip_space()                                  { GEN_NS strip_space(* this); } | ||||||
| 	forceinline void          trim(char const* cut_set)                      { GEN_NS trim(*this, cut_set); } | 	forceinline void          trim(char const* cut_set)                      { GEN_NS trim(* this, cut_set); } | ||||||
| 	forceinline void          trim_space()                                   { GEN_NS trim_space(*this); } | 	forceinline void          trim_space()                                   { GEN_NS trim_space(* this); } | ||||||
| 	forceinline String        visualize_whitespace() const                   { return GEN_NS visualize_whitespace(*this); } | 	forceinline String        visualize_whitespace() const                   { return GEN_NS visualize_whitespace(* this); } | ||||||
| 	forceinline StringHeader& get_header()                                   { return GEN_NS get_header(*this); } | 	forceinline StringHeader& get_header()                                   { return * GEN_NS get_header(* this); } | ||||||
|  |  | ||||||
| 	bool append_fmt(char const* fmt, ...) { | 	bool append_fmt(char const* fmt, ...) { | ||||||
| 		ssize res; | 		ssize res; | ||||||
| @@ -164,13 +165,26 @@ struct String | |||||||
| 		res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1; | 		res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1; | ||||||
| 		va_end(va); | 		va_end(va); | ||||||
|  |  | ||||||
| 		return GEN_NS append(*this, buf, res); | 		return GEN_NS append(this, buf, res); | ||||||
| 	} | 	} | ||||||
| #pragma endregion Member Mapping | #pragma endregion Member Mapping | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #if GEN_SUPPORT_CPP_REFERENCES | ||||||
|  | bool          make_space_for(String& str, char const* to_append, ssize add_len); | ||||||
|  | bool          append(String& str, char c); | ||||||
|  | bool          append(String& str, char const* str_to_append); | ||||||
|  | bool          append(String& str, char const* str_to_append, ssize length); | ||||||
|  | bool          append(String& str, StrC str_to_append); | ||||||
|  | bool          append(String& str, const String other); | ||||||
|  | bool          append_fmt(String& str, char const* fmt, ...); | ||||||
|  | char&         back(String& str); | ||||||
|  | void          clear(String& str); | ||||||
|  | void          free(String& str); | ||||||
|  | #endif | ||||||
|  |  | ||||||
| inline char* begin(String& str) { return str; } | inline char* begin(String& str) { return str; } | ||||||
| inline char* end(String& str)   { return scast(char*, str) + length(str); } | inline char* end(String& str)   { return scast(char*, str) + length(str); } | ||||||
| inline char* next(String& str)  { return scast(char*, str) + 1; } | inline char* next(String& str)  { return scast(char*, str) + 1; } | ||||||
| @@ -223,57 +237,64 @@ String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts, | |||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx < num_parts; ++idx) | 	for (ssize idx = 0; idx < num_parts; ++idx) | ||||||
| 	{ | 	{ | ||||||
| 		append(result, parts[idx]); | 		append(& result, parts[idx]); | ||||||
|  |  | ||||||
| 		if (idx < num_parts - 1) | 		if (idx < num_parts - 1) | ||||||
| 			append(result, glue); | 			append(& result, glue); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool append(String& str, char c) { | bool append(String* str, char c) { | ||||||
|  | 	GEN_ASSERT(str != nullptr); | ||||||
| 	return append(str, &c, 1); | 	return append(str, &c, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool append(String& str, char const* str_to_append) { | bool append(String* str, char const* str_to_append) { | ||||||
|  | 	GEN_ASSERT(str != nullptr); | ||||||
| 	return append(str, str_to_append, str_len(str_to_append)); | 	return append(str, str_to_append, str_len(str_to_append)); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool append(String& str, char const* str_to_append, ssize append_length) | bool append(String* str, char const* str_to_append, ssize append_length) | ||||||
| { | { | ||||||
|  | 	GEN_ASSERT(str != nullptr); | ||||||
| 	if (sptr(str_to_append) > 0) | 	if (sptr(str_to_append) > 0) | ||||||
| 	{ | 	{ | ||||||
| 		ssize curr_len = length(str); | 		ssize curr_len = length(* str); | ||||||
|  |  | ||||||
| 		if (!make_space_for(str, str_to_append, append_length)) | 		if ( ! make_space_for(str, str_to_append, append_length)) | ||||||
| 			return false; | 			return false; | ||||||
|  |  | ||||||
| 		StringHeader& header = get_header(str); | 		StringHeader* header = get_header(* str); | ||||||
|  |  | ||||||
| 		mem_copy( scast(char*, str) + curr_len, str_to_append, append_length); | 		char* Data = * str; | ||||||
|  | 		mem_copy( Data + curr_len, str_to_append, append_length); | ||||||
|  |  | ||||||
| 		str[curr_len + append_length] = '\0'; | 		Data[curr_len + append_length] = '\0'; | ||||||
|  |  | ||||||
| 		header.Length = curr_len + append_length; | 		header->Length = curr_len + append_length; | ||||||
| 	} | 	} | ||||||
| 	return str_to_append != nullptr; | 	return str_to_append != nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool append(String& str, StrC str_to_append) { | bool append(String* str, StrC str_to_append) { | ||||||
|  | 	GEN_ASSERT(str != nullptr); | ||||||
| 	return append(str, str_to_append.Ptr, str_to_append.Len); | 	return append(str, str_to_append.Ptr, str_to_append.Len); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool append(String& str, const String other) { | bool append(String* str, const String other) { | ||||||
|  | 	GEN_ASSERT(str != nullptr); | ||||||
| 	return append(str, other, length(other)); | 	return append(str, other, length(other)); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool append_fmt(String& str, char const* fmt, ...) { | bool append_fmt(String* str, char const* fmt, ...) { | ||||||
|  | 	GEN_ASSERT(str != nullptr); | ||||||
| 	ssize res; | 	ssize res; | ||||||
| 	char buf[GEN_PRINTF_MAXLEN] = { 0 }; | 	char buf[GEN_PRINTF_MAXLEN] = { 0 }; | ||||||
|  |  | ||||||
| @@ -286,7 +307,7 @@ bool append_fmt(String& str, char const* fmt, ...) { | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool are_equal(String const& lhs, String const& rhs) | bool are_equal(String const lhs, String const rhs) | ||||||
| { | { | ||||||
| 	if (length(lhs) != length(rhs)) | 	if (length(lhs) != length(rhs)) | ||||||
| 		return false; | 		return false; | ||||||
| @@ -299,43 +320,43 @@ bool are_equal(String const& lhs, String const& rhs) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool are_equal(String const& lhs, StrC rhs) | bool are_equal(String const lhs, StrC rhs) | ||||||
| { | { | ||||||
| 	if (length(lhs) != (rhs.Len)) | 	if (length(lhs) != (rhs.Len)) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx < length(lhs); ++idx) | 	for (ssize idx = 0; idx < length(lhs); ++idx) | ||||||
| 		if (lhs[idx] != rhs[idx]) | 		if (lhs[idx] != rhs.Ptr[idx]) | ||||||
| 			return false; | 			return false; | ||||||
|  |  | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| ssize avail_space(String const& str) { | ssize avail_space(String const str) { | ||||||
| 	StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | 	StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | ||||||
| 	return header.Capacity - header.Length; | 	return header->Capacity - header->Length; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| char& back(String& str) { | char* back(String* str) { | ||||||
| 	return str.Data[length(str) - 1]; | 	return & (*str)[length(* str) - 1]; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool contains(String const& str, StrC substring) | bool contains(String const str, StrC substring) | ||||||
| { | { | ||||||
| 	StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | 	StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | ||||||
|  |  | ||||||
| 	if (substring.Len > header.Length) | 	if (substring.Len > header->Length) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	ssize main_len = header.Length; | 	ssize main_len = header->Length; | ||||||
| 	ssize sub_len  = substring.Len; | 	ssize sub_len  = substring.Len; | ||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx <= main_len - sub_len; ++idx) | 	for (ssize idx = 0; idx <= main_len - sub_len; ++idx) | ||||||
| 	{ | 	{ | ||||||
| 		if (str_compare(str.Data + idx, substring.Ptr, sub_len) == 0) | 		if (str_compare(str + idx, substring.Ptr, sub_len) == 0) | ||||||
| 			return true; | 			return true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -343,19 +364,19 @@ bool contains(String const& str, StrC substring) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool contains(String const& str, String const& substring) | bool contains(String const str, String const substring) | ||||||
| { | { | ||||||
| 	StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | 	StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | ||||||
|  |  | ||||||
| 	if (length(substring) > header.Length) | 	if (length(substring) > header->Length) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	ssize main_len = header.Length; | 	ssize main_len = header->Length; | ||||||
| 	ssize sub_len  = length(substring); | 	ssize sub_len  = length(substring); | ||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx <= main_len - sub_len; ++idx) | 	for (ssize idx = 0; idx <= main_len - sub_len; ++idx) | ||||||
| 	{ | 	{ | ||||||
| 		if (str_compare(str.Data + idx, substring.Data, sub_len) == 0) | 		if (str_compare(str + idx, substring, sub_len) == 0) | ||||||
| 			return true; | 			return true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -363,46 +384,47 @@ bool contains(String const& str, String const& substring) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| ssize capacity(String const& str) { | ssize capacity(String const str) { | ||||||
|    StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); |    StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | ||||||
|    return header.Capacity; |    return header->Capacity; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void clear(String& str) { | void clear(String str) { | ||||||
|    get_header(str).Length = 0; |    get_header(str)->Length = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| String duplicate(String const& str, AllocatorInfo allocator) { | String duplicate(String const str, AllocatorInfo allocator) { | ||||||
|    return string_make_length(allocator, str, length(str)); |    return string_make_length(allocator, str, length(str)); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void free(String& str) { | void free(String* str) { | ||||||
|    if (!str.Data) | 	GEN_ASSERT(str != nullptr); | ||||||
|  | 	if (! (* str)) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
|    StringHeader& header = get_header(str); | 	StringHeader* header = get_header(* str); | ||||||
|    GEN_NS free(header.Allocator, &header); | 	GEN_NS free(header->Allocator, header); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| StringHeader& get_header(String& str) { | StringHeader* get_header(String str) { | ||||||
|    return *(StringHeader*)(str.Data - sizeof(StringHeader)); |    return (StringHeader*)(scast(char*, str) - sizeof(StringHeader)); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| ssize length(String const& str) | ssize length(String const str) | ||||||
| { | { | ||||||
|    StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); |    StringHeader const& header = *rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | ||||||
|    return header.Length; |    return header.Length; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool make_space_for(String& str, char const* to_append, ssize add_len) | bool make_space_for(String* str, char const* to_append, ssize add_len) | ||||||
| { | { | ||||||
| 	ssize available = avail_space(str); | 	ssize available = avail_space(* str); | ||||||
|  |  | ||||||
| 	if (available >= add_len) { | 	if (available >= add_len) { | ||||||
| 		return true; | 		return true; | ||||||
| @@ -413,12 +435,12 @@ bool make_space_for(String& str, char const* to_append, ssize add_len) | |||||||
| 		void* ptr; | 		void* ptr; | ||||||
| 		void* new_ptr; | 		void* new_ptr; | ||||||
|  |  | ||||||
| 		AllocatorInfo allocator = get_header(str).Allocator; | 		AllocatorInfo allocator = get_header(* str)->Allocator; | ||||||
| 		StringHeader* header    = nullptr; | 		StringHeader* header    = nullptr; | ||||||
|  |  | ||||||
| 		new_len = string_grow_formula(length(str) + add_len); | 		new_len  = string_grow_formula(length(* str) + add_len); | ||||||
| 		ptr = &get_header(str); | 		ptr      = get_header(* str); | ||||||
| 		old_size = size_of(StringHeader) + length(str) + 1; | 		old_size = size_of(StringHeader) + length(* str) + 1; | ||||||
| 		new_size = size_of(StringHeader) + new_len + 1; | 		new_size = size_of(StringHeader) + new_len + 1; | ||||||
|  |  | ||||||
| 		new_ptr = resize(allocator, ptr, old_size, new_size); | 		new_ptr = resize(allocator, ptr, old_size, new_size); | ||||||
| @@ -430,14 +452,15 @@ bool make_space_for(String& str, char const* to_append, ssize add_len) | |||||||
| 		header->Allocator = allocator; | 		header->Allocator = allocator; | ||||||
| 		header->Capacity  = new_len; | 		header->Capacity  = new_len; | ||||||
|  |  | ||||||
| 		str.Data = rcast(char*, header + 1); | 		char** Data = rcast(char**, str); | ||||||
|  | 		* Data = rcast(char*, header + 1); | ||||||
|  |  | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| b32 starts_with(String const& str, StrC substring) { | b32 starts_with(String const str, StrC substring) { | ||||||
| 	if (substring.Len > length(str)) | 	if (substring.Len > length(str)) | ||||||
| 	return false; | 	return false; | ||||||
|  |  | ||||||
| @@ -446,7 +469,7 @@ b32 starts_with(String const& str, StrC substring) { | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| b32 starts_with(String const& str, String substring) { | b32 starts_with(String const str, String substring) { | ||||||
| 	if (length(substring) > length(str)) | 	if (length(substring) > length(str)) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| @@ -455,7 +478,7 @@ b32 starts_with(String const& str, String substring) { | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void skip_line(String& str) | void skip_line(String str) | ||||||
| { | { | ||||||
| #define current (*scanner) | #define current (*scanner) | ||||||
| 	char* scanner = str.Data; | 	char* scanner = str.Data; | ||||||
| @@ -471,22 +494,22 @@ void skip_line(String& str) | |||||||
|  |  | ||||||
| 	mem_move(str.Data, scanner, new_length); | 	mem_move(str.Data, scanner, new_length); | ||||||
|  |  | ||||||
| 	StringHeader* header = &get_header(str); | 	StringHeader* header = get_header(str); | ||||||
| 	header->Length = new_length; | 	header->Length = new_length; | ||||||
| #undef current | #undef current | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void strip_space(String& str) | void strip_space(String str) | ||||||
| { | { | ||||||
|    char* write_pos = str.Data; |    char* write_pos = str; | ||||||
|    char* read_pos = str.Data; |    char* read_pos  = str; | ||||||
|  |  | ||||||
|    while (*read_pos) |    while (* read_pos) | ||||||
|    { |    { | ||||||
|    	if (!char_is_space(*read_pos)) |    	if (! char_is_space(* read_pos)) | ||||||
|    	{ |    	{ | ||||||
|    		*write_pos = *read_pos; |    		* write_pos = * read_pos; | ||||||
|    		  write_pos++; |    		  write_pos++; | ||||||
|    	} |    	} | ||||||
|    	read_pos++; |    	read_pos++; | ||||||
| @@ -495,11 +518,11 @@ void strip_space(String& str) | |||||||
|    write_pos[0] = '\0';  // Null-terminate the modified string |    write_pos[0] = '\0';  // Null-terminate the modified string | ||||||
|  |  | ||||||
|    // Update the length if needed |    // Update the length if needed | ||||||
|    get_header(str).Length = write_pos - str.Data; |    get_header(str)->Length = write_pos - str.Data; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void trim(String& str, char const* cut_set) | void trim(String str, char const* cut_set) | ||||||
| { | { | ||||||
|    ssize len = 0; |    ssize len = 0; | ||||||
|  |  | ||||||
| @@ -519,16 +542,16 @@ void trim(String& str, char const* cut_set) | |||||||
|  |  | ||||||
|    str.Data[len] = '\0'; |    str.Data[len] = '\0'; | ||||||
|  |  | ||||||
|    get_header(str).Length = len; |    get_header(str)->Length = len; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void trim_space(String& str) { | void trim_space(String str) { | ||||||
|    trim(str, " \t\r\n\v\f"); |    trim(str, " \t\r\n\v\f"); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| String visualize_whitespace(String const& str) | String visualize_whitespace(String const str) | ||||||
| { | { | ||||||
| 	StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader)); | 	StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader)); | ||||||
| 	String        result = string_make_reserve(header->Allocator, length(str) * 2); // Assume worst case for space requirements. | 	String        result = string_make_reserve(header->Allocator, length(str) * 2); // Assume worst case for space requirements. | ||||||
| @@ -536,25 +559,25 @@ String visualize_whitespace(String const& str) | |||||||
| 	for (auto c : str) switch (c) | 	for (auto c : str) switch (c) | ||||||
| 	{ | 	{ | ||||||
| 		case ' ': | 		case ' ': | ||||||
| 			append(result, txt("·")); | 			append(& result, txt("·")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\t': | 		case '\t': | ||||||
| 			append(result, txt("→")); | 			append(& result, txt("→")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\n': | 		case '\n': | ||||||
| 			append(result, txt("↵")); | 			append(& result, txt("↵")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\r': | 		case '\r': | ||||||
| 			append(result, txt("⏎")); | 			append(& result, txt("⏎")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\v': | 		case '\v': | ||||||
| 			append(result, txt("⇕")); | 			append(& result, txt("⇕")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\f': | 		case '\f': | ||||||
| 			append(result, txt("⌂")); | 			append(& result, txt("⌂")); | ||||||
| 		break; | 		break; | ||||||
| 		default: | 		default: | ||||||
| 			append(result, c); | 			append(& result, c); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ CodeBody gen_ecode( char const* path ) | |||||||
| 	char  scratch_mem[kilobytes(1)]; | 	char  scratch_mem[kilobytes(1)]; | ||||||
| 	Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); | 	Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); | ||||||
|  |  | ||||||
| 	file_read_contents( allocator_info(scratch), zero_terminate, path ); | 	file_read_contents( allocator_info( & scratch), zero_terminate, path ); | ||||||
|  |  | ||||||
| 	CSV_Object csv_nodes; | 	CSV_Object csv_nodes; | ||||||
| 	csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); | 	csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); | ||||||
| @@ -23,11 +23,12 @@ CodeBody gen_ecode( char const* path ) | |||||||
| 	String enum_entries   = string_make_reserve( GlobalAllocator, kilobytes(1) ); | 	String enum_entries   = string_make_reserve( GlobalAllocator, kilobytes(1) ); | ||||||
| 	String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); | 	String to_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); | ||||||
|  |  | ||||||
| 	for ( ADT_Node node : enum_strs ) | 	for ( ADT_Node& node : enum_strs ) | ||||||
| 	{ | 	{ | ||||||
| 		char const* code = node.string; | 		char const* code = node.string; | ||||||
| 		append_fmt( enum_entries, "%s,\n", code ); |  | ||||||
| 		append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); | 		append_fmt( & enum_entries, "%s,\n", code ); | ||||||
|  | 		append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", (StrC)enum_entries, "enum Type : u32 { <entries> NumTypes };")); | 	CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", (StrC)enum_entries, "enum Type : u32 { <entries> NumTypes };")); | ||||||
| @@ -59,7 +60,7 @@ CodeBody gen_eoperator( char const* path ) | |||||||
| 	char scratch_mem[kilobytes(4)]; | 	char scratch_mem[kilobytes(4)]; | ||||||
| 	Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); | 	Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); | ||||||
|  |  | ||||||
| 	file_read_contents( allocator_info(scratch), zero_terminate, path ); | 	file_read_contents( allocator_info(& scratch), zero_terminate, path ); | ||||||
|  |  | ||||||
| 	CSV_Object csv_nodes; | 	CSV_Object csv_nodes; | ||||||
| 	csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); | 	csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); | ||||||
| @@ -75,8 +76,8 @@ CodeBody gen_eoperator( char const* path ) | |||||||
| 		char const* enum_str     = enum_strs[idx].string; | 		char const* enum_str     = enum_strs[idx].string; | ||||||
| 		char const* entry_to_str = str_strs [idx].string; | 		char const* entry_to_str = str_strs [idx].string; | ||||||
|  |  | ||||||
| 		append_fmt( enum_entries, "%s,\n", enum_str ); | 		append_fmt( & enum_entries, "%s,\n", enum_str ); | ||||||
| 		append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | 		append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeEnum  enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize( | 	CodeEnum  enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize( | ||||||
| @@ -115,7 +116,7 @@ CodeBody gen_especifier( char const* path ) | |||||||
| 	char scratch_mem[kilobytes(4)]; | 	char scratch_mem[kilobytes(4)]; | ||||||
| 	Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); | 	Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); | ||||||
|  |  | ||||||
| 	file_read_contents( allocator_info(scratch), zero_terminate, path ); | 	file_read_contents( allocator_info(& scratch), zero_terminate, path ); | ||||||
|  |  | ||||||
| 	CSV_Object csv_nodes; | 	CSV_Object csv_nodes; | ||||||
| 	csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); | 	csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); | ||||||
| @@ -131,8 +132,8 @@ CodeBody gen_especifier( char const* path ) | |||||||
| 		char const* enum_str     = enum_strs[idx].string; | 		char const* enum_str     = enum_strs[idx].string; | ||||||
| 		char const* entry_to_str = str_strs [idx].string; | 		char const* entry_to_str = str_strs [idx].string; | ||||||
|  |  | ||||||
| 		append_fmt( enum_entries, "%s,\n", enum_str ); | 		append_fmt( & enum_entries, "%s,\n", enum_str ); | ||||||
| 		append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | 		append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeEnum  enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize( | 	CodeEnum  enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize( | ||||||
| @@ -220,7 +221,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) | |||||||
| 	char  scratch_mem[kilobytes(16)]; | 	char  scratch_mem[kilobytes(16)]; | ||||||
| 	Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); | 	Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); | ||||||
|  |  | ||||||
| 	AllocatorInfo scratch_info = allocator_info(scratch); | 	AllocatorInfo scratch_info = allocator_info(& scratch); | ||||||
|  |  | ||||||
| 	FileContents enum_content = file_read_contents( scratch_info, zero_terminate, etok_path ); | 	FileContents enum_content = file_read_contents( scratch_info, zero_terminate, etok_path ); | ||||||
|  |  | ||||||
| @@ -248,8 +249,8 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) | |||||||
| 		char const* enum_str     = enum_strs[idx].string; | 		char const* enum_str     = enum_strs[idx].string; | ||||||
| 		char const* entry_to_str = enum_str_strs [idx].string; | 		char const* entry_to_str = enum_str_strs [idx].string; | ||||||
|  |  | ||||||
| 		append_fmt( enum_entries, "%s,\n", enum_str ); | 		append_fmt( & enum_entries, "%s,\n", enum_str ); | ||||||
| 		append_fmt( to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | 		append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for ( usize idx = 0; idx < num(attribute_strs); idx++ ) | 	for ( usize idx = 0; idx < num(attribute_strs); idx++ ) | ||||||
| @@ -257,14 +258,14 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) | |||||||
| 		char const* attribute_str = attribute_strs[idx].string; | 		char const* attribute_str = attribute_strs[idx].string; | ||||||
| 		char const* entry_to_str  = attribute_str_strs [idx].string; | 		char const* entry_to_str  = attribute_str_strs [idx].string; | ||||||
|  |  | ||||||
| 		append_fmt( attribute_entries, "Attribute_%s,\n", attribute_str ); | 		append_fmt( & attribute_entries, "Attribute_%s,\n", attribute_str ); | ||||||
| 		append_fmt( to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | 		append_fmt( & to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||||
| 		append_fmt( attribute_define_entries, "Entry( Attribute_%s, \"%s\" )", attribute_str, entry_to_str ); | 		append_fmt( & attribute_define_entries, "Entry( Attribute_%s, \"%s\" )", attribute_str, entry_to_str ); | ||||||
|  |  | ||||||
| 		if ( idx < num(attribute_strs) - 1 ) | 		if ( idx < num(attribute_strs) - 1 ) | ||||||
| 			append( attribute_define_entries, " \\\n"); | 			append( & attribute_define_entries, " \\\n"); | ||||||
| 		else | 		else | ||||||
| 			append( attribute_define_entries, "\n"); | 			append( & attribute_define_entries, "\n"); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") | #pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") | ||||||
| @@ -342,68 +343,17 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) | |||||||
|  |  | ||||||
| CodeBody gen_ast_inlines() | CodeBody gen_ast_inlines() | ||||||
| { | { | ||||||
|  | #pragma push_macro("GEN_NS") | ||||||
| #pragma push_macro("rcast") | #pragma push_macro("rcast") | ||||||
| #pragma push_macro("log_failure") | #pragma push_macro("log_failure") | ||||||
|  | #pragma push_macro("CodeInvalid") | ||||||
|  | #undef GEN_NS | ||||||
| #undef rcast | #undef rcast | ||||||
| #undef log_failure | #undef log_failure | ||||||
|  | #undef CodeInvalid | ||||||
| 	char const* code_impl_tmpl = stringize( | 	char const* code_impl_tmpl = stringize( | ||||||
| 		\n | 		\n | ||||||
| 		inline | 		inline | ||||||
| 		char const* <typename>::debug_str() |  | ||||||
| 		{ |  | ||||||
| 			if ( ast == nullptr ) |  | ||||||
| 				return "Code::debug_str: AST is null!"; |  | ||||||
|  |  | ||||||
| 			return rcast(AST*, ast)->debug_str(); |  | ||||||
| 		} |  | ||||||
| 		inline |  | ||||||
| 		Code <typename>::duplicate() |  | ||||||
| 		{ |  | ||||||
| 			if ( ast == nullptr ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure("Code::duplicate: Cannot duplicate code, AST is null!"); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			return { rcast(AST*, ast)->duplicate() }; |  | ||||||
| 		} |  | ||||||
| 		inline |  | ||||||
| 		bool <typename>::is_body() |  | ||||||
| 		{ |  | ||||||
| 			if ( ast == nullptr ) |  | ||||||
| 			{ |  | ||||||
| 				return rcast(AST*, ast)->is_body(); |  | ||||||
| 			} |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 		inline |  | ||||||
| 		bool <typename>::is_equal( Code other ) |  | ||||||
| 		{ |  | ||||||
| 			if ( ast == nullptr || other.ast == nullptr ) |  | ||||||
| 			{ |  | ||||||
| 				// Just check if they're both null. |  | ||||||
| 				// log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); |  | ||||||
| 				return ast == nullptr && other.ast == nullptr; |  | ||||||
| 			} |  | ||||||
| 			return rcast(AST*, ast)->is_equal( other.ast ); |  | ||||||
| 		} |  | ||||||
| 		inline |  | ||||||
| 		bool <typename>::is_valid() |  | ||||||
| 		{ |  | ||||||
| 			return (AST*) ast != nullptr && rcast( AST*, ast)->Type != CodeT::Invalid; |  | ||||||
| 		} |  | ||||||
| 		inline |  | ||||||
| 		void <typename>::set_global() |  | ||||||
| 		{ |  | ||||||
| 			if ( ast == nullptr ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure("Code::set_global: Cannot set code as global, AST is null!"); |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			rcast(AST*, ast)->Parent = Code::Global.ast; |  | ||||||
| 		} |  | ||||||
| 		inline |  | ||||||
| 		<typename>& <typename>::operator =( Code other ) | 		<typename>& <typename>::operator =( Code other ) | ||||||
| 		{ | 		{ | ||||||
| 			if ( other.ast && other->Parent ) | 			if ( other.ast && other->Parent ) | ||||||
| @@ -416,16 +366,6 @@ CodeBody gen_ast_inlines() | |||||||
| 			return *this; | 			return *this; | ||||||
| 		} | 		} | ||||||
| 		inline | 		inline | ||||||
| 		bool <typename>::operator ==( Code other ) |  | ||||||
| 		{ |  | ||||||
| 			return (AST*) ast == other.ast; |  | ||||||
| 		} |  | ||||||
| 		inline |  | ||||||
| 		bool <typename>::operator !=( Code other ) |  | ||||||
| 		{ |  | ||||||
| 			return (AST*) ast != other.ast; |  | ||||||
| 		} |  | ||||||
| 		inline |  | ||||||
| 		<typename>::operator bool() | 		<typename>::operator bool() | ||||||
| 		{ | 		{ | ||||||
| 			return ast != nullptr; | 			return ast != nullptr; | ||||||
| @@ -455,6 +395,8 @@ CodeBody gen_ast_inlines() | |||||||
| 		} | 		} | ||||||
| 		\n | 		\n | ||||||
| 	); | 	); | ||||||
|  | #pragma pop_macro("GEN_NS") | ||||||
|  | #pragma pop_macro("CodeInvalid") | ||||||
|  |  | ||||||
| 	CodeBody impl_code          = parse_global_body( token_fmt( "typename", StrC name(Code),               code_impl_tmpl )); | 	CodeBody impl_code          = parse_global_body( token_fmt( "typename", StrC name(Code),               code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_body     = parse_global_body( token_fmt( "typename", StrC name(CodeBody),           code_impl_tmpl )); | 	CodeBody impl_code_body     = parse_global_body( token_fmt( "typename", StrC name(CodeBody),           code_impl_tmpl )); | ||||||
|   | |||||||
| @@ -226,6 +226,30 @@ if ( $c_library ) | |||||||
| 			write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms" | 			write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms" | ||||||
| 		} | 		} | ||||||
| 	Pop-Location | 	Pop-Location | ||||||
|  |  | ||||||
|  | 	$unit       = join-path $path_c_library "gen.c" | ||||||
|  | 	$executable = join-path $path_build     "gen_c_library_test.exe" | ||||||
|  |  | ||||||
|  | 	if ($vendor -eq "clang") { | ||||||
|  | 		$compiler_args += "-x" | ||||||
|  | 		$compiler_args += "c" | ||||||
|  | 	} elseif ($vendor -eq "msvc") { | ||||||
|  | 		$compiler_args += "/TC" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	build-simple $path_build $includes $compiler_args $linker_args $unit $executable | ||||||
|  |  | ||||||
|  | 	Push-Location $path_c_library | ||||||
|  | 		if ( Test-Path( $executable ) ) { | ||||||
|  | 			write-host "`nRunning c_library test" | ||||||
|  | 			$time_taken = Measure-Command { & $executable | ||||||
|  | 					| ForEach-Object { | ||||||
|  | 						write-host `t $_ -ForegroundColor Green | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms" | ||||||
|  | 		} | ||||||
|  | 	Pop-Location | ||||||
| } | } | ||||||
|  |  | ||||||
| if ( $unreal ) | if ( $unreal ) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user