mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 06:20:52 -07:00 
			
		
		
		
	Compare commits
	
		
			14 Commits
		
	
	
		
			v0.20-Alph
			...
			5705196710
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5705196710 | |||
| cf0d787196 | |||
| 8d436fe546 | |||
| e15ac22132 | |||
| bac57a5872 | |||
| 012fcb6bd5 | |||
| 6ffdca8595 | |||
| e3172057d3 | |||
| 8d48da0b9e | |||
| 30dea2e9fd | |||
| 633879d35f | |||
| 831b52129d | |||
| 55427822a0 | |||
| 71b7320e1c | 
							
								
								
									
										0
									
								
								.vscode/bookmarks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								.vscode/bookmarks.json
									
									
									
									
										vendored
									
									
								
							
							
								
								
									
										31
									
								
								Readme.md
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								Readme.md
									
									
									
									
									
								
							| @@ -6,39 +6,36 @@ The library API is a composition of code element constructors, and a non-standar | |||||||
| These build up a code AST to then serialize with a file builder, or can be traversed for staged-reflection of C/C++ code. | These build up a code AST to then serialize with a file builder, or can be traversed for staged-reflection of C/C++ code. | ||||||
|  |  | ||||||
| This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto).   | This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto).   | ||||||
| Its not meant to be a black box metaprogramming utility, it should be easy to intergrate into a user's project domain. | Its not meant to be a black box metaprogramming utility, it should be easy to integrate into a user's project domain. | ||||||
|  |  | ||||||
| ## Documentation | ## Documentation | ||||||
|  |  | ||||||
| * [docs - General](./docs/Readme.md): Overview and additional docs | * [docs - General](./docs/Readme.md): Overview and additional docs | ||||||
|   * [AST_Design](./docs/AST_Design.md): Overvie of ASTs |   * [AST_Design](./docs/AST_Design.md): Overview of ASTs | ||||||
|   * [AST Types](./docs/AST_Types.md): Listing of all AST types along with their Code type interface. |   * [AST Types](./docs/AST_Types.md): Listing of all AST types along with their Code type interface. | ||||||
|   * [Parsing](./docs/Parsing.md): Overview of the parsing interface. |   * [Parsing](./docs/Parsing.md): Overview of the parsing interface. | ||||||
|   * [Parser Algo](./docs/Parser_Algo.md): In-depth breakdown of the parser's implementation. |   * [Parser Algo](./docs/Parser_Algo.md): In-depth breakdown of the parser's implementation. | ||||||
| * [base](./base/Readme.md): Essential (base) library. | * [base](./base/Readme.md): Essential (base) library. | ||||||
| * [gen_c_library](./gen_c_library/): C11 library variant generation (single header and segmeented). | * [gen_c_library](./gen_c_library/): C11 library variant generation (single header and segmented). | ||||||
| * [gen_segmented](./gen_segmented/): Segemented C++ (`gen.<hpp/cpp>`, `gen.dep.<hpp/cpp>`) generation | * [gen_segmented](./gen_segmented/): Segmented C++ (`gen.<hpp/cpp>`, `gen.dep.<hpp/cpp>`) generation | ||||||
| * [gen_singleheader](./gen_singleheader/): Singlehader C++ generation `gen.hpp` | * [gen_singleheader](./gen_singleheader/): Singlehader C++ generation `gen.hpp` | ||||||
| * [gen_unreal_engine](./gen_unreal_engine/): Unreal Engine thirdparty code generation. | * [gen_unreal_engine](./gen_unreal_engine/): Unreal Engine thirdparty code generation. | ||||||
|  |  | ||||||
| ## Notes | ## Notes | ||||||
|  |  | ||||||
| **On Partial Hiatus: Life has got me tackling other issues..** |  | ||||||
| I will be passively updating the library with bug fixes and minor improvements as I use it for my personal projects.   |  | ||||||
| There won't be any major reworks or features to this thing for a while. |  | ||||||
|  |  | ||||||
| This project is still in development (very much an alpha state), so expect bugs and missing features.   | This project is still in development (very much an alpha state), so expect bugs and missing features.   | ||||||
| See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos. | See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos. | ||||||
|  |  | ||||||
| The library can already be used to generate code just fine, but the parser is where the most work is needed. If your C++ isn't "down to earth" expect issues. | The library can already be used to generate code just fine, but the parser is where the most work is needed. If your C++ isn't "down to earth" expect issues. | ||||||
|  |  | ||||||
| A `natvis` and `natstepfilter` are provided in the scripts directory (its outdated, I'll update this readme when its not).   | A `natvis` and `natstepfilter` are provided in the scripts directory (its outdated, I'll update this readme when its not).   | ||||||
|  | *Minor update: I've been using [RAD Debugger](https://github.com/EpicGamesExt/raddebugger) with this and the code structures should be easy to debug even without natvis.* | ||||||
|  |  | ||||||
| ## Usage | ## Usage | ||||||
|  |  | ||||||
| A metaprogram is built to generate files before the main program is built. We'll term runtime for this program as `GEN_TIME`. The metaprogram's core implementation are within `gen.hpp` and `gen.cpp` in the project directory. | A metaprogram is built to generate files before the main program is built. We'll term runtime for this program as `GEN_TIME`. The metaprogram's core implementation are within `gen.hpp` and `gen.cpp` in the project directory. | ||||||
|  |  | ||||||
| `gen.cpp` \`s  `main()` is defined as `gen_main()` which the user will have to define once for their program. There they will dictate everything that should be generated. | `gen.cpp` \`s  `main()` is defined as `gen_main()` which the user will have to define once for their program. There they may reflect and/or generate code. | ||||||
|  |  | ||||||
| In order to keep the locality of this code within the same files the following pattern may be used (although this pattern isn't the best to use): | In order to keep the locality of this code within the same files the following pattern may be used (although this pattern isn't the best to use): | ||||||
|  |  | ||||||
| @@ -98,8 +95,8 @@ Validation through ast construction. | |||||||
| Code header = parse_struct( code( | Code header = parse_struct( code( | ||||||
|     struct ArrayHeader |     struct ArrayHeader | ||||||
|     { |     { | ||||||
|         usize        Num; |         usize     Num; | ||||||
|         usize        Capacity; |         usize     Capacity; | ||||||
|         allocator Allocator; |         allocator Allocator; | ||||||
|     }; |     }; | ||||||
| )); | )); | ||||||
| @@ -114,8 +111,8 @@ No validation, just glorified text injection. | |||||||
| Code header = code_str( | Code header = code_str( | ||||||
|     struct ArrayHeader |     struct ArrayHeader | ||||||
|     { |     { | ||||||
|         usize        Num; |         usize     Num; | ||||||
|         usize        Capacity; |         usize     Capacity; | ||||||
|         allocator Allocator; |         allocator Allocator; | ||||||
|     }; |     }; | ||||||
| ); | ); | ||||||
| @@ -124,15 +121,15 @@ Code header = code_str( | |||||||
| `name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions.   | `name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions.   | ||||||
| `code` is a helper macro for providing a string literal with its size, but intended for code string parameters.   | `code` is a helper macro for providing a string literal with its size, but intended for code string parameters.   | ||||||
| `args` is a helper macro for providing the number of arguments to varadic constructors.   | `args` is a helper macro for providing the number of arguments to varadic constructors.   | ||||||
| `code_str` is a helper macro for writting `untyped_str( code( <content> ))` | `code_str` is a helper macro for writing `untyped_str( code( <content> ))` | ||||||
|  |  | ||||||
| All three constrcuton interfaces will generate the following C code: | All three construction interfaces will generate the following C code: | ||||||
|  |  | ||||||
| ```cpp | ```cpp | ||||||
| struct ArrayHeader | struct ArrayHeader | ||||||
| { | { | ||||||
|     usize        Num; |     usize     Num; | ||||||
|     usize        Capacity; |     usize     Capacity; | ||||||
|     allocator Allocator; |     allocator Allocator; | ||||||
| }; | }; | ||||||
| ``` | ``` | ||||||
|   | |||||||
| @@ -13,11 +13,11 @@ Standard formats: | |||||||
| * **base**: Files are in granular pieces separated into four directories: | * **base**: Files are in granular pieces separated into four directories: | ||||||
|   * **dependencies**: Originally from the c-zpl library and modified thereafter. |   * **dependencies**: Originally from the c-zpl library and modified thereafter. | ||||||
|   * **components**: The essential definitions of the library. |   * **components**: The essential definitions of the library. | ||||||
|   * **helpers**: Contains helper functionality used by base and other libraries to regenerate or generate the other library formats. |   * **helpers**: Contains helper functionality used by base and the variant library generators. | ||||||
|     * `base_codegen.hpp`: Helps with self-hosted code generation of enums, and operator overload inlines of the code types. |     * `base_codegen.hpp`: Helps with self-hosted code generation of enums, and operator overload inlines of the code types. | ||||||
|     * `<push/pop>.<name>.inline.<hpp>`: macros that are meant to be injected at specific locations of the library. |     * `<push/pop>.<name>.inline.<hpp>`: macros that are meant to be injected at specific locations of the library file/s. | ||||||
|     * `misc.hpp`: Misc functionality used by the library generation metaprograms. |     * `misc.hpp`: Misc functionality used by the library generation metaprograms. | ||||||
|     * `undef.macros.h`: Undefines all macros from library that original were intended to leak into user code. |     * `undef.macros.h`: Undefines all macros from library. | ||||||
|   * **auxillary**: Non-essential tooling: |   * **auxillary**: Non-essential tooling: | ||||||
|     * `Builder`: Similar conceptually to Jai programming language's *builder*, just opens a file and prepares a string buffer to serialize code into (`builder_print`, `builder_print_fmt`). Then write & close the file when completed (`builder_write`). |     * `Builder`: Similar conceptually to Jai programming language's *builder*, just opens a file and prepares a string buffer to serialize code into (`builder_print`, `builder_print_fmt`). Then write & close the file when completed (`builder_write`). | ||||||
|     * **`Scanner`**: Interface to load up `Code` from files two basic funcctions are currently provided. |     * **`Scanner`**: Interface to load up `Code` from files two basic funcctions are currently provided. | ||||||
| @@ -127,6 +127,14 @@ There are ***five*** header files which are automatically generated using [base_ | |||||||
|  |  | ||||||
| [`misc.hpp`](./helpers/misc.hpp): Has shared functions used by the library generation meta-programs throughout this codebase. | [`misc.hpp`](./helpers/misc.hpp): Has shared functions used by the library generation meta-programs throughout this codebase. | ||||||
|  |  | ||||||
|  | If using the library's provided build scripts: | ||||||
|  |  | ||||||
|  | ```ps1 | ||||||
|  | .\build.ps1 <compiler> <debug or omit> base | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Will refresh those files. | ||||||
|  |  | ||||||
| ## 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. | ||||||
| @@ -140,13 +148,13 @@ The convention you'll see used throughout the upfront interface of the library i | |||||||
| 1. Check name or parameters to make sure they are valid for the construction requested | 1. Check name or parameters to make sure they are valid for the construction requested | ||||||
| 2. Create a code object using `make_code`. | 2. Create a code object using `make_code`. | ||||||
| 3. Populate immediate fields (Name, Type, ModuleFlags, etc) | 3. Populate immediate fields (Name, Type, ModuleFlags, etc) | ||||||
| 4. Populate sub-entires using `add_entry`. If using the default serialization function `to_string`, follow the order at which entires are expected to appear (there is a strong ordering expected). | 4. Populate sub-entires using `add_entry`. If using the default serialization function `to_strbuilder`, follow the order at which entires are expected to appear (there is a strong ordering expected). | ||||||
|  |  | ||||||
| Names or Content fields are interned strings and thus showed be cached using `get_cached_string` if its desired to preserve that behavior. | Names or Content fields are interned strings and thus showed be cached using `get_cached_string` if its desired to preserve that behavior. | ||||||
|  |  | ||||||
| `def_operator` is the most sophisticated upfront constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid. | `def_operator` is the most sophisticated upfront constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid. | ||||||
|  |  | ||||||
| The parser is documented under [`docs/Parsing.md`](../docs/Parsing.md) and [`docs/Parser_Algo.md`](../docs/Parser_Algo.md). Extending it is more serious. | The parser is documented under [`docs/Parsing.md`](../docs/Parsing.md) and [`docs/Parser_Algo.md`](../docs/Parser_Algo.md). | ||||||
|  |  | ||||||
| ## A note on compilation and runtime generation speed | ## A note on compilation and runtime generation speed | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ Builder builder_open( char const* path ) | |||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	result.Buffer = string_make_reserve( GlobalAllocator, Builder_StrBufferReserve ); | 	result.Buffer = strbuilder_make_reserve( GlobalAllocator, Builder_StrBufferReserve ); | ||||||
|  |  | ||||||
| 	// log_fmt("$Builder - Opened file: %s\n", result.File.filename ); | 	// log_fmt("$Builder - Opened file: %s\n", result.File.filename ); | ||||||
| 	return result; | 	return result; | ||||||
| @@ -23,15 +23,15 @@ Builder builder_open( char const* path ) | |||||||
|  |  | ||||||
| void builder_pad_lines( Builder* builder, s32 num ) | void builder_pad_lines( Builder* builder, s32 num ) | ||||||
| { | { | ||||||
| 	string_append_strc( & builder->Buffer, txt("\n") ); | 	strbuilder_append_str( & builder->Buffer, txt("\n") ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void builder_print( Builder* builder, Code code ) | void builder_print( Builder* builder, Code code ) | ||||||
| { | { | ||||||
| 	String   str = code_to_string(code); | 	StrBuilder   str = code_to_strbuilder(code); | ||||||
| 	// 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 ); | ||||||
| 	string_append_string( & builder->Buffer, str ); | 	strbuilder_append_string( & builder->Buffer, str ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va ) | void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va ) | ||||||
| @@ -39,21 +39,21 @@ void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va ) | |||||||
| 	ssize   res; | 	ssize   res; | ||||||
| 	char buf[ GEN_PRINTF_MAXLEN ] = { 0 }; | 	char buf[ GEN_PRINTF_MAXLEN ] = { 0 }; | ||||||
|  |  | ||||||
| 	res = str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1; | 	res = c_str_fmt_va( buf, count_of( buf ) - 1, fmt, va ) - 1; | ||||||
|  |  | ||||||
| 	string_append_c_str_len( (String*) & (builder->Buffer), (char const*)buf, res); | 	strbuilder_append_c_str_len( (StrBuilder*) & (builder->Buffer), (char const*)buf, res); | ||||||
| } | } | ||||||
|  |  | ||||||
| void builder_write(Builder* builder) | void builder_write(Builder* builder) | ||||||
| { | { | ||||||
| 	b32 result = file_write( & builder->File, builder->Buffer, string_length(builder->Buffer) ); | 	b32 result = file_write( & builder->File, builder->Buffer, strbuilder_length(builder->Buffer) ); | ||||||
|  |  | ||||||
| 	if ( result == false ) | 	if ( result == false ) | ||||||
| 		log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & builder->File ) ); | 		log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & builder->File ) ); | ||||||
|  |  | ||||||
| 	log_fmt( "Generated: %s\n", builder->File.filename ); | 	log_fmt( "Generated: %s\n", builder->File.filename ); | ||||||
| 	file_close( & builder->File ); | 	file_close( & builder->File ); | ||||||
| 	string_free(& builder->Buffer); | 	strbuilder_free(& builder->Buffer); | ||||||
| } | } | ||||||
|  |  | ||||||
| #pragma endregion Builder | #pragma endregion Builder | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ void builder_write( Builder* builder ); | |||||||
| struct Builder | struct Builder | ||||||
| { | { | ||||||
| 	FileInfo File; | 	FileInfo File; | ||||||
| 	String   Buffer; | 	StrBuilder   Buffer; | ||||||
|  |  | ||||||
| #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP | #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP | ||||||
| 	forceinline static Builder open( char const* path ) { return builder_open(path); } | 	forceinline static Builder open( char const* path ) { return builder_open(path); } | ||||||
|   | |||||||
| @@ -32,4 +32,4 @@ CodeFn       gen_func_template( CodeTemplate template, ...  ); | |||||||
| Code         gen_class_struct_template( CodeTemplate template, ... ); | Code         gen_class_struct_template( CodeTemplate template, ... ); | ||||||
|  |  | ||||||
| Code gen_template( CodeTemplate template, ... ); | Code gen_template( CodeTemplate template, ... ); | ||||||
| Code gen_template( StrC template, StrC instantiation ); | Code gen_template( Str template, Str instantiation ); | ||||||
|   | |||||||
| @@ -20,9 +20,9 @@ Code scan_file( char const* path ) | |||||||
| 		GEN_FATAL("scan_file: %s is empty", path ); | 		GEN_FATAL("scan_file: %s is empty", path ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	String str = string_make_reserve( GlobalAllocator, fsize ); | 	StrBuilder str = strbuilder_make_reserve( GlobalAllocator, fsize ); | ||||||
| 		file_read( & file, str, fsize ); | 		file_read( & file, str, fsize ); | ||||||
| 		string_get_header(str)->Length = fsize; | 		strbuilder_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. | ||||||
| @@ -31,9 +31,9 @@ Code scan_file( char const* path ) | |||||||
| 	#define current (*scanner) | 	#define current (*scanner) | ||||||
| 	#define matched    0 | 	#define matched    0 | ||||||
| 	#define move_fwd() do { ++ scanner; -- left; } while (0) | 	#define move_fwd() do { ++ scanner; -- left; } while (0) | ||||||
| 		const StrC directive_start = txt( "ifdef" ); | 		const Str directive_start = txt( "ifdef" ); | ||||||
| 		const StrC directive_end   = txt( "endif" ); | 		const Str directive_end   = txt( "endif" ); | ||||||
| 		const StrC def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" ); | 		const Str def_intellisense = txt("GEN_INTELLISENSE_DIRECTIVES" ); | ||||||
|  |  | ||||||
| 		bool        found_directive = false; | 		bool        found_directive = false; | ||||||
| 		char const* scanner         = (char const*)str; | 		char const* scanner         = (char const*)str; | ||||||
| @@ -49,7 +49,7 @@ Code scan_file( char const* path ) | |||||||
|  |  | ||||||
| 				if ( ! found_directive ) | 				if ( ! found_directive ) | ||||||
| 				{ | 				{ | ||||||
| 					if ( left && str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched ) | 					if ( left && c_str_compare_len( scanner, directive_start.Ptr, directive_start.Len ) == matched ) | ||||||
| 					{ | 					{ | ||||||
| 						scanner += directive_start.Len; | 						scanner += directive_start.Len; | ||||||
| 						left    -= directive_start.Len; | 						left    -= directive_start.Len; | ||||||
| @@ -57,7 +57,7 @@ Code scan_file( char const* path ) | |||||||
| 						while ( left && char_is_space( current ) ) | 						while ( left && char_is_space( current ) ) | ||||||
| 							move_fwd(); | 							move_fwd(); | ||||||
|  |  | ||||||
| 						if ( left && str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched ) | 						if ( left && c_str_compare_len( scanner, def_intellisense.Ptr, def_intellisense.Len ) == matched ) | ||||||
| 						{ | 						{ | ||||||
| 							scanner += def_intellisense.Len; | 							scanner += def_intellisense.Len; | ||||||
| 							left    -= def_intellisense.Len; | 							left    -= def_intellisense.Len; | ||||||
| @@ -77,7 +77,7 @@ Code scan_file( char const* path ) | |||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				if ( left && str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched ) | 				if ( left && c_str_compare_len( scanner, directive_end.Ptr, directive_end.Len ) == matched ) | ||||||
| 				{ | 				{ | ||||||
| 					scanner += directive_end.Len; | 					scanner += directive_end.Len; | ||||||
| 					left    -= directive_end.Len; | 					left    -= directive_end.Len; | ||||||
| @@ -94,12 +94,12 @@ Code scan_file( char const* path ) | |||||||
| 					if ( (scanner + 2) >= ( (char const*) str + fsize ) ) | 					if ( (scanner + 2) >= ( (char const*) str + fsize ) ) | ||||||
| 					{ | 					{ | ||||||
| 						mem_move( str, scanner, left ); | 						mem_move( str, scanner, left ); | ||||||
| 						string_get_header(str)->Length = left; | 						strbuilder_get_header(str)->Length = left; | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					mem_move( str, scanner, left ); | 					mem_move( str, scanner, left ); | ||||||
| 					string_get_header(str)->Length = left; | 					strbuilder_get_header(str)->Length = left; | ||||||
|  |  | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| @@ -113,12 +113,12 @@ Code scan_file( char const* path ) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	file_close( & file ); | 	file_close( & file ); | ||||||
| 	return untyped_str( string_to_strc(str) ); | 	return untyped_str( strbuilder_to_str(str) ); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeBody parse_file( const char* path ) { | CodeBody parse_file( const char* path ) { | ||||||
| 	FileContents file    = file_read_contents( GlobalAllocator, true, path ); | 	FileContents file    = file_read_contents( GlobalAllocator, true, path ); | ||||||
| 	StrC         content = { file.size, (char const*)file.data }; | 	Str          content = { (char const*)file.data, file.size }; | ||||||
| 	CodeBody     code    = parse_global_body( content ); | 	CodeBody     code    = parse_global_body( content ); | ||||||
| 	log_fmt("\nParsed: %s\n", path); | 	log_fmt("\nParsed: %s\n", path); | ||||||
| 	return code; | 	return code; | ||||||
|   | |||||||
| @@ -35,12 +35,13 @@ int gen_main() | |||||||
| 		def_include(txt("components/types.hpp")), | 		def_include(txt("components/types.hpp")), | ||||||
| 		preprocess_endif, | 		preprocess_endif, | ||||||
| 		fmt_newline, | 		fmt_newline, | ||||||
| 		untyped_str( to_strc_from_c_str(generation_notice) ) | 		untyped_str( to_str_from_c_str(generation_notice) ) | ||||||
| 	)); | 	)); | ||||||
|  |  | ||||||
| 	CodeBody ecode       = gen_ecode     ( "enums/ECodeTypes.csv" ); | 	CodeBody ecode       = gen_ecode     ( "enums/ECodeTypes.csv" ); | ||||||
| 	CodeBody eoperator   = gen_eoperator ( "enums/EOperator.csv" ); | 	CodeBody eoperator   = gen_eoperator ( "enums/EOperator.csv" ); | ||||||
| 	CodeBody especifier  = gen_especifier( "enums/ESpecifier.csv" ); | 	CodeBody especifier  = gen_especifier( "enums/ESpecifier.csv" ); | ||||||
|  | 	CodeBody etoktype    = gen_etoktype  ( "enums/ETokType.csv", "enums/AttributeTokens.csv" ); | ||||||
| 	CodeBody ast_inlines = gen_ast_inlines(); | 	CodeBody ast_inlines = gen_ast_inlines(); | ||||||
|  |  | ||||||
| 	Builder header_ecode = builder_open( "components/gen/ecodetypes.hpp" ); | 	Builder header_ecode = builder_open( "components/gen/ecodetypes.hpp" ); | ||||||
| @@ -58,6 +59,11 @@ int gen_main() | |||||||
| 	builder_print( & header_especifier, format(especifier) ); | 	builder_print( & header_especifier, format(especifier) ); | ||||||
| 	builder_write( & header_especifier); | 	builder_write( & header_especifier); | ||||||
| 	 | 	 | ||||||
|  | 	Builder header_etoktype = builder_open( "components/gen/etoktype.cpp" ); | ||||||
|  | 	builder_print( & header_etoktype, gen_component_header ); | ||||||
|  | 	builder_print( & header_etoktype, format(etoktype) ); | ||||||
|  | 	builder_write( & header_etoktype); | ||||||
|  |  | ||||||
| 	Builder header_ast_inlines = builder_open( "components/gen/ast_inlines.hpp" ); | 	Builder header_ast_inlines = builder_open( "components/gen/ast_inlines.hpp" ); | ||||||
| 	builder_print( & header_ast_inlines, gen_component_header ); | 	builder_print( & header_ast_inlines, gen_component_header ); | ||||||
| 	builder_print( & header_ast_inlines, format(ast_inlines) ); | 	builder_print( & header_ast_inlines, format(ast_inlines) ); | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -242,7 +242,7 @@ GEN_NS_PARSER_END | |||||||
| // I have ideas for ways to pack that into the typedef/using ast, but for now just keeping it like this | // I have ideas for ways to pack that into the typedef/using ast, but for now just keeping it like this | ||||||
| #define ParserTokenType GEN_NS_PARSER Token | #define ParserTokenType GEN_NS_PARSER Token | ||||||
| typedef ParserTokenType Token; | typedef ParserTokenType Token; | ||||||
| #undef ParserTokenType | #undef  ParserTokenType | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if GEN_COMPILER_CPP | #if GEN_COMPILER_CPP | ||||||
| @@ -251,19 +251,19 @@ template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( | |||||||
|  |  | ||||||
| #pragma region Code C-Interface | #pragma region Code C-Interface | ||||||
|  |  | ||||||
| void   code_append       (Code code, Code other ); | void       code_append           (Code code, Code other ); | ||||||
| StrC   code_debug_str    (Code code); | Str        code_debug_str        (Code code); | ||||||
| Code   code_duplicate    (Code code); | Code       code_duplicate        (Code code); | ||||||
| Code*  code_entry        (Code code, u32 idx ); | Code*      code_entry            (Code code, u32 idx ); | ||||||
| bool   code_has_entries  (Code code); | bool       code_has_entries      (Code code); | ||||||
| bool   code_is_body      (Code code); | bool       code_is_body          (Code code); | ||||||
| bool   code_is_equal     (Code code, Code other); | bool       code_is_equal         (Code code, Code other); | ||||||
| bool   code_is_valid     (Code code); | bool       code_is_valid         (Code code); | ||||||
| void   code_set_global   (Code code); | void       code_set_global       (Code code); | ||||||
| String code_to_string    (Code self ); | StrBuilder code_to_strbuilder    (Code self ); | ||||||
| void   code_to_string_ptr(Code self, String* result ); | void       code_to_strbuilder_ptr(Code self, StrBuilder* result ); | ||||||
| StrC   code_type_str     (Code self ); | Str        code_type_str         (Code self ); | ||||||
| bool   code_validate_body(Code self ); | bool       code_validate_body    (Code self ); | ||||||
|  |  | ||||||
| #pragma endregion Code C-Interface | #pragma endregion Code C-Interface | ||||||
|  |  | ||||||
| @@ -278,7 +278,7 @@ struct Code | |||||||
| 	AST* ast; | 	AST* ast; | ||||||
|  |  | ||||||
| #	define Using_Code( Typename )                                                        \ | #	define Using_Code( Typename )                                                        \ | ||||||
| 	forceinline StrC debug_str()                { return code_debug_str(* this); }       \ | 	forceinline Str  debug_str()                { return code_debug_str(* this); }       \ | ||||||
| 	forceinline Code duplicate()                { return code_duplicate(* this); }	     \ | 	forceinline Code duplicate()                { return code_duplicate(* this); }	     \ | ||||||
| 	forceinline bool is_equal( Code other )     { return code_is_equal(* this, other); } \ | 	forceinline bool is_equal( Code other )     { return code_is_equal(* this, other); } \ | ||||||
| 	forceinline bool is_body()                  { return code_is_body(* this); }         \ | 	forceinline bool is_body()                  { return code_is_body(* this); }         \ | ||||||
| @@ -295,16 +295,17 @@ struct Code | |||||||
|  |  | ||||||
| #if ! GEN_C_LIKE_CPP | #if ! GEN_C_LIKE_CPP | ||||||
| 	Using_Code( Code ); | 	Using_Code( Code ); | ||||||
| 	forceinline void   append(Code other)        { return code_append(* this, other); } | 	forceinline void       append(Code other)                { return code_append(* this, other); } | ||||||
| 	forceinline Code*  entry(u32 idx)            { return code_entry(* this, idx); } | 	forceinline Code*      entry(u32 idx)                    { return code_entry(* this, idx); } | ||||||
| 	forceinline bool   has_entries()             { return code_has_entries(* this); } | 	forceinline bool       has_entries()                     { return code_has_entries(* this); } | ||||||
| 	forceinline String to_string()               { return code_to_string(* this); } | 	forceinline StrBuilder to_strbuilder()                   { return code_to_strbuilder(* this); } | ||||||
| 	forceinline void   to_string(String& result) { return code_to_string_ptr(* this, & result); } | 	forceinline void       to_strbuilder(StrBuilder& result) { return code_to_strbuilder_ptr(* this, & result); } | ||||||
| 	forceinline StrC   type_str()                { return code_type_str(* this); } | 	forceinline Str        type_str()                        { return code_type_str(* this); } | ||||||
| 	forceinline bool   validate_body()           { return code_validate_body(*this); } | 	forceinline bool       validate_body()                   { return code_validate_body(*this); } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 	Using_CodeOps( Code ); | 	Using_CodeOps( Code ); | ||||||
|  | 	forceinline Code operator *() { return * this; } // Required to support for-range iteration. | ||||||
| 	forceinline AST* operator ->() { return ast; } | 	forceinline AST* operator ->() { return ast; } | ||||||
|  |  | ||||||
| 	Code& operator ++(); | 	Code& operator ++(); | ||||||
|   | |||||||
| @@ -1,4 +1,6 @@ | |||||||
| #	define GEN_AST_BODY_CLASS_UNALLOWED_TYPES \ | // These macros are used in the swtich cases are used within ast.cpp, inteface.upfront.cpp, parser.cpp | ||||||
|  |  | ||||||
|  | #	define GEN_AST_BODY_CLASS_UNALLOWED_TYPES    \ | ||||||
| 	case CT_PlatformAttributes:                  \ | 	case CT_PlatformAttributes:                  \ | ||||||
| 	case CT_Class_Body:                          \ | 	case CT_Class_Body:                          \ | ||||||
| 	case CT_Enum_Body:                           \ | 	case CT_Enum_Body:                           \ | ||||||
| @@ -13,7 +15,7 @@ | |||||||
| 	case CT_Parameters:                          \ | 	case CT_Parameters:                          \ | ||||||
| 	case CT_Specifiers:                          \ | 	case CT_Specifiers:                          \ | ||||||
| 	case CT_Struct_Body:                         \ | 	case CT_Struct_Body:                         \ | ||||||
| 	case CT_Typename: | 	case CT_Typename | ||||||
| #	define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES GEN_AST_BODY_CLASS_UNALLOWED_TYPES | #	define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES GEN_AST_BODY_CLASS_UNALLOWED_TYPES | ||||||
|  |  | ||||||
| #	define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES \ | #	define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES \ | ||||||
| @@ -37,7 +39,7 @@ | |||||||
| 	case CT_Parameters:                             \ | 	case CT_Parameters:                             \ | ||||||
| 	case CT_Specifiers:                             \ | 	case CT_Specifiers:                             \ | ||||||
| 	case CT_Struct_Body:                            \ | 	case CT_Struct_Body:                            \ | ||||||
| 	case CT_Typename: | 	case CT_Typename | ||||||
|  |  | ||||||
| #	define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES     \ | #	define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES     \ | ||||||
| 	case CT_Access_Public:                         \ | 	case CT_Access_Public:                         \ | ||||||
| @@ -55,7 +57,7 @@ | |||||||
| 	case CT_Parameters:                            \ | 	case CT_Parameters:                            \ | ||||||
| 	case CT_Specifiers:                            \ | 	case CT_Specifiers:                            \ | ||||||
| 	case CT_Struct_Body:                           \ | 	case CT_Struct_Body:                           \ | ||||||
| 	case CT_Typename: | 	case CT_Typename | ||||||
| #	define GEN_AST_BODY_EXPORT_UNALLOWED_TYPES         GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | #	define GEN_AST_BODY_EXPORT_UNALLOWED_TYPES         GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||||
| #	define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | #	define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||||
|  |  | ||||||
| @@ -75,4 +77,4 @@ | |||||||
| 	case CT_Parameters:                           \ | 	case CT_Parameters:                           \ | ||||||
| 	case CT_Specifiers:                           \ | 	case CT_Specifiers:                           \ | ||||||
| 	case CT_Struct_Body:                          \ | 	case CT_Struct_Body:                          \ | ||||||
| 	case CT_Typename: | 	case CT_Typename | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -64,7 +64,7 @@ inline AST_Attributes* CodeAttributes::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -95,7 +95,7 @@ inline AST_Comment* CodeComment::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -126,7 +126,7 @@ inline AST_Constructor* CodeConstructor::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -173,7 +173,7 @@ inline AST_Define* CodeDefine::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -204,7 +204,7 @@ inline AST_Destructor* CodeDestructor::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -235,7 +235,7 @@ inline AST_Enum* CodeEnum::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -266,7 +266,7 @@ inline AST_Exec* CodeExec::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -297,7 +297,7 @@ inline AST_Extern* CodeExtern::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -328,7 +328,7 @@ inline AST_Friend* CodeFriend::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -359,7 +359,7 @@ inline AST_Fn* CodeFn::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -390,7 +390,7 @@ inline AST_Include* CodeInclude::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -421,7 +421,7 @@ inline AST_Module* CodeModule::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -452,7 +452,7 @@ inline AST_NS* CodeNS::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -483,7 +483,7 @@ inline AST_Operator* CodeOperator::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -514,7 +514,7 @@ inline AST_OpCast* CodeOpCast::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -561,7 +561,7 @@ inline AST_Pragma* CodePragma::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -592,7 +592,7 @@ inline AST_PreprocessCond* CodePreprocessCond::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -655,7 +655,7 @@ inline AST_Template* CodeTemplate::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -686,7 +686,7 @@ inline AST_Typename* CodeTypename::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -717,7 +717,7 @@ inline AST_Typedef* CodeTypedef::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -748,7 +748,7 @@ inline AST_Union* CodeUnion::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -779,7 +779,7 @@ inline AST_Using* CodeUsing::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
| @@ -810,7 +810,7 @@ inline AST_Var* CodeVar::operator->() | |||||||
| { | { | ||||||
| 	if ( ast == nullptr ) | 	if ( ast == nullptr ) | ||||||
| 	{ | 	{ | ||||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 	return ast; | 	return ast; | ||||||
|   | |||||||
| @@ -72,148 +72,148 @@ enum CodeType : u32 | |||||||
| 	CT_UnderlyingType = GEN_U32_MAX | 	CT_UnderlyingType = GEN_U32_MAX | ||||||
| }; | }; | ||||||
|  |  | ||||||
| inline StrC codetype_to_str( CodeType type ) | inline Str codetype_to_str( CodeType type ) | ||||||
| { | { | ||||||
| 	local_persist StrC lookup[61] = { | 	local_persist Str lookup[61] = { | ||||||
| 		{ sizeof( "Invalid" ),             "Invalid"             }, | 		{ "Invalid",             sizeof( "Invalid" ) - 1             }, | ||||||
| 		{ sizeof( "Untyped" ),             "Untyped"             }, | 		{ "Untyped",             sizeof( "Untyped" ) - 1             }, | ||||||
| 		{ sizeof( "NewLine" ),             "NewLine"             }, | 		{ "NewLine",             sizeof( "NewLine" ) - 1             }, | ||||||
| 		{ sizeof( "Comment" ),             "Comment"             }, | 		{ "Comment",             sizeof( "Comment" ) - 1             }, | ||||||
| 		{ sizeof( "Access_Private" ),      "Access_Private"      }, | 		{ "Access_Private",      sizeof( "Access_Private" ) - 1      }, | ||||||
| 		{ sizeof( "Access_Protected" ),    "Access_Protected"    }, | 		{ "Access_Protected",    sizeof( "Access_Protected" ) - 1    }, | ||||||
| 		{ sizeof( "Access_Public" ),       "Access_Public"       }, | 		{ "Access_Public",       sizeof( "Access_Public" ) - 1       }, | ||||||
| 		{ sizeof( "PlatformAttributes" ),  "PlatformAttributes"  }, | 		{ "PlatformAttributes",  sizeof( "PlatformAttributes" ) - 1  }, | ||||||
| 		{ sizeof( "Class" ),               "Class"               }, | 		{ "Class",               sizeof( "Class" ) - 1               }, | ||||||
| 		{ sizeof( "Class_Fwd" ),           "Class_Fwd"           }, | 		{ "Class_Fwd",           sizeof( "Class_Fwd" ) - 1           }, | ||||||
| 		{ sizeof( "Class_Body" ),          "Class_Body"          }, | 		{ "Class_Body",          sizeof( "Class_Body" ) - 1          }, | ||||||
| 		{ sizeof( "Constructor" ),         "Constructor"         }, | 		{ "Constructor",         sizeof( "Constructor" ) - 1         }, | ||||||
| 		{ sizeof( "Constructor_Fwd" ),     "Constructor_Fwd"     }, | 		{ "Constructor_Fwd",     sizeof( "Constructor_Fwd" ) - 1     }, | ||||||
| 		{ sizeof( "Destructor" ),          "Destructor"          }, | 		{ "Destructor",          sizeof( "Destructor" ) - 1          }, | ||||||
| 		{ sizeof( "Destructor_Fwd" ),      "Destructor_Fwd"      }, | 		{ "Destructor_Fwd",      sizeof( "Destructor_Fwd" ) - 1      }, | ||||||
| 		{ sizeof( "Enum" ),                "Enum"                }, | 		{ "Enum",                sizeof( "Enum" ) - 1                }, | ||||||
| 		{ sizeof( "Enum_Fwd" ),            "Enum_Fwd"            }, | 		{ "Enum_Fwd",            sizeof( "Enum_Fwd" ) - 1            }, | ||||||
| 		{ sizeof( "Enum_Body" ),           "Enum_Body"           }, | 		{ "Enum_Body",           sizeof( "Enum_Body" ) - 1           }, | ||||||
| 		{ sizeof( "Enum_Class" ),          "Enum_Class"          }, | 		{ "Enum_Class",          sizeof( "Enum_Class" ) - 1          }, | ||||||
| 		{ sizeof( "Enum_Class_Fwd" ),      "Enum_Class_Fwd"      }, | 		{ "Enum_Class_Fwd",      sizeof( "Enum_Class_Fwd" ) - 1      }, | ||||||
| 		{ sizeof( "Execution" ),           "Execution"           }, | 		{ "Execution",           sizeof( "Execution" ) - 1           }, | ||||||
| 		{ sizeof( "Export_Body" ),         "Export_Body"         }, | 		{ "Export_Body",         sizeof( "Export_Body" ) - 1         }, | ||||||
| 		{ sizeof( "Extern_Linkage" ),      "Extern_Linkage"      }, | 		{ "Extern_Linkage",      sizeof( "Extern_Linkage" ) - 1      }, | ||||||
| 		{ sizeof( "Extern_Linkage_Body" ), "Extern_Linkage_Body" }, | 		{ "Extern_Linkage_Body", sizeof( "Extern_Linkage_Body" ) - 1 }, | ||||||
| 		{ sizeof( "Friend" ),              "Friend"              }, | 		{ "Friend",              sizeof( "Friend" ) - 1              }, | ||||||
| 		{ sizeof( "Function" ),            "Function"            }, | 		{ "Function",            sizeof( "Function" ) - 1            }, | ||||||
| 		{ sizeof( "Function_Fwd" ),        "Function_Fwd"        }, | 		{ "Function_Fwd",        sizeof( "Function_Fwd" ) - 1        }, | ||||||
| 		{ sizeof( "Function_Body" ),       "Function_Body"       }, | 		{ "Function_Body",       sizeof( "Function_Body" ) - 1       }, | ||||||
| 		{ sizeof( "Global_Body" ),         "Global_Body"         }, | 		{ "Global_Body",         sizeof( "Global_Body" ) - 1         }, | ||||||
| 		{ sizeof( "Module" ),              "Module"              }, | 		{ "Module",              sizeof( "Module" ) - 1              }, | ||||||
| 		{ sizeof( "Namespace" ),           "Namespace"           }, | 		{ "Namespace",           sizeof( "Namespace" ) - 1           }, | ||||||
| 		{ sizeof( "Namespace_Body" ),      "Namespace_Body"      }, | 		{ "Namespace_Body",      sizeof( "Namespace_Body" ) - 1      }, | ||||||
| 		{ sizeof( "Operator" ),            "Operator"            }, | 		{ "Operator",            sizeof( "Operator" ) - 1            }, | ||||||
| 		{ sizeof( "Operator_Fwd" ),        "Operator_Fwd"        }, | 		{ "Operator_Fwd",        sizeof( "Operator_Fwd" ) - 1        }, | ||||||
| 		{ sizeof( "Operator_Member" ),     "Operator_Member"     }, | 		{ "Operator_Member",     sizeof( "Operator_Member" ) - 1     }, | ||||||
| 		{ sizeof( "Operator_Member_Fwd" ), "Operator_Member_Fwd" }, | 		{ "Operator_Member_Fwd", sizeof( "Operator_Member_Fwd" ) - 1 }, | ||||||
| 		{ sizeof( "Operator_Cast" ),       "Operator_Cast"       }, | 		{ "Operator_Cast",       sizeof( "Operator_Cast" ) - 1       }, | ||||||
| 		{ sizeof( "Operator_Cast_Fwd" ),   "Operator_Cast_Fwd"   }, | 		{ "Operator_Cast_Fwd",   sizeof( "Operator_Cast_Fwd" ) - 1   }, | ||||||
| 		{ sizeof( "Parameters" ),          "Parameters"          }, | 		{ "Parameters",          sizeof( "Parameters" ) - 1          }, | ||||||
| 		{ sizeof( "Preprocess_Define" ),   "Preprocess_Define"   }, | 		{ "Preprocess_Define",   sizeof( "Preprocess_Define" ) - 1   }, | ||||||
| 		{ sizeof( "Preprocess_Include" ),  "Preprocess_Include"  }, | 		{ "Preprocess_Include",  sizeof( "Preprocess_Include" ) - 1  }, | ||||||
| 		{ sizeof( "Preprocess_If" ),       "Preprocess_If"       }, | 		{ "Preprocess_If",       sizeof( "Preprocess_If" ) - 1       }, | ||||||
| 		{ sizeof( "Preprocess_IfDef" ),    "Preprocess_IfDef"    }, | 		{ "Preprocess_IfDef",    sizeof( "Preprocess_IfDef" ) - 1    }, | ||||||
| 		{ sizeof( "Preprocess_IfNotDef" ), "Preprocess_IfNotDef" }, | 		{ "Preprocess_IfNotDef", sizeof( "Preprocess_IfNotDef" ) - 1 }, | ||||||
| 		{ sizeof( "Preprocess_ElIf" ),     "Preprocess_ElIf"     }, | 		{ "Preprocess_ElIf",     sizeof( "Preprocess_ElIf" ) - 1     }, | ||||||
| 		{ sizeof( "Preprocess_Else" ),     "Preprocess_Else"     }, | 		{ "Preprocess_Else",     sizeof( "Preprocess_Else" ) - 1     }, | ||||||
| 		{ sizeof( "Preprocess_EndIf" ),    "Preprocess_EndIf"    }, | 		{ "Preprocess_EndIf",    sizeof( "Preprocess_EndIf" ) - 1    }, | ||||||
| 		{ sizeof( "Preprocess_Pragma" ),   "Preprocess_Pragma"   }, | 		{ "Preprocess_Pragma",   sizeof( "Preprocess_Pragma" ) - 1   }, | ||||||
| 		{ sizeof( "Specifiers" ),          "Specifiers"          }, | 		{ "Specifiers",          sizeof( "Specifiers" ) - 1          }, | ||||||
| 		{ sizeof( "Struct" ),              "Struct"              }, | 		{ "Struct",              sizeof( "Struct" ) - 1              }, | ||||||
| 		{ sizeof( "Struct_Fwd" ),          "Struct_Fwd"          }, | 		{ "Struct_Fwd",          sizeof( "Struct_Fwd" ) - 1          }, | ||||||
| 		{ sizeof( "Struct_Body" ),         "Struct_Body"         }, | 		{ "Struct_Body",         sizeof( "Struct_Body" ) - 1         }, | ||||||
| 		{ sizeof( "Template" ),            "Template"            }, | 		{ "Template",            sizeof( "Template" ) - 1            }, | ||||||
| 		{ sizeof( "Typedef" ),             "Typedef"             }, | 		{ "Typedef",             sizeof( "Typedef" ) - 1             }, | ||||||
| 		{ sizeof( "Typename" ),            "Typename"            }, | 		{ "Typename",            sizeof( "Typename" ) - 1            }, | ||||||
| 		{ sizeof( "Union" ),               "Union"               }, | 		{ "Union",               sizeof( "Union" ) - 1               }, | ||||||
| 		{ sizeof( "Union_Fwd" ),           "Union_Fwd"           }, | 		{ "Union_Fwd",           sizeof( "Union_Fwd" ) - 1           }, | ||||||
| 		{ sizeof( "Union_Body" ),          "Union_Body"          }, | 		{ "Union_Body",          sizeof( "Union_Body" ) - 1          }, | ||||||
| 		{ sizeof( "Using" ),               "Using"               }, | 		{ "Using",               sizeof( "Using" ) - 1               }, | ||||||
| 		{ sizeof( "Using_Namespace" ),     "Using_Namespace"     }, | 		{ "Using_Namespace",     sizeof( "Using_Namespace" ) - 1     }, | ||||||
| 		{ sizeof( "Variable" ),            "Variable"            }, | 		{ "Variable",            sizeof( "Variable" ) - 1            }, | ||||||
| 	}; | 	}; | ||||||
| 	return lookup[type]; | 	return lookup[type]; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline StrC codetype_to_keyword_str( CodeType type ) | inline Str codetype_to_keyword_str( CodeType type ) | ||||||
| { | { | ||||||
| 	local_persist StrC lookup[61] = { | 	local_persist Str lookup[61] = { | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "//" ) - 1,              "//"              }, | 		{ "//",              sizeof( "//" ) - 1              }, | ||||||
| 		{ sizeof( "private" ) - 1,         "private"         }, | 		{ "private",         sizeof( "private" ) - 1         }, | ||||||
| 		{ sizeof( "protected" ) - 1,       "protected"       }, | 		{ "protected",       sizeof( "protected" ) - 1       }, | ||||||
| 		{ sizeof( "public" ) - 1,          "public"          }, | 		{ "public",          sizeof( "public" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "class" ) - 1,           "class"           }, | 		{ "class",           sizeof( "class" ) - 1           }, | ||||||
| 		{ sizeof( "clsss" ) - 1,           "clsss"           }, | 		{ "clsss",           sizeof( "clsss" ) - 1           }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "enum" ) - 1,            "enum"            }, | 		{ "enum",            sizeof( "enum" ) - 1            }, | ||||||
| 		{ sizeof( "enum" ) - 1,            "enum"            }, | 		{ "enum",            sizeof( "enum" ) - 1            }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "enum class" ) - 1,      "enum class"      }, | 		{ "enum class",      sizeof( "enum class" ) - 1      }, | ||||||
| 		{ sizeof( "enum class" ) - 1,      "enum class"      }, | 		{ "enum class",      sizeof( "enum class" ) - 1      }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "extern" ) - 1,          "extern"          }, | 		{ "extern",          sizeof( "extern" ) - 1          }, | ||||||
| 		{ sizeof( "extern" ) - 1,          "extern"          }, | 		{ "extern",          sizeof( "extern" ) - 1          }, | ||||||
| 		{ sizeof( "friend" ) - 1,          "friend"          }, | 		{ "friend",          sizeof( "friend" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "module" ) - 1,          "module"          }, | 		{ "module",          sizeof( "module" ) - 1          }, | ||||||
| 		{ sizeof( "namespace" ) - 1,       "namespace"       }, | 		{ "namespace",       sizeof( "namespace" ) - 1       }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "define" ) - 1,          "define"          }, | 		{ "define",          sizeof( "define" ) - 1          }, | ||||||
| 		{ sizeof( "include" ) - 1,         "include"         }, | 		{ "include",         sizeof( "include" ) - 1         }, | ||||||
| 		{ sizeof( "if" ) - 1,              "if"              }, | 		{ "if",              sizeof( "if" ) - 1              }, | ||||||
| 		{ sizeof( "ifdef" ) - 1,           "ifdef"           }, | 		{ "ifdef",           sizeof( "ifdef" ) - 1           }, | ||||||
| 		{ sizeof( "ifndef" ) - 1,          "ifndef"          }, | 		{ "ifndef",          sizeof( "ifndef" ) - 1          }, | ||||||
| 		{ sizeof( "elif" ) - 1,            "elif"            }, | 		{ "elif",            sizeof( "elif" ) - 1            }, | ||||||
| 		{ sizeof( "else" ) - 1,            "else"            }, | 		{ "else",            sizeof( "else" ) - 1            }, | ||||||
| 		{ sizeof( "endif" ) - 1,           "endif"           }, | 		{ "endif",           sizeof( "endif" ) - 1           }, | ||||||
| 		{ sizeof( "pragma" ) - 1,          "pragma"          }, | 		{ "pragma",          sizeof( "pragma" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "struct" ) - 1,          "struct"          }, | 		{ "struct",          sizeof( "struct" ) - 1          }, | ||||||
| 		{ sizeof( "struct" ) - 1,          "struct"          }, | 		{ "struct",          sizeof( "struct" ) - 1          }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "template" ) - 1,        "template"        }, | 		{ "template",        sizeof( "template" ) - 1        }, | ||||||
| 		{ sizeof( "typedef" ) - 1,         "typedef"         }, | 		{ "typedef",         sizeof( "typedef" ) - 1         }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "union" ) - 1,           "union"           }, | 		{ "union",           sizeof( "union" ) - 1           }, | ||||||
| 		{ sizeof( "union" ) - 1,           "union"           }, | 		{ "union",           sizeof( "union" ) - 1           }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 		{ sizeof( "using" ) - 1,           "using"           }, | 		{ "using",           sizeof( "using" ) - 1           }, | ||||||
| 		{ sizeof( "using namespace" ) - 1, "using namespace" }, | 		{ "using namespace", sizeof( "using namespace" ) - 1 }, | ||||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||||
| 	}; | 	}; | ||||||
| 	return lookup[type]; | 	return lookup[type]; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline StrC to_str( CodeType type ) | forceinline Str to_str( CodeType type ) | ||||||
| { | { | ||||||
| 	return codetype_to_str( type ); | 	return codetype_to_str( type ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline StrC to_keyword_str( CodeType type ) | forceinline Str to_keyword_str( CodeType type ) | ||||||
| { | { | ||||||
| 	return codetype_to_keyword_str( type ); | 	return codetype_to_keyword_str( type ); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -58,61 +58,61 @@ enum Operator : u32 | |||||||
| 	Op_UnderlyingType = 0xffffffffu | 	Op_UnderlyingType = 0xffffffffu | ||||||
| }; | }; | ||||||
|  |  | ||||||
| inline StrC operator_to_str( Operator op ) | inline Str operator_to_str( Operator op ) | ||||||
| { | { | ||||||
| 	local_persist StrC lookup[47] = { | 	local_persist Str lookup[47] = { | ||||||
| 		{ sizeof( "INVALID" ),  "INVALID"  }, | 		{ "INVALID",  sizeof( "INVALID" ) - 1  }, | ||||||
| 		{ sizeof( "=" ),        "="        }, | 		{ "=",        sizeof( "=" ) - 1        }, | ||||||
| 		{ sizeof( "+=" ),       "+="       }, | 		{ "+=",       sizeof( "+=" ) - 1       }, | ||||||
| 		{ sizeof( "-=" ),       "-="       }, | 		{ "-=",       sizeof( "-=" ) - 1       }, | ||||||
| 		{ sizeof( "*=" ),       "*="       }, | 		{ "*=",       sizeof( "*=" ) - 1       }, | ||||||
| 		{ sizeof( "/=" ),       "/="       }, | 		{ "/=",       sizeof( "/=" ) - 1       }, | ||||||
| 		{ sizeof( "%=" ),       "%="       }, | 		{ "%=",       sizeof( "%=" ) - 1       }, | ||||||
| 		{ sizeof( "&=" ),       "&="       }, | 		{ "&=",       sizeof( "&=" ) - 1       }, | ||||||
| 		{ sizeof( "|=" ),       "|="       }, | 		{ "|=",       sizeof( "|=" ) - 1       }, | ||||||
| 		{ sizeof( "^=" ),       "^="       }, | 		{ "^=",       sizeof( "^=" ) - 1       }, | ||||||
| 		{ sizeof( "<<=" ),      "<<="      }, | 		{ "<<=",      sizeof( "<<=" ) - 1      }, | ||||||
| 		{ sizeof( ">>=" ),      ">>="      }, | 		{ ">>=",      sizeof( ">>=" ) - 1      }, | ||||||
| 		{ sizeof( "++" ),       "++"       }, | 		{ "++",       sizeof( "++" ) - 1       }, | ||||||
| 		{ sizeof( "--" ),       "--"       }, | 		{ "--",       sizeof( "--" ) - 1       }, | ||||||
| 		{ sizeof( "+" ),        "+"        }, | 		{ "+",        sizeof( "+" ) - 1        }, | ||||||
| 		{ sizeof( "-" ),        "-"        }, | 		{ "-",        sizeof( "-" ) - 1        }, | ||||||
| 		{ sizeof( "!" ),        "!"        }, | 		{ "!",        sizeof( "!" ) - 1        }, | ||||||
| 		{ sizeof( "+" ),        "+"        }, | 		{ "+",        sizeof( "+" ) - 1        }, | ||||||
| 		{ sizeof( "-" ),        "-"        }, | 		{ "-",        sizeof( "-" ) - 1        }, | ||||||
| 		{ sizeof( "*" ),        "*"        }, | 		{ "*",        sizeof( "*" ) - 1        }, | ||||||
| 		{ sizeof( "/" ),        "/"        }, | 		{ "/",        sizeof( "/" ) - 1        }, | ||||||
| 		{ sizeof( "%" ),        "%"        }, | 		{ "%",        sizeof( "%" ) - 1        }, | ||||||
| 		{ sizeof( "~" ),        "~"        }, | 		{ "~",        sizeof( "~" ) - 1        }, | ||||||
| 		{ sizeof( "&" ),        "&"        }, | 		{ "&",        sizeof( "&" ) - 1        }, | ||||||
| 		{ sizeof( "|" ),        "|"        }, | 		{ "|",        sizeof( "|" ) - 1        }, | ||||||
| 		{ sizeof( "^" ),        "^"        }, | 		{ "^",        sizeof( "^" ) - 1        }, | ||||||
| 		{ sizeof( "<<" ),       "<<"       }, | 		{ "<<",       sizeof( "<<" ) - 1       }, | ||||||
| 		{ sizeof( ">>" ),       ">>"       }, | 		{ ">>",       sizeof( ">>" ) - 1       }, | ||||||
| 		{ sizeof( "&&" ),       "&&"       }, | 		{ "&&",       sizeof( "&&" ) - 1       }, | ||||||
| 		{ sizeof( "||" ),       "||"       }, | 		{ "||",       sizeof( "||" ) - 1       }, | ||||||
| 		{ sizeof( "==" ),       "=="       }, | 		{ "==",       sizeof( "==" ) - 1       }, | ||||||
| 		{ sizeof( "!=" ),       "!="       }, | 		{ "!=",       sizeof( "!=" ) - 1       }, | ||||||
| 		{ sizeof( "<" ),        "<"        }, | 		{ "<",        sizeof( "<" ) - 1        }, | ||||||
| 		{ sizeof( ">" ),        ">"        }, | 		{ ">",        sizeof( ">" ) - 1        }, | ||||||
| 		{ sizeof( "<=" ),       "<="       }, | 		{ "<=",       sizeof( "<=" ) - 1       }, | ||||||
| 		{ sizeof( ">=" ),       ">="       }, | 		{ ">=",       sizeof( ">=" ) - 1       }, | ||||||
| 		{ sizeof( "[]" ),       "[]"       }, | 		{ "[]",       sizeof( "[]" ) - 1       }, | ||||||
| 		{ sizeof( "*" ),        "*"        }, | 		{ "*",        sizeof( "*" ) - 1        }, | ||||||
| 		{ sizeof( "&" ),        "&"        }, | 		{ "&",        sizeof( "&" ) - 1        }, | ||||||
| 		{ sizeof( "->" ),       "->"       }, | 		{ "->",       sizeof( "->" ) - 1       }, | ||||||
| 		{ sizeof( "->*" ),      "->*"      }, | 		{ "->*",      sizeof( "->*" ) - 1      }, | ||||||
| 		{ sizeof( "()" ),       "()"       }, | 		{ "()",       sizeof( "()" ) - 1       }, | ||||||
| 		{ sizeof( "," ),        ","        }, | 		{ ",",        sizeof( "," ) - 1        }, | ||||||
| 		{ sizeof( "new" ),      "new"      }, | 		{ "new",      sizeof( "new" ) - 1      }, | ||||||
| 		{ sizeof( "new[]" ),    "new[]"    }, | 		{ "new[]",    sizeof( "new[]" ) - 1    }, | ||||||
| 		{ sizeof( "delete" ),   "delete"   }, | 		{ "delete",   sizeof( "delete" ) - 1   }, | ||||||
| 		{ sizeof( "delete[]" ), "delete[]" }, | 		{ "delete[]", sizeof( "delete[]" ) - 1 }, | ||||||
| 	}; | 	}; | ||||||
| 	return lookup[op]; | 	return lookup[op]; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline StrC to_str( Operator op ) | forceinline Str to_str( Operator op ) | ||||||
| { | { | ||||||
| 	return operator_to_str( op ); | 	return operator_to_str( op ); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -37,35 +37,35 @@ enum Specifier : u32 | |||||||
| 	Spec_UnderlyingType = 0xffffffffu | 	Spec_UnderlyingType = 0xffffffffu | ||||||
| }; | }; | ||||||
|  |  | ||||||
| inline StrC spec_to_str( Specifier type ) | inline Str spec_to_str( Specifier type ) | ||||||
| { | { | ||||||
| 	local_persist StrC lookup[26] = { | 	local_persist Str lookup[26] = { | ||||||
| 		{ sizeof( "INVALID" ),       "INVALID"       }, | 		{ "INVALID",       sizeof( "INVALID" ) - 1       }, | ||||||
| 		{ sizeof( "consteval" ),     "consteval"     }, | 		{ "consteval",     sizeof( "consteval" ) - 1     }, | ||||||
| 		{ sizeof( "constexpr" ),     "constexpr"     }, | 		{ "constexpr",     sizeof( "constexpr" ) - 1     }, | ||||||
| 		{ sizeof( "constinit" ),     "constinit"     }, | 		{ "constinit",     sizeof( "constinit" ) - 1     }, | ||||||
| 		{ sizeof( "explicit" ),      "explicit"      }, | 		{ "explicit",      sizeof( "explicit" ) - 1      }, | ||||||
| 		{ sizeof( "extern" ),        "extern"        }, | 		{ "extern",        sizeof( "extern" ) - 1        }, | ||||||
| 		{ sizeof( "forceinline" ),   "forceinline"   }, | 		{ "forceinline",   sizeof( "forceinline" ) - 1   }, | ||||||
| 		{ sizeof( "global" ),        "global"        }, | 		{ "global",        sizeof( "global" ) - 1        }, | ||||||
| 		{ sizeof( "inline" ),        "inline"        }, | 		{ "inline",        sizeof( "inline" ) - 1        }, | ||||||
| 		{ sizeof( "internal" ),      "internal"      }, | 		{ "internal",      sizeof( "internal" ) - 1      }, | ||||||
| 		{ sizeof( "local_persist" ), "local_persist" }, | 		{ "local_persist", sizeof( "local_persist" ) - 1 }, | ||||||
| 		{ sizeof( "mutable" ),       "mutable"       }, | 		{ "mutable",       sizeof( "mutable" ) - 1       }, | ||||||
| 		{ sizeof( "neverinline" ),   "neverinline"   }, | 		{ "neverinline",   sizeof( "neverinline" ) - 1   }, | ||||||
| 		{ sizeof( "*" ),             "*"             }, | 		{ "*",             sizeof( "*" ) - 1             }, | ||||||
| 		{ sizeof( "&" ),             "&"             }, | 		{ "&",             sizeof( "&" ) - 1             }, | ||||||
| 		{ sizeof( "register" ),      "register"      }, | 		{ "register",      sizeof( "register" ) - 1      }, | ||||||
| 		{ sizeof( "&&" ),            "&&"            }, | 		{ "&&",            sizeof( "&&" ) - 1            }, | ||||||
| 		{ sizeof( "static" ),        "static"        }, | 		{ "static",        sizeof( "static" ) - 1        }, | ||||||
| 		{ sizeof( "thread_local" ),  "thread_local"  }, | 		{ "thread_local",  sizeof( "thread_local" ) - 1  }, | ||||||
| 		{ sizeof( "virtual" ),       "virtual"       }, | 		{ "virtual",       sizeof( "virtual" ) - 1       }, | ||||||
| 		{ sizeof( "const" ),         "const"         }, | 		{ "const",         sizeof( "const" ) - 1         }, | ||||||
| 		{ sizeof( "final" ),         "final"         }, | 		{ "final",         sizeof( "final" ) - 1         }, | ||||||
| 		{ sizeof( "noexcept" ),      "noexcept"      }, | 		{ "noexcept",      sizeof( "noexcept" ) - 1      }, | ||||||
| 		{ sizeof( "override" ),      "override"      }, | 		{ "override",      sizeof( "override" ) - 1      }, | ||||||
| 		{ sizeof( "= 0" ),           "= 0"           }, | 		{ "= 0",           sizeof( "= 0" ) - 1           }, | ||||||
| 		{ sizeof( "volatile" ),      "volatile"      }, | 		{ "volatile",      sizeof( "volatile" ) - 1      }, | ||||||
| 	}; | 	}; | ||||||
| 	return lookup[type]; | 	return lookup[type]; | ||||||
| } | } | ||||||
| @@ -75,13 +75,13 @@ inline bool spec_is_trailing( Specifier specifier ) | |||||||
| 	return specifier > Spec_Virtual; | 	return specifier > Spec_Virtual; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline Specifier strc_to_specifier( StrC str ) | inline Specifier str_to_specifier( Str str ) | ||||||
| { | { | ||||||
| 	local_persist u32 keymap[Spec_NumSpecifiers]; | 	local_persist u32 keymap[Spec_NumSpecifiers]; | ||||||
| 	do_once_start for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) | 	do_once_start for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) | ||||||
| 	{ | 	{ | ||||||
| 		StrC enum_str = spec_to_str( (Specifier)index ); | 		Str enum_str  = spec_to_str( (Specifier)index ); | ||||||
| 		keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 ); | 		keymap[index] = crc32( enum_str.Ptr, enum_str.Len ); | ||||||
| 	} | 	} | ||||||
| 	do_once_end u32 hash = crc32( str.Ptr, str.Len ); | 	do_once_end u32 hash = crc32( str.Ptr, str.Len ); | ||||||
| 	for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) | 	for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) | ||||||
| @@ -92,14 +92,14 @@ inline Specifier strc_to_specifier( StrC str ) | |||||||
| 	return Spec_Invalid; | 	return Spec_Invalid; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline StrC to_str( Specifier spec ) | forceinline Str to_str( Specifier spec ) | ||||||
| { | { | ||||||
| 	return spec_to_str( spec ); | 	return spec_to_str( spec ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline Specifier to_type( StrC str ) | forceinline Specifier to_type( Str str ) | ||||||
| { | { | ||||||
| 	return strc_to_specifier( str ); | 	return str_to_specifier( str ); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline bool is_trailing( Specifier specifier ) | forceinline bool is_trailing( Specifier specifier ) | ||||||
|   | |||||||
| @@ -111,117 +111,117 @@ enum TokType : u32 | |||||||
| 	Tok_NumTokens | 	Tok_NumTokens | ||||||
| }; | }; | ||||||
|  |  | ||||||
| inline StrC toktype_to_str( TokType type ) | inline Str toktype_to_str( TokType type ) | ||||||
| { | { | ||||||
| 	local_persist StrC lookup[] = { | 	local_persist Str lookup[] = { | ||||||
| 		{ sizeof( "__invalid__" ),         "__invalid__"         }, | 		{ "__invalid__",         sizeof( "__invalid__" ) - 1         }, | ||||||
| 		{ sizeof( "private" ),             "private"             }, | 		{ "private",             sizeof( "private" ) - 1             }, | ||||||
| 		{ sizeof( "protected" ),           "protected"           }, | 		{ "protected",           sizeof( "protected" ) - 1           }, | ||||||
| 		{ sizeof( "public" ),              "public"              }, | 		{ "public",              sizeof( "public" ) - 1              }, | ||||||
| 		{ sizeof( "." ),                   "."                   }, | 		{ ".",		           sizeof( "." ) - 1                   }, | ||||||
| 		{ sizeof( "::" ),                  "::"                  }, | 		{ "::",		          sizeof( "::" ) - 1                  }, | ||||||
| 		{ sizeof( "&" ),                   "&"                   }, | 		{ "&",		           sizeof( "&" ) - 1                   }, | ||||||
| 		{ sizeof( "&&" ),                  "&&"                  }, | 		{ "&&",		          sizeof( "&&" ) - 1                  }, | ||||||
| 		{ sizeof( ":" ),                   ":"                   }, | 		{ ":",		           sizeof( ":" ) - 1                   }, | ||||||
| 		{ sizeof( "[[" ),                  "[["                  }, | 		{ "[[",		          sizeof( "[[" ) - 1                  }, | ||||||
| 		{ sizeof( "]]" ),                  "]]"                  }, | 		{ "]]",		          sizeof( "]]" ) - 1                  }, | ||||||
| 		{ sizeof( "{" ),                   "{"                   }, | 		{ "{",		           sizeof( "{" ) - 1                   }, | ||||||
| 		{ sizeof( "}" ),                   "}"                   }, | 		{ "}",		           sizeof( "}" ) - 1                   }, | ||||||
| 		{ sizeof( "[" ),                   "["                   }, | 		{ "[",		           sizeof( "[" ) - 1                   }, | ||||||
| 		{ sizeof( "]" ),                   "]"                   }, | 		{ "]",		           sizeof( "]" ) - 1                   }, | ||||||
| 		{ sizeof( "(" ),                   "("                   }, | 		{ "(",		           sizeof( "(" ) - 1                   }, | ||||||
| 		{ sizeof( ")" ),                   ")"                   }, | 		{ ")",		           sizeof( ")" ) - 1                   }, | ||||||
| 		{ sizeof( "__comment__" ),         "__comment__"         }, | 		{ "__comment__",         sizeof( "__comment__" ) - 1         }, | ||||||
| 		{ sizeof( "__comment_end__" ),     "__comment_end__"     }, | 		{ "__comment_end__",     sizeof( "__comment_end__" ) - 1     }, | ||||||
| 		{ sizeof( "__comment_start__" ),   "__comment_start__"   }, | 		{ "__comment_start__",   sizeof( "__comment_start__" ) - 1   }, | ||||||
| 		{ sizeof( "__character__" ),       "__character__"       }, | 		{ "__character__",       sizeof( "__character__" ) - 1       }, | ||||||
| 		{ sizeof( "," ),                   ","                   }, | 		{ ",",		           sizeof( "," ) - 1                   }, | ||||||
| 		{ sizeof( "class" ),               "class"               }, | 		{ "class",               sizeof( "class" ) - 1               }, | ||||||
| 		{ sizeof( "__attribute__" ),       "__attribute__"       }, | 		{ "__attribute__",       sizeof( "__attribute__" ) - 1       }, | ||||||
| 		{ sizeof( "__declspec" ),          "__declspec"          }, | 		{ "__declspec",          sizeof( "__declspec" ) - 1          }, | ||||||
| 		{ sizeof( "enum" ),                "enum"                }, | 		{ "enum",                sizeof( "enum" ) - 1                }, | ||||||
| 		{ sizeof( "extern" ),              "extern"              }, | 		{ "extern",              sizeof( "extern" ) - 1              }, | ||||||
| 		{ sizeof( "friend" ),              "friend"              }, | 		{ "friend",              sizeof( "friend" ) - 1              }, | ||||||
| 		{ sizeof( "module" ),              "module"              }, | 		{ "module",              sizeof( "module" ) - 1              }, | ||||||
| 		{ sizeof( "namespace" ),           "namespace"           }, | 		{ "namespace",           sizeof( "namespace" ) - 1           }, | ||||||
| 		{ sizeof( "operator" ),            "operator"            }, | 		{ "operator",            sizeof( "operator" ) - 1            }, | ||||||
| 		{ sizeof( "struct" ),              "struct"              }, | 		{ "struct",              sizeof( "struct" ) - 1              }, | ||||||
| 		{ sizeof( "template" ),            "template"            }, | 		{ "template",            sizeof( "template" ) - 1            }, | ||||||
| 		{ sizeof( "typedef" ),             "typedef"             }, | 		{ "typedef",             sizeof( "typedef" ) - 1             }, | ||||||
| 		{ sizeof( "using" ),               "using"               }, | 		{ "using",               sizeof( "using" ) - 1               }, | ||||||
| 		{ sizeof( "union" ),               "union"               }, | 		{ "union",               sizeof( "union" ) - 1               }, | ||||||
| 		{ sizeof( "__identifier__" ),      "__identifier__"      }, | 		{ "__identifier__",      sizeof( "__identifier__" ) - 1      }, | ||||||
| 		{ sizeof( "import" ),              "import"              }, | 		{ "import",              sizeof( "import" ) - 1              }, | ||||||
| 		{ sizeof( "export" ),              "export"              }, | 		{ "export",              sizeof( "export" ) - 1              }, | ||||||
| 		{ sizeof( "__new_line__" ),        "__new_line__"        }, | 		{ "__new_line__",        sizeof( "__new_line__" ) - 1        }, | ||||||
| 		{ sizeof( "__number__" ),          "__number__"          }, | 		{ "__number__",          sizeof( "__number__" ) - 1          }, | ||||||
| 		{ sizeof( "__operator__" ),        "__operator__"        }, | 		{ "__operator__",        sizeof( "__operator__" ) - 1        }, | ||||||
| 		{ sizeof( "#" ),                   "#"                   }, | 		{ "#",		           sizeof( "#" ) - 1                   }, | ||||||
| 		{ sizeof( "define" ),              "define"              }, | 		{ "define",              sizeof( "define" ) - 1              }, | ||||||
| 		{ sizeof( "if" ),                  "if"                  }, | 		{ "if",		          sizeof( "if" ) - 1                  }, | ||||||
| 		{ sizeof( "ifdef" ),               "ifdef"               }, | 		{ "ifdef",               sizeof( "ifdef" ) - 1               }, | ||||||
| 		{ sizeof( "ifndef" ),              "ifndef"              }, | 		{ "ifndef",              sizeof( "ifndef" ) - 1              }, | ||||||
| 		{ sizeof( "elif" ),                "elif"                }, | 		{ "elif",                sizeof( "elif" ) - 1                }, | ||||||
| 		{ sizeof( "else" ),                "else"                }, | 		{ "else",                sizeof( "else" ) - 1                }, | ||||||
| 		{ sizeof( "endif" ),               "endif"               }, | 		{ "endif",               sizeof( "endif" ) - 1               }, | ||||||
| 		{ sizeof( "include" ),             "include"             }, | 		{ "include",             sizeof( "include" ) - 1             }, | ||||||
| 		{ sizeof( "pragma" ),              "pragma"              }, | 		{ "pragma",              sizeof( "pragma" ) - 1              }, | ||||||
| 		{ sizeof( "__macro_content__" ),   "__macro_content__"   }, | 		{ "__macro_content__",   sizeof( "__macro_content__" ) - 1   }, | ||||||
| 		{ sizeof( "__macro__" ),           "__macro__"           }, | 		{ "__macro__",           sizeof( "__macro__" ) - 1           }, | ||||||
| 		{ sizeof( "__unsupported__" ),     "__unsupported__"     }, | 		{ "__unsupported__",     sizeof( "__unsupported__" ) - 1     }, | ||||||
| 		{ sizeof( "alignas" ),             "alignas"             }, | 		{ "alignas",             sizeof( "alignas" ) - 1             }, | ||||||
| 		{ sizeof( "const" ),               "const"               }, | 		{ "const",               sizeof( "const" ) - 1               }, | ||||||
| 		{ sizeof( "consteval" ),           "consteval"           }, | 		{ "consteval",           sizeof( "consteval" ) - 1           }, | ||||||
| 		{ sizeof( "constexpr" ),           "constexpr"           }, | 		{ "constexpr",           sizeof( "constexpr" ) - 1           }, | ||||||
| 		{ sizeof( "constinit" ),           "constinit"           }, | 		{ "constinit",           sizeof( "constinit" ) - 1           }, | ||||||
| 		{ sizeof( "explicit" ),            "explicit"            }, | 		{ "explicit",            sizeof( "explicit" ) - 1            }, | ||||||
| 		{ sizeof( "extern" ),              "extern"              }, | 		{ "extern",              sizeof( "extern" ) - 1              }, | ||||||
| 		{ sizeof( "final" ),               "final"               }, | 		{ "final",               sizeof( "final" ) - 1               }, | ||||||
| 		{ sizeof( "forceinline" ),         "forceinline"         }, | 		{ "forceinline",         sizeof( "forceinline" ) - 1         }, | ||||||
| 		{ sizeof( "global" ),              "global"              }, | 		{ "global",              sizeof( "global" ) - 1              }, | ||||||
| 		{ sizeof( "inline" ),              "inline"              }, | 		{ "inline",              sizeof( "inline" ) - 1              }, | ||||||
| 		{ sizeof( "internal" ),            "internal"            }, | 		{ "internal",            sizeof( "internal" ) - 1            }, | ||||||
| 		{ sizeof( "local_persist" ),       "local_persist"       }, | 		{ "local_persist",       sizeof( "local_persist" ) - 1       }, | ||||||
| 		{ sizeof( "mutable" ),             "mutable"             }, | 		{ "mutable",             sizeof( "mutable" ) - 1             }, | ||||||
| 		{ sizeof( "neverinline" ),         "neverinline"         }, | 		{ "neverinline",         sizeof( "neverinline" ) - 1         }, | ||||||
| 		{ sizeof( "override" ),            "override"            }, | 		{ "override",            sizeof( "override" ) - 1            }, | ||||||
| 		{ sizeof( "static" ),              "static"              }, | 		{ "static",              sizeof( "static" ) - 1              }, | ||||||
| 		{ sizeof( "thread_local" ),        "thread_local"        }, | 		{ "thread_local",        sizeof( "thread_local" ) - 1        }, | ||||||
| 		{ sizeof( "volatile" ),            "volatile"            }, | 		{ "volatile",            sizeof( "volatile" ) - 1            }, | ||||||
| 		{ sizeof( "virtual" ),             "virtual"             }, | 		{ "virtual",             sizeof( "virtual" ) - 1             }, | ||||||
| 		{ sizeof( "*" ),                   "*"                   }, | 		{ "*",		           sizeof( "*" ) - 1                   }, | ||||||
| 		{ sizeof( ";" ),                   ";"                   }, | 		{ ";",		           sizeof( ";" ) - 1                   }, | ||||||
| 		{ sizeof( "static_assert" ),       "static_assert"       }, | 		{ "static_assert",       sizeof( "static_assert" ) - 1       }, | ||||||
| 		{ sizeof( "__string__" ),          "__string__"          }, | 		{ "__string__",          sizeof( "__string__" ) - 1          }, | ||||||
| 		{ sizeof( "typename" ),            "typename"            }, | 		{ "typename",            sizeof( "typename" ) - 1            }, | ||||||
| 		{ sizeof( "unsigned" ),            "unsigned"            }, | 		{ "unsigned",            sizeof( "unsigned" ) - 1            }, | ||||||
| 		{ sizeof( "signed" ),              "signed"              }, | 		{ "signed",              sizeof( "signed" ) - 1              }, | ||||||
| 		{ sizeof( "short" ),               "short"               }, | 		{ "short",               sizeof( "short" ) - 1               }, | ||||||
| 		{ sizeof( "long" ),                "long"                }, | 		{ "long",                sizeof( "long" ) - 1                }, | ||||||
| 		{ sizeof( "bool" ),                "bool"                }, | 		{ "bool",                sizeof( "bool" ) - 1                }, | ||||||
| 		{ sizeof( "char" ),                "char"                }, | 		{ "char",                sizeof( "char" ) - 1                }, | ||||||
| 		{ sizeof( "int" ),                 "int"                 }, | 		{ "int",		         sizeof( "int" ) - 1                 }, | ||||||
| 		{ sizeof( "double" ),              "double"              }, | 		{ "double",              sizeof( "double" ) - 1              }, | ||||||
| 		{ sizeof( "__int8" ),              "__int8"              }, | 		{ "__int8",              sizeof( "__int8" ) - 1              }, | ||||||
| 		{ sizeof( "__int16" ),             "__int16"             }, | 		{ "__int16",             sizeof( "__int16" ) - 1             }, | ||||||
| 		{ sizeof( "__int32" ),             "__int32"             }, | 		{ "__int32",             sizeof( "__int32" ) - 1             }, | ||||||
| 		{ sizeof( "__int64" ),             "__int64"             }, | 		{ "__int64",             sizeof( "__int64" ) - 1             }, | ||||||
| 		{ sizeof( "_W64" ),                "_W64"                }, | 		{ "_W64",                sizeof( "_W64" ) - 1                }, | ||||||
| 		{ sizeof( "..." ),                 "..."                 }, | 		{ "...",		         sizeof( "..." ) - 1                 }, | ||||||
| 		{ sizeof( "__attrib_start__" ),    "__attrib_start__"    }, | 		{ "__attrib_start__",    sizeof( "__attrib_start__" ) - 1    }, | ||||||
| 		{ sizeof( "GEN_API_Export_Code" ), "GEN_API_Export_Code" }, | 		{ "GEN_API_Export_Code", sizeof( "GEN_API_Export_Code" ) - 1 }, | ||||||
| 		{ sizeof( "GEN_API_Import_Code" ), "GEN_API_Import_Code" }, | 		{ "GEN_API_Import_Code", sizeof( "GEN_API_Import_Code" ) - 1 }, | ||||||
| 	}; | 	}; | ||||||
| 	return lookup[type]; | 	return lookup[type]; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline TokType strc_to_toktype( StrC str ) | inline TokType str_to_toktype( Str str ) | ||||||
| { | { | ||||||
| 	local_persist u32 keymap[Tok_NumTokens]; | 	local_persist u32 keymap[Tok_NumTokens]; | ||||||
| 	do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ ) | 	do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ ) | ||||||
| 	{ | 	{ | ||||||
| 		StrC enum_str = toktype_to_str( (TokType)index ); | 		Str enum_str  = toktype_to_str( (TokType)index ); | ||||||
| 		keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 ); | 		keymap[index] = crc32( enum_str.Ptr, enum_str.Len ); | ||||||
| 	} | 	} | ||||||
| 	do_once_end u32 hash = crc32( str.Ptr, str.Len ); | 	do_once_end u32 hash = crc32( str.Ptr, str.Len ); | ||||||
| 	for ( u32 index = 0; index < Tok_NumTokens; index++ ) | 	for ( u32 index = 0; index < Tok_NumTokens; index++ ) | ||||||
|   | |||||||
| @@ -53,7 +53,7 @@ constexpr s32 MaxUntypedStrLength       = GEN_MAX_UNTYPED_STR_LENGTH; | |||||||
| constexpr s32 LexAllocator_Size         = GEN_LEX_ALLOCATOR_SIZE; | constexpr s32 LexAllocator_Size         = GEN_LEX_ALLOCATOR_SIZE; | ||||||
| constexpr s32 Builder_StrBufferReserve  = GEN_BUILDER_STR_BUFFER_RESERVE; | constexpr s32 Builder_StrBufferReserve  = GEN_BUILDER_STR_BUFFER_RESERVE; | ||||||
|  |  | ||||||
| extern StrC enum_underlying_sig; | extern Str enum_underlying_sig; | ||||||
|  |  | ||||||
| extern Code access_public; | extern Code access_public; | ||||||
| extern Code access_protected; | extern Code access_protected; | ||||||
|   | |||||||
| @@ -101,7 +101,7 @@ Code& Code::operator ++() | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
| forceinline | forceinline | ||||||
| StrC code_type_str(Code self) | Str code_type_str(Code self) | ||||||
| { | { | ||||||
| 	GEN_ASSERT(self != nullptr); | 	GEN_ASSERT(self != nullptr); | ||||||
| 	return codetype_to_str( self->Type ); | 	return codetype_to_str( self->Type ); | ||||||
| @@ -397,7 +397,7 @@ CodeBody def_body( CodeType type ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| StrC token_fmt_impl( ssize num, ... ) | Str token_fmt_impl( ssize num, ... ) | ||||||
| { | { | ||||||
| 	local_persist thread_local | 	local_persist thread_local | ||||||
| 	char buf[GEN_PRINTF_MAXLEN] = { 0 }; | 	char buf[GEN_PRINTF_MAXLEN] = { 0 }; | ||||||
| @@ -408,7 +408,7 @@ StrC token_fmt_impl( ssize num, ... ) | |||||||
| 	ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va); | 	ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| 	StrC str = { result, buf }; | 	Str str = { buf, result }; | ||||||
| 	return str; | 	return str; | ||||||
| } | } | ||||||
| #pragma endregion Interface | #pragma endregion Interface | ||||||
|   | |||||||
| @@ -101,11 +101,11 @@ void define_constants() | |||||||
| 	access_public->Name = get_cached_string( txt("public:\n") ); | 	access_public->Name = get_cached_string( txt("public:\n") ); | ||||||
| 	code_set_global(access_public); | 	code_set_global(access_public); | ||||||
|  |  | ||||||
| 	StrC api_export_str = code(GEN_API_Export_Code); | 	Str api_export_str = code(GEN_API_Export_Code); | ||||||
| 	attrib_api_export = def_attributes( api_export_str ); | 	attrib_api_export = def_attributes( api_export_str ); | ||||||
| 	code_set_global(cast(Code, attrib_api_export)); | 	code_set_global(cast(Code, attrib_api_export)); | ||||||
|  |  | ||||||
| 	StrC api_import_str = code(GEN_API_Import_Code); | 	Str api_import_str = code(GEN_API_Import_Code); | ||||||
| 	attrib_api_import = def_attributes( api_import_str ); | 	attrib_api_import = def_attributes( api_import_str ); | ||||||
| 	code_set_global(cast(Code, attrib_api_import)); | 	code_set_global(cast(Code, attrib_api_import)); | ||||||
|  |  | ||||||
| @@ -145,43 +145,34 @@ void define_constants() | |||||||
| 	preprocess_endif->Type = CT_Preprocess_EndIf; | 	preprocess_endif->Type = CT_Preprocess_EndIf; | ||||||
| 	code_set_global((Code)preprocess_endif); | 	code_set_global((Code)preprocess_endif); | ||||||
|  |  | ||||||
| #	define def_constant_code_type( Type_ )           \ | 	Str auto_str     = txt("auto");     t_auto     = def_type( auto_str );     code_set_global( t_auto ); | ||||||
| 		do                                           \ | 	Str void_str     = txt("void");     t_void     = def_type( void_str );     code_set_global( t_void ); | ||||||
| 		{                                            \ | 	Str int_str      = txt("int");      t_int      = def_type( int_str );      code_set_global( t_int  ); | ||||||
| 			StrC name_str = name(Type_);             \ | 	Str bool_str     = txt("bool");     t_bool     = def_type( bool_str );     code_set_global( t_bool ); | ||||||
| 			t_##Type_ = def_type( name_str );        \ | 	Str char_str     = txt("char");     t_char     = def_type( char_str );     code_set_global( t_char ); | ||||||
| 			code_set_global( cast(Code, t_##Type_)); \ | 	Str wchar_str    = txt("wchar_t");  t_wchar_t  = def_type( wchar_str );    code_set_global( t_wchar_t ); | ||||||
| 		} while(0) | 	Str class_str    = txt("class");    t_class    = def_type( class_str );    code_set_global( t_class ); | ||||||
|  | 	Str typename_str = txt("typename"); t_typename = def_type( typename_str ); code_set_global( t_typename ); | ||||||
| 	def_constant_code_type( auto ); |  | ||||||
| 	def_constant_code_type( void ); |  | ||||||
| 	def_constant_code_type( int ); |  | ||||||
| 	def_constant_code_type( bool ); |  | ||||||
| 	def_constant_code_type( char ); |  | ||||||
| 	def_constant_code_type( wchar_t ); |  | ||||||
| 	def_constant_code_type( class ); |  | ||||||
| 	def_constant_code_type( typename ); |  | ||||||
|  |  | ||||||
| #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS | #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS | ||||||
| 	t_b32 = def_type( name(b32) ); | 	t_b32 = def_type( name(b32) ); code_set_global( t_b32 ); | ||||||
|  |  | ||||||
| 	def_constant_code_type( s8 ); | 	Str s8_str  = txt("s8");  t_s8  = def_type( s8_str ); code_set_global( t_s8 ); | ||||||
| 	def_constant_code_type( s16 ); | 	Str s16_str = txt("s16"); t_s16 = def_type( s16_str ); code_set_global( t_s16 ); | ||||||
| 	def_constant_code_type( s32 ); | 	Str s32_str = txt("s32"); t_s32 = def_type( s32_str ); code_set_global( t_s32 ); | ||||||
| 	def_constant_code_type( s64 ); | 	Str s64_str = txt("s64"); t_s64 = def_type( s64_str ); code_set_global( t_s64 ); | ||||||
|  |  | ||||||
| 	def_constant_code_type( u8 ); | 	Str u8_str  = txt("u8");  t_u8  = def_type( u8_str );  code_set_global( t_u8 ); | ||||||
| 	def_constant_code_type( u16 ); | 	Str u16_str = txt("u16"); t_u16 = def_type( u16_str ); code_set_global( t_u16 ); | ||||||
| 	def_constant_code_type( u32 ); | 	Str u32_str = txt("u32"); t_u32 = def_type( u32_str ); code_set_global( t_u32 ); | ||||||
| 	def_constant_code_type( u64 ); | 	Str u64_str = txt("u64"); t_u64 = def_type( u64_str ); code_set_global( t_u64 ); | ||||||
|  |  | ||||||
| 	def_constant_code_type( ssize ); | 	Str ssize_str = txt("ssize"); t_ssize = def_type( ssize_str ); code_set_global( t_ssize ); | ||||||
| 	def_constant_code_type( usize ); | 	Str usize_str = txt("usize"); t_usize = def_type( usize_str ); code_set_global( t_usize ); | ||||||
|  |  | ||||||
| 	def_constant_code_type( f32 ); | 	Str f32_str = txt("f32"); t_f32 = def_type( f32_str ); code_set_global( t_f32 ); | ||||||
| 	def_constant_code_type( f64 ); | 	Str f64_str = txt("f64"); t_f64 = def_type( f64_str ); code_set_global( t_f64 ); | ||||||
| #endif | #endif | ||||||
| #	undef def_constant_code_type |  | ||||||
|  |  | ||||||
| 	spec_const            = def_specifier( Spec_Const);            code_set_global( cast(Code, spec_const )); | 	spec_const            = def_specifier( Spec_Const);            code_set_global( cast(Code, spec_const )); | ||||||
| 	spec_consteval        = def_specifier( Spec_Consteval);        code_set_global( cast(Code, spec_consteval ));; | 	spec_consteval        = def_specifier( Spec_Consteval);        code_set_global( cast(Code, spec_consteval ));; | ||||||
| @@ -282,12 +273,12 @@ void init() | |||||||
|  |  | ||||||
| 		LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size ); | 		LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size ); | ||||||
|  |  | ||||||
| 		Arena string_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); | 		Arena strbuilder_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); | ||||||
|  |  | ||||||
| 		if ( string_arena.PhysicalStart == nullptr ) | 		if ( strbuilder_arena.PhysicalStart == nullptr ) | ||||||
| 			GEN_FATAL( "gen::init: Failed to initialize the string arena" ); | 			GEN_FATAL( "gen::init: Failed to initialize the string arena" ); | ||||||
|  |  | ||||||
| 		array_append( StringArenas, string_arena ); | 		array_append( StringArenas, strbuilder_arena ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Setup the hash tables | 	// Setup the hash tables | ||||||
| @@ -321,8 +312,8 @@ void deinit() | |||||||
| 	left  = array_num(StringArenas); | 	left  = array_num(StringArenas); | ||||||
| 	do | 	do | ||||||
| 	{ | 	{ | ||||||
| 		Arena* string_arena = & StringArenas[index]; | 		Arena* strbuilder_arena = & StringArenas[index]; | ||||||
| 		arena_free(string_arena); | 		arena_free(strbuilder_arena); | ||||||
| 		index++; | 		index++; | ||||||
| 	} | 	} | ||||||
| 	while ( left--, left ); | 	while ( left--, left ); | ||||||
| @@ -366,8 +357,8 @@ void reset() | |||||||
| 	left  = array_num(StringArenas); | 	left  = array_num(StringArenas); | ||||||
| 	do | 	do | ||||||
| 	{ | 	{ | ||||||
| 		Arena* string_arena = & StringArenas[index]; | 		Arena* strbuilder_arena = & StringArenas[index]; | ||||||
| 		string_arena->TotalUsed = 0;; | 		strbuilder_arena->TotalUsed = 0;; | ||||||
| 		index++; | 		index++; | ||||||
| 	} | 	} | ||||||
| 	while ( left--, left ); | 	while ( left--, left ); | ||||||
| @@ -377,18 +368,18 @@ void reset() | |||||||
| 	define_constants(); | 	define_constants(); | ||||||
| } | } | ||||||
|  |  | ||||||
| AllocatorInfo get_string_allocator( s32 str_length ) | AllocatorInfo get_strbuilder_allocator( s32 c_str_length ) | ||||||
| { | { | ||||||
| 	Arena* last = array_back(StringArenas); | 	Arena* last = array_back(StringArenas); | ||||||
|  |  | ||||||
| 	usize size_req = str_length + sizeof(StringHeader) + sizeof(char*); | 	usize size_req = c_str_length + sizeof(StrBuilderHeader) + sizeof(char*); | ||||||
|  |  | ||||||
| 	if ( last->TotalUsed + scast(ssize, size_req) > last->TotalSize ) | 	if ( last->TotalUsed + scast(ssize, size_req) > last->TotalSize ) | ||||||
| 	{ | 	{ | ||||||
| 		Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); | 		Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena ); | ||||||
|  |  | ||||||
| 		if ( ! array_append( StringArenas, new_arena ) ) | 		if ( ! array_append( StringArenas, new_arena ) ) | ||||||
| 			GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" ); | 			GEN_FATAL( "gen::get_strbuilder_allocator: Failed to allocate a new string arena" ); | ||||||
|  |  | ||||||
| 		last = array_back(StringArenas); | 		last = array_back(StringArenas); | ||||||
| 	} | 	} | ||||||
| @@ -397,7 +388,7 @@ AllocatorInfo get_string_allocator( s32 str_length ) | |||||||
| } | } | ||||||
|  |  | ||||||
| // Will either make or retrive a code string. | // Will either make or retrive a code string. | ||||||
| StringCached get_cached_string( StrC str ) | StringCached get_cached_string( Str str ) | ||||||
| { | { | ||||||
| 	s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len; | 	s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len; | ||||||
| 	u64 key         = crc32( str.Ptr, hash_length ); | 	u64 key         = crc32( str.Ptr, hash_length ); | ||||||
| @@ -408,7 +399,7 @@ StringCached get_cached_string( StrC str ) | |||||||
| 			return * result; | 			return * result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	StrC result = string_to_strc( string_make_strc( get_string_allocator( str.Len ), str )); | 	Str result = strbuilder_to_str( strbuilder_make_str( get_strbuilder_allocator( str.Len ), str )); | ||||||
| 	hashtable_set(StringCache, key, result ); | 	hashtable_set(StringCache, key, result ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -451,12 +442,12 @@ void set_allocator_lexer( AllocatorInfo allocator ) | |||||||
| 	Allocator_Lexer = allocator; | 	Allocator_Lexer = allocator; | ||||||
| } | } | ||||||
|  |  | ||||||
| void set_allocator_string_arena( AllocatorInfo allocator ) | void set_allocator_strbuilder_arena( AllocatorInfo allocator ) | ||||||
| { | { | ||||||
| 	Allocator_StringArena = allocator; | 	Allocator_StringArena = allocator; | ||||||
| } | } | ||||||
|  |  | ||||||
| void set_allocator_string_table( AllocatorInfo allocator ) | void set_allocator_strbuilder_table( AllocatorInfo allocator ) | ||||||
| { | { | ||||||
| 	Allocator_StringArena = allocator; | 	Allocator_StringArena = allocator; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ void reset(); | |||||||
|  |  | ||||||
| // Used internally to retrive or make string allocations. | // Used internally to retrive or make string allocations. | ||||||
| // Strings are stored in a series of string arenas of fixed size (SizePer_StringArena) | // Strings are stored in a series of string arenas of fixed size (SizePer_StringArena) | ||||||
| StringCached get_cached_string( StrC str ); | StringCached get_cached_string( Str str ); | ||||||
|  |  | ||||||
| /* | /* | ||||||
| 	This provides a fresh Code AST. | 	This provides a fresh Code AST. | ||||||
| @@ -42,14 +42,14 @@ Code make_code(); | |||||||
| void set_allocator_data_arrays ( AllocatorInfo data_array_allocator ); | void set_allocator_data_arrays ( AllocatorInfo data_array_allocator ); | ||||||
| void set_allocator_code_pool   ( AllocatorInfo pool_allocator ); | void set_allocator_code_pool   ( AllocatorInfo pool_allocator ); | ||||||
| void set_allocator_lexer       ( AllocatorInfo lex_allocator ); | void set_allocator_lexer       ( AllocatorInfo lex_allocator ); | ||||||
| void set_allocator_string_arena( AllocatorInfo string_allocator ); | void set_allocator_strbuilder_arena( AllocatorInfo strbuilder_allocator ); | ||||||
| void set_allocator_string_table( AllocatorInfo string_allocator ); | void set_allocator_strbuilder_table( AllocatorInfo strbuilder_allocator ); | ||||||
| void set_allocator_type_table  ( AllocatorInfo type_reg_allocator ); | void set_allocator_type_table  ( AllocatorInfo type_reg_allocator ); | ||||||
|  |  | ||||||
| #pragma region Upfront | #pragma region Upfront | ||||||
|  |  | ||||||
| CodeAttributes def_attributes( StrC content ); | CodeAttributes def_attributes( Str content ); | ||||||
| CodeComment    def_comment   ( StrC content ); | CodeComment    def_comment   ( Str content ); | ||||||
|  |  | ||||||
| struct Opts_def_struct { | struct Opts_def_struct { | ||||||
| 	CodeBody       body; | 	CodeBody       body; | ||||||
| @@ -60,7 +60,7 @@ struct Opts_def_struct { | |||||||
| 	s32            num_interfaces; | 	s32            num_interfaces; | ||||||
| 	ModuleFlag     mflags; | 	ModuleFlag     mflags; | ||||||
| }; | }; | ||||||
| CodeClass def_class( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT ); | CodeClass def_class( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_constructor { | struct Opts_def_constructor { | ||||||
| 	CodeParams params; | 	CodeParams params; | ||||||
| @@ -72,7 +72,7 @@ CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT ); | |||||||
| struct Opts_def_define { | struct Opts_def_define { | ||||||
| 	b32 dont_append_preprocess_defines; | 	b32 dont_append_preprocess_defines; | ||||||
| }; | }; | ||||||
| CodeDefine def_define( StrC name, StrC content, Opts_def_define opts GEN_PARAM_DEFAULT ); | CodeDefine def_define( Str name, Str content, Opts_def_define opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_destructor { | struct Opts_def_destructor { | ||||||
| 	Code           body; | 	Code           body; | ||||||
| @@ -88,10 +88,10 @@ struct Opts_def_enum { | |||||||
| 	ModuleFlag     mflags; | 	ModuleFlag     mflags; | ||||||
| 	Code           type_macro; | 	Code           type_macro; | ||||||
| }; | }; | ||||||
| CodeEnum def_enum( StrC name, Opts_def_enum opts GEN_PARAM_DEFAULT ); | CodeEnum def_enum( Str name, Opts_def_enum opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| CodeExec   def_execution  ( StrC content ); | CodeExec   def_execution  ( Str content ); | ||||||
| CodeExtern def_extern_link( StrC name, CodeBody body ); | CodeExtern def_extern_link( Str name, CodeBody body ); | ||||||
| CodeFriend def_friend     ( Code symbol ); | CodeFriend def_friend     ( Code symbol ); | ||||||
|  |  | ||||||
| struct Opts_def_function { | struct Opts_def_function { | ||||||
| @@ -102,14 +102,14 @@ struct Opts_def_function { | |||||||
| 	CodeAttributes  attrs; | 	CodeAttributes  attrs; | ||||||
| 	ModuleFlag      mflags; | 	ModuleFlag      mflags; | ||||||
| }; | }; | ||||||
| CodeFn def_function( StrC name, Opts_def_function opts GEN_PARAM_DEFAULT ); | CodeFn def_function( Str name, Opts_def_function opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_include   { b32        foreign; }; | struct Opts_def_include   { b32        foreign; }; | ||||||
| struct Opts_def_module    { ModuleFlag mflags;  }; | struct Opts_def_module    { ModuleFlag mflags;  }; | ||||||
| struct Opts_def_namespace { ModuleFlag mflags;  }; | struct Opts_def_namespace { ModuleFlag mflags;  }; | ||||||
| CodeInclude def_include  ( StrC content,             Opts_def_include   opts GEN_PARAM_DEFAULT ); | CodeInclude def_include  ( Str content,             Opts_def_include   opts GEN_PARAM_DEFAULT ); | ||||||
| CodeModule  def_module   ( StrC name,                Opts_def_module    opts GEN_PARAM_DEFAULT ); | CodeModule  def_module   ( Str name,                Opts_def_module    opts GEN_PARAM_DEFAULT ); | ||||||
| CodeNS      def_namespace( StrC name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT ); | CodeNS      def_namespace( Str name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_operator { | struct Opts_def_operator { | ||||||
| 	CodeParams      params; | 	CodeParams      params; | ||||||
| @@ -119,7 +119,7 @@ struct Opts_def_operator { | |||||||
| 	CodeAttributes  attributes; | 	CodeAttributes  attributes; | ||||||
| 	ModuleFlag      mflags; | 	ModuleFlag      mflags; | ||||||
| }; | }; | ||||||
| CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator opts GEN_PARAM_DEFAULT ); | CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_operator_cast { | struct Opts_def_operator_cast { | ||||||
| 	CodeBody       body; | 	CodeBody       body; | ||||||
| @@ -128,14 +128,14 @@ struct Opts_def_operator_cast { | |||||||
| CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT ); | CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_param { Code value; }; | struct Opts_def_param { Code value; }; | ||||||
| CodeParams  def_param ( CodeTypename type, StrC name, Opts_def_param opts GEN_PARAM_DEFAULT ); | CodeParams  def_param ( CodeTypename type, Str name, Opts_def_param opts GEN_PARAM_DEFAULT ); | ||||||
| CodePragma def_pragma( StrC directive ); | CodePragma def_pragma( Str directive ); | ||||||
|  |  | ||||||
| CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC content ); | CodePreprocessCond def_preprocess_cond( EPreprocessCond type, Str content ); | ||||||
|  |  | ||||||
| CodeSpecifiers def_specifier( Specifier specifier ); | CodeSpecifiers def_specifier( Specifier specifier ); | ||||||
|  |  | ||||||
| CodeStruct def_struct( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT ); | CodeStruct def_struct( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_template { ModuleFlag mflags; }; | struct Opts_def_template { ModuleFlag mflags; }; | ||||||
| CodeTemplate def_template( CodeParams params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT ); | CodeTemplate def_template( CodeParams params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT ); | ||||||
| @@ -146,27 +146,27 @@ struct Opts_def_type { | |||||||
| 	CodeSpecifiers specifiers; | 	CodeSpecifiers specifiers; | ||||||
| 	CodeAttributes attributes; | 	CodeAttributes attributes; | ||||||
| }; | }; | ||||||
| CodeTypename def_type( StrC name, Opts_def_type opts GEN_PARAM_DEFAULT ); | CodeTypename def_type( Str name, Opts_def_type opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_typedef { | struct Opts_def_typedef { | ||||||
| 	CodeAttributes attributes; | 	CodeAttributes attributes; | ||||||
| 	ModuleFlag     mflags; | 	ModuleFlag     mflags; | ||||||
| }; | }; | ||||||
| CodeTypedef def_typedef( StrC name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT ); | CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_union { | struct Opts_def_union { | ||||||
| 	CodeAttributes attributes; | 	CodeAttributes attributes; | ||||||
| 	ModuleFlag     mflags; | 	ModuleFlag     mflags; | ||||||
| }; | }; | ||||||
| CodeUnion def_union( StrC name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT ); | CodeUnion def_union( Str name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| struct Opts_def_using { | struct Opts_def_using { | ||||||
| 	CodeAttributes attributes; | 	CodeAttributes attributes; | ||||||
| 	ModuleFlag     mflags; | 	ModuleFlag     mflags; | ||||||
| }; | }; | ||||||
| CodeUsing def_using( StrC name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT ); | CodeUsing def_using( Str name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| CodeUsing def_using_namespace( StrC name ); | CodeUsing def_using_namespace( Str name ); | ||||||
|  |  | ||||||
| struct Opts_def_variable | struct Opts_def_variable | ||||||
| { | { | ||||||
| @@ -175,7 +175,7 @@ struct Opts_def_variable | |||||||
| 	CodeAttributes attributes; | 	CodeAttributes attributes; | ||||||
| 	ModuleFlag     mflags; | 	ModuleFlag     mflags; | ||||||
| }; | }; | ||||||
| CodeVar def_variable( CodeTypename type, StrC name, Opts_def_variable opts GEN_PARAM_DEFAULT ); | CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable opts GEN_PARAM_DEFAULT ); | ||||||
|  |  | ||||||
| // Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries. | // Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries. | ||||||
| CodeBody def_body( CodeType type ); | CodeBody def_body( CodeType type ); | ||||||
| @@ -220,13 +220,13 @@ struct StackNode | |||||||
|  |  | ||||||
| 	Token Start; | 	Token Start; | ||||||
| 	Token Name;       // The name of the AST node (if parsed) | 	Token Name;       // The name of the AST node (if parsed) | ||||||
| 	StrC  FailedProc; // The name of the procedure that failed | 	Str  FailedProc; // The name of the procedure that failed | ||||||
| }; | }; | ||||||
| // Stack nodes are allocated the error's allocator | // Stack nodes are allocated the error's allocator | ||||||
|  |  | ||||||
| struct Error | struct Error | ||||||
| { | { | ||||||
| 	String     message; | 	StrBuilder     message; | ||||||
| 	StackNode* context_stack; | 	StackNode* context_stack; | ||||||
| }; | }; | ||||||
| GEN_NS_PARSER_END | GEN_NS_PARSER_END | ||||||
| @@ -243,28 +243,28 @@ struct ParseInfo | |||||||
| 	// Errors are allocated to a dedicated general arena. | 	// Errors are allocated to a dedicated general arena. | ||||||
| }; | }; | ||||||
|  |  | ||||||
| CodeBody parse_file( StrC path ); | CodeBody parse_file( Str path ); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| CodeClass       parse_class        ( StrC class_def       ); | CodeClass       parse_class        ( Str class_def       ); | ||||||
| CodeConstructor parse_constructor  ( StrC constructor_def ); | CodeConstructor parse_constructor  ( Str constructor_def ); | ||||||
| CodeDestructor  parse_destructor   ( StrC destructor_def  ); | CodeDestructor  parse_destructor   ( Str destructor_def  ); | ||||||
| CodeEnum        parse_enum         ( StrC enum_def        ); | CodeEnum        parse_enum         ( Str enum_def        ); | ||||||
| CodeBody        parse_export_body  ( StrC export_def      ); | CodeBody        parse_export_body  ( Str export_def      ); | ||||||
| CodeExtern      parse_extern_link  ( StrC exten_link_def  ); | CodeExtern      parse_extern_link  ( Str exten_link_def  ); | ||||||
| CodeFriend      parse_friend       ( StrC friend_def      ); | CodeFriend      parse_friend       ( Str friend_def      ); | ||||||
| CodeFn          parse_function     ( StrC fn_def          ); | CodeFn          parse_function     ( Str fn_def          ); | ||||||
| CodeBody        parse_global_body  ( StrC body_def        ); | CodeBody        parse_global_body  ( Str body_def        ); | ||||||
| CodeNS          parse_namespace    ( StrC namespace_def   ); | CodeNS          parse_namespace    ( Str namespace_def   ); | ||||||
| CodeOperator    parse_operator     ( StrC operator_def    ); | CodeOperator    parse_operator     ( Str operator_def    ); | ||||||
| CodeOpCast      parse_operator_cast( StrC operator_def    ); | CodeOpCast      parse_operator_cast( Str operator_def    ); | ||||||
| CodeStruct      parse_struct       ( StrC struct_def      ); | CodeStruct      parse_struct       ( Str struct_def      ); | ||||||
| CodeTemplate    parse_template     ( StrC template_def    ); | CodeTemplate    parse_template     ( Str template_def    ); | ||||||
| CodeTypename    parse_type         ( StrC type_def        ); | CodeTypename    parse_type         ( Str type_def        ); | ||||||
| CodeTypedef     parse_typedef      ( StrC typedef_def     ); | CodeTypedef     parse_typedef      ( Str typedef_def     ); | ||||||
| CodeUnion       parse_union        ( StrC union_def       ); | CodeUnion       parse_union        ( Str union_def       ); | ||||||
| CodeUsing       parse_using        ( StrC using_def       ); | CodeUsing       parse_using        ( Str using_def       ); | ||||||
| CodeVar         parse_variable     ( StrC var_def         ); | CodeVar         parse_variable     ( Str var_def         ); | ||||||
|  |  | ||||||
| #pragma endregion Parsing | #pragma endregion Parsing | ||||||
|  |  | ||||||
| @@ -272,9 +272,9 @@ CodeVar         parse_variable     ( StrC var_def         ); | |||||||
|  |  | ||||||
| ssize   token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va ); | ssize   token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va ); | ||||||
| //! Do not use directly. Use the token_fmt macro instead. | //! Do not use directly. Use the token_fmt macro instead. | ||||||
| StrC token_fmt_impl( ssize, ... ); | Str token_fmt_impl( ssize, ... ); | ||||||
|  |  | ||||||
| Code untyped_str      ( StrC content); | Code untyped_str      ( Str content); | ||||||
| Code untyped_fmt      ( char const* fmt, ... ); | Code untyped_fmt      ( char const* fmt, ... ); | ||||||
| Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ); | Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ); | ||||||
|  |  | ||||||
| @@ -289,12 +289,12 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ); | |||||||
| #ifndef name | #ifndef name | ||||||
| //	Convienence for defining any name used with the gen api. | //	Convienence for defining any name used with the gen api. | ||||||
| //  Lets you provide the length and string literal to the functions without the need for the DSL. | //  Lets you provide the length and string literal to the functions without the need for the DSL. | ||||||
| #define name( Id_ )   { sizeof(stringize( Id_ )) - 1, stringize(Id_) } | #define name( Id_ )   { stringize(Id_), sizeof(stringize( Id_ )) - 1 } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef code | #ifndef code | ||||||
| //  Same as name just used to indicate intention of literal for code instead of names. | //  Same as name just used to indicate intention of literal for code instead of names. | ||||||
| #define code( ... ) { sizeof(stringize(__VA_ARGS__)) - 1, stringize( __VA_ARGS__ ) } | #define code( ... ) { stringize( __VA_ARGS__ ), sizeof(stringize(__VA_ARGS__)) - 1 } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef args | #ifndef args | ||||||
| @@ -317,21 +317,21 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ); | |||||||
|  |  | ||||||
| #ifndef token_fmt | #ifndef token_fmt | ||||||
| /* | /* | ||||||
| Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string. | Takes a format string (char const*) and a list of tokens (Str) and returns a Str of the formatted string. | ||||||
| Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brackets (you can change it in token_fmt_va) | Tokens are provided in '<'identifier'>' format where '<' '>' are just angle brackets (you can change it in token_fmt_va) | ||||||
| --------------------------------------------------------- | --------------------------------------------------------- | ||||||
| 	Example - A string with: | 	Example - A string with: | ||||||
| 		typedef <type> <name> <name>; | 		typedef <type> <name> <name>; | ||||||
| 	Will have a token_fmt arguments populated with: | 	Will have a token_fmt arguments populated with: | ||||||
| 		"type", strc_for_type, | 		"type", str_for_type, | ||||||
| 		"name", strc_for_name, | 		"name", str_for_name, | ||||||
| 	and: | 	and: | ||||||
| 		stringize( typedef <type> <name> <name>; ) | 		stringize( typedef <type> <name> <name>; ) | ||||||
| ----------------------------------------------------------- | ----------------------------------------------------------- | ||||||
| So the full call for this example would be: | So the full call for this example would be: | ||||||
| 	token_fmt( | 	token_fmt( | ||||||
| 		"type", strc_for_type | 		"type", str_for_type | ||||||
| 	,	"name", strc_for_name | 	,	"name", str_for_name | ||||||
| 	,	stringize( | 	,	stringize( | ||||||
| 		typedef <type> <name> <name> | 		typedef <type> <name> <name> | ||||||
| 	)); | 	)); | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|  |  | ||||||
| // Publically Exposed Interface | // Publically Exposed Interface | ||||||
|  |  | ||||||
| CodeClass parse_class( StrC def ) | CodeClass parse_class( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -24,7 +24,7 @@ CodeClass parse_class( StrC def ) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeConstructor parse_constructor( StrC def ) | CodeConstructor parse_constructor( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -41,7 +41,7 @@ CodeConstructor parse_constructor( StrC def ) | |||||||
|  |  | ||||||
| 	while ( left && tok_is_specifier(currtok) ) | 	while ( left && tok_is_specifier(currtok) ) | ||||||
| 	{ | 	{ | ||||||
| 		Specifier spec = strc_to_specifier( tok_to_str(currtok) ); | 		Specifier spec = str_to_specifier( tok_to_str(currtok) ); | ||||||
|  |  | ||||||
| 		b32 ignore_spec = false; | 		b32 ignore_spec = false; | ||||||
|  |  | ||||||
| @@ -59,7 +59,7 @@ CodeConstructor parse_constructor( StrC def ) | |||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			default : | 			default : | ||||||
| 				log_failure( "Invalid specifier %s for variable\n%s", spec_to_str( spec ), parser_to_string(Context) ); | 				log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(Context) ); | ||||||
| 				parser_pop(& Context); | 				parser_pop(& Context); | ||||||
| 				return InvalidCode; | 				return InvalidCode; | ||||||
| 		} | 		} | ||||||
| @@ -84,7 +84,7 @@ CodeConstructor parse_constructor( StrC def ) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeDestructor parse_destructor( StrC def ) | CodeDestructor parse_destructor( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -101,7 +101,7 @@ CodeDestructor parse_destructor( StrC def ) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeEnum parse_enum( StrC def ) | CodeEnum parse_enum( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -117,7 +117,7 @@ CodeEnum parse_enum( StrC def ) | |||||||
| 	return parser_parse_enum( parser_not_inplace_def); | 	return parser_parse_enum( parser_not_inplace_def); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeBody parse_export_body( StrC def ) | CodeBody parse_export_body( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -130,7 +130,7 @@ CodeBody parse_export_body( StrC def ) | |||||||
| 	return parser_parse_export_body(); | 	return parser_parse_export_body(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeExtern parse_extern_link( StrC def ) | CodeExtern parse_extern_link( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -143,7 +143,7 @@ CodeExtern parse_extern_link( StrC def ) | |||||||
| 	return parser_parse_extern_link(); | 	return parser_parse_extern_link(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeFriend parse_friend( StrC def ) | CodeFriend parse_friend( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -156,7 +156,7 @@ CodeFriend parse_friend( StrC def ) | |||||||
| 	return parser_parse_friend(); | 	return parser_parse_friend(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeFn parse_function( StrC def ) | CodeFn parse_function( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -169,7 +169,7 @@ CodeFn parse_function( StrC def ) | |||||||
| 	return (CodeFn) parser_parse_function(); | 	return (CodeFn) parser_parse_function(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeBody parse_global_body( StrC def ) | CodeBody parse_global_body( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -185,7 +185,7 @@ CodeBody parse_global_body( StrC def ) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeNS parse_namespace( StrC def ) | CodeNS parse_namespace( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -198,7 +198,7 @@ CodeNS parse_namespace( StrC def ) | |||||||
| 	return parser_parse_namespace(); | 	return parser_parse_namespace(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeOperator parse_operator( StrC def ) | CodeOperator parse_operator( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -211,7 +211,7 @@ CodeOperator parse_operator( StrC def ) | |||||||
| 	return (CodeOperator) parser_parse_operator(); | 	return (CodeOperator) parser_parse_operator(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeOpCast parse_operator_cast( StrC def ) | CodeOpCast parse_operator_cast( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -224,7 +224,7 @@ CodeOpCast parse_operator_cast( StrC def ) | |||||||
| 	return parser_parse_operator_cast(NullCode); | 	return parser_parse_operator_cast(NullCode); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeStruct parse_struct( StrC def ) | CodeStruct parse_struct( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -240,7 +240,7 @@ CodeStruct parse_struct( StrC def ) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeTemplate parse_template( StrC def ) | CodeTemplate parse_template( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -253,7 +253,7 @@ CodeTemplate parse_template( StrC def ) | |||||||
| 	return parser_parse_template(); | 	return parser_parse_template(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeTypename parse_type( StrC def ) | CodeTypename parse_type( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -266,7 +266,7 @@ CodeTypename parse_type( StrC def ) | |||||||
| 	return parser_parse_type( parser_not_from_template, nullptr); | 	return parser_parse_type( parser_not_from_template, nullptr); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeTypedef parse_typedef( StrC def ) | CodeTypedef parse_typedef( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -279,7 +279,7 @@ CodeTypedef parse_typedef( StrC def ) | |||||||
| 	return parser_parse_typedef(); | 	return parser_parse_typedef(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeUnion parse_union( StrC def ) | CodeUnion parse_union( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -292,7 +292,7 @@ CodeUnion parse_union( StrC def ) | |||||||
| 	return parser_parse_union( parser_not_inplace_def); | 	return parser_parse_union( parser_not_inplace_def); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeUsing parse_using( StrC def ) | CodeUsing parse_using( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
| @@ -305,7 +305,7 @@ CodeUsing parse_using( StrC def ) | |||||||
| 	return parser_parse_using(); | 	return parser_parse_using(); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeVar parse_variable( StrC def ) | CodeVar parse_variable( Str def ) | ||||||
| { | { | ||||||
| 	GEN_USING_NS_PARSER; | 	GEN_USING_NS_PARSER; | ||||||
| 	check_parse_args( def ); | 	check_parse_args( def ); | ||||||
|   | |||||||
| @@ -15,16 +15,16 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va ) | |||||||
| 	local_persist | 	local_persist | ||||||
| 	StringTable tok_map; | 	StringTable tok_map; | ||||||
| 	{ | 	{ | ||||||
| 		tok_map = hashtable_init(StrC, fixed_arena_allocator_info(& tok_map_arena) ); | 		tok_map = hashtable_init(Str, fixed_arena_allocator_info(& tok_map_arena) ); | ||||||
|  |  | ||||||
| 		s32 left = num_tokens - 1; | 		s32 left = num_tokens - 1; | ||||||
|  |  | ||||||
| 		while ( left-- ) | 		while ( left-- ) | ||||||
| 		{ | 		{ | ||||||
| 			char const* token = va_arg( va, char const* ); | 			char const* token = va_arg( va, char const* ); | ||||||
| 			StrC        value = va_arg( va, StrC ); | 			Str        value = va_arg( va, Str ); | ||||||
|  |  | ||||||
| 			u32 key = crc32( token, str_len(token) ); | 			u32 key = crc32( token, c_str_len(token) ); | ||||||
| 			hashtable_set( tok_map, key, value ); | 			hashtable_set( tok_map, key, value ); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -61,7 +61,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va ) | |||||||
| 			char const* token = fmt + 1; | 			char const* token = fmt + 1; | ||||||
|  |  | ||||||
| 			u32       key   = crc32( token, tok_len ); | 			u32       key   = crc32( token, tok_len ); | ||||||
| 			StrC*     value = hashtable_get(tok_map, key ); | 			Str*     value = hashtable_get(tok_map, key ); | ||||||
|  |  | ||||||
| 			if ( value ) | 			if ( value ) | ||||||
| 			{ | 			{ | ||||||
| @@ -99,7 +99,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va ) | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| Code untyped_str( StrC content ) | Code untyped_str( Str content ) | ||||||
| { | { | ||||||
| 	if ( content.Len == 0 ) | 	if ( content.Len == 0 ) | ||||||
| 	{ | 	{ | ||||||
| @@ -135,11 +135,11 @@ Code untyped_fmt( char const* fmt, ...) | |||||||
|  |  | ||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, fmt); | 	va_start(va, fmt); | ||||||
| 	ssize length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va); | 	ssize length = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| 	StrC buf_str      = { str_len_capped(fmt, MaxNameLength), fmt }; | 	Str buf_str      = { fmt, c_str_len_capped(fmt, MaxNameLength) }; | ||||||
|     StrC uncapped_str = { length, buf }; |     Str uncapped_str = { buf, length }; | ||||||
|  |  | ||||||
| 	Code | 	Code | ||||||
| 	result          = make_code(); | 	result          = make_code(); | ||||||
| @@ -172,7 +172,7 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ) | |||||||
| 	ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va); | 	ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| 	StrC buf_str = { length, buf }; | 	Str buf_str = { buf, length }; | ||||||
|  |  | ||||||
| 	Code | 	Code | ||||||
| 	result          = make_code(); | 	result          = make_code(); | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -28,7 +28,7 @@ global AllocatorInfo Allocator_TypeTable   = {0}; | |||||||
|  |  | ||||||
| #pragma region Constants | #pragma region Constants | ||||||
|  |  | ||||||
| global StrC enum_underlying_sig; | global Str enum_underlying_sig; | ||||||
|  |  | ||||||
| global Code access_public; | global Code access_public; | ||||||
| global Code access_protected; | global Code access_protected; | ||||||
|   | |||||||
| @@ -44,17 +44,17 @@ enum AccessSpec : u32 | |||||||
| static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" ); | static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" ); | ||||||
|  |  | ||||||
| inline | inline | ||||||
| StrC access_spec_to_str( AccessSpec type ) | Str access_spec_to_str( AccessSpec type ) | ||||||
| { | { | ||||||
| 	local_persist | 	local_persist | ||||||
| 	StrC lookup[ (u32)AccessSpec_Num_AccessSpec ] = { | 	Str lookup[ (u32)AccessSpec_Num_AccessSpec ] = { | ||||||
| 		{ sizeof("") - 1,          "" }, | 		{ "",        sizeof( "" )        - 1 }, | ||||||
| 		{ sizeof("prviate") - 1,   "private" }, | 		{ "private", sizeof("prviate")   - 1 }, | ||||||
| 		{ sizeof("protected") - 1, "private" }, | 		{ "private", sizeof("protected") - 1 }, | ||||||
| 		{ sizeof("public") - 1,    "public" }, | 		{ "public",  sizeof("public")    - 1 }, | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	StrC invalid = { sizeof("Invalid") - 1, "Invalid" }; | 	Str invalid = { "Invalid", sizeof("Invalid") - 1 }; | ||||||
| 	if ( type > AccessSpec_Public ) | 	if ( type > AccessSpec_Public ) | ||||||
| 		return invalid; | 		return invalid; | ||||||
|  |  | ||||||
| @@ -97,17 +97,17 @@ enum ModuleFlag : u32 | |||||||
| static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" ); | static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" ); | ||||||
|  |  | ||||||
| inline | inline | ||||||
| StrC module_flag_to_str( ModuleFlag flag ) | Str module_flag_to_str( ModuleFlag flag ) | ||||||
| { | { | ||||||
| 	local_persist | 	local_persist | ||||||
| 	StrC lookup[ (u32)Num_ModuleFlags ] = { | 	Str lookup[ (u32)Num_ModuleFlags ] = { | ||||||
| 		{ sizeof("__none__"), "__none__" }, | 		{ "__none__", sizeof("__none__") - 1 }, | ||||||
| 		{ sizeof("export"), "export" }, | 		{ "export",   sizeof("export")   - 1 }, | ||||||
| 		{ sizeof("import"), "import" }, | 		{ "import",   sizeof("import")   - 1 }, | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	local_persist | 	local_persist | ||||||
| 	StrC invalid_flag = { sizeof("invalid"), "invalid" }; | 	Str invalid_flag = { "invalid", sizeof("invalid") }; | ||||||
| 	if ( flag > ModuleFlag_Import ) | 	if ( flag > ModuleFlag_Import ) | ||||||
| 		return invalid_flag; | 		return invalid_flag; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -102,16 +102,16 @@ struct Array | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if GEN_COMPILER_CPP && 0 | #if GEN_COMPILER_CPP && 0 | ||||||
| template<class Type> bool         append(Array<Type>& array, Array<Type> other)                         { return append( & array, other ); } | template<class Type> bool append(Array<Type>& array, Array<Type> other)                         { return append( & array, other ); } | ||||||
| template<class Type> bool         append(Array<Type>& array, Type value)                                { return append( & array, value ); } | template<class Type> bool append(Array<Type>& array, Type value)                                { return append( & array, value ); } | ||||||
| template<class Type> bool         append(Array<Type>& array, Type* items, usize item_num)               { return append( & array, items, item_num ); } | template<class Type> bool append(Array<Type>& array, Type* items, usize item_num)               { return append( & array, items, item_num ); } | ||||||
| template<class Type> bool         append_at(Array<Type>& array, Type item, usize idx)                   { return append_at( & array, item, idx ); } | template<class Type> bool append_at(Array<Type>& array, Type item, usize idx)                   { return append_at( & array, item, idx ); } | ||||||
| template<class Type> bool         append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return append_at( & array, items, item_num, idx ); } | template<class Type> bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return append_at( & array, items, item_num, idx ); } | ||||||
| template<class Type> void         free(Array<Type>& array)                                              { return free( & array ); } | template<class Type> void free(Array<Type>& array)                                              { return free( & array ); } | ||||||
| template<class Type> bool         grow(Array<Type>& array, usize min_capacity)                          { return grow( & array, min_capacity); } | template<class Type> bool grow(Array<Type>& array, usize min_capacity)                          { return grow( & array, min_capacity); } | ||||||
| template<class Type> bool         reserve(Array<Type>& array, usize new_capacity)                       { return reserve( & array, new_capacity); } | template<class Type> bool reserve(Array<Type>& array, usize new_capacity)                       { return reserve( & array, new_capacity); } | ||||||
| template<class Type> bool         resize(Array<Type>& array, usize num)                                 { return resize( & array, num); } | template<class Type> bool resize(Array<Type>& array, usize num)                                 { return resize( & array, num); } | ||||||
| template<class Type> bool         set_capacity(Array<Type>& array, usize new_capacity)                  { return set_capacity( & array, new_capacity); } | template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity)                  { return set_capacity( & array, new_capacity); } | ||||||
|  |  | ||||||
| template<class Type> forceinline Type* begin(Array<Type>& array)             { return array;      } | template<class Type> forceinline Type* begin(Array<Type>& array)             { return array;      } | ||||||
| template<class Type> forceinline Type* end(Array<Type>& array)               { return array + array_get_header(array)->Num; } | template<class Type> forceinline Type* end(Array<Type>& array)               { return array + array_get_header(array)->Num; } | ||||||
|   | |||||||
| @@ -8,16 +8,23 @@ | |||||||
|  |  | ||||||
| #pragma region Debug | #pragma region Debug | ||||||
|  |  | ||||||
| #if defined( _MSC_VER ) | #if GEN_BUILD_DEBUG | ||||||
| #	if _MSC_VER < 1300 | #	if defined( GEN_COMPILER_MSVC ) | ||||||
| #		define GEN_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */ | #		if _MSC_VER < 1300 | ||||||
|  | #pragma message("GEN_BUILD_DEBUG: __asm int 3") | ||||||
|  | #			define GEN_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */ | ||||||
|  | #		else | ||||||
|  | #pragma message("GEN_BUILD_DEBUG: __debugbreak()") | ||||||
|  | #			define GEN_DEBUG_TRAP() __debugbreak() | ||||||
|  | #		endif | ||||||
|  | #	elif defined( GEN_COMPILER_TINYC ) | ||||||
|  | #		define GEN_DEBUG_TRAP() process_exit( 1 ) | ||||||
| #	else | #	else | ||||||
| #		define GEN_DEBUG_TRAP() __debugbreak() | #		define GEN_DEBUG_TRAP() __builtin_trap() | ||||||
| #	endif | #	endif | ||||||
| #elif defined( GEN_COMPILER_TINYC ) |  | ||||||
| #	define GEN_DEBUG_TRAP() process_exit( 1 ) |  | ||||||
| #else | #else | ||||||
| #	define GEN_DEBUG_TRAP() __builtin_trap() | #pragma message("GEN_BUILD_DEBUG: omitted") | ||||||
|  | #	define GEN_DEBUG_TRAP() | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #define GEN_ASSERT( cond ) GEN_ASSERT_MSG( cond, NULL ) | #define GEN_ASSERT( cond ) GEN_ASSERT_MSG( cond, NULL ) | ||||||
| @@ -37,14 +44,14 @@ | |||||||
| // NOTE: Things that shouldn't happen with a message! | // NOTE: Things that shouldn't happen with a message! | ||||||
| #define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ ) | #define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ ) | ||||||
|  |  | ||||||
| #if Build_Debug | #if GEN_BULD_DEBUG | ||||||
| 	#define GEN_FATAL( ... )                               \ | 	#define GEN_FATAL( ... )                               \ | ||||||
| 	do                                                     \ | 	do                                                     \ | ||||||
| 	{                                                      \ | 	{                                                      \ | ||||||
| 		local_persist thread_local                         \ | 		local_persist thread_local                         \ | ||||||
| 		char buf[GEN_PRINTF_MAXLEN] = { 0 };               \ | 		char buf[GEN_PRINTF_MAXLEN] = { 0 };               \ | ||||||
| 		                                                   \ | 		                                                   \ | ||||||
| 		str_fmt(buf, GEN_PRINTF_MAXLEN, __VA_ARGS__);      \ | 		c_str_fmt(buf, GEN_PRINTF_MAXLEN, __VA_ARGS__);    \ | ||||||
| 		GEN_PANIC(buf);                                    \ | 		GEN_PANIC(buf);                                    \ | ||||||
| 	}                                                      \ | 	}                                                      \ | ||||||
| 	while (0) | 	while (0) | ||||||
| @@ -53,7 +60,8 @@ | |||||||
| #	define GEN_FATAL( ... )                  \ | #	define GEN_FATAL( ... )                  \ | ||||||
| 	do                                       \ | 	do                                       \ | ||||||
| 	{                                        \ | 	{                                        \ | ||||||
| 		str_fmt_out_err( __VA_ARGS__ );      \ | 		c_str_fmt_out_err( __VA_ARGS__ );    \ | ||||||
|  | 		GEN_DEBUG_TRAP();                    \ | ||||||
| 		process_exit(1);                     \ | 		process_exit(1);                     \ | ||||||
| 	}                                        \ | 	}                                        \ | ||||||
| 	while (0) | 	while (0) | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ ) | |||||||
| 			*w_len_ = w_len; | 			*w_len_ = w_len; | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
| 	len = str_len( text ); | 	len = c_str_len( text ); | ||||||
| 	if ( len == 0 ) | 	if ( len == 0 ) | ||||||
| 	{ | 	{ | ||||||
| 		if ( w_len_ ) | 		if ( w_len_ ) | ||||||
| @@ -375,7 +375,7 @@ FileError file_close( FileInfo* f ) | |||||||
| FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename ) | FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename ) | ||||||
| { | { | ||||||
| 	FileError err = EFileError_NONE; | 	FileError err = EFileError_NONE; | ||||||
| 	ssize        len = str_len( filename ); | 	ssize        len = c_str_len( filename ); | ||||||
|  |  | ||||||
| 	f->ops             = ops; | 	f->ops             = ops; | ||||||
| 	f->fd              = fd; | 	f->fd              = fd; | ||||||
|   | |||||||
| @@ -93,7 +93,7 @@ struct DirInfo | |||||||
|  |  | ||||||
| 	// Internals | 	// Internals | ||||||
| 	char** filenames;    // zpl_array | 	char** filenames;    // zpl_array | ||||||
| 	String buf; | 	StrBuilder buf; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct FileInfo | struct FileInfo | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| #define _adt_fprintf( s_, fmt_, ... )                      \ | #define _adt_fprintf( s_, fmt_, ... )                      \ | ||||||
| 	do                                                     \ | 	do                                                     \ | ||||||
| 	{                                                      \ | 	{                                                      \ | ||||||
| 		if ( str_fmt_file( s_, fmt_, ##__VA_ARGS__ ) < 0 ) \ | 		if ( c_str_fmt_file( s_, fmt_, ##__VA_ARGS__ ) < 0 ) \ | ||||||
| 			return EADT_ERROR_OUT_OF_MEMORY;               \ | 			return EADT_ERROR_OUT_OF_MEMORY;               \ | ||||||
| 	} while ( 0 ) | 	} while ( 0 ) | ||||||
|  |  | ||||||
| @@ -69,7 +69,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ) | |||||||
|  |  | ||||||
| 	for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ ) | 	for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ ) | ||||||
| 	{ | 	{ | ||||||
| 		if ( ! str_compare( node->nodes[ i ].name, name ) ) | 		if ( ! c_str_compare( node->nodes[ i ].name, name ) ) | ||||||
| 		{ | 		{ | ||||||
| 			return ( node->nodes + i ); | 			return ( node->nodes + i ); | ||||||
| 		} | 		} | ||||||
| @@ -96,7 +96,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value ) | |||||||
| 		case EADT_TYPE_MULTISTRING : | 		case EADT_TYPE_MULTISTRING : | ||||||
| 		case EADT_TYPE_STRING : | 		case EADT_TYPE_STRING : | ||||||
| 			{ | 			{ | ||||||
| 				if ( node->string && ! str_compare( node->string, value ) ) | 				if ( node->string && ! c_str_compare( node->string, value ) ) | ||||||
| 				{ | 				{ | ||||||
| 					return node; | 					return node; | ||||||
| 				} | 				} | ||||||
| @@ -115,7 +115,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value ) | |||||||
| 				ssize  fsize = 0; | 				ssize  fsize = 0; | ||||||
| 				u8* buf   = file_stream_buf( &tmp, &fsize ); | 				u8* buf   = file_stream_buf( &tmp, &fsize ); | ||||||
|  |  | ||||||
| 				if ( ! str_compare( ( char const* )buf, value ) ) | 				if ( ! c_str_compare( ( char const* )buf, value ) ) | ||||||
| 				{ | 				{ | ||||||
| 					file_close( &tmp ); | 					file_close( &tmp ); | ||||||
| 					return node; | 					return node; | ||||||
| @@ -135,7 +135,7 @@ internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value ) | |||||||
| { | { | ||||||
| 	for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ ) | 	for ( ssize i = 0; i < scast(ssize, array_num(node->nodes)); i++ ) | ||||||
| 	{ | 	{ | ||||||
| 		if ( ! str_compare( node->nodes[ i ].name, name ) ) | 		if ( ! c_str_compare( node->nodes[ i ].name, name ) ) | ||||||
| 		{ | 		{ | ||||||
| 			ADT_Node* child = &node->nodes[ i ]; | 			ADT_Node* child = &node->nodes[ i ]; | ||||||
| 			if ( _adt_get_value( child, value ) ) | 			if ( _adt_get_value( child, value ) ) | ||||||
| @@ -168,22 +168,22 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #if defined EADT_URI_DEBUG || 0 | #if defined EADT_URI_DEBUG || 0 | ||||||
| 	str_fmt_out( "uri: %s\n", uri ); | 	c_str_fmt_out( "uri: %s\n", uri ); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 	char *    p = ( char* )uri, *b = p, *e = p; | 	char *    p = ( char* )uri, *b = p, *e = p; | ||||||
| 	ADT_Node* found_node = NULL; | 	ADT_Node* found_node = NULL; | ||||||
|  |  | ||||||
| 	b = p; | 	b = p; | ||||||
| 	p = e     = ( char* )str_skip( p, '/' ); | 	p = e     = ( char* )c_str_skip( p, '/' ); | ||||||
| 	char* buf = str_fmt_buf( "%.*s", ( int )( e - b ), b ); | 	char* buf = c_str_fmt_buf( "%.*s", ( int )( e - b ), b ); | ||||||
|  |  | ||||||
| 	/* handle field value lookup */ | 	/* handle field value lookup */ | ||||||
| 	if ( *b == '[' ) | 	if ( *b == '[' ) | ||||||
| 	{ | 	{ | ||||||
| 		char *l_p = buf + 1, *l_b = l_p, *l_e = l_p, *l_b2 = l_p, *l_e2 = l_p; | 		char *l_p = buf + 1, *l_b = l_p, *l_e = l_p, *l_b2 = l_p, *l_e2 = l_p; | ||||||
| 		l_e  = ( char* )str_skip( l_p, '=' ); | 		l_e  = ( char* )c_str_skip( l_p, '=' ); | ||||||
| 		l_e2 = ( char* )str_skip( l_p, ']' ); | 		l_e2 = ( char* )c_str_skip( l_p, ']' ); | ||||||
|  |  | ||||||
| 		if ( ( ! *l_e && node->type != EADT_TYPE_ARRAY ) || ! *l_e2 ) | 		if ( ( ! *l_e && node->type != EADT_TYPE_ARRAY ) || ! *l_e2 ) | ||||||
| 		{ | 		{ | ||||||
| @@ -257,7 +257,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) | |||||||
| 	/* handle array index lookup */ | 	/* handle array index lookup */ | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		ssize idx = ( ssize )str_to_i64( buf, NULL, 10 ); | 		ssize idx = ( ssize )c_str_to_i64( buf, NULL, 10 ); | ||||||
| 		if ( idx >= 0 && idx < scast(ssize, array_num(node->nodes)) ) | 		if ( idx >= 0 && idx < scast(ssize, array_num(node->nodes)) ) | ||||||
| 		{ | 		{ | ||||||
| 			found_node = &node->nodes[ idx ]; | 			found_node = &node->nodes[ idx ]; | ||||||
| @@ -511,7 +511,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str ) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		if ( ! str_compare_len( e, "0x", 2 ) || ! str_compare_len( e, "0X", 2 ) ) | 		if ( ! c_str_compare_len( e, "0x", 2 ) || ! c_str_compare_len( e, "0X", 2 ) ) | ||||||
| 		{ | 		{ | ||||||
| 			node_props = EADT_PROPS_IS_HEX; | 			node_props = EADT_PROPS_IS_HEX; | ||||||
| 		} | 		} | ||||||
| @@ -575,12 +575,12 @@ char* adt_parse_number( ADT_Node* node, char* base_str ) | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		orig_exp = exp = ( u8 )str_to_i64( expbuf, NULL, 10 ); | 		orig_exp = exp = ( u8 )c_str_to_i64( expbuf, NULL, 10 ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( node_type == EADT_TYPE_INTEGER ) | 	if ( node_type == EADT_TYPE_INTEGER ) | ||||||
| 	{ | 	{ | ||||||
| 		node->integer = str_to_i64( buf, 0, 0 ); | 		node->integer = c_str_to_i64( buf, 0, 0 ); | ||||||
| #ifndef GEN_PARSER_DISABLE_ANALYSIS | #ifndef GEN_PARSER_DISABLE_ANALYSIS | ||||||
| 		/* special case: negative zero */ | 		/* special case: negative zero */ | ||||||
| 		if ( node->integer == 0 && buf[ 0 ] == '-' ) | 		if ( node->integer == 0 && buf[ 0 ] == '-' ) | ||||||
| @@ -595,19 +595,19 @@ char* adt_parse_number( ADT_Node* node, char* base_str ) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		node->real = str_to_f64( buf, 0 ); | 		node->real = c_str_to_f64( buf, 0 ); | ||||||
|  |  | ||||||
| #ifndef GEN_PARSER_DISABLE_ANALYSIS | #ifndef GEN_PARSER_DISABLE_ANALYSIS | ||||||
| 		char *q = buf, *base_string = q, *base_string2 = q; | 		char *q = buf, *base_string = q, *base_string2 = q; | ||||||
| 		base_string           = ccast( char*, str_skip( base_string, '.' )); | 		base_string           = ccast( char*, c_str_skip( base_string, '.' )); | ||||||
| 		*base_string          = '\0'; | 		*base_string          = '\0'; | ||||||
| 		base_string2          = base_string + 1; | 		base_string2          = base_string + 1; | ||||||
| 		char* base_string_off = base_string2; | 		char* base_strbuilder_off = base_string2; | ||||||
| 		while ( *base_string_off++ == '0' ) | 		while ( *base_strbuilder_off++ == '0' ) | ||||||
| 			base2_offset++; | 			base2_offset++; | ||||||
|  |  | ||||||
| 		base  = ( s32 )str_to_i64( q, 0, 0 ); | 		base  = ( s32 )c_str_to_i64( q, 0, 0 ); | ||||||
| 		base2 = ( s32 )str_to_i64( base_string2, 0, 0 ); | 		base2 = ( s32 )c_str_to_i64( base_string2, 0, 0 ); | ||||||
| 		if ( exp ) | 		if ( exp ) | ||||||
| 		{ | 		{ | ||||||
| 			exp        = exp * ( ! ( eb == 10.0f ) ? -1 : 1 ); | 			exp        = exp * ( ! ( eb == 10.0f ) ? -1 : 1 ); | ||||||
| @@ -750,7 +750,7 @@ ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_ | |||||||
|  |  | ||||||
| 	do | 	do | ||||||
| 	{ | 	{ | ||||||
| 		p = str_skip_any( p, escaped_chars ); | 		p = c_str_skip_any( p, escaped_chars ); | ||||||
| 		_adt_fprintf( file, "%.*s", pointer_diff( b, p ), b ); | 		_adt_fprintf( file, "%.*s", pointer_diff( b, p ), b ); | ||||||
| 		if ( *p && ! ! char_first_occurence( escaped_chars, *p ) ) | 		if ( *p && ! ! char_first_occurence( escaped_chars, *p ) ) | ||||||
| 		{ | 		{ | ||||||
| @@ -763,7 +763,7 @@ ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_ | |||||||
| 	return EADT_ERROR_NONE; | 	return EADT_ERROR_NONE; | ||||||
| } | } | ||||||
|  |  | ||||||
| ADT_Error adt_str_to_number( ADT_Node* node ) | ADT_Error adt_c_str_to_number( ADT_Node* node ) | ||||||
| { | { | ||||||
| 	GEN_ASSERT( node ); | 	GEN_ASSERT( node ); | ||||||
|  |  | ||||||
| @@ -779,7 +779,7 @@ ADT_Error adt_str_to_number( ADT_Node* node ) | |||||||
| 	return EADT_ERROR_NONE; | 	return EADT_ERROR_NONE; | ||||||
| } | } | ||||||
|  |  | ||||||
| ADT_Error adt_str_to_number_strict( ADT_Node* node ) | ADT_Error adt_c_str_to_number_strict( ADT_Node* node ) | ||||||
| { | { | ||||||
| 	GEN_ASSERT( node ); | 	GEN_ASSERT( node ); | ||||||
|  |  | ||||||
| @@ -826,7 +826,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | |||||||
| 	do | 	do | ||||||
| 	{ | 	{ | ||||||
| 		char delimiter = 0; | 		char delimiter = 0; | ||||||
| 		currentChar = ccast( char*, str_trim( currentChar, false )); | 		currentChar = ccast( char*, c_str_trim( currentChar, false )); | ||||||
|  |  | ||||||
| 		if ( *currentChar == 0 ) | 		if ( *currentChar == 0 ) | ||||||
| 			break; | 			break; | ||||||
| @@ -850,7 +850,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | |||||||
| 		#endif | 		#endif | ||||||
| 			do | 			do | ||||||
| 			{ | 			{ | ||||||
| 				endChar = ccast( char*, str_skip( endChar, '"' )); | 				endChar = ccast( char*, c_str_skip( endChar, '"' )); | ||||||
|  |  | ||||||
| 				if ( *endChar && *( endChar + 1 ) == '"' ) | 				if ( *endChar && *( endChar + 1 ) == '"' ) | ||||||
| 				{ | 				{ | ||||||
| @@ -869,7 +869,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			*endChar    = 0; | 			*endChar    = 0; | ||||||
| 			currentChar = ccast( char*, str_trim( endChar + 1, true )); | 			currentChar = ccast( char*, c_str_trim( endChar + 1, true )); | ||||||
| 			delimiter   = * currentChar; | 			delimiter   = * currentChar; | ||||||
|  |  | ||||||
| 			/* unescape escaped quotes (so that unescaped text escapes :) */ | 			/* unescape escaped quotes (so that unescaped text escapes :) */ | ||||||
| @@ -879,7 +879,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | |||||||
| 				{ | 				{ | ||||||
| 					if ( *escapedChar == '"' && *( escapedChar + 1 ) == '"' ) | 					if ( *escapedChar == '"' && *( escapedChar + 1 ) == '"' ) | ||||||
| 					{ | 					{ | ||||||
| 						mem_move( escapedChar, escapedChar + 1, str_len( escapedChar ) ); | 						mem_move( escapedChar, escapedChar + 1, c_str_len( escapedChar ) ); | ||||||
| 					} | 					} | ||||||
| 					escapedChar++; | 					escapedChar++; | ||||||
| 				} | 				} | ||||||
| @@ -906,7 +906,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | |||||||
|  |  | ||||||
| 			if ( * endChar ) | 			if ( * endChar ) | ||||||
| 			{ | 			{ | ||||||
| 				currentChar = ccast( char*, str_trim( endChar, true )); | 				currentChar = ccast( char*, c_str_trim( endChar, true )); | ||||||
|  |  | ||||||
| 				while ( char_is_space( *( endChar - 1 ) ) ) | 				while ( char_is_space( *( endChar - 1 ) ) ) | ||||||
| 				{ | 				{ | ||||||
| @@ -927,7 +927,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | |||||||
| 			char* num_p       = beginChar; | 			char* num_p       = beginChar; | ||||||
|  |  | ||||||
| 			// We only consider hexadecimal values if they start with 0x | 			// We only consider hexadecimal values if they start with 0x | ||||||
| 			if ( str_len(num_p) > 2 && num_p[0] == '0' && (num_p[1] == 'x' || num_p[1] == 'X') ) | 			if ( c_str_len(num_p) > 2 && num_p[0] == '0' && (num_p[1] == 'x' || num_p[1] == 'X') ) | ||||||
| 			{ | 			{ | ||||||
| 				num_p += 2; // skip '0x' prefix | 				num_p += 2; // skip '0x' prefix | ||||||
| 				do | 				do | ||||||
| @@ -946,7 +946,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | |||||||
|  |  | ||||||
| 			if (!skip_number) | 			if (!skip_number) | ||||||
| 			{ | 			{ | ||||||
| 				adt_str_to_number(&rowItem); | 				adt_c_str_to_number(&rowItem); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -1021,16 +1021,16 @@ void _csv_write_record( FileInfo* file, CSV_Object* node ) | |||||||
| 				{ | 				{ | ||||||
| 					case EADT_NAME_STYLE_DOUBLE_QUOTE : | 					case EADT_NAME_STYLE_DOUBLE_QUOTE : | ||||||
| 						{ | 						{ | ||||||
| 							str_fmt_file( file, "\"" ); | 							c_str_fmt_file( file, "\"" ); | ||||||
| 							adt_print_string( file, node, "\"", "\"" ); | 							adt_print_string( file, node, "\"", "\"" ); | ||||||
| 							str_fmt_file( file, "\"" ); | 							c_str_fmt_file( file, "\"" ); | ||||||
| 						} | 						} | ||||||
| 						break; | 						break; | ||||||
|  |  | ||||||
| 					case EADT_NAME_STYLE_NO_QUOTES : | 					case EADT_NAME_STYLE_NO_QUOTES : | ||||||
| 						{ | 						{ | ||||||
| #endif | #endif | ||||||
| 							str_fmt_file( file, "%s", node->string ); | 							c_str_fmt_file( file, "%s", node->string ); | ||||||
| #ifndef GEN_PARSER_DISABLE_ANALYSIS | #ifndef GEN_PARSER_DISABLE_ANALYSIS | ||||||
| 						} | 						} | ||||||
| 						break; | 						break; | ||||||
| @@ -1078,10 +1078,10 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter ) | |||||||
| 			_csv_write_header( file, &obj->nodes[ i ] ); | 			_csv_write_header( file, &obj->nodes[ i ] ); | ||||||
| 			if ( i + 1 != cols ) | 			if ( i + 1 != cols ) | ||||||
| 			{ | 			{ | ||||||
| 				str_fmt_file( file, "%c", delimiter ); | 				c_str_fmt_file( file, "%c", delimiter ); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		str_fmt_file( file, "\n" ); | 		c_str_fmt_file( file, "\n" ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for ( ssize r = 0; r < rows; r++ ) | 	for ( ssize r = 0; r < rows; r++ ) | ||||||
| @@ -1091,14 +1091,14 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter ) | |||||||
| 			_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] ); | 			_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] ); | ||||||
| 			if ( i + 1 != cols ) | 			if ( i + 1 != cols ) | ||||||
| 			{ | 			{ | ||||||
| 				str_fmt_file( file, "%c", delimiter ); | 				c_str_fmt_file( file, "%c", delimiter ); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		str_fmt_file( file, "\n" ); | 		c_str_fmt_file( file, "\n" ); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimiter ) | StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delimiter ) | ||||||
| { | { | ||||||
| 	FileInfo tmp; | 	FileInfo tmp; | ||||||
| 	file_stream_new( &tmp, a ); | 	file_stream_new( &tmp, a ); | ||||||
| @@ -1106,7 +1106,7 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi | |||||||
|  |  | ||||||
| 	ssize  fsize; | 	ssize  fsize; | ||||||
| 	u8*    buf    = file_stream_buf( &tmp, &fsize ); | 	u8*    buf    = file_stream_buf( &tmp, &fsize ); | ||||||
| 	String output = string_make_length( a, ( char* )buf, fsize ); | 	StrBuilder output = strbuilder_make_length( a, ( char* )buf, fsize ); | ||||||
| 	file_close( &tmp ); | 	file_close( &tmp ); | ||||||
| 	return output; | 	return output; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -350,7 +350,7 @@ char* adt_parse_number_strict( ADT_Node* node, char* base_str ); | |||||||
| 	* @param node | 	* @param node | ||||||
| 	* @return | 	* @return | ||||||
| 	*/ | 	*/ | ||||||
| ADT_Error adt_str_to_number( ADT_Node* node ); | ADT_Error adt_c_str_to_number( ADT_Node* node ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| 	* @brief Parses and converts an existing string node into a number. | 	* @brief Parses and converts an existing string node into a number. | ||||||
| @@ -359,7 +359,7 @@ ADT_Error adt_str_to_number( ADT_Node* node ); | |||||||
| 	* @param node | 	* @param node | ||||||
| 	* @return | 	* @return | ||||||
| 	*/ | 	*/ | ||||||
| ADT_Error adt_str_to_number_strict( ADT_Node* node ); | ADT_Error adt_c_str_to_number_strict( ADT_Node* node ); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| 	* @brief Prints a number into a file stream. | 	* @brief Prints a number into a file stream. | ||||||
| @@ -406,9 +406,9 @@ u8   csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, | |||||||
| void csv_free( CSV_Object* obj ); | void csv_free( CSV_Object* obj ); | ||||||
|  |  | ||||||
| void   csv_write( FileInfo* file, CSV_Object* obj ); | void   csv_write( FileInfo* file, CSV_Object* obj ); | ||||||
| String csv_write_string( AllocatorInfo a, CSV_Object* obj ); | StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj ); | ||||||
| void   csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim ); | void   csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim ); | ||||||
| String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim ); | StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim ); | ||||||
|  |  | ||||||
| /* inline */ | /* inline */ | ||||||
|  |  | ||||||
| @@ -425,9 +425,9 @@ void csv_write( FileInfo* file, CSV_Object* obj ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| String csv_write_string( AllocatorInfo a, CSV_Object* obj ) | StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj ) | ||||||
| { | { | ||||||
| 	return csv_write_string_delimiter( a, obj, ',' ); | 	return csv_write_strbuilder_delimiter( a, obj, ',' ); | ||||||
| } | } | ||||||
|  |  | ||||||
| #pragma endregion CSV | #pragma endregion CSV | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| #ifdef GEN_INTELLISENSE_DIRECTIVES | #ifdef GEN_INTELLISENSE_DIRECTIVES | ||||||
| #	pragma once | #	pragma once | ||||||
| #	include "string_ops.cpp" | #	include "strbuilder_ops.cpp" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #pragma region Printing | #pragma region Printing | ||||||
| @@ -48,7 +48,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha | |||||||
|  |  | ||||||
| 	if ( str == NULL && max_len >= 6 ) | 	if ( str == NULL && max_len >= 6 ) | ||||||
| 	{ | 	{ | ||||||
| 		res += str_copy_nulpad( text, "(null)", 6 ); | 		res += c_str_copy_nulpad( text, "(null)", 6 ); | ||||||
| 		return res; | 		return res; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -56,7 +56,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha | |||||||
| 		// Made the design decision for this library that precision is the length of the string. | 		// Made the design decision for this library that precision is the length of the string. | ||||||
| 		len = info->precision; | 		len = info->precision; | ||||||
| 	else | 	else | ||||||
| 		len = str_len( str ); | 		len = c_str_len( str ); | ||||||
|  |  | ||||||
| 	if ( info && ( info->width == 0 && info->flags & GEN_FMT_WIDTH ) ) | 	if ( info && ( info->width == 0 && info->flags & GEN_FMT_WIDTH ) ) | ||||||
| 	{ | 	{ | ||||||
| @@ -69,7 +69,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha | |||||||
| 			len = info->precision < len ? info->precision : len; | 			len = info->precision < len ? info->precision : len; | ||||||
| 		if ( res + len > max_len ) | 		if ( res + len > max_len ) | ||||||
| 			return res; | 			return res; | ||||||
| 		res  += str_copy_nulpad( text, str, len ); | 		res  += c_str_copy_nulpad( text, str, len ); | ||||||
| 		text += res; | 		text += res; | ||||||
|  |  | ||||||
| 		if ( info->width > res ) | 		if ( info->width > res ) | ||||||
| @@ -93,15 +93,15 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha | |||||||
|  |  | ||||||
| 		if ( res + len > max_len ) | 		if ( res + len > max_len ) | ||||||
| 			return res; | 			return res; | ||||||
| 		res += str_copy_nulpad( text, str, len ); | 		res += c_str_copy_nulpad( text, str, len ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( info ) | 	if ( info ) | ||||||
| 	{ | 	{ | ||||||
| 		if ( info->flags & GEN_FMT_UPPER ) | 		if ( info->flags & GEN_FMT_UPPER ) | ||||||
| 			str_to_upper( begin ); | 			c_str_to_upper( begin ); | ||||||
| 		else if ( info->flags & GEN_FMT_LOWER ) | 		else if ( info->flags & GEN_FMT_LOWER ) | ||||||
| 			str_to_lower( begin ); | 			c_str_to_lower( begin ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return res; | 	return res; | ||||||
| @@ -238,7 +238,7 @@ internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is | |||||||
| 	return ( text - text_begin ); | 	return ( text - text_begin ); | ||||||
| } | } | ||||||
|  |  | ||||||
| neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va ) | neverinline ssize c_str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va ) | ||||||
| { | { | ||||||
| 	char const* text_begin = text; | 	char const* text_begin = text; | ||||||
| 	ssize          remaining  = max_len, res; | 	ssize          remaining  = max_len, res; | ||||||
| @@ -310,7 +310,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			info.width = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 )); | 			info.width = scast( s32, c_str_to_i64( fmt, ccast( char**, & fmt), 10 )); | ||||||
| 			if ( info.width != 0 ) | 			if ( info.width != 0 ) | ||||||
| 			{ | 			{ | ||||||
| 				info.flags |= GEN_FMT_WIDTH; | 				info.flags |= GEN_FMT_WIDTH; | ||||||
| @@ -328,7 +328,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis | |||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				info.precision = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 )); | 				info.precision = scast( s32, c_str_to_i64( fmt, ccast( char**, & fmt), 10 )); | ||||||
| 			} | 			} | ||||||
| 			info.flags &= ~GEN_FMT_ZERO; | 			info.flags &= ~GEN_FMT_ZERO; | ||||||
| 		} | 		} | ||||||
| @@ -419,19 +419,20 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis | |||||||
|  |  | ||||||
| 			case 'S': | 			case 'S': | ||||||
| 			{ | 			{ | ||||||
| 				if ( *(fmt + 1) == 'C' ) | 				if ( *(fmt + 1) == 'B' ) | ||||||
| 				{ | 				{ | ||||||
|  |  | ||||||
| 					++ fmt; | 					++ fmt; | ||||||
| 					StrC gen_str   = va_arg( va, StrC); | 					StrBuilder gen_str = { va_arg( va, char*) }; | ||||||
| 					info.precision = gen_str.Len; |  | ||||||
| 					len            = _print_string( text, remaining, &info, gen_str.Ptr ); | 					info.precision = strbuilder_length(gen_str); | ||||||
|  | 					len            = _print_string( text, remaining, &info, gen_str ); | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				String gen_str = { va_arg( va, char*) }; | 				Str gen_str    = va_arg( va, Str); | ||||||
|  | 				info.precision = gen_str.Len; | ||||||
| 				info.precision = string_length(gen_str); | 				len            = _print_string( text, remaining, &info, gen_str.Ptr ); | ||||||
| 				len            = _print_string( text, remaining, &info, gen_str ); |  | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| @@ -531,67 +532,67 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis | |||||||
| 	return ( res >= max_len || res < 0 ) ? -1 : res; | 	return ( res >= max_len || res < 0 ) ? -1 : res; | ||||||
| } | } | ||||||
|  |  | ||||||
| char* str_fmt_buf_va( char const* fmt, va_list va ) | char* c_str_fmt_buf_va( char const* fmt, va_list va ) | ||||||
| { | { | ||||||
| 	local_persist thread_local char buffer[ GEN_PRINTF_MAXLEN ]; | 	local_persist thread_local char buffer[ GEN_PRINTF_MAXLEN ]; | ||||||
| 	str_fmt_va( buffer, size_of( buffer ), fmt, va ); | 	c_str_fmt_va( buffer, size_of( buffer ), fmt, va ); | ||||||
| 	return buffer; | 	return buffer; | ||||||
| } | } | ||||||
|  |  | ||||||
| char* str_fmt_buf( char const* fmt, ... ) | char* c_str_fmt_buf( char const* fmt, ... ) | ||||||
| { | { | ||||||
| 	va_list va; | 	va_list va; | ||||||
| 	char*   str; | 	char*   str; | ||||||
| 	va_start( va, fmt ); | 	va_start( va, fmt ); | ||||||
| 	str = str_fmt_buf_va( fmt, va ); | 	str = c_str_fmt_buf_va( fmt, va ); | ||||||
| 	va_end( va ); | 	va_end( va ); | ||||||
| 	return str; | 	return str; | ||||||
| } | } | ||||||
|  |  | ||||||
| ssize str_fmt_file_va( FileInfo* f, char const* fmt, va_list va ) | ssize c_str_fmt_file_va( FileInfo* f, char const* fmt, va_list va ) | ||||||
| { | { | ||||||
| 	local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ]; | 	local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ]; | ||||||
| 	ssize                              len = str_fmt_va( buf, size_of( buf ), fmt, va ); | 	ssize                              len = c_str_fmt_va( buf, size_of( buf ), fmt, va ); | ||||||
| 	b32                             res = file_write( f, buf, len - 1 );    // NOTE: prevent extra whitespace | 	b32                             res = file_write( f, buf, len - 1 );    // NOTE: prevent extra whitespace | ||||||
| 	return res ? len : -1; | 	return res ? len : -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| ssize str_fmt_file( FileInfo* f, char const* fmt, ... ) | ssize c_str_fmt_file( FileInfo* f, char const* fmt, ... ) | ||||||
| { | { | ||||||
| 	ssize      res; | 	ssize      res; | ||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start( va, fmt ); | 	va_start( va, fmt ); | ||||||
| 	res = str_fmt_file_va( f, fmt, va ); | 	res = c_str_fmt_file_va( f, fmt, va ); | ||||||
| 	va_end( va ); | 	va_end( va ); | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
|  |  | ||||||
| ssize str_fmt( char* str, ssize n, char const* fmt, ... ) | ssize c_str_fmt( char* str, ssize n, char const* fmt, ... ) | ||||||
| { | { | ||||||
| 	ssize      res; | 	ssize      res; | ||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start( va, fmt ); | 	va_start( va, fmt ); | ||||||
| 	res = str_fmt_va( str, n, fmt, va ); | 	res = c_str_fmt_va( str, n, fmt, va ); | ||||||
| 	va_end( va ); | 	va_end( va ); | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
|  |  | ||||||
| ssize str_fmt_out_va( char const* fmt, va_list va ) | ssize c_str_fmt_out_va( char const* fmt, va_list va ) | ||||||
| { | { | ||||||
| 	return str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va ); | 	return c_str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va ); | ||||||
| } | } | ||||||
|  |  | ||||||
| ssize str_fmt_out_err_va( char const* fmt, va_list va ) | ssize c_str_fmt_out_err_va( char const* fmt, va_list va ) | ||||||
| { | { | ||||||
| 	return str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va ); | 	return c_str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va ); | ||||||
| } | } | ||||||
|  |  | ||||||
| ssize str_fmt_out_err( char const* fmt, ... ) | ssize c_str_fmt_out_err( char const* fmt, ... ) | ||||||
| { | { | ||||||
| 	ssize      res; | 	ssize      res; | ||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start( va, fmt ); | 	va_start( va, fmt ); | ||||||
| 	res = str_fmt_out_err_va( fmt, va ); | 	res = c_str_fmt_out_err_va( fmt, va ); | ||||||
| 	va_end( va ); | 	va_end( va ); | ||||||
| 	return res; | 	return res; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| #ifdef GEN_INTELLISENSE_DIRECTIVES | #ifdef GEN_INTELLISENSE_DIRECTIVES | ||||||
| #	pragma once | #	pragma once | ||||||
| #	include "string_ops.hpp" | #	include "strbuilder_ops.hpp" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #pragma region Printing | #pragma region Printing | ||||||
| @@ -13,15 +13,15 @@ typedef struct FileInfo FileInfo; | |||||||
| typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN]; | typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN]; | ||||||
|  |  | ||||||
| // NOTE: A locally persisting buffer is used internally | // NOTE: A locally persisting buffer is used internally | ||||||
| char*  str_fmt_buf       ( char const* fmt, ... ); | char*  c_str_fmt_buf       ( char const* fmt, ... ); | ||||||
| char*  str_fmt_buf_va    ( char const* fmt, va_list va ); | char*  c_str_fmt_buf_va    ( char const* fmt, va_list va ); | ||||||
| ssize  str_fmt           ( char* str, ssize n, char const* fmt, ... ); | ssize  c_str_fmt           ( char* str, ssize n, char const* fmt, ... ); | ||||||
| ssize  str_fmt_va        ( char* str, ssize n, char const* fmt, va_list va ); | ssize  c_str_fmt_va        ( char* str, ssize n, char const* fmt, va_list va ); | ||||||
| ssize  str_fmt_out_va    ( char const* fmt, va_list va ); | ssize  c_str_fmt_out_va    ( char const* fmt, va_list va ); | ||||||
| ssize  str_fmt_out_err   ( char const* fmt, ... ); | ssize  c_str_fmt_out_err   ( char const* fmt, ... ); | ||||||
| ssize  str_fmt_out_err_va( char const* fmt, va_list va ); | ssize  c_str_fmt_out_err_va( char const* fmt, va_list va ); | ||||||
| ssize  str_fmt_file      ( FileInfo* f, char const* fmt, ... ); | ssize  c_str_fmt_file      ( FileInfo* f, char const* fmt, ... ); | ||||||
| ssize  str_fmt_file_va   ( FileInfo* f, char const* fmt, va_list va ); | ssize  c_str_fmt_file_va   ( FileInfo* f, char const* fmt, va_list va ); | ||||||
|  |  | ||||||
| constexpr | constexpr | ||||||
| char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; | char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; | ||||||
| @@ -33,7 +33,7 @@ ssize log_fmt(char const* fmt, ...) | |||||||
| 	va_list va; | 	va_list va; | ||||||
|  |  | ||||||
| 	va_start(va, fmt); | 	va_start(va, fmt); | ||||||
| 	res = str_fmt_out_va(fmt, va); | 	res = c_str_fmt_out_va(fmt, va); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| 	return res; | 	return res; | ||||||
|   | |||||||
| @@ -13,9 +13,9 @@ | |||||||
| #			define _printf_err( fmt, ... )   fprintf( stderr, fmt, __VA_ARGS__ ) | #			define _printf_err( fmt, ... )   fprintf( stderr, fmt, __VA_ARGS__ ) | ||||||
| #			define _printf_err_va( fmt, va ) vfprintf( stderr, fmt, va ) | #			define _printf_err_va( fmt, va ) vfprintf( stderr, fmt, va ) | ||||||
| #		else | #		else | ||||||
| #			define _strlen                   str_len | #			define _strlen                   c_str_len | ||||||
| #			define _printf_err( fmt, ... )   str_fmt_out_err( fmt, __VA_ARGS__ ) | #			define _printf_err( fmt, ... )   c_str_fmt_out_err( fmt, __VA_ARGS__ ) | ||||||
| #			define _printf_err_va( fmt, va ) str_fmt_out_err_va( fmt, va ) | #			define _printf_err_va( fmt, va ) c_str_fmt_out_err_va( fmt, va ) | ||||||
| #		endif | #		endif | ||||||
| #	endif | #	endif | ||||||
| # | # | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ ssize _scan_zpl_i64( const char* text, s32 base, s64* value ) | |||||||
| 		text++; | 		text++; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ( base == 16 && str_compare_len( text, "0x", 2 ) == 0 ) | 	if ( base == 16 && c_str_compare_len( text, "0x", 2 ) == 0 ) | ||||||
| 		text += 2; | 		text += 2; | ||||||
|  |  | ||||||
| 	for ( ;; ) | 	for ( ;; ) | ||||||
| @@ -53,14 +53,14 @@ global const char _num_to_char_table[] = | |||||||
| 	"abcdefghijklmnopqrstuvwxyz" | 	"abcdefghijklmnopqrstuvwxyz" | ||||||
| 	"@$"; | 	"@$"; | ||||||
|  |  | ||||||
| s64 str_to_i64( const char* str, char** end_ptr, s32 base ) | s64 c_str_to_i64( const char* str, char** end_ptr, s32 base ) | ||||||
| { | { | ||||||
| 	ssize  len; | 	ssize  len; | ||||||
| 	s64 value; | 	s64 value; | ||||||
|  |  | ||||||
| 	if ( ! base ) | 	if ( ! base ) | ||||||
| 	{ | 	{ | ||||||
| 		if ( ( str_len( str ) > 2 ) && ( str_compare_len( str, "0x", 2 ) == 0 ) ) | 		if ( ( c_str_len( str ) > 2 ) && ( c_str_compare_len( str, "0x", 2 ) == 0 ) ) | ||||||
| 			base = 16; | 			base = 16; | ||||||
| 		else | 		else | ||||||
| 			base = 10; | 			base = 10; | ||||||
| @@ -100,7 +100,7 @@ void i64_to_str( s64 value, char* string, s32 base ) | |||||||
| 	if ( negative ) | 	if ( negative ) | ||||||
| 		*buf++ = '-'; | 		*buf++ = '-'; | ||||||
| 	*buf = '\0'; | 	*buf = '\0'; | ||||||
| 	str_reverse( string ); | 	c_str_reverse( string ); | ||||||
| } | } | ||||||
|  |  | ||||||
| void u64_to_str( u64 value, char* string, s32 base ) | void u64_to_str( u64 value, char* string, s32 base ) | ||||||
| @@ -121,10 +121,10 @@ void u64_to_str( u64 value, char* string, s32 base ) | |||||||
| 	} | 	} | ||||||
| 	*buf = '\0'; | 	*buf = '\0'; | ||||||
|  |  | ||||||
| 	str_reverse( string ); | 	c_str_reverse( string ); | ||||||
| } | } | ||||||
|  |  | ||||||
| f64 str_to_f64( const char* str, char** end_ptr ) | f64 c_str_to_f64( const char* str, char** end_ptr ) | ||||||
| { | { | ||||||
| 	f64 result, value, sign, scale; | 	f64 result, value, sign, scale; | ||||||
| 	s32 frac; | 	s32 frac; | ||||||
|   | |||||||
| @@ -18,25 +18,25 @@ char  char_to_upper( char c ); | |||||||
| s32  digit_to_int( char c ); | s32  digit_to_int( char c ); | ||||||
| s32  hex_digit_to_int( char c ); | s32  hex_digit_to_int( char c ); | ||||||
|  |  | ||||||
| s32         str_compare( const char* s1, const char* s2 ); | s32         c_str_compare( const char* s1, const char* s2 ); | ||||||
| s32         str_compare_len( const char* s1, const char* s2, ssize len ); | s32         c_str_compare_len( const char* s1, const char* s2, ssize len ); | ||||||
| char*       str_copy( char* dest, const char* source, ssize len ); | char*       c_str_copy( char* dest, const char* source, ssize len ); | ||||||
| ssize       str_copy_nulpad( char* dest, const char* source, ssize len ); | ssize       c_str_copy_nulpad( char* dest, const char* source, ssize len ); | ||||||
| ssize       str_len( const char* str ); | ssize       c_str_len( const char* str ); | ||||||
| ssize       str_len_capped( const char* str, ssize max_len ); | ssize       c_str_len_capped( const char* str, ssize max_len ); | ||||||
| char*       str_reverse( char* str );    // NOTE: ASCII only | char*       c_str_reverse( char* str );    // NOTE: ASCII only | ||||||
| char const* str_skip( char const* str, char c ); | char const* c_str_skip( char const* str, char c ); | ||||||
| char const* str_skip_any( char const* str, char const* char_list ); | char const* c_str_skip_any( char const* str, char const* char_list ); | ||||||
| char const* str_trim( char const* str, b32 catch_newline ); | char const* c_str_trim( char const* str, b32 catch_newline ); | ||||||
|  |  | ||||||
| // NOTE: ASCII only | // NOTE: ASCII only | ||||||
| void str_to_lower( char* str ); | void c_str_to_lower( char* str ); | ||||||
| void str_to_upper( char* str ); | void c_str_to_upper( char* str ); | ||||||
|  |  | ||||||
| s64  str_to_i64( const char* str, char** end_ptr, s32 base ); | s64  c_str_to_i64( const char* str, char** end_ptr, s32 base ); | ||||||
| void i64_to_str( s64 value, char* string, s32 base ); | void i64_to_str( s64 value, char* string, s32 base ); | ||||||
| void u64_to_str( u64 value, char* string, s32 base ); | void u64_to_str( u64 value, char* string, s32 base ); | ||||||
| f64  str_to_f64( const char* str, char** end_ptr ); | f64  c_str_to_f64( const char* str, char** end_ptr ); | ||||||
|  |  | ||||||
| inline | inline | ||||||
| const char* char_first_occurence( const char* s, char c ) | const char* char_first_occurence( const char* s, char c ) | ||||||
| @@ -122,7 +122,7 @@ s32 hex_digit_to_int( char c ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| s32 str_compare( const char* s1, const char* s2 ) | s32 c_str_compare( const char* s1, const char* s2 ) | ||||||
| { | { | ||||||
| 	while ( *s1 && ( *s1 == *s2 ) ) | 	while ( *s1 && ( *s1 == *s2 ) ) | ||||||
| 	{ | 	{ | ||||||
| @@ -132,7 +132,7 @@ s32 str_compare( const char* s1, const char* s2 ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| s32 str_compare_len( const char* s1, const char* s2, ssize len ) | s32 c_str_compare_len( const char* s1, const char* s2, ssize len ) | ||||||
| { | { | ||||||
| 	for ( ; len > 0; s1++, s2++, len-- ) | 	for ( ; len > 0; s1++, s2++, len-- ) | ||||||
| 	{ | 	{ | ||||||
| @@ -145,7 +145,7 @@ s32 str_compare_len( const char* s1, const char* s2, ssize len ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| char* str_copy( char* dest, const char* source, ssize len ) | char* c_str_copy( char* dest, const char* source, ssize len ) | ||||||
| { | { | ||||||
| 	GEN_ASSERT_NOT_NULL( dest ); | 	GEN_ASSERT_NOT_NULL( dest ); | ||||||
| 	if ( source ) | 	if ( source ) | ||||||
| @@ -166,7 +166,7 @@ char* str_copy( char* dest, const char* source, ssize len ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| ssize str_copy_nulpad( char* dest, const char* source, ssize len ) | ssize c_str_copy_nulpad( char* dest, const char* source, ssize len ) | ||||||
| { | { | ||||||
| 	ssize result = 0; | 	ssize result = 0; | ||||||
| 	GEN_ASSERT_NOT_NULL( dest ); | 	GEN_ASSERT_NOT_NULL( dest ); | ||||||
| @@ -191,7 +191,7 @@ ssize str_copy_nulpad( char* dest, const char* source, ssize len ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| ssize str_len( const char* str ) | ssize c_str_len( const char* str ) | ||||||
| { | { | ||||||
| 	if ( str == NULL ) | 	if ( str == NULL ) | ||||||
| 	{ | 	{ | ||||||
| @@ -204,7 +204,7 @@ ssize str_len( const char* str ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| ssize str_len_capped( const char* str, ssize max_len ) | ssize c_str_len_capped( const char* str, ssize max_len ) | ||||||
| { | { | ||||||
| 	const char* end = rcast(const char*, mem_find( str, 0, max_len )); | 	const char* end = rcast(const char*, mem_find( str, 0, max_len )); | ||||||
| 	if ( end ) | 	if ( end ) | ||||||
| @@ -213,9 +213,9 @@ ssize str_len_capped( const char* str, ssize max_len ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| char* str_reverse( char* str ) | char* c_str_reverse( char* str ) | ||||||
| { | { | ||||||
| 	ssize    len  = str_len( str ); | 	ssize    len  = c_str_len( str ); | ||||||
| 	char* a    = str + 0; | 	char* a    = str + 0; | ||||||
| 	char* b    = str + len - 1; | 	char* b    = str + len - 1; | ||||||
| 	len       /= 2; | 	len       /= 2; | ||||||
| @@ -228,7 +228,7 @@ char* str_reverse( char* str ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| char const* str_skip( char const* str, char c ) | char const* c_str_skip( char const* str, char c ) | ||||||
| { | { | ||||||
| 	while ( *str && *str != c ) | 	while ( *str && *str != c ) | ||||||
| 	{ | 	{ | ||||||
| @@ -238,20 +238,20 @@ char const* str_skip( char const* str, char c ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| char const* str_skip_any( char const* str, char const* char_list ) | char const* c_str_skip_any( char const* str, char const* char_list ) | ||||||
| { | { | ||||||
| 	char const* closest_ptr     = rcast( char const*, pointer_add_const( rcast(mem_ptr_const, str), str_len( str ) )); | 	char const* closest_ptr     = rcast( char const*, pointer_add_const( rcast(mem_ptr_const, str), c_str_len( str ) )); | ||||||
| 	ssize       char_list_count = str_len( char_list ); | 	ssize       char_list_count = c_str_len( char_list ); | ||||||
| 	for ( ssize i = 0; i < char_list_count; i++ ) | 	for ( ssize i = 0; i < char_list_count; i++ ) | ||||||
| 	{ | 	{ | ||||||
| 		char const* p = str_skip( str, char_list[ i ] ); | 		char const* p = c_str_skip( str, char_list[ i ] ); | ||||||
| 		closest_ptr   = min( closest_ptr, p ); | 		closest_ptr   = min( closest_ptr, p ); | ||||||
| 	} | 	} | ||||||
| 	return closest_ptr; | 	return closest_ptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| char const* str_trim( char const* str, b32 catch_newline ) | char const* c_str_trim( char const* str, b32 catch_newline ) | ||||||
| { | { | ||||||
| 	while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) ) | 	while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) ) | ||||||
| 	{ | 	{ | ||||||
| @@ -261,7 +261,7 @@ char const* str_trim( char const* str, b32 catch_newline ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void str_to_lower( char* str ) | void c_str_to_lower( char* str ) | ||||||
| { | { | ||||||
| 	if ( ! str ) | 	if ( ! str ) | ||||||
| 		return; | 		return; | ||||||
| @@ -273,7 +273,7 @@ void str_to_lower( char* str ) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void str_to_upper( char* str ) | void c_str_to_upper( char* str ) | ||||||
| { | { | ||||||
| 	if ( ! str ) | 	if ( ! str ) | ||||||
| 		return; | 		return; | ||||||
|   | |||||||
| @@ -3,27 +3,27 @@ | |||||||
| #	include "hashing.cpp" | #	include "hashing.cpp" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #pragma region String | #pragma region StrBuilder | ||||||
|  |  | ||||||
| String string_make_length( AllocatorInfo allocator, char const* str, ssize length ) | StrBuilder strbuilder_make_length( AllocatorInfo allocator, char const* str, ssize length ) | ||||||
| { | { | ||||||
| 	ssize const header_size = sizeof( StringHeader ); | 	ssize const header_size = sizeof( StrBuilderHeader ); | ||||||
|  |  | ||||||
| 	s32   alloc_size = header_size + length + 1; | 	s32   alloc_size = header_size + length + 1; | ||||||
| 	void* allocation = alloc( allocator, alloc_size ); | 	void* allocation = alloc( allocator, alloc_size ); | ||||||
|  |  | ||||||
| 	if ( allocation == nullptr ) { | 	if ( allocation == nullptr ) { | ||||||
| 		String null_string = {nullptr}; | 		StrBuilder null_string = {nullptr}; | ||||||
| 		return null_string; | 		return null_string; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	StringHeader* | 	StrBuilderHeader* | ||||||
| 	header = rcast(StringHeader*, allocation); | 	header = rcast(StrBuilderHeader*, allocation); | ||||||
| 	header->Allocator = allocator; | 	header->Allocator = allocator; | ||||||
| 	header->Capacity  = length; | 	header->Capacity  = length; | ||||||
| 	header->Length    = length; | 	header->Length    = length; | ||||||
|  |  | ||||||
| 	String  result = { rcast( char*, allocation) + header_size }; | 	StrBuilder  result = { rcast( char*, allocation) + header_size }; | ||||||
|  |  | ||||||
| 	if ( length && str ) | 	if ( length && str ) | ||||||
| 		mem_copy( result, str, length ); | 		mem_copy( result, str, length ); | ||||||
| @@ -35,27 +35,27 @@ String string_make_length( AllocatorInfo allocator, char const* str, ssize lengt | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| String string_make_reserve( AllocatorInfo allocator, ssize capacity ) | StrBuilder strbuilder_make_reserve( AllocatorInfo allocator, ssize capacity ) | ||||||
| { | { | ||||||
| 	ssize const header_size = sizeof( StringHeader ); | 	ssize const header_size = sizeof( StrBuilderHeader ); | ||||||
|  |  | ||||||
| 	s32   alloc_size = header_size + capacity + 1; | 	s32   alloc_size = header_size + capacity + 1; | ||||||
| 	void* allocation = alloc( allocator, alloc_size ); | 	void* allocation = alloc( allocator, alloc_size ); | ||||||
|  |  | ||||||
| 	if ( allocation == nullptr ) { | 	if ( allocation == nullptr ) { | ||||||
| 		String null_string = {nullptr}; | 		StrBuilder null_string = {nullptr}; | ||||||
| 		return null_string; | 		return null_string; | ||||||
| 	} | 	} | ||||||
| 	mem_set( allocation, 0, alloc_size ); | 	mem_set( allocation, 0, alloc_size ); | ||||||
|  |  | ||||||
| 	StringHeader* | 	StrBuilderHeader* | ||||||
| 	header            = rcast(StringHeader*, allocation); | 	header            = rcast(StrBuilderHeader*, allocation); | ||||||
| 	header->Allocator = allocator; | 	header->Allocator = allocator; | ||||||
| 	header->Capacity  = capacity; | 	header->Capacity  = capacity; | ||||||
| 	header->Length    = 0; | 	header->Length    = 0; | ||||||
|  |  | ||||||
| 	String result = { rcast(char*, allocation) + header_size }; | 	StrBuilder result = { rcast(char*, allocation) + header_size }; | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| #pragma endregion String | #pragma endregion StrBuilder | ||||||
|   | |||||||
| @@ -5,61 +5,61 @@ | |||||||
|  |  | ||||||
| #pragma region Strings | #pragma region Strings | ||||||
|  |  | ||||||
| struct StrC; | struct Str; | ||||||
|  |  | ||||||
| StrC        to_strc_from_c_str       (char const* bad_string); | Str         to_str_from_c_str       (char const* bad_string); | ||||||
| bool        strc_are_equal           (StrC lhs, StrC rhs); | bool        str_are_equal           (Str lhs, Str rhs); | ||||||
| char const* strc_back                (StrC str); | char const* str_back                (Str str); | ||||||
| bool        strc_contains            (StrC str, StrC substring); | bool        str_contains            (Str str, Str substring); | ||||||
| StrC        strc_duplicate           (StrC str, AllocatorInfo allocator); | Str         str_duplicate           (Str str, AllocatorInfo allocator); | ||||||
| b32         strc_starts_with         (StrC str, StrC substring); | b32         str_starts_with         (Str str, Str substring); | ||||||
| StrC        strc_visualize_whitespace(StrC str, AllocatorInfo allocator); | Str         str_visualize_whitespace(Str str, AllocatorInfo allocator); | ||||||
|  |  | ||||||
| // Constant string with length. | // Constant string with length. | ||||||
| struct StrC | struct Str | ||||||
| { | { | ||||||
| 	ssize       Len; |  | ||||||
| 	char const* Ptr; | 	char const* Ptr; | ||||||
|  | 	ssize       Len; | ||||||
|  |  | ||||||
| #if GEN_COMPILER_CPP | #if GEN_COMPILER_CPP | ||||||
| 	forceinline operator char const* ()               const { return Ptr; } | 	forceinline operator char const* ()               const { return Ptr; } | ||||||
| 	forceinline char const& operator[]( ssize index ) const { return Ptr[index]; } | 	forceinline char const& operator[]( ssize index ) const { return Ptr[index]; } | ||||||
|  |  | ||||||
| #if ! GEN_C_LIKE_CPP | #if ! GEN_C_LIKE_CPP | ||||||
| 	forceinline bool        is_equal            (StrC rhs)                const { return strc_are_equal(* this, rhs); } | 	forceinline bool        is_equal            (Str rhs)                 const { return str_are_equal(* this, rhs); } | ||||||
| 	forceinline char const* back                ()                        const { return strc_back(* this); } | 	forceinline char const* back                ()                        const { return str_back(* this); } | ||||||
| 	forceinline bool        contains            (StrC substring)          const { return strc_contains(* this, substring); } | 	forceinline bool        contains            (Str substring)           const { return str_contains(* this, substring); } | ||||||
| 	forceinline StrC        duplicate           (AllocatorInfo allocator) const { return strc_duplicate(* this, allocator); } | 	forceinline Str         duplicate           (AllocatorInfo allocator) const { return str_duplicate(* this, allocator); } | ||||||
| 	forceinline b32         starts_with         (StrC substring)          const { return strc_starts_with(* this, substring); } | 	forceinline b32         starts_with         (Str substring)           const { return str_starts_with(* this, substring); } | ||||||
| 	forceinline StrC        visualize_whitespace(AllocatorInfo allocator) const { return strc_visualize_whitespace(* this, allocator); } | 	forceinline Str         visualize_whitespace(AllocatorInfo allocator) const { return str_visualize_whitespace(* this, allocator); } | ||||||
| #endif | #endif | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) ) | #define cast_to_str( str ) * rcast( Str*, (str) - sizeof(ssize) ) | ||||||
|  |  | ||||||
| #ifndef txt | #ifndef txt | ||||||
| #	if GEN_COMPILER_CPP | #	if GEN_COMPILER_CPP | ||||||
| #		define txt( text )          StrC { sizeof( text ) - 1, ( text ) } | #		define txt( text )          Str { ( text ), sizeof( text ) - 1 } | ||||||
| #	else | #	else | ||||||
| #		define txt( text )         (StrC){ sizeof( text ) - 1, ( text ) } | #		define txt( text )         (Str){ ( text ), sizeof( text ) - 1 } | ||||||
| #	endif | #	endif | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| GEN_API_C_BEGIN | GEN_API_C_BEGIN | ||||||
| forceinline char const* strc_begin(StrC str)                   { return str.Ptr; } | forceinline char const* str_begin(Str str)                   { return str.Ptr; } | ||||||
| forceinline char const* strc_end  (StrC str)                   { return str.Ptr + str.Len; } | forceinline char const* str_end  (Str str)                   { return str.Ptr + str.Len; } | ||||||
| forceinline char const* strc_next (StrC str, char const* iter) { return iter + 1; } | forceinline char const* str_next (Str str, char const* iter) { return iter + 1; } | ||||||
| GEN_API_C_END | GEN_API_C_END | ||||||
|  |  | ||||||
| #if GEN_COMPILER_CPP | #if GEN_COMPILER_CPP | ||||||
| forceinline char const* begin(StrC str)                   { return str.Ptr; } | forceinline char const* begin(Str str)                   { return str.Ptr; } | ||||||
| forceinline char const* end  (StrC str)                   { return str.Ptr + str.Len; } | forceinline char const* end  (Str str)                   { return str.Ptr + str.Len; } | ||||||
| forceinline char const* next (StrC str, char const* iter) { return iter + 1; } | forceinline char const* next (Str str, char const* iter) { return iter + 1; } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool strc_are_equal(StrC lhs, StrC rhs) | bool str_are_equal(Str lhs, Str rhs) | ||||||
| { | { | ||||||
| 	if (lhs.Len != rhs.Len) | 	if (lhs.Len != rhs.Len) | ||||||
| 		return false; | 		return false; | ||||||
| @@ -72,12 +72,12 @@ bool strc_are_equal(StrC lhs, StrC rhs) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| char const* strc_back(StrC str) { | char const* str_back(Str str) { | ||||||
| 	return & str.Ptr[str.Len - 1]; | 	return & str.Ptr[str.Len - 1]; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool strc_contains(StrC str, StrC substring) | bool str_contains(Str str, Str substring) | ||||||
| { | { | ||||||
| 	if (substring.Len > str.Len) | 	if (substring.Len > str.Len) | ||||||
| 		return false; | 		return false; | ||||||
| @@ -86,97 +86,97 @@ bool strc_contains(StrC str, StrC substring) | |||||||
| 	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_len(str.Ptr + idx, substring.Ptr, sub_len) == 0) | 		if (c_str_compare_len(str.Ptr + idx, substring.Ptr, sub_len) == 0) | ||||||
| 			return true; | 			return true; | ||||||
| 	} | 	} | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| b32 strc_starts_with(StrC str, StrC substring) { | b32 str_starts_with(Str str, Str substring) { | ||||||
| 	if (substring.Len > str.Len) | 	if (substring.Len > str.Len) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	b32 result = str_compare_len(str.Ptr, substring.Ptr, substring.Len) == 0; | 	b32 result = c_str_compare_len(str.Ptr, substring.Ptr, substring.Len) == 0; | ||||||
| 		return result; | 		return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| StrC to_strc_from_c_str( char const* bad_str ) { | Str to_str_from_c_str( char const* bad_str ) { | ||||||
| 	StrC result = { str_len( bad_str ), bad_str }; | 	Str result = { bad_str, c_str_len( bad_str ) }; | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Dynamic String | // Dynamic StrBuilder | ||||||
| // This is directly based off the ZPL string api. | // This is directly based off the ZPL string api. | ||||||
| // They used a header pattern | // They used a header pattern | ||||||
| // I kept it for simplicty of porting but its not necessary to keep it that way. | // I kept it for simplicty of porting but its not necessary to keep it that way. | ||||||
| #pragma region String | #pragma region StrBuilder | ||||||
| struct StringHeader; | struct StrBuilderHeader; | ||||||
|  |  | ||||||
| #if GEN_COMPILER_C | #if GEN_COMPILER_C | ||||||
| typedef char* String; | typedef char* StrBuilder; | ||||||
| #else | #else | ||||||
| struct String; | struct StrBuilder; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| forceinline usize string_grow_formula(usize value); | forceinline usize strbuilder_grow_formula(usize value); | ||||||
|  |  | ||||||
| String        string_make_c_str          (AllocatorInfo allocator, char const*  str); | StrBuilder        strbuilder_make_c_str          (AllocatorInfo allocator, char const*  str); | ||||||
| String        string_make_strc           (AllocatorInfo allocator, StrC         str); | StrBuilder        strbuilder_make_str            (AllocatorInfo allocator, Str         str); | ||||||
| String        string_make_reserve        (AllocatorInfo allocator, ssize        capacity); | StrBuilder        strbuilder_make_reserve        (AllocatorInfo allocator, ssize        capacity); | ||||||
| String        string_make_length         (AllocatorInfo allocator, char const*  str,   ssize length); | StrBuilder        strbuilder_make_length         (AllocatorInfo allocator, char const*  str,   ssize length); | ||||||
| String        string_fmt                 (AllocatorInfo allocator, char*        buf,   ssize buf_size,  char const* fmt, ...); | StrBuilder        strbuilder_fmt                 (AllocatorInfo allocator, char*        buf,   ssize buf_size,  char const* fmt, ...); | ||||||
| String        string_fmt_buf             (AllocatorInfo allocator, char const*  fmt, ...); | StrBuilder        strbuilder_fmt_buf             (AllocatorInfo allocator, char const*  fmt, ...); | ||||||
| String        string_join                (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue); | StrBuilder        strbuilder_join                (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue); | ||||||
| bool          string_are_equal           (String const lhs, String const rhs); | bool              strbuilder_are_equal           (StrBuilder const lhs, StrBuilder const rhs); | ||||||
| bool          string_are_equal_strc      (String const lhs, StrC rhs); | bool              strbuilder_are_equal_str       (StrBuilder const lhs, Str rhs); | ||||||
| bool          string_make_space_for      (String*      str, char const*  to_append, ssize add_len); | bool              strbuilder_make_space_for      (StrBuilder*      str, char const*  to_append, ssize add_len); | ||||||
| bool          string_append_char         (String*      str, char         c); | bool              strbuilder_append_char         (StrBuilder*      str, char         c); | ||||||
| bool          string_append_c_str        (String*      str, char const*  str_to_append); | bool              strbuilder_append_c_str        (StrBuilder*      str, char const*  c_str_to_append); | ||||||
| bool          string_append_c_str_len    (String*      str, char const*  str_to_append, ssize length); | bool              strbuilder_append_c_str_len    (StrBuilder*      str, char const*  c_str_to_append, ssize length); | ||||||
| bool          string_append_strc         (String*      str, StrC         str_to_append); | bool              strbuilder_append_str          (StrBuilder*      str, Str         c_str_to_append); | ||||||
| bool          string_append_string       (String*      str, String const other); | bool              strbuilder_append_string       (StrBuilder*      str, StrBuilder const other); | ||||||
| bool          string_append_fmt          (String*      str, char const*  fmt, ...); | bool              strbuilder_append_fmt          (StrBuilder*      str, char const*  fmt, ...); | ||||||
| ssize         string_avail_space         (String const str); | ssize             strbuilder_avail_space         (StrBuilder const str); | ||||||
| char*         string_back                (String       str); | char*             strbuilder_back                (StrBuilder       str); | ||||||
| bool          string_contains_strc       (String const str, StrC         substring); | bool              strbuilder_contains_str        (StrBuilder const str, Str         substring); | ||||||
| bool          string_contains_string     (String const str, String const substring); | bool              strbuilder_contains_string     (StrBuilder const str, StrBuilder const substring); | ||||||
| ssize         string_capacity            (String const str); | ssize             strbuilder_capacity            (StrBuilder const str); | ||||||
| void          string_clear               (String       str); | void              strbuilder_clear               (StrBuilder       str); | ||||||
| String        string_duplicate           (String const str, AllocatorInfo allocator); | StrBuilder        strbuilder_duplicate           (StrBuilder const str, AllocatorInfo allocator); | ||||||
| void          string_free                (String*      str); | void              strbuilder_free                (StrBuilder*      str); | ||||||
| StringHeader* string_get_header          (String       str); | StrBuilderHeader* strbuilder_get_header          (StrBuilder       str); | ||||||
| ssize         string_length              (String const str); | ssize             strbuilder_length              (StrBuilder const str); | ||||||
| b32           string_starts_with_strc    (String const str, StrC   substring); | b32               strbuilder_starts_with_str     (StrBuilder const str, Str   substring); | ||||||
| b32           string_starts_with_string  (String const str, String substring); | b32               strbuilder_starts_with_string  (StrBuilder const str, StrBuilder substring); | ||||||
| void          string_skip_line           (String       str); | void              strbuilder_skip_line           (StrBuilder       str); | ||||||
| void          string_strip_space         (String       str); | void              strbuilder_strip_space         (StrBuilder       str); | ||||||
| StrC          string_to_strc             (String       str); | Str               strbuilder_to_str              (StrBuilder       str); | ||||||
| void          string_trim                (String       str, char const* cut_set); | void              strbuilder_trim                (StrBuilder       str, char const* cut_set); | ||||||
| void          string_trim_space          (String       str); | void              strbuilder_trim_space          (StrBuilder       str); | ||||||
| String        string_visualize_whitespace(String const str); | StrBuilder        strbuilder_visualize_whitespace(StrBuilder const str); | ||||||
|  |  | ||||||
| struct StringHeader { | struct StrBuilderHeader { | ||||||
| 	AllocatorInfo Allocator; | 	AllocatorInfo Allocator; | ||||||
| 	ssize         Capacity; | 	ssize         Capacity; | ||||||
| 	ssize         Length; | 	ssize         Length; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #if GEN_COMPILER_CPP | #if GEN_COMPILER_CPP | ||||||
| struct String | struct StrBuilder | ||||||
| { | { | ||||||
| 	char* Data; | 	char* Data; | ||||||
|  |  | ||||||
| 	forceinline operator char*()             { return Data; } | 	forceinline operator char*()             { return Data; } | ||||||
| 	forceinline operator char const*() const { return Data; } | 	forceinline operator char const*() const { return Data; } | ||||||
| 	forceinline operator StrC()        const { return { string_length(* this), Data }; } | 	forceinline operator Str()         const { return { Data, strbuilder_length(* this) }; } | ||||||
|  |  | ||||||
| 	String const& operator=(String const& other) const { | 	StrBuilder const& operator=(StrBuilder const& other) const { | ||||||
| 		if (this == &other) | 		if (this == &other) | ||||||
| 			return *this; | 			return *this; | ||||||
|  |  | ||||||
| 		String* this_ = ccast(String*, this); | 		StrBuilder* this_ = ccast(StrBuilder*, this); | ||||||
| 		this_->Data = other.Data; | 		this_->Data = other.Data; | ||||||
|  |  | ||||||
| 		return *this; | 		return *this; | ||||||
| @@ -185,69 +185,69 @@ struct String | |||||||
| 	forceinline char&       operator[](ssize index)       { return Data[index]; } | 	forceinline char&       operator[](ssize index)       { return Data[index]; } | ||||||
| 	forceinline char const& operator[](ssize index) const { return Data[index]; } | 	forceinline char const& operator[](ssize index) const { return Data[index]; } | ||||||
|  |  | ||||||
| 	       forceinline bool operator==(std::nullptr_t) const             { return     Data == nullptr; } | 	       forceinline bool operator==(std::nullptr_t) const                 { return     Data == nullptr; } | ||||||
| 	       forceinline bool operator!=(std::nullptr_t) const             { return     Data != nullptr; } | 	       forceinline bool operator!=(std::nullptr_t) const                 { return     Data != nullptr; } | ||||||
| 	friend forceinline bool operator==(std::nullptr_t, const String str) { return str.Data == nullptr; } | 	friend forceinline bool operator==(std::nullptr_t, const StrBuilder str) { return str.Data == nullptr; } | ||||||
| 	friend forceinline bool operator!=(std::nullptr_t, const String str) { return str.Data != nullptr; } | 	friend forceinline bool operator!=(std::nullptr_t, const StrBuilder str) { return str.Data != nullptr; } | ||||||
|  |  | ||||||
| #if ! GEN_C_LIKE_CPP | #if ! GEN_C_LIKE_CPP | ||||||
| 	forceinline char* begin() const { return Data; } | 	forceinline char* begin() const { return Data; } | ||||||
| 	forceinline char* end()   const { return Data + string_length(* this); } | 	forceinline char* end()   const { return Data + strbuilder_length(* this); } | ||||||
|  |  | ||||||
| #pragma region Member Mapping | #pragma region Member Mapping | ||||||
| 	forceinline static String make(AllocatorInfo allocator, char const* str)                { return string_make_c_str(allocator, str); } | 	forceinline static StrBuilder make(AllocatorInfo allocator, char const* str)                { return strbuilder_make_c_str(allocator, str); } | ||||||
| 	forceinline static String make(AllocatorInfo allocator, StrC str)                       { return string_make_strc(allocator, str); } | 	forceinline static StrBuilder make(AllocatorInfo allocator, Str str)                        { return strbuilder_make_str(allocator, str); } | ||||||
| 	forceinline static String make_reserve(AllocatorInfo allocator, ssize cap)              { return string_make_reserve(allocator, cap); } | 	forceinline static StrBuilder make_reserve(AllocatorInfo allocator, ssize cap)              { return strbuilder_make_reserve(allocator, cap); } | ||||||
| 	forceinline static String make_length(AllocatorInfo a, char const* s, ssize l)          { return string_make_length(a, s, l); } | 	forceinline static StrBuilder make_length(AllocatorInfo a, char const* s, ssize l)          { return strbuilder_make_length(a, s, l); } | ||||||
| 	forceinline static String join(AllocatorInfo a, char const** p, ssize n, char const* g) { return string_join(a, p, n, g); } | 	forceinline static StrBuilder join(AllocatorInfo a, char const** p, ssize n, char const* g) { return strbuilder_join(a, p, n, g); } | ||||||
| 	forceinline static usize  grow_formula(usize value)                                     { return string_grow_formula(value); } | 	forceinline static usize      grow_formula(usize value)                                     { return strbuilder_grow_formula(value); } | ||||||
|  |  | ||||||
| 	static | 	static | ||||||
| 	String fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) { | 	StrBuilder fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) { | ||||||
| 		va_list va; | 		va_list va; | ||||||
| 		va_start(va, fmt); | 		va_start(va, fmt); | ||||||
| 		ssize res = str_fmt_va(buf, buf_size, fmt, va) - 1; | 		ssize res = c_str_fmt_va(buf, buf_size, fmt, va) - 1; | ||||||
| 		va_end(va); | 		va_end(va); | ||||||
| 		return string_make_length(allocator, buf, res); | 		return strbuilder_make_length(allocator, buf, res); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	static | 	static | ||||||
| 	String fmt_buf(AllocatorInfo allocator, char const* fmt, ...) { | 	StrBuilder fmt_buf(AllocatorInfo allocator, char const* fmt, ...) { | ||||||
| 		local_persist thread_local | 		local_persist thread_local | ||||||
| 		char buf[GEN_PRINTF_MAXLEN] = { 0 }; | 		char buf[GEN_PRINTF_MAXLEN] = { 0 }; | ||||||
| 		va_list va; | 		va_list va; | ||||||
| 		va_start(va, fmt); | 		va_start(va, fmt); | ||||||
| 		ssize res = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) - 1; | 		ssize res = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) - 1; | ||||||
| 		va_end(va); | 		va_end(va); | ||||||
| 		return string_make_length(allocator, buf, res); | 		return strbuilder_make_length(allocator, buf, res); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	forceinline bool          make_space_for(char const* str, ssize add_len) { return string_make_space_for(this, str, add_len); } | 	forceinline bool              make_space_for(char const* str, ssize add_len) { return strbuilder_make_space_for(this, str, add_len); } | ||||||
| 	forceinline bool          append(char c)                                 { return string_append_char(this, c); } | 	forceinline bool              append(char c)                                 { return strbuilder_append_char(this, c); } | ||||||
| 	forceinline bool          append(char const* str)                        { return string_append_c_str(this, str); } | 	forceinline bool              append(char const* str)                        { return strbuilder_append_c_str(this, str); } | ||||||
| 	forceinline bool          append(char const* str, ssize length)          { return string_append_c_str_len(this, str, length); } | 	forceinline bool              append(char const* str, ssize length)          { return strbuilder_append_c_str_len(this, str, length); } | ||||||
| 	forceinline bool          append(StrC str)                               { return string_append_strc(this, str); } | 	forceinline bool              append(Str str)                                { return strbuilder_append_str(this, str); } | ||||||
| 	forceinline bool          append(const String other)                     { return string_append_string(this, other); } | 	forceinline bool              append(const StrBuilder other)                 { return strbuilder_append_string(this, other); } | ||||||
| 	forceinline ssize         avail_space() const                            { return string_avail_space(* this); } | 	forceinline ssize             avail_space() const                            { return strbuilder_avail_space(* this); } | ||||||
| 	forceinline char*         back()                                         { return string_back(* this); } | 	forceinline char*             back()                                         { return strbuilder_back(* this); } | ||||||
| 	forceinline bool          contains(StrC substring) const                 { return string_contains_strc(* this, substring); } | 	forceinline bool              contains(Str substring) const                  { return strbuilder_contains_str(* this, substring); } | ||||||
| 	forceinline bool          contains(String const& substring) const        { return string_contains_string(* this, substring); } | 	forceinline bool              contains(StrBuilder const& substring) const    { return strbuilder_contains_string(* this, substring); } | ||||||
| 	forceinline ssize         capacity() const                               { return string_capacity(* this); } | 	forceinline ssize             capacity() const                               { return strbuilder_capacity(* this); } | ||||||
| 	forceinline void          clear()                                        {        string_clear(* this); } | 	forceinline void              clear()                                        {        strbuilder_clear(* this); } | ||||||
| 	forceinline String        duplicate(AllocatorInfo allocator) const       { return string_duplicate(* this, allocator); } | 	forceinline StrBuilder        duplicate(AllocatorInfo allocator) const       { return strbuilder_duplicate(* this, allocator); } | ||||||
| 	forceinline void          free()                                         {        string_free(this); } | 	forceinline void              free()                                         {        strbuilder_free(this); } | ||||||
| 	forceinline bool          is_equal(String const& other) const            { return string_are_equal(* this, other); } | 	forceinline bool              is_equal(StrBuilder const& other) const        { return strbuilder_are_equal(* this, other); } | ||||||
| 	forceinline bool          is_equal(StrC other) const                     { return string_are_equal_strc(* this, other); } | 	forceinline bool              is_equal(Str other) const                      { return strbuilder_are_equal_str(* this, other); } | ||||||
| 	forceinline ssize         length() const                                 { return string_length(* this); } | 	forceinline ssize             length() const                                 { return strbuilder_length(* this); } | ||||||
| 	forceinline b32           starts_with(StrC substring) const              { return string_starts_with_strc(* this, substring); } | 	forceinline b32               starts_with(Str substring) const               { return strbuilder_starts_with_str(* this, substring); } | ||||||
| 	forceinline b32           starts_with(String substring) const            { return string_starts_with_string(* this, substring); } | 	forceinline b32               starts_with(StrBuilder substring) const        { return strbuilder_starts_with_string(* this, substring); } | ||||||
| 	forceinline void          skip_line()                                    {        string_skip_line(* this); } | 	forceinline void              skip_line()                                    {        strbuilder_skip_line(* this); } | ||||||
| 	forceinline void          strip_space()                                  {        string_strip_space(* this); } | 	forceinline void              strip_space()                                  {        strbuilder_strip_space(* this); } | ||||||
| 	forceinline StrC          to_strc()                                      { return { string_length(*this), Data}; } | 	forceinline Str               to_str()                                       { return { Data, strbuilder_length(*this) }; } | ||||||
| 	forceinline void          trim(char const* cut_set)                      {        string_trim(* this, cut_set); } | 	forceinline void              trim(char const* cut_set)                      {        strbuilder_trim(* this, cut_set); } | ||||||
| 	forceinline void          trim_space()                                   {        string_trim_space(* this); } | 	forceinline void              trim_space()                                   {        strbuilder_trim_space(* this); } | ||||||
| 	forceinline String        visualize_whitespace() const                   { return string_visualize_whitespace(* this); } | 	forceinline StrBuilder        visualize_whitespace() const                   { return strbuilder_visualize_whitespace(* this); } | ||||||
| 	forceinline StringHeader& get_header()                                   { return * string_get_header(* this); } | 	forceinline StrBuilderHeader& get_header()                                   { return * strbuilder_get_header(* this); } | ||||||
|  |  | ||||||
| 	bool append_fmt(char const* fmt, ...) { | 	bool append_fmt(char const* fmt, ...) { | ||||||
| 		ssize res; | 		ssize res; | ||||||
| @@ -255,163 +255,163 @@ struct String | |||||||
|  |  | ||||||
| 		va_list va; | 		va_list va; | ||||||
| 		va_start(va, fmt); | 		va_start(va, fmt); | ||||||
| 		res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1; | 		res = c_str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1; | ||||||
| 		va_end(va); | 		va_end(va); | ||||||
|  |  | ||||||
| 		return string_append_c_str_len(this, buf, res); | 		return strbuilder_append_c_str_len(this, buf, res); | ||||||
| 	} | 	} | ||||||
| #pragma endregion Member Mapping | #pragma endregion Member Mapping | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| forceinline char* string_begin(String str)                   { return ((char*) str); } | forceinline char* strbuilder_begin(StrBuilder str)                   { return ((char*) str); } | ||||||
| forceinline char* string_end  (String str)                   { return ((char*) str + string_length(str)); } | forceinline char* strbuilder_end  (StrBuilder str)                   { return ((char*) str + strbuilder_length(str)); } | ||||||
| forceinline char* string_next (String str, char const* iter) { return ((char*) iter + 1); } | forceinline char* strbuilder_next (StrBuilder str, char const* iter) { return ((char*) iter + 1); } | ||||||
|  |  | ||||||
| #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP | #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP | ||||||
| forceinline char* begin(String str)             { return ((char*) str); } | forceinline char* begin(StrBuilder str)             { return ((char*) str); } | ||||||
| forceinline char* end  (String str)             { return ((char*) str + string_length(str)); } | forceinline char* end  (StrBuilder str)             { return ((char*) str + strbuilder_length(str)); } | ||||||
| forceinline char* next (String str, char* iter) { return ((char*) iter + 1); } | forceinline char* next (StrBuilder str, char* iter) { return ((char*) iter + 1); } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP | #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP | ||||||
| forceinline bool  make_space_for(String& str, char const* to_append, ssize add_len); | forceinline bool  make_space_for(StrBuilder& str, char const* to_append, ssize add_len); | ||||||
| forceinline bool  append(String& str, char c); | forceinline bool  append(StrBuilder& str, char c); | ||||||
| forceinline bool  append(String& str, char const* str_to_append); | forceinline bool  append(StrBuilder& str, char const* c_str_to_append); | ||||||
| forceinline bool  append(String& str, char const* str_to_append, ssize length); | forceinline bool  append(StrBuilder& str, char const* c_str_to_append, ssize length); | ||||||
| forceinline bool  append(String& str, StrC str_to_append); | forceinline bool  append(StrBuilder& str, Str c_str_to_append); | ||||||
| forceinline bool  append(String& str, const String other); | forceinline bool  append(StrBuilder& str, const StrBuilder other); | ||||||
| forceinline bool  append_fmt(String& str, char const* fmt, ...); | forceinline bool  append_fmt(StrBuilder& str, char const* fmt, ...); | ||||||
| forceinline char& back(String& str); | forceinline char& back(StrBuilder& str); | ||||||
| forceinline void  clear(String& str); | forceinline void  clear(StrBuilder& str); | ||||||
| forceinline void  free(String& str); | forceinline void  free(StrBuilder& str); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| usize string_grow_formula(usize value) { | usize strbuilder_grow_formula(usize value) { | ||||||
| 	// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library. | 	// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library. | ||||||
| 	return 4 * value + 8; | 	return 4 * value + 8; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| String string_make_c_str(AllocatorInfo allocator, char const* str) { | StrBuilder strbuilder_make_c_str(AllocatorInfo allocator, char const* str) { | ||||||
| 	ssize length = str ? str_len(str) : 0; | 	ssize length = str ? c_str_len(str) : 0; | ||||||
| 	return string_make_length(allocator, str, length); | 	return strbuilder_make_length(allocator, str, length); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| String string_make_strc(AllocatorInfo allocator, StrC str) { | StrBuilder strbuilder_make_str(AllocatorInfo allocator, Str str) { | ||||||
| 	return string_make_length(allocator, str.Ptr, str.Len); | 	return strbuilder_make_length(allocator, str.Ptr, str.Len); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| String string_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) { | StrBuilder strbuilder_fmt(AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...) { | ||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, fmt); | 	va_start(va, fmt); | ||||||
| 	ssize res = str_fmt_va(buf, buf_size, fmt, va) - 1; | 	ssize res = c_str_fmt_va(buf, buf_size, fmt, va) - 1; | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| 	return string_make_length(allocator, buf, res); | 	return strbuilder_make_length(allocator, buf, res); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| String string_fmt_buf(AllocatorInfo allocator, char const* fmt, ...) | StrBuilder strbuilder_fmt_buf(AllocatorInfo allocator, char const* fmt, ...) | ||||||
| { | { | ||||||
| 	local_persist thread_local | 	local_persist thread_local | ||||||
| 	PrintF_Buffer buf = struct_init(PrintF_Buffer, {0}); | 	PrintF_Buffer buf = struct_init(PrintF_Buffer, {0}); | ||||||
|  |  | ||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, fmt); | 	va_start(va, fmt); | ||||||
| 	ssize res = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) -1; | 	ssize res = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) -1; | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| 	return string_make_length(allocator, buf, res); | 	return strbuilder_make_length(allocator, buf, res); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| String string_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue) | StrBuilder strbuilder_join(AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue) | ||||||
| { | { | ||||||
| 	String result = string_make_c_str(allocator, ""); | 	StrBuilder result = strbuilder_make_c_str(allocator, ""); | ||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx < num_parts; ++idx) | 	for (ssize idx = 0; idx < num_parts; ++idx) | ||||||
| 	{ | 	{ | ||||||
| 		string_append_c_str(& result, parts[idx]); | 		strbuilder_append_c_str(& result, parts[idx]); | ||||||
|  |  | ||||||
| 		if (idx < num_parts - 1) | 		if (idx < num_parts - 1) | ||||||
| 			string_append_c_str(& result, glue); | 			strbuilder_append_c_str(& result, glue); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool string_append_char(String* str, char c) { | bool strbuilder_append_char(StrBuilder* str, char c) { | ||||||
| 	GEN_ASSERT(str != nullptr); | 	GEN_ASSERT(str != nullptr); | ||||||
| 	return string_append_c_str_len( str, (char const*)& c, (ssize)1); | 	return strbuilder_append_c_str_len( str, (char const*)& c, (ssize)1); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool string_append_c_str(String* str, char const* str_to_append) { | bool strbuilder_append_c_str(StrBuilder* str, char const* c_str_to_append) { | ||||||
| 	GEN_ASSERT(str != nullptr); | 	GEN_ASSERT(str != nullptr); | ||||||
| 	return string_append_c_str_len(str, str_to_append, str_len(str_to_append)); | 	return strbuilder_append_c_str_len(str, c_str_to_append, c_str_len(c_str_to_append)); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool string_append_c_str_len(String* str, char const* str_to_append, ssize append_length) | bool strbuilder_append_c_str_len(StrBuilder* str, char const* c_str_to_append, ssize append_length) | ||||||
| { | { | ||||||
| 	GEN_ASSERT(str != nullptr); | 	GEN_ASSERT(str != nullptr); | ||||||
| 	if ( rcast(sptr, str_to_append) > 0) | 	if ( rcast(sptr, c_str_to_append) > 0) | ||||||
| 	{ | 	{ | ||||||
| 		ssize curr_len = string_length(* str); | 		ssize curr_len = strbuilder_length(* str); | ||||||
|  |  | ||||||
| 		if ( ! string_make_space_for(str, str_to_append, append_length)) | 		if ( ! strbuilder_make_space_for(str, c_str_to_append, append_length)) | ||||||
| 			return false; | 			return false; | ||||||
|  |  | ||||||
| 		StringHeader* header = string_get_header(* str); | 		StrBuilderHeader* header = strbuilder_get_header(* str); | ||||||
|  |  | ||||||
| 		char* Data = * str; | 		char* Data = * str; | ||||||
| 		mem_copy( Data + curr_len, str_to_append, append_length); | 		mem_copy( Data + curr_len, c_str_to_append, append_length); | ||||||
|  |  | ||||||
| 		Data[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 c_str_to_append != nullptr; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool string_append_strc(String* str, StrC str_to_append) { | bool strbuilder_append_str(StrBuilder* str, Str c_str_to_append) { | ||||||
| 	GEN_ASSERT(str != nullptr); | 	GEN_ASSERT(str != nullptr); | ||||||
| 	return string_append_c_str_len(str, str_to_append.Ptr, str_to_append.Len); | 	return strbuilder_append_c_str_len(str, c_str_to_append.Ptr, c_str_to_append.Len); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| bool string_append_string(String* str, String const other) { | bool strbuilder_append_string(StrBuilder* str, StrBuilder const other) { | ||||||
| 	GEN_ASSERT(str != nullptr); | 	GEN_ASSERT(str != nullptr); | ||||||
| 	return string_append_c_str_len(str, (char const*)other, string_length(other)); | 	return strbuilder_append_c_str_len(str, (char const*)other, strbuilder_length(other)); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool string_append_fmt(String* str, char const* fmt, ...) { | bool strbuilder_append_fmt(StrBuilder* str, char const* fmt, ...) { | ||||||
| 	GEN_ASSERT(str != nullptr); | 	GEN_ASSERT(str != nullptr); | ||||||
| 	ssize res; | 	ssize res; | ||||||
| 	char buf[GEN_PRINTF_MAXLEN] = { 0 }; | 	char buf[GEN_PRINTF_MAXLEN] = { 0 }; | ||||||
|  |  | ||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, fmt); | 	va_start(va, fmt); | ||||||
| 	res = str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1; | 	res = c_str_fmt_va(buf, count_of(buf) - 1, fmt, va) - 1; | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| 	return string_append_c_str_len(str, (char const*)buf, res); | 	return strbuilder_append_c_str_len(str, (char const*)buf, res); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool string_are_equal_string(String const lhs, String const rhs) | bool strbuilder_are_equal_string(StrBuilder const lhs, StrBuilder const rhs) | ||||||
| { | { | ||||||
| 	if (string_length(lhs) != string_length(rhs)) | 	if (strbuilder_length(lhs) != strbuilder_length(rhs)) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx < string_length(lhs); ++idx) | 	for (ssize idx = 0; idx < strbuilder_length(lhs); ++idx) | ||||||
| 		if (lhs[idx] != rhs[idx]) | 		if (lhs[idx] != rhs[idx]) | ||||||
| 			return false; | 			return false; | ||||||
|  |  | ||||||
| @@ -419,12 +419,12 @@ bool string_are_equal_string(String const lhs, String const rhs) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool string_are_equal_strc(String const lhs, StrC rhs) | bool strbuilder_are_equal_str(StrBuilder const lhs, Str rhs) | ||||||
| { | { | ||||||
| 	if (string_length(lhs) != (rhs.Len)) | 	if (strbuilder_length(lhs) != (rhs.Len)) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx < string_length(lhs); ++idx) | 	for (ssize idx = 0; idx < strbuilder_length(lhs); ++idx) | ||||||
| 		if (lhs[idx] != rhs.Ptr[idx]) | 		if (lhs[idx] != rhs.Ptr[idx]) | ||||||
| 			return false; | 			return false; | ||||||
|  |  | ||||||
| @@ -432,20 +432,20 @@ bool string_are_equal_strc(String const lhs, StrC rhs) | |||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| ssize string_avail_space(String const str) { | ssize strbuilder_avail_space(StrBuilder const str) { | ||||||
| 	StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | 	StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader)); | ||||||
| 	return header->Capacity - header->Length; | 	return header->Capacity - header->Length; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| char* string_back(String str) { | char* strbuilder_back(StrBuilder str) { | ||||||
| 	return & (str)[string_length(str) - 1]; | 	return & (str)[strbuilder_length(str) - 1]; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool string_contains_StrC(String const str, StrC substring) | bool strbuilder_contains_StrC(StrBuilder const str, Str substring) | ||||||
| { | { | ||||||
| 	StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | 	StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader)); | ||||||
|  |  | ||||||
| 	if (substring.Len > header->Length) | 	if (substring.Len > header->Length) | ||||||
| 		return false; | 		return false; | ||||||
| @@ -455,7 +455,7 @@ bool string_contains_StrC(String const str, StrC substring) | |||||||
|  |  | ||||||
| 	for (ssize idx = 0; idx <= main_len - sub_len; ++idx) | 	for (ssize idx = 0; idx <= main_len - sub_len; ++idx) | ||||||
| 	{ | 	{ | ||||||
| 		if (str_compare_len(str + idx, substring.Ptr, sub_len) == 0) | 		if (c_str_compare_len(str + idx, substring.Ptr, sub_len) == 0) | ||||||
| 			return true; | 			return true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -463,19 +463,19 @@ bool string_contains_StrC(String const str, StrC substring) | |||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool string_contains_string(String const str, String const substring) | bool strbuilder_contains_string(StrBuilder const str, StrBuilder const substring) | ||||||
| { | { | ||||||
| 	StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | 	StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader)); | ||||||
|  |  | ||||||
| 	if (string_length(substring) > header->Length) | 	if (strbuilder_length(substring) > header->Length) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	ssize main_len = header->Length; | 	ssize main_len = header->Length; | ||||||
| 	ssize sub_len  = string_length(substring); | 	ssize sub_len  = strbuilder_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_len(str + idx, substring, sub_len) == 0) | 		if (c_str_compare_len(str + idx, substring, sub_len) == 0) | ||||||
| 			return true; | 			return true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -483,47 +483,47 @@ bool string_contains_string(String const str, String const substring) | |||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| ssize string_capacity(String const str) { | ssize strbuilder_capacity(StrBuilder const str) { | ||||||
| 	StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | 	StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader)); | ||||||
| 	return header->Capacity; | 	return header->Capacity; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| void string_clear(String str) { | void strbuilder_clear(StrBuilder str) { | ||||||
| 	string_get_header(str)->Length = 0; | 	strbuilder_get_header(str)->Length = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| String string_duplicate(String const str, AllocatorInfo allocator) { | StrBuilder strbuilder_duplicate(StrBuilder const str, AllocatorInfo allocator) { | ||||||
| 	return string_make_length(allocator, str, string_length(str)); | 	return strbuilder_make_length(allocator, str, strbuilder_length(str)); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| void string_free(String* str) { | void strbuilder_free(StrBuilder* str) { | ||||||
| 	GEN_ASSERT(str != nullptr); | 	GEN_ASSERT(str != nullptr); | ||||||
| 	if (! (* str)) | 	if (! (* str)) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	StringHeader* header = string_get_header(* str); | 	StrBuilderHeader* header = strbuilder_get_header(* str); | ||||||
| 	allocator_free(header->Allocator, header); | 	allocator_free(header->Allocator, header); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| StringHeader* string_get_header(String str) { | StrBuilderHeader* strbuilder_get_header(StrBuilder str) { | ||||||
| 	return (StringHeader*)(scast(char*, str) - sizeof(StringHeader)); | 	return (StrBuilderHeader*)(scast(char*, str) - sizeof(StrBuilderHeader)); | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| ssize string_length(String const str) | ssize strbuilder_length(StrBuilder const str) | ||||||
| { | { | ||||||
| 	StringHeader const* header = rcast(StringHeader const*, scast(char const*, str) - sizeof(StringHeader)); | 	StrBuilderHeader const* header = rcast(StrBuilderHeader const*, scast(char const*, str) - sizeof(StrBuilderHeader)); | ||||||
| 	return header->Length; | 	return header->Length; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| bool string_make_space_for(String* str, char const* to_append, ssize add_len) | bool strbuilder_make_space_for(StrBuilder* str, char const* to_append, ssize add_len) | ||||||
| { | { | ||||||
| 	ssize available = string_avail_space(* str); | 	ssize available = strbuilder_avail_space(* str); | ||||||
|  |  | ||||||
| 	if (available >= add_len) { | 	if (available >= add_len) { | ||||||
| 		return true; | 		return true; | ||||||
| @@ -534,20 +534,20 @@ bool string_make_space_for(String* str, char const* to_append, ssize add_len) | |||||||
| 		void* ptr; | 		void* ptr; | ||||||
| 		void* new_ptr; | 		void* new_ptr; | ||||||
|  |  | ||||||
| 		AllocatorInfo allocator = string_get_header(* str)->Allocator; | 		AllocatorInfo allocator = strbuilder_get_header(* str)->Allocator; | ||||||
| 		StringHeader* header    = nullptr; | 		StrBuilderHeader* header    = nullptr; | ||||||
|  |  | ||||||
| 		new_len  = string_grow_formula(string_length(* str) + add_len); | 		new_len  = strbuilder_grow_formula(strbuilder_length(* str) + add_len); | ||||||
| 		ptr      = string_get_header(* str); | 		ptr      = strbuilder_get_header(* str); | ||||||
| 		old_size = size_of(StringHeader) + string_length(* str) + 1; | 		old_size = size_of(StrBuilderHeader) + strbuilder_length(* str) + 1; | ||||||
| 		new_size = size_of(StringHeader) + new_len + 1; | 		new_size = size_of(StrBuilderHeader) + new_len + 1; | ||||||
|  |  | ||||||
| 		new_ptr = resize(allocator, ptr, old_size, new_size); | 		new_ptr = resize(allocator, ptr, old_size, new_size); | ||||||
|  |  | ||||||
| 		if (new_ptr == nullptr) | 		if (new_ptr == nullptr) | ||||||
| 			return false; | 			return false; | ||||||
|  |  | ||||||
| 		header = rcast(StringHeader*, new_ptr); | 		header = rcast(StrBuilderHeader*, new_ptr); | ||||||
| 		header->Allocator = allocator; | 		header->Allocator = allocator; | ||||||
| 		header->Capacity  = new_len; | 		header->Capacity  = new_len; | ||||||
|  |  | ||||||
| @@ -559,25 +559,25 @@ bool string_make_space_for(String* str, char const* to_append, ssize add_len) | |||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| b32 string_starts_with_strc(String const str, StrC substring) { | b32 strbuilder_starts_with_str(StrBuilder const str, Str substring) { | ||||||
| 	if (substring.Len > string_length(str)) | 	if (substring.Len > strbuilder_length(str)) | ||||||
| 	return false; | 	return false; | ||||||
|  |  | ||||||
| 	b32 result = str_compare_len(str, substring.Ptr, substring.Len) == 0; | 	b32 result = c_str_compare_len(str, substring.Ptr, substring.Len) == 0; | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| b32 string_starts_with_string(String const str, String substring) { | b32 strbuilder_starts_with_string(StrBuilder const str, StrBuilder substring) { | ||||||
| 	if (string_length(substring) > string_length(str)) | 	if (strbuilder_length(substring) > strbuilder_length(str)) | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	b32 result = str_compare_len(str, substring, string_length(substring) - 1) == 0; | 	b32 result = c_str_compare_len(str, substring, strbuilder_length(substring) - 1) == 0; | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void string_skip_line(String str) | void strbuilder_skip_line(StrBuilder str) | ||||||
| { | { | ||||||
| #define current (*scanner) | #define current (*scanner) | ||||||
| 	char* scanner = str; | 	char* scanner = str; | ||||||
| @@ -593,13 +593,13 @@ void string_skip_line(String str) | |||||||
|  |  | ||||||
| 	mem_move((char*)str, scanner, new_length); | 	mem_move((char*)str, scanner, new_length); | ||||||
|  |  | ||||||
| 	StringHeader* header = string_get_header(str); | 	StrBuilderHeader* header = strbuilder_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(StrBuilder str) | ||||||
| { | { | ||||||
| 	char* write_pos = str; | 	char* write_pos = str; | ||||||
| 	char* read_pos  = str; | 	char* read_pos  = str; | ||||||
| @@ -616,22 +616,22 @@ 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 | ||||||
| 	string_get_header(str)->Length = write_pos - str; | 	strbuilder_get_header(str)->Length = write_pos - str; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| StrC string_to_strc(String str) { | Str strbuilder_to_str(StrBuilder str) { | ||||||
| 	StrC result = { string_length(str), (char const*)str }; | 	Str result = { (char const*)str, strbuilder_length(str) }; | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| void string_trim(String str, char const* cut_set) | void strbuilder_trim(StrBuilder str, char const* cut_set) | ||||||
| { | { | ||||||
| 	ssize len = 0; | 	ssize len = 0; | ||||||
|  |  | ||||||
| 	char* start_pos = str; | 	char* start_pos = str; | ||||||
| 	char* end_pos   = scast(char*, str) + string_length(str) - 1; | 	char* end_pos   = scast(char*, str) + strbuilder_length(str) - 1; | ||||||
|  |  | ||||||
| 	while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos)) | 	while (start_pos <= end_pos && char_first_occurence(cut_set, *start_pos)) | ||||||
| 	start_pos++; | 	start_pos++; | ||||||
| @@ -646,98 +646,98 @@ void string_trim(String str, char const* cut_set) | |||||||
|  |  | ||||||
| 	str[len] = '\0'; | 	str[len] = '\0'; | ||||||
|  |  | ||||||
| 	string_get_header(str)->Length = len; | 	strbuilder_get_header(str)->Length = len; | ||||||
| } | } | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| void string_trim_space(String str) { | void strbuilder_trim_space(StrBuilder str) { | ||||||
| 	string_trim(str, " \t\r\n\v\f"); | 	strbuilder_trim(str, " \t\r\n\v\f"); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| String string_visualize_whitespace(String const str) | StrBuilder strbuilder_visualize_whitespace(StrBuilder const str) | ||||||
| { | { | ||||||
| 	StringHeader* header = (StringHeader*)(scast(char const*, str) - sizeof(StringHeader)); | 	StrBuilderHeader* header = (StrBuilderHeader*)(scast(char const*, str) - sizeof(StrBuilderHeader)); | ||||||
| 	String        result = string_make_reserve(header->Allocator, string_length(str) * 2); // Assume worst case for space requirements. | 	StrBuilder        result = strbuilder_make_reserve(header->Allocator, strbuilder_length(str) * 2); // Assume worst case for space requirements. | ||||||
|  |  | ||||||
| 	for (char const* c = string_begin(str); c != string_end(str); c = string_next(str, c)) | 	for (char const* c = strbuilder_begin(str); c != strbuilder_end(str); c = strbuilder_next(str, c)) | ||||||
| 	switch ( * c ) | 	switch ( * c ) | ||||||
| 	{ | 	{ | ||||||
| 		case ' ': | 		case ' ': | ||||||
| 			string_append_strc(& result, txt("·")); | 			strbuilder_append_str(& result, txt("·")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\t': | 		case '\t': | ||||||
| 			string_append_strc(& result, txt("→")); | 			strbuilder_append_str(& result, txt("→")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\n': | 		case '\n': | ||||||
| 			string_append_strc(& result, txt("↵")); | 			strbuilder_append_str(& result, txt("↵")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\r': | 		case '\r': | ||||||
| 			string_append_strc(& result, txt("⏎")); | 			strbuilder_append_str(& result, txt("⏎")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\v': | 		case '\v': | ||||||
| 			string_append_strc(& result, txt("⇕")); | 			strbuilder_append_str(& result, txt("⇕")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\f': | 		case '\f': | ||||||
| 			string_append_strc(& result, txt("⌂")); | 			strbuilder_append_str(& result, txt("⌂")); | ||||||
| 		break; | 		break; | ||||||
| 		default: | 		default: | ||||||
| 			string_append_char(& result, * c); | 			strbuilder_append_char(& result, * c); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| #pragma endregion String | #pragma endregion StrBuilder | ||||||
|  |  | ||||||
| #if GEN_COMPILER_CPP | #if GEN_COMPILER_CPP | ||||||
| struct String_POD { | struct StrBuilder_POD { | ||||||
| 	char* Data; | 	char* Data; | ||||||
| }; | }; | ||||||
| static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" ); | static_assert( sizeof( StrBuilder_POD ) == sizeof( StrBuilder ), "StrBuilder is not a POD" ); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| forceinline | forceinline | ||||||
| StrC strc_duplicate(StrC str, AllocatorInfo allocator) { | Str str_duplicate(Str str, AllocatorInfo allocator) { | ||||||
| 	StrC result = string_to_strc( string_make_length(allocator, str.Ptr, str.Len)); | 	Str result = strbuilder_to_str( strbuilder_make_length(allocator, str.Ptr, str.Len)); | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| inline | inline | ||||||
| StrC strc_visualize_whitespace(StrC str, AllocatorInfo allocator) | Str str_visualize_whitespace(Str str, AllocatorInfo allocator) | ||||||
| { | { | ||||||
| 	String result = string_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements. | 	StrBuilder result = strbuilder_make_reserve(allocator, str.Len * 2); // Assume worst case for space requirements. | ||||||
| 	for (char const* c = strc_begin(str); c != strc_end(str); c = strc_next(str, c)) | 	for (char const* c = str_begin(str); c != str_end(str); c = str_next(str, c)) | ||||||
| 	switch ( * c ) | 	switch ( * c ) | ||||||
| 	{ | 	{ | ||||||
| 		case ' ': | 		case ' ': | ||||||
| 			string_append_strc(& result, txt("·")); | 			strbuilder_append_str(& result, txt("·")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\t': | 		case '\t': | ||||||
| 			string_append_strc(& result, txt("→")); | 			strbuilder_append_str(& result, txt("→")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\n': | 		case '\n': | ||||||
| 			string_append_strc(& result, txt("↵")); | 			strbuilder_append_str(& result, txt("↵")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\r': | 		case '\r': | ||||||
| 			string_append_strc(& result, txt("⏎")); | 			strbuilder_append_str(& result, txt("⏎")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\v': | 		case '\v': | ||||||
| 			string_append_strc(& result, txt("⇕")); | 			strbuilder_append_str(& result, txt("⇕")); | ||||||
| 		break; | 		break; | ||||||
| 		case '\f': | 		case '\f': | ||||||
| 			string_append_strc(& result, txt("⌂")); | 			strbuilder_append_str(& result, txt("⌂")); | ||||||
| 		break; | 		break; | ||||||
| 		default: | 		default: | ||||||
| 			string_append_char(& result, * c); | 			strbuilder_append_char(& result, * c); | ||||||
| 		break; | 		break; | ||||||
| } | } | ||||||
| 	return string_to_strc(result); | 	return strbuilder_to_str(result); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Represents strings cached with the string table. | // Represents strings cached with the string table. | ||||||
| // Should never be modified, if changed string is desired, cache_string( str ) another. | // Should never be modified, if changed string is desired, cache_string( str ) another. | ||||||
| typedef StrC StringCached; | typedef Str StringCached; | ||||||
|  |  | ||||||
| // Implements basic string interning. Data structure is based off the ZPL Hashtable. | // Implements basic string interning. Data structure is based off the ZPL Hashtable. | ||||||
| typedef HashTable(StringCached) StringTable; | typedef HashTable(StringCached) StringTable; | ||||||
|   | |||||||
| @@ -1,423 +0,0 @@ | |||||||
|  __VERSION 1 |  | ||||||
|  |  | ||||||
| // This is a example template to be used with the refactor program |  | ||||||
| // Use it to refactor the naming convention of this library to your own. |  | ||||||
| // Can be used as an aid to help use use your project's implementation if it fullfills the dependencies of this project. |  | ||||||
| // Example: Most likely have a memory and string library already, just rename the functions and make sure the args are the same. |  | ||||||
| // Program: https://github.com/Ed94/refactor |  | ||||||
|  |  | ||||||
| // NOTE: Due to the current limitations of the program, not every symbol in the library can be renamed. |  | ||||||
| // This is due to the program not actually parsing C/C++. |  | ||||||
|  |  | ||||||
| // not       : Ignore |  | ||||||
| // include   : #includes |  | ||||||
| // word      : Alphanumeric or underscore |  | ||||||
| // namespace : Prefix search and replace (c-namspaces). |  | ||||||
| // regex     : Unavailable in __VERSION 1. |  | ||||||
|  |  | ||||||
| // Precedence (highest to lowest): |  | ||||||
| // word, namespace, regex |  | ||||||
|  |  | ||||||
| // TODO(ED): THIS IS VERY OUTDATED |  | ||||||
|  |  | ||||||
| // Gen Macro namespace |  | ||||||
| // namespace GEN_, new_namespace_ |  | ||||||
|  |  | ||||||
| // ---------- Dependency Macros |  | ||||||
|     // Platform |  | ||||||
| // word GEN_ARCH_64_BIT, new_name |  | ||||||
| // word GEN_ARCH_32_BIT, new_name |  | ||||||
|  |  | ||||||
| // word GEN_SYSTEM_ANDROID,    new_name |  | ||||||
| // word GEN_SYSTEM_CYGWIN,     new_name |  | ||||||
| // word GEN_SYSTEM_EMSCRIPTEN, new_name |  | ||||||
| // word GEN_SYSTEM_FREEBSD,    new_name |  | ||||||
| // word GEN_SYSTEM_IOS,	       new_name |  | ||||||
| // word GEN_SYSTEM_LINUX,      new_name |  | ||||||
| // word GEN_SYSTEM_MACOS,      new_name |  | ||||||
| // word GEN_SYSTEM_OPENBSD,    new_name |  | ||||||
| // word GEN_SYSTEM_OSX,        new_name |  | ||||||
| // word GEN_SYSTEM_UNIX,       new_name |  | ||||||
| // word GEN_SYSTEM_WINDOWS,    new_name |  | ||||||
|  |  | ||||||
| // word GEN_COMPILER_CLANG, new_name |  | ||||||
| // word GEN_COMPILER_GCC,   new_name |  | ||||||
| // word GEN_COMPILER_MINGW, new_name |  | ||||||
| // word GEN_COMPILER_MSVC,  new_name |  | ||||||
|  |  | ||||||
| // word global,        new_name |  | ||||||
| // word internal,      new_name |  | ||||||
| // word local_persist, new_name |  | ||||||
| // word forceinline,   new_name |  | ||||||
| // word neverinline,   new_name |  | ||||||
|  |  | ||||||
| // word bit,               new_name |  | ||||||
| // word bitfield_is_equal, new_name |  | ||||||
|  |  | ||||||
| // word ccast, new_name |  | ||||||
| // word pcast, new_name |  | ||||||
| // word rcast, new_name |  | ||||||
| // word scast, new_name |  | ||||||
|  |  | ||||||
| // word num_args,      new_name |  | ||||||
| // word num_args_impl, new_name |  | ||||||
|  |  | ||||||
| // word stringize,    new_name |  | ||||||
| // word stringize_va, new_name |  | ||||||
|  |  | ||||||
| // word do_once,           new_name |  | ||||||
| // word do_once_start,     new_name |  | ||||||
| // word do_once_end,       new_name |  | ||||||
| // word label_scope_start, new_name |  | ||||||
| // word label_scope_end,   new_name |  | ||||||
|  |  | ||||||
| // word count_of,   new_name |  | ||||||
| // word is_between, new_name |  | ||||||
| // word min,        new_name |  | ||||||
| // word size_of,    new_name |  | ||||||
| // word offset_of,  new_name |  | ||||||
| // word swap,       new_name |  | ||||||
|  |  | ||||||
|     // Basic Types |  | ||||||
| // word GEN_U8_MIN, new_name |  | ||||||
| // word GEN_U8_MAX, new_name |  | ||||||
| // word GEN_I8_MIN, new_name |  | ||||||
| // word GEN_I8_MAX, new_name |  | ||||||
|  |  | ||||||
| // word GEN_U16_MIN, new_name |  | ||||||
| // word GEN_U16_MAX, new_name |  | ||||||
| // word GEN_I16_MIN, new_name |  | ||||||
| // word GEN_I16_MAX, new_name |  | ||||||
|  |  | ||||||
| // word GEN_U32_MIN, new_name |  | ||||||
| // word GEN_U32_MAX, new_name |  | ||||||
| // word GEN_I32_MIN, new_name |  | ||||||
| // word GEN_I32_MAX, new_name |  | ||||||
|  |  | ||||||
| // word GEN_U64_MIN, new_name |  | ||||||
| // word GEN_U64_MAX, new_name |  | ||||||
| // word GEN_I64_MIN, new_name |  | ||||||
| // word GEN_I64_MAX, new_name |  | ||||||
|  |  | ||||||
| // word GEN_USIZE_MIN, new_name |  | ||||||
| // word GEN_USIZE_MAX, new_name |  | ||||||
| // word GEN_ISIZE_MIN, new_name |  | ||||||
| // word GEN_ISIZE_MAX, new_name |  | ||||||
|  |  | ||||||
| // word GEN_F32_MIN, new_name |  | ||||||
| // word GEN_F32_MAX, new_name |  | ||||||
| // word GEN_F64_MIN, new_name |  | ||||||
| // word GEN_F64_MAX, new_name |  | ||||||
|  |  | ||||||
|     // Debug |  | ||||||
| // word GEN_DEBUG_TRAP,      new_name |  | ||||||
| // word GEN_ASSERT,          new_name |  | ||||||
| // word GEN_ASSERT_MSG,      new_name |  | ||||||
| // word GEN_ASSERT_NOT_NULL, new_name |  | ||||||
| // word GEN_PANIC,           new_name |  | ||||||
| // word GEN_FATAL,           new_name |  | ||||||
|  |  | ||||||
|     // Memory |  | ||||||
| // word kilobytes, new_name |  | ||||||
| // word megabytes, new_name |  | ||||||
| // word gigabytes, new_name |  | ||||||
| // word terabytes, new_name |  | ||||||
|  |  | ||||||
| // word zero_item,  new_name |  | ||||||
| // word zero_array, new_name |  | ||||||
|  |  | ||||||
| // word alloc_item,  new_name |  | ||||||
| // word alloc_array, new_name |  | ||||||
|  |  | ||||||
| // word malloc, new_name |  | ||||||
| // word mfree,  new_name |  | ||||||
|  |  | ||||||
|     // Strings |  | ||||||
| // word txt, new_name |  | ||||||
| // word cast_to_strc, new_name |  | ||||||
|  |  | ||||||
| // ---------- Dependency Types |  | ||||||
|  |  | ||||||
| // word b8,   new_name |  | ||||||
| // word b16,  new_name |  | ||||||
| // word b32,  new_name |  | ||||||
| // word s8,   new_name |  | ||||||
| // word s16,  new_name |  | ||||||
| // word s32,  new_name |  | ||||||
| // word s64,  new_name |  | ||||||
| // word u8,   new_name |  | ||||||
| // word u16,  new_name |  | ||||||
| // word u32,  new_name |  | ||||||
| // word u64,  new_name |  | ||||||
| // word usize,   new_name |  | ||||||
| // word ssize,   new_name |  | ||||||
| // word sptr, new_name |  | ||||||
| // word uptr, new_name |  | ||||||
| // word f32,  new_name |  | ||||||
| // word f64,  new_name |  | ||||||
|  |  | ||||||
| // namespace EAllocator_, new_namespace_ |  | ||||||
| // namespace EFileMode_,  new_namespace_ |  | ||||||
| // namespace EFileError_, new_namespace_ |  | ||||||
|  |  | ||||||
| // word AllocatorInfo,    new_name |  | ||||||
| // word AllocatorProc,    new_name |  | ||||||
| // word AllocFlag,        new_name |  | ||||||
| // word AllocType,        new_name |  | ||||||
| // word ArrayHeader,      new_name |  | ||||||
| // word DirEntry,         new_name |  | ||||||
| // word DirInfo,          new_name |  | ||||||
| // word DirType,          new_name |  | ||||||
| // word FileDescriptor,   new_name |  | ||||||
| // word FileError,        new_name |  | ||||||
| // word FileInfo,         new_name |  | ||||||
| // word FileTime,         new_name |  | ||||||
| // word FileModeFlag,     new_name |  | ||||||
| // word FileOperations,   new_name |  | ||||||
| // word FileStandardType, new_name |  | ||||||
| // word SeekWhenceType,   new_name |  | ||||||
|  |  | ||||||
| // ---------- Dependency Data |  | ||||||
|  |  | ||||||
| // word default_file_operations, new_name |  | ||||||
|  |  | ||||||
| // ---------- Dependency Procedures |  | ||||||
|  |  | ||||||
| // word align_forward,          new_name |  | ||||||
| // word align_fordward_i64,     new_name |  | ||||||
| // word alloc,                  new_name |  | ||||||
| // word alloc_align,            new_name |  | ||||||
| // word assert_handler,         new_name |  | ||||||
| // word assert_crash,           new_name |  | ||||||
| // word char_first_occurence,   new_name |  | ||||||
| // word char_is_alpha,          new_name |  | ||||||
| // word char_is_alphanumeric,   new_name |  | ||||||
| // word char_is_digit,          new_name |  | ||||||
| // word char_is_hex_digit,      new_name |  | ||||||
| // word char_is_space,          new_name |  | ||||||
| // word char_to_lower,		    new_name |  | ||||||
| // word char_to_upper,		    new_name |  | ||||||
| // word crc32,                  new_name |  | ||||||
| // word default_resize_align,   new_name |  | ||||||
| // word digit_to_int,		    new_name |  | ||||||
| // word file_close,  		    new_name |  | ||||||
| // word file_get_standard,      new_name |  | ||||||
| // word file_name,              new_name |  | ||||||
| // word file_open,              new_name |  | ||||||
| // word file_open_mode,         new_name |  | ||||||
| // word file_seek, 			    new_name |  | ||||||
| // word file_tell, 			    new_name |  | ||||||
| // word file_write, 		    new_name |  | ||||||
| // word file_write_at, 		    new_name |  | ||||||
| // word file_write_at_check,    new_name |  | ||||||
| // word free,                   new_name |  | ||||||
| // word free_all,               new_name |  | ||||||
| // word heap,                   new_name |  | ||||||
| // word heap_allocator_proc,    new_name |  | ||||||
| // word heap_stats_check,       new_name |  | ||||||
| // word heap_stats_alloc_count, new_name |  | ||||||
| // word heap_stats_init,        new_name |  | ||||||
| // word heap_stats_used_memory, new_name |  | ||||||
| // word hex_digit_to_int,	    new_name |  | ||||||
| // word i64_to_str,			    new_name |  | ||||||
| // word is_power_of_two,        new_name |  | ||||||
| // word log_fmt,                new_name |  | ||||||
| // word mem_copy,               new_name |  | ||||||
| // word mem_move,               new_name |  | ||||||
| // word mem_set,                new_name |  | ||||||
| // word pointer_add,            new_name |  | ||||||
| // word mem_copy,               new_name |  | ||||||
| // word mem_find,               new_name |  | ||||||
| // word mem_move,               new_name |  | ||||||
| // word mem_set,                new_name |  | ||||||
| // word resize,                 new_name |  | ||||||
| // word resize_align,           new_name |  | ||||||
| // word process_exit,           new_name |  | ||||||
| // word str_compare,            new_name |  | ||||||
| // word str_copy,               new_name |  | ||||||
| // word str_copy_nulpad, 	    new_name |  | ||||||
| // word str_fmt_buf,            new_name |  | ||||||
| // word str_fmt_buf_va,	        new_name |  | ||||||
| // word str_fmt_file_va,        new_name |  | ||||||
| // word str_fmt_out_va,         new_name |  | ||||||
| // word str_fmt_out_err,        new_name |  | ||||||
| // word str_fmt_out_err_va,	    new_name |  | ||||||
| // word str_fmt_va,             new_name |  | ||||||
| // word str_len,                new_name |  | ||||||
| // word str_reverse, 		    new_name |  | ||||||
| // word str_to_i64, 		    new_name |  | ||||||
| // word str_to_lower, 		    new_name |  | ||||||
| // word str_to_upper,  	        new_name |  | ||||||
| // word u64_to_str, 		    new_name |  | ||||||
| // word zero_size,              new_name |  | ||||||
|  |  | ||||||
| // ---------- gencpp Macros |  | ||||||
|  |  | ||||||
| // word log_failure, new_name |  | ||||||
|  |  | ||||||
| // word NullCode,      new_name |  | ||||||
| // word CodeInvalid, new_name |  | ||||||
|  |  | ||||||
| // ------------ gencpp common |  | ||||||
|  |  | ||||||
| // word Arena,     new_name |  | ||||||
| // word Array,     new_name |  | ||||||
| // word HashTable, new_name |  | ||||||
| // word Pool,      new_name |  | ||||||
| // word StrC,      new_name |  | ||||||
| // word String,    new_name |  | ||||||
|  |  | ||||||
| // word to_str,  new_name |  | ||||||
| // word to_str,  new_name |  | ||||||
| // word to_type, new_name |  | ||||||
|  |  | ||||||
| // ------------ gencpp Types & Constants |  | ||||||
|  |  | ||||||
| // word LogFailType, new_name |  | ||||||
|  |  | ||||||
| // word AccessSpec,     new_name |  | ||||||
| // word ECode,          new_name |  | ||||||
| // word EnumClass,      new_name |  | ||||||
| // word EnumRegular,    new_name |  | ||||||
| // word EnumT,          new_name |  | ||||||
| // word EOperator,      new_name |  | ||||||
| // word ESpecifier,     new_name |  | ||||||
| // word OperatorT,      new_name |  | ||||||
| // word ModuleFlag,     new_name |  | ||||||
| // word SpecifierT,     new_name |  | ||||||
| // word StringCached,   new_name |  | ||||||
| // word StringTable,    new_name |  | ||||||
| // word UsingRegular,   new_name |  | ||||||
| // word UsingNamespace, new_name |  | ||||||
|  |  | ||||||
| // ------------ gencpp Data |  | ||||||
|  |  | ||||||
| // word API_Export,   new_name |  | ||||||
| // word API_Import,   new_name |  | ||||||
| // word AST_POD_Size, new_name |  | ||||||
| // word AST,          new_name |  | ||||||
| // word AST_POD,      new_name |  | ||||||
| // word Code,         new_name |  | ||||||
| // word Code_POD,     new_name |  | ||||||
| // word Keyword,      new_name |  | ||||||
|  |  | ||||||
| // ------------ gencpp API |  | ||||||
|  |  | ||||||
| // word init,                             new_name |  | ||||||
| // word deinit,                           new_name |  | ||||||
|  |  | ||||||
| // word get_cached_string,                new_name |  | ||||||
| // word make_code,                        new_name |  | ||||||
| // word make_code_entries,                new_name |  | ||||||
|  |  | ||||||
| // word set_allocator_data_arrays,        new_name |  | ||||||
| // word set_allocator_code_pool,          new_name |  | ||||||
| // word set_allocator_code_entries_arena, new_name |  | ||||||
| // word set_allocator_string_arena,       new_name |  | ||||||
| // word set_allocator_string_table,       new_name |  | ||||||
| // word set_allocator_type_table,         new_name |  | ||||||
|  |  | ||||||
| // ------------ upfront constructor namespace |  | ||||||
| // namespace def_ new_namespace_ |  | ||||||
|  |  | ||||||
| // ------------ upfront constructor individual |  | ||||||
|  |  | ||||||
| // word def_attributes,      new_name |  | ||||||
| // word def_comment,         new_name |  | ||||||
| // word def_class,           new_name |  | ||||||
| // word def_constructor,     new_name |  | ||||||
| // word def_destructor,      new_name |  | ||||||
| // word def_define,          new_name |  | ||||||
| // word def_enum,            new_name |  | ||||||
| // word def_execution,       new_name |  | ||||||
| // word def_extern_link,     new_name |  | ||||||
| // word def_friend,          new_name |  | ||||||
| // word def_function,        new_name |  | ||||||
| // word def_include,         new_name |  | ||||||
| // word def_module,          new_name |  | ||||||
| // word def_namespace,       new_name |  | ||||||
| // word def_operator,        new_name |  | ||||||
| // word def_operator_cast,   new_name |  | ||||||
| // word def_param,           new_name |  | ||||||
| // word def_pargma,          new_name |  | ||||||
| // word def_preprocess_cond, new_name |  | ||||||
| // word def_specifier,       new_name |  | ||||||
| // word def_struct,          new_name |  | ||||||
| // word def_template,        new_name |  | ||||||
| // word def_type,            new_name |  | ||||||
| // word def_typedef,         new_name |  | ||||||
| // word def_union,           new_name |  | ||||||
| // word def_using,           new_name |  | ||||||
| // word def_using_namespace, new_name |  | ||||||
| // word def_variable,        new_name |  | ||||||
|  |  | ||||||
| // word def_body,             new_name |  | ||||||
| // word def_class_body,       new_name |  | ||||||
| // word def_enum_body,        new_name |  | ||||||
| // word def_export_body,      new_name |  | ||||||
| // word def_extern_link_body, new_name |  | ||||||
| // word def_function_body,    new_name |  | ||||||
| // word def_global_body,      new_name |  | ||||||
| // word def_namespace_body,   new_name |  | ||||||
| // word def_params,           new_name |  | ||||||
| // word def_specifiers,       new_name |  | ||||||
| // word def_struct_body,      new_name |  | ||||||
| // word def_union_body,       new_name |  | ||||||
|  |  | ||||||
| // ------------ parse constructor namespace |  | ||||||
| // namespace parse_, new_namespace_ |  | ||||||
|  |  | ||||||
| // ------------ parse constructor individual |  | ||||||
|  |  | ||||||
| // word parse_class,       new_name |  | ||||||
| // word parse_enum,        new_name |  | ||||||
| // word parse_export_body, new_name |  | ||||||
| // word parse_extern_link, new_name |  | ||||||
| // word parse_friend,      new_name |  | ||||||
| // word parse_function,    new_name |  | ||||||
| // word parse_global_body, new_name |  | ||||||
| // word parse_namespace,   new_name |  | ||||||
| // word parse_operator,    new_name |  | ||||||
| // word parse_struct,      new_name |  | ||||||
| // word parse_template,    new_name |  | ||||||
| // word parse_type,        new_name |  | ||||||
| // word parse_typedef,     new_name |  | ||||||
| // word parse_union,       new_name |  | ||||||
| // word parse_using,       new_name |  | ||||||
| // word parse_variable,    new_name |  | ||||||
|  |  | ||||||
| // ------------ untyped constructor namespace |  | ||||||
| // namespace untyped_, new_namespace_ |  | ||||||
|  |  | ||||||
| // ------------ untyped constructor individual |  | ||||||
|  |  | ||||||
| // word token_fmt_impl,    new_name |  | ||||||
| // word token_fmt_va,      new_name |  | ||||||
| // word untyped_str,       new_name |  | ||||||
| // word untyped_fmt,       new_name |  | ||||||
| // word untyped_token_fmt, new_name |  | ||||||
|  |  | ||||||
| // ------------ File Ops |  | ||||||
|  |  | ||||||
| // word Builder, new_name |  | ||||||
| // word Editor,  new_name |  | ||||||
| // word Scanner, new_name |  | ||||||
|  |  | ||||||
| // ------------ gencpp user macros |  | ||||||
|  |  | ||||||
| // word gen_main,     new_name |  | ||||||
| // word GEN_TIME,     new_name |  | ||||||
|  |  | ||||||
| // word __,        new_name |  | ||||||
| // word name,      new_name |  | ||||||
| // word code,      new_name |  | ||||||
| // word args,      new_name |  | ||||||
| // word code_str,  new_name |  | ||||||
| // word code_fmt,  new_name |  | ||||||
| // word token_fmt, new_name |  | ||||||
|  |  | ||||||
| // ------------ Type AST namespace |  | ||||||
| // namespace t_, new_namespace_ |  | ||||||
|  |  | ||||||
| // ------------ Specifier AST namespace |  | ||||||
| // namespace spec_, new_namespace_ |  | ||||||
| @@ -9,58 +9,58 @@ using namespace gen; | |||||||
|  |  | ||||||
| CodeBody gen_ecode( char const* path, bool use_c_definition = false ) | CodeBody gen_ecode( char const* path, bool use_c_definition = false ) | ||||||
| { | { | ||||||
| 	FixedArena_32KB scratch; fixed_arena_init(& scratch); | 	FixedArena_32KB scratch;       fixed_arena_init(& scratch); | ||||||
| 	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch); | 	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch); | ||||||
|  |  | ||||||
| 	CSV_Columns2 csv_enum         = parse_csv_two_columns( scratch_info, path ); | 	CSV_Columns2 csv_enum                 = parse_csv_two_columns( scratch_info, path ); | ||||||
| 	String enum_entries           = string_make_reserve( GlobalAllocator, kilobytes(1) ); | 	StrBuilder   enum_entries             = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) ); | ||||||
| 	String to_str_entries         = string_make_reserve( GlobalAllocator, kilobytes(1) ); | 	StrBuilder   to_c_str_entries         = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) ); | ||||||
| 	String to_keyword_str_entries = string_make_reserve( GlobalAllocator, kilobytes(1) ); | 	StrBuilder   to_keyword_c_str_entries = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) ); | ||||||
|  |  | ||||||
| 	for ( ssize idx = 0; idx < array_num(csv_enum.Col_1); ++ idx ) 	{ | 	for ( ssize idx = 0; idx < array_num(csv_enum.Col_1); ++ idx ) 	{ | ||||||
| 		char const* code    = csv_enum.Col_1[idx].string; | 		char const* code    = csv_enum.Col_1[idx].string; | ||||||
| 		char const* keyword = csv_enum.Col_2[idx].string; | 		char const* keyword = csv_enum.Col_2[idx].string; | ||||||
| 		// TODO(Ed): to_str_entries and the others in here didn't have proper sizing of the StrC slice. | 		// TODO(Ed): to_c_str_entries and the others in here didn't have proper sizing of the Str slice. | ||||||
| 		string_append_fmt( & enum_entries,           "CT_%s,\n", code ); | 		strbuilder_append_fmt( & enum_entries,             "CT_%s,\n", code ); | ||||||
| 		string_append_fmt( & to_str_entries,         "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); | 		strbuilder_append_fmt( & to_c_str_entries,         "{ \"%s\",  sizeof(\"%s\") - 1 },\n", code,    code ); | ||||||
| 		string_append_fmt( & to_keyword_str_entries, "{ sizeof(\"%s\") - 1, \"%s\" },\n", keyword, keyword ); | 		strbuilder_append_fmt( & to_keyword_c_str_entries, "{  \"%s\", sizeof(\"%s\") - 1 },\n", keyword, keyword ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeEnum enum_code; | 	CodeEnum enum_code; | ||||||
| 	if (use_c_definition) { | 	if (use_c_definition) { | ||||||
| 		enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries), | 		enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", strbuilder_to_str(enum_entries), | ||||||
| 			"enum CodeType enum_underlying(u32) { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };" | 			"enum CodeType enum_underlying(u32) { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };" | ||||||
| 		)); | 		)); | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", string_to_strc(enum_entries), | 		enum_code = parse_enum(token_fmt_impl((3 + 1) / 2, "entries", strbuilder_to_str(enum_entries), | ||||||
| 			"enum CodeType : u32 { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };" | 			"enum CodeType : u32 { <entries> CT_NumTypes, CT_UnderlyingType = GEN_U32_MAX };" | ||||||
| 		)); | 		)); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #pragma push_macro("local_persist") | #pragma push_macro("local_persist") | ||||||
| #undef local_persist | #undef local_persist | ||||||
| 	StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) )); | 	Str      lookup_size  = strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) )); | ||||||
| 	CodeBody to_str_fns = parse_global_body( token_fmt( | 	CodeBody to_c_str_fns = parse_global_body( token_fmt( | ||||||
| 		"entries",  string_to_strc(to_str_entries) | 		"entries",  strbuilder_to_str(to_c_str_entries) | ||||||
| 	,	"keywords", string_to_strc(to_keyword_str_entries) | 	,	"keywords", strbuilder_to_str(to_keyword_c_str_entries) | ||||||
| 	,	"num",      lookup_size | 	,	"num",      lookup_size | ||||||
| 	, stringize( | 	, stringize( | ||||||
| 		inline | 		inline | ||||||
| 		StrC codetype_to_str( CodeType type ) | 		Str codetype_to_str( CodeType type ) | ||||||
| 		{ | 		{ | ||||||
| 			local_persist | 			local_persist | ||||||
| 			StrC lookup[<num>] = { | 			Str lookup[<num>] = { | ||||||
| 				<entries> | 				<entries> | ||||||
| 			}; | 			}; | ||||||
| 			return lookup[ type ]; | 			return lookup[ type ]; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		inline | 		inline | ||||||
| 		StrC codetype_to_keyword_str( CodeType type ) | 		Str codetype_to_keyword_str( CodeType type ) | ||||||
| 		{ | 		{ | ||||||
| 			local_persist | 			local_persist | ||||||
| 			StrC lookup[ <num> ] = { | 			Str lookup[ <num> ] = { | ||||||
| 				<keywords> | 				<keywords> | ||||||
| 			}; | 			}; | ||||||
| 			return lookup[ type ]; | 			return lookup[ type ]; | ||||||
| @@ -76,14 +76,14 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false ) | |||||||
| 		body_append(result, code_t); | 		body_append(result, code_t); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	body_append(result, to_str_fns); | 	body_append(result, to_c_str_fns); | ||||||
|  |  | ||||||
| 	if (! use_c_definition) { | 	if (! use_c_definition) { | ||||||
| 		#pragma push_macro("forceinline") | 		#pragma push_macro("forceinline") | ||||||
| 		#undef forceinline | 		#undef forceinline | ||||||
| 		CodeBody alias_mappings = parse_global_body(code( | 		CodeBody alias_mappings = parse_global_body(code( | ||||||
| 			forceinline StrC to_str        (CodeType type) { return codetype_to_str(type);         } | 			forceinline Str to_str        (CodeType type) { return codetype_to_str(type);         } | ||||||
| 			forceinline StrC to_keyword_str(CodeType type) { return codetype_to_keyword_str(type); } | 			forceinline Str to_keyword_str(CodeType type) { return codetype_to_keyword_str(type); } | ||||||
| 		)); | 		)); | ||||||
| 		#pragma pop_macro("forceinline") | 		#pragma pop_macro("forceinline") | ||||||
| 		body_append(result, alias_mappings); | 		body_append(result, alias_mappings); | ||||||
| @@ -93,19 +93,18 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false ) | |||||||
|  |  | ||||||
| CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | ||||||
| { | { | ||||||
| 	FixedArena_16KB scratch; fixed_arena_init(& scratch); | 	FixedArena_16KB scratch;       fixed_arena_init(& scratch); | ||||||
| 	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch); | 	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch); | ||||||
|  |  | ||||||
| 	CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path ); | 	CSV_Columns2 csv_enum       = parse_csv_two_columns( scratch_info, path ); | ||||||
| 	String enum_entries   = string_make_reserve( GlobalAllocator, 32 ); | 	StrBuilder enum_entries     = strbuilder_make_reserve( GlobalAllocator, 32 ); | ||||||
| 	String to_str_entries = string_make_reserve( GlobalAllocator, 32 ); | 	StrBuilder to_c_str_entries = strbuilder_make_reserve( GlobalAllocator, 32 ); | ||||||
|  |  | ||||||
| 	for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) { | 	for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) { | ||||||
| 		char const* enum_str     = csv_enum.Col_1[idx].string; | 		char const* enum_str     = csv_enum.Col_1[idx].string; | ||||||
| 		char const* entry_to_str = csv_enum.Col_2[idx].string; | 		char const* entry_to_str = csv_enum.Col_2[idx].string; | ||||||
|  | 		strbuilder_append_fmt( & enum_entries,     "Op_%s,\n", enum_str ); | ||||||
| 		string_append_fmt( & enum_entries, "Op_%s,\n", enum_str ); | 		strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str); | ||||||
| 		string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeEnum  enum_code; | 	CodeEnum  enum_code; | ||||||
| @@ -113,7 +112,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | |||||||
| 	{ | 	{ | ||||||
| 	#pragma push_macro("enum_underlying") | 	#pragma push_macro("enum_underlying") | ||||||
| 	#undef enum_underlying | 	#undef enum_underlying | ||||||
| 		enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( | 		enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize( | ||||||
| 			enum Operator enum_underlying(u32) | 			enum Operator enum_underlying(u32) | ||||||
| 			{ | 			{ | ||||||
| 				<entries> | 				<entries> | ||||||
| @@ -125,7 +124,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( | 		enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize( | ||||||
| 			enum Operator : u32 | 			enum Operator : u32 | ||||||
| 			{ | 			{ | ||||||
| 				<entries> | 				<entries> | ||||||
| @@ -137,16 +136,16 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | |||||||
|  |  | ||||||
| #pragma push_macro("local_persist") | #pragma push_macro("local_persist") | ||||||
| #undef local_persist | #undef local_persist | ||||||
| 	StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) )); | 	Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) )); | ||||||
| 	CodeFn to_str   = parse_function(token_fmt( | 	CodeFn to_str   = parse_function(token_fmt( | ||||||
| 		"entries", string_to_strc(to_str_entries) | 		"entries", strbuilder_to_str(to_c_str_entries) | ||||||
| 	,	"num",     lookup_size | 	,	"num",     lookup_size | ||||||
| 	, stringize( | 	, stringize( | ||||||
| 		inline | 		inline | ||||||
| 		StrC operator_to_str( Operator op ) | 		Str operator_to_str( Operator op ) | ||||||
| 		{ | 		{ | ||||||
| 			local_persist | 			local_persist | ||||||
| 			StrC lookup[<num>] = { | 			Str lookup[<num>] = { | ||||||
| 				<entries> | 				<entries> | ||||||
| 			}; | 			}; | ||||||
|  |  | ||||||
| @@ -169,7 +168,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | |||||||
| 	#pragma push_macro("forceinline") | 	#pragma push_macro("forceinline") | ||||||
| 	#undef forceinline | 	#undef forceinline | ||||||
| 		CodeBody alias_mappings = parse_global_body(code( | 		CodeBody alias_mappings = parse_global_body(code( | ||||||
| 			forceinline StrC to_str(Operator op) { return operator_to_str(op); } | 			forceinline Str to_str(Operator op) { return operator_to_str(op); } | ||||||
| 		)); | 		)); | ||||||
| 	#pragma pop_macro("forceinline") | 	#pragma pop_macro("forceinline") | ||||||
| 		body_append(result, alias_mappings); | 		body_append(result, alias_mappings); | ||||||
| @@ -179,20 +178,19 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | |||||||
|  |  | ||||||
| CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | ||||||
| { | { | ||||||
| 	FixedArena_16KB scratch; fixed_arena_init(& scratch); | 	FixedArena_16KB scratch;       fixed_arena_init(& scratch); | ||||||
| 	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch); | 	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch); | ||||||
|  |  | ||||||
| 	CSV_Columns2 csv_enum = parse_csv_two_columns( scratch_info, path ); | 	CSV_Columns2 csv_enum       = parse_csv_two_columns(   scratch_info, path ); | ||||||
| 	String enum_entries   = string_make_reserve( scratch_info, kilobytes(1) ); | 	StrBuilder enum_entries     = strbuilder_make_reserve( scratch_info, kilobytes(1) ); | ||||||
| 	String to_str_entries = string_make_reserve( scratch_info, kilobytes(1) ); | 	StrBuilder to_c_str_entries = strbuilder_make_reserve( scratch_info, kilobytes(1) ); | ||||||
|  |  | ||||||
| 	for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) | 	for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) | ||||||
| 	{ | 	{ | ||||||
| 		char const* enum_str     = csv_enum.Col_1[idx].string; | 		char const* enum_str     = csv_enum.Col_1[idx].string; | ||||||
| 		char const* entry_to_str = csv_enum.Col_2[idx].string; | 		char const* entry_to_str = csv_enum.Col_2[idx].string; | ||||||
|  | 		strbuilder_append_fmt( & enum_entries,     "Spec_%s,\n", enum_str ); | ||||||
| 		string_append_fmt( & enum_entries, "Spec_%s,\n", enum_str ); | 		strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str); | ||||||
| 		string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	CodeEnum enum_code; | 	CodeEnum enum_code; | ||||||
| @@ -200,7 +198,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | |||||||
| 	{ | 	{ | ||||||
| 	#pragma push_macro("enum_underlying") | 	#pragma push_macro("enum_underlying") | ||||||
| 	#undef enum_underlying | 	#undef enum_underlying | ||||||
| 		enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( | 		enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize( | ||||||
| 			enum Specifier enum_underlying(u32) | 			enum Specifier enum_underlying(u32) | ||||||
| 			{ | 			{ | ||||||
| 				<entries> | 				<entries> | ||||||
| @@ -212,7 +210,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), stringize( | 		enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), stringize( | ||||||
| 			enum Specifier : u32 | 			enum Specifier : u32 | ||||||
| 			{ | 			{ | ||||||
| 				<entries> | 				<entries> | ||||||
| @@ -221,8 +219,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | |||||||
| 			}; | 			}; | ||||||
| 		))); | 		))); | ||||||
| 	} | 	} | ||||||
|  | 	CodeFn is_trailing = parse_function(token_fmt("specifier", strbuilder_to_str(to_c_str_entries), stringize( | ||||||
| 	CodeFn is_trailing = parse_function(token_fmt("specifier", string_to_strc(to_str_entries), stringize( |  | ||||||
| 		inline | 		inline | ||||||
| 		bool spec_is_trailing( Specifier specifier ) | 		bool spec_is_trailing( Specifier specifier ) | ||||||
| 		{ | 		{ | ||||||
| @@ -240,16 +237,16 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | |||||||
| #undef do_once_end | #undef do_once_end | ||||||
| #undef forceinline | #undef forceinline | ||||||
| #undef neverinline | #undef neverinline | ||||||
| 	StrC lookup_size = string_to_strc(string_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) )); | 	Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) )); | ||||||
| 	CodeFn to_str   = parse_function(token_fmt( | 	CodeFn to_str   = parse_function(token_fmt( | ||||||
| 		"entries", string_to_strc(to_str_entries) | 		"entries", strbuilder_to_str(to_c_str_entries) | ||||||
| 	,	"num",     lookup_size | 	,	"num",     lookup_size | ||||||
| 	, stringize( | 	, stringize( | ||||||
| 		inline | 		inline | ||||||
| 		StrC spec_to_str( Specifier type ) | 		Str spec_to_str( Specifier type ) | ||||||
| 		{ | 		{ | ||||||
| 			local_persist | 			local_persist | ||||||
| 			StrC lookup[<num>] = { | 			Str lookup[<num>] = { | ||||||
| 				<entries> | 				<entries> | ||||||
| 			}; | 			}; | ||||||
|  |  | ||||||
| @@ -257,20 +254,20 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | |||||||
| 		} | 		} | ||||||
| 	))); | 	))); | ||||||
|  |  | ||||||
| 	CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize( | 	CodeFn to_type = parse_function( token_fmt( "entries", strbuilder_to_str(to_c_str_entries), stringize( | ||||||
| 		inline | 		inline | ||||||
| 		Specifier strc_to_specifier( StrC str ) | 		Specifier str_to_specifier( Str str ) | ||||||
| 		{ | 		{ | ||||||
| 			local_persist | 			local_persist | ||||||
| 			u32 keymap[ Spec_NumSpecifiers ]; | 			u32 keymap[ Spec_NumSpecifiers ]; | ||||||
| 			do_once_start | 			do_once_start | ||||||
| 				for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) | 				for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) | ||||||
| 				{ | 				{ | ||||||
| 					StrC enum_str = spec_to_str( (Specifier)index ); | 					Str enum_str = spec_to_str( (Specifier)index ); | ||||||
|  |  | ||||||
| 					// We subtract 1 to remove the null terminator | 					// We subtract 1 to remove the null terminator | ||||||
| 					// This is because the tokens lexed are not null terminated. | 					// This is because the tokens lexed are not null terminated. | ||||||
| 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1); | 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len  ); | ||||||
| 				} | 				} | ||||||
| 			do_once_end | 			do_once_end | ||||||
|  |  | ||||||
| @@ -308,8 +305,8 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | |||||||
| 	#pragma push_macro("forceinline") | 	#pragma push_macro("forceinline") | ||||||
| 	#undef forceinline | 	#undef forceinline | ||||||
| 		CodeBody alias_mappings = parse_global_body(code( | 		CodeBody alias_mappings = parse_global_body(code( | ||||||
| 			forceinline StrC      to_str (Specifier spec)            { return spec_to_str(spec); } | 			forceinline Str      to_str (Specifier spec)            { return spec_to_str(spec); } | ||||||
| 			forceinline Specifier to_type( StrC str )                { return strc_to_specifier(str); } | 			forceinline Specifier to_type( Str str )                { return str_to_specifier(str); } | ||||||
| 			forceinline bool      is_trailing( Specifier specifier ) { return spec_is_trailing(specifier); } | 			forceinline bool      is_trailing( Specifier specifier ) { return spec_is_trailing(specifier); } | ||||||
| 		)); | 		)); | ||||||
| 	#pragma pop_macro("forceinline") | 	#pragma pop_macro("forceinline") | ||||||
| @@ -320,7 +317,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | |||||||
|  |  | ||||||
| CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_definition = false ) | CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_definition = false ) | ||||||
| { | { | ||||||
| 	FixedArena_64KB scratch; fixed_arena_init(& scratch); | 	FixedArena_64KB scratch;       fixed_arena_init(& scratch); | ||||||
| 	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch); | 	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch); | ||||||
|  |  | ||||||
| 	FileContents enum_content = file_read_contents( scratch_info, file_zero_terminate, etok_path ); | 	FileContents enum_content = file_read_contents( scratch_info, file_zero_terminate, etok_path ); | ||||||
| @@ -333,51 +330,51 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | |||||||
| 	CSV_Object csv_attr_nodes; | 	CSV_Object csv_attr_nodes; | ||||||
| 	csv_parse( &csv_attr_nodes, rcast(char*, attrib_content.data), scratch_info, false ); | 	csv_parse( &csv_attr_nodes, rcast(char*, attrib_content.data), scratch_info, false ); | ||||||
|  |  | ||||||
| 	Array<ADT_Node> enum_strs          = csv_enum_nodes.nodes[0].nodes; | 	Array<ADT_Node> enum_strs            = csv_enum_nodes.nodes[0].nodes; | ||||||
| 	Array<ADT_Node> enum_str_strs      = csv_enum_nodes.nodes[1].nodes; | 	Array<ADT_Node> enum_c_str_strs      = csv_enum_nodes.nodes[1].nodes; | ||||||
| 	Array<ADT_Node> attribute_strs     = csv_attr_nodes.nodes[0].nodes; | 	Array<ADT_Node> attribute_strs       = csv_attr_nodes.nodes[0].nodes; | ||||||
| 	Array<ADT_Node> attribute_str_strs = csv_attr_nodes.nodes[1].nodes; | 	Array<ADT_Node> attribute_c_str_strs = csv_attr_nodes.nodes[1].nodes; | ||||||
|  |  | ||||||
| 	String enum_entries             = string_make_reserve( scratch_info, kilobytes(2) ); | 	StrBuilder enum_entries             = strbuilder_make_reserve( scratch_info, kilobytes(2) ); | ||||||
| 	String to_str_entries           = string_make_reserve( scratch_info, kilobytes(4) ); | 	StrBuilder to_c_str_entries         = strbuilder_make_reserve( scratch_info, kilobytes(4) ); | ||||||
| 	String attribute_entries        = string_make_reserve( scratch_info, kilobytes(2) ); | 	StrBuilder attribute_entries        = strbuilder_make_reserve( scratch_info, kilobytes(2) ); | ||||||
| 	String to_str_attributes        = string_make_reserve( scratch_info, kilobytes(4) ); | 	StrBuilder to_c_str_attributes      = strbuilder_make_reserve( scratch_info, kilobytes(4) ); | ||||||
| 	String attribute_define_entries = string_make_reserve( scratch_info, kilobytes(4) ); | 	StrBuilder attribute_define_entries = strbuilder_make_reserve( scratch_info, kilobytes(4) ); | ||||||
|  |  | ||||||
| 	for (usize idx = 0; idx < array_num(enum_strs); idx++) | 	for (usize idx = 0; idx < array_num(enum_strs); idx++) | ||||||
| 	{ | 	{ | ||||||
| 		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_c_str_strs [idx].string; | ||||||
|  |  | ||||||
| 		string_append_fmt( & enum_entries, "Tok_%s,\n", enum_str ); | 		strbuilder_append_fmt( & enum_entries,     "Tok_%s,\n",                         enum_str ); | ||||||
| 		string_append_fmt( & to_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | 		strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for ( usize idx = 0; idx < array_num(attribute_strs); idx++ ) | 	for ( usize idx = 0; idx < array_num(attribute_strs); idx++ ) | ||||||
| 	{ | 	{ | ||||||
| 		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_c_str_strs [idx].string; | ||||||
|  |  | ||||||
| 		string_append_fmt( & attribute_entries, "Tok_Attribute_%s,\n", attribute_str ); | 		strbuilder_append_fmt( & attribute_entries,        "Tok_Attribute_%s,\n",               attribute_str ); | ||||||
| 		string_append_fmt( & to_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | 		strbuilder_append_fmt( & to_c_str_attributes,      "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str); | ||||||
| 		string_append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str ); | 		strbuilder_append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str ); | ||||||
|  |  | ||||||
| 		if ( idx < array_num(attribute_strs) - 1 ) | 		if ( idx < array_num(attribute_strs) - 1 ) | ||||||
| 			string_append_strc( & attribute_define_entries, txt(" \\\n")); | 			strbuilder_append_str( & attribute_define_entries, txt(" \\\n")); | ||||||
| 		else | 		else | ||||||
| 			string_append_strc( & attribute_define_entries, txt("\n")); | 			strbuilder_append_str( & attribute_define_entries, txt("\n")); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") | #pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") | ||||||
| #undef GEN_DEFINE_ATTRIBUTE_TOKENS | #undef GEN_DEFINE_ATTRIBUTE_TOKENS | ||||||
| 	CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), string_to_strc(attribute_define_entries)  ); | 	CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), strbuilder_to_str(attribute_define_entries)  ); | ||||||
| #pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") | #pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS") | ||||||
|  |  | ||||||
| 	// We cannot parse this enum, it has Attribute names as enums | 	// We cannot parse this enum, it has Attribute names as enums | ||||||
| 	CodeEnum enum_code; | 	CodeEnum enum_code; | ||||||
| 	if (use_c_definition) | 	if (use_c_definition) | ||||||
| 	{ | 	{ | ||||||
| 		enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize( | 		enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), "attribute_toks", strbuilder_to_str(attribute_entries), stringize( | ||||||
| 			enum TokType | 			enum TokType | ||||||
| 			{ | 			{ | ||||||
| 				<entries> | 				<entries> | ||||||
| @@ -389,7 +386,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		enum_code = parse_enum(token_fmt("entries", string_to_strc(enum_entries), "attribute_toks", string_to_strc(attribute_entries), stringize( | 		enum_code = parse_enum(token_fmt("entries", strbuilder_to_str(enum_entries), "attribute_toks", strbuilder_to_str(attribute_entries), stringize( | ||||||
| 			enum TokType : u32 | 			enum TokType : u32 | ||||||
| 			{ | 			{ | ||||||
| 				<entries> | 				<entries> | ||||||
| @@ -405,12 +402,12 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | |||||||
| #undef local_persist | #undef local_persist | ||||||
| #undef do_once_start | #undef do_once_start | ||||||
| #undef do_once_end | #undef do_once_end | ||||||
| 	CodeFn to_str = parse_function(token_fmt("entries", string_to_strc(to_str_entries), "attribute_toks", string_to_strc(to_str_attributes), stringize( | 	CodeFn to_str = parse_function(token_fmt("entries", strbuilder_to_str(to_c_str_entries), "attribute_toks", strbuilder_to_str(to_c_str_attributes), stringize( | ||||||
| 		inline | 		inline | ||||||
| 		StrC toktype_to_str( TokType type ) | 		Str toktype_to_str( TokType type ) | ||||||
| 		{ | 		{ | ||||||
| 			local_persist | 			local_persist | ||||||
| 			StrC lookup[] = { | 			Str lookup[] = { | ||||||
| 				<entries> | 				<entries> | ||||||
| 				<attribute_toks> | 				<attribute_toks> | ||||||
| 			}; | 			}; | ||||||
| @@ -419,20 +416,20 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | |||||||
| 		} | 		} | ||||||
| 	))); | 	))); | ||||||
|  |  | ||||||
| 	CodeFn to_type = parse_function( token_fmt( "entries", string_to_strc(to_str_entries), stringize( | 	CodeFn to_type = parse_function( token_fmt( "entries", strbuilder_to_str(to_c_str_entries), stringize( | ||||||
| 		inline | 		inline | ||||||
| 		TokType strc_to_toktype( StrC str ) | 		TokType str_to_toktype( Str str ) | ||||||
| 		{ | 		{ | ||||||
| 			local_persist | 			local_persist | ||||||
| 			u32 keymap[ Tok_NumTokens ]; | 			u32 keymap[ Tok_NumTokens ]; | ||||||
| 			do_once_start | 			do_once_start | ||||||
| 				for ( u32 index = 0; index < Tok_NumTokens; index++ ) | 				for ( u32 index = 0; index < Tok_NumTokens; index++ ) | ||||||
| 				{ | 				{ | ||||||
| 					StrC enum_str = toktype_to_str( (TokType)index ); | 					Str enum_str = toktype_to_str( (TokType)index ); | ||||||
|  |  | ||||||
| 					// We subtract 1 to remove the null terminator | 					// We subtract 1 to remove the null terminator | ||||||
| 					// This is because the tokens lexed are not null terminated. | 					// This is because the tokens lexed are not null terminated. | ||||||
| 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1); | 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len); | ||||||
| 				} | 				} | ||||||
| 			do_once_end | 			do_once_end | ||||||
|  |  | ||||||
| @@ -508,7 +505,7 @@ CodeBody gen_ast_inlines() | |||||||
| 		{ | 		{ | ||||||
| 			if ( ast == nullptr ) | 			if ( ast == nullptr ) | ||||||
| 			{ | 			{ | ||||||
| 				log_failure( "Attempt to dereference a nullptr!" ); | 				log_failure( "Attempt to dereference a nullptr!\n" ); | ||||||
| 				return nullptr; | 				return nullptr; | ||||||
| 			} | 			} | ||||||
| 			return ast; | 			return ast; | ||||||
| @@ -518,59 +515,59 @@ CodeBody gen_ast_inlines() | |||||||
| #pragma pop_macro("GEN_NS") | #pragma pop_macro("GEN_NS") | ||||||
| #pragma pop_macro("CodeInvalid") | #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", Str 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", Str name(CodeBody),           code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_attr     = parse_global_body( token_fmt( "typename", StrC name(CodeAttributes),     code_impl_tmpl )); | 	CodeBody impl_code_attr     = parse_global_body( token_fmt( "typename", Str name(CodeAttributes),     code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_cmt      = parse_global_body( token_fmt( "typename", StrC name(CodeComment),        code_impl_tmpl )); | 	CodeBody impl_code_cmt      = parse_global_body( token_fmt( "typename", Str name(CodeComment),        code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_constr   = parse_global_body( token_fmt( "typename", StrC name(CodeConstructor),    code_impl_tmpl )); | 	CodeBody impl_code_constr   = parse_global_body( token_fmt( "typename", Str name(CodeConstructor),    code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_class    = parse_global_body( token_fmt( "typename", StrC name(CodeClass),          code_impl_tmpl )); | 	CodeBody impl_code_class    = parse_global_body( token_fmt( "typename", Str name(CodeClass),          code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_define   = parse_global_body( token_fmt( "typename", StrC name(CodeDefine),         code_impl_tmpl )); | 	CodeBody impl_code_define   = parse_global_body( token_fmt( "typename", Str name(CodeDefine),         code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", StrC name(CodeDestructor),     code_impl_tmpl )); | 	CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", Str name(CodeDestructor),     code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_enum     = parse_global_body( token_fmt( "typename", StrC name(CodeEnum),           code_impl_tmpl )); | 	CodeBody impl_code_enum     = parse_global_body( token_fmt( "typename", Str name(CodeEnum),           code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_exec     = parse_global_body( token_fmt( "typename", StrC name(CodeExec),           code_impl_tmpl )); | 	CodeBody impl_code_exec     = parse_global_body( token_fmt( "typename", Str name(CodeExec),           code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_extern   = parse_global_body( token_fmt( "typename", StrC name(CodeExtern),         code_impl_tmpl )); | 	CodeBody impl_code_extern   = parse_global_body( token_fmt( "typename", Str name(CodeExtern),         code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_include  = parse_global_body( token_fmt( "typename", StrC name(CodeInclude),        code_impl_tmpl )); | 	CodeBody impl_code_include  = parse_global_body( token_fmt( "typename", Str name(CodeInclude),        code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_friend   = parse_global_body( token_fmt( "typename", StrC name(CodeFriend),         code_impl_tmpl )); | 	CodeBody impl_code_friend   = parse_global_body( token_fmt( "typename", Str name(CodeFriend),         code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_fn	    = parse_global_body( token_fmt( "typename", StrC name(CodeFn),             code_impl_tmpl )); | 	CodeBody impl_code_fn	    = parse_global_body( token_fmt( "typename", Str name(CodeFn),             code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_module   = parse_global_body( token_fmt( "typename", StrC name(CodeModule),         code_impl_tmpl )); | 	CodeBody impl_code_module   = parse_global_body( token_fmt( "typename", Str name(CodeModule),         code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_ns       = parse_global_body( token_fmt( "typename", StrC name(CodeNS),             code_impl_tmpl )); | 	CodeBody impl_code_ns       = parse_global_body( token_fmt( "typename", Str name(CodeNS),             code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_op       = parse_global_body( token_fmt( "typename", StrC name(CodeOperator),       code_impl_tmpl )); | 	CodeBody impl_code_op       = parse_global_body( token_fmt( "typename", Str name(CodeOperator),       code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_opcast   = parse_global_body( token_fmt( "typename", StrC name(CodeOpCast),         code_impl_tmpl )); | 	CodeBody impl_code_opcast   = parse_global_body( token_fmt( "typename", Str name(CodeOpCast),         code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_params   = parse_global_body( token_fmt( "typename", StrC name(CodeParams),         code_impl_tmpl )); | 	CodeBody impl_code_params   = parse_global_body( token_fmt( "typename", Str name(CodeParams),         code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_pragma   = parse_global_body( token_fmt( "typename", StrC name(CodePragma),         code_impl_tmpl )); | 	CodeBody impl_code_pragma   = parse_global_body( token_fmt( "typename", Str name(CodePragma),         code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_precond  = parse_global_body( token_fmt( "typename", StrC name(CodePreprocessCond), code_impl_tmpl )); | 	CodeBody impl_code_precond  = parse_global_body( token_fmt( "typename", Str name(CodePreprocessCond), code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_specs    = parse_global_body( token_fmt( "typename", StrC name(CodeSpecifiers),     code_impl_tmpl )); | 	CodeBody impl_code_specs    = parse_global_body( token_fmt( "typename", Str name(CodeSpecifiers),     code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_struct   = parse_global_body( token_fmt( "typename", StrC name(CodeStruct),         code_impl_tmpl )); | 	CodeBody impl_code_struct   = parse_global_body( token_fmt( "typename", Str name(CodeStruct),         code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_tmpl     = parse_global_body( token_fmt( "typename", StrC name(CodeTemplate),       code_impl_tmpl )); | 	CodeBody impl_code_tmpl     = parse_global_body( token_fmt( "typename", Str name(CodeTemplate),       code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_type     = parse_global_body( token_fmt( "typename", StrC name(CodeTypename),       code_impl_tmpl )); | 	CodeBody impl_code_type     = parse_global_body( token_fmt( "typename", Str name(CodeTypename),       code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_typedef  = parse_global_body( token_fmt( "typename", StrC name(CodeTypedef),        code_impl_tmpl )); | 	CodeBody impl_code_typedef  = parse_global_body( token_fmt( "typename", Str name(CodeTypedef),        code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_union    = parse_global_body( token_fmt( "typename", StrC name(CodeUnion),          code_impl_tmpl )); | 	CodeBody impl_code_union    = parse_global_body( token_fmt( "typename", Str name(CodeUnion),          code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_using    = parse_global_body( token_fmt( "typename", StrC name(CodeUsing),          code_impl_tmpl )); | 	CodeBody impl_code_using    = parse_global_body( token_fmt( "typename", Str name(CodeUsing),          code_impl_tmpl )); | ||||||
| 	CodeBody impl_code_var      = parse_global_body( token_fmt( "typename", StrC name(CodeVar),            code_impl_tmpl )); | 	CodeBody impl_code_var      = parse_global_body( token_fmt( "typename", Str name(CodeVar),            code_impl_tmpl )); | ||||||
|  |  | ||||||
| 	body_append(impl_code_attr,     parse_global_body( token_fmt( "typename", StrC name(Attributes),     codetype_impl_tmpl ))); | 	body_append(impl_code_attr,     parse_global_body( token_fmt( "typename", Str name(Attributes),     codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_cmt,      parse_global_body( token_fmt( "typename", StrC name(Comment),        codetype_impl_tmpl ))); | 	body_append(impl_code_cmt,      parse_global_body( token_fmt( "typename", Str name(Comment),        codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_constr,   parse_global_body( token_fmt( "typename", StrC name(Constructor),    codetype_impl_tmpl ))); | 	body_append(impl_code_constr,   parse_global_body( token_fmt( "typename", Str name(Constructor),    codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_define,   parse_global_body( token_fmt( "typename", StrC name(Define),         codetype_impl_tmpl ))); | 	body_append(impl_code_define,   parse_global_body( token_fmt( "typename", Str name(Define),         codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_destruct, parse_global_body( token_fmt( "typename", StrC name(Destructor),     codetype_impl_tmpl ))); | 	body_append(impl_code_destruct, parse_global_body( token_fmt( "typename", Str name(Destructor),     codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_enum,     parse_global_body( token_fmt( "typename", StrC name(Enum),           codetype_impl_tmpl ))); | 	body_append(impl_code_enum,     parse_global_body( token_fmt( "typename", Str name(Enum),           codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_exec,     parse_global_body( token_fmt( "typename", StrC name(Exec),           codetype_impl_tmpl ))); | 	body_append(impl_code_exec,     parse_global_body( token_fmt( "typename", Str name(Exec),           codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_extern,   parse_global_body( token_fmt( "typename", StrC name(Extern),         codetype_impl_tmpl ))); | 	body_append(impl_code_extern,   parse_global_body( token_fmt( "typename", Str name(Extern),         codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_include,  parse_global_body( token_fmt( "typename", StrC name(Include),        codetype_impl_tmpl ))); | 	body_append(impl_code_include,  parse_global_body( token_fmt( "typename", Str name(Include),        codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_friend,   parse_global_body( token_fmt( "typename", StrC name(Friend),         codetype_impl_tmpl ))); | 	body_append(impl_code_friend,   parse_global_body( token_fmt( "typename", Str name(Friend),         codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_fn,       parse_global_body( token_fmt( "typename", StrC name(Fn),             codetype_impl_tmpl ))); | 	body_append(impl_code_fn,       parse_global_body( token_fmt( "typename", Str name(Fn),             codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_module,   parse_global_body( token_fmt( "typename", StrC name(Module),         codetype_impl_tmpl ))); | 	body_append(impl_code_module,   parse_global_body( token_fmt( "typename", Str name(Module),         codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_ns,       parse_global_body( token_fmt( "typename", StrC name(NS),             codetype_impl_tmpl ))); | 	body_append(impl_code_ns,       parse_global_body( token_fmt( "typename", Str name(NS),             codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_op,       parse_global_body( token_fmt( "typename", StrC name(Operator),       codetype_impl_tmpl ))); | 	body_append(impl_code_op,       parse_global_body( token_fmt( "typename", Str name(Operator),       codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_opcast,   parse_global_body( token_fmt( "typename", StrC name(OpCast),         codetype_impl_tmpl ))); | 	body_append(impl_code_opcast,   parse_global_body( token_fmt( "typename", Str name(OpCast),         codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_pragma,   parse_global_body( token_fmt( "typename", StrC name(Pragma),         codetype_impl_tmpl ))); | 	body_append(impl_code_pragma,   parse_global_body( token_fmt( "typename", Str name(Pragma),         codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_precond,  parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), codetype_impl_tmpl ))); | 	body_append(impl_code_precond,  parse_global_body( token_fmt( "typename", Str name(PreprocessCond), codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_tmpl,     parse_global_body( token_fmt( "typename", StrC name(Template),       codetype_impl_tmpl ))); | 	body_append(impl_code_tmpl,     parse_global_body( token_fmt( "typename", Str name(Template),       codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_type,     parse_global_body( token_fmt( "typename", StrC name(Typename),       codetype_impl_tmpl ))); | 	body_append(impl_code_type,     parse_global_body( token_fmt( "typename", Str name(Typename),       codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_typedef,  parse_global_body( token_fmt( "typename", StrC name(Typedef),        codetype_impl_tmpl ))); | 	body_append(impl_code_typedef,  parse_global_body( token_fmt( "typename", Str name(Typedef),        codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_union,    parse_global_body( token_fmt( "typename", StrC name(Union),          codetype_impl_tmpl ))); | 	body_append(impl_code_union,    parse_global_body( token_fmt( "typename", Str name(Union),          codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_using,    parse_global_body( token_fmt( "typename", StrC name(Using),          codetype_impl_tmpl ))); | 	body_append(impl_code_using,    parse_global_body( token_fmt( "typename", Str name(Using),          codetype_impl_tmpl ))); | ||||||
| 	body_append(impl_code_var,      parse_global_body( token_fmt( "typename", StrC name(Var),            codetype_impl_tmpl ))); | 	body_append(impl_code_var,      parse_global_body( token_fmt( "typename", Str name(Var),            codetype_impl_tmpl ))); | ||||||
|  |  | ||||||
| 	#pragma push_macro("forceinline") | 	#pragma push_macro("forceinline") | ||||||
| 	#undef forceinline | 	#undef forceinline | ||||||
| @@ -582,34 +579,34 @@ CodeBody gen_ast_inlines() | |||||||
| 	); | 	); | ||||||
| 	#pragma pop_macro("forceinline") | 	#pragma pop_macro("forceinline") | ||||||
|  |  | ||||||
| 	CodeBody impl_cast_body      = parse_global_body( token_fmt( "typename", StrC name(Body),           cast_tmpl )); | 	CodeBody impl_cast_body      = parse_global_body( token_fmt( "typename", Str name(Body),           cast_tmpl )); | ||||||
| 	CodeBody impl_cast_attribute = parse_global_body( token_fmt( "typename", StrC name(Attributes),     cast_tmpl )); | 	CodeBody impl_cast_attribute = parse_global_body( token_fmt( "typename", Str name(Attributes),     cast_tmpl )); | ||||||
| 	CodeBody impl_cast_cmt       = parse_global_body( token_fmt( "typename", StrC name(Comment),        cast_tmpl )); | 	CodeBody impl_cast_cmt       = parse_global_body( token_fmt( "typename", Str name(Comment),        cast_tmpl )); | ||||||
| 	CodeBody impl_cast_constr    = parse_global_body( token_fmt( "typename", StrC name(Constructor),    cast_tmpl )); | 	CodeBody impl_cast_constr    = parse_global_body( token_fmt( "typename", Str name(Constructor),    cast_tmpl )); | ||||||
| 	CodeBody impl_cast_class     = parse_global_body( token_fmt( "typename", StrC name(Class),          cast_tmpl )); | 	CodeBody impl_cast_class     = parse_global_body( token_fmt( "typename", Str name(Class),          cast_tmpl )); | ||||||
| 	CodeBody impl_cast_define    = parse_global_body( token_fmt( "typename", StrC name(Define),         cast_tmpl )); | 	CodeBody impl_cast_define    = parse_global_body( token_fmt( "typename", Str name(Define),         cast_tmpl )); | ||||||
| 	CodeBody impl_cast_destruct  = parse_global_body( token_fmt( "typename", StrC name(Destructor),     cast_tmpl )); | 	CodeBody impl_cast_destruct  = parse_global_body( token_fmt( "typename", Str name(Destructor),     cast_tmpl )); | ||||||
| 	CodeBody impl_cast_enum      = parse_global_body( token_fmt( "typename", StrC name(Enum),           cast_tmpl )); | 	CodeBody impl_cast_enum      = parse_global_body( token_fmt( "typename", Str name(Enum),           cast_tmpl )); | ||||||
| 	CodeBody impl_cast_exec      = parse_global_body( token_fmt( "typename", StrC name(Exec),           cast_tmpl )); | 	CodeBody impl_cast_exec      = parse_global_body( token_fmt( "typename", Str name(Exec),           cast_tmpl )); | ||||||
| 	CodeBody impl_cast_extern    = parse_global_body( token_fmt( "typename", StrC name(Extern),         cast_tmpl )); | 	CodeBody impl_cast_extern    = parse_global_body( token_fmt( "typename", Str name(Extern),         cast_tmpl )); | ||||||
| 	CodeBody impl_cast_friend    = parse_global_body( token_fmt( "typename", StrC name(Friend),         cast_tmpl )); | 	CodeBody impl_cast_friend    = parse_global_body( token_fmt( "typename", Str name(Friend),         cast_tmpl )); | ||||||
| 	CodeBody impl_cast_fn        = parse_global_body( token_fmt( "typename", StrC name(Fn),             cast_tmpl )); | 	CodeBody impl_cast_fn        = parse_global_body( token_fmt( "typename", Str name(Fn),             cast_tmpl )); | ||||||
| 	CodeBody impl_cast_include   = parse_global_body( token_fmt( "typename", StrC name(Include),        cast_tmpl )); | 	CodeBody impl_cast_include   = parse_global_body( token_fmt( "typename", Str name(Include),        cast_tmpl )); | ||||||
| 	CodeBody impl_cast_module    = parse_global_body( token_fmt( "typename", StrC name(Module),         cast_tmpl )); | 	CodeBody impl_cast_module    = parse_global_body( token_fmt( "typename", Str name(Module),         cast_tmpl )); | ||||||
| 	CodeBody impl_cast_ns        = parse_global_body( token_fmt( "typename", StrC name(NS),             cast_tmpl )); | 	CodeBody impl_cast_ns        = parse_global_body( token_fmt( "typename", Str name(NS),             cast_tmpl )); | ||||||
| 	CodeBody impl_cast_op        = parse_global_body( token_fmt( "typename", StrC name(Operator),       cast_tmpl )); | 	CodeBody impl_cast_op        = parse_global_body( token_fmt( "typename", Str name(Operator),       cast_tmpl )); | ||||||
| 	CodeBody impl_cast_opcast    = parse_global_body( token_fmt( "typename", StrC name(OpCast),         cast_tmpl )); | 	CodeBody impl_cast_opcast    = parse_global_body( token_fmt( "typename", Str name(OpCast),         cast_tmpl )); | ||||||
| 	CodeBody impl_cast_params    = parse_global_body( token_fmt( "typename", StrC name(Params),         cast_tmpl )); | 	CodeBody impl_cast_params    = parse_global_body( token_fmt( "typename", Str name(Params),         cast_tmpl )); | ||||||
| 	CodeBody impl_cast_pragma    = parse_global_body( token_fmt( "typename", StrC name(Pragma),         cast_tmpl )); | 	CodeBody impl_cast_pragma    = parse_global_body( token_fmt( "typename", Str name(Pragma),         cast_tmpl )); | ||||||
| 	CodeBody impl_cast_precond   = parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), cast_tmpl )); | 	CodeBody impl_cast_precond   = parse_global_body( token_fmt( "typename", Str name(PreprocessCond), cast_tmpl )); | ||||||
| 	CodeBody impl_cast_specs     = parse_global_body( token_fmt( "typename", StrC name(Specifiers),     cast_tmpl )); | 	CodeBody impl_cast_specs     = parse_global_body( token_fmt( "typename", Str name(Specifiers),     cast_tmpl )); | ||||||
| 	CodeBody impl_cast_struct    = parse_global_body( token_fmt( "typename", StrC name(Struct),         cast_tmpl )); | 	CodeBody impl_cast_struct    = parse_global_body( token_fmt( "typename", Str name(Struct),         cast_tmpl )); | ||||||
| 	CodeBody impl_cast_tmpl      = parse_global_body( token_fmt( "typename", StrC name(Template),       cast_tmpl )); | 	CodeBody impl_cast_tmpl      = parse_global_body( token_fmt( "typename", Str name(Template),       cast_tmpl )); | ||||||
| 	CodeBody impl_cast_type      = parse_global_body( token_fmt( "typename", StrC name(Typename),       cast_tmpl )); | 	CodeBody impl_cast_type      = parse_global_body( token_fmt( "typename", Str name(Typename),       cast_tmpl )); | ||||||
| 	CodeBody impl_cast_typedef   = parse_global_body( token_fmt( "typename", StrC name(Typedef),        cast_tmpl )); | 	CodeBody impl_cast_typedef   = parse_global_body( token_fmt( "typename", Str name(Typedef),        cast_tmpl )); | ||||||
| 	CodeBody impl_cast_union     = parse_global_body( token_fmt( "typename", StrC name(Union),          cast_tmpl )); | 	CodeBody impl_cast_union     = parse_global_body( token_fmt( "typename", Str name(Union),          cast_tmpl )); | ||||||
| 	CodeBody impl_cast_using     = parse_global_body( token_fmt( "typename", StrC name(Using),          cast_tmpl )); | 	CodeBody impl_cast_using     = parse_global_body( token_fmt( "typename", Str name(Using),          cast_tmpl )); | ||||||
| 	CodeBody impl_cast_var       = parse_global_body( token_fmt( "typename", StrC name(Var),            cast_tmpl )); | 	CodeBody impl_cast_var       = parse_global_body( token_fmt( "typename", Str name(Var),            cast_tmpl )); | ||||||
|  |  | ||||||
| 	CodeBody result = def_global_body( args( | 	CodeBody result = def_global_body( args( | ||||||
| 		def_pragma( txt("region generated code inline implementation")), | 		def_pragma( txt("region generated code inline implementation")), | ||||||
|   | |||||||
| @@ -21,22 +21,22 @@ using namespace gen; | |||||||
| void clang_format_file( char const* path, char const* style_path ) | void clang_format_file( char const* path, char const* style_path ) | ||||||
| { | { | ||||||
| 	GEN_ASSERT_NOT_NULL(path); | 	GEN_ASSERT_NOT_NULL(path); | ||||||
| 	String resolved_path = string_make_strc(GlobalAllocator, to_strc_from_c_str(path)); | 	StrBuilder resolved_path = strbuilder_make_str(GlobalAllocator, to_str_from_c_str(path)); | ||||||
| 	String style_arg; | 	StrBuilder style_arg; | ||||||
| 	if (style_path) { | 	if (style_path) { | ||||||
| 		style_arg = string_make_strc(GlobalAllocator, txt("-style=file:")); | 		style_arg = strbuilder_make_str(GlobalAllocator, txt("-style=file:")); | ||||||
| 		string_append_fmt( & style_arg, "%s ", style_path ); | 		strbuilder_append_fmt( & style_arg, "%s ", style_path ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	StrC clang_format      = txt("clang-format "); | 	Str clang_format      = txt("clang-format "); | ||||||
| 	StrC cf_format_inplace = txt("-i "); | 	Str cf_format_inplace = txt("-i "); | ||||||
| 	StrC cf_verbose        = txt("-verbose "); | 	Str cf_verbose        = txt("-verbose "); | ||||||
|  |  | ||||||
| 	String command = string_make_strc( GlobalAllocator, clang_format ); | 	StrBuilder command = strbuilder_make_str( GlobalAllocator, clang_format ); | ||||||
| 	string_append_strc( & command, cf_format_inplace ); | 	strbuilder_append_str( & command, cf_format_inplace ); | ||||||
| 	string_append_strc( & command, cf_verbose ); | 	strbuilder_append_str( & command, cf_verbose ); | ||||||
| 	string_append_string( & command, style_arg ); | 	strbuilder_append_string( & command, style_arg ); | ||||||
| 	string_append_string( & command, resolved_path ); | 	strbuilder_append_string( & command, resolved_path ); | ||||||
| 	system( command ); | 	system( command ); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -48,11 +48,11 @@ void refactor_file( char const* path, char const* refactor_script ) | |||||||
| 	GEN_ASSERT_NOT_NULL(path); | 	GEN_ASSERT_NOT_NULL(path); | ||||||
| 	GEN_ASSERT_NOT_NULL(refactor_script); | 	GEN_ASSERT_NOT_NULL(refactor_script); | ||||||
|  |  | ||||||
| 	String command = string_make_strc(GlobalAllocator, txt("refactor ")); | 	StrBuilder command = strbuilder_make_str(GlobalAllocator, txt("refactor ")); | ||||||
| 	// string_append_strc( & command, txt("-debug ") ); | 	// strbuilder_append_str( & command, txt("-debug ") ); | ||||||
| 	string_append_strc( & command, txt("-num=1 ") ); | 	strbuilder_append_str( & command, txt("-num=1 ") ); | ||||||
| 	string_append_fmt( & command, "-src=%s ", path ); | 	strbuilder_append_fmt( & command, "-src=%s ", path ); | ||||||
| 	string_append_fmt( & command,"-spec=%s ", refactor_script ); | 	strbuilder_append_fmt( & command,"-spec=%s ", refactor_script ); | ||||||
| 	system(command); | 	system(command); | ||||||
| 	log_fmt("\n"); | 	log_fmt("\n"); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ The full definitions of all asts are within: | |||||||
|  |  | ||||||
| * [`ast.hpp`](../base/components/ast.hpp) | * [`ast.hpp`](../base/components/ast.hpp) | ||||||
| * [`ast_types.hpp`](../base/components/ast_types.hpp) | * [`ast_types.hpp`](../base/components/ast_types.hpp) | ||||||
| * [`code_types.hpp`](../base/components/ast_types.hpp) | * [`code_types.hpp`](../base/components/code_types.hpp) | ||||||
|  |  | ||||||
| The C/C++ interface procedures are located with `ast.hpp` (for the Code type), and `code_types.hpp` for all others. | The C/C++ interface procedures are located with `ast.hpp` (for the Code type), and `code_types.hpp` for all others. | ||||||
|  |  | ||||||
| @@ -46,13 +46,13 @@ The C/C++ interface procedures are located with `ast.hpp` (for the Code type), a | |||||||
| All code types can either serialize using a function of the pattern: | All code types can either serialize using a function of the pattern: | ||||||
|  |  | ||||||
| ```c | ```c | ||||||
| String <prefix>_to_string(Code code); | StrBuilder <prefix>_to_strbuilder(Code code); | ||||||
| // or | // or | ||||||
| <prefix>_to_string(Code code, String& result); | <prefix>_to_strbuilder(Code code, StrBuilder& result); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator. | Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator. | ||||||
|  |  | ||||||
| Serialization of for the AST is defined for `Code` in [`ast.chpp`](../base/components/ast.cpp) with `code_to_string_ptr` & `code_to_string`.   | Serialization of for the AST is defined for `Code` in [`ast.chpp`](../base/components/ast.cpp) with `code_to_strbuilder_ptr` & `code_to_strbuilder`.   | ||||||
| Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).   | Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).   | ||||||
| Gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after serializing. | Gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after serializing. | ||||||
|   | |||||||
| @@ -248,7 +248,7 @@ ModuleFlag     ModuleFlags; | |||||||
| ``` | ``` | ||||||
|  |  | ||||||
| UnderlyingTypeMacro is a macro the library natively supports: `enum_underlying(type)` that is meant to behave as a wrapper for underlying type assignment.   | UnderlyingTypeMacro is a macro the library natively supports: `enum_underlying(type)` that is meant to behave as a wrapper for underlying type assignment.   | ||||||
| The `enum_underlying_sig` is a `StrC` global var that can be set which will be defined within `PreprocessorDefines` and used in `parser_parse_enum` to identify a valid macro. | The `enum_underlying_sig` is a `Str` global var that can be set which will be defined within `PreprocessorDefines` and used in `parser_parse_enum` to identify a valid macro. | ||||||
|  |  | ||||||
| Serialization: | Serialization: | ||||||
|  |  | ||||||
| @@ -637,7 +637,7 @@ Serialization: | |||||||
|  |  | ||||||
| `<Name>` currently has the full serialization of anything with | `<Name>` currently has the full serialization of anything with | ||||||
|  |  | ||||||
| *Note: ArrExpr is not used in serialization by `typename_to_string_ref` its instead handled by a parent AST's serailization (variable, typedef, using).* | *Note: ArrExpr is not used in serialization by `typename_to_strbuilder_ref` its instead handled by a parent AST's serailization (variable, typedef, using).* | ||||||
|  |  | ||||||
| ## Typedef | ## Typedef | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,8 +12,8 @@ gencpp uses a hand-written recursive descent parser. Both the lexer and parser c | |||||||
|  |  | ||||||
| ### Lexer | ### Lexer | ||||||
|  |  | ||||||
| The lex procedure does the lexical pass of content provided as a `StrC` type. | The lex procedure does the lexical pass of content provided as a `Str` type.   | ||||||
| The tokens are stored (for now) in `gen::parser::Lexer_Tokens`. | The tokens are stored (for now) in `Lexer_Tokens`. | ||||||
|  |  | ||||||
| Fields: | Fields: | ||||||
|  |  | ||||||
| @@ -75,7 +75,7 @@ The parser has a limited user interface, only specific types of definitions or s | |||||||
| Each public user interface procedure has the following format: | Each public user interface procedure has the following format: | ||||||
|  |  | ||||||
| ```cpp | ```cpp | ||||||
| <code type> parse_<definition type>( StrC def ) | <code type> parse_<definition type>( Str def ) | ||||||
| { | { | ||||||
|     check_parse_args( def ); |     check_parse_args( def ); | ||||||
|     using namespace Parser; |     using namespace Parser; | ||||||
| @@ -287,7 +287,7 @@ In the future statements and expressions will be parsed. | |||||||
|         1. Attributes ( Standard, GNU, MSVC, Macro ) : `parse_attributes` |         1. Attributes ( Standard, GNU, MSVC, Macro ) : `parse_attributes` | ||||||
|         2. Specifiers ( consteval, constexpr, constinit, extern, forceinline, global, inline, internal_linkage, neverinline, static ) |         2. Specifiers ( consteval, constexpr, constinit, extern, forceinline, global, inline, internal_linkage, neverinline, static ) | ||||||
|         3. Is either ( identifier, const specifier, long, short, signed, unsigned, bool, char, double, int) |         3. Is either ( identifier, const specifier, long, short, signed, unsigned, bool, char, double, int) | ||||||
|             1. Attempt to parse as constrcutor or destructor : `parse_global_nspace_constructor_destructor` |             1. Attempt to parse as construtor or destructor : `parse_global_nspace_constructor_destructor` | ||||||
|             2. If its an operator cast (definition outside class) : `parse_operator_cast` |             2. If its an operator cast (definition outside class) : `parse_operator_cast` | ||||||
|             3. Its an operator, function, or varaible : `parse_operator_function_or_varaible` |             3. Its an operator, function, or varaible : `parse_operator_function_or_varaible` | ||||||
| 4. If its not a global body, consume the closing curly brace | 4. If its not a global body, consume the closing curly brace | ||||||
|   | |||||||
| @@ -15,25 +15,25 @@ You can think of this parser as *frontend parser* vs a *semantic parser*. Its in | |||||||
| User exposed interface: | User exposed interface: | ||||||
|  |  | ||||||
| ```cpp | ```cpp | ||||||
| CodeClass       parse_class        ( StrC class_def       ); | CodeClass       parse_class        ( Str class_def       ); | ||||||
| CodeConstructor parse_constructor  ( StrC constructor_def ); | CodeConstructor parse_constructor  ( Str constructor_def ); | ||||||
| CodeDestructor  parse_destructor   ( StrC destructor_def  ); | CodeDestructor  parse_destructor   ( Str destructor_def  ); | ||||||
| CodeEnum        parse_enum         ( StrC enum_def        ); | CodeEnum        parse_enum         ( Str enum_def        ); | ||||||
| CodeBody        parse_export_body  ( StrC export_def      ); | CodeBody        parse_export_body  ( Str export_def      ); | ||||||
| CodeExtern      parse_extern_link  ( StrC exten_link_def  ); | CodeExtern      parse_extern_link  ( Str exten_link_def  ); | ||||||
| CodeFriend      parse_friend       ( StrC friend_def      ); | CodeFriend      parse_friend       ( Str friend_def      ); | ||||||
| CodeFn          parse_function     ( StrC fn_def          ); | CodeFn          parse_function     ( Str fn_def          ); | ||||||
| CodeBody        parse_global_body  ( StrC body_def        ); | CodeBody        parse_global_body  ( Str body_def        ); | ||||||
| CodeNS          parse_namespace    ( StrC namespace_def   ); | CodeNS          parse_namespace    ( Str namespace_def   ); | ||||||
| CodeOperator    parse_operator     ( StrC operator_def    ); | CodeOperator    parse_operator     ( Str operator_def    ); | ||||||
| CodeOpCast      parse_operator_cast( StrC operator_def    ); | CodeOpCast      parse_operator_cast( Str operator_def    ); | ||||||
| CodeStruct      parse_struct       ( StrC struct_def      ); | CodeStruct      parse_struct       ( Str struct_def      ); | ||||||
| CodeTemplate    parse_template     ( StrC template_def    ); | CodeTemplate    parse_template     ( Str template_def    ); | ||||||
| CodeType        parse_type         ( StrC type_def        ); | CodeType        parse_type         ( Str type_def        ); | ||||||
| CodeTypedef     parse_typedef      ( StrC typedef_def     ); | CodeTypedef     parse_typedef      ( Str typedef_def     ); | ||||||
| CodeUnion       parse_union        ( StrC union_def       ); | CodeUnion       parse_union        ( Str union_def       ); | ||||||
| CodeUsing       parse_using        ( StrC using_def       ); | CodeUsing       parse_using        ( Str using_def       ); | ||||||
| CodeVar         parse_variable     ( StrC var_def         ); | CodeVar         parse_variable     ( Str var_def         ); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| To parse file buffers, use the `parse_global_body` function. | To parse file buffers, use the `parse_global_body` function. | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|  |  | ||||||
| Contains: | Contains: | ||||||
|  |  | ||||||
| * [AST_Design](./AST_Design.md): Overvie of ASTs | * [AST_Design](./AST_Design.md): Overview of ASTs | ||||||
| * [AST Types](./AST_Types.md): Listing of all AST types along with their Code type interface. | * [AST Types](./AST_Types.md): Listing of all AST types along with their Code type interface. | ||||||
| * [Parsing](./Parsing.md): Overview of the parsing interface. | * [Parsing](./Parsing.md): Overview of the parsing interface. | ||||||
| * [Parser Algo](./Parser_Algo.md): In-depth breakdown of the parser's implementation. | * [Parser Algo](./Parser_Algo.md): In-depth breakdown of the parser's implementation. | ||||||
| @@ -49,10 +49,10 @@ However, the user may specifiy memory configuration. | |||||||
|  |  | ||||||
| https://github.com/Ed94/gencpp/blob/eea4ebf5c40d5d87baa465abfb1be30845b2377e/base/components/ast.hpp#L396-L461 | https://github.com/Ed94/gencpp/blob/eea4ebf5c40d5d87baa465abfb1be30845b2377e/base/components/ast.hpp#L396-L461 | ||||||
|  |  | ||||||
|  | *`StringCahced` is a typedef for `Str` (a string slice), to denote it is an interned string*   | ||||||
| *`CodeType` is enum taggin the type of code. Has an underlying type of `u32`*   | *`CodeType` is enum taggin the type of code. Has an underlying type of `u32`*   | ||||||
| *`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`*   | *`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`*   | ||||||
| *`StringCahced` is a typedef for `String const`, to denote it is an interned string*   | *`StrBuilder` is the dynamically allocated string type for the library*   | ||||||
| *`String` is the dynamically allocated string type for the library*   |  | ||||||
|  |  | ||||||
| AST widths are setup to be AST_POD_Size.   | AST widths are setup to be AST_POD_Size.   | ||||||
| The width dictates how much the static array can hold before it must give way to using an allocated array: | The width dictates how much the static array can hold before it must give way to using an allocated array: | ||||||
| @@ -79,7 +79,7 @@ int AST_ArrSpecs_Cap = | |||||||
| Data Notes: | Data Notes: | ||||||
|  |  | ||||||
| * The allocator definitions used are exposed to the user incase they want to dictate memory usage | * The allocator definitions used are exposed to the user incase they want to dictate memory usage | ||||||
|   * You'll find the memory handling in `init`, `deinit`, `reset`, `gen_string_allocator`, `get_cached_string`, `make_code`. |   * You'll find the memory handling in `init`, `deinit`, `reset`, `gen_strbuilder_allocator`, `get_cached_string`, `make_code`. | ||||||
|   * Allocators are defined with the `AllocatorInfo` structure found in [`memory.hpp`](../base/dependencies/memory.hpp) |   * Allocators are defined with the `AllocatorInfo` structure found in [`memory.hpp`](../base/dependencies/memory.hpp) | ||||||
|   * Most of the work is just defining the allocation procedure: |   * Most of the work is just defining the allocation procedure: | ||||||
|  |  | ||||||
| @@ -308,7 +308,7 @@ Code <name> = code_str( <some code without "" quotes > ) | |||||||
| Template metaprogramming in the traditional sense becomes possible with the use of `token_fmt` and parse constructors: | Template metaprogramming in the traditional sense becomes possible with the use of `token_fmt` and parse constructors: | ||||||
|  |  | ||||||
| ```cpp | ```cpp | ||||||
| StrC value = txt("Something"); | Str value = txt("Something"); | ||||||
|  |  | ||||||
| char const* template_str = txt( | char const* template_str = txt( | ||||||
|     Code with <key> to replace with token_values |     Code with <key> to replace with token_values | ||||||
| @@ -403,7 +403,7 @@ There are two provided auxillary interfaces: | |||||||
| * Builder | * Builder | ||||||
| * Scanner | * Scanner | ||||||
|  |  | ||||||
| ### Builder is a similar object to the jai language's string_builder | ### Builder is a similar object to the jai language's strbuilder_builder | ||||||
|  |  | ||||||
| * The purpose of it is to generate a file. | * The purpose of it is to generate a file. | ||||||
| * A file is specified and opened for writing using the open( file_path) function. | * A file is specified and opened for writing using the open( file_path) function. | ||||||
|   | |||||||
| @@ -24,24 +24,24 @@ constexpr char const* generation_notice = | |||||||
| "// This file was generated automatially by gencpp's c_library.cpp  " | "// This file was generated automatially by gencpp's c_library.cpp  " | ||||||
| "(See: https://github.com/Ed94/gencpp)\n\n"; | "(See: https://github.com/Ed94/gencpp)\n\n"; | ||||||
|  |  | ||||||
| constexpr StrC roll_own_dependencies_guard_start = txt(R"( | constexpr Str roll_own_dependencies_guard_start = txt(R"( | ||||||
| //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. | //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. | ||||||
| // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl | // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl | ||||||
| #ifndef GEN_ROLL_OWN_DEPENDENCIES | #ifndef GEN_ROLL_OWN_DEPENDENCIES | ||||||
| )"); | )"); | ||||||
|  |  | ||||||
| constexpr StrC roll_own_dependencies_guard_end = txt(R"( | constexpr Str roll_own_dependencies_guard_end = txt(R"( | ||||||
| // GEN_ROLL_OWN_DEPENDENCIES | // GEN_ROLL_OWN_DEPENDENCIES | ||||||
| #endif | #endif | ||||||
| )"); | )"); | ||||||
|  |  | ||||||
| constexpr StrC implementation_guard_start = txt(R"( | constexpr Str implementation_guard_start = txt(R"( | ||||||
| #pragma region GENCPP IMPLEMENTATION GUARD | #pragma region GENCPP IMPLEMENTATION GUARD | ||||||
| #if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) | #if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) | ||||||
| #	define GEN_IMPLEMENTED | #	define GEN_IMPLEMENTED | ||||||
| )"); | )"); | ||||||
|  |  | ||||||
| constexpr StrC implementation_guard_end = txt(R"( | constexpr Str implementation_guard_end = txt(R"( | ||||||
| #endif | #endif | ||||||
| #pragma endregion GENCPP IMPLEMENTATION GUARD | #pragma endregion GENCPP IMPLEMENTATION GUARD | ||||||
| )"); | )"); | ||||||
| @@ -87,7 +87,7 @@ int gen_main() | |||||||
| #pragma region Resolve Dependencies | #pragma region Resolve Dependencies | ||||||
| 	Code header_platform       = scan_file( path_base "dependencies/platform.hpp" ); | 	Code header_platform       = scan_file( path_base "dependencies/platform.hpp" ); | ||||||
| 	Code header_macros         = scan_file( path_base "dependencies/macros.hpp" ); | 	Code header_macros         = scan_file( path_base "dependencies/macros.hpp" ); | ||||||
| 	Code header_generic_macros = scan_file(           "components/generic_macros.hpp" ); | 	Code header_generic_macros = scan_file(           "components/generic_macros.h" ); | ||||||
| 	Code header_basic_types    = scan_file( path_base "dependencies/basic_types.hpp" ); | 	Code header_basic_types    = scan_file( path_base "dependencies/basic_types.hpp" ); | ||||||
| 	Code header_debug          = scan_file( path_base "dependencies/debug.hpp" ); | 	Code header_debug          = scan_file( path_base "dependencies/debug.hpp" ); | ||||||
| 	Code header_string_ops     = scan_file( path_base "dependencies/string_ops.hpp" ); | 	Code header_string_ops     = scan_file( path_base "dependencies/string_ops.hpp" ); | ||||||
| @@ -100,7 +100,7 @@ int gen_main() | |||||||
| 	{ | 	{ | ||||||
| 		case CT_Using: | 		case CT_Using: | ||||||
| 		{ | 		{ | ||||||
| 			log_fmt("REPLACE THIS MANUALLY: %SC\n", entry->Name); | 			log_fmt("REPLACE THIS MANUALLY: %S\n", entry->Name); | ||||||
| 			CodeUsing   using_ver   = cast(CodeUsing, entry); | 			CodeUsing   using_ver   = cast(CodeUsing, entry); | ||||||
| 			CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); | 			CodeTypedef typedef_ver = def_typedef(using_ver->Name, using_ver->UnderlyingType); | ||||||
|  |  | ||||||
| @@ -126,7 +126,7 @@ int gen_main() | |||||||
| 			if (fn->Specs) { | 			if (fn->Specs) { | ||||||
| 				s32 constexpr_found = fn->Specs.remove( Spec_Constexpr ); | 				s32 constexpr_found = fn->Specs.remove( Spec_Constexpr ); | ||||||
| 				if (constexpr_found > -1) { | 				if (constexpr_found > -1) { | ||||||
| 					//log_fmt("Found constexpr: %S\n", entry.to_string()); | 					//log_fmt("Found constexpr: %SB\n", entry.to_strbuilder()); | ||||||
| 					fn->Specs.append(Spec_Inline); | 					fn->Specs.append(Spec_Inline); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @@ -238,7 +238,7 @@ do                          \ | |||||||
| 		break; | 		break; | ||||||
| 		case CT_Variable: | 		case CT_Variable: | ||||||
| 		{ | 		{ | ||||||
| 			if ( strc_contains(entry->Name, txt("Msg_Invalid_Value"))) | 			if ( str_contains(entry->Name, txt("Msg_Invalid_Value"))) | ||||||
| 			{ | 			{ | ||||||
| 				CodeDefine define = def_define(entry->Name, entry->Value->Content); | 				CodeDefine define = def_define(entry->Name, entry->Value->Content); | ||||||
| 				header_printing.append(define); | 				header_printing.append(define); | ||||||
| @@ -292,16 +292,16 @@ do                          \ | |||||||
|  |  | ||||||
| 		case CT_Preprocess_IfNotDef: | 		case CT_Preprocess_IfNotDef: | ||||||
| 		{ | 		{ | ||||||
| 			//log_fmt("\nIFNDEF: %SC\n", entry->Content); | 			//log_fmt("\nIFNDEF: %S\n", entry->Content); | ||||||
| 			header_strings.append(entry); | 			header_strings.append(entry); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 		case CT_Struct_Fwd: | 		case CT_Struct_Fwd: | ||||||
| 		{ | 		{ | ||||||
| 			if ( entry->Name.is_equal(txt("String")) ) | 			if ( entry->Name.is_equal(txt("StrBuilder")) ) | ||||||
| 			{ | 			{ | ||||||
| 				CodeTypedef c_def = parse_typedef(code( typedef char* String; )); | 				CodeTypedef c_def = parse_typedef(code( typedef char* StrBuilder; )); | ||||||
| 				header_strings.append(c_def); | 				header_strings.append(c_def); | ||||||
| 				header_strings.append(fmt_newline); | 				header_strings.append(fmt_newline); | ||||||
| 				++ entry; | 				++ entry; | ||||||
| @@ -341,12 +341,12 @@ do                          \ | |||||||
|  |  | ||||||
| 		case CT_Typedef: | 		case CT_Typedef: | ||||||
| 		{ | 		{ | ||||||
| 			StrC name_string_table = txt("StringTable"); | 			Str name_string_table = txt("StringTable"); | ||||||
|  |  | ||||||
| 			CodeTypedef td = cast(CodeTypedef, entry); | 			CodeTypedef td = cast(CodeTypedef, entry); | ||||||
| 			if (td->Name.contains(name_string_table)) | 			if (td->Name.contains(name_string_table)) | ||||||
| 			{ | 			{ | ||||||
| 				CodeBody ht = gen_hashtable(txt("gen_StrC"), name_string_table); | 				CodeBody ht = gen_hashtable(txt("gen_Str"), name_string_table); | ||||||
| 				header_strings.append(ht); | 				header_strings.append(ht); | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| @@ -388,8 +388,8 @@ do                          \ | |||||||
| 		case CT_Union: | 		case CT_Union: | ||||||
| 		case CT_Union_Fwd: | 		case CT_Union_Fwd: | ||||||
| 		{ | 		{ | ||||||
| 			StrC type_str      = codetype_to_keyword_str(entry->Type); | 			Str type_str      = codetype_to_keyword_str(entry->Type); | ||||||
| 			StrC formated_tmpl = token_fmt_impl( 3, | 			Str formated_tmpl = token_fmt_impl( 3, | ||||||
| 				"type", type_str | 				"type", type_str | ||||||
| 			,	"name", entry->Name, | 			,	"name", entry->Name, | ||||||
| 			stringize( | 			stringize( | ||||||
| @@ -490,8 +490,8 @@ do                          \ | |||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			StrC type_str      = codetype_to_keyword_str(entry->Type); | 			Str type_str      = codetype_to_keyword_str(entry->Type); | ||||||
| 			StrC formated_tmpl = token_fmt_impl( 3, | 			Str formated_tmpl = token_fmt_impl( 3, | ||||||
| 				"type", type_str | 				"type", type_str | ||||||
| 			,	"name", entry->Name, | 			,	"name", entry->Name, | ||||||
| 			stringize( | 			stringize( | ||||||
| @@ -549,9 +549,9 @@ do                          \ | |||||||
| 			{ | 			{ | ||||||
| 				CodeTypename type       = using_ver->UnderlyingType; | 				CodeTypename type       = using_ver->UnderlyingType; | ||||||
| 				CodeTypedef typedef_ver = parse_typedef(token_fmt( | 				CodeTypedef typedef_ver = parse_typedef(token_fmt( | ||||||
| 					"ReturnType", to_string(type->ReturnType).to_strc() | 					"ReturnType", to_strbuilder(type->ReturnType).to_str() | ||||||
| 				,	"Name"      , using_ver->Name | 				,	"Name"      , using_ver->Name | ||||||
| 				,	"Parameters", to_string(type->Params).to_strc() | 				,	"Parameters", to_strbuilder(type->Params).to_str() | ||||||
| 				,	stringize( | 				,	stringize( | ||||||
| 						typedef <ReturnType>( * <Name>)(<Parameters>); | 						typedef <ReturnType>( * <Name>)(<Parameters>); | ||||||
| 				))); | 				))); | ||||||
| @@ -578,7 +578,7 @@ do                          \ | |||||||
| 				types.append(entry_td); | 				types.append(entry_td); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 			//log_fmt("Detected ENUM: %S", entry->Name); | 			//log_fmt("Detected ENUM: %SB", entry->Name); | ||||||
| 			convert_cpp_enum_to_c(cast(CodeEnum, entry), types); | 			convert_cpp_enum_to_c(cast(CodeEnum, entry), types); | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| @@ -645,9 +645,9 @@ do                          \ | |||||||
| 					CodeFn fn = cast(CodeFn, entry); | 					CodeFn fn = cast(CodeFn, entry); | ||||||
| 					if (fn->Name.starts_with(txt("code_"))) | 					if (fn->Name.starts_with(txt("code_"))) | ||||||
| 					{ | 					{ | ||||||
| 						StrC   old_prefix  = txt("code_"); | 						Str   old_prefix  = txt("code_"); | ||||||
| 						StrC   actual_name = { fn->Name.Len  - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; | 						Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len }; | ||||||
| 						String new_name    = String::fmt_buf(GlobalAllocator, "code__%SC", actual_name ); | 						StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name ); | ||||||
|  |  | ||||||
| 						fn->Name = get_cached_string(new_name); | 						fn->Name = get_cached_string(new_name); | ||||||
| 						code_c_interface.append(fn); | 						code_c_interface.append(fn); | ||||||
| @@ -694,21 +694,21 @@ do                          \ | |||||||
|  |  | ||||||
| 			s32 constexpr_found = var->Specs ? var->Specs.remove( Spec_Constexpr ) : - 1; | 			s32 constexpr_found = var->Specs ? var->Specs.remove( Spec_Constexpr ) : - 1; | ||||||
| 			if (constexpr_found > -1) { | 			if (constexpr_found > -1) { | ||||||
| 				//log_fmt("Found constexpr: %S\n", entry.to_string()); | 				//log_fmt("Found constexpr: %SB\n", entry.to_strbuilder()); | ||||||
| 				if (var->Name.contains(txt("AST_ArrSpecs_Cap"))) | 				if (var->Name.contains(txt("AST_ArrSpecs_Cap"))) | ||||||
| 				{ | 				{ | ||||||
| 					Code def = untyped_str(txt( | 					Code def = untyped_str(txt( | ||||||
| R"(#define AST_ArrSpecs_Cap \ | R"(#define AST_ArrSpecs_Cap \ | ||||||
| (                           \ | (                           \ | ||||||
| 	AST_POD_Size            \ | 	AST_POD_Size              \ | ||||||
| 	- sizeof(Code)          \ | 	- sizeof(Code)            \ | ||||||
| 	- sizeof(StringCached)  \ | 	- sizeof(StringCached)    \ | ||||||
| 	- sizeof(Code) * 2      \ | 	- sizeof(Code) * 2        \ | ||||||
| 	- sizeof(Token*)        \ | 	- sizeof(Token*)          \ | ||||||
| 	- sizeof(Code)          \ | 	- sizeof(Code)            \ | ||||||
| 	- sizeof(CodeType)      \ | 	- sizeof(CodeType)        \ | ||||||
| 	- sizeof(ModuleFlag)    \ | 	- sizeof(ModuleFlag)      \ | ||||||
| 	- sizeof(u32)           \ | 	- sizeof(u32)             \ | ||||||
| )                           \ | )                           \ | ||||||
| / sizeof(Specifier) - 1 | / sizeof(Specifier) - 1 | ||||||
| )" | )" | ||||||
| @@ -716,7 +716,7 @@ R"(#define AST_ArrSpecs_Cap \ | |||||||
| 					ast.append(def); | 					ast.append(def); | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| 				CodeDefine def = def_define(var->Name, var->Value.to_string()); | 				CodeDefine def = def_define(var->Name, var->Value.to_strbuilder()); | ||||||
| 				ast.append(def); | 				ast.append(def); | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| @@ -729,7 +729,7 @@ R"(#define AST_ArrSpecs_Cap \ | |||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	StrC code_typenames[] = { | 	Str code_typenames[] = { | ||||||
| 		txt("Code"), | 		txt("Code"), | ||||||
| 		txt("CodeBody"), | 		txt("CodeBody"), | ||||||
| 		txt("CodeAttributes"), | 		txt("CodeAttributes"), | ||||||
| @@ -752,6 +752,7 @@ R"(#define AST_ArrSpecs_Cap \ | |||||||
| 		txt("CodeParams"), | 		txt("CodeParams"), | ||||||
| 		txt("CodePreprocessCond"), | 		txt("CodePreprocessCond"), | ||||||
| 		txt("CodeSpecifiers"), | 		txt("CodeSpecifiers"), | ||||||
|  | 		txt("CodeStruct"), | ||||||
| 		txt("CodeTemplate"), | 		txt("CodeTemplate"), | ||||||
| 		txt("CodeTypename"), | 		txt("CodeTypename"), | ||||||
| 		txt("CodeTypedef"), | 		txt("CodeTypedef"), | ||||||
| @@ -790,24 +791,24 @@ R"(#define AST_ArrSpecs_Cap \ | |||||||
| 				default: gen_generic_selection (Fail case)                                    \ | 				default: gen_generic_selection (Fail case)                                    \ | ||||||
| 			) GEN_RESOLVED_FUNCTION_CALL( code, ... )                                       \ | 			) GEN_RESOLVED_FUNCTION_CALL( code, ... )                                       \ | ||||||
| 			*/ | 			*/ | ||||||
| 			String generic_selector = String::make_reserve(GlobalAllocator, kilobytes(2)); | 			StrBuilder generic_selector = StrBuilder::make_reserve(GlobalAllocator, kilobytes(2)); | ||||||
| 			for ( CodeFn fn : code_c_interface ) | 			for ( CodeFn fn : code_c_interface ) | ||||||
| 			{ | 			{ | ||||||
| 				generic_selector.clear(); | 				generic_selector.clear(); | ||||||
| 				StrC   private_prefix  = txt("code__"); | 				Str   private_prefix  = txt("code__"); | ||||||
| 				StrC   actual_name     = { fn->Name.Len - private_prefix.Len, fn->Name.Ptr + private_prefix.Len }; | 				Str   actual_name     = { fn->Name.Ptr + private_prefix.Len, fn->Name.Len - private_prefix.Len }; | ||||||
| 				String interface_name  = String::fmt_buf(GlobalAllocator, "code_%SC", actual_name ); | 				StrBuilder interface_name  = StrBuilder::fmt_buf(GlobalAllocator, "code_%S", actual_name ); | ||||||
|  |  | ||||||
| 				// Resolve generic's arguments | 				// Resolve generic's arguments | ||||||
| 				b32    has_args   = fn->Params->NumEntries > 1; | 				b32    has_args   = fn->Params->NumEntries > 1; | ||||||
| 				String params_str = String::make_reserve(GlobalAllocator, 32); | 				StrBuilder params_str = StrBuilder::make_reserve(GlobalAllocator, 32); | ||||||
| 				for (CodeParams param = fn->Params->Next; param != fn->Params.end(); ++ param) { | 				for (CodeParams param = fn->Params->Next; param != fn->Params.end(); ++ param) { | ||||||
| 					// We skip the first parameter as its always going to be the code for selection | 					// We skip the first parameter as its always going to be the code for selection | ||||||
| 					if (param->Next == nullptr) { | 					if (param->Next == nullptr) { | ||||||
| 						params_str.append_fmt( "%SC", param->Name ); | 						params_str.append_fmt( "%S", param->Name ); | ||||||
| 						continue; | 						continue; | ||||||
| 					} | 					} | ||||||
| 					params_str.append_fmt( "%SC, ", param->Name ); | 					params_str.append_fmt( "%S, ", param->Name ); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				char const* tmpl_def_start = nullptr; | 				char const* tmpl_def_start = nullptr; | ||||||
| @@ -823,14 +824,14 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 				} | 				} | ||||||
| 				// Definition start | 				// Definition start | ||||||
| 				generic_selector.append( token_fmt( | 				generic_selector.append( token_fmt( | ||||||
| 							"interface_name", interface_name.to_strc() | 							"interface_name", interface_name.to_str() | ||||||
| 					,		"params",         params_str.to_strc() // Only used if has_args | 					,		"params",         params_str.to_str() // Only used if has_args | ||||||
| 					, tmpl_def_start | 					, tmpl_def_start | ||||||
| 				)); | 				)); | ||||||
|  |  | ||||||
| 				// Append slots | 				// Append slots | ||||||
| 				for(StrC type : code_typenames ) { | 				for(Str type : code_typenames ) { | ||||||
| 					generic_selector.append_fmt("%SC : %SC,\\\n", type, fn->Name ); | 					generic_selector.append_fmt("%S : %S,\\\n", type, fn->Name ); | ||||||
| 				} | 				} | ||||||
| 				generic_selector.append(txt("default: gen_generic_selection_fail \\\n")); | 				generic_selector.append(txt("default: gen_generic_selection_fail \\\n")); | ||||||
|  |  | ||||||
| @@ -843,7 +844,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 				} | 				} | ||||||
| 				// Definition end | 				// Definition end | ||||||
| 				generic_selector.append( token_fmt( | 				generic_selector.append( token_fmt( | ||||||
| 						"params", params_str.to_strc() | 						"params", params_str.to_str() | ||||||
| 				, 	"type",   fn->Params->ValueType->Name | 				, 	"type",   fn->Params->ValueType->Name | ||||||
| 				,		tmpl_def_end ) ); | 				,		tmpl_def_end ) ); | ||||||
|  |  | ||||||
| @@ -889,8 +890,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 						char conversion_buf[32] = {}; | 						char conversion_buf[32] = {}; | ||||||
| 						u64_to_str(size_of(AST_Body::_PAD_), conversion_buf, 10); | 						u64_to_str(size_of(AST_Body::_PAD_), conversion_buf, 10); | ||||||
|  |  | ||||||
| 						StrC arr_exp  = union_entry->ValueType->ArrExpr->Content; | 						Str arr_exp  = union_entry->ValueType->ArrExpr->Content; | ||||||
| 						StrC cpp_size = to_strc_from_c_str(conversion_buf); | 						Str cpp_size = to_str_from_c_str(conversion_buf); | ||||||
| 						union_entry->ValueType->ArrExpr = untyped_str( cpp_size ); | 						union_entry->ValueType->ArrExpr = untyped_str( cpp_size ); | ||||||
| 						union_entry->InlineCmt          = untyped_str(token_fmt("arr_exp", arr_exp, | 						union_entry->InlineCmt          = untyped_str(token_fmt("arr_exp", arr_exp, | ||||||
| 							"// Had to hardcode _PAD_ because (<arr_exp>) was 67 bytes in C\n" | 							"// Had to hardcode _PAD_ because (<arr_exp>) was 67 bytes in C\n" | ||||||
| @@ -930,8 +931,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
|  |  | ||||||
| 			if (prev && prev->Name.is_equal(entry->Name)) { | 			if (prev && prev->Name.is_equal(entry->Name)) { | ||||||
| 				// rename second definition so there isn't a symbol conflict | 				// rename second definition so there isn't a symbol conflict | ||||||
| 				String postfix_arr = String::fmt_buf(GlobalAllocator, "%SC_arr", entry->Name); | 				StrBuilder postfix_arr = StrBuilder::fmt_buf(GlobalAllocator, "%S_arr", entry->Name); | ||||||
| 				entry->Name = get_cached_string(postfix_arr.to_strc()); | 				entry->Name = get_cached_string(postfix_arr.to_str()); | ||||||
| 				postfix_arr.free(); | 				postfix_arr.free(); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -939,20 +940,20 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 			for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) | 			for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) | ||||||
| 			{ | 			{ | ||||||
| 				// Convert the definition to use a default struct: https://vxtwitter.com/vkrajacic/status/1749816169736073295 | 				// Convert the definition to use a default struct: https://vxtwitter.com/vkrajacic/status/1749816169736073295 | ||||||
| 				StrC prefix      = txt("def_"); | 				Str prefix      = txt("def_"); | ||||||
| 				StrC actual_name = { fn->Name.Len  - prefix.Len, fn->Name.Ptr + prefix.Len }; | 				Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len  - prefix.Len }; | ||||||
| 				StrC new_name    = String::fmt_buf(GlobalAllocator, "def__%SC", actual_name ).to_strc(); | 				Str new_name    = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str(); | ||||||
|  |  | ||||||
| 				// Resolve define's arguments | 				// Resolve define's arguments | ||||||
| 				b32    has_args   = fn->Params->NumEntries > 1; | 				b32    has_args   = fn->Params->NumEntries > 1; | ||||||
| 				String params_str = String::make_reserve(GlobalAllocator, 32); | 				StrBuilder params_str = StrBuilder::make_reserve(GlobalAllocator, 32); | ||||||
| 				for (CodeParams other_param = fn->Params; other_param != opt_param; ++ other_param) { | 				for (CodeParams other_param = fn->Params; other_param != opt_param; ++ other_param) { | ||||||
| 					if ( other_param == opt_param ) { | 					if ( other_param == opt_param ) { | ||||||
| 						params_str.append_fmt( "%SC", other_param->Name ); | 						params_str.append_fmt( "%S", other_param->Name ); | ||||||
| 						break; | 						break; | ||||||
| 					} | 					} | ||||||
| 					// If there are arguments before the optional, prepare them here. | 					// If there are arguments before the optional, prepare them here. | ||||||
| 					params_str.append_fmt( "%SC, ", other_param->Name ); | 					params_str.append_fmt( "%S, ", other_param->Name ); | ||||||
| 				} | 				} | ||||||
| 				char const* tmpl_fn_macro = nullptr; | 				char const* tmpl_fn_macro = nullptr; | ||||||
| 				if (params_str.length() > 0 ) { | 				if (params_str.length() > 0 ) { | ||||||
| @@ -964,7 +965,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 				Code fn_macro = untyped_str(token_fmt( | 				Code fn_macro = untyped_str(token_fmt( | ||||||
| 						"def_name",  fn->Name | 						"def_name",  fn->Name | ||||||
| 				,		"def__name", new_name | 				,		"def__name", new_name | ||||||
| 				,		"params",    params_str.to_strc() | 				,		"params",    params_str.to_str() | ||||||
| 				,		"opts_type", opt_param->ValueType->Name | 				,		"opts_type", opt_param->ValueType->Name | ||||||
| 				,	tmpl_fn_macro | 				,	tmpl_fn_macro | ||||||
| 				)); | 				)); | ||||||
| @@ -1018,9 +1019,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 			CodeFn fn = cast(CodeFn, entry); | 			CodeFn fn = cast(CodeFn, entry); | ||||||
| 			if (fn->Name.starts_with(txt("code_"))) | 			if (fn->Name.starts_with(txt("code_"))) | ||||||
| 			{ | 			{ | ||||||
| 				StrC   old_prefix  = txt("code_"); | 				Str   old_prefix  = txt("code_"); | ||||||
| 				StrC   actual_name = { fn->Name.Len  - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; | 				Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len }; | ||||||
| 				String new_name    = String::fmt_buf(GlobalAllocator, "code__%SC", actual_name ); | 				StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name ); | ||||||
|  |  | ||||||
| 				fn->Name = get_cached_string(new_name); | 				fn->Name = get_cached_string(new_name); | ||||||
| 			} | 			} | ||||||
| @@ -1173,9 +1174,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 			CodeFn fn = cast(CodeFn, entry); | 			CodeFn fn = cast(CodeFn, entry); | ||||||
| 			if (fn->Name.starts_with(txt("code_"))) | 			if (fn->Name.starts_with(txt("code_"))) | ||||||
| 			{ | 			{ | ||||||
| 				StrC   old_prefix  = txt("code_"); | 				Str   old_prefix  = txt("code_"); | ||||||
| 				StrC   actual_name = { fn->Name.Len  - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; | 				Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len }; | ||||||
| 				String new_name    = String::fmt_buf(GlobalAllocator, "code__%SC", actual_name ); | 				StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name ); | ||||||
|  |  | ||||||
| 				fn->Name = get_cached_string(new_name); | 				fn->Name = get_cached_string(new_name); | ||||||
| 			} | 			} | ||||||
| @@ -1218,16 +1219,16 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 				) | 				) | ||||||
| 				{ | 				{ | ||||||
| 					// rename second definition so there isn't a symbol conflict | 					// rename second definition so there isn't a symbol conflict | ||||||
| 					String postfix_arr = String::fmt_buf(GlobalAllocator, "%SC_arr", fn->Name); | 					StrBuilder postfix_arr = StrBuilder::fmt_buf(GlobalAllocator, "%S_arr", fn->Name); | ||||||
| 					fn->Name = get_cached_string(postfix_arr.to_strc()); | 					fn->Name = get_cached_string(postfix_arr.to_str()); | ||||||
| 					postfix_arr.free(); | 					postfix_arr.free(); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 			for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) | 			for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) | ||||||
| 			{ | 			{ | ||||||
| 				StrC prefix      = txt("def_"); | 				Str prefix      = txt("def_"); | ||||||
| 				StrC actual_name = { fn->Name.Len  - prefix.Len, fn->Name.Ptr + prefix.Len }; | 				Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len  - prefix.Len }; | ||||||
| 				StrC new_name    = String::fmt_buf(GlobalAllocator, "def__%SC", actual_name ).to_strc(); | 				Str new_name    = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str(); | ||||||
|  |  | ||||||
| 				fn->Name = get_cached_string(new_name); | 				fn->Name = get_cached_string(new_name); | ||||||
| 			} | 			} | ||||||
| @@ -1318,7 +1319,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 				Code define_ver = untyped_str(token_fmt( | 				Code define_ver = untyped_str(token_fmt( | ||||||
| 						"name",  var->Name | 						"name",  var->Name | ||||||
| 					,	"value", var->Value->Content | 					,	"value", var->Value->Content | ||||||
| 					,	"type",  var->ValueType.to_string().to_strc() | 					,	"type",  var->ValueType.to_strbuilder().to_str() | ||||||
| 					,	"#define <name> (<type>) <value>\n" | 					,	"#define <name> (<type>) <value>\n" | ||||||
| 				)); | 				)); | ||||||
| 				src_lexer.append(define_ver); | 				src_lexer.append(define_ver); | ||||||
| @@ -1363,7 +1364,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 				Code define_ver = untyped_str(token_fmt( | 				Code define_ver = untyped_str(token_fmt( | ||||||
| 						"name",  var->Name | 						"name",  var->Name | ||||||
| 					,	"value", var->Value->Content | 					,	"value", var->Value->Content | ||||||
| 					,	"type",  var->ValueType.to_string().to_strc() | 					,	"type",  var->ValueType.to_strbuilder().to_str() | ||||||
| 					,	"#define <name> (<type>) <value>\n" | 					,	"#define <name> (<type>) <value>\n" | ||||||
| 				)); | 				)); | ||||||
| 				src_parser.append(define_ver); | 				src_parser.append(define_ver); | ||||||
| @@ -1480,6 +1481,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 		header.print_fmt( roll_own_dependencies_guard_start ); | 		header.print_fmt( roll_own_dependencies_guard_start ); | ||||||
| 		header.print( r_header_platform ); | 		header.print( r_header_platform ); | ||||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n" ); | 		header.print_fmt( "\nGEN_NS_BEGIN\n" ); | ||||||
|  | 		header.print_fmt( "GEN_API_C_BEGIN\n" ); | ||||||
|  |  | ||||||
| 		header.print( r_header_macros ); | 		header.print( r_header_macros ); | ||||||
| 		header.print( header_generic_macros ); | 		header.print( header_generic_macros ); | ||||||
| @@ -1496,7 +1498,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 		header.print( r_header_timing ); | 		header.print( r_header_timing ); | ||||||
| 		header.print(rf_header_parsing ); | 		header.print(rf_header_parsing ); | ||||||
|  |  | ||||||
| 		header.print_fmt( "\nGEN_NS_END\n" ); | 		header.print_fmt( "\nGEN_API_C_END\n" ); | ||||||
|  | 		header.print_fmt( "GEN_NS_END\n" ); | ||||||
| 		header.print_fmt( roll_own_dependencies_guard_end ); | 		header.print_fmt( roll_own_dependencies_guard_end ); | ||||||
| 	#pragma endregion Print Dependencies | 	#pragma endregion Print Dependencies | ||||||
|  |  | ||||||
| @@ -1547,7 +1550,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
|  |  | ||||||
| 	#pragma region Print Dependencies | 	#pragma region Print Dependencies | ||||||
| 		header.print_fmt( roll_own_dependencies_guard_start ); | 		header.print_fmt( roll_own_dependencies_guard_start ); | ||||||
| 		header.print_fmt( "GEN_NS_BEGIN\n"); | 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | ||||||
| 		header.print_fmt( "GEN_API_C_BEGIN\n" ); | 		header.print_fmt( "GEN_API_C_BEGIN\n" ); | ||||||
|  |  | ||||||
| 		header.print( r_src_dep_start ); | 		header.print( r_src_dep_start ); | ||||||
| @@ -1561,12 +1564,14 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 		header.print( r_src_timing ); | 		header.print( r_src_timing ); | ||||||
| 		header.print( rf_src_parsing ); | 		header.print( rf_src_parsing ); | ||||||
|  |  | ||||||
|  | 		header.print_fmt( "\nGEN_API_C_END\n" ); | ||||||
| 		header.print_fmt( "GEN_NS_END\n"); | 		header.print_fmt( "GEN_NS_END\n"); | ||||||
| 		header.print_fmt( roll_own_dependencies_guard_end ); | 		header.print_fmt( roll_own_dependencies_guard_end ); | ||||||
| 	#pragma endregion Print Dependencies | 	#pragma endregion Print Dependencies | ||||||
|  |  | ||||||
| 	#pragma region Print Components | 	#pragma region Print Components | ||||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | ||||||
|  | 		header.print_fmt( "GEN_API_C_BEGIN\n" ); | ||||||
|  |  | ||||||
| 		header.print( fmt_newline); | 		header.print( fmt_newline); | ||||||
| 		header.print( rf_array_arena ); | 		header.print( rf_array_arena ); | ||||||
| @@ -1595,12 +1600,13 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | |||||||
| 		header.print( r_src_parsing ); | 		header.print( r_src_parsing ); | ||||||
| 		header.print_fmt( "\n#pragma endregion Parsing\n" ); | 		header.print_fmt( "\n#pragma endregion Parsing\n" ); | ||||||
| 		header.print( r_src_untyped ); | 		header.print( r_src_untyped ); | ||||||
| 		header.print_fmt( "\n#pragma endregion Interface\n\n"); | 		header.print_fmt( "\n#pragma endregion Interface\n"); | ||||||
|  |  | ||||||
| 		header.print( rf_src_builder ); | 		header.print( rf_src_builder ); | ||||||
| 		header.print( rf_src_scanner ); | 		header.print( rf_src_scanner ); | ||||||
|  |  | ||||||
| 		header.print_fmt( "GEN_API_C_END\n" ); | 		header.print_fmt( "\nGEN_API_C_END\n" ); | ||||||
|  | 		header.print_fmt( "GEN_NS_END\n"); | ||||||
| 	#pragma endregion Print Components | 	#pragma endregion Print Components | ||||||
|  |  | ||||||
| 		header.print_fmt( implementation_guard_end ); | 		header.print_fmt( implementation_guard_end ); | ||||||
|   | |||||||
| @@ -167,7 +167,7 @@ namespace pool_, gen_pool_ | |||||||
|  |  | ||||||
| // Printing | // Printing | ||||||
|  |  | ||||||
| namespace str_, gen_str_ | namespace c_str_, gen_c_str_ | ||||||
|  |  | ||||||
| word PrintF_Buffer,     gen_PrintF_Buffer | word PrintF_Buffer,     gen_PrintF_Buffer | ||||||
| word Msg_Invalid_Value, gen_Msg_Invalid_Value | word Msg_Invalid_Value, gen_Msg_Invalid_Value | ||||||
| @@ -211,18 +211,18 @@ word crc64, gen_crc64 | |||||||
|  |  | ||||||
| // Strings | // Strings | ||||||
|  |  | ||||||
| word StrC, gen_StrC | word Str, gen_Str | ||||||
|  |  | ||||||
| word to_strc_from_c_str, gen_to_strc_from_c_str | word to_str_from_c_str, gen_to_str_from_c_str | ||||||
|  |  | ||||||
| namespace strc_, gen_strc_ | namespace str_, gen_str_ | ||||||
|  |  | ||||||
| word cast_to_strc, gen_cast_to_strc | word cast_to_str, gen_cast_to_str | ||||||
|  |  | ||||||
| word StringHeader, gen_StringHeader | word StrBuilderHeader, gen_StrBuilderHeader | ||||||
| word String,       gen_String | word StrBuilder,       gen_StrBuilder | ||||||
|  |  | ||||||
| namespace string_, gen_string_ | namespace strbuilder_, gen_strbuilder_ | ||||||
|  |  | ||||||
| word StringCached, gen_StringCached | word StringCached, gen_StringCached | ||||||
|  |  | ||||||
| @@ -308,7 +308,7 @@ word operator_to_str, gen_operator_to_str | |||||||
| word Specifier,        gen_Specifier | word Specifier,        gen_Specifier | ||||||
| word spec_to_str,      gen_spec_to_str | word spec_to_str,      gen_spec_to_str | ||||||
| word spec_is_trailing, gen_spec_is_trailing | word spec_is_trailing, gen_spec_is_trailing | ||||||
| // word strc_to_specifier, gen_strc_to_specifier | // word str_to_specifier, gen_str_to_specifier | ||||||
|  |  | ||||||
| // AST | // AST | ||||||
|  |  | ||||||
| @@ -340,6 +340,7 @@ word CodePragma,         gen_CodePragma | |||||||
| word CodeParams,         gen_CodeParams | word CodeParams,         gen_CodeParams | ||||||
| word CodePreprocessCond, gen_CodePreprocessCond | word CodePreprocessCond, gen_CodePreprocessCond | ||||||
| word CodeSpecifiers,     gen_CodeSpecifiers | word CodeSpecifiers,     gen_CodeSpecifiers | ||||||
|  | word CodeStruct,         gen_CodeStruct | ||||||
| word CodeTemplate,       gen_CodeTemplate | word CodeTemplate,       gen_CodeTemplate | ||||||
| word CodeTypename,       gen_CodeTypename | word CodeTypename,       gen_CodeTypename | ||||||
| word CodeTypedef,        gen_CodeTypedef | word CodeTypedef,        gen_CodeTypedef | ||||||
| @@ -467,6 +468,10 @@ word Allocator_TypeTable,     gen_Allocator_TypeTable | |||||||
| word      Builder,  gen_Builder | word      Builder,  gen_Builder | ||||||
| namespace builder_, gen_builder_ | namespace builder_, gen_builder_ | ||||||
|  |  | ||||||
|  | // Scanner | ||||||
|  |  | ||||||
|  | word scan_file, gen_scan_file | ||||||
|  |  | ||||||
| // Implementation (prviate) | // Implementation (prviate) | ||||||
|  |  | ||||||
| word _format_info, gen__format_info | word _format_info, gen__format_info | ||||||
| @@ -522,7 +527,7 @@ word parser_deinit, gen_parser_deinit | |||||||
|  |  | ||||||
| word TokType,         gen_TokType | word TokType,         gen_TokType | ||||||
| word toktype_to_str,  gen_toktype_to_str | word toktype_to_str,  gen_toktype_to_str | ||||||
| // word strc_to_toktype, gen_strc_to_toktype | // word str_to_toktype, gen_str_to_toktype | ||||||
| word NullToken,       gen_NullToken | word NullToken,       gen_NullToken | ||||||
|  |  | ||||||
| namespace tok_, gen_tok_ | namespace tok_, gen_tok_ | ||||||
|   | |||||||
| @@ -40,11 +40,11 @@ CodeBody gen_array_base() | |||||||
| 	)); | 	)); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| CodeBody gen_array( StrC type, StrC array_name ) | CodeBody gen_array( Str type, Str array_name ) | ||||||
| { | { | ||||||
| 	String array_type = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr ); | 	StrBuilder array_type = StrBuilder::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr ); | ||||||
| 	String fn         = String::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr ); | 	StrBuilder fn         = StrBuilder::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr ); | ||||||
| 	// str_to_lower(fn.Data); | 	// c_str_to_lower(fn.Data); | ||||||
|  |  | ||||||
| #pragma push_macro( "GEN_ASSERT" ) | #pragma push_macro( "GEN_ASSERT" ) | ||||||
| #pragma push_macro( "rcast" ) | #pragma push_macro( "rcast" ) | ||||||
| @@ -56,7 +56,7 @@ CodeBody gen_array( StrC type, StrC array_name ) | |||||||
| #undef cast | #undef cast | ||||||
| #undef typeof | #undef typeof | ||||||
| #undef forceinline | #undef forceinline | ||||||
| 	CodeBody result = parse_global_body( token_fmt( "array_type", (StrC)array_type, "fn", (StrC)fn, "type", (StrC)type | 	CodeBody result = parse_global_body( token_fmt( "array_type", (Str)array_type, "fn", (Str)fn, "type", (Str)type | ||||||
| 	, stringize( | 	, stringize( | ||||||
| 		typedef <type>* <array_type>; | 		typedef <type>* <array_type>; | ||||||
|  |  | ||||||
| @@ -375,9 +375,9 @@ CodeBody gen_array( StrC type, StrC array_name ) | |||||||
| #pragma pop_macro( "forceinline" ) | #pragma pop_macro( "forceinline" ) | ||||||
|  |  | ||||||
| 	++ Array_DefinitionCounter; | 	++ Array_DefinitionCounter; | ||||||
| 	StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", Array_DefinitionCounter).to_strc(); | 	Str slot_str = StrBuilder::fmt_buf(GlobalAllocator, "%d", Array_DefinitionCounter).to_str(); | ||||||
|  |  | ||||||
| 	Code generic_interface_slot = untyped_str(token_fmt( "type", type, "array_type", (StrC)array_type, "slot", (StrC)slot_str, | 	Code generic_interface_slot = untyped_str(token_fmt( "type", type, "array_type", (Str)array_type, "slot", (Str)slot_str, | ||||||
| R"(#define GENERIC_SLOT_<slot>__array_init         <type>,        <array_type>_init | R"(#define GENERIC_SLOT_<slot>__array_init         <type>,        <array_type>_init | ||||||
| #define GENERIC_SLOT_<slot>__array_init_reserve    <type>,        <array_type>_init_reserve | #define GENERIC_SLOT_<slot>__array_init_reserve    <type>,        <array_type>_init_reserve | ||||||
| #define GENERIC_SLOT_<slot>__array_append          <array_type>,  <array_type>_append | #define GENERIC_SLOT_<slot>__array_append          <array_type>,  <array_type>_append | ||||||
| @@ -399,13 +399,13 @@ R"(#define GENERIC_SLOT_<slot>__array_init         <type>,        <array_type>_i | |||||||
| 	)); | 	)); | ||||||
|  |  | ||||||
| 	return def_global_body( args( | 	return def_global_body( args( | ||||||
| 		def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", array_type ))), | 		def_pragma( strbuilder_to_str( strbuilder_fmt_buf( GlobalAllocator, "region %SB", array_type ))), | ||||||
| 		fmt_newline, | 		fmt_newline, | ||||||
| 		generic_interface_slot, | 		generic_interface_slot, | ||||||
| 		fmt_newline, | 		fmt_newline, | ||||||
| 		result, | 		result, | ||||||
| 		fmt_newline, | 		fmt_newline, | ||||||
| 		def_pragma( string_to_strc(string_fmt_buf( GlobalAllocator, "endregion %S", array_type ))), | 		def_pragma( strbuilder_to_str(strbuilder_fmt_buf( GlobalAllocator, "endregion %SB", array_type ))), | ||||||
| 		fmt_newline | 		fmt_newline | ||||||
| 	)); | 	)); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -27,24 +27,24 @@ R"(#define HashTable(_type) struct _type | |||||||
| 	return def_global_body(args(struct_def, define_type, define_critical_load_scale)); | 	return def_global_body(args(struct_def, define_type, define_critical_load_scale)); | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeBody gen_hashtable( StrC type, StrC hashtable_name ) | CodeBody gen_hashtable( Str type, Str hashtable_name ) | ||||||
| { | { | ||||||
|  |  | ||||||
| 	String tbl_type = {(char*) hashtable_name.duplicate(GlobalAllocator).Ptr}; | 	StrBuilder tbl_type = {(char*) hashtable_name.duplicate(GlobalAllocator).Ptr}; | ||||||
| 	String fn       = tbl_type.duplicate(GlobalAllocator); | 	StrBuilder fn       = tbl_type.duplicate(GlobalAllocator); | ||||||
| 	// str_to_lower(fn.Data); | 	// c_str_to_lower(fn.Data); | ||||||
|  |  | ||||||
| 	String name_lower = String::make( GlobalAllocator, hashtable_name ); | 	StrBuilder name_lower = StrBuilder::make( GlobalAllocator, hashtable_name ); | ||||||
| 	// str_to_lower( name_lower.Data ); | 	// c_str_to_lower( name_lower.Data ); | ||||||
|  |  | ||||||
| 	String hashtable_entry   = String::fmt_buf( GlobalAllocator, "HTE_%.*s",     hashtable_name.Len, hashtable_name.Ptr ); | 	StrBuilder hashtable_entry   = StrBuilder::fmt_buf( GlobalAllocator, "HTE_%.*s",     hashtable_name.Len, hashtable_name.Ptr ); | ||||||
| 	String entry_array_name  = String::fmt_buf( GlobalAllocator, "Arr_HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr ); | 	StrBuilder entry_array_name  = StrBuilder::fmt_buf( GlobalAllocator, "Arr_HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr ); | ||||||
| 	String entry_array_fn_ns = String::fmt_buf( GlobalAllocator, "arr_hte_%.*s", name_lower.length(), name_lower.Data ); | 	StrBuilder entry_array_fn_ns = StrBuilder::fmt_buf( GlobalAllocator, "arr_hte_%.*s", name_lower.length(), name_lower.Data ); | ||||||
|  |  | ||||||
| 	CodeBody hashtable_types = parse_global_body( token_fmt( | 	CodeBody hashtable_types = parse_global_body( token_fmt( | ||||||
| 		"type",        (StrC) type, | 		"type",        (Str) type, | ||||||
| 		"tbl_name",    (StrC) hashtable_name, | 		"tbl_name",    (Str) hashtable_name, | ||||||
| 		"tbl_type",    (StrC) tbl_type, | 		"tbl_type",    (Str) tbl_type, | ||||||
| 	stringize( | 	stringize( | ||||||
| 		typedef struct HashTable_<type> <tbl_type>; | 		typedef struct HashTable_<type> <tbl_type>; | ||||||
| 		typedef struct HTE_<tbl_name> HTE_<tbl_name>; | 		typedef struct HTE_<tbl_name> HTE_<tbl_name>; | ||||||
| @@ -74,13 +74,13 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name ) | |||||||
| #undef typeof | #undef typeof | ||||||
| #undef forceinline | #undef forceinline | ||||||
| 	CodeBody hashtable_def = parse_global_body( token_fmt( | 	CodeBody hashtable_def = parse_global_body( token_fmt( | ||||||
| 		"type",           (StrC) type, | 		"type",           (Str) type, | ||||||
| 		"tbl_name",       (StrC) hashtable_name, | 		"tbl_name",       (Str) hashtable_name, | ||||||
| 		"tbl_type",       (StrC) tbl_type, | 		"tbl_type",       (Str) tbl_type, | ||||||
| 		"fn",             (StrC) fn, | 		"fn",             (Str) fn, | ||||||
| 		"entry_type",     (StrC) hashtable_entry, | 		"entry_type",     (Str) hashtable_entry, | ||||||
| 		"array_entry",    (StrC) entry_array_name, | 		"array_entry",    (Str) entry_array_name, | ||||||
| 		"fn_array",       (StrC) entry_array_fn_ns, | 		"fn_array",       (Str) entry_array_fn_ns, | ||||||
| 	stringize( | 	stringize( | ||||||
| 		struct HashTable_<type> { | 		struct HashTable_<type> { | ||||||
| 			Array_ssize   Hashes; | 			Array_ssize   Hashes; | ||||||
| @@ -372,9 +372,9 @@ CodeBody gen_hashtable( StrC type, StrC hashtable_name ) | |||||||
| #pragma pop_macro( "forceinline" ) | #pragma pop_macro( "forceinline" ) | ||||||
|  |  | ||||||
| 	++ HashTable_DefinitionCounter; | 	++ HashTable_DefinitionCounter; | ||||||
| 	StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", HashTable_DefinitionCounter).to_strc(); | 	Str slot_str = StrBuilder::fmt_buf(GlobalAllocator, "%d", HashTable_DefinitionCounter).to_str(); | ||||||
|  |  | ||||||
| 	Code generic_interface_slot = untyped_str(token_fmt( "type", type, "tbl_type", (StrC)tbl_type, "slot", (StrC)slot_str, | 	Code generic_interface_slot = untyped_str(token_fmt( "type", type, "tbl_type", (Str)tbl_type, "slot", (Str)slot_str, | ||||||
| R"(#define GENERIC_SLOT_<slot>__hashtable_init          <type>,      <tbl_type>_init | R"(#define GENERIC_SLOT_<slot>__hashtable_init          <type>,      <tbl_type>_init | ||||||
| #define GENERIC_SLOT_<slot>__hashtable_init_reserve     <type>,      <tbl_type>_init_reserve | #define GENERIC_SLOT_<slot>__hashtable_init_reserve     <type>,      <tbl_type>_init_reserve | ||||||
| #define GENERIC_SLOT_<slot>__hashtable_clear            <tbl_type>,  <tbl_type>_clear | #define GENERIC_SLOT_<slot>__hashtable_clear            <tbl_type>,  <tbl_type>_clear | ||||||
| @@ -395,12 +395,12 @@ R"(#define GENERIC_SLOT_<slot>__hashtable_init          <type>,      <tbl_type>_ | |||||||
| )" | )" | ||||||
| 	)); | 	)); | ||||||
|  |  | ||||||
| 	char const* cmt_str = str_fmt_buf( "Name: %.*s Type: %.*s" | 	char const* cmt_str = c_str_fmt_buf( "Name: %.*s Type: %.*s" | ||||||
| 		, tbl_type.length(), tbl_type.Data | 		, tbl_type.length(), tbl_type.Data | ||||||
| 		, type.Len, type.Ptr ); | 		, type.Len, type.Ptr ); | ||||||
|  |  | ||||||
| 	return def_global_body(args( | 	return def_global_body(args( | ||||||
| 		def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "region %S", tbl_type ))), | 		def_pragma( strbuilder_to_str( strbuilder_fmt_buf( GlobalAllocator, "region %SB", tbl_type ))), | ||||||
| 		fmt_newline, | 		fmt_newline, | ||||||
| 		generic_interface_slot, | 		generic_interface_slot, | ||||||
| 		fmt_newline, | 		fmt_newline, | ||||||
| @@ -409,7 +409,7 @@ R"(#define GENERIC_SLOT_<slot>__hashtable_init          <type>,      <tbl_type>_ | |||||||
| 		entry_array, | 		entry_array, | ||||||
| 		hashtable_def, | 		hashtable_def, | ||||||
| 		fmt_newline, | 		fmt_newline, | ||||||
| 		def_pragma( string_to_strc( string_fmt_buf( GlobalAllocator, "endregion %S", tbl_type ))), | 		def_pragma( strbuilder_to_str( strbuilder_fmt_buf( GlobalAllocator, "endregion %SB", tbl_type ))), | ||||||
| 		fmt_newline | 		fmt_newline | ||||||
| 	)); | 	)); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,9 +3,9 @@ | |||||||
| //   ____                       _        ______                _   _                ____                  _                 __ _
 | //   ____                       _        ______                _   _                ____                  _                 __ _
 | ||||||
| //  / ___}                     (_)      |  ____}              | | (_)              / __ \                | |               | |(_)
 | //  / ___}                     (_)      |  ____}              | | (_)              / __ \                | |               | |(_)
 | ||||||
| // | | ___  ___ _ __   ___ _ __ _  ___  | |__ _   _ _ __   ___| |_ _  ___  _ __   | |  | |_   _____ _ __ | | ___   __ _  __| | _ _ __   __ _
 | // | | ___  ___ _ __   ___ _ __ _  ___  | |__ _   _ _ __   ___| |_ _  ___  _ __   | |  | |_   _____ _ __ | | ___   __ _  __| | _ _ __   __ _
 | ||||||
| // | |{__ |/ _ \ '_ \ / _ \ '__} |/ __| |  __} | | | '_ \ / __} __} |/ _ \| '_ \  | |  | \ \ / / _ \ '_ \| |/ _ \ / _` |/ _` || | '_ \ / _` |
 | // | |{__ |/ _ \ '_ \ / _ \ '__} |/ __| |  __} | | | '_ \ / __} __} |/ _ \| '_ \  | |  | \ \ / / _ \ '_ }| |/ _ \ / _` |/ _` || | '_ \ / _` |
 | ||||||
| // | |__j |  __/ | | |  __/ |  | | (__  | |  | |_| | | | | (__| l_| | (_) | | | | | l__| |\ V /  __/ | | | | (_) | (_| | (_| || | | | | (_| |
 | // | |__j |  __/ | | |  __/ |  | | (__  | |  | |_| | | | | (__| l_| | (_) | | | | | l__| |\ V /  __/ |   | | (_) | (_| | (_| || | | | | (_| |
 | ||||||
| //  \____/ \___}_l l_l\___}_l  l_l\___| l_l   \__,_l_l l_l\___}\__}_l\___/l_l l_l  \____/  \_/ \___}_l l_l_l\___/ \__,_l\__,_l|_|_| |_|\__, |
 | //  \____/ \___}_l l_l\___}_l  l_l\___| l_l   \__,_l_l l_l\___}\__}_l\___/l_l l_l  \____/  \_/ \___}_l   l_l\___/ \__,_l\__,_l|_|_| |_|\__, |
 | ||||||
| // This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in:                                            __| |
 | // This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in:                                            __| |
 | ||||||
| // https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md                            {___/
 | // https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md                            {___/
 | ||||||
| // Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unobfuscated as possible.
 | // Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unobfuscated as possible.
 | ||||||
| @@ -30,7 +30,7 @@ | |||||||
| // Where GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER is specifically looking for that <comma> ,
 | // Where GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER is specifically looking for that <comma> ,
 | ||||||
| #define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ) GEN_COMMA_OPERATOR, , ) | #define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ) GEN_COMMA_OPERATOR, , ) | ||||||
| //                                                          ^ Selects the comma                              ^ is the type                             ^ is the function                             ^ Insert a comma
 | //                                                          ^ Selects the comma                              ^ is the type                             ^ is the function                             ^ Insert a comma
 | ||||||
| // The slot won't exist if that comma is not found.                                                                                                                                                  |
 | // The slot won't exist if that comma is not found.
 | ||||||
| 
 | 
 | ||||||
| // For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
 | // For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
 | ||||||
| typedef struct GENCPP_NO_RESOLVED_GENERIC_SELECTION GENCPP_NO_RESOLVED_GENERIC_SELECTION; | typedef struct GENCPP_NO_RESOLVED_GENERIC_SELECTION GENCPP_NO_RESOLVED_GENERIC_SELECTION; | ||||||
| @@ -43,12 +43,12 @@ GENCPP_NO_RESOLVED_GENERIC_SELECTION const gen_generic_selection_fail = {0}; | |||||||
| 
 | 
 | ||||||
| // Below are generated on demand for an overlaod depdendent on a type:
 | // Below are generated on demand for an overlaod depdendent on a type:
 | ||||||
| // ----------------------------------------------------------------------------------------------------------------------------------
 | // ----------------------------------------------------------------------------------------------------------------------------------
 | ||||||
| #define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic(       \ | #define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic(             \ | ||||||
| (selector_arg), /* Select Via Expression*/                           \ | (selector_arg), /* Select Via Expression*/                                 \ | ||||||
|   /* Extendibility slots: */                                         \ |   /* Extendibility slots: */                                               \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig ) \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2__function_sig ) \ | ||||||
| 	default: gen_generic_selection_fail                              \ | 	default: gen_generic_selection_fail                                    \ | ||||||
| ) GEN_RESOLVED_FUNCTION_CALL( selector_arg ) | ) GEN_RESOLVED_FUNCTION_CALL( selector_arg ) | ||||||
| // ----------------------------------------------------------------------------------------------------------------------------------
 | // ----------------------------------------------------------------------------------------------------------------------------------
 | ||||||
| 
 | 
 | ||||||
| @@ -68,20 +68,21 @@ size_t gen_example_hash__P_long( long val ) { return val * 2654435761ull; } | |||||||
| #define GENERIC_SLOT_2_gen_example_hash  long long, gen_example_hash__P_long_long | #define GENERIC_SLOT_2_gen_example_hash  long long, gen_example_hash__P_long_long | ||||||
| size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761ull; } | size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761ull; } | ||||||
| 
 | 
 | ||||||
| // If using an Editor with support for syntax hightlighting macros: HASH__ARGS_SIG_1 and HASH_ARGS_SIG_2 should show color highlighting indicating the slot is enabled,
 | // If using an Editor with support for syntax hightlighting macros:
 | ||||||
|  | // GENERIC_SLOT_1_gen_example_hash and GENERIC_SLOT_2_gen_example_hash should show color highlighting indicating the slot is enabled,
 | ||||||
| // or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
 | // or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
 | ||||||
| #define gen_hash_example( function_arguments ) _Generic(       \ | #define gen_hash_example( function_arguments ) _Generic(                      \ | ||||||
| (function_arguments), /* Select Via Expression*/               \ | (function_arguments), /* Select Via Expression*/                              \ | ||||||
|   /* Extendibility slots: */                                   \ |   /* Extendibility slots: */                                                  \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_1 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1_gen_example_hash ) \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_2 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2_gen_example_hash ) \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_3 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_3_gen_example_hash ) \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_4 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_4_gen_example_hash ) \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_5 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_5_gen_example_hash ) \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_6 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_6_gen_example_hash ) \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_7 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_7_gen_example_hash ) \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_8 ) \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_8_gen_example_hash ) \ | ||||||
| 	default: gen_generic_selection_fail                        \ | 	default: gen_generic_selection_fail                                       \ | ||||||
| ) GEN_RESOLVED_FUNCTION_CALL( function_arguments ) | ) GEN_RESOLVED_FUNCTION_CALL( function_arguments ) | ||||||
| 
 | 
 | ||||||
| // Additional Variations:
 | // Additional Variations:
 | ||||||
| @@ -89,20 +90,20 @@ size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761u | |||||||
| // If the function takes more than one argument the following is used:
 | // If the function takes more than one argument the following is used:
 | ||||||
| #define GEN_FUNCTION_GENERIC_EXAMPLE_VARADIC( selector_arg, ... ) _Generic( \ | #define GEN_FUNCTION_GENERIC_EXAMPLE_VARADIC( selector_arg, ... ) _Generic( \ | ||||||
| (selector_arg),                                                             \ | (selector_arg),                                                             \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )        \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig )  \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 )        \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2__function_sig )  \ | ||||||
| 	/* ... */                                                               \ | 	/* ... */                                                               \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N )         \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(GENERIC_SLOT_N__function_sig )   \ | ||||||
| 	default: gen_generic_selection_fail                                     \ | 	default: gen_generic_selection_fail                                     \ | ||||||
| ) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ ) | ) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ ) | ||||||
| 
 | 
 | ||||||
| // If the function does not take the arugment as a parameter:
 | // If the function does not take the arugment as a parameter:
 | ||||||
| #define GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( selector_arg ) _Generic( \ | #define GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( selector_arg ) _Generic( \ | ||||||
| ( GEN_TYPE_TO_EXP(selector_arg) ),                                         \ | ( GEN_TYPE_TO_EXP(selector_arg) ),                                         \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 )       \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig ) \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 )       \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_2__function_sig ) \ | ||||||
| 	/* ... */                                                              \ | 	/* ... */                                                              \ | ||||||
| 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N )        \ | 	GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(GENERIC_SLOT_N__function_sig )  \ | ||||||
| 	default: gen_generic_selection_fail                                    \ | 	default: gen_generic_selection_fail                                    \ | ||||||
| ) GEN_RESOLVED_FUNCTION_CALL() | ) GEN_RESOLVED_FUNCTION_CALL() | ||||||
| 
 | 
 | ||||||
| @@ -18,13 +18,13 @@ void convert_cpp_enum_to_c( CodeEnum to_convert, CodeBody to_append ) | |||||||
| #pragma pop_macro("enum_underlying") | #pragma pop_macro("enum_underlying") | ||||||
| } | } | ||||||
|  |  | ||||||
| b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& parsed_body, CodeBody& body ) | b32 ignore_preprocess_cond_block( Str cond_sig, Code& entry_iter, CodeBody& parsed_body, CodeBody& body ) | ||||||
| { | { | ||||||
| 	b32 found = false; | 	b32 found = false; | ||||||
| 	CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter); | 	CodePreprocessCond cond = cast(CodePreprocessCond, entry_iter); | ||||||
| 	if ( cond->Content.is_equal(cond_sig) ) | 	if ( cond->Content.is_equal(cond_sig) ) | ||||||
| 	{ | 	{ | ||||||
| 		//log_fmt("Preprocess cond found: %SC\n", cond->Content); | 		//log_fmt("Preprocess cond found: %S\n", cond->Content); | ||||||
| 		found = true; | 		found = true; | ||||||
|  |  | ||||||
| 		s32 depth = 1; | 		s32 depth = 1; | ||||||
| @@ -72,7 +72,7 @@ b32 ignore_preprocess_cond_block( StrC cond_sig, Code& entry_iter, CodeBody& par | |||||||
|  |  | ||||||
| constexpr bool GenericSel_One_Arg = true; | constexpr bool GenericSel_One_Arg = true; | ||||||
| enum GenericSelectionOpts : u32 { GenericSel_Default, GenericSel_By_Ref, GenericSel_Direct_Type }; | enum GenericSelectionOpts : u32 { GenericSel_Default, GenericSel_By_Ref, GenericSel_Direct_Type }; | ||||||
| Code gen_generic_selection_function_macro( s32 num_slots, StrC macro_name, GenericSelectionOpts opts = GenericSel_Default, bool one_arg = false ) | Code gen_generic_selection_function_macro( s32 num_slots, Str macro_name, GenericSelectionOpts opts = GenericSel_Default, bool one_arg = false ) | ||||||
| { | { | ||||||
| /* Implements: | /* Implements: | ||||||
| 	#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg, ... ) _Generic(      \ | 	#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg, ... ) _Generic(      \ | ||||||
| @@ -84,18 +84,18 @@ Code gen_generic_selection_function_macro( s32 num_slots, StrC macro_name, Gener | |||||||
| 	) GEN_RESOLVED_FUNCTION_CALL( selector_arg ) | 	) GEN_RESOLVED_FUNCTION_CALL( selector_arg ) | ||||||
| */ | */ | ||||||
| 	local_persist | 	local_persist | ||||||
| 	String define_builder = String::make_reserve(GlobalAllocator, kilobytes(64)); | 	StrBuilder define_builder = StrBuilder::make_reserve(GlobalAllocator, kilobytes(64)); | ||||||
| 	define_builder.clear(); | 	define_builder.clear(); | ||||||
|  |  | ||||||
| 	StrC macro_begin; | 	Str macro_begin; | ||||||
| 	if (opts == GenericSel_Direct_Type) { | 	if (opts == GenericSel_Direct_Type) { | ||||||
| 		macro_begin = token_fmt( "macro_name", (StrC)macro_name, | 		macro_begin = token_fmt( "macro_name", (Str)macro_name, | ||||||
| R"(#define <macro_name>(selector_arg, ...) _Generic( (*(selector_arg*)NULL ), \ | R"(#define <macro_name>(selector_arg, ...) _Generic( (*(selector_arg*)NULL ), \ | ||||||
| )" | )" | ||||||
| 		); | 		); | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		macro_begin = token_fmt( "macro_name", (StrC)macro_name, | 		macro_begin = token_fmt( "macro_name", (Str)macro_name, | ||||||
| R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \ | R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \ | ||||||
| )" | )" | ||||||
| 		); | 		); | ||||||
| @@ -104,7 +104,7 @@ R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \ | |||||||
|  |  | ||||||
| 	for ( s32 slot = 1; slot <= num_slots; ++ slot ) | 	for ( s32 slot = 1; slot <= num_slots; ++ slot ) | ||||||
| 	{ | 	{ | ||||||
| 		StrC slot_str = String::fmt_buf(GlobalAllocator, "%d", slot).to_strc(); | 		Str slot_str = StrBuilder::fmt_buf(GlobalAllocator, "%d", slot).to_str(); | ||||||
| 		if (slot == num_slots && false) | 		if (slot == num_slots && false) | ||||||
| 		{ | 		{ | ||||||
| 			define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str, | 			define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str, | ||||||
| @@ -152,25 +152,25 @@ R"(		GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_<slot>__<macro_name> ) | |||||||
| 	// Add gap for next definition | 	// Add gap for next definition | ||||||
| 	define_builder.append(txt("\n\n")); | 	define_builder.append(txt("\n\n")); | ||||||
|  |  | ||||||
| 	Code macro = untyped_str(define_builder.to_strc()); | 	Code macro = untyped_str(define_builder.to_str()); | ||||||
| 	return macro; | 	return macro; | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt("")) | CodeFn rename_function_to_unique_symbol(CodeFn fn, Str optional_prefix = txt("")) | ||||||
| { | { | ||||||
|     // Get basic components for the name |     // Get basic components for the name | ||||||
|     StrC old_name = fn->Name; |     Str        old_name = fn->Name; | ||||||
|     String new_name; |     StrBuilder new_name; | ||||||
|  |  | ||||||
|     // Add prefix if provided |     // Add prefix if provided | ||||||
|     if (optional_prefix.Len) |     if (optional_prefix.Len) | ||||||
|         new_name = string_fmt_buf(GlobalAllocator, "%SC_%SC_", optional_prefix, old_name); |         new_name = strbuilder_fmt_buf(GlobalAllocator, "%S_%S_", optional_prefix, old_name); | ||||||
|     else |     else | ||||||
|         new_name = string_fmt_buf(GlobalAllocator, "%SC_", old_name); |         new_name = strbuilder_fmt_buf(GlobalAllocator, "%S_", old_name); | ||||||
|  |  | ||||||
|     // Add return type to the signature |     // Add return type to the signature | ||||||
|     if (fn->ReturnType) |     if (fn->ReturnType) | ||||||
|         new_name.append_fmt("_%SC", fn->ReturnType->Name); |         new_name.append_fmt("_%S", fn->ReturnType->Name); | ||||||
|  |  | ||||||
|     // Add parameter types to create a unique signature |     // Add parameter types to create a unique signature | ||||||
|     bool first_param = true; |     bool first_param = true; | ||||||
| @@ -198,11 +198,11 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt("" | |||||||
| 						continue; | 						continue; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
|                     new_name.append_fmt("%SC_", spec_to_str(spec)); |                     new_name.append_fmt("%S_", spec_to_str(spec)); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             new_name.append_fmt("%SC", param->ValueType->Name); |             new_name.append_fmt("%S", param->ValueType->Name); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -214,7 +214,7 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt("" | |||||||
|              spec != end(fn->Specs); |              spec != end(fn->Specs); | ||||||
|              ++spec) |              ++spec) | ||||||
|         { |         { | ||||||
|             new_name.append_fmt("%SC_", spec_to_str(*spec)); |             new_name.append_fmt("%S_", spec_to_str(*spec)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -223,13 +223,13 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt("" | |||||||
| } | } | ||||||
|  |  | ||||||
| using SwapContentProc = CodeBody(void); | using SwapContentProc = CodeBody(void); | ||||||
| bool swap_pragma_region_implementation( StrC region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body ) | bool swap_pragma_region_implementation( Str region_name, SwapContentProc* swap_content, Code& entry_iter, CodeBody& body ) | ||||||
| { | { | ||||||
| 	bool found = false; | 	bool found = false; | ||||||
| 	CodePragma possible_region = cast(CodePragma, entry_iter); | 	CodePragma possible_region = cast(CodePragma, entry_iter); | ||||||
|  |  | ||||||
| 	String region_sig    = string_fmt_buf(GlobalAllocator, "region %s",    region_name.Ptr); | 	StrBuilder region_sig    = strbuilder_fmt_buf(GlobalAllocator, "region %s",    region_name.Ptr); | ||||||
| 	String endregion_sig = string_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr); | 	StrBuilder endregion_sig = strbuilder_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr); | ||||||
| 	if ( possible_region->Content.contains(region_sig)) | 	if ( possible_region->Content.contains(region_sig)) | ||||||
| 	{ | 	{ | ||||||
| 		found = true; | 		found = true; | ||||||
|   | |||||||
| @@ -117,7 +117,7 @@ int gen_main() | |||||||
| 		def_include(txt("components/types.hpp")), | 		def_include(txt("components/types.hpp")), | ||||||
| 		preprocess_endif, | 		preprocess_endif, | ||||||
| 		fmt_newline, | 		fmt_newline, | ||||||
| 		untyped_str( to_strc_from_c_str(generation_notice) ) | 		untyped_str( to_str_from_c_str(generation_notice) ) | ||||||
| 	)); | 	)); | ||||||
|  |  | ||||||
| 	// gen.hpp | 	// gen.hpp | ||||||
| @@ -171,7 +171,7 @@ int gen_main() | |||||||
| 		builder_print_fmt( header, "#pragma endregion Inlines\n" ); | 		builder_print_fmt( header, "#pragma endregion Inlines\n" ); | ||||||
|  |  | ||||||
| 		builder_print( header, header_end ); | 		builder_print( header, header_end ); | ||||||
| 		builder_print_fmt( header, "GEN_NS_END\n\n" ); | 		builder_print_fmt( header, "\nGEN_NS_END\n\n" ); | ||||||
| 		builder_print( header, pop_ignores ); | 		builder_print( header, pop_ignores ); | ||||||
| 		builder_write(header); | 		builder_write(header); | ||||||
| 	} | 	} | ||||||
| @@ -238,7 +238,7 @@ int gen_main() | |||||||
| 		builder_print( & header, def_include( txt("gen.hpp") )); | 		builder_print( & header, def_include( txt("gen.hpp") )); | ||||||
| 		builder_print_fmt( & header, "\nGEN_NS_BEGIN\n" ); | 		builder_print_fmt( & header, "\nGEN_NS_BEGIN\n" ); | ||||||
| 		builder_print( & header, builder ); | 		builder_print( & header, builder ); | ||||||
| 		builder_print_fmt( & header, "GEN_NS_END\n" ); | 		builder_print_fmt( & header, "\nGEN_NS_END\n" ); | ||||||
| 		builder_write( & header); | 		builder_write( & header); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -278,7 +278,7 @@ int gen_main() | |||||||
| 		builder_print( & src, def_include( txt("gen.scanner.hpp") ) ); | 		builder_print( & src, def_include( txt("gen.scanner.hpp") ) ); | ||||||
| 		builder_print_fmt( & src, "\nGEN_NS_BEGIN\n" ); | 		builder_print_fmt( & src, "\nGEN_NS_BEGIN\n" ); | ||||||
| 		builder_print( & src, scanner ); | 		builder_print( & src, scanner ); | ||||||
| 		builder_print_fmt( & src, "GEN_NS_END\n" ); | 		builder_print_fmt( & src, "\nGEN_NS_END\n" ); | ||||||
| 		builder_write( & src); | 		builder_write( & src); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,24 +17,24 @@ constexpr char const* generation_notice = | |||||||
| "// This file was generated automatially by gencpp's singleheader.cpp" | "// This file was generated automatially by gencpp's singleheader.cpp" | ||||||
| "(See: https://github.com/Ed94/gencpp)\n\n"; | "(See: https://github.com/Ed94/gencpp)\n\n"; | ||||||
|  |  | ||||||
| constexpr StrC implementation_guard_start = txt(R"( | constexpr Str implementation_guard_start = txt(R"( | ||||||
| #pragma region GENCPP IMPLEMENTATION GUARD | #pragma region GENCPP IMPLEMENTATION GUARD | ||||||
| #if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) | #if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) | ||||||
| #	define GEN_IMPLEMENTED | #	define GEN_IMPLEMENTED | ||||||
| )"); | )"); | ||||||
|  |  | ||||||
| constexpr StrC implementation_guard_end = txt(R"( | constexpr Str implementation_guard_end = txt(R"( | ||||||
| #endif | #endif | ||||||
| #pragma endregion GENCPP IMPLEMENTATION GUARD | #pragma endregion GENCPP IMPLEMENTATION GUARD | ||||||
| )"); | )"); | ||||||
|  |  | ||||||
| constexpr StrC roll_own_dependencies_guard_start = txt(R"( | constexpr Str roll_own_dependencies_guard_start = txt(R"( | ||||||
| //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. | //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. | ||||||
| // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl | // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl | ||||||
| #ifndef GEN_ROLL_OWN_DEPENDENCIES | #ifndef GEN_ROLL_OWN_DEPENDENCIES | ||||||
| )"); | )"); | ||||||
|  |  | ||||||
| constexpr StrC roll_own_dependencies_guard_end = txt(R"( | constexpr Str roll_own_dependencies_guard_end = txt(R"( | ||||||
| // GEN_ROLL_OWN_DEPENDENCIES | // GEN_ROLL_OWN_DEPENDENCIES | ||||||
| #endif | #endif | ||||||
| )"); | )"); | ||||||
| @@ -77,7 +77,7 @@ int gen_main() | |||||||
| 			Code basic_types  = scan_file( path_base "dependencies/basic_types.hpp" ); | 			Code basic_types  = scan_file( path_base "dependencies/basic_types.hpp" ); | ||||||
| 			Code debug        = scan_file( path_base "dependencies/debug.hpp" ); | 			Code debug        = scan_file( path_base "dependencies/debug.hpp" ); | ||||||
| 			Code memory	      = scan_file( path_base "dependencies/memory.hpp" ); | 			Code memory	      = scan_file( path_base "dependencies/memory.hpp" ); | ||||||
| 			Code string_ops   = scan_file( path_base "dependencies/string_ops.hpp" ); | 			Code stirng_ops   = scan_file( path_base "dependencies/string_ops.hpp" ); | ||||||
| 			Code printing     = scan_file( path_base "dependencies/printing.hpp" ); | 			Code printing     = scan_file( path_base "dependencies/printing.hpp" ); | ||||||
| 			Code containers   = scan_file( path_base "dependencies/containers.hpp" ); | 			Code containers   = scan_file( path_base "dependencies/containers.hpp" ); | ||||||
| 			Code hashing 	  = scan_file( path_base "dependencies/hashing.hpp" ); | 			Code hashing 	  = scan_file( path_base "dependencies/hashing.hpp" ); | ||||||
| @@ -93,7 +93,7 @@ int gen_main() | |||||||
| 			header.print( basic_types ); | 			header.print( basic_types ); | ||||||
| 			header.print( debug ); | 			header.print( debug ); | ||||||
| 			header.print( memory ); | 			header.print( memory ); | ||||||
| 			header.print( string_ops ); | 			header.print( stirng_ops ); | ||||||
| 			header.print( printing ); | 			header.print( printing ); | ||||||
| 			header.print( containers ); | 			header.print( containers ); | ||||||
| 			header.print( hashing ); | 			header.print( hashing ); | ||||||
| @@ -105,6 +105,7 @@ int gen_main() | |||||||
| 				header.print( scan_file( path_base "dependencies/parsing.hpp" ) ); | 				header.print( scan_file( path_base "dependencies/parsing.hpp" ) ); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			header.print(fmt_newline); | ||||||
| 			header.print_fmt( "GEN_NS_END\n" ); | 			header.print_fmt( "GEN_NS_END\n" ); | ||||||
| 			header.print_fmt( roll_own_dependencies_guard_end ); | 			header.print_fmt( roll_own_dependencies_guard_end ); | ||||||
| 			header.print( fmt_newline ); | 			header.print( fmt_newline ); | ||||||
| @@ -155,7 +156,11 @@ int gen_main() | |||||||
| 		if ( generate_builder ) { | 		if ( generate_builder ) { | ||||||
| 			header.print( scan_file( path_base "auxillary/builder.hpp" ) ); | 			header.print( scan_file( path_base "auxillary/builder.hpp" ) ); | ||||||
| 		} | 		} | ||||||
|  | 		if ( generate_scanner ) { | ||||||
|  | 			header.print( scan_file( path_base "auxillary/scanner.hpp" ) ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		header.print(fmt_newline); | ||||||
| 		header.print_fmt( "GEN_NS_END\n" ); | 		header.print_fmt( "GEN_NS_END\n" ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -176,9 +181,10 @@ int gen_main() | |||||||
| 			Code timing     = scan_file( path_base "dependencies/timing.cpp" ); | 			Code timing     = scan_file( path_base "dependencies/timing.cpp" ); | ||||||
|  |  | ||||||
| 			header.print_fmt( roll_own_dependencies_guard_start ); | 			header.print_fmt( roll_own_dependencies_guard_start ); | ||||||
| 			header.print_fmt( "GEN_NS_BEGIN\n\n"); |  | ||||||
|  |  | ||||||
| 			header.print( impl_start ); | 			header.print( impl_start ); | ||||||
|  | 			header.print( fmt_newline ); | ||||||
|  | 			header.print_fmt( "GEN_NS_BEGIN\n"); | ||||||
|  |  | ||||||
| 			header.print( debug ); | 			header.print( debug ); | ||||||
| 			header.print( string_ops ); | 			header.print( string_ops ); | ||||||
| 			header.print( printing ); | 			header.print( printing ); | ||||||
| @@ -209,8 +215,7 @@ int gen_main() | |||||||
| 		Code parsing_interface = scan_file( path_base "components/interface.parsing.cpp" ); | 		Code parsing_interface = scan_file( path_base "components/interface.parsing.cpp" ); | ||||||
| 		Code untyped           = scan_file( path_base "components/interface.untyped.cpp" ); | 		Code untyped           = scan_file( path_base "components/interface.untyped.cpp" ); | ||||||
|  |  | ||||||
| 		CodeBody etoktype      = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" ); | 		CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" ); | ||||||
| 		CodeNS   parser_nspace = def_namespace( name(parser), def_namespace_body( args(etoktype)) ); |  | ||||||
|  |  | ||||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | ||||||
| 		header.print( static_data ); | 		header.print( static_data ); | ||||||
| @@ -225,27 +230,23 @@ int gen_main() | |||||||
| 		header.print( interface ); | 		header.print( interface ); | ||||||
| 		header.print( upfront ); | 		header.print( upfront ); | ||||||
| 		header.print_fmt( "\n#pragma region Parsing\n\n" ); | 		header.print_fmt( "\n#pragma region Parsing\n\n" ); | ||||||
| 		header.print( format(parser_nspace) ); | 		header.print( format(etoktype) ); | ||||||
| 		header.print( lexer ); | 		header.print( lexer ); | ||||||
| 		header.print( parser ); | 		header.print( parser ); | ||||||
| 		header.print( parsing_interface ); | 		header.print( parsing_interface ); | ||||||
| 		header.print_fmt( "\n#pragma endregion Parsing\n" ); | 		header.print_fmt( "\n#pragma endregion Parsing\n" ); | ||||||
| 		header.print( untyped ); | 		header.print( untyped ); | ||||||
| 		header.print_fmt( "\n#pragma endregion Interface\n\n"); | 		header.print_fmt( "\n#pragma endregion Interface\n"); | ||||||
|  |  | ||||||
| 		if ( generate_builder ) { | 		if ( generate_builder ) { | ||||||
| 			header.print( scan_file( path_base "auxillary/builder.cpp"  ) ); | 			header.print( scan_file( path_base "auxillary/builder.cpp"  ) ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Scanner header depends on implementation |  | ||||||
| 		if ( generate_scanner ) { |  | ||||||
| 			header.print( scan_file( path_base "auxillary/scanner.hpp" ) ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if ( generate_scanner ) { | 		if ( generate_scanner ) { | ||||||
| 			header.print( scan_file( path_base "auxillary/scanner.cpp" ) ); | 			header.print( scan_file( path_base "auxillary/scanner.cpp" ) ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		header.print( fmt_newline); | ||||||
| 		header.print_fmt( "GEN_NS_END\n"); | 		header.print_fmt( "GEN_NS_END\n"); | ||||||
|  |  | ||||||
| 		header.print_fmt( "%s\n", (char const*) implementation_guard_end ); | 		header.print_fmt( "%s\n", (char const*) implementation_guard_end ); | ||||||
|   | |||||||
| @@ -17,25 +17,25 @@ constexpr char const* generation_notice = | |||||||
| "// This file was generated automatially by gencpp's unreal.cpp " | "// This file was generated automatially by gencpp's unreal.cpp " | ||||||
| "(See: https://github.com/Ed94/gencpp)\n\n"; | "(See: https://github.com/Ed94/gencpp)\n\n"; | ||||||
|  |  | ||||||
| constexpr StrC implementation_guard_start = txt(R"( | constexpr Str implementation_guard_start = txt(R"( | ||||||
| #pragma region GENCPP IMPLEMENTATION GUARD | #pragma region GENCPP IMPLEMENTATION GUARD | ||||||
| #if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) | #if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED) | ||||||
| #	define GEN_IMPLEMENTED | #	define GEN_IMPLEMENTED | ||||||
| )"); | )"); | ||||||
|  |  | ||||||
| constexpr StrC implementation_guard_end = txt(R"( | constexpr Str implementation_guard_end = txt(R"( | ||||||
| #endif | #endif | ||||||
| #pragma endregion GENCPP IMPLEMENTATION GUARD | #pragma endregion GENCPP IMPLEMENTATION GUARD | ||||||
| )"); | )"); | ||||||
|  |  | ||||||
| constexpr StrC roll_own_dependencies_guard_start = txt(R"( | constexpr Str roll_own_dependencies_guard_start = txt(R"( | ||||||
| //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. | //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. | ||||||
| // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl | // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl | ||||||
| #ifndef GEN_ROLL_OWN_DEPENDENCIES | #ifndef GEN_ROLL_OWN_DEPENDENCIES | ||||||
|  |  | ||||||
| )"); | )"); | ||||||
|  |  | ||||||
| constexpr StrC roll_own_dependencies_guard_end = txt(R"( | constexpr Str roll_own_dependencies_guard_end = txt(R"( | ||||||
| // GEN_ROLL_OWN_DEPENDENCIES | // GEN_ROLL_OWN_DEPENDENCIES | ||||||
| #endif | #endif | ||||||
| )"); | )"); | ||||||
| @@ -68,7 +68,7 @@ int gen_main() | |||||||
| 		CodeBody macros = def_body( CT_Global_Body ); | 		CodeBody macros = def_body( CT_Global_Body ); | ||||||
| 		{ | 		{ | ||||||
| 			FileContents content    = file_read_contents( GlobalAllocator, true, path_base "dependencies/macros.hpp" ); | 			FileContents content    = file_read_contents( GlobalAllocator, true, path_base "dependencies/macros.hpp" ); | ||||||
| 			CodeBody     ori_macros = parse_global_body( StrC { content.size, (char const*)content.data }); | 			CodeBody     ori_macros = parse_global_body( Str { (char const*)content.data, content.size }); | ||||||
|  |  | ||||||
| 			for (Code	code =  ori_macros.begin(); | 			for (Code	code =  ori_macros.begin(); | ||||||
| 						code != ori_macros.end(); | 						code != ori_macros.end(); | ||||||
| @@ -223,7 +223,7 @@ int gen_main() | |||||||
| 		header.print_fmt( "#pragma endregion Inlines\n" ); | 		header.print_fmt( "#pragma endregion Inlines\n" ); | ||||||
|  |  | ||||||
| 		header.print( header_end ); | 		header.print( header_end ); | ||||||
| 		header.print_fmt( "GEN_NS_END\n\n" ); | 		header.print_fmt( "\nGEN_NS_END\n\n" ); | ||||||
| 		header.print( pop_ignores ); | 		header.print( pop_ignores ); | ||||||
| 		header.write(); | 		header.write(); | ||||||
| 	} | 	} | ||||||
| @@ -294,7 +294,7 @@ int gen_main() | |||||||
| 		header.print( def_include( txt("gen.hpp") )); | 		header.print( def_include( txt("gen.hpp") )); | ||||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n" ); | 		header.print_fmt( "\nGEN_NS_BEGIN\n" ); | ||||||
| 		header.print( builder ); | 		header.print( builder ); | ||||||
| 		header.print_fmt( "GEN_NS_END\n" ); | 		header.print_fmt( "\nGEN_NS_END\n" ); | ||||||
| 		header.print( fmt_newline ); | 		header.print( fmt_newline ); | ||||||
| 		header.print( pop_ignores ); | 		header.print( pop_ignores ); | ||||||
| 		header.write(); | 		header.write(); | ||||||
| @@ -333,7 +333,7 @@ int gen_main() | |||||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n" ); | 		header.print_fmt( "\nGEN_NS_BEGIN\n" ); | ||||||
| 		header.print( parsing ); | 		header.print( parsing ); | ||||||
| 		header.print( scanner ); | 		header.print( scanner ); | ||||||
| 		header.print_fmt( "GEN_NS_END\n" ); | 		header.print_fmt( "\nGEN_NS_END\n" ); | ||||||
| 		header.print( fmt_newline ); | 		header.print( fmt_newline ); | ||||||
| 		header.print( pop_ignores ); | 		header.print( pop_ignores ); | ||||||
| 		header.write(); | 		header.write(); | ||||||
| @@ -353,7 +353,7 @@ int gen_main() | |||||||
| 		src.print_fmt( "\nGEN_NS_BEGIN\n" ); | 		src.print_fmt( "\nGEN_NS_BEGIN\n" ); | ||||||
| 		src.print( parsing ); | 		src.print( parsing ); | ||||||
| 		// src.print( scanner ); | 		// src.print( scanner ); | ||||||
| 		src.print_fmt( "GEN_NS_END\n" ); | 		src.print_fmt( "\nGEN_NS_END\n" ); | ||||||
| 		src.print( fmt_newline ); | 		src.print( fmt_newline ); | ||||||
| 		src.print( pop_ignores ); | 		src.print( pop_ignores ); | ||||||
| 		src.write(); | 		src.write(); | ||||||
|   | |||||||
| @@ -1,3 +1,3 @@ | |||||||
| <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> | <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> | ||||||
| 	<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=53AF600D_002DC09C_002D4F39_002D83E0_002DE022AA9479F2_002Fd_003Athirdparty_002Ff_003Azpl_002Eh/@EntryIndexedValue">ForceIncluded</s:String> | 	<s:StrBuilder x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=53AF600D_002DC09C_002D4F39_002D83E0_002DE022AA9479F2_002Fd_003Athirdparty_002Ff_003Azpl_002Eh/@EntryIndexedValue">ForceIncluded</s:StrBuilder> | ||||||
| 	<s:String x:Key="/Default/CodeInspection/Highlighting/SweaWarningsMode/@EntryValue">ShowAndRun</s:String></wpf:ResourceDictionary> | 	<s:StrBuilder x:Key="/Default/CodeInspection/Highlighting/SweaWarningsMode/@EntryValue">ShowAndRun</s:StrBuilder></wpf:ResourceDictionary> | ||||||
| @@ -21,10 +21,10 @@ | |||||||
| 		<Action>NoStepInto</Action> | 		<Action>NoStepInto</Action> | ||||||
| 	</Function> | 	</Function> | ||||||
| 	<Function> | 	<Function> | ||||||
| 		<Name>gen::Code.*::to_string</Name> | 		<Name>gen::Code.*::to_strbuilder</Name> | ||||||
| 		<Action>NoStepInto</Action> | 		<Action>NoStepInto</Action> | ||||||
| 	</Function> | 	</Function> | ||||||
| 	<Function> | 	<Function> | ||||||
| 		<Name>gen::String::operator .*</Name> | 		<Name>gen::StrBuilder::operator .*</Name> | ||||||
| 	</Function> | 	</Function> | ||||||
| </StepFilter> | </StepFilter> | ||||||
|   | |||||||
| @@ -36,11 +36,11 @@ | |||||||
| 		</Expand> | 		</Expand> | ||||||
| 	</Type> | 	</Type> | ||||||
|  |  | ||||||
| 	<Type Name="gen::StrC"> | 	<Type Name="gen::Str"> | ||||||
| 		<DisplayString>Len:{Len} Ptr:{Ptr, [Len]s}</DisplayString> | 		<DisplayString>Len:{Len} Ptr:{Ptr, [Len]s}</DisplayString> | ||||||
| 	</Type> | 	</Type> | ||||||
|  |  | ||||||
| 	<Type Name="gen::String"> | 	<Type Name="gen::StrBuilder"> | ||||||
| 		<DisplayString Condition="Data == nullptr">null</DisplayString> | 		<DisplayString Condition="Data == nullptr">null</DisplayString> | ||||||
| 		<DisplayString>{Data,na}</DisplayString> | 		<DisplayString>{Data,na}</DisplayString> | ||||||
| 		<Expand> | 		<Expand> | ||||||
| @@ -55,7 +55,7 @@ | |||||||
| 		</Expand> | 		</Expand> | ||||||
| 	</Type> | 	</Type> | ||||||
|  |  | ||||||
| 	<Type Name="gen::String::Header"> | 	<Type Name="gen::StrBuilder::Header"> | ||||||
| 		<DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString> | 		<DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString> | ||||||
| 		<Expand> | 		<Expand> | ||||||
| 			<Item Name="Allocator">Allocator</Item> | 			<Item Name="Allocator">Allocator</Item> | ||||||
|   | |||||||
| @@ -197,11 +197,11 @@ if ( $vendor -match "clang" ) | |||||||
| 			$compiler_args += $flag_no_optimization | 			$compiler_args += $flag_no_optimization | ||||||
| 		} | 		} | ||||||
| 		if ( $debug ) { | 		if ( $debug ) { | ||||||
| 			$compiler_args += ( $flag_define + 'Build_Debug=1' ) | 			$compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' ) | ||||||
| 			$compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug | 			$compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			$compiler_args += ( $flag_define + 'Build_Debug=0' ) | 			$compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' ) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		$warning_ignores | ForEach-Object { | 		$warning_ignores | ForEach-Object { | ||||||
| @@ -277,11 +277,11 @@ if ( $vendor -match "clang" ) | |||||||
| 			$compiler_args += $flag_no_optimization | 			$compiler_args += $flag_no_optimization | ||||||
| 		} | 		} | ||||||
| 		if ( $debug ) { | 		if ( $debug ) { | ||||||
| 			$compiler_args += ( $flag_define + 'Build_Debug=1' ) | 			$compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' ) | ||||||
| 			$compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug | 			$compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			$compiler_args += ( $flag_define + 'Build_Debug=0' ) | 			$compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' ) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		$warning_ignores | ForEach-Object { | 		$warning_ignores | ForEach-Object { | ||||||
| @@ -402,7 +402,7 @@ if ( $vendor -match "msvc" ) | |||||||
| 		if ( $debug ) | 		if ( $debug ) | ||||||
| 		{ | 		{ | ||||||
| 			$compiler_args += $flag_debug | 			$compiler_args += $flag_debug | ||||||
| 			$compiler_args += ( $flag_define + 'Build_Debug=1' ) | 			$compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' ) | ||||||
| 			$compiler_args += ( $flag_path_debug + $path_output + '\' ) | 			$compiler_args += ( $flag_path_debug + $path_output + '\' ) | ||||||
| 			$compiler_args += $flag_link_win_rt_static_debug | 			$compiler_args += $flag_link_win_rt_static_debug | ||||||
|  |  | ||||||
| @@ -412,7 +412,7 @@ if ( $vendor -match "msvc" ) | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			$compiler_args += ( $flag_define + 'Build_Debug=0' ) | 			$compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' ) | ||||||
| 			$compiler_args += $flag_link_win_rt_static | 			$compiler_args += $flag_link_win_rt_static | ||||||
| 		} | 		} | ||||||
| 		$compiler_args += $includes | ForEach-Object { $flag_include + $_ } | 		$compiler_args += $includes | ForEach-Object { $flag_include + $_ } | ||||||
| @@ -489,7 +489,7 @@ if ( $vendor -match "msvc" ) | |||||||
| 		if ( $debug ) | 		if ( $debug ) | ||||||
| 		{ | 		{ | ||||||
| 			$compiler_args += $flag_debug | 			$compiler_args += $flag_debug | ||||||
| 			$compiler_args += ( $flag_define + 'Build_Debug=1' ) | 			$compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' ) | ||||||
| 			$compiler_args += ( $flag_path_debug + $path_output + '\' ) | 			$compiler_args += ( $flag_path_debug + $path_output + '\' ) | ||||||
| 			$compiler_args += $flag_link_win_rt_static_debug | 			$compiler_args += $flag_link_win_rt_static_debug | ||||||
|  |  | ||||||
| @@ -498,7 +498,7 @@ if ( $vendor -match "msvc" ) | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			$compiler_args += ( $flag_define + 'Build_Debug=0' ) | 			$compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' ) | ||||||
| 			$compiler_args += $flag_link_win_rt_static | 			$compiler_args += $flag_link_win_rt_static | ||||||
| 		} | 		} | ||||||
| 		$compiler_args += $includes | ForEach-Object { $flag_include + $_ } | 		$compiler_args += $includes | ForEach-Object { $flag_include + $_ } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user