mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-11-03 15:26:12 -08:00 
			
		
		
		
	Compare commits
	
		
			37 Commits
		
	
	
		
			string_dis
			...
			772d0de5c1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 772d0de5c1 | |||
| cb50f93af5 | |||
| e4f564b165 | |||
| 0b78b74fbc | |||
| 5d8883ec45 | |||
| c90c210e04 | |||
| 980d1d7134 | |||
| b027778328 | |||
| a6143e12b4 | |||
| 868b93cdd0 | |||
| 0b03b3cd92 | |||
| 572e957c17 | |||
| 63bc3bebed | |||
| 70872c29d1 | |||
| e9752cb906 | |||
| 7946954017 | |||
| 4fe1a4da65 | |||
| 956ab73130 | |||
| f93250da07 | |||
| 1b4f9a2e77 | |||
| c8cf55403b | |||
| 76257123da | |||
| 3c249d2fae | |||
| 683f13deab | |||
| a7da5f2060 | |||
| db88979b75 | |||
| e04f72ddca | |||
| e8bb381520 | |||
| a33b3644d9 | |||
| 96ffca3094 | |||
| 967a044637 | |||
| b5cf633e98 | |||
| 16d0e0834f | |||
| 76ac3a0f93 | |||
| 78bcc21130 | |||
| a125653448 | |||
| aa2170ba80 | 
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -32,3 +32,12 @@ test/gen/original
 | 
			
		||||
singleheader/gen/scratch.hpp
 | 
			
		||||
test/gen/scratch.cpp
 | 
			
		||||
gen_c_library/gen
 | 
			
		||||
 | 
			
		||||
**/*.sln
 | 
			
		||||
**/*.sln.DotSettings.user
 | 
			
		||||
**/*.10x
 | 
			
		||||
**/*.vcxproj
 | 
			
		||||
**/*.vcxproj.filters
 | 
			
		||||
**/*.vcxproj.user
 | 
			
		||||
test/c_library/gen
 | 
			
		||||
test/cpp_library/gen
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										67
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								.vscode/c_cpp_properties.json
									
									
									
									
										vendored
									
									
								
							@@ -28,27 +28,6 @@
 | 
			
		||||
                "/FC"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Win32 msvc c_library",
 | 
			
		||||
            "includePath": [
 | 
			
		||||
                "${workspaceFolder}/gen_c_library/**"
 | 
			
		||||
            ],
 | 
			
		||||
            "defines": [
 | 
			
		||||
                "_DEBUG",
 | 
			
		||||
                "UNICODE",
 | 
			
		||||
                "_UNICODE",
 | 
			
		||||
                "GEN_TIME",
 | 
			
		||||
                "GEN_IMPLEMENTATION",
 | 
			
		||||
                // "GEN_DONT_USE_NAMESPACE"
 | 
			
		||||
                "GEN_INTELLISENSE_DIRECTIVES",
 | 
			
		||||
                "INTELLISENSE_DIRECTIVES"
 | 
			
		||||
            ],
 | 
			
		||||
            "cppStandard": "c++17",
 | 
			
		||||
            "windowsSdkVersion": "10.0.19041.0",
 | 
			
		||||
            "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe",
 | 
			
		||||
            "intelliSenseMode": "msvc-x64",
 | 
			
		||||
            "compileCommands": "${workspaceFolder}/.vscode/tasks.json"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Win32 clang",
 | 
			
		||||
            "includePath": [
 | 
			
		||||
@@ -64,10 +43,56 @@
 | 
			
		||||
                "GEN_INTELLISENSE_DIRECTIVES",
 | 
			
		||||
                "INTELLISENSE_DIRECTIVES"
 | 
			
		||||
            ],
 | 
			
		||||
            "cStandard": "c11",
 | 
			
		||||
            "cppStandard": "c++17",
 | 
			
		||||
            "windowsSdkVersion": "10.0.19041.0",
 | 
			
		||||
            "compilerPath": "clang++.exe",
 | 
			
		||||
            "intelliSenseMode": "windows-clang-x64",
 | 
			
		||||
            "compileCommands": "${workspaceFolder}/.vscode/tasks.json"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Win32 msvc c_library",
 | 
			
		||||
            "includePath": [
 | 
			
		||||
                "${workspaceFolder}/gen_c_library/**"
 | 
			
		||||
            ],
 | 
			
		||||
            "defines": [
 | 
			
		||||
                "_DEBUG",
 | 
			
		||||
                "UNICODE",
 | 
			
		||||
                "_UNICODE",
 | 
			
		||||
                "GEN_TIME",
 | 
			
		||||
                "GEN_IMPLEMENTATION",
 | 
			
		||||
                // "GEN_DONT_USE_NAMESPACE"
 | 
			
		||||
                "GEN_INTELLISENSE_DIRECTIVES",
 | 
			
		||||
                "INTELLISENSE_DIRECTIVES"
 | 
			
		||||
            ],
 | 
			
		||||
            "cStandard": "c11",
 | 
			
		||||
            "cppStandard": "c++17",
 | 
			
		||||
            "windowsSdkVersion": "10.0.19041.0",
 | 
			
		||||
            "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe",
 | 
			
		||||
            "intelliSenseMode": "msvc-x64",
 | 
			
		||||
            "compileCommands": "${workspaceFolder}/.vscode/tasks.json"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "Win32 msvc c_library test",
 | 
			
		||||
            "includePath": [
 | 
			
		||||
                "${workspaceFolder}/test/c_library/**",
 | 
			
		||||
                "${workspaceFolder}/gen_c_library/gen/**"
 | 
			
		||||
            ],
 | 
			
		||||
            "defines": [
 | 
			
		||||
                "_DEBUG",
 | 
			
		||||
                "UNICODE",
 | 
			
		||||
                "_UNICODE",
 | 
			
		||||
                "GEN_TIME",
 | 
			
		||||
                "GEN_IMPLEMENTATION",
 | 
			
		||||
                // "GEN_DONT_USE_NAMESPACE"
 | 
			
		||||
                "GEN_INTELLISENSE_DIRECTIVES",
 | 
			
		||||
                "INTELLISENSE_DIRECTIVES"
 | 
			
		||||
            ],
 | 
			
		||||
            "cStandard": "c11",
 | 
			
		||||
            "windowsSdkVersion": "10.0.19041.0",
 | 
			
		||||
            "compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.29.30133/bin/HostX64/x64/cl.exe",
 | 
			
		||||
            "intelliSenseMode": "msvc-x64",
 | 
			
		||||
            "compileCommands": "${workspaceFolder}/.vscode/tasks.json"
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "version": 4
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@@ -56,7 +56,8 @@
 | 
			
		||||
		"new": "cpp",
 | 
			
		||||
		"typeinfo": "cpp",
 | 
			
		||||
		"unordered_map": "cpp",
 | 
			
		||||
		"xstddef": "cpp"
 | 
			
		||||
		"xstddef": "cpp",
 | 
			
		||||
		"gen_singleheader.h": "c"
 | 
			
		||||
	},
 | 
			
		||||
	"C_Cpp.intelliSenseEngineFallback": "disabled",
 | 
			
		||||
	"mesonbuild.configureOnOpen": true,
 | 
			
		||||
@@ -72,5 +73,25 @@
 | 
			
		||||
	},
 | 
			
		||||
	"autoHide.autoHidePanel": false,
 | 
			
		||||
	"autoHide.autoHideSideBar": false,
 | 
			
		||||
	"dimmer.enabled": false
 | 
			
		||||
	"dimmer.enabled": false,
 | 
			
		||||
	"workbench.colorCustomizations": {
 | 
			
		||||
		"activityBar.activeBackground": "#fa1b49",
 | 
			
		||||
		"activityBar.background": "#fa1b49",
 | 
			
		||||
		"activityBar.foreground": "#e7e7e7",
 | 
			
		||||
		"activityBar.inactiveForeground": "#e7e7e799",
 | 
			
		||||
		"activityBarBadge.background": "#155e02",
 | 
			
		||||
		"activityBarBadge.foreground": "#e7e7e7",
 | 
			
		||||
		"commandCenter.border": "#e7e7e799",
 | 
			
		||||
		"sash.hoverBorder": "#fa1b49",
 | 
			
		||||
		"statusBar.background": "#dd0531",
 | 
			
		||||
		"statusBar.foreground": "#e7e7e7",
 | 
			
		||||
		"statusBarItem.hoverBackground": "#fa1b49",
 | 
			
		||||
		"statusBarItem.remoteBackground": "#dd0531",
 | 
			
		||||
		"statusBarItem.remoteForeground": "#e7e7e7",
 | 
			
		||||
		"titleBar.activeBackground": "#dd0531",
 | 
			
		||||
		"titleBar.activeForeground": "#e7e7e7",
 | 
			
		||||
		"titleBar.inactiveBackground": "#dd053199",
 | 
			
		||||
		"titleBar.inactiveForeground": "#e7e7e799"
 | 
			
		||||
	},
 | 
			
		||||
	"peacock.color": "#dd0531"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
# gencpp
 | 
			
		||||
 | 
			
		||||
An attempt at simple staged metaprogramming for C/C++.
 | 
			
		||||
An attempt at simple staged metaprogramming for C/C++. Reflect and generate code for your codebase at runtime!
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
The library API is a composition of code element constructors, and a non-standards-compliant single-pass C/C++ parser.  
 | 
			
		||||
These build up a code AST to then serialize with a file builder, or can be traversed for staged-reflection of C/C++ code.
 | 
			
		||||
@@ -49,7 +52,11 @@ Within `program.cpp` :
 | 
			
		||||
 | 
			
		||||
u32 gen_main()
 | 
			
		||||
{
 | 
			
		||||
    gen::Context ctx;
 | 
			
		||||
    gen::init(& ctx);
 | 
			
		||||
    ...
 | 
			
		||||
    gen::deinit(& ctx);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,12 @@
 | 
			
		||||
 | 
			
		||||
The library is fragmented into a series of headers and source files meant to be scanned in and then generated to a standard target format, or a user's desires.
 | 
			
		||||
 | 
			
		||||
If using the library's provided build scripts:
 | 
			
		||||
 | 
			
		||||
```ps1
 | 
			
		||||
.\build.ps1 <compiler> <debug or omit> base
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Standard formats:
 | 
			
		||||
 | 
			
		||||
* **base**: Files are in granular pieces separated into four directories:
 | 
			
		||||
@@ -27,7 +33,7 @@ Standard formats:
 | 
			
		||||
* **gen_segemetned**: Dependencies go into gen.dep.{hpp/cpp} and components into gen.{hpp/cpp}
 | 
			
		||||
* **gen_singleheader**: Everything into a single file: gen.hpp
 | 
			
		||||
* **gen_unreal_engine**: Like gen_segemented but the library is modified slightly to compile as a thirdparty library within an Unreal Engine plugin or module.
 | 
			
		||||
* **gen_c_library**: The library is heavily modifed into C11 compliant code. A segemented and single-header set of variants are generatd.
 | 
			
		||||
* **gen_c_library**: The library is heavily modifed into C11 compliant code. A segemented and single-header set of variants are generated.
 | 
			
		||||
 | 
			
		||||
Code not making up the core library is located in `auxiliary/<auxiliary_name>.<hpp/cpp>`. These are optional extensions or tools for the library.
 | 
			
		||||
 | 
			
		||||
@@ -150,7 +156,7 @@ The convention you'll see used throughout the upfront interface of the library i
 | 
			
		||||
3. Populate immediate fields (Name, Type, ModuleFlags, etc)
 | 
			
		||||
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 `cache_str` 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.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,9 @@ Builder builder_open( char const* path )
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result.Buffer = strbuilder_make_reserve( GlobalAllocator, Builder_StrBufferReserve );
 | 
			
		||||
	Context* ctx = get_context();
 | 
			
		||||
	GEN_ASSERT_NOT_NULL(ctx);
 | 
			
		||||
	result.Buffer = strbuilder_make_reserve( ctx->Allocator_Temp, ctx->InitSize_BuilderBuffer );
 | 
			
		||||
 | 
			
		||||
	// log_fmt("$Builder - Opened file: %s\n", result.File.filename );
 | 
			
		||||
	return result;
 | 
			
		||||
 
 | 
			
		||||
@@ -25,13 +25,14 @@ Builder builder_open        ( char const* path );
 | 
			
		||||
void    builder_pad_lines   ( Builder* builder, s32 num );
 | 
			
		||||
void    builder_print       ( Builder* builder, Code code );
 | 
			
		||||
void    builder_print_fmt_va( Builder* builder, char const* fmt, va_list va );
 | 
			
		||||
void    builder_print_fmt   ( Builder* builder, char const* fmt, ... ) {
 | 
			
		||||
void    builder_write       ( Builder* builder );
 | 
			
		||||
 | 
			
		||||
forceinline void builder_print_fmt   ( Builder* builder, char const* fmt, ... ) {
 | 
			
		||||
	va_list va;
 | 
			
		||||
	va_start( va, fmt );
 | 
			
		||||
	builder_print_fmt_va( builder, fmt, va );
 | 
			
		||||
	va_end( va );
 | 
			
		||||
}
 | 
			
		||||
void builder_write( Builder* builder );
 | 
			
		||||
 | 
			
		||||
struct Builder
 | 
			
		||||
{
 | 
			
		||||
@@ -56,10 +57,10 @@ struct Builder
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
 | 
			
		||||
void    builder_pad_lines( Builder& builder, s32 num )    { return builder_pad_lines(& builder, num); }
 | 
			
		||||
void    builder_print    ( Builder& builder, Code code )  { return builder_print(& builder, code); }
 | 
			
		||||
void    builder_write    ( Builder& builder )             { return builder_write(& builder ); }
 | 
			
		||||
void    builder_print_fmt( Builder& builder, char const* fmt, ...) {
 | 
			
		||||
forceinline void    builder_pad_lines( Builder& builder, s32 num )    { return builder_pad_lines(& builder, num); }
 | 
			
		||||
forceinline void    builder_print    ( Builder& builder, Code code )  { return builder_print(& builder, code); }
 | 
			
		||||
forceinline void    builder_write    ( Builder& builder )             { return builder_write(& builder ); }
 | 
			
		||||
forceinline void    builder_print_fmt( Builder& builder, char const* fmt, ...) {
 | 
			
		||||
	va_list va;
 | 
			
		||||
	va_start( va, fmt );
 | 
			
		||||
	builder_print_fmt_va( & builder, fmt, va );
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ Code scan_file( char const* path )
 | 
			
		||||
		GEN_FATAL("scan_file: %s is empty", path );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	StrBuilder str = strbuilder_make_reserve( GlobalAllocator, fsize );
 | 
			
		||||
	StrBuilder str = strbuilder_make_reserve( get_context()->Allocator_Temp, fsize );
 | 
			
		||||
		file_read( & file, str, fsize );
 | 
			
		||||
		strbuilder_get_header(str)->Length = fsize;
 | 
			
		||||
 | 
			
		||||
@@ -117,7 +117,7 @@ Code scan_file( char const* path )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeBody parse_file( const char* path ) {
 | 
			
		||||
	FileContents file    = file_read_contents( GlobalAllocator, true, path );
 | 
			
		||||
	FileContents file    = file_read_contents( get_context()->Allocator_Temp, true, path );
 | 
			
		||||
	Str          content = { (char const*)file.data, file.size };
 | 
			
		||||
	CodeBody     code    = parse_global_body( content );
 | 
			
		||||
	log_fmt("\nParsed: %s\n", path);
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,8 @@ constexpr char const* generation_notice =
 | 
			
		||||
 | 
			
		||||
int gen_main()
 | 
			
		||||
{
 | 
			
		||||
	gen::init();
 | 
			
		||||
	gen::Context ctx {};
 | 
			
		||||
	gen::init( & ctx);
 | 
			
		||||
 | 
			
		||||
	CodeBody gen_component_header = def_global_body( args(
 | 
			
		||||
		def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ),
 | 
			
		||||
@@ -59,7 +60,7 @@ int gen_main()
 | 
			
		||||
	builder_print( & header_especifier, format(especifier) );
 | 
			
		||||
	builder_write( & header_especifier);
 | 
			
		||||
	
 | 
			
		||||
	Builder header_etoktype = builder_open( "components/gen/etoktype.cpp" );
 | 
			
		||||
	Builder header_etoktype = builder_open( "components/gen/etoktype.hpp" );
 | 
			
		||||
	builder_print( & header_etoktype, gen_component_header );
 | 
			
		||||
	builder_print( & header_etoktype, format(etoktype) );
 | 
			
		||||
	builder_write( & header_etoktype);
 | 
			
		||||
@@ -69,6 +70,6 @@ int gen_main()
 | 
			
		||||
	builder_print( & header_ast_inlines, format(ast_inlines) );
 | 
			
		||||
	builder_write( & header_ast_inlines);
 | 
			
		||||
 | 
			
		||||
	gen::deinit();
 | 
			
		||||
	gen::deinit(& ctx);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,14 +3,11 @@
 | 
			
		||||
#include "static_data.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
global Code Code_Global;
 | 
			
		||||
global Code Code_Invalid;
 | 
			
		||||
 | 
			
		||||
// This serializes all the data-members in a "debug" format, where each member is printed with its associated value.
 | 
			
		||||
Str code_debug_str(Code self)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self != nullptr);
 | 
			
		||||
	StrBuilder  result_stack = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) );
 | 
			
		||||
	StrBuilder  result_stack = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
 | 
			
		||||
	StrBuilder* result       = & result_stack;
 | 
			
		||||
 | 
			
		||||
	if ( self->Parent )
 | 
			
		||||
@@ -39,7 +36,6 @@ Str code_debug_str(Code self)
 | 
			
		||||
		case CT_Execution:
 | 
			
		||||
		case CT_Comment:
 | 
			
		||||
		case CT_PlatformAttributes:
 | 
			
		||||
		case CT_Preprocess_Define:
 | 
			
		||||
		case CT_Preprocess_Include:
 | 
			
		||||
		case CT_Preprocess_Pragma:
 | 
			
		||||
		case CT_Preprocess_If:
 | 
			
		||||
@@ -55,6 +51,11 @@ Str code_debug_str(Code self)
 | 
			
		||||
			strbuilder_append_fmt( result, "\n\tContent: %S", self->Content );
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Preprocess_Define:
 | 
			
		||||
			// TODO(ED): Needs implementaton
 | 
			
		||||
			log_failure("code_debug_str: NOT IMPLEMENTED for CT_Preprocess_Define");
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Class:
 | 
			
		||||
		case CT_Struct:
 | 
			
		||||
			if ( self->Prev )
 | 
			
		||||
@@ -262,6 +263,11 @@ Str code_debug_str(Code self)
 | 
			
		||||
			strbuilder_append_fmt( result, "\n\tValue     : %S", self->Value     ? strbuilder_to_str( code_to_strbuilder(self->Value))     : txt("Null") );
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Parameters_Define:
 | 
			
		||||
			// TODO(ED): Needs implementaton
 | 
			
		||||
			log_failure("code_debug_str: NOT IMPLEMENTED for CT_Parameters_Define");
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Specifiers:
 | 
			
		||||
		{
 | 
			
		||||
			strbuilder_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries );
 | 
			
		||||
@@ -372,7 +378,7 @@ Code code_duplicate(Code self)
 | 
			
		||||
 | 
			
		||||
StrBuilder code_to_strbuilder(Code self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_str( GlobalAllocator, txt("") );
 | 
			
		||||
	StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") );
 | 
			
		||||
	code_to_strbuilder_ptr( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -500,6 +506,10 @@ void code_to_strbuilder_ptr( Code self, StrBuilder* result )
 | 
			
		||||
			params_to_strbuilder_ref(cast(CodeParams, self), result );
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Parameters_Define:
 | 
			
		||||
			define_params_to_strbuilder_ref(cast(CodeDefineParams, self), result);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Preprocess_Define:
 | 
			
		||||
			define_to_strbuilder_ref(cast(CodeDefine, self), result );
 | 
			
		||||
		break;
 | 
			
		||||
@@ -612,7 +622,7 @@ bool code_is_equal( Code self, Code other )
 | 
			
		||||
	{
 | 
			
		||||
		log_fmt("AST::is_equal: Type check failure with other\nAST: %S\nOther: %S"
 | 
			
		||||
			, code_debug_str(self)
 | 
			
		||||
			,code_debug_str(other)
 | 
			
		||||
			, code_debug_str(other)
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		return false;
 | 
			
		||||
@@ -646,23 +656,23 @@ bool code_is_equal( Code self, Code other )
 | 
			
		||||
		return false;                                               \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#define check_member_content( content )                                \
 | 
			
		||||
	if ( ! str_are_equal( self->content, other->content ))                 \
 | 
			
		||||
	{                                                                      \
 | 
			
		||||
		log_fmt("\nAST::is_equal: Member content - "#content " failed\n"   \
 | 
			
		||||
				"AST  : %S\n"                                              \
 | 
			
		||||
				"Other: %S\n"                                              \
 | 
			
		||||
			, code_debug_str(self)                                         \
 | 
			
		||||
			, code_debug_str(other)                                        \
 | 
			
		||||
		);                                                                 \
 | 
			
		||||
                                                                           \
 | 
			
		||||
		log_fmt("Content cannot be trusted to be unique with this check "  \
 | 
			
		||||
			"so it must be verified by eye for now\n"                      \
 | 
			
		||||
			"AST   Content:\n%S\n"                                         \
 | 
			
		||||
			"Other Content:\n%S\n"                                         \
 | 
			
		||||
			, str_visualize_whitespace(self->content, GlobalAllocator)     \
 | 
			
		||||
			, str_visualize_whitespace(other->content, GlobalAllocator)    \
 | 
			
		||||
		);                                                                 \
 | 
			
		||||
	#define check_member_content( content )                                  \
 | 
			
		||||
	if ( ! str_are_equal( self->content, other->content ))                   \
 | 
			
		||||
	{                                                                        \
 | 
			
		||||
		log_fmt("\nAST::is_equal: Member content - "#content " failed\n"     \
 | 
			
		||||
				"AST  : %S\n"                                                \
 | 
			
		||||
				"Other: %S\n"                                                \
 | 
			
		||||
			, code_debug_str(self)                                           \
 | 
			
		||||
			, code_debug_str(other)                                          \
 | 
			
		||||
		);                                                                   \
 | 
			
		||||
                                                                             \
 | 
			
		||||
		log_fmt("Content cannot be trusted to be unique with this check "    \
 | 
			
		||||
			"so it must be verified by eye for now\n"                        \
 | 
			
		||||
			"AST   Content:\n%S\n"                                           \
 | 
			
		||||
			"Other Content:\n%S\n"                                           \
 | 
			
		||||
			, str_visualize_whitespace(self->content, _ctx->Allocator_Temp)  \
 | 
			
		||||
			, str_visualize_whitespace(other->content, _ctx->Allocator_Temp) \
 | 
			
		||||
		);                                                                   \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#define check_member_ast( ast )                                                                \
 | 
			
		||||
@@ -990,11 +1000,17 @@ bool code_is_equal( Code self, Code other )
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		case CT_Parameters_Define:
 | 
			
		||||
		{
 | 
			
		||||
			// TODO(ED): Needs implementaton
 | 
			
		||||
			log_failure("code_is_equal: NOT IMPLEMENTED for CT_Parameters_Define");
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		case CT_Preprocess_Define:
 | 
			
		||||
		{
 | 
			
		||||
			check_member_str( Name );
 | 
			
		||||
			check_member_content( Content );
 | 
			
		||||
 | 
			
		||||
			check_member_content( Body->Content );
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -1168,7 +1184,7 @@ bool code_validate_body(Code self)
 | 
			
		||||
			CodeBody body = cast(CodeBody, self);
 | 
			
		||||
			for (Code code_entry = begin_CodeBody(body); code_entry != end_CodeBody(body); next_CodeBody(body, code_entry)) switch (code_entry->Type)
 | 
			
		||||
			{
 | 
			
		||||
				GEN_AST_BODY_CLASS_UNALLOWED_TYPES:
 | 
			
		||||
				GEN_AST_BODY_CLASS_UNALLOWED_TYPES_CASES:
 | 
			
		||||
					log_failure("AST::validate_body: Invalid entry in body %S", code_debug_str(code_entry));
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
@@ -1195,7 +1211,7 @@ bool code_validate_body(Code self)
 | 
			
		||||
			CodeBody body = cast(CodeBody, self);
 | 
			
		||||
			for (Code code_entry = begin_CodeBody(body); code_entry != end_CodeBody(body); next_CodeBody(body, code_entry)) switch (code_entry->Type)
 | 
			
		||||
			{
 | 
			
		||||
				GEN_AST_BODY_EXPORT_UNALLOWED_TYPES:
 | 
			
		||||
				GEN_AST_BODY_EXPORT_UNALLOWED_TYPES_CASES:
 | 
			
		||||
					log_failure("AST::validate_body: Invalid entry in body %S", code_debug_str(code_entry));
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
@@ -1209,7 +1225,7 @@ bool code_validate_body(Code self)
 | 
			
		||||
			CodeBody body = cast(CodeBody, self);
 | 
			
		||||
			for (Code code_entry = begin_CodeBody(body); code_entry != end_CodeBody(body); next_CodeBody(body, code_entry)) switch (code_entry->Type)
 | 
			
		||||
			{
 | 
			
		||||
				GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES:
 | 
			
		||||
				GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES_CASES:
 | 
			
		||||
					log_failure("AST::validate_body: Invalid entry in body %S", code_debug_str(code_entry));
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
@@ -1223,7 +1239,7 @@ bool code_validate_body(Code self)
 | 
			
		||||
			CodeBody body = cast(CodeBody, self);
 | 
			
		||||
			for (Code code_entry = begin_CodeBody(body); code_entry != end_CodeBody(body); next_CodeBody(body, code_entry)) switch (code_entry->Type)
 | 
			
		||||
			{
 | 
			
		||||
				GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES:
 | 
			
		||||
				GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES_CASES:
 | 
			
		||||
					log_failure("AST::validate_body: Invalid entry in body %S", code_debug_str(code_entry));
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
@@ -1237,7 +1253,7 @@ bool code_validate_body(Code self)
 | 
			
		||||
			CodeBody body = cast(CodeBody, self);
 | 
			
		||||
			for ( Code entry = begin_CodeBody(body); entry != end_CodeBody(body); next_CodeBody(body, entry) )switch (entry->Type)
 | 
			
		||||
			{
 | 
			
		||||
				GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES:
 | 
			
		||||
				GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES_CASES:
 | 
			
		||||
					log_failure("AST::validate_body: Invalid entry in body %S", code_debug_str(entry));
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
@@ -1248,7 +1264,7 @@ bool code_validate_body(Code self)
 | 
			
		||||
			CodeBody body = cast(CodeBody, self);
 | 
			
		||||
			for ( Code entry = begin_CodeBody(body); entry != end_CodeBody(body); next_CodeBody(body, entry) ) switch (entry->Type)
 | 
			
		||||
			{
 | 
			
		||||
				GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES:
 | 
			
		||||
				GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES_CASES:
 | 
			
		||||
					log_failure("AST::validate_body: Invalid entry in body %S", code_debug_str(entry));
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
@@ -1259,7 +1275,7 @@ bool code_validate_body(Code self)
 | 
			
		||||
			CodeBody body = cast(CodeBody, self);
 | 
			
		||||
			for ( Code entry = begin_CodeBody(body); entry != end_CodeBody(body); next_CodeBody(body, entry) ) switch (entry->Type)
 | 
			
		||||
			{
 | 
			
		||||
				GEN_AST_BODY_STRUCT_UNALLOWED_TYPES:
 | 
			
		||||
				GEN_AST_BODY_STRUCT_UNALLOWED_TYPES_CASES:
 | 
			
		||||
					log_failure("AST::validate_body: Invalid entry in body %S", code_debug_str(entry));
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
@@ -1283,6 +1299,5 @@ bool code_validate_body(Code self)
 | 
			
		||||
			log_failure( "AST::validate_body: Invalid this AST does not have a body %S", code_debug_str(self) );
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ struct AST_Constructor;
 | 
			
		||||
// struct AST_BaseClass;
 | 
			
		||||
struct AST_Class;
 | 
			
		||||
struct AST_Define;
 | 
			
		||||
struct AST_DefineParams;
 | 
			
		||||
struct AST_Destructor;
 | 
			
		||||
struct AST_Enum;
 | 
			
		||||
struct AST_Exec;
 | 
			
		||||
@@ -98,6 +99,7 @@ typedef AST_Comment*        CodeComment;
 | 
			
		||||
typedef AST_Class*          CodeClass;
 | 
			
		||||
typedef AST_Constructor*    CodeConstructor;
 | 
			
		||||
typedef AST_Define*         CodeDefine;
 | 
			
		||||
typedef AST_DefineParams*   CodeDefineParams;
 | 
			
		||||
typedef AST_Destructor*     CodeDestructor;
 | 
			
		||||
typedef AST_Enum*           CodeEnum;
 | 
			
		||||
typedef AST_Exec*           CodeExec;
 | 
			
		||||
@@ -120,6 +122,7 @@ struct CodeComment;
 | 
			
		||||
struct CodeClass;
 | 
			
		||||
struct CodeConstructor;
 | 
			
		||||
struct CodeDefine;
 | 
			
		||||
struct CodeDefineParams;
 | 
			
		||||
struct CodeDestructor;
 | 
			
		||||
struct CodeEnum;
 | 
			
		||||
struct CodeExec;
 | 
			
		||||
@@ -230,40 +233,25 @@ struct CodeUsing;
 | 
			
		||||
struct CodeVar;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GEN_NS_PARSER_BEGIN
 | 
			
		||||
 | 
			
		||||
struct Token;
 | 
			
		||||
 | 
			
		||||
GEN_NS_PARSER_END
 | 
			
		||||
 | 
			
		||||
#if GEN_COMPILER_CPP
 | 
			
		||||
// Note(Ed): This is to alleviate an edge case with parsing usings or typedefs where I don't really have it setup
 | 
			
		||||
// to parse a 'namespace' macro or a type with a macro.
 | 
			
		||||
// 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
 | 
			
		||||
typedef ParserTokenType Token;
 | 
			
		||||
#undef  ParserTokenType
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if GEN_COMPILER_CPP
 | 
			
		||||
template< class Type> forceinline Type tmpl_cast( Code self ) { return * rcast( Type*, & self ); }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma region Code C-Interface
 | 
			
		||||
 | 
			
		||||
void       code_append           (Code code, Code other );
 | 
			
		||||
Str        code_debug_str        (Code code);
 | 
			
		||||
Code       code_duplicate        (Code code);
 | 
			
		||||
Code*      code_entry            (Code code, u32 idx );
 | 
			
		||||
bool       code_has_entries      (Code code);
 | 
			
		||||
bool       code_is_body          (Code code);
 | 
			
		||||
bool       code_is_equal         (Code code, Code other);
 | 
			
		||||
bool       code_is_valid         (Code code);
 | 
			
		||||
void       code_set_global       (Code code);
 | 
			
		||||
StrBuilder code_to_strbuilder    (Code self );
 | 
			
		||||
void       code_to_strbuilder_ptr(Code self, StrBuilder* result );
 | 
			
		||||
Str        code_type_str         (Code self );
 | 
			
		||||
bool       code_validate_body    (Code self );
 | 
			
		||||
GEN_API void       code_append           (Code code, Code other );
 | 
			
		||||
GEN_API Str        code_debug_str        (Code code);
 | 
			
		||||
GEN_API Code       code_duplicate        (Code code);
 | 
			
		||||
GEN_API Code*      code_entry            (Code code, u32 idx );
 | 
			
		||||
GEN_API bool       code_has_entries      (Code code);
 | 
			
		||||
GEN_API bool       code_is_body          (Code code);
 | 
			
		||||
GEN_API bool       code_is_equal         (Code code, Code other);
 | 
			
		||||
GEN_API bool       code_is_valid         (Code code);
 | 
			
		||||
GEN_API void       code_set_global       (Code code);
 | 
			
		||||
GEN_API StrBuilder code_to_strbuilder    (Code self );
 | 
			
		||||
GEN_API void       code_to_strbuilder_ptr(Code self, StrBuilder* result );
 | 
			
		||||
GEN_API Str        code_type_str         (Code self );
 | 
			
		||||
GEN_API bool       code_validate_body    (Code self );
 | 
			
		||||
 | 
			
		||||
#pragma endregion Code C-Interface
 | 
			
		||||
 | 
			
		||||
@@ -320,6 +308,7 @@ struct Code
 | 
			
		||||
	operator CodeClass() const;
 | 
			
		||||
	operator CodeConstructor() const;
 | 
			
		||||
	operator CodeDefine() const;
 | 
			
		||||
	operator CodeDefineParams() const;
 | 
			
		||||
	operator CodeDestructor() const;
 | 
			
		||||
	operator CodeExec() const;
 | 
			
		||||
	operator CodeEnum() const;
 | 
			
		||||
@@ -368,7 +357,7 @@ int AST_ArrSpecs_Cap =
 | 
			
		||||
(
 | 
			
		||||
	AST_POD_Size
 | 
			
		||||
	- sizeof(Code)
 | 
			
		||||
	- sizeof(StringCached)
 | 
			
		||||
	- sizeof(StrCached)
 | 
			
		||||
	- sizeof(Code) * 2
 | 
			
		||||
	- sizeof(Token*)
 | 
			
		||||
	- sizeof(Code)
 | 
			
		||||
@@ -380,6 +369,7 @@ int AST_ArrSpecs_Cap =
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	Simple AST POD with functionality to seralize into C++ syntax.
 | 
			
		||||
	TODO(Ed): Eventually haven't a transparent AST like this will longer be viable once statements & expressions are in (most likely....)
 | 
			
		||||
*/
 | 
			
		||||
struct AST
 | 
			
		||||
{
 | 
			
		||||
@@ -387,7 +377,7 @@ struct AST
 | 
			
		||||
		struct
 | 
			
		||||
		{
 | 
			
		||||
			Code      InlineCmt;       // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
 | 
			
		||||
			Code      Attributes;      // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
 | 
			
		||||
			Code      Attributes;      // Class, Enum, Function, Struct, Typedef, Union, Using, Variable // TODO(Ed): Parameters can have attributes
 | 
			
		||||
			Code      Specs;           // Destructor, Function, Operator, Typename, Variable
 | 
			
		||||
			union {
 | 
			
		||||
				Code  InitializerList; // Constructor
 | 
			
		||||
@@ -399,12 +389,12 @@ struct AST
 | 
			
		||||
			union {
 | 
			
		||||
				Code  Macro;               // Parameter
 | 
			
		||||
				Code  BitfieldSize;        // Variable (Class/Struct Data Member)
 | 
			
		||||
				Code  Params;              // Constructor, Function, Operator, Template, Typename
 | 
			
		||||
				Code  Params;              // Constructor, Define, Function, Operator, Template, Typename
 | 
			
		||||
				Code  UnderlyingTypeMacro; // Enum
 | 
			
		||||
			};
 | 
			
		||||
			union {
 | 
			
		||||
				Code  ArrExpr;          // Typename
 | 
			
		||||
				Code  Body;             // Class, Constructor, Destructor, Enum, Friend, Function, Namespace, Struct, Union
 | 
			
		||||
				Code  Body;             // Class, Constructor, Define, Destructor, Enum, Friend, Function, Namespace, Struct, Union
 | 
			
		||||
				Code  Declaration;      // Friend, Template
 | 
			
		||||
				Code  Value;            // Parameter, Variable
 | 
			
		||||
			};
 | 
			
		||||
@@ -414,13 +404,13 @@ struct AST
 | 
			
		||||
				Code  PostNameMacro;    // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
		StringCached  Content;          // Attributes, Comment, Execution, Include
 | 
			
		||||
		StrCached  Content;          // Attributes, Comment, Execution, Include
 | 
			
		||||
		struct {
 | 
			
		||||
			Specifier  ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
 | 
			
		||||
			Code       NextSpecs;              // Specifiers; If ArrSpecs is full, then NextSpecs is used.
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	union {
 | 
			
		||||
		Code Prev;
 | 
			
		||||
		Code Front;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
// These macros are used in the swtich cases are used within ast.cpp, inteface.upfront.cpp, parser.cpp
 | 
			
		||||
// These macros are used in the swtich cases within ast.cpp, inteface.upfront.cpp, parser.cpp
 | 
			
		||||
 | 
			
		||||
#	define GEN_AST_BODY_CLASS_UNALLOWED_TYPES    \
 | 
			
		||||
#	define GEN_AST_BODY_CLASS_UNALLOWED_TYPES_CASES    \
 | 
			
		||||
	case CT_PlatformAttributes:                  \
 | 
			
		||||
	case CT_Class_Body:                          \
 | 
			
		||||
	case CT_Enum_Body:                           \
 | 
			
		||||
@@ -16,9 +16,9 @@
 | 
			
		||||
	case CT_Specifiers:                          \
 | 
			
		||||
	case CT_Struct_Body:                         \
 | 
			
		||||
	case CT_Typename
 | 
			
		||||
#	define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES GEN_AST_BODY_CLASS_UNALLOWED_TYPES
 | 
			
		||||
#	define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES_CASES GEN_AST_BODY_CLASS_UNALLOWED_TYPES_CASES
 | 
			
		||||
 | 
			
		||||
#	define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES \
 | 
			
		||||
#	define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES_CASES \
 | 
			
		||||
	case CT_Access_Public:                          \
 | 
			
		||||
	case CT_Access_Protected:                       \
 | 
			
		||||
	case CT_Access_Private:                         \
 | 
			
		||||
@@ -41,7 +41,7 @@
 | 
			
		||||
	case CT_Struct_Body:                            \
 | 
			
		||||
	case CT_Typename
 | 
			
		||||
 | 
			
		||||
#	define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES     \
 | 
			
		||||
#	define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES_CASES     \
 | 
			
		||||
	case CT_Access_Public:                         \
 | 
			
		||||
	case CT_Access_Protected:                      \
 | 
			
		||||
	case CT_Access_Private:                        \
 | 
			
		||||
@@ -58,10 +58,10 @@
 | 
			
		||||
	case CT_Specifiers:                            \
 | 
			
		||||
	case CT_Struct_Body:                           \
 | 
			
		||||
	case CT_Typename
 | 
			
		||||
#	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_EXPORT_UNALLOWED_TYPES_CASES         GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES_CASES
 | 
			
		||||
#	define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES_CASES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES_CASES
 | 
			
		||||
 | 
			
		||||
#	define GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES \
 | 
			
		||||
#	define GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES_CASES \
 | 
			
		||||
	case CT_Access_Public:                        \
 | 
			
		||||
	case CT_Access_Protected:                     \
 | 
			
		||||
	case CT_Access_Private:                       \
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ struct AST_Body
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Front;
 | 
			
		||||
	Code              Back;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -42,13 +42,14 @@ struct AST_Body
 | 
			
		||||
};
 | 
			
		||||
static_assert( sizeof(AST_Body) == sizeof(AST), "ERROR: AST_Body is not the same size as AST");
 | 
			
		||||
 | 
			
		||||
// TODO(Ed): Support chaining attributes (Use parameter linkage pattern)
 | 
			
		||||
struct AST_Attributes
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
		StringCached  Content;
 | 
			
		||||
		StrCached  Content;
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached         Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -64,7 +65,7 @@ struct AST_BaseClass
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -79,9 +80,9 @@ struct AST_Comment
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
		StringCached  Content;
 | 
			
		||||
		StrCached  Content;
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -106,7 +107,7 @@ struct AST_Class
 | 
			
		||||
			char 	        _PAD_PROPERTIES_2_[ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached            Name;
 | 
			
		||||
	StrCached            Name;
 | 
			
		||||
	CodeTypename            Prev;
 | 
			
		||||
	CodeTypename            Next;
 | 
			
		||||
	Token*                  Tok;
 | 
			
		||||
@@ -132,7 +133,7 @@ struct AST_Constructor
 | 
			
		||||
			char 		   _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -146,9 +147,15 @@ struct AST_Define
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
		StringCached  Content;
 | 
			
		||||
		struct
 | 
			
		||||
		{
 | 
			
		||||
			char              _PAD_PROPERTIES_ [ sizeof(AST*) * 4 ];
 | 
			
		||||
			CodeDefineParams  Params;
 | 
			
		||||
			Code              Body; // Should be completely serialized for now to a: StrCached Content.
 | 
			
		||||
			char              _PAD_PROPERTIES_2_ [ sizeof(AST*) * 1 ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached         Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -158,6 +165,22 @@ struct AST_Define
 | 
			
		||||
};
 | 
			
		||||
static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the same size as AST");
 | 
			
		||||
 | 
			
		||||
struct AST_DefineParams
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StrCached         Name;
 | 
			
		||||
	CodeDefineParams  Last;
 | 
			
		||||
	CodeDefineParams  Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
	Code              Parent;
 | 
			
		||||
	CodeType          Type;
 | 
			
		||||
	char 			  _PAD_UNUSED_[ sizeof(ModuleFlag) ];
 | 
			
		||||
	s32               NumEntries;
 | 
			
		||||
};
 | 
			
		||||
static_assert( sizeof(AST_DefineParams) == sizeof(AST), "ERROR: AST_DefineParams is not the same size as AST");
 | 
			
		||||
 | 
			
		||||
struct AST_Destructor
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
@@ -172,7 +195,7 @@ struct AST_Destructor
 | 
			
		||||
			char 		   _PAD_PROPERTIES_3_ [ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached           Name;
 | 
			
		||||
	StrCached           Name;
 | 
			
		||||
	Code                   Prev;
 | 
			
		||||
	Code                   Next;
 | 
			
		||||
	Token*                 Tok;
 | 
			
		||||
@@ -197,7 +220,7 @@ struct AST_Enum
 | 
			
		||||
			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached           Name;
 | 
			
		||||
	StrCached           Name;
 | 
			
		||||
	Code                   Prev;
 | 
			
		||||
	Code                   Next;
 | 
			
		||||
	Token*                 Tok;
 | 
			
		||||
@@ -212,9 +235,9 @@ struct AST_Exec
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
		StringCached  Content;
 | 
			
		||||
		StrCached  Content;
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -230,7 +253,7 @@ struct AST_Expr
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -245,7 +268,7 @@ struct AST_Expr_Assign
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -260,7 +283,7 @@ struct AST_Expr_Alignof
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -275,7 +298,7 @@ struct AST_Expr_Binary
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -290,7 +313,7 @@ struct AST_Expr_CStyleCast
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -305,7 +328,7 @@ struct AST_Expr_FunctionalCast
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -320,7 +343,7 @@ struct AST_Expr_CppCast
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -335,7 +358,7 @@ struct AST_Expr_ProcCall
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -350,7 +373,7 @@ struct AST_Expr_Decltype
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -365,7 +388,7 @@ struct AST_Expr_Comma
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -380,7 +403,7 @@ struct AST_Expr_AMS
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -395,7 +418,7 @@ struct AST_Expr_Sizeof
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -410,7 +433,7 @@ struct AST_Expr_Subscript
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -425,7 +448,7 @@ struct AST_Expr_Ternary
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -440,7 +463,7 @@ struct AST_Expr_UnaryPrefix
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -455,7 +478,7 @@ struct AST_Expr_UnaryPostfix
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -470,7 +493,7 @@ struct AST_Expr_Element
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -492,7 +515,7 @@ struct AST_Extern
 | 
			
		||||
			char      _PAD_PROPERTIES_2_[ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -506,9 +529,9 @@ struct AST_Include
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
		StringCached  Content;
 | 
			
		||||
		StrCached  Content;
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -530,7 +553,7 @@ struct AST_Friend
 | 
			
		||||
			char 	    _PAD_PROPERTIES_2_[ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -555,7 +578,7 @@ struct AST_Fn
 | 
			
		||||
			char 	        _PAD_PROPERTIES_ [ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached            Name;
 | 
			
		||||
	StrCached            Name;
 | 
			
		||||
	Code                    Prev;
 | 
			
		||||
	Code                    Next;
 | 
			
		||||
	Token*                  Tok;
 | 
			
		||||
@@ -571,7 +594,7 @@ struct AST_Module
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -592,7 +615,7 @@ struct AST_NS
 | 
			
		||||
			char 	  _PAD_PROPERTIES_2_[ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -618,7 +641,7 @@ struct AST_Operator
 | 
			
		||||
			char 	        _PAD_PROPERTIES_ [ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	Code           Prev;
 | 
			
		||||
	Code           Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -644,7 +667,7 @@ struct AST_OpCast
 | 
			
		||||
			char 	        _PAD_PROPERTIES_3_[ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -660,6 +683,7 @@ struct AST_Params
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
		struct
 | 
			
		||||
		{
 | 
			
		||||
			// TODO(Ed): Support attributes for parameters (Some prefix macros can be converted to that...)
 | 
			
		||||
			char 	     _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
 | 
			
		||||
			CodeTypename ValueType;
 | 
			
		||||
			Code         Macro;
 | 
			
		||||
@@ -668,7 +692,7 @@ struct AST_Params
 | 
			
		||||
			// char     _PAD_PROPERTIES_3_[sizeof( AST* )];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached         Name;
 | 
			
		||||
	CodeParams        Last;
 | 
			
		||||
	CodeParams        Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -683,9 +707,9 @@ struct AST_Pragma
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
		StringCached  Content;
 | 
			
		||||
		StrCached  Content;
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -699,9 +723,9 @@ struct AST_PreprocessCond
 | 
			
		||||
{
 | 
			
		||||
	union {
 | 
			
		||||
		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
		StringCached  Content;
 | 
			
		||||
		StrCached  Content;
 | 
			
		||||
	};
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
	Token*            Tok;
 | 
			
		||||
@@ -714,7 +738,7 @@ static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_Preprocess
 | 
			
		||||
struct AST_Specifiers
 | 
			
		||||
{
 | 
			
		||||
	Specifier         ArrSpecs[ AST_ArrSpecs_Cap ];
 | 
			
		||||
	StringCached      Name;
 | 
			
		||||
	StrCached      Name;
 | 
			
		||||
	CodeSpecifiers    NextSpecs;
 | 
			
		||||
	Code              Prev;
 | 
			
		||||
	Code              Next;
 | 
			
		||||
@@ -732,7 +756,7 @@ struct AST_Stmt
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -747,7 +771,7 @@ struct AST_Stmt_Break
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -762,7 +786,7 @@ struct AST_Stmt_Case
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -777,7 +801,7 @@ struct AST_Stmt_Continue
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -792,7 +816,7 @@ struct AST_Stmt_Decl
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -807,7 +831,7 @@ struct AST_Stmt_Do
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -822,7 +846,7 @@ struct AST_Stmt_Expr
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -837,7 +861,7 @@ struct AST_Stmt_Else
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -852,7 +876,7 @@ struct AST_Stmt_If
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -867,7 +891,7 @@ struct AST_Stmt_For
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -882,7 +906,7 @@ struct AST_Stmt_Goto
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -897,7 +921,7 @@ struct AST_Stmt_Label
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -912,7 +936,7 @@ struct AST_Stmt_Switch
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -927,7 +951,7 @@ struct AST_Stmt_While
 | 
			
		||||
	union {
 | 
			
		||||
		char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
 | 
			
		||||
	};
 | 
			
		||||
	StringCached   Name;
 | 
			
		||||
	StrCached   Name;
 | 
			
		||||
	CodeExpr       Prev;
 | 
			
		||||
	CodeExpr       Next;
 | 
			
		||||
	Token*         Tok;
 | 
			
		||||
@@ -953,7 +977,7 @@ struct AST_Struct
 | 
			
		||||
			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached           Name;
 | 
			
		||||
	StrCached           Name;
 | 
			
		||||
	CodeTypename           Prev;
 | 
			
		||||
	CodeTypename           Next;
 | 
			
		||||
	Token*                 Tok;
 | 
			
		||||
@@ -976,7 +1000,7 @@ struct AST_Template
 | 
			
		||||
			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached           Name;
 | 
			
		||||
	StrCached           Name;
 | 
			
		||||
	Code                   Prev;
 | 
			
		||||
	Code                   Next;
 | 
			
		||||
	Token*                 Tok;
 | 
			
		||||
@@ -1005,7 +1029,7 @@ struct AST_Type
 | 
			
		||||
			// CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached           Name;
 | 
			
		||||
	StrCached           Name;
 | 
			
		||||
	Code                   Prev;
 | 
			
		||||
	Code                   Next;
 | 
			
		||||
	Token*                  Tok;
 | 
			
		||||
@@ -1032,7 +1056,7 @@ struct AST_Typename
 | 
			
		||||
			CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached           Name;
 | 
			
		||||
	StrCached           Name;
 | 
			
		||||
	Code                   Prev;
 | 
			
		||||
	Code                   Next;
 | 
			
		||||
	Token*                 Tok;
 | 
			
		||||
@@ -1058,7 +1082,7 @@ struct AST_Typedef
 | 
			
		||||
			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached           Name;
 | 
			
		||||
	StrCached           Name;
 | 
			
		||||
	Code                   Prev;
 | 
			
		||||
	Code                   Next;
 | 
			
		||||
	Token*                 Tok;
 | 
			
		||||
@@ -1082,7 +1106,7 @@ struct AST_Union
 | 
			
		||||
			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached           Name;
 | 
			
		||||
	StrCached           Name;
 | 
			
		||||
	Code                   Prev;
 | 
			
		||||
	Code                   Next;
 | 
			
		||||
	Token*                 Tok;
 | 
			
		||||
@@ -1106,7 +1130,7 @@ struct AST_Using
 | 
			
		||||
			char 	        _PAD_PROPERTIES_[ sizeof(AST*) * 3 ];
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached            Name;
 | 
			
		||||
	StrCached            Name;
 | 
			
		||||
	Code                    Prev;
 | 
			
		||||
	Code                    Next;
 | 
			
		||||
	Token*                  Tok;
 | 
			
		||||
@@ -1132,7 +1156,7 @@ struct AST_Var
 | 
			
		||||
			CodeVar		   NextVar;
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
	StringCached           Name;
 | 
			
		||||
	StrCached           Name;
 | 
			
		||||
	Code                   Prev;
 | 
			
		||||
	Code                   Next;
 | 
			
		||||
	Token*                 Tok;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
inline
 | 
			
		||||
StrBuilder attributes_to_strbuilder(CodeAttributes attributes) {
 | 
			
		||||
	GEN_ASSERT(attributes);
 | 
			
		||||
	char* raw = ccast(char*, str_duplicate( attributes->Content, GlobalAllocator ).Ptr);
 | 
			
		||||
	char* raw = ccast(char*, str_duplicate( attributes->Content, _ctx->Allocator_Temp ).Ptr);
 | 
			
		||||
	StrBuilder result = { raw };
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -21,7 +21,7 @@ void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result)
 | 
			
		||||
StrBuilder body_to_strbuilder(CodeBody body)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(body);
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
 | 
			
		||||
	switch ( body->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Untyped:
 | 
			
		||||
@@ -82,7 +82,7 @@ void body_to_strbuilder_export( CodeBody body, StrBuilder* result )
 | 
			
		||||
inline
 | 
			
		||||
StrBuilder comment_to_strbuilder(CodeComment comment) {
 | 
			
		||||
	GEN_ASSERT(comment);
 | 
			
		||||
	char* raw = ccast(char*, str_duplicate( comment->Content, GlobalAllocator ).Ptr);
 | 
			
		||||
	char* raw = ccast(char*, str_duplicate( comment->Content, _ctx->Allocator_Temp ).Ptr);
 | 
			
		||||
	StrBuilder result = { raw };
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -96,7 +96,7 @@ void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result) {
 | 
			
		||||
 | 
			
		||||
StrBuilder constructor_to_strbuilder(CodeConstructor self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
 | 
			
		||||
	switch (self->Type)
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Constructor:
 | 
			
		||||
@@ -159,7 +159,7 @@ void constructor_to_strbuilder_fwd(CodeConstructor self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder class_to_strbuilder( CodeClass self )
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Class:
 | 
			
		||||
@@ -176,7 +176,7 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	strbuilder_append_str( result, txt("class ") );
 | 
			
		||||
@@ -221,7 +221,7 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes )
 | 
			
		||||
@@ -241,17 +241,53 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder define_to_strbuilder(CodeDefine define)
 | 
			
		||||
{
 | 
			
		||||
	return strbuilder_fmt_buf( GlobalAllocator, "#define %S %S", define->Name, define->Content );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
 | 
			
		||||
	define_to_strbuilder_ref(define, & result);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	strbuilder_append_fmt( result, "#define %S %S", define->Name, define->Content );
 | 
			
		||||
	GEN_ASSERT(define);
 | 
			
		||||
	GEN_ASSERT(define->Body);
 | 
			
		||||
	GEN_ASSERT(define->Body->Content.Ptr && define->Body->Content.Len > 0);
 | 
			
		||||
	if (define->Params) {
 | 
			
		||||
		StrBuilder params_builder = define_params_to_strbuilder(define->Params);
 | 
			
		||||
		strbuilder_append_fmt( result, "#define %S(%S) %S", define->Name, strbuilder_to_str(params_builder), define->Body->Content );
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		strbuilder_append_fmt( result, "#define %S %S", define->Name, define->Body->Content );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StrBuilder define_params_to_strbuilder(CodeDefineParams params)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(params);
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
 | 
			
		||||
	define_params_to_strbuilder_ref( params, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void define_params_to_strbuilder_ref(CodeDefineParams self, StrBuilder* result)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	GEN_ASSERT(result);
 | 
			
		||||
	if ( self->Name.Ptr && self->Name.Len )
 | 
			
		||||
	{
 | 
			
		||||
		strbuilder_append_fmt( result, " %S", self->Name );
 | 
			
		||||
	}
 | 
			
		||||
	if ( self->NumEntries - 1 > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		for ( CodeDefineParams param = begin_CodeDefineParams(self->Next); param != end_CodeDefineParams(self->Next); param = next_CodeDefineParams(self->Next, param) )
 | 
			
		||||
		{
 | 
			
		||||
			strbuilder_append_fmt( result, ", %SB", define_params_to_strbuilder(param) );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StrBuilder destructor_to_strbuilder(CodeDestructor self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Destructor:
 | 
			
		||||
@@ -308,7 +344,7 @@ void destructor_to_strbuilder_fwd(CodeDestructor self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder enum_to_strbuilder(CodeEnum self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Enum:
 | 
			
		||||
@@ -329,7 +365,7 @@ StrBuilder enum_to_strbuilder(CodeEnum self)
 | 
			
		||||
 | 
			
		||||
void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes || self->UnderlyingType || self->UnderlyingTypeMacro )
 | 
			
		||||
@@ -362,7 +398,7 @@ void enum_to_strbuilder_def(CodeEnum self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes )
 | 
			
		||||
@@ -389,7 +425,7 @@ void enum_to_strbuilder_fwd(CodeEnum self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes || self->UnderlyingType )
 | 
			
		||||
@@ -421,7 +457,7 @@ void enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	strbuilder_append_str( result, txt("enum class ") );
 | 
			
		||||
@@ -443,7 +479,7 @@ void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result )
 | 
			
		||||
StrBuilder exec_to_strbuilder(CodeExec exec)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(exec);
 | 
			
		||||
	char* raw = ccast(char*, str_duplicate( exec->Content, GlobalAllocator ).Ptr);
 | 
			
		||||
	char* raw = ccast(char*, str_duplicate( exec->Content, _ctx->Allocator_Temp ).Ptr);
 | 
			
		||||
	StrBuilder result = { raw };
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -458,7 +494,7 @@ void extern_to_strbuilder(CodeExtern self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder include_to_strbuilder(CodeInclude include)
 | 
			
		||||
{
 | 
			
		||||
	return strbuilder_fmt_buf( GlobalAllocator, "#include %S\n", include->Content );
 | 
			
		||||
	return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#include %S\n", include->Content );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void include_to_strbuilder_ref( CodeInclude include, StrBuilder* result )
 | 
			
		||||
@@ -468,7 +504,7 @@ void include_to_strbuilder_ref( CodeInclude include, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder friend_to_strbuilder(CodeFriend self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 256 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
 | 
			
		||||
	friend_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -490,7 +526,7 @@ void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder fn_to_strbuilder(CodeFn self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Function:
 | 
			
		||||
@@ -505,7 +541,7 @@ StrBuilder fn_to_strbuilder(CodeFn self)
 | 
			
		||||
 | 
			
		||||
void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes )
 | 
			
		||||
@@ -558,7 +594,7 @@ void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes )
 | 
			
		||||
@@ -621,7 +657,7 @@ void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder module_to_strbuilder(CodeModule self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 64 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
 | 
			
		||||
	module_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -639,14 +675,14 @@ void module_to_strbuilder_ref(CodeModule self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder namespace_to_strbuilder(CodeNS self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
 | 
			
		||||
	namespace_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	strbuilder_append_fmt( result, "namespace %S\n{\n%SB\n}\n", self->Name, body_to_strbuilder(self->Body) );
 | 
			
		||||
@@ -654,7 +690,7 @@ void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder code_op_to_strbuilder(CodeOperator self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Operator:
 | 
			
		||||
@@ -671,7 +707,7 @@ StrBuilder code_op_to_strbuilder(CodeOperator self)
 | 
			
		||||
 | 
			
		||||
void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes )
 | 
			
		||||
@@ -725,7 +761,7 @@ void code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes )
 | 
			
		||||
@@ -776,7 +812,7 @@ void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder opcast_to_strbuilder(CodeOpCast self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Operator_Cast:
 | 
			
		||||
@@ -866,8 +902,7 @@ void opcast_to_strbuilder_fwd(CodeOpCast self, StrBuilder* result )
 | 
			
		||||
StrBuilder params_to_strbuilder(CodeParams self)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
 | 
			
		||||
	params_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -914,7 +949,7 @@ void params_to_strbuilder_ref( CodeParams self, StrBuilder* result )
 | 
			
		||||
StrBuilder preprocess_to_strbuilder(CodePreprocessCond self)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 256 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Preprocess_If:
 | 
			
		||||
@@ -978,7 +1013,7 @@ void preprocess_to_strbuilder_endif(CodePreprocessCond cond, StrBuilder* result
 | 
			
		||||
StrBuilder pragma_to_strbuilder(CodePragma self)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 256 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
 | 
			
		||||
	pragma_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -990,7 +1025,7 @@ void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder specifiers_to_strbuilder(CodeSpecifiers self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 64 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 );
 | 
			
		||||
	specifiers_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -1001,19 +1036,31 @@ void specifiers_to_strbuilder_ref( CodeSpecifiers self, StrBuilder* result )
 | 
			
		||||
	GEN_ASSERT(result);
 | 
			
		||||
	s32 idx  = 0;
 | 
			
		||||
	s32 left = self->NumEntries;
 | 
			
		||||
	while ( left-- )
 | 
			
		||||
	while ( left -- )
 | 
			
		||||
	{
 | 
			
		||||
		Str spec = spec_to_str( self->ArrSpecs[idx] );
 | 
			
		||||
		strbuilder_append_fmt( result, "%.*s ", spec.Len, spec.Ptr );
 | 
			
		||||
		Specifier spec     = self->ArrSpecs[idx];
 | 
			
		||||
		Str       spec_str = spec_to_str( spec );
 | 
			
		||||
		if ( idx > 0 ) switch (spec) {
 | 
			
		||||
			case Spec_Ptr:
 | 
			
		||||
			case Spec_Ref:
 | 
			
		||||
			case Spec_RValue:
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
			default:
 | 
			
		||||
				strbuilder_append_str(result, txt(" "));
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		strbuilder_append_fmt( result, "%S", spec_str );
 | 
			
		||||
		idx++;
 | 
			
		||||
	}
 | 
			
		||||
	strbuilder_append_str(result, txt(" "));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StrBuilder struct_to_strbuilder(CodeStruct self)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Struct:
 | 
			
		||||
@@ -1030,7 +1077,7 @@ void struct_to_strbuilder_def( CodeStruct self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	GEN_ASSERT(result);
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	strbuilder_append_str( result, txt("struct ") );
 | 
			
		||||
@@ -1076,7 +1123,7 @@ void struct_to_strbuilder_fwd( CodeStruct self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	GEN_ASSERT(result);
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes )
 | 
			
		||||
@@ -1096,7 +1143,7 @@ void struct_to_strbuilder_fwd( CodeStruct self, StrBuilder* result )
 | 
			
		||||
StrBuilder template_to_strbuilder(CodeTemplate self)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 1024 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 1024 );
 | 
			
		||||
	template_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -1105,7 +1152,7 @@ void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	GEN_ASSERT(result);
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Params )
 | 
			
		||||
@@ -1116,14 +1163,14 @@ void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder typedef_to_strbuilder(CodeTypedef self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
 | 
			
		||||
	typedef_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	strbuilder_append_str( result, txt("typedef "));
 | 
			
		||||
@@ -1158,7 +1205,7 @@ void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder typename_to_strbuilder(CodeTypename self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_str( GlobalAllocator, txt("") );
 | 
			
		||||
	StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") );
 | 
			
		||||
	typename_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -1221,7 +1268,7 @@ void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
StrBuilder union_to_strbuilder(CodeUnion self)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Union:
 | 
			
		||||
@@ -1236,7 +1283,7 @@ StrBuilder union_to_strbuilder(CodeUnion self)
 | 
			
		||||
 | 
			
		||||
void union_to_strbuilder_def(CodeUnion self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	strbuilder_append_str( result, txt("union ") );
 | 
			
		||||
@@ -1267,7 +1314,7 @@ void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	GEN_ASSERT(result);
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	strbuilder_append_str( result, txt("union ") );
 | 
			
		||||
@@ -1287,7 +1334,7 @@ void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result )
 | 
			
		||||
StrBuilder using_to_strbuilder(CodeUsing self)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 );
 | 
			
		||||
	switch ( self->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Using:
 | 
			
		||||
@@ -1304,7 +1351,7 @@ void using_to_strbuilder_ref(CodeUsing self, StrBuilder* result )
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	GEN_ASSERT(result);
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes )
 | 
			
		||||
@@ -1352,7 +1399,7 @@ inline
 | 
			
		||||
StrBuilder var_to_strbuilder(CodeVar self)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(self);
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 256 );
 | 
			
		||||
	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 );
 | 
			
		||||
	var_to_strbuilder_ref( self, & result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -1371,7 +1418,7 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result )
 | 
			
		||||
 | 
			
		||||
		strbuilder_append_str( result, self->Name );
 | 
			
		||||
 | 
			
		||||
		if ( self->ValueType->ArrExpr )
 | 
			
		||||
		if ( self->ValueType && self->ValueType->ArrExpr )
 | 
			
		||||
		{
 | 
			
		||||
			strbuilder_append_fmt( result, "[ %SB ]", code_to_strbuilder(self->ValueType->ArrExpr) );
 | 
			
		||||
 | 
			
		||||
@@ -1401,16 +1448,16 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result )
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( bitfield_is_equal( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
	if ( bitfield_is_set( u32, self->ModuleFlags, ModuleFlag_Export ))
 | 
			
		||||
		strbuilder_append_str( result, txt("export ") );
 | 
			
		||||
 | 
			
		||||
	if ( self->Attributes || self->Specs )
 | 
			
		||||
	{
 | 
			
		||||
		if ( self->Attributes )
 | 
			
		||||
			strbuilder_append_fmt( result, "%SB ", specifiers_to_strbuilder(self->Specs) );
 | 
			
		||||
			strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) );
 | 
			
		||||
 | 
			
		||||
		if ( self->Specs )
 | 
			
		||||
			strbuilder_append_fmt( result, "%SB\n", specifiers_to_strbuilder(self->Specs) );
 | 
			
		||||
			strbuilder_append_fmt( result, "%SB", specifiers_to_strbuilder(self->Specs) );
 | 
			
		||||
 | 
			
		||||
		strbuilder_append_fmt( result, "%SB %S", typename_to_strbuilder(self->ValueType), self->Name );
 | 
			
		||||
 | 
			
		||||
@@ -1454,7 +1501,7 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result )
 | 
			
		||||
	if ( self->BitfieldSize )
 | 
			
		||||
		strbuilder_append_fmt( result, "%SB %S : %SB", typename_to_strbuilder(self->ValueType), self->Name, code_to_strbuilder(self->BitfieldSize) );
 | 
			
		||||
 | 
			
		||||
	else if ( self->ValueType->ArrExpr )
 | 
			
		||||
	else if ( self->ValueType && self->ValueType->ArrExpr )
 | 
			
		||||
	{
 | 
			
		||||
		strbuilder_append_fmt( result, "%SB %S[ %SB ]", typename_to_strbuilder(self->ValueType), self->Name, code_to_strbuilder(self->ValueType->ArrExpr) );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,128 +17,138 @@
 | 
			
		||||
 | 
			
		||||
#pragma region Code Type C-Interface
 | 
			
		||||
 | 
			
		||||
void       body_append              ( CodeBody body, Code     other );
 | 
			
		||||
void       body_append_body         ( CodeBody body, CodeBody other );
 | 
			
		||||
StrBuilder body_to_strbuilder       ( CodeBody body );
 | 
			
		||||
void       body_to_strbuilder_ref   ( CodeBody body, StrBuilder* result );
 | 
			
		||||
void       body_to_strbuilder_export( CodeBody body, StrBuilder* result );
 | 
			
		||||
GEN_API void       body_append              ( CodeBody body, Code     other );
 | 
			
		||||
GEN_API void       body_append_body         ( CodeBody body, CodeBody other );
 | 
			
		||||
GEN_API StrBuilder body_to_strbuilder       ( CodeBody body );
 | 
			
		||||
GEN_API void       body_to_strbuilder_ref   ( CodeBody body, StrBuilder* result );
 | 
			
		||||
GEN_API void       body_to_strbuilder_export( CodeBody body, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
Code begin_CodeBody( CodeBody body);
 | 
			
		||||
Code end_CodeBody  ( CodeBody body );
 | 
			
		||||
Code next_CodeBody ( CodeBody body, Code entry_iter );
 | 
			
		||||
GEN_API Code begin_CodeBody( CodeBody body);
 | 
			
		||||
GEN_API Code end_CodeBody  ( CodeBody body );
 | 
			
		||||
GEN_API Code next_CodeBody ( CodeBody body, Code entry_iter );
 | 
			
		||||
 | 
			
		||||
void       class_add_interface    ( CodeClass self, CodeTypename interface );
 | 
			
		||||
StrBuilder class_to_strbuilder    ( CodeClass self );
 | 
			
		||||
void       class_to_strbuilder_def( CodeClass self, StrBuilder* result );
 | 
			
		||||
void       class_to_strbuilder_fwd( CodeClass self, StrBuilder* result );
 | 
			
		||||
GEN_API void       class_add_interface    ( CodeClass self, CodeTypename interface );
 | 
			
		||||
GEN_API StrBuilder class_to_strbuilder    ( CodeClass self );
 | 
			
		||||
GEN_API void       class_to_strbuilder_def( CodeClass self, StrBuilder* result );
 | 
			
		||||
GEN_API void       class_to_strbuilder_fwd( CodeClass self, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
void       params_append           (CodeParams params, CodeParams param );
 | 
			
		||||
CodeParams params_get              (CodeParams params, s32 idx);
 | 
			
		||||
bool       params_has_entries      (CodeParams params );
 | 
			
		||||
StrBuilder params_to_strbuilder    (CodeParams params );
 | 
			
		||||
void       params_to_strbuilder_ref(CodeParams params, StrBuilder* result );
 | 
			
		||||
GEN_API void             define_params_append           (CodeDefineParams appendee, CodeDefineParams other );
 | 
			
		||||
GEN_API CodeDefineParams define_params_get              (CodeDefineParams params, s32 idx);
 | 
			
		||||
GEN_API bool             define_params_has_entries      (CodeDefineParams params );
 | 
			
		||||
GEN_API StrBuilder       define_params_to_strbuilder    (CodeDefineParams params );
 | 
			
		||||
GEN_API void             define_params_to_strbuilder_ref(CodeDefineParams params, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
CodeParams begin_CodeParams(CodeParams params);
 | 
			
		||||
CodeParams end_CodeParams  (CodeParams params);
 | 
			
		||||
CodeParams next_CodeParams (CodeParams params, CodeParams entry_iter);
 | 
			
		||||
GEN_API CodeDefineParams begin_CodeDefineParams(CodeDefineParams params);
 | 
			
		||||
GEN_API CodeDefineParams end_CodeDefineParams  (CodeDefineParams params);
 | 
			
		||||
GEN_API CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter);
 | 
			
		||||
 | 
			
		||||
bool       specifiers_append           (CodeSpecifiers specifiers, Specifier spec);
 | 
			
		||||
s32        specifiers_has              (CodeSpecifiers specifiers, Specifier spec);
 | 
			
		||||
s32        specifiers_remove           (CodeSpecifiers specifiers, Specifier to_remove );
 | 
			
		||||
StrBuilder specifiers_to_strbuilder    (CodeSpecifiers specifiers);
 | 
			
		||||
void       specifiers_to_strbuilder_ref(CodeSpecifiers specifiers, StrBuilder* result);
 | 
			
		||||
GEN_API void       params_append           (CodeParams appendee, CodeParams other );
 | 
			
		||||
GEN_API CodeParams params_get              (CodeParams params, s32 idx);
 | 
			
		||||
GEN_API bool       params_has_entries      (CodeParams params );
 | 
			
		||||
GEN_API StrBuilder params_to_strbuilder    (CodeParams params );
 | 
			
		||||
GEN_API void       params_to_strbuilder_ref(CodeParams params, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
Specifier* begin_CodeSpecifiers(CodeSpecifiers specifiers);
 | 
			
		||||
Specifier* end_CodeSpecifiers  (CodeSpecifiers specifiers);
 | 
			
		||||
Specifier* next_CodeSpecifiers (CodeSpecifiers specifiers, Specifier* spec_iter);
 | 
			
		||||
GEN_API CodeParams begin_CodeParams(CodeParams params);
 | 
			
		||||
GEN_API CodeParams end_CodeParams  (CodeParams params);
 | 
			
		||||
GEN_API CodeParams next_CodeParams (CodeParams params, CodeParams entry_iter);
 | 
			
		||||
 | 
			
		||||
void       struct_add_interface    (CodeStruct self, CodeTypename interface);
 | 
			
		||||
StrBuilder struct_to_strbuilder    (CodeStruct self);
 | 
			
		||||
void       struct_to_strbuilder_fwd(CodeStruct self, StrBuilder* result);
 | 
			
		||||
void       struct_to_strbuilder_def(CodeStruct self, StrBuilder* result);
 | 
			
		||||
GEN_API bool       specifiers_append           (CodeSpecifiers specifiers, Specifier spec);
 | 
			
		||||
GEN_API s32        specifiers_has              (CodeSpecifiers specifiers, Specifier spec);
 | 
			
		||||
GEN_API s32        specifiers_remove           (CodeSpecifiers specifiers, Specifier to_remove );
 | 
			
		||||
GEN_API StrBuilder specifiers_to_strbuilder    (CodeSpecifiers specifiers);
 | 
			
		||||
GEN_API void       specifiers_to_strbuilder_ref(CodeSpecifiers specifiers, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder attributes_to_strbuilder    (CodeAttributes attributes);
 | 
			
		||||
void       attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result);
 | 
			
		||||
GEN_API Specifier* begin_CodeSpecifiers(CodeSpecifiers specifiers);
 | 
			
		||||
GEN_API Specifier* end_CodeSpecifiers  (CodeSpecifiers specifiers);
 | 
			
		||||
GEN_API Specifier* next_CodeSpecifiers (CodeSpecifiers specifiers, Specifier* spec_iter);
 | 
			
		||||
 | 
			
		||||
StrBuilder comment_to_strbuilder    (CodeComment comment );
 | 
			
		||||
void       comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result );
 | 
			
		||||
GEN_API void       struct_add_interface    (CodeStruct self, CodeTypename interface);
 | 
			
		||||
GEN_API StrBuilder struct_to_strbuilder    (CodeStruct self);
 | 
			
		||||
GEN_API void       struct_to_strbuilder_fwd(CodeStruct self, StrBuilder* result);
 | 
			
		||||
GEN_API void       struct_to_strbuilder_def(CodeStruct self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder constructor_to_strbuilder    (CodeConstructor constructor);
 | 
			
		||||
void       constructor_to_strbuilder_def(CodeConstructor constructor, StrBuilder* result );
 | 
			
		||||
void       constructor_to_strbuilder_fwd(CodeConstructor constructor, StrBuilder* result );
 | 
			
		||||
GEN_API StrBuilder attributes_to_strbuilder    (CodeAttributes attributes);
 | 
			
		||||
GEN_API void       attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder define_to_strbuilder    (CodeDefine self);
 | 
			
		||||
void       define_to_strbuilder_ref(CodeDefine self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder comment_to_strbuilder    (CodeComment comment );
 | 
			
		||||
GEN_API void       comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
StrBuilder destructor_to_strbuilder    (CodeDestructor destructor);
 | 
			
		||||
void       destructor_to_strbuilder_fwd(CodeDestructor destructor, StrBuilder* result );
 | 
			
		||||
void       destructor_to_strbuilder_def(CodeDestructor destructor, StrBuilder* result );
 | 
			
		||||
GEN_API StrBuilder constructor_to_strbuilder    (CodeConstructor constructor);
 | 
			
		||||
GEN_API void       constructor_to_strbuilder_def(CodeConstructor constructor, StrBuilder* result );
 | 
			
		||||
GEN_API void       constructor_to_strbuilder_fwd(CodeConstructor constructor, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
StrBuilder enum_to_strbuilder          (CodeEnum self);
 | 
			
		||||
void       enum_to_strbuilder_def      (CodeEnum self, StrBuilder* result );
 | 
			
		||||
void       enum_to_strbuilder_fwd      (CodeEnum self, StrBuilder* result );
 | 
			
		||||
void       enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result );
 | 
			
		||||
void       enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result );
 | 
			
		||||
GEN_API StrBuilder define_to_strbuilder    (CodeDefine self);
 | 
			
		||||
GEN_API void       define_to_strbuilder_ref(CodeDefine self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder exec_to_strbuilder    (CodeExec exec);
 | 
			
		||||
void       exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder destructor_to_strbuilder    (CodeDestructor destructor);
 | 
			
		||||
GEN_API void       destructor_to_strbuilder_fwd(CodeDestructor destructor, StrBuilder* result );
 | 
			
		||||
GEN_API void       destructor_to_strbuilder_def(CodeDestructor destructor, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
void extern_to_strbuilder(CodeExtern self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder enum_to_strbuilder          (CodeEnum self);
 | 
			
		||||
GEN_API void       enum_to_strbuilder_def      (CodeEnum self, StrBuilder* result );
 | 
			
		||||
GEN_API void       enum_to_strbuilder_fwd      (CodeEnum self, StrBuilder* result );
 | 
			
		||||
GEN_API void       enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result );
 | 
			
		||||
GEN_API void       enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
StrBuilder include_to_strbuilder    (CodeInclude self);
 | 
			
		||||
void       include_to_strbuilder_ref(CodeInclude self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder exec_to_strbuilder    (CodeExec exec);
 | 
			
		||||
GEN_API void       exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder friend_to_strbuilder     (CodeFriend self);
 | 
			
		||||
void       friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result);
 | 
			
		||||
GEN_API void extern_to_strbuilder(CodeExtern self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder fn_to_strbuilder    (CodeFn self);
 | 
			
		||||
void       fn_to_strbuilder_def(CodeFn self, StrBuilder* result);
 | 
			
		||||
void       fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder include_to_strbuilder    (CodeInclude self);
 | 
			
		||||
GEN_API void       include_to_strbuilder_ref(CodeInclude self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder module_to_strbuilder    (CodeModule self);
 | 
			
		||||
void       module_to_strbuilder_ref(CodeModule self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder friend_to_strbuilder     (CodeFriend self);
 | 
			
		||||
GEN_API void       friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder namespace_to_strbuilder    (CodeNS self);
 | 
			
		||||
void       namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder fn_to_strbuilder    (CodeFn self);
 | 
			
		||||
GEN_API void       fn_to_strbuilder_def(CodeFn self, StrBuilder* result);
 | 
			
		||||
GEN_API void       fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder code_op_to_strbuilder    (CodeOperator self);
 | 
			
		||||
void       code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result );
 | 
			
		||||
void       code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result );
 | 
			
		||||
GEN_API StrBuilder module_to_strbuilder    (CodeModule self);
 | 
			
		||||
GEN_API void       module_to_strbuilder_ref(CodeModule self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder opcast_to_strbuilder     (CodeOpCast op_cast );
 | 
			
		||||
void       opcast_to_strbuilder_def(CodeOpCast op_cast, StrBuilder* result );
 | 
			
		||||
void       opcast_to_strbuilder_fwd(CodeOpCast op_cast, StrBuilder* result );
 | 
			
		||||
GEN_API StrBuilder namespace_to_strbuilder    (CodeNS self);
 | 
			
		||||
GEN_API void       namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder pragma_to_strbuilder    (CodePragma self);
 | 
			
		||||
void       pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder code_op_to_strbuilder    (CodeOperator self);
 | 
			
		||||
GEN_API void       code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result );
 | 
			
		||||
GEN_API void       code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
StrBuilder preprocess_to_strbuilder       (CodePreprocessCond cond);
 | 
			
		||||
void       preprocess_to_strbuilder_if    (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
void       preprocess_to_strbuilder_ifdef (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
void       preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
void       preprocess_to_strbuilder_elif  (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
void       preprocess_to_strbuilder_else  (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
void       preprocess_to_strbuilder_endif (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
GEN_API StrBuilder opcast_to_strbuilder     (CodeOpCast op_cast );
 | 
			
		||||
GEN_API void       opcast_to_strbuilder_def(CodeOpCast op_cast, StrBuilder* result );
 | 
			
		||||
GEN_API void       opcast_to_strbuilder_fwd(CodeOpCast op_cast, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
StrBuilder template_to_strbuilder    (CodeTemplate self);
 | 
			
		||||
void       template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder pragma_to_strbuilder    (CodePragma self);
 | 
			
		||||
GEN_API void       pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder typename_to_strbuilder    (CodeTypename self);
 | 
			
		||||
void       typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder preprocess_to_strbuilder       (CodePreprocessCond cond);
 | 
			
		||||
GEN_API void       preprocess_to_strbuilder_if    (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
GEN_API void       preprocess_to_strbuilder_ifdef (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
GEN_API void       preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
GEN_API void       preprocess_to_strbuilder_elif  (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
GEN_API void       preprocess_to_strbuilder_else  (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
GEN_API void       preprocess_to_strbuilder_endif (CodePreprocessCond cond, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
StrBuilder typedef_to_strbuilder    (CodeTypedef self);
 | 
			
		||||
void       typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result );
 | 
			
		||||
GEN_API StrBuilder template_to_strbuilder    (CodeTemplate self);
 | 
			
		||||
GEN_API void       template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder union_to_strbuilder    (CodeUnion self);
 | 
			
		||||
void       union_to_strbuilder_def(CodeUnion self, StrBuilder* result);
 | 
			
		||||
void       union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder typename_to_strbuilder    (CodeTypename self);
 | 
			
		||||
GEN_API void       typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
StrBuilder using_to_strbuilder    (CodeUsing op_cast );
 | 
			
		||||
void       using_to_strbuilder_ref(CodeUsing op_cast, StrBuilder* result );
 | 
			
		||||
void       using_to_strbuilder_ns (CodeUsing op_cast, StrBuilder* result );
 | 
			
		||||
GEN_API StrBuilder typedef_to_strbuilder    (CodeTypedef self);
 | 
			
		||||
GEN_API void       typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
StrBuilder var_to_strbuilder    (CodeVar self);
 | 
			
		||||
void       var_to_strbuilder_ref(CodeVar self, StrBuilder* result);
 | 
			
		||||
GEN_API StrBuilder union_to_strbuilder    (CodeUnion self);
 | 
			
		||||
GEN_API void       union_to_strbuilder_def(CodeUnion self, StrBuilder* result);
 | 
			
		||||
GEN_API void       union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
GEN_API StrBuilder using_to_strbuilder    (CodeUsing op_cast );
 | 
			
		||||
GEN_API void       using_to_strbuilder_ref(CodeUsing op_cast, StrBuilder* result );
 | 
			
		||||
GEN_API void       using_to_strbuilder_ns (CodeUsing op_cast, StrBuilder* result );
 | 
			
		||||
 | 
			
		||||
GEN_API StrBuilder var_to_strbuilder    (CodeVar self);
 | 
			
		||||
GEN_API void       var_to_strbuilder_ref(CodeVar self, StrBuilder* result);
 | 
			
		||||
 | 
			
		||||
#pragma endregion Code Type C-Interface
 | 
			
		||||
 | 
			
		||||
@@ -192,12 +202,11 @@ struct CodeParams
 | 
			
		||||
{
 | 
			
		||||
#if ! GEN_C_LIKE_CPP
 | 
			
		||||
	Using_Code( CodeParams );
 | 
			
		||||
	forceinline void          append( CodeParams other );
 | 
			
		||||
	forceinline CodeParams    get( s32 idx );
 | 
			
		||||
	forceinline bool          has_entries();
 | 
			
		||||
	forceinline StrBuilder    to_strbuilder();
 | 
			
		||||
	forceinline void          to_strbuilder( StrBuilder& result );
 | 
			
		||||
 | 
			
		||||
	forceinline void          append( CodeParams other )          { return params_append(* this, other); }
 | 
			
		||||
	forceinline CodeParams    get( s32 idx )                      { return params_get( * this, idx); }
 | 
			
		||||
	forceinline bool          has_entries()                       { return params_has_entries(* this); }
 | 
			
		||||
	forceinline StrBuilder    to_strbuilder()                     { return params_to_strbuilder(* this); }
 | 
			
		||||
	forceinline void          to_strbuilder( StrBuilder& result ) { return params_to_strbuilder_ref(*this, & result); }
 | 
			
		||||
#endif
 | 
			
		||||
	Using_CodeOps( CodeParams );
 | 
			
		||||
	forceinline CodeParams begin() { return begin_CodeParams(* this); }
 | 
			
		||||
@@ -212,6 +221,29 @@ struct CodeParams
 | 
			
		||||
	AST_Params* ast;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CodeDefineParams
 | 
			
		||||
{
 | 
			
		||||
#if ! GEN_C_LIKE_CPP
 | 
			
		||||
	Using_Code( CodeDefineParams );
 | 
			
		||||
	forceinline void             append( CodeDefineParams other )    { return params_append( cast(CodeParams, * this), cast(CodeParams, other)); }
 | 
			
		||||
	forceinline CodeDefineParams get( s32 idx )                      { return (CodeDefineParams) (Code) params_get( cast(CodeParams, * this), idx); }
 | 
			
		||||
	forceinline bool             has_entries()                       { return params_has_entries( cast(CodeParams, * this)); }
 | 
			
		||||
	forceinline StrBuilder       to_strbuilder()                     { return define_params_to_strbuilder(* this); }
 | 
			
		||||
	forceinline void             to_strbuilder( StrBuilder& result ) { return define_params_to_strbuilder_ref(* this, & result); }
 | 
			
		||||
#endif
 | 
			
		||||
	Using_CodeOps( CodeDefineParams );
 | 
			
		||||
	forceinline CodeDefineParams begin() { return (CodeDefineParams) (Code) begin_CodeParams( cast(CodeParams, * this)); }
 | 
			
		||||
	forceinline CodeDefineParams end()   { return (CodeDefineParams) (Code) end_CodeParams( cast(CodeParams, * this)); }
 | 
			
		||||
	forceinline operator Code() { return { (AST*)ast }; }
 | 
			
		||||
	forceinline CodeDefineParams  operator *() { return * this; } // Required to support for-range iteration.
 | 
			
		||||
	forceinline AST_DefineParams* operator->() {
 | 
			
		||||
		GEN_ASSERT(ast);
 | 
			
		||||
		return ast;
 | 
			
		||||
	}
 | 
			
		||||
	forceinline CodeDefineParams& operator++();
 | 
			
		||||
	AST_DefineParams* ast;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CodeSpecifiers
 | 
			
		||||
{
 | 
			
		||||
#if ! GEN_C_LIKE_CPP
 | 
			
		||||
@@ -941,6 +973,7 @@ struct InvalidCode_ImplictCaster
 | 
			
		||||
    operator CodeClass         () const { return cast(CodeClass,          Code_Invalid); }
 | 
			
		||||
    operator CodeConstructor   () const { return cast(CodeConstructor,    Code_Invalid); }
 | 
			
		||||
    operator CodeDefine        () const { return cast(CodeDefine,         Code_Invalid); }
 | 
			
		||||
    operator CodeDefineParams  () const { return cast(CodeDefineParams,   Code_Invalid); }
 | 
			
		||||
    operator CodeDestructor    () const { return cast(CodeDestructor,     Code_Invalid); }
 | 
			
		||||
    operator CodeExec          () const { return cast(CodeExec,           Code_Invalid); }
 | 
			
		||||
    operator CodeEnum          () const { return cast(CodeEnum,           Code_Invalid); }
 | 
			
		||||
@@ -974,6 +1007,7 @@ struct NullCode_ImplicitCaster
 | 
			
		||||
    operator CodeClass         () const { return {nullptr}; }
 | 
			
		||||
    operator CodeConstructor   () const { return {nullptr}; }
 | 
			
		||||
    operator CodeDefine        () const { return {nullptr}; }
 | 
			
		||||
    operator CodeDefineParams  () const { return {nullptr}; }
 | 
			
		||||
    operator CodeDestructor    () const { return {nullptr}; }
 | 
			
		||||
    operator CodeExec          () const { return {nullptr}; }
 | 
			
		||||
    operator CodeEnum          () const { return {nullptr}; }
 | 
			
		||||
@@ -1024,17 +1058,23 @@ forceinline StrBuilder to_strbuilder    ( CodeClass self )
 | 
			
		||||
forceinline void       to_strbuilder_def( CodeClass self, StrBuilder& result )     { return class_to_strbuilder_def(self, & result); }
 | 
			
		||||
forceinline void       to_strbuilder_fwd( CodeClass self, StrBuilder& result )     { return class_to_strbuilder_fwd(self, & result); }
 | 
			
		||||
 | 
			
		||||
forceinline void       append       (CodeParams params, CodeParams param )   { return params_append(params, param); }
 | 
			
		||||
forceinline CodeParams get          (CodeParams params, s32 idx)             { return params_get(params, idx); }
 | 
			
		||||
forceinline bool       has_entries  (CodeParams params )                     { return params_has_entries(params); }
 | 
			
		||||
forceinline StrBuilder to_strbuilder(CodeParams params )                     { return params_to_strbuilder(params); }
 | 
			
		||||
forceinline void       to_strbuilder(CodeParams params, StrBuilder& result ) { return params_to_strbuilder_ref(params, & result); }
 | 
			
		||||
forceinline void             append       (CodeDefineParams appendee, CodeDefineParams other ) {        params_append(cast(CodeParams, appendee), cast(CodeParams, other)); }
 | 
			
		||||
forceinline CodeDefineParams get          (CodeDefineParams params, s32 idx)                   { return (CodeDefineParams) (Code) params_get(cast(CodeParams, params), idx); }
 | 
			
		||||
forceinline bool             has_entries  (CodeDefineParams params )                           { return params_has_entries(cast(CodeParams, params)); }
 | 
			
		||||
forceinline StrBuilder       to_strbuilder(CodeDefineParams params )                           { return define_params_to_strbuilder(params); }
 | 
			
		||||
forceinline void             to_strbuilder(CodeDefineParams params, StrBuilder& result )       { return define_params_to_strbuilder_ref(params, & result); }
 | 
			
		||||
 | 
			
		||||
forceinline void       append       (CodeParams appendee, CodeParams other )   { return params_append(appendee, other); }
 | 
			
		||||
forceinline CodeParams get          (CodeParams params, s32 idx)               { return params_get(params, idx); }
 | 
			
		||||
forceinline bool       has_entries  (CodeParams params )                       { return params_has_entries(params); }
 | 
			
		||||
forceinline StrBuilder to_strbuilder(CodeParams params )                       { return params_to_strbuilder(params); }
 | 
			
		||||
forceinline void       to_strbuilder(CodeParams params, StrBuilder& result )   { return params_to_strbuilder_ref(params, & result); }
 | 
			
		||||
  
 | 
			
		||||
forceinline bool       append       (CodeSpecifiers specifiers, Specifier spec)       { return specifiers_append(specifiers, spec); }
 | 
			
		||||
forceinline s32        has          (CodeSpecifiers specifiers, Specifier spec)       { return specifiers_has(specifiers, spec); }
 | 
			
		||||
forceinline s32        remove       (CodeSpecifiers specifiers, Specifier to_remove ) { return specifiers_remove(specifiers, to_remove); }
 | 
			
		||||
forceinline StrBuilder to_strbuilder(CodeSpecifiers specifiers)                       { return specifiers_to_strbuilder(specifiers); }
 | 
			
		||||
forceinline void       to_strbuilder(CodeSpecifiers specifiers, StrBuilder& result)       { return specifiers_to_strbuilder_ref(specifiers, & result);  }
 | 
			
		||||
forceinline void       to_strbuilder(CodeSpecifiers specifiers, StrBuilder& result)   { return specifiers_to_strbuilder_ref(specifiers, & result);  }
 | 
			
		||||
 | 
			
		||||
forceinline void       add_interface    (CodeStruct self, CodeTypename interface) { return struct_add_interface(self, interface); }
 | 
			
		||||
forceinline StrBuilder to_strbuilder    (CodeStruct self)                         { return struct_to_strbuilder(self); }
 | 
			
		||||
 
 | 
			
		||||
@@ -179,6 +179,22 @@ inline AST_Define* CodeDefine::operator->()
 | 
			
		||||
	return ast;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline CodeDefineParams& CodeDefineParams::operator=( Code other )
 | 
			
		||||
{
 | 
			
		||||
	if ( other.ast != nullptr && other->Parent != nullptr )
 | 
			
		||||
	{
 | 
			
		||||
		ast         = rcast( decltype( ast ), code_duplicate( other ).ast );
 | 
			
		||||
		ast->Parent = { nullptr };
 | 
			
		||||
	}
 | 
			
		||||
	ast = rcast( decltype( ast ), other.ast );
 | 
			
		||||
	return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline CodeDefineParams::operator bool()
 | 
			
		||||
{
 | 
			
		||||
	return ast != nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline CodeDestructor& CodeDestructor::operator=( Code other )
 | 
			
		||||
{
 | 
			
		||||
	if ( other.ast != nullptr && other->Parent != nullptr )
 | 
			
		||||
@@ -851,6 +867,11 @@ forceinline Code::operator CodeDefine() const
 | 
			
		||||
	return { (AST_Define*)ast };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline Code::operator CodeDefineParams() const
 | 
			
		||||
{
 | 
			
		||||
	return { (AST_DefineParams*)ast };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline Code::operator CodeDestructor() const
 | 
			
		||||
{
 | 
			
		||||
	return { (AST_Destructor*)ast };
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,7 @@ enum CodeType : u32
 | 
			
		||||
	CT_Operator_Cast,
 | 
			
		||||
	CT_Operator_Cast_Fwd,
 | 
			
		||||
	CT_Parameters,
 | 
			
		||||
	CT_Parameters_Define,
 | 
			
		||||
	CT_Preprocess_Define,
 | 
			
		||||
	CT_Preprocess_Include,
 | 
			
		||||
	CT_Preprocess_If,
 | 
			
		||||
@@ -74,7 +75,7 @@ enum CodeType : u32
 | 
			
		||||
 | 
			
		||||
inline Str codetype_to_str( CodeType type )
 | 
			
		||||
{
 | 
			
		||||
	local_persist Str lookup[61] = {
 | 
			
		||||
	local_persist Str lookup[] = {
 | 
			
		||||
		{ "Invalid",             sizeof( "Invalid" ) - 1             },
 | 
			
		||||
		{ "Untyped",             sizeof( "Untyped" ) - 1             },
 | 
			
		||||
		{ "NewLine",             sizeof( "NewLine" ) - 1             },
 | 
			
		||||
@@ -114,6 +115,7 @@ inline Str codetype_to_str( CodeType type )
 | 
			
		||||
		{ "Operator_Cast",       sizeof( "Operator_Cast" ) - 1       },
 | 
			
		||||
		{ "Operator_Cast_Fwd",   sizeof( "Operator_Cast_Fwd" ) - 1   },
 | 
			
		||||
		{ "Parameters",          sizeof( "Parameters" ) - 1          },
 | 
			
		||||
		{ "Parameters_Define",   sizeof( "Parameters_Define" ) - 1   },
 | 
			
		||||
		{ "Preprocess_Define",   sizeof( "Preprocess_Define" ) - 1   },
 | 
			
		||||
		{ "Preprocess_Include",  sizeof( "Preprocess_Include" ) - 1  },
 | 
			
		||||
		{ "Preprocess_If",       sizeof( "Preprocess_If" ) - 1       },
 | 
			
		||||
@@ -142,7 +144,7 @@ inline Str codetype_to_str( CodeType type )
 | 
			
		||||
 | 
			
		||||
inline Str codetype_to_keyword_str( CodeType type )
 | 
			
		||||
{
 | 
			
		||||
	local_persist Str lookup[61] = {
 | 
			
		||||
	local_persist Str lookup[] = {
 | 
			
		||||
		{ "__NA__",          sizeof( "__NA__" ) - 1          },
 | 
			
		||||
		{ "__NA__",          sizeof( "__NA__" ) - 1          },
 | 
			
		||||
		{ "__NA__",          sizeof( "__NA__" ) - 1          },
 | 
			
		||||
@@ -182,6 +184,7 @@ inline Str codetype_to_keyword_str( CodeType type )
 | 
			
		||||
		{ "operator",        sizeof( "operator" ) - 1        },
 | 
			
		||||
		{ "operator",        sizeof( "operator" ) - 1        },
 | 
			
		||||
		{ "__NA__",          sizeof( "__NA__" ) - 1          },
 | 
			
		||||
		{ "__NA__",          sizeof( "__NA__" ) - 1          },
 | 
			
		||||
		{ "define",          sizeof( "define" ) - 1          },
 | 
			
		||||
		{ "include",         sizeof( "include" ) - 1         },
 | 
			
		||||
		{ "if",              sizeof( "if" ) - 1              },
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@ enum Operator : u32
 | 
			
		||||
 | 
			
		||||
inline Str operator_to_str( Operator op )
 | 
			
		||||
{
 | 
			
		||||
	local_persist Str lookup[47] = {
 | 
			
		||||
	local_persist Str lookup[] = {
 | 
			
		||||
		{ "INVALID",  sizeof( "INVALID" ) - 1  },
 | 
			
		||||
		{ "=",        sizeof( "=" ) - 1        },
 | 
			
		||||
		{ "+=",       sizeof( "+=" ) - 1       },
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ enum Specifier : u32
 | 
			
		||||
 | 
			
		||||
inline Str spec_to_str( Specifier type )
 | 
			
		||||
{
 | 
			
		||||
	local_persist Str lookup[26] = {
 | 
			
		||||
	local_persist Str lookup[] = {
 | 
			
		||||
		{ "INVALID",       sizeof( "INVALID" ) - 1       },
 | 
			
		||||
		{ "consteval",     sizeof( "consteval" ) - 1     },
 | 
			
		||||
		{ "constexpr",     sizeof( "constexpr" ) - 1     },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,235 +0,0 @@
 | 
			
		||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "components/types.hpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
 | 
			
		||||
 | 
			
		||||
GEN_NS_PARSER_BEGIN
 | 
			
		||||
 | 
			
		||||
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Tok_Attribute_API_Import, "GEN_API_Import_Code" )
 | 
			
		||||
 | 
			
		||||
enum TokType : u32
 | 
			
		||||
{
 | 
			
		||||
	Tok_Invalid,
 | 
			
		||||
	Tok_Access_Private,
 | 
			
		||||
	Tok_Access_Protected,
 | 
			
		||||
	Tok_Access_Public,
 | 
			
		||||
	Tok_Access_MemberSymbol,
 | 
			
		||||
	Tok_Access_StaticSymbol,
 | 
			
		||||
	Tok_Ampersand,
 | 
			
		||||
	Tok_Ampersand_DBL,
 | 
			
		||||
	Tok_Assign_Classifer,
 | 
			
		||||
	Tok_Attribute_Open,
 | 
			
		||||
	Tok_Attribute_Close,
 | 
			
		||||
	Tok_BraceCurly_Open,
 | 
			
		||||
	Tok_BraceCurly_Close,
 | 
			
		||||
	Tok_BraceSquare_Open,
 | 
			
		||||
	Tok_BraceSquare_Close,
 | 
			
		||||
	Tok_Capture_Start,
 | 
			
		||||
	Tok_Capture_End,
 | 
			
		||||
	Tok_Comment,
 | 
			
		||||
	Tok_Comment_End,
 | 
			
		||||
	Tok_Comment_Start,
 | 
			
		||||
	Tok_Char,
 | 
			
		||||
	Tok_Comma,
 | 
			
		||||
	Tok_Decl_Class,
 | 
			
		||||
	Tok_Decl_GNU_Attribute,
 | 
			
		||||
	Tok_Decl_MSVC_Attribute,
 | 
			
		||||
	Tok_Decl_Enum,
 | 
			
		||||
	Tok_Decl_Extern_Linkage,
 | 
			
		||||
	Tok_Decl_Friend,
 | 
			
		||||
	Tok_Decl_Module,
 | 
			
		||||
	Tok_Decl_Namespace,
 | 
			
		||||
	Tok_Decl_Operator,
 | 
			
		||||
	Tok_Decl_Struct,
 | 
			
		||||
	Tok_Decl_Template,
 | 
			
		||||
	Tok_Decl_Typedef,
 | 
			
		||||
	Tok_Decl_Using,
 | 
			
		||||
	Tok_Decl_Union,
 | 
			
		||||
	Tok_Identifier,
 | 
			
		||||
	Tok_Module_Import,
 | 
			
		||||
	Tok_Module_Export,
 | 
			
		||||
	Tok_NewLine,
 | 
			
		||||
	Tok_Number,
 | 
			
		||||
	Tok_Operator,
 | 
			
		||||
	Tok_Preprocess_Hash,
 | 
			
		||||
	Tok_Preprocess_Define,
 | 
			
		||||
	Tok_Preprocess_If,
 | 
			
		||||
	Tok_Preprocess_IfDef,
 | 
			
		||||
	Tok_Preprocess_IfNotDef,
 | 
			
		||||
	Tok_Preprocess_ElIf,
 | 
			
		||||
	Tok_Preprocess_Else,
 | 
			
		||||
	Tok_Preprocess_EndIf,
 | 
			
		||||
	Tok_Preprocess_Include,
 | 
			
		||||
	Tok_Preprocess_Pragma,
 | 
			
		||||
	Tok_Preprocess_Content,
 | 
			
		||||
	Tok_Preprocess_Macro,
 | 
			
		||||
	Tok_Preprocess_Unsupported,
 | 
			
		||||
	Tok_Spec_Alignas,
 | 
			
		||||
	Tok_Spec_Const,
 | 
			
		||||
	Tok_Spec_Consteval,
 | 
			
		||||
	Tok_Spec_Constexpr,
 | 
			
		||||
	Tok_Spec_Constinit,
 | 
			
		||||
	Tok_Spec_Explicit,
 | 
			
		||||
	Tok_Spec_Extern,
 | 
			
		||||
	Tok_Spec_Final,
 | 
			
		||||
	Tok_Spec_ForceInline,
 | 
			
		||||
	Tok_Spec_Global,
 | 
			
		||||
	Tok_Spec_Inline,
 | 
			
		||||
	Tok_Spec_Internal_Linkage,
 | 
			
		||||
	Tok_Spec_LocalPersist,
 | 
			
		||||
	Tok_Spec_Mutable,
 | 
			
		||||
	Tok_Spec_NeverInline,
 | 
			
		||||
	Tok_Spec_Override,
 | 
			
		||||
	Tok_Spec_Static,
 | 
			
		||||
	Tok_Spec_ThreadLocal,
 | 
			
		||||
	Tok_Spec_Volatile,
 | 
			
		||||
	Tok_Spec_Virtual,
 | 
			
		||||
	Tok_Star,
 | 
			
		||||
	Tok_Statement_End,
 | 
			
		||||
	Tok_StaticAssert,
 | 
			
		||||
	Tok_String,
 | 
			
		||||
	Tok_Type_Typename,
 | 
			
		||||
	Tok_Type_Unsigned,
 | 
			
		||||
	Tok_Type_Signed,
 | 
			
		||||
	Tok_Type_Short,
 | 
			
		||||
	Tok_Type_Long,
 | 
			
		||||
	Tok_Type_bool,
 | 
			
		||||
	Tok_Type_char,
 | 
			
		||||
	Tok_Type_int,
 | 
			
		||||
	Tok_Type_double,
 | 
			
		||||
	Tok_Type_MS_int8,
 | 
			
		||||
	Tok_Type_MS_int16,
 | 
			
		||||
	Tok_Type_MS_int32,
 | 
			
		||||
	Tok_Type_MS_int64,
 | 
			
		||||
	Tok_Type_MS_W64,
 | 
			
		||||
	Tok_Varadic_Argument,
 | 
			
		||||
	Tok___Attributes_Start,
 | 
			
		||||
	Tok_Attribute_API_Export,
 | 
			
		||||
	Tok_Attribute_API_Import,
 | 
			
		||||
	Tok_NumTokens
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline Str toktype_to_str( TokType type )
 | 
			
		||||
{
 | 
			
		||||
	local_persist Str lookup[] = {
 | 
			
		||||
		{ "__invalid__",         sizeof( "__invalid__" ) - 1         },
 | 
			
		||||
		{ "private",             sizeof( "private" ) - 1             },
 | 
			
		||||
		{ "protected",           sizeof( "protected" ) - 1           },
 | 
			
		||||
		{ "public",              sizeof( "public" ) - 1              },
 | 
			
		||||
		{ ".",		           sizeof( "." ) - 1                   },
 | 
			
		||||
		{ "::",		          sizeof( "::" ) - 1                  },
 | 
			
		||||
		{ "&",		           sizeof( "&" ) - 1                   },
 | 
			
		||||
		{ "&&",		          sizeof( "&&" ) - 1                  },
 | 
			
		||||
		{ ":",		           sizeof( ":" ) - 1                   },
 | 
			
		||||
		{ "[[",		          sizeof( "[[" ) - 1                  },
 | 
			
		||||
		{ "]]",		          sizeof( "]]" ) - 1                  },
 | 
			
		||||
		{ "{",		           sizeof( "{" ) - 1                   },
 | 
			
		||||
		{ "}",		           sizeof( "}" ) - 1                   },
 | 
			
		||||
		{ "[",		           sizeof( "[" ) - 1                   },
 | 
			
		||||
		{ "]",		           sizeof( "]" ) - 1                   },
 | 
			
		||||
		{ "(",		           sizeof( "(" ) - 1                   },
 | 
			
		||||
		{ ")",		           sizeof( ")" ) - 1                   },
 | 
			
		||||
		{ "__comment__",         sizeof( "__comment__" ) - 1         },
 | 
			
		||||
		{ "__comment_end__",     sizeof( "__comment_end__" ) - 1     },
 | 
			
		||||
		{ "__comment_start__",   sizeof( "__comment_start__" ) - 1   },
 | 
			
		||||
		{ "__character__",       sizeof( "__character__" ) - 1       },
 | 
			
		||||
		{ ",",		           sizeof( "," ) - 1                   },
 | 
			
		||||
		{ "class",               sizeof( "class" ) - 1               },
 | 
			
		||||
		{ "__attribute__",       sizeof( "__attribute__" ) - 1       },
 | 
			
		||||
		{ "__declspec",          sizeof( "__declspec" ) - 1          },
 | 
			
		||||
		{ "enum",                sizeof( "enum" ) - 1                },
 | 
			
		||||
		{ "extern",              sizeof( "extern" ) - 1              },
 | 
			
		||||
		{ "friend",              sizeof( "friend" ) - 1              },
 | 
			
		||||
		{ "module",              sizeof( "module" ) - 1              },
 | 
			
		||||
		{ "namespace",           sizeof( "namespace" ) - 1           },
 | 
			
		||||
		{ "operator",            sizeof( "operator" ) - 1            },
 | 
			
		||||
		{ "struct",              sizeof( "struct" ) - 1              },
 | 
			
		||||
		{ "template",            sizeof( "template" ) - 1            },
 | 
			
		||||
		{ "typedef",             sizeof( "typedef" ) - 1             },
 | 
			
		||||
		{ "using",               sizeof( "using" ) - 1               },
 | 
			
		||||
		{ "union",               sizeof( "union" ) - 1               },
 | 
			
		||||
		{ "__identifier__",      sizeof( "__identifier__" ) - 1      },
 | 
			
		||||
		{ "import",              sizeof( "import" ) - 1              },
 | 
			
		||||
		{ "export",              sizeof( "export" ) - 1              },
 | 
			
		||||
		{ "__new_line__",        sizeof( "__new_line__" ) - 1        },
 | 
			
		||||
		{ "__number__",          sizeof( "__number__" ) - 1          },
 | 
			
		||||
		{ "__operator__",        sizeof( "__operator__" ) - 1        },
 | 
			
		||||
		{ "#",		           sizeof( "#" ) - 1                   },
 | 
			
		||||
		{ "define",              sizeof( "define" ) - 1              },
 | 
			
		||||
		{ "if",		          sizeof( "if" ) - 1                  },
 | 
			
		||||
		{ "ifdef",               sizeof( "ifdef" ) - 1               },
 | 
			
		||||
		{ "ifndef",              sizeof( "ifndef" ) - 1              },
 | 
			
		||||
		{ "elif",                sizeof( "elif" ) - 1                },
 | 
			
		||||
		{ "else",                sizeof( "else" ) - 1                },
 | 
			
		||||
		{ "endif",               sizeof( "endif" ) - 1               },
 | 
			
		||||
		{ "include",             sizeof( "include" ) - 1             },
 | 
			
		||||
		{ "pragma",              sizeof( "pragma" ) - 1              },
 | 
			
		||||
		{ "__macro_content__",   sizeof( "__macro_content__" ) - 1   },
 | 
			
		||||
		{ "__macro__",           sizeof( "__macro__" ) - 1           },
 | 
			
		||||
		{ "__unsupported__",     sizeof( "__unsupported__" ) - 1     },
 | 
			
		||||
		{ "alignas",             sizeof( "alignas" ) - 1             },
 | 
			
		||||
		{ "const",               sizeof( "const" ) - 1               },
 | 
			
		||||
		{ "consteval",           sizeof( "consteval" ) - 1           },
 | 
			
		||||
		{ "constexpr",           sizeof( "constexpr" ) - 1           },
 | 
			
		||||
		{ "constinit",           sizeof( "constinit" ) - 1           },
 | 
			
		||||
		{ "explicit",            sizeof( "explicit" ) - 1            },
 | 
			
		||||
		{ "extern",              sizeof( "extern" ) - 1              },
 | 
			
		||||
		{ "final",               sizeof( "final" ) - 1               },
 | 
			
		||||
		{ "forceinline",         sizeof( "forceinline" ) - 1         },
 | 
			
		||||
		{ "global",              sizeof( "global" ) - 1              },
 | 
			
		||||
		{ "inline",              sizeof( "inline" ) - 1              },
 | 
			
		||||
		{ "internal",            sizeof( "internal" ) - 1            },
 | 
			
		||||
		{ "local_persist",       sizeof( "local_persist" ) - 1       },
 | 
			
		||||
		{ "mutable",             sizeof( "mutable" ) - 1             },
 | 
			
		||||
		{ "neverinline",         sizeof( "neverinline" ) - 1         },
 | 
			
		||||
		{ "override",            sizeof( "override" ) - 1            },
 | 
			
		||||
		{ "static",              sizeof( "static" ) - 1              },
 | 
			
		||||
		{ "thread_local",        sizeof( "thread_local" ) - 1        },
 | 
			
		||||
		{ "volatile",            sizeof( "volatile" ) - 1            },
 | 
			
		||||
		{ "virtual",             sizeof( "virtual" ) - 1             },
 | 
			
		||||
		{ "*",		           sizeof( "*" ) - 1                   },
 | 
			
		||||
		{ ";",		           sizeof( ";" ) - 1                   },
 | 
			
		||||
		{ "static_assert",       sizeof( "static_assert" ) - 1       },
 | 
			
		||||
		{ "__string__",          sizeof( "__string__" ) - 1          },
 | 
			
		||||
		{ "typename",            sizeof( "typename" ) - 1            },
 | 
			
		||||
		{ "unsigned",            sizeof( "unsigned" ) - 1            },
 | 
			
		||||
		{ "signed",              sizeof( "signed" ) - 1              },
 | 
			
		||||
		{ "short",               sizeof( "short" ) - 1               },
 | 
			
		||||
		{ "long",                sizeof( "long" ) - 1                },
 | 
			
		||||
		{ "bool",                sizeof( "bool" ) - 1                },
 | 
			
		||||
		{ "char",                sizeof( "char" ) - 1                },
 | 
			
		||||
		{ "int",		         sizeof( "int" ) - 1                 },
 | 
			
		||||
		{ "double",              sizeof( "double" ) - 1              },
 | 
			
		||||
		{ "__int8",              sizeof( "__int8" ) - 1              },
 | 
			
		||||
		{ "__int16",             sizeof( "__int16" ) - 1             },
 | 
			
		||||
		{ "__int32",             sizeof( "__int32" ) - 1             },
 | 
			
		||||
		{ "__int64",             sizeof( "__int64" ) - 1             },
 | 
			
		||||
		{ "_W64",                sizeof( "_W64" ) - 1                },
 | 
			
		||||
		{ "...",		         sizeof( "..." ) - 1                 },
 | 
			
		||||
		{ "__attrib_start__",    sizeof( "__attrib_start__" ) - 1    },
 | 
			
		||||
		{ "GEN_API_Export_Code", sizeof( "GEN_API_Export_Code" ) - 1 },
 | 
			
		||||
		{ "GEN_API_Import_Code", sizeof( "GEN_API_Import_Code" ) - 1 },
 | 
			
		||||
	};
 | 
			
		||||
	return lookup[type];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline TokType str_to_toktype( Str str )
 | 
			
		||||
{
 | 
			
		||||
	local_persist u32 keymap[Tok_NumTokens];
 | 
			
		||||
	do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ )
 | 
			
		||||
	{
 | 
			
		||||
		Str enum_str  = toktype_to_str( (TokType)index );
 | 
			
		||||
		keymap[index] = crc32( enum_str.Ptr, enum_str.Len );
 | 
			
		||||
	}
 | 
			
		||||
	do_once_end u32 hash = crc32( str.Ptr, str.Len );
 | 
			
		||||
	for ( u32 index = 0; index < Tok_NumTokens; index++ )
 | 
			
		||||
	{
 | 
			
		||||
		if ( keymap[index] == hash )
 | 
			
		||||
			return (TokType)index;
 | 
			
		||||
	}
 | 
			
		||||
	return Tok_Invalid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GEN_NS_PARSER_END
 | 
			
		||||
							
								
								
									
										235
									
								
								base/components/gen/etoktype.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								base/components/gen/etoktype.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,235 @@
 | 
			
		||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "components/types.hpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
 | 
			
		||||
 | 
			
		||||
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_GEN_API, "GEN_API" )
 | 
			
		||||
 | 
			
		||||
enum TokType : u32
 | 
			
		||||
{
 | 
			
		||||
	Tok_Invalid,
 | 
			
		||||
	Tok_Access_Private,
 | 
			
		||||
	Tok_Access_Protected,
 | 
			
		||||
	Tok_Access_Public,
 | 
			
		||||
	Tok_Access_MemberSymbol,
 | 
			
		||||
	Tok_Access_StaticSymbol,
 | 
			
		||||
	Tok_Ampersand,
 | 
			
		||||
	Tok_Ampersand_DBL,
 | 
			
		||||
	Tok_Assign_Classifer,
 | 
			
		||||
	Tok_Attribute_Open,
 | 
			
		||||
	Tok_Attribute_Close,
 | 
			
		||||
	Tok_BraceCurly_Open,
 | 
			
		||||
	Tok_BraceCurly_Close,
 | 
			
		||||
	Tok_BraceSquare_Open,
 | 
			
		||||
	Tok_BraceSquare_Close,
 | 
			
		||||
	Tok_Paren_Open,
 | 
			
		||||
	Tok_Paren_Close,
 | 
			
		||||
	Tok_Comment,
 | 
			
		||||
	Tok_Comment_End,
 | 
			
		||||
	Tok_Comment_Start,
 | 
			
		||||
	Tok_Char,
 | 
			
		||||
	Tok_Comma,
 | 
			
		||||
	Tok_Decl_Class,
 | 
			
		||||
	Tok_Decl_GNU_Attribute,
 | 
			
		||||
	Tok_Decl_MSVC_Attribute,
 | 
			
		||||
	Tok_Decl_Enum,
 | 
			
		||||
	Tok_Decl_Extern_Linkage,
 | 
			
		||||
	Tok_Decl_Friend,
 | 
			
		||||
	Tok_Decl_Module,
 | 
			
		||||
	Tok_Decl_Namespace,
 | 
			
		||||
	Tok_Decl_Operator,
 | 
			
		||||
	Tok_Decl_Struct,
 | 
			
		||||
	Tok_Decl_Template,
 | 
			
		||||
	Tok_Decl_Typedef,
 | 
			
		||||
	Tok_Decl_Using,
 | 
			
		||||
	Tok_Decl_Union,
 | 
			
		||||
	Tok_Identifier,
 | 
			
		||||
	Tok_Module_Import,
 | 
			
		||||
	Tok_Module_Export,
 | 
			
		||||
	Tok_NewLine,
 | 
			
		||||
	Tok_Number,
 | 
			
		||||
	Tok_Operator,
 | 
			
		||||
	Tok_Preprocess_Hash,
 | 
			
		||||
	Tok_Preprocess_Define,
 | 
			
		||||
	Tok_Preprocess_Define_Param,
 | 
			
		||||
	Tok_Preprocess_If,
 | 
			
		||||
	Tok_Preprocess_IfDef,
 | 
			
		||||
	Tok_Preprocess_IfNotDef,
 | 
			
		||||
	Tok_Preprocess_ElIf,
 | 
			
		||||
	Tok_Preprocess_Else,
 | 
			
		||||
	Tok_Preprocess_EndIf,
 | 
			
		||||
	Tok_Preprocess_Include,
 | 
			
		||||
	Tok_Preprocess_Pragma,
 | 
			
		||||
	Tok_Preprocess_Content,
 | 
			
		||||
	Tok_Preprocess_Macro_Expr,
 | 
			
		||||
	Tok_Preprocess_Macro_Stmt,
 | 
			
		||||
	Tok_Preprocess_Macro_Typename,
 | 
			
		||||
	Tok_Preprocess_Unsupported,
 | 
			
		||||
	Tok_Spec_Alignas,
 | 
			
		||||
	Tok_Spec_Const,
 | 
			
		||||
	Tok_Spec_Consteval,
 | 
			
		||||
	Tok_Spec_Constexpr,
 | 
			
		||||
	Tok_Spec_Constinit,
 | 
			
		||||
	Tok_Spec_Explicit,
 | 
			
		||||
	Tok_Spec_Extern,
 | 
			
		||||
	Tok_Spec_Final,
 | 
			
		||||
	Tok_Spec_ForceInline,
 | 
			
		||||
	Tok_Spec_Global,
 | 
			
		||||
	Tok_Spec_Inline,
 | 
			
		||||
	Tok_Spec_Internal_Linkage,
 | 
			
		||||
	Tok_Spec_LocalPersist,
 | 
			
		||||
	Tok_Spec_Mutable,
 | 
			
		||||
	Tok_Spec_NeverInline,
 | 
			
		||||
	Tok_Spec_Override,
 | 
			
		||||
	Tok_Spec_Static,
 | 
			
		||||
	Tok_Spec_ThreadLocal,
 | 
			
		||||
	Tok_Spec_Volatile,
 | 
			
		||||
	Tok_Spec_Virtual,
 | 
			
		||||
	Tok_Star,
 | 
			
		||||
	Tok_Statement_End,
 | 
			
		||||
	Tok_StaticAssert,
 | 
			
		||||
	Tok_String,
 | 
			
		||||
	Tok_Type_Typename,
 | 
			
		||||
	Tok_Type_Unsigned,
 | 
			
		||||
	Tok_Type_Signed,
 | 
			
		||||
	Tok_Type_Short,
 | 
			
		||||
	Tok_Type_Long,
 | 
			
		||||
	Tok_Type_bool,
 | 
			
		||||
	Tok_Type_char,
 | 
			
		||||
	Tok_Type_int,
 | 
			
		||||
	Tok_Type_double,
 | 
			
		||||
	Tok_Type_MS_int8,
 | 
			
		||||
	Tok_Type_MS_int16,
 | 
			
		||||
	Tok_Type_MS_int32,
 | 
			
		||||
	Tok_Type_MS_int64,
 | 
			
		||||
	Tok_Type_MS_W64,
 | 
			
		||||
	Tok_Varadic_Argument,
 | 
			
		||||
	Tok___Attributes_Start,
 | 
			
		||||
	Tok_Attribute_GEN_API,
 | 
			
		||||
	Tok_NumTokens
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline Str toktype_to_str( TokType type )
 | 
			
		||||
{
 | 
			
		||||
	local_persist Str lookup[] = {
 | 
			
		||||
		{ "__invalid__",          sizeof( "__invalid__" ) - 1          },
 | 
			
		||||
		{ "private",              sizeof( "private" ) - 1              },
 | 
			
		||||
		{ "protected",            sizeof( "protected" ) - 1            },
 | 
			
		||||
		{ "public",               sizeof( "public" ) - 1               },
 | 
			
		||||
		{ ".",		            sizeof( "." ) - 1                    },
 | 
			
		||||
		{ "::",		           sizeof( "::" ) - 1                   },
 | 
			
		||||
		{ "&",		            sizeof( "&" ) - 1                    },
 | 
			
		||||
		{ "&&",		           sizeof( "&&" ) - 1                   },
 | 
			
		||||
		{ ":",		            sizeof( ":" ) - 1                    },
 | 
			
		||||
		{ "[[",		           sizeof( "[[" ) - 1                   },
 | 
			
		||||
		{ "]]",		           sizeof( "]]" ) - 1                   },
 | 
			
		||||
		{ "{",		            sizeof( "{" ) - 1                    },
 | 
			
		||||
		{ "}",		            sizeof( "}" ) - 1                    },
 | 
			
		||||
		{ "[",		            sizeof( "[" ) - 1                    },
 | 
			
		||||
		{ "]",		            sizeof( "]" ) - 1                    },
 | 
			
		||||
		{ "(",		            sizeof( "(" ) - 1                    },
 | 
			
		||||
		{ ")",		            sizeof( ")" ) - 1                    },
 | 
			
		||||
		{ "__comment__",          sizeof( "__comment__" ) - 1          },
 | 
			
		||||
		{ "__comment_end__",      sizeof( "__comment_end__" ) - 1      },
 | 
			
		||||
		{ "__comment_start__",    sizeof( "__comment_start__" ) - 1    },
 | 
			
		||||
		{ "__character__",        sizeof( "__character__" ) - 1        },
 | 
			
		||||
		{ ",",		            sizeof( "," ) - 1                    },
 | 
			
		||||
		{ "class",                sizeof( "class" ) - 1                },
 | 
			
		||||
		{ "__attribute__",        sizeof( "__attribute__" ) - 1        },
 | 
			
		||||
		{ "__declspec",           sizeof( "__declspec" ) - 1           },
 | 
			
		||||
		{ "enum",                 sizeof( "enum" ) - 1                 },
 | 
			
		||||
		{ "extern",               sizeof( "extern" ) - 1               },
 | 
			
		||||
		{ "friend",               sizeof( "friend" ) - 1               },
 | 
			
		||||
		{ "module",               sizeof( "module" ) - 1               },
 | 
			
		||||
		{ "namespace",            sizeof( "namespace" ) - 1            },
 | 
			
		||||
		{ "operator",             sizeof( "operator" ) - 1             },
 | 
			
		||||
		{ "struct",               sizeof( "struct" ) - 1               },
 | 
			
		||||
		{ "template",             sizeof( "template" ) - 1             },
 | 
			
		||||
		{ "typedef",              sizeof( "typedef" ) - 1              },
 | 
			
		||||
		{ "using",                sizeof( "using" ) - 1                },
 | 
			
		||||
		{ "union",                sizeof( "union" ) - 1                },
 | 
			
		||||
		{ "__identifier__",       sizeof( "__identifier__" ) - 1       },
 | 
			
		||||
		{ "import",               sizeof( "import" ) - 1               },
 | 
			
		||||
		{ "export",               sizeof( "export" ) - 1               },
 | 
			
		||||
		{ "__new_line__",         sizeof( "__new_line__" ) - 1         },
 | 
			
		||||
		{ "__number__",           sizeof( "__number__" ) - 1           },
 | 
			
		||||
		{ "__operator__",         sizeof( "__operator__" ) - 1         },
 | 
			
		||||
		{ "#",		            sizeof( "#" ) - 1                    },
 | 
			
		||||
		{ "define",               sizeof( "define" ) - 1               },
 | 
			
		||||
		{ "__define_param__",     sizeof( "__define_param__" ) - 1     },
 | 
			
		||||
		{ "if",		           sizeof( "if" ) - 1                   },
 | 
			
		||||
		{ "ifdef",                sizeof( "ifdef" ) - 1                },
 | 
			
		||||
		{ "ifndef",               sizeof( "ifndef" ) - 1               },
 | 
			
		||||
		{ "elif",                 sizeof( "elif" ) - 1                 },
 | 
			
		||||
		{ "else",                 sizeof( "else" ) - 1                 },
 | 
			
		||||
		{ "endif",                sizeof( "endif" ) - 1                },
 | 
			
		||||
		{ "include",              sizeof( "include" ) - 1              },
 | 
			
		||||
		{ "pragma",               sizeof( "pragma" ) - 1               },
 | 
			
		||||
		{ "__macro_content__",    sizeof( "__macro_content__" ) - 1    },
 | 
			
		||||
		{ "__macro_expression__", sizeof( "__macro_expression__" ) - 1 },
 | 
			
		||||
		{ "__macro_statment__",   sizeof( "__macro_statment__" ) - 1   },
 | 
			
		||||
		{ "__macro_typename__",   sizeof( "__macro_typename__" ) - 1   },
 | 
			
		||||
		{ "__unsupported__",      sizeof( "__unsupported__" ) - 1      },
 | 
			
		||||
		{ "alignas",              sizeof( "alignas" ) - 1              },
 | 
			
		||||
		{ "const",                sizeof( "const" ) - 1                },
 | 
			
		||||
		{ "consteval",            sizeof( "consteval" ) - 1            },
 | 
			
		||||
		{ "constexpr",            sizeof( "constexpr" ) - 1            },
 | 
			
		||||
		{ "constinit",            sizeof( "constinit" ) - 1            },
 | 
			
		||||
		{ "explicit",             sizeof( "explicit" ) - 1             },
 | 
			
		||||
		{ "extern",               sizeof( "extern" ) - 1               },
 | 
			
		||||
		{ "final",                sizeof( "final" ) - 1                },
 | 
			
		||||
		{ "forceinline",          sizeof( "forceinline" ) - 1          },
 | 
			
		||||
		{ "global",               sizeof( "global" ) - 1               },
 | 
			
		||||
		{ "inline",               sizeof( "inline" ) - 1               },
 | 
			
		||||
		{ "internal",             sizeof( "internal" ) - 1             },
 | 
			
		||||
		{ "local_persist",        sizeof( "local_persist" ) - 1        },
 | 
			
		||||
		{ "mutable",              sizeof( "mutable" ) - 1              },
 | 
			
		||||
		{ "neverinline",          sizeof( "neverinline" ) - 1          },
 | 
			
		||||
		{ "override",             sizeof( "override" ) - 1             },
 | 
			
		||||
		{ "static",               sizeof( "static" ) - 1               },
 | 
			
		||||
		{ "thread_local",         sizeof( "thread_local" ) - 1         },
 | 
			
		||||
		{ "volatile",             sizeof( "volatile" ) - 1             },
 | 
			
		||||
		{ "virtual",              sizeof( "virtual" ) - 1              },
 | 
			
		||||
		{ "*",		            sizeof( "*" ) - 1                    },
 | 
			
		||||
		{ ";",		            sizeof( ";" ) - 1                    },
 | 
			
		||||
		{ "static_assert",        sizeof( "static_assert" ) - 1        },
 | 
			
		||||
		{ "__string__",           sizeof( "__string__" ) - 1           },
 | 
			
		||||
		{ "typename",             sizeof( "typename" ) - 1             },
 | 
			
		||||
		{ "unsigned",             sizeof( "unsigned" ) - 1             },
 | 
			
		||||
		{ "signed",               sizeof( "signed" ) - 1               },
 | 
			
		||||
		{ "short",                sizeof( "short" ) - 1                },
 | 
			
		||||
		{ "long",                 sizeof( "long" ) - 1                 },
 | 
			
		||||
		{ "bool",                 sizeof( "bool" ) - 1                 },
 | 
			
		||||
		{ "char",                 sizeof( "char" ) - 1                 },
 | 
			
		||||
		{ "int",		          sizeof( "int" ) - 1                  },
 | 
			
		||||
		{ "double",               sizeof( "double" ) - 1               },
 | 
			
		||||
		{ "__int8",               sizeof( "__int8" ) - 1               },
 | 
			
		||||
		{ "__int16",              sizeof( "__int16" ) - 1              },
 | 
			
		||||
		{ "__int32",              sizeof( "__int32" ) - 1              },
 | 
			
		||||
		{ "__int64",              sizeof( "__int64" ) - 1              },
 | 
			
		||||
		{ "_W64",                 sizeof( "_W64" ) - 1                 },
 | 
			
		||||
		{ "...",		          sizeof( "..." ) - 1                  },
 | 
			
		||||
		{ "__attrib_start__",     sizeof( "__attrib_start__" ) - 1     },
 | 
			
		||||
		{ "GEN_API",              sizeof( "GEN_API" ) - 1              },
 | 
			
		||||
	};
 | 
			
		||||
	return lookup[type];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline TokType str_to_toktype( Str str )
 | 
			
		||||
{
 | 
			
		||||
	local_persist u32 keymap[Tok_NumTokens];
 | 
			
		||||
	do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ )
 | 
			
		||||
	{
 | 
			
		||||
		Str enum_str  = toktype_to_str( (TokType)index );
 | 
			
		||||
		keymap[index] = crc32( enum_str.Ptr, enum_str.Len );
 | 
			
		||||
	}
 | 
			
		||||
	do_once_end u32 hash = crc32( str.Ptr, str.Len );
 | 
			
		||||
	for ( u32 index = 0; index < Tok_NumTokens; index++ )
 | 
			
		||||
	{
 | 
			
		||||
		if ( keymap[index] == hash )
 | 
			
		||||
			return (TokType)index;
 | 
			
		||||
	}
 | 
			
		||||
	return Tok_Invalid;
 | 
			
		||||
}
 | 
			
		||||
@@ -6,54 +6,7 @@
 | 
			
		||||
 | 
			
		||||
#pragma region Constants
 | 
			
		||||
 | 
			
		||||
#ifndef GEN_GLOBAL_BUCKET_SIZE
 | 
			
		||||
#	define GEN_GLOBAL_BUCKET_SIZE megabytes(8)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GEN_CODEPOOL_NUM_BLOCKS
 | 
			
		||||
#	define GEN_CODEPOOL_NUM_BLOCKS kilobytes(16)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GEN_SIZE_PER_STRING_ARENA
 | 
			
		||||
#	define GEN_SIZE_PER_STRING_ARENA megabytes(1)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GEN_MAX_COMMENT_LINE_LENGTH
 | 
			
		||||
#	define GEN_MAX_COMMENT_LINE_LENGTH 1024
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GEN_MAX_NAME_LENGTH
 | 
			
		||||
#	define GEN_MAX_NAME_LENGTH 128
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GEN_MAX_UNTYPED_STR_LENGTH
 | 
			
		||||
#	define GEN_MAX_UNTYPED_STR_LENGTH megabytes(1)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef TokenMap_FixedArena
 | 
			
		||||
#	define TokenMap_FixedArena FixedArena_8KB
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GEN_LEX_ALLOCATOR_SIZE
 | 
			
		||||
#	define GEN_LEX_ALLOCATOR_SIZE megabytes(4)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef GEN_BUILDER_STR_BUFFER_RESERVE
 | 
			
		||||
#	define GEN_BUILDER_STR_BUFFER_RESERVE megabytes(2)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// These constexprs are used for allocation behavior of data structures
 | 
			
		||||
// or string handling while constructing or serializing.
 | 
			
		||||
// Change them to suit your needs.
 | 
			
		||||
 | 
			
		||||
constexpr s32 InitSize_DataArrays = 16;
 | 
			
		||||
 | 
			
		||||
// NOTE: This limits the maximum size of an allocation
 | 
			
		||||
// If you are generating a string larger than this, increase the size of the bucket here.
 | 
			
		||||
constexpr usize  Global_BucketSize      = GEN_GLOBAL_BUCKET_SIZE;
 | 
			
		||||
constexpr s32 CodePool_NumBlocks        = GEN_CODEPOOL_NUM_BLOCKS;
 | 
			
		||||
constexpr s32 SizePer_StringArena       = GEN_SIZE_PER_STRING_ARENA;
 | 
			
		||||
 | 
			
		||||
constexpr s32 MaxCommentLineLength      = GEN_MAX_COMMENT_LINE_LENGTH;
 | 
			
		||||
constexpr s32 MaxNameLength             = GEN_MAX_NAME_LENGTH;
 | 
			
		||||
constexpr s32 MaxUntypedStrLength       = GEN_MAX_UNTYPED_STR_LENGTH;
 | 
			
		||||
// constexpr s32 TokenFmt_TokenMap_MemSize	= GEN_TOKEN_FMT_TOKEN_MAP_MEM_SIZE;
 | 
			
		||||
constexpr s32 LexAllocator_Size         = GEN_LEX_ALLOCATOR_SIZE;
 | 
			
		||||
constexpr s32 Builder_StrBufferReserve  = GEN_BUILDER_STR_BUFFER_RESERVE;
 | 
			
		||||
 | 
			
		||||
extern Str enum_underlying_sig;
 | 
			
		||||
extern Macro enum_underlying_macro;
 | 
			
		||||
 | 
			
		||||
extern Code access_public;
 | 
			
		||||
extern Code access_protected;
 | 
			
		||||
@@ -111,6 +64,7 @@ extern CodeTypename t_typename;
 | 
			
		||||
 | 
			
		||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
 | 
			
		||||
	// Predefined typename codes. Are set to readonly and are setup during gen::init()
 | 
			
		||||
	extern Context* _ctx;
 | 
			
		||||
 | 
			
		||||
	extern CodeTypename t_b32;
 | 
			
		||||
 | 
			
		||||
@@ -132,28 +86,3 @@ extern CodeTypename t_typename;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma endregion Constants
 | 
			
		||||
 | 
			
		||||
// Used by the lexer to persistently treat all these identifiers as preprocessor defines.
 | 
			
		||||
// Populate with strings via gen::get_cached_string.
 | 
			
		||||
// Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments.
 | 
			
		||||
extern Array(StringCached) PreprocessorDefines;
 | 
			
		||||
 | 
			
		||||
#ifdef GEN_EXPOSE_BACKEND
 | 
			
		||||
	// Global allocator used for data with process lifetime.
 | 
			
		||||
	extern AllocatorInfo  GlobalAllocator;
 | 
			
		||||
	extern Array(Arena) Global_AllocatorBuckets;
 | 
			
		||||
 | 
			
		||||
	extern Array(Pool)  CodePools;
 | 
			
		||||
	extern Array(Arena) StringArenas;
 | 
			
		||||
 | 
			
		||||
	extern StringTable StringCache;
 | 
			
		||||
 | 
			
		||||
	extern Arena LexArena;
 | 
			
		||||
 | 
			
		||||
	extern AllocatorInfo Allocator_DataArrays;
 | 
			
		||||
	extern AllocatorInfo Allocator_CodePool;
 | 
			
		||||
	extern AllocatorInfo Allocator_Lexer;
 | 
			
		||||
	extern AllocatorInfo Allocator_StringArena;
 | 
			
		||||
	extern AllocatorInfo Allocator_StringTable;
 | 
			
		||||
	extern AllocatorInfo Allocator_TypeTable;
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
	|  \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l                       |
 | 
			
		||||
	|                        | |   | |                      __} |                                  |
 | 
			
		||||
	|                        l_l   l_l                     {___/                                   |
 | 
			
		||||
	! ----------------------------------------------------------------------- VERSION: v0.20-Alpha |
 | 
			
		||||
	! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
 | 
			
		||||
	! ============================================================================================ |
 | 
			
		||||
	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                 |
 | 
			
		||||
	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |
 | 
			
		||||
 
 | 
			
		||||
@@ -257,6 +257,25 @@ CodeParams next_CodeParams(CodeParams params, CodeParams param_iter)
 | 
			
		||||
}
 | 
			
		||||
#pragma endregion CodeParams
 | 
			
		||||
 | 
			
		||||
#pragma region CodeDefineParams
 | 
			
		||||
forceinline void             define_params_append     (CodeDefineParams appendee, CodeDefineParams other ) { params_append( cast(CodeParams, appendee), cast(CodeParams, other) ); }
 | 
			
		||||
forceinline CodeDefineParams define_params_get        (CodeDefineParams self, s32 idx )                    { return (CodeDefineParams) (Code) params_get( cast(CodeParams, self), idx); }
 | 
			
		||||
forceinline bool             define_params_has_entries(CodeDefineParams self)                              { return params_has_entries( cast(CodeParams, self)); }
 | 
			
		||||
 | 
			
		||||
forceinline CodeDefineParams begin_CodeDefineParams(CodeDefineParams params)                              { return (CodeDefineParams) (Code) begin_CodeParams( cast(CodeParams, (Code)params)); }
 | 
			
		||||
forceinline CodeDefineParams end_CodeDefineParams  (CodeDefineParams params)                              { return (CodeDefineParams) (Code) end_CodeParams  ( cast(CodeParams, (Code)params)); }
 | 
			
		||||
forceinline CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter) { return (CodeDefineParams) (Code) next_CodeParams ( cast(CodeParams, (Code)params), cast(CodeParams, (Code)entry_iter)); }
 | 
			
		||||
 | 
			
		||||
#if GEN_COMPILER_CPP
 | 
			
		||||
forceinline
 | 
			
		||||
CodeDefineParams& CodeDefineParams::operator ++()
 | 
			
		||||
{
 | 
			
		||||
	* this = ast->Next;
 | 
			
		||||
	return * this;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#pragma endregion CodeDefineParams
 | 
			
		||||
 | 
			
		||||
#pragma region CodeSpecifiers
 | 
			
		||||
inline
 | 
			
		||||
bool specifiers_append(CodeSpecifiers self, Specifier spec )
 | 
			
		||||
 
 | 
			
		||||
@@ -3,15 +3,15 @@
 | 
			
		||||
#include "code_serialization.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GEN_NS_PARSER_BEGIN
 | 
			
		||||
internal void parser_init();
 | 
			
		||||
internal void parser_deinit();
 | 
			
		||||
GEN_NS_PARSER_END
 | 
			
		||||
 | 
			
		||||
internal
 | 
			
		||||
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
 | 
			
		||||
void* fallback_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
 | 
			
		||||
{
 | 
			
		||||
	Arena* last = array_back(Global_AllocatorBuckets);
 | 
			
		||||
	GEN_ASSERT(_ctx);
 | 
			
		||||
	GEN_ASSERT(_ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
	Arena* last = array_back(_ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
 | 
			
		||||
	switch ( type )
 | 
			
		||||
	{
 | 
			
		||||
@@ -19,15 +19,15 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
 | 
			
		||||
		{
 | 
			
		||||
			if ( ( last->TotalUsed + size ) > last->TotalSize )
 | 
			
		||||
			{
 | 
			
		||||
				Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
 | 
			
		||||
				Arena bucket = arena_init_from_allocator( heap(), _ctx->InitSize_Fallback_Allocator_Bucket_Size );
 | 
			
		||||
 | 
			
		||||
				if ( bucket.PhysicalStart == nullptr )
 | 
			
		||||
					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
 | 
			
		||||
					GEN_FATAL( "Failed to create bucket for Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
				if ( ! array_append( Global_AllocatorBuckets, bucket ) )
 | 
			
		||||
					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
 | 
			
		||||
				if ( ! array_append( _ctx->Fallback_AllocatorBuckets, bucket ) )
 | 
			
		||||
					GEN_FATAL( "Failed to append bucket to Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
				last = array_back(Global_AllocatorBuckets);
 | 
			
		||||
				last = array_back(_ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return alloc_align( arena_allocator_info(last), size, alignment );
 | 
			
		||||
@@ -46,15 +46,15 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
 | 
			
		||||
		{
 | 
			
		||||
			if ( last->TotalUsed + size > last->TotalSize )
 | 
			
		||||
			{
 | 
			
		||||
				Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
 | 
			
		||||
				Arena bucket = arena_init_from_allocator( heap(), _ctx->InitSize_Fallback_Allocator_Bucket_Size );
 | 
			
		||||
 | 
			
		||||
				if ( bucket.PhysicalStart == nullptr )
 | 
			
		||||
					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
 | 
			
		||||
					GEN_FATAL( "Failed to create bucket for Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
				if ( ! array_append( Global_AllocatorBuckets, bucket ) )
 | 
			
		||||
					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
 | 
			
		||||
				if ( ! array_append( _ctx->Fallback_AllocatorBuckets, bucket ) )
 | 
			
		||||
					GEN_FATAL( "Failed to append bucket to Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
				last = array_back(Global_AllocatorBuckets);
 | 
			
		||||
				last = array_back( _ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			void* result = alloc_align( last->Backing, size, alignment );
 | 
			
		||||
@@ -74,8 +74,12 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
 | 
			
		||||
internal
 | 
			
		||||
void define_constants()
 | 
			
		||||
{
 | 
			
		||||
	// We only initalize these if there is no base context.
 | 
			
		||||
	if ( context_counter > 0 )
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	Code_Global          = make_code();
 | 
			
		||||
	Code_Global->Name    = get_cached_string( txt("Global Code") );
 | 
			
		||||
	Code_Global->Name    = cache_str( txt("Global Code") );
 | 
			
		||||
	Code_Global->Content = Code_Global->Name;
 | 
			
		||||
 | 
			
		||||
	Code_Invalid = make_code();
 | 
			
		||||
@@ -83,22 +87,22 @@ void define_constants()
 | 
			
		||||
 | 
			
		||||
	t_empty       = (CodeTypename) make_code();
 | 
			
		||||
	t_empty->Type = CT_Typename;
 | 
			
		||||
	t_empty->Name = get_cached_string( txt("") );
 | 
			
		||||
	t_empty->Name = cache_str( txt("") );
 | 
			
		||||
	code_set_global(cast(Code, t_empty));
 | 
			
		||||
 | 
			
		||||
	access_private       = make_code();
 | 
			
		||||
	access_private->Type = CT_Access_Private;
 | 
			
		||||
	access_private->Name = get_cached_string( txt("private:\n") );
 | 
			
		||||
	access_private->Name = cache_str( txt("private:\n") );
 | 
			
		||||
	code_set_global(cast(Code, access_private));
 | 
			
		||||
 | 
			
		||||
	access_protected       = make_code();
 | 
			
		||||
	access_protected->Type = CT_Access_Protected;
 | 
			
		||||
	access_protected->Name = get_cached_string( txt("protected:\n") );
 | 
			
		||||
	access_protected->Name = cache_str( txt("protected:\n") );
 | 
			
		||||
	code_set_global(access_protected);
 | 
			
		||||
 | 
			
		||||
	access_public       = make_code();
 | 
			
		||||
	access_public->Type = CT_Access_Public;
 | 
			
		||||
	access_public->Name = get_cached_string( txt("public:\n") );
 | 
			
		||||
	access_public->Name = cache_str( txt("public:\n") );
 | 
			
		||||
	code_set_global(access_public);
 | 
			
		||||
 | 
			
		||||
	Str api_export_str = code(GEN_API_Export_Code);
 | 
			
		||||
@@ -111,13 +115,13 @@ void define_constants()
 | 
			
		||||
 | 
			
		||||
	module_global_fragment          = make_code();
 | 
			
		||||
	module_global_fragment->Type    = CT_Untyped;
 | 
			
		||||
	module_global_fragment->Name    = get_cached_string( txt("module;") );
 | 
			
		||||
	module_global_fragment->Name    = cache_str( txt("module;") );
 | 
			
		||||
	module_global_fragment->Content = module_global_fragment->Name;
 | 
			
		||||
	code_set_global(cast(Code, module_global_fragment));
 | 
			
		||||
 | 
			
		||||
	module_private_fragment          = make_code();
 | 
			
		||||
	module_private_fragment->Type    = CT_Untyped;
 | 
			
		||||
	module_private_fragment->Name    = get_cached_string( txt("module : private;") );
 | 
			
		||||
	module_private_fragment->Name    = cache_str( txt("module : private;") );
 | 
			
		||||
	module_private_fragment->Content = module_private_fragment->Name;
 | 
			
		||||
	code_set_global(cast(Code, module_private_fragment));
 | 
			
		||||
 | 
			
		||||
@@ -127,13 +131,13 @@ void define_constants()
 | 
			
		||||
 | 
			
		||||
	pragma_once          = (CodePragma) make_code();
 | 
			
		||||
	pragma_once->Type    = CT_Preprocess_Pragma;
 | 
			
		||||
	pragma_once->Name    = get_cached_string( txt("once") );
 | 
			
		||||
	pragma_once->Name    = cache_str( txt("once") );
 | 
			
		||||
	pragma_once->Content = pragma_once->Name;
 | 
			
		||||
	code_set_global((Code)pragma_once);
 | 
			
		||||
 | 
			
		||||
	param_varadic            = (CodeParams) make_code();
 | 
			
		||||
	param_varadic->Type      = CT_Parameters;
 | 
			
		||||
	param_varadic->Name      = get_cached_string( txt("...") );
 | 
			
		||||
	param_varadic->Name      = cache_str( txt("...") );
 | 
			
		||||
	param_varadic->ValueType = t_empty;
 | 
			
		||||
	code_set_global((Code)param_varadic);
 | 
			
		||||
 | 
			
		||||
@@ -175,279 +179,343 @@ void define_constants()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	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_constexpr        = def_specifier( Spec_Constexpr);        code_set_global( cast(Code, spec_constexpr ));;
 | 
			
		||||
	spec_constinit        = def_specifier( Spec_Constinit);        code_set_global( cast(Code, spec_constinit ));;
 | 
			
		||||
	spec_extern_linkage   = def_specifier( Spec_External_Linkage); code_set_global( cast(Code, spec_extern_linkage ));;
 | 
			
		||||
	spec_final            = def_specifier( Spec_Final);            code_set_global( cast(Code, spec_final ));;
 | 
			
		||||
	spec_forceinline      = def_specifier( Spec_ForceInline);      code_set_global( cast(Code, spec_forceinline ));;
 | 
			
		||||
	spec_global           = def_specifier( Spec_Global);           code_set_global( cast(Code, spec_global ));;
 | 
			
		||||
	spec_inline           = def_specifier( Spec_Inline);           code_set_global( cast(Code, spec_inline ));;
 | 
			
		||||
	spec_internal_linkage = def_specifier( Spec_Internal_Linkage); code_set_global( cast(Code, spec_internal_linkage ));;
 | 
			
		||||
	spec_local_persist    = def_specifier( Spec_Local_Persist);    code_set_global( cast(Code, spec_local_persist ));;
 | 
			
		||||
	spec_mutable          = def_specifier( Spec_Mutable);          code_set_global( cast(Code, spec_mutable ));;
 | 
			
		||||
	spec_neverinline      = def_specifier( Spec_NeverInline);      code_set_global( cast(Code, spec_neverinline ));;
 | 
			
		||||
	spec_noexcept         = def_specifier( Spec_NoExceptions);     code_set_global( cast(Code, spec_noexcept ));;
 | 
			
		||||
	spec_override         = def_specifier( Spec_Override);         code_set_global( cast(Code, spec_override ));;
 | 
			
		||||
	spec_ptr              = def_specifier( Spec_Ptr);              code_set_global( cast(Code, spec_ptr ));;
 | 
			
		||||
	spec_consteval        = def_specifier( Spec_Consteval);        code_set_global( cast(Code, spec_consteval ));
 | 
			
		||||
	spec_constexpr        = def_specifier( Spec_Constexpr);        code_set_global( cast(Code, spec_constexpr ));
 | 
			
		||||
	spec_constinit        = def_specifier( Spec_Constinit);        code_set_global( cast(Code, spec_constinit ));
 | 
			
		||||
	spec_extern_linkage   = def_specifier( Spec_External_Linkage); code_set_global( cast(Code, spec_extern_linkage ));
 | 
			
		||||
	spec_final            = def_specifier( Spec_Final);            code_set_global( cast(Code, spec_final ));
 | 
			
		||||
	spec_forceinline      = def_specifier( Spec_ForceInline);      code_set_global( cast(Code, spec_forceinline ));
 | 
			
		||||
	spec_global           = def_specifier( Spec_Global);           code_set_global( cast(Code, spec_global ));
 | 
			
		||||
	spec_inline           = def_specifier( Spec_Inline);           code_set_global( cast(Code, spec_inline ));
 | 
			
		||||
	spec_internal_linkage = def_specifier( Spec_Internal_Linkage); code_set_global( cast(Code, spec_internal_linkage ));
 | 
			
		||||
	spec_local_persist    = def_specifier( Spec_Local_Persist);    code_set_global( cast(Code, spec_local_persist ));
 | 
			
		||||
	spec_mutable          = def_specifier( Spec_Mutable);          code_set_global( cast(Code, spec_mutable ));
 | 
			
		||||
	spec_neverinline      = def_specifier( Spec_NeverInline);      code_set_global( cast(Code, spec_neverinline ));
 | 
			
		||||
	spec_noexcept         = def_specifier( Spec_NoExceptions);     code_set_global( cast(Code, spec_noexcept ));
 | 
			
		||||
	spec_override         = def_specifier( Spec_Override);         code_set_global( cast(Code, spec_override ));
 | 
			
		||||
	spec_ptr              = def_specifier( Spec_Ptr);              code_set_global( cast(Code, spec_ptr ));
 | 
			
		||||
	spec_pure             = def_specifier( Spec_Pure);             code_set_global( cast(Code, spec_pure ));
 | 
			
		||||
	spec_ref              = def_specifier( Spec_Ref);              code_set_global( cast(Code, spec_ref ));;
 | 
			
		||||
	spec_register         = def_specifier( Spec_Register);         code_set_global( cast(Code, spec_register ));;
 | 
			
		||||
	spec_rvalue           = def_specifier( Spec_RValue);           code_set_global( cast(Code, spec_rvalue ));;
 | 
			
		||||
	spec_static_member    = def_specifier( Spec_Static);           code_set_global( cast(Code, spec_static_member ));;
 | 
			
		||||
	spec_thread_local     = def_specifier( Spec_Thread_Local);     code_set_global( cast(Code, spec_thread_local ));;
 | 
			
		||||
	spec_virtual          = def_specifier( Spec_Virtual);          code_set_global( cast(Code, spec_virtual ));;
 | 
			
		||||
	spec_ref              = def_specifier( Spec_Ref);              code_set_global( cast(Code, spec_ref ));
 | 
			
		||||
	spec_register         = def_specifier( Spec_Register);         code_set_global( cast(Code, spec_register ));
 | 
			
		||||
	spec_rvalue           = def_specifier( Spec_RValue);           code_set_global( cast(Code, spec_rvalue ));
 | 
			
		||||
	spec_static_member    = def_specifier( Spec_Static);           code_set_global( cast(Code, spec_static_member ));
 | 
			
		||||
	spec_thread_local     = def_specifier( Spec_Thread_Local);     code_set_global( cast(Code, spec_thread_local ));
 | 
			
		||||
	spec_virtual          = def_specifier( Spec_Virtual);          code_set_global( cast(Code, spec_virtual ));
 | 
			
		||||
	spec_volatile         = def_specifier( Spec_Volatile);         code_set_global( cast(Code, spec_volatile ));
 | 
			
		||||
 | 
			
		||||
	spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
 | 
			
		||||
	code_set_global(cast(Code, spec_local_persist));
 | 
			
		||||
 | 
			
		||||
	if (enum_underlying_sig.Len == 0) {
 | 
			
		||||
		enum_underlying_sig = txt("enum_underlying(");
 | 
			
		||||
	if (enum_underlying_macro.Name.Len == 0) {
 | 
			
		||||
		enum_underlying_macro.Name  = txt("enum_underlying");
 | 
			
		||||
		enum_underlying_macro.Type  = MT_Expression;
 | 
			
		||||
		enum_underlying_macro.Flags = MF_Functional;
 | 
			
		||||
	}
 | 
			
		||||
	array_append(PreprocessorDefines, enum_underlying_sig);
 | 
			
		||||
 | 
			
		||||
#	undef def_constant_spec
 | 
			
		||||
	register_macro(enum_underlying_macro);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init()
 | 
			
		||||
void init(Context* ctx)
 | 
			
		||||
{
 | 
			
		||||
	// Setup global allocator
 | 
			
		||||
	do_once() {
 | 
			
		||||
		context_counter = 0;
 | 
			
		||||
	}
 | 
			
		||||
	AllocatorInfo fallback_allocator = { & fallback_allocator_proc, nullptr };
 | 
			
		||||
	
 | 
			
		||||
	b32 using_fallback_allocator = false;
 | 
			
		||||
	if (ctx->Allocator_DyanmicContainers.Proc == nullptr) {
 | 
			
		||||
		ctx->Allocator_DyanmicContainers = fallback_allocator;
 | 
			
		||||
		using_fallback_allocator = true;
 | 
			
		||||
	}
 | 
			
		||||
	if (ctx->Allocator_Pool.Proc == nullptr ) {
 | 
			
		||||
		ctx->Allocator_Pool = fallback_allocator;
 | 
			
		||||
		using_fallback_allocator = true;
 | 
			
		||||
	}
 | 
			
		||||
	if (ctx->Allocator_StrCache.Proc == nullptr) {
 | 
			
		||||
		ctx->Allocator_StrCache = fallback_allocator;
 | 
			
		||||
		using_fallback_allocator = true;
 | 
			
		||||
	}
 | 
			
		||||
	if (ctx->Allocator_Temp.Proc == nullptr) {
 | 
			
		||||
		ctx->Allocator_Temp = fallback_allocator;
 | 
			
		||||
		using_fallback_allocator = true;
 | 
			
		||||
	}
 | 
			
		||||
	// Setup fallback allocator
 | 
			
		||||
	if (using_fallback_allocator)
 | 
			
		||||
	{
 | 
			
		||||
		AllocatorInfo becasue_C = { & Global_Allocator_Proc, nullptr };
 | 
			
		||||
		GlobalAllocator = becasue_C;
 | 
			
		||||
 | 
			
		||||
		Global_AllocatorBuckets = array_init_reserve(Arena, heap(), 128 );
 | 
			
		||||
 | 
			
		||||
		if ( Global_AllocatorBuckets == nullptr )
 | 
			
		||||
			GEN_FATAL( "Failed to reserve memory for Global_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
		Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
 | 
			
		||||
		ctx->Fallback_AllocatorBuckets = array_init_reserve(Arena, heap(), 128 );
 | 
			
		||||
		if ( ctx->Fallback_AllocatorBuckets == nullptr )
 | 
			
		||||
			GEN_FATAL( "Failed to reserve memory for Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
		Arena bucket = arena_init_from_allocator( heap(), ctx->InitSize_Fallback_Allocator_Bucket_Size );
 | 
			
		||||
		if ( bucket.PhysicalStart == nullptr )
 | 
			
		||||
			GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets");
 | 
			
		||||
			GEN_FATAL( "Failed to create first bucket for Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
		array_append( Global_AllocatorBuckets, bucket );
 | 
			
		||||
		array_append( ctx->Fallback_AllocatorBuckets, bucket );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (Allocator_DataArrays.Proc == nullptr) {
 | 
			
		||||
		Allocator_DataArrays = GlobalAllocator;
 | 
			
		||||
	if (ctx->Max_CommentLineLength == 0) {
 | 
			
		||||
		ctx->Max_CommentLineLength = 1024;
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_CodePool.Proc == nullptr ) {
 | 
			
		||||
		Allocator_CodePool = GlobalAllocator;
 | 
			
		||||
	if (ctx->Max_StrCacheLength == 0) {
 | 
			
		||||
		ctx->Max_StrCacheLength = kilobytes(512);
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_Lexer.Proc == nullptr) {
 | 
			
		||||
		Allocator_Lexer = GlobalAllocator;
 | 
			
		||||
 | 
			
		||||
	if (ctx->InitSize_BuilderBuffer == 0) {
 | 
			
		||||
		ctx->InitSize_BuilderBuffer = megabytes(2);
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_StringArena.Proc == nullptr) {
 | 
			
		||||
		Allocator_StringArena = GlobalAllocator;
 | 
			
		||||
	if (ctx->InitSize_CodePoolsArray == 0) { 
 | 
			
		||||
		ctx->InitSize_CodePoolsArray = 16; 
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_StringTable.Proc == nullptr) {
 | 
			
		||||
		Allocator_StringTable = GlobalAllocator;
 | 
			
		||||
	if (ctx->InitSize_StringArenasArray == 0) {
 | 
			
		||||
		ctx->InitSize_StringArenasArray = 16; 
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_TypeTable.Proc == nullptr) {
 | 
			
		||||
		Allocator_TypeTable = GlobalAllocator;
 | 
			
		||||
	if (ctx->CodePool_NumBlocks == 0) {
 | 
			
		||||
		ctx->CodePool_NumBlocks = kilobytes(16);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ctx->InitSize_LexerTokens == 0 ) {
 | 
			
		||||
		ctx->InitSize_LexerTokens = kilobytes(64);
 | 
			
		||||
	}
 | 
			
		||||
	if (ctx->SizePer_StringArena == 0) {
 | 
			
		||||
		ctx->SizePer_StringArena = megabytes(1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ctx->InitSize_Fallback_Allocator_Bucket_Size == 0) { 
 | 
			
		||||
		ctx->InitSize_Fallback_Allocator_Bucket_Size = megabytes(8);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Override the current context (user has to put it back if unwanted).
 | 
			
		||||
	_ctx = ctx;
 | 
			
		||||
 | 
			
		||||
	// Setup the arrays
 | 
			
		||||
	{
 | 
			
		||||
		CodePools = array_init_reserve(Pool, Allocator_DataArrays, InitSize_DataArrays );
 | 
			
		||||
 | 
			
		||||
		if ( CodePools == nullptr )
 | 
			
		||||
		ctx->CodePools = array_init_reserve(Pool, ctx->Allocator_DyanmicContainers, ctx->InitSize_CodePoolsArray );
 | 
			
		||||
		if ( ctx->CodePools == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the CodePools array" );
 | 
			
		||||
 | 
			
		||||
		StringArenas = array_init_reserve(Arena, Allocator_DataArrays, InitSize_DataArrays );
 | 
			
		||||
 | 
			
		||||
		if ( StringArenas == nullptr )
 | 
			
		||||
		ctx->StringArenas = array_init_reserve(Arena, ctx->Allocator_DyanmicContainers, ctx->InitSize_StringArenasArray );
 | 
			
		||||
		if ( ctx->StringArenas == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the StringArenas array" );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Setup the code pool and code entries arena.
 | 
			
		||||
	{
 | 
			
		||||
		Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
 | 
			
		||||
 | 
			
		||||
		Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, sizeof(AST) );
 | 
			
		||||
		if ( code_pool.PhysicalStart == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the code pool" );
 | 
			
		||||
		array_append( ctx->CodePools, code_pool );
 | 
			
		||||
 | 
			
		||||
		array_append( CodePools, code_pool );
 | 
			
		||||
 | 
			
		||||
		LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size );
 | 
			
		||||
 | 
			
		||||
		Arena strbuilder_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
 | 
			
		||||
 | 
			
		||||
		// TODO(Ed): Eventually the string arenas needs to be phased out for a dedicated string slab allocator
 | 
			
		||||
		Arena strbuilder_arena = arena_init_from_allocator( ctx->Allocator_StrCache, ctx->SizePer_StringArena );
 | 
			
		||||
		if ( strbuilder_arena.PhysicalStart == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the string arena" );
 | 
			
		||||
 | 
			
		||||
		array_append( StringArenas, strbuilder_arena );
 | 
			
		||||
		array_append( ctx->StringArenas, strbuilder_arena );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Setup the hash tables
 | 
			
		||||
	{
 | 
			
		||||
		StringCache = hashtable_init(StringCached, Allocator_StringTable);
 | 
			
		||||
 | 
			
		||||
		if ( StringCache.Entries == nullptr )
 | 
			
		||||
		ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers);
 | 
			
		||||
		if ( ctx->StrCache.Entries == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the StringCache");
 | 
			
		||||
 | 
			
		||||
		ctx->Macros = hashtable_init(Macro, ctx->Allocator_DyanmicContainers);
 | 
			
		||||
		if (ctx->Macros.Hashes == nullptr || ctx->Macros.Entries == nullptr) {
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the PreprocessMacros table" );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Preprocessor Defines
 | 
			
		||||
	PreprocessorDefines = array_init_reserve(StringCached, GlobalAllocator, kilobytes(1) );
 | 
			
		||||
 | 
			
		||||
	define_constants();
 | 
			
		||||
	GEN_NS_PARSER parser_init();
 | 
			
		||||
	parser_init();
 | 
			
		||||
 | 
			
		||||
	++ context_counter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void deinit()
 | 
			
		||||
void deinit(Context* ctx)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(context_counter);
 | 
			
		||||
	GEN_ASSERT_MSG(context_counter > 0, "Attempted to deinit a context that for some reason wan't accounted for!");
 | 
			
		||||
	usize index = 0;
 | 
			
		||||
	usize left  = array_num(CodePools);
 | 
			
		||||
	usize left  = array_num(ctx->CodePools);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Pool* code_pool = & CodePools[index];
 | 
			
		||||
		Pool* code_pool = & ctx->CodePools[index];
 | 
			
		||||
		pool_free(code_pool);
 | 
			
		||||
		index++;
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
 | 
			
		||||
	index = 0;
 | 
			
		||||
	left  = array_num(StringArenas);
 | 
			
		||||
	left  = array_num(ctx->StringArenas);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Arena* strbuilder_arena = & StringArenas[index];
 | 
			
		||||
		Arena* strbuilder_arena = & ctx->StringArenas[index];
 | 
			
		||||
		arena_free(strbuilder_arena);
 | 
			
		||||
		index++;
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
 | 
			
		||||
	hashtable_destroy(StringCache);
 | 
			
		||||
	hashtable_destroy(ctx->StrCache);
 | 
			
		||||
 | 
			
		||||
	array_free( CodePools);
 | 
			
		||||
	array_free( StringArenas);
 | 
			
		||||
	array_free( ctx->CodePools);
 | 
			
		||||
	array_free( ctx->StringArenas);
 | 
			
		||||
 | 
			
		||||
	arena_free(& LexArena);
 | 
			
		||||
	hashtable_destroy(ctx->Macros);
 | 
			
		||||
 | 
			
		||||
	array_free(PreprocessorDefines);
 | 
			
		||||
 | 
			
		||||
	index = 0;
 | 
			
		||||
	left  = array_num(Global_AllocatorBuckets);
 | 
			
		||||
	do
 | 
			
		||||
	left  = array_num( ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
	if (left)
 | 
			
		||||
	{
 | 
			
		||||
		Arena* bucket = & Global_AllocatorBuckets[ index ];
 | 
			
		||||
		arena_free(bucket);
 | 
			
		||||
		index++;
 | 
			
		||||
		index = 0;
 | 
			
		||||
		do
 | 
			
		||||
		{
 | 
			
		||||
			Arena* bucket = & ctx->Fallback_AllocatorBuckets[ index ];
 | 
			
		||||
			arena_free(bucket);
 | 
			
		||||
			index++;
 | 
			
		||||
		}
 | 
			
		||||
		while ( left--, left );
 | 
			
		||||
		array_free( ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
	parser_deinit();
 | 
			
		||||
 | 
			
		||||
	array_free(Global_AllocatorBuckets);
 | 
			
		||||
	GEN_NS_PARSER parser_deinit();
 | 
			
		||||
	if (_ctx == ctx) 
 | 
			
		||||
		_ctx = nullptr;
 | 
			
		||||
	-- context_counter;
 | 
			
		||||
 | 
			
		||||
	Context wipe = {};
 | 
			
		||||
	* ctx = wipe;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void reset()
 | 
			
		||||
Context* get_context() { 
 | 
			
		||||
	return _ctx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void reset(Context* ctx)
 | 
			
		||||
{
 | 
			
		||||
	s32 index = 0;
 | 
			
		||||
	s32 left  = array_num(CodePools);
 | 
			
		||||
	s32 left  = array_num(ctx->CodePools);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Pool* code_pool = & CodePools[index];
 | 
			
		||||
		Pool* code_pool = & ctx->CodePools[index];
 | 
			
		||||
		pool_clear(code_pool);
 | 
			
		||||
		index++;
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
 | 
			
		||||
	index = 0;
 | 
			
		||||
	left  = array_num(StringArenas);
 | 
			
		||||
	left  = array_num(ctx->StringArenas);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Arena* strbuilder_arena = & StringArenas[index];
 | 
			
		||||
		Arena* strbuilder_arena = & ctx->StringArenas[index];
 | 
			
		||||
		strbuilder_arena->TotalUsed = 0;;
 | 
			
		||||
		index++;
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
 | 
			
		||||
	hashtable_clear(StringCache);
 | 
			
		||||
 | 
			
		||||
	hashtable_clear(ctx->StrCache);
 | 
			
		||||
	hashtable_clear(ctx->Macros);
 | 
			
		||||
	define_constants();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AllocatorInfo get_strbuilder_allocator( s32 c_str_length )
 | 
			
		||||
void set_context(Context* new_ctx) {
 | 
			
		||||
	GEN_ASSERT(new_ctx);
 | 
			
		||||
	_ctx = new_ctx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AllocatorInfo get_cached_str_allocator( s32 str_length )
 | 
			
		||||
{
 | 
			
		||||
	Arena* last = array_back(StringArenas);
 | 
			
		||||
 | 
			
		||||
	usize size_req = c_str_length + sizeof(StrBuilderHeader) + sizeof(char*);
 | 
			
		||||
 | 
			
		||||
	Arena* last     = array_back(_ctx->StringArenas);
 | 
			
		||||
	usize  size_req = str_length + sizeof(StrBuilderHeader) + sizeof(char*);
 | 
			
		||||
	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( _ctx->Allocator_StrCache, _ctx->SizePer_StringArena );
 | 
			
		||||
		if ( ! array_append( _ctx->StringArenas, new_arena ) )
 | 
			
		||||
			GEN_FATAL( "gen::get_cached_str_allocator: Failed to allocate a new string arena" );
 | 
			
		||||
 | 
			
		||||
		if ( ! array_append( StringArenas, new_arena ) )
 | 
			
		||||
			GEN_FATAL( "gen::get_strbuilder_allocator: Failed to allocate a new string arena" );
 | 
			
		||||
 | 
			
		||||
		last = array_back(StringArenas);
 | 
			
		||||
		last = array_back( _ctx->StringArenas);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return arena_allocator_info(last);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Will either make or retrive a code string.
 | 
			
		||||
StringCached get_cached_string( Str str )
 | 
			
		||||
StrCached cache_str( Str str )
 | 
			
		||||
{
 | 
			
		||||
	s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
 | 
			
		||||
	u64 key         = crc32( str.Ptr, hash_length );
 | 
			
		||||
	{
 | 
			
		||||
		StringCached* result = hashtable_get(StringCache, key );
 | 
			
		||||
 | 
			
		||||
	if (str.Len > _ctx->Max_StrCacheLength) {
 | 
			
		||||
		// Do not cache the string, just shove into the arena and and return it.
 | 
			
		||||
		Str result = strbuilder_to_str( strbuilder_make_str( get_cached_str_allocator( str.Len ), str ));
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	u64 key = crc32( str.Ptr, str.Len ); {
 | 
			
		||||
		StrCached* result = hashtable_get( _ctx->StrCache, key );
 | 
			
		||||
		if ( result )
 | 
			
		||||
			return * result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Str result = strbuilder_to_str( strbuilder_make_str( get_strbuilder_allocator( str.Len ), str ));
 | 
			
		||||
	hashtable_set(StringCache, key, result );
 | 
			
		||||
 | 
			
		||||
	Str result = strbuilder_to_str( strbuilder_make_str( get_cached_str_allocator( str.Len ), str ));
 | 
			
		||||
	hashtable_set( _ctx->StrCache, key, result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Used internally to retireve a Code object form the CodePool.
 | 
			
		||||
Code make_code()
 | 
			
		||||
{
 | 
			
		||||
	Pool* allocator = array_back( CodePools);
 | 
			
		||||
	Pool* allocator = array_back( _ctx->CodePools);
 | 
			
		||||
	if ( allocator->FreeList == nullptr )
 | 
			
		||||
	{
 | 
			
		||||
		Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
 | 
			
		||||
		Pool code_pool = pool_init( _ctx->Allocator_Pool, _ctx->CodePool_NumBlocks, sizeof(AST) );
 | 
			
		||||
 | 
			
		||||
		if ( code_pool.PhysicalStart == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
 | 
			
		||||
 | 
			
		||||
		if ( ! array_append( CodePools, code_pool ) )
 | 
			
		||||
		if ( ! array_append( _ctx->CodePools, code_pool ) )
 | 
			
		||||
			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
 | 
			
		||||
 | 
			
		||||
		allocator = array_back( CodePools);
 | 
			
		||||
		allocator = array_back( _ctx->CodePools);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Code result = { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) };
 | 
			
		||||
	mem_set( rcast(void*, cast(AST*, result)), 0, sizeof(AST) );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_allocator_data_arrays( AllocatorInfo allocator )
 | 
			
		||||
{
 | 
			
		||||
	Allocator_DataArrays = allocator;
 | 
			
		||||
Macro* lookup_macro( Str name ) {
 | 
			
		||||
	u32 key = crc32( name.Ptr, name.Len );
 | 
			
		||||
	return hashtable_get( _ctx->Macros, key );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_allocator_code_pool( AllocatorInfo allocator )
 | 
			
		||||
{
 | 
			
		||||
	Allocator_CodePool = allocator;
 | 
			
		||||
void register_macro( Macro macro ) {
 | 
			
		||||
	GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
 | 
			
		||||
	GEN_ASSERT(macro.Name.Len > 0);
 | 
			
		||||
	u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
 | 
			
		||||
	macro.Name = cache_str(macro.Name);
 | 
			
		||||
	hashtable_set( _ctx->Macros, key, macro );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_allocator_lexer( AllocatorInfo allocator )
 | 
			
		||||
void register_macros( s32 num, ... )
 | 
			
		||||
{
 | 
			
		||||
	Allocator_Lexer = allocator;
 | 
			
		||||
	GEN_ASSERT(num > 0);
 | 
			
		||||
	va_list va;
 | 
			
		||||
	va_start(va, num);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Macro macro = va_arg(va, Macro);
 | 
			
		||||
		GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
 | 
			
		||||
		GEN_ASSERT(macro.Name.Len > 0);
 | 
			
		||||
		macro.Name = cache_str(macro.Name);
 | 
			
		||||
 | 
			
		||||
		u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
 | 
			
		||||
		hashtable_set( _ctx->Macros, key, macro );
 | 
			
		||||
	}
 | 
			
		||||
	while (num--, num > 0);
 | 
			
		||||
	va_end(va);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_allocator_strbuilder_arena( AllocatorInfo allocator )
 | 
			
		||||
void register_macros_arr( s32 num,  Macro* macros )
 | 
			
		||||
{
 | 
			
		||||
	Allocator_StringArena = allocator;
 | 
			
		||||
}
 | 
			
		||||
	GEN_ASSERT(num > 0);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Macro macro = * macros;
 | 
			
		||||
		GEN_ASSERT_NOT_NULL(macro.Name.Ptr);
 | 
			
		||||
		GEN_ASSERT(macro.Name.Len > 0);
 | 
			
		||||
		macro.Name = cache_str(macro.Name);
 | 
			
		||||
 | 
			
		||||
void set_allocator_strbuilder_table( AllocatorInfo allocator )
 | 
			
		||||
{
 | 
			
		||||
	Allocator_StringArena = allocator;
 | 
			
		||||
		u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
 | 
			
		||||
		hashtable_set( _ctx->Macros, key, macro );
 | 
			
		||||
		++ macros;
 | 
			
		||||
	}
 | 
			
		||||
	while (num--, num > 0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,41 +15,138 @@
 | 
			
		||||
  \▓▓▓▓▓▓  \▓▓▓▓▓▓▓\▓▓   \▓▓     \▓▓▓▓▓▓\▓▓   \▓▓   \▓▓▓▓  \▓▓▓▓▓▓▓\▓▓      \▓▓       \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// Initialize the library.
 | 
			
		||||
void init();
 | 
			
		||||
#if 0
 | 
			
		||||
enum LogLevel : u32
 | 
			
		||||
{
 | 
			
		||||
	Info,
 | 
			
		||||
	Warning,
 | 
			
		||||
	Panic,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct LogEntry
 | 
			
		||||
{
 | 
			
		||||
	Str   msg;
 | 
			
		||||
	u32   line_num;
 | 
			
		||||
	void* data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef void LoggerCallback(LogEntry entry);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Note(Ed): This is subject to heavily change 
 | 
			
		||||
// with upcoming changes to the library's fallback (default) allocations strategy;
 | 
			
		||||
// and major changes to lexer/parser context usage.
 | 
			
		||||
struct Context
 | 
			
		||||
{
 | 
			
		||||
// User Configuration
 | 
			
		||||
 | 
			
		||||
// Persistent Data Allocation
 | 
			
		||||
	AllocatorInfo Allocator_DyanmicContainers; // By default will use a genral slab allocator (TODO(Ed): Currently does not)
 | 
			
		||||
	AllocatorInfo Allocator_Pool;              // By default will use the growing vmem reserve (TODO(Ed): Currently does not)
 | 
			
		||||
	AllocatorInfo Allocator_StrCache;          // By default will use a dedicated slab allocator (TODO(Ed): Currently does not)
 | 
			
		||||
 | 
			
		||||
// Temporary Allocation
 | 
			
		||||
	AllocatorInfo Allocator_Temp;
 | 
			
		||||
 | 
			
		||||
	// LoggerCallaback* log_callback; // TODO(Ed): Impl user logger callback as an option.
 | 
			
		||||
 | 
			
		||||
	u32 Max_CommentLineLength; // Used by def_comment
 | 
			
		||||
	u32 Max_StrCacheLength;    // Any cached string longer than this is always allocated again.
 | 
			
		||||
 | 
			
		||||
	u32 InitSize_BuilderBuffer;
 | 
			
		||||
	u32 InitSize_CodePoolsArray;
 | 
			
		||||
	u32 InitSize_StringArenasArray;
 | 
			
		||||
 | 
			
		||||
	u32 CodePool_NumBlocks;
 | 
			
		||||
 | 
			
		||||
	// TODO(Ed): Review these... (No longer needed if using the proper allocation strategy)
 | 
			
		||||
	u32 InitSize_LexerTokens;
 | 
			
		||||
	u32 SizePer_StringArena;
 | 
			
		||||
 | 
			
		||||
// TODO(Ed): Symbol Table
 | 
			
		||||
	// Keep track of all resolved symbols (naemspaced identifiers)
 | 
			
		||||
 | 
			
		||||
// Parser
 | 
			
		||||
 | 
			
		||||
	// Used by the lexer to persistently treat all these identifiers as preprocessor defines.
 | 
			
		||||
	// Populate with strings via gen::cache_str.
 | 
			
		||||
	// Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments.
 | 
			
		||||
	MacroTable Macros;
 | 
			
		||||
 | 
			
		||||
// Backend
 | 
			
		||||
 | 
			
		||||
	// The fallback allocator is utilized if any fo the three above allocators is not specified by the user.
 | 
			
		||||
	u32 InitSize_Fallback_Allocator_Bucket_Size;
 | 
			
		||||
	Array(Arena) Fallback_AllocatorBuckets;
 | 
			
		||||
 | 
			
		||||
	StringTable token_fmt_map;
 | 
			
		||||
 | 
			
		||||
	// Array(Token) LexerTokens;
 | 
			
		||||
 | 
			
		||||
	Array(Pool)  CodePools;
 | 
			
		||||
	Array(Arena) StringArenas;
 | 
			
		||||
 | 
			
		||||
	StringTable StrCache;
 | 
			
		||||
 | 
			
		||||
	// TODO(Ed): This needs to be just handled by a parser context
 | 
			
		||||
	Array(Token) Lexer_Tokens;
 | 
			
		||||
 | 
			
		||||
	// TODO(Ed): Active parse context vs a parse result need to be separated conceptually
 | 
			
		||||
	ParseContext parser;
 | 
			
		||||
 | 
			
		||||
	// TODO(Ed): Formatting - This will eventually be in a separate struct when in the process of serialization of the builder.
 | 
			
		||||
	s32 temp_serialize_indent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Initialize the library. There first ctx initialized must exist for lifetime of other contextes that come after as its the one that
 | 
			
		||||
GEN_API void init(Context* ctx);
 | 
			
		||||
 | 
			
		||||
// Currently manually free's the arenas, code for checking for leaks.
 | 
			
		||||
// However on Windows at least, it doesn't need to occur as the OS will clean up after the process.
 | 
			
		||||
void deinit();
 | 
			
		||||
GEN_API void deinit(Context* ctx);
 | 
			
		||||
 | 
			
		||||
// Clears the allocations, but doesn't return to the heap, the calls init() again.
 | 
			
		||||
// Retrieves the active context (not usually needed, but here in case...)
 | 
			
		||||
GEN_API Context* get_context();
 | 
			
		||||
 | 
			
		||||
// Clears the allocations, but doesn't free the memoery, then calls init() again.
 | 
			
		||||
// Ease of use.
 | 
			
		||||
void reset();
 | 
			
		||||
GEN_API void reset(Context* ctx);
 | 
			
		||||
 | 
			
		||||
GEN_API void set_context(Context* ctx);
 | 
			
		||||
 | 
			
		||||
// Mostly intended for the parser
 | 
			
		||||
GEN_API Macro* lookup_macro( Str Name );
 | 
			
		||||
 | 
			
		||||
// Alternative way to add a preprocess define entry for the lexer & parser to utilize 
 | 
			
		||||
// if the user doesn't want to use def_define
 | 
			
		||||
// Macros are tracked by name so if the name already exists the entry will be overwritten.
 | 
			
		||||
GEN_API void register_macro( Macro macro );
 | 
			
		||||
 | 
			
		||||
// Ease of use batch registration
 | 
			
		||||
GEN_API void register_macros( s32 num, ... );
 | 
			
		||||
GEN_API void register_macros_arr( s32 num, Macro* macros );
 | 
			
		||||
 | 
			
		||||
#if GEN_COMPILER_CPP
 | 
			
		||||
forceinline void register_macros( s32 num, Macro* macros ) { return register_macros_arr(num, macros); }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Used internally to retrive or make string allocations.
 | 
			
		||||
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
 | 
			
		||||
StringCached get_cached_string( Str str );
 | 
			
		||||
GEN_API StrCached cache_str( Str str );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	This provides a fresh Code AST.
 | 
			
		||||
	The gen interface use this as their method from getting a new AST object from the CodePool.
 | 
			
		||||
	Use this if you want to make your own API for formatting the supported Code Types.
 | 
			
		||||
*/
 | 
			
		||||
Code make_code();
 | 
			
		||||
GEN_API Code make_code();
 | 
			
		||||
 | 
			
		||||
// Set these before calling gen's init() procedure.
 | 
			
		||||
 | 
			
		||||
void set_allocator_data_arrays ( AllocatorInfo data_array_allocator );
 | 
			
		||||
void set_allocator_code_pool   ( AllocatorInfo pool_allocator );
 | 
			
		||||
void set_allocator_lexer       ( AllocatorInfo lex_allocator );
 | 
			
		||||
void set_allocator_strbuilder_arena( AllocatorInfo strbuilder_allocator );
 | 
			
		||||
void set_allocator_strbuilder_table( AllocatorInfo strbuilder_allocator );
 | 
			
		||||
void set_allocator_type_table  ( AllocatorInfo type_reg_allocator );
 | 
			
		||||
 | 
			
		||||
#pragma region Upfront
 | 
			
		||||
 | 
			
		||||
CodeAttributes def_attributes( Str content );
 | 
			
		||||
CodeComment    def_comment   ( Str content );
 | 
			
		||||
GEN_API CodeAttributes def_attributes( Str content );
 | 
			
		||||
GEN_API CodeComment    def_comment   ( Str content );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_struct {
 | 
			
		||||
	CodeBody       body;
 | 
			
		||||
@@ -60,25 +157,28 @@ struct Opts_def_struct {
 | 
			
		||||
	s32            num_interfaces;
 | 
			
		||||
	ModuleFlag     mflags;
 | 
			
		||||
};
 | 
			
		||||
CodeClass def_class( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeClass def_class( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_constructor {
 | 
			
		||||
	CodeParams params;
 | 
			
		||||
	Code      initializer_list;
 | 
			
		||||
	Code      body;
 | 
			
		||||
};
 | 
			
		||||
CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_define {
 | 
			
		||||
	b32 dont_append_preprocess_defines;
 | 
			
		||||
	CodeDefineParams params;
 | 
			
		||||
	Str              content;
 | 
			
		||||
	MacroFlags       flags;
 | 
			
		||||
	b32              dont_register_to_preprocess_macros;
 | 
			
		||||
};
 | 
			
		||||
CodeDefine def_define( Str name, Str content, Opts_def_define opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeDefine def_define( Str name, MacroType type, Opts_def_define opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_destructor {
 | 
			
		||||
	Code           body;
 | 
			
		||||
	CodeSpecifiers specifiers;
 | 
			
		||||
};
 | 
			
		||||
CodeDestructor def_destructor( Opts_def_destructor opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeDestructor def_destructor( Opts_def_destructor opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_enum {
 | 
			
		||||
	CodeBody       body;
 | 
			
		||||
@@ -88,11 +188,11 @@ struct Opts_def_enum {
 | 
			
		||||
	ModuleFlag     mflags;
 | 
			
		||||
	Code           type_macro;
 | 
			
		||||
};
 | 
			
		||||
CodeEnum def_enum( Str name, Opts_def_enum opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeEnum def_enum( Str name, Opts_def_enum opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
CodeExec   def_execution  ( Str content );
 | 
			
		||||
CodeExtern def_extern_link( Str name, CodeBody body );
 | 
			
		||||
CodeFriend def_friend     ( Code symbol );
 | 
			
		||||
GEN_API CodeExec   def_execution  ( Str content );
 | 
			
		||||
GEN_API CodeExtern def_extern_link( Str name, CodeBody body );
 | 
			
		||||
GEN_API CodeFriend def_friend     ( Code symbol );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_function {
 | 
			
		||||
	CodeParams      params;
 | 
			
		||||
@@ -102,14 +202,14 @@ struct Opts_def_function {
 | 
			
		||||
	CodeAttributes  attrs;
 | 
			
		||||
	ModuleFlag      mflags;
 | 
			
		||||
};
 | 
			
		||||
CodeFn def_function( Str name, Opts_def_function opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeFn def_function( Str name, Opts_def_function opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_include   { b32        foreign; };
 | 
			
		||||
struct Opts_def_module    { ModuleFlag mflags;  };
 | 
			
		||||
struct Opts_def_namespace { ModuleFlag mflags;  };
 | 
			
		||||
CodeInclude def_include  ( Str content,             Opts_def_include   opts GEN_PARAM_DEFAULT );
 | 
			
		||||
CodeModule  def_module   ( Str name,                Opts_def_module    opts GEN_PARAM_DEFAULT );
 | 
			
		||||
CodeNS      def_namespace( Str name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeInclude def_include  ( Str content,             Opts_def_include   opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeModule  def_module   ( Str name,                Opts_def_module    opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeNS      def_namespace( Str name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_operator {
 | 
			
		||||
	CodeParams      params;
 | 
			
		||||
@@ -119,26 +219,26 @@ struct Opts_def_operator {
 | 
			
		||||
	CodeAttributes  attributes;
 | 
			
		||||
	ModuleFlag      mflags;
 | 
			
		||||
};
 | 
			
		||||
CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_operator_cast {
 | 
			
		||||
	CodeBody       body;
 | 
			
		||||
	CodeSpecifiers specs;
 | 
			
		||||
};
 | 
			
		||||
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_param { Code value; };
 | 
			
		||||
CodeParams  def_param ( CodeTypename type, Str name, Opts_def_param opts GEN_PARAM_DEFAULT );
 | 
			
		||||
CodePragma def_pragma( Str directive );
 | 
			
		||||
GEN_API CodeParams  def_param ( CodeTypename type, Str name, Opts_def_param opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodePragma def_pragma( Str directive );
 | 
			
		||||
 | 
			
		||||
CodePreprocessCond def_preprocess_cond( EPreprocessCond type, Str content );
 | 
			
		||||
GEN_API CodePreprocessCond def_preprocess_cond( EPreprocessCond type, Str content );
 | 
			
		||||
 | 
			
		||||
CodeSpecifiers def_specifier( Specifier specifier );
 | 
			
		||||
GEN_API CodeSpecifiers def_specifier( Specifier specifier );
 | 
			
		||||
 | 
			
		||||
CodeStruct def_struct( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeStruct def_struct( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_template { ModuleFlag mflags; };
 | 
			
		||||
CodeTemplate def_template( CodeParams params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeTemplate def_template( CodeParams params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_type {
 | 
			
		||||
	ETypenameTag   type_tag;
 | 
			
		||||
@@ -146,27 +246,27 @@ struct Opts_def_type {
 | 
			
		||||
	CodeSpecifiers specifiers;
 | 
			
		||||
	CodeAttributes attributes;
 | 
			
		||||
};
 | 
			
		||||
CodeTypename def_type( Str name, Opts_def_type opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeTypename def_type( Str name, Opts_def_type opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_typedef {
 | 
			
		||||
	CodeAttributes attributes;
 | 
			
		||||
	ModuleFlag     mflags;
 | 
			
		||||
};
 | 
			
		||||
CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_union {
 | 
			
		||||
	CodeAttributes attributes;
 | 
			
		||||
	ModuleFlag     mflags;
 | 
			
		||||
};
 | 
			
		||||
CodeUnion def_union( Str name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeUnion def_union( Str name, CodeBody body, Opts_def_union opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_using {
 | 
			
		||||
	CodeAttributes attributes;
 | 
			
		||||
	ModuleFlag     mflags;
 | 
			
		||||
};
 | 
			
		||||
CodeUsing def_using( Str name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API CodeUsing def_using( Str name, CodeTypename type, Opts_def_using opts GEN_PARAM_DEFAULT );
 | 
			
		||||
 | 
			
		||||
CodeUsing def_using_namespace( Str name );
 | 
			
		||||
GEN_API CodeUsing def_using_namespace( Str name );
 | 
			
		||||
 | 
			
		||||
struct Opts_def_variable
 | 
			
		||||
{
 | 
			
		||||
@@ -175,36 +275,53 @@ struct Opts_def_variable
 | 
			
		||||
	CodeAttributes attributes;
 | 
			
		||||
	ModuleFlag     mflags;
 | 
			
		||||
};
 | 
			
		||||
CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable opts GEN_PARAM_DEFAULT );
 | 
			
		||||
GEN_API 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.
 | 
			
		||||
CodeBody def_body( CodeType type );
 | 
			
		||||
GEN_API CodeBody def_body( CodeType type );
 | 
			
		||||
 | 
			
		||||
// There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num,
 | 
			
		||||
/// or provide as an array of Code objects.
 | 
			
		||||
 | 
			
		||||
CodeBody       def_class_body      ( s32 num, ... );
 | 
			
		||||
CodeBody       def_class_body      ( s32 num, Code* codes );
 | 
			
		||||
CodeBody       def_enum_body       ( s32 num, ... );
 | 
			
		||||
CodeBody       def_enum_body       ( s32 num, Code* codes );
 | 
			
		||||
CodeBody       def_export_body     ( s32 num, ... );
 | 
			
		||||
CodeBody       def_export_body     ( s32 num, Code* codes);
 | 
			
		||||
CodeBody       def_extern_link_body( s32 num, ... );
 | 
			
		||||
CodeBody       def_extern_link_body( s32 num, Code* codes );
 | 
			
		||||
CodeBody       def_function_body   ( s32 num, ... );
 | 
			
		||||
CodeBody       def_function_body   ( s32 num, Code* codes );
 | 
			
		||||
CodeBody       def_global_body     ( s32 num, ... );
 | 
			
		||||
CodeBody       def_global_body     ( s32 num, Code* codes );
 | 
			
		||||
CodeBody       def_namespace_body  ( s32 num, ... );
 | 
			
		||||
CodeBody       def_namespace_body  ( s32 num, Code* codes );
 | 
			
		||||
CodeParams     def_params          ( s32 num, ... );
 | 
			
		||||
CodeParams     def_params          ( s32 num, CodeParams* params );
 | 
			
		||||
CodeSpecifiers def_specifiers      ( s32 num, ... );
 | 
			
		||||
CodeSpecifiers def_specifiers      ( s32 num, Specifier* specs );
 | 
			
		||||
CodeBody       def_struct_body     ( s32 num, ... );
 | 
			
		||||
CodeBody       def_struct_body     ( s32 num, Code* codes );
 | 
			
		||||
CodeBody       def_union_body      ( s32 num, ... );
 | 
			
		||||
CodeBody       def_union_body      ( s32 num, Code* codes );
 | 
			
		||||
GEN_API CodeBody         def_class_body           ( s32 num, ... );
 | 
			
		||||
GEN_API CodeBody         def_class_body_arr       ( s32 num, Code* codes );
 | 
			
		||||
GEN_API CodeDefineParams def_define_params        ( s32 num, ... );
 | 
			
		||||
GEN_API CodeDefineParams def_define_params_arr    ( s32 num, CodeDefineParams* codes );
 | 
			
		||||
GEN_API CodeBody         def_enum_body            ( s32 num, ... );
 | 
			
		||||
GEN_API CodeBody         def_enum_body_arr        ( s32 num, Code* codes );
 | 
			
		||||
GEN_API CodeBody         def_export_body          ( s32 num, ... );
 | 
			
		||||
GEN_API CodeBody         def_export_body_arr      ( s32 num, Code* codes);
 | 
			
		||||
GEN_API CodeBody         def_extern_link_body     ( s32 num, ... );
 | 
			
		||||
GEN_API CodeBody         def_extern_link_body_arr ( s32 num, Code* codes );
 | 
			
		||||
GEN_API CodeBody         def_function_body        ( s32 num, ... );
 | 
			
		||||
GEN_API CodeBody         def_function_body_arr    ( s32 num, Code* codes );
 | 
			
		||||
GEN_API CodeBody         def_global_body          ( s32 num, ... );
 | 
			
		||||
GEN_API CodeBody         def_global_body_arr      ( s32 num, Code* codes );
 | 
			
		||||
GEN_API CodeBody         def_namespace_body       ( s32 num, ... );
 | 
			
		||||
GEN_API CodeBody         def_namespace_body_arr   ( s32 num, Code* codes );
 | 
			
		||||
GEN_API CodeParams       def_params               ( s32 num, ... );
 | 
			
		||||
GEN_API CodeParams       def_params_arr           ( s32 num, CodeParams* params );
 | 
			
		||||
GEN_API CodeSpecifiers   def_specifiers           ( s32 num, ... );
 | 
			
		||||
GEN_API CodeSpecifiers   def_specifiers_arr       ( s32 num, Specifier* specs );
 | 
			
		||||
GEN_API CodeBody         def_struct_body          ( s32 num, ... );
 | 
			
		||||
GEN_API CodeBody         def_struct_body_arr      ( s32 num, Code* codes );
 | 
			
		||||
GEN_API CodeBody         def_union_body           ( s32 num, ... );
 | 
			
		||||
GEN_API CodeBody         def_union_body_arr       ( s32 num, Code* codes );
 | 
			
		||||
 | 
			
		||||
#if GEN_COMPILER_CPP
 | 
			
		||||
forceinline CodeBody         def_class_body      ( s32 num, Code* codes )             { return def_class_body_arr(num, codes); }
 | 
			
		||||
forceinline CodeDefineParams def_define_params   ( s32 num, CodeDefineParams* codes ) { return def_define_params_arr(num, codes); }
 | 
			
		||||
forceinline CodeBody         def_enum_body       ( s32 num, Code* codes )             { return def_enum_body_arr(num, codes); }
 | 
			
		||||
forceinline CodeBody         def_export_body     ( s32 num, Code* codes)              { return def_export_body_arr(num, codes); }
 | 
			
		||||
forceinline CodeBody         def_extern_link_body( s32 num, Code* codes )             { return def_extern_link_body_arr(num, codes); }
 | 
			
		||||
forceinline CodeBody         def_function_body   ( s32 num, Code* codes )             { return def_function_body_arr(num, codes); }
 | 
			
		||||
forceinline CodeBody         def_global_body     ( s32 num, Code* codes )             { return def_global_body_arr(num, codes); }
 | 
			
		||||
forceinline CodeBody         def_namespace_body  ( s32 num, Code* codes )             { return def_namespace_body_arr(num, codes); }
 | 
			
		||||
forceinline CodeParams       def_params          ( s32 num, CodeParams* params )      { return def_params_arr(num, params); }
 | 
			
		||||
forceinline CodeSpecifiers   def_specifiers      ( s32 num, Specifier* specs )        { return def_specifiers_arr(num, specs); }
 | 
			
		||||
forceinline CodeBody         def_struct_body     ( s32 num, Code* codes )             { return def_struct_body_arr(num, codes); }
 | 
			
		||||
forceinline CodeBody         def_union_body      ( s32 num, Code* codes )             { return def_union_body_arr(num, codes); }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma endregion Upfront
 | 
			
		||||
 | 
			
		||||
@@ -213,7 +330,6 @@ CodeBody       def_union_body      ( s32 num, Code* codes );
 | 
			
		||||
// TODO(Ed) : Implmeent the new parser API design.
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
GEN_NS_PARSER_BEGIN
 | 
			
		||||
struct StackNode
 | 
			
		||||
{
 | 
			
		||||
	StackNode* Prev;
 | 
			
		||||
@@ -229,7 +345,6 @@ struct Error
 | 
			
		||||
	StrBuilder     message;
 | 
			
		||||
	StackNode* context_stack;
 | 
			
		||||
};
 | 
			
		||||
GEN_NS_PARSER_END
 | 
			
		||||
 | 
			
		||||
struct ParseInfo
 | 
			
		||||
{
 | 
			
		||||
@@ -246,37 +361,38 @@ struct ParseInfo
 | 
			
		||||
CodeBody parse_file( Str path );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
CodeClass       parse_class        ( Str class_def       );
 | 
			
		||||
CodeConstructor parse_constructor  ( Str constructor_def );
 | 
			
		||||
CodeDestructor  parse_destructor   ( Str destructor_def  );
 | 
			
		||||
CodeEnum        parse_enum         ( Str enum_def        );
 | 
			
		||||
CodeBody        parse_export_body  ( Str export_def      );
 | 
			
		||||
CodeExtern      parse_extern_link  ( Str exten_link_def  );
 | 
			
		||||
CodeFriend      parse_friend       ( Str friend_def      );
 | 
			
		||||
CodeFn          parse_function     ( Str fn_def          );
 | 
			
		||||
CodeBody        parse_global_body  ( Str body_def        );
 | 
			
		||||
CodeNS          parse_namespace    ( Str namespace_def   );
 | 
			
		||||
CodeOperator    parse_operator     ( Str operator_def    );
 | 
			
		||||
CodeOpCast      parse_operator_cast( Str operator_def    );
 | 
			
		||||
CodeStruct      parse_struct       ( Str struct_def      );
 | 
			
		||||
CodeTemplate    parse_template     ( Str template_def    );
 | 
			
		||||
CodeTypename    parse_type         ( Str type_def        );
 | 
			
		||||
CodeTypedef     parse_typedef      ( Str typedef_def     );
 | 
			
		||||
CodeUnion       parse_union        ( Str union_def       );
 | 
			
		||||
CodeUsing       parse_using        ( Str using_def       );
 | 
			
		||||
CodeVar         parse_variable     ( Str var_def         );
 | 
			
		||||
GEN_API CodeClass       parse_class        ( Str class_def       );
 | 
			
		||||
GEN_API CodeConstructor parse_constructor  ( Str constructor_def );
 | 
			
		||||
GEN_API CodeDefine      parse_define       ( Str define_def      );
 | 
			
		||||
GEN_API CodeDestructor  parse_destructor   ( Str destructor_def  );
 | 
			
		||||
GEN_API CodeEnum        parse_enum         ( Str enum_def        );
 | 
			
		||||
GEN_API CodeBody        parse_export_body  ( Str export_def      );
 | 
			
		||||
GEN_API CodeExtern      parse_extern_link  ( Str exten_link_def  );
 | 
			
		||||
GEN_API CodeFriend      parse_friend       ( Str friend_def      );
 | 
			
		||||
GEN_API CodeFn          parse_function     ( Str fn_def          );
 | 
			
		||||
GEN_API CodeBody        parse_global_body  ( Str body_def        );
 | 
			
		||||
GEN_API CodeNS          parse_namespace    ( Str namespace_def   );
 | 
			
		||||
GEN_API CodeOperator    parse_operator     ( Str operator_def    );
 | 
			
		||||
GEN_API CodeOpCast      parse_operator_cast( Str operator_def    );
 | 
			
		||||
GEN_API CodeStruct      parse_struct       ( Str struct_def      );
 | 
			
		||||
GEN_API CodeTemplate    parse_template     ( Str template_def    );
 | 
			
		||||
GEN_API CodeTypename    parse_type         ( Str type_def        );
 | 
			
		||||
GEN_API CodeTypedef     parse_typedef      ( Str typedef_def     );
 | 
			
		||||
GEN_API CodeUnion       parse_union        ( Str union_def       );
 | 
			
		||||
GEN_API CodeUsing       parse_using        ( Str using_def       );
 | 
			
		||||
GEN_API CodeVar         parse_variable     ( Str var_def         );
 | 
			
		||||
 | 
			
		||||
#pragma endregion Parsing
 | 
			
		||||
 | 
			
		||||
#pragma region Untyped text
 | 
			
		||||
 | 
			
		||||
ssize   token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va );
 | 
			
		||||
GEN_API 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.
 | 
			
		||||
Str token_fmt_impl( ssize, ... );
 | 
			
		||||
GEN_API Str token_fmt_impl( ssize, ... );
 | 
			
		||||
 | 
			
		||||
Code untyped_str      ( Str content);
 | 
			
		||||
Code untyped_fmt      ( char const* fmt, ... );
 | 
			
		||||
Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
 | 
			
		||||
GEN_API Code untyped_str( Str content);
 | 
			
		||||
GEN_API Code untyped_fmt      ( char const* fmt, ... );
 | 
			
		||||
GEN_API Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
 | 
			
		||||
 | 
			
		||||
#pragma endregion Untyped text
 | 
			
		||||
 | 
			
		||||
@@ -289,12 +405,20 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );
 | 
			
		||||
#ifndef name
 | 
			
		||||
//	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.
 | 
			
		||||
#define name( Id_ )   { stringize(Id_), sizeof(stringize( Id_ )) - 1 }
 | 
			
		||||
#	if GEN_COMPILER_C
 | 
			
		||||
#		define name( Id_ ) (Str){ stringize(Id_), sizeof(stringize( Id_ )) - 1 }
 | 
			
		||||
#	else
 | 
			
		||||
#		define name( Id_ )  Str { stringize(Id_), sizeof(stringize( Id_ )) - 1 }
 | 
			
		||||
#	endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef code
 | 
			
		||||
//  Same as name just used to indicate intention of literal for code instead of names.
 | 
			
		||||
#define code( ... ) { stringize( __VA_ARGS__ ), sizeof(stringize(__VA_ARGS__)) - 1 }
 | 
			
		||||
#	if GEN_COMPILER_C
 | 
			
		||||
#		define code( ... ) (Str){ stringize( __VA_ARGS__ ), sizeof(stringize(__VA_ARGS__)) - 1 }
 | 
			
		||||
#	else
 | 
			
		||||
#		define code( ... )  Str { stringize( __VA_ARGS__ ), sizeof(stringize(__VA_ARGS__)) - 1 }
 | 
			
		||||
#	endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef args
 | 
			
		||||
 
 | 
			
		||||
@@ -10,23 +10,21 @@
 | 
			
		||||
 | 
			
		||||
CodeClass parse_class( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	push_scope();
 | 
			
		||||
	CodeClass result = (CodeClass) parse_class_struct( Tok_Decl_Class, parser_not_inplace_def );
 | 
			
		||||
	parser_pop(& Context);
 | 
			
		||||
	parser_pop(& _ctx->parser);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeConstructor parse_constructor( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
@@ -59,8 +57,8 @@ CodeConstructor parse_constructor( Str def )
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			default :
 | 
			
		||||
				log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(Context) );
 | 
			
		||||
				parser_pop(& Context);
 | 
			
		||||
				log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(_ctx->parser) );
 | 
			
		||||
				parser_pop(& _ctx->parser);
 | 
			
		||||
				return InvalidCode;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -75,18 +73,32 @@ CodeConstructor parse_constructor( Str def )
 | 
			
		||||
 | 
			
		||||
	if ( NumSpecifiers )
 | 
			
		||||
	{
 | 
			
		||||
		specifiers = def_specifiers( NumSpecifiers, specs_found );
 | 
			
		||||
		specifiers = def_specifiers_arr( NumSpecifiers, specs_found );
 | 
			
		||||
		// <specifiers> ...
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Context.Tokens         = toks;
 | 
			
		||||
	_ctx->parser.Tokens         = toks;
 | 
			
		||||
	CodeConstructor result = parser_parse_constructor( specifiers );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeDefine parse_define( Str def )
 | 
			
		||||
{
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	push_scope();
 | 
			
		||||
	CodeDefine result = parser_parse_define();
 | 
			
		||||
	parser_pop(& _ctx->parser);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeDestructor parse_destructor( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
@@ -96,225 +108,209 @@ CodeDestructor parse_destructor( Str def )
 | 
			
		||||
	// TODO(Ed): Destructors can have prefix attributes
 | 
			
		||||
	// TODO(Ed): Destructors can have virtual
 | 
			
		||||
 | 
			
		||||
	Context.Tokens        = toks;
 | 
			
		||||
	_ctx->parser.Tokens        = toks;
 | 
			
		||||
	CodeDestructor result = parser_parse_destructor(NullCode);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeEnum parse_enum( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
	{
 | 
			
		||||
		parser_pop(& Context);
 | 
			
		||||
		parser_pop(& _ctx->parser);
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_enum( parser_not_inplace_def);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeBody parse_export_body( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_export_body();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeExtern parse_extern_link( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_extern_link();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeFriend parse_friend( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_friend();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeFn parse_function( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return (CodeFn) parser_parse_function();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeBody parse_global_body( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	push_scope();
 | 
			
		||||
	CodeBody result = parse_global_nspace( CT_Global_Body );
 | 
			
		||||
	parser_pop(& Context);
 | 
			
		||||
	parser_pop(& _ctx->parser);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeNS parse_namespace( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_namespace();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeOperator parse_operator( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return (CodeOperator) parser_parse_operator();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeOpCast parse_operator_cast( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_operator_cast(NullCode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeStruct parse_struct( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	push_scope();
 | 
			
		||||
	CodeStruct result = (CodeStruct) parse_class_struct( Tok_Decl_Struct, parser_not_inplace_def );
 | 
			
		||||
	parser_pop(& Context);
 | 
			
		||||
	parser_pop(& _ctx->parser);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeTemplate parse_template( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_template();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeTypename parse_type( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_type( parser_not_from_template, nullptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeTypedef parse_typedef( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_typedef();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeUnion parse_union( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_union( parser_not_inplace_def);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeUsing parse_using( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_using();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CodeVar parse_variable( Str def )
 | 
			
		||||
{
 | 
			
		||||
	GEN_USING_NS_PARSER;
 | 
			
		||||
	check_parse_args( def );
 | 
			
		||||
 | 
			
		||||
	TokArray toks = lex( def );
 | 
			
		||||
	if ( toks.Arr == nullptr )
 | 
			
		||||
		return InvalidCode;
 | 
			
		||||
 | 
			
		||||
	Context.Tokens = toks;
 | 
			
		||||
	_ctx->parser.Tokens = toks;
 | 
			
		||||
	return parser_parse_variable();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,24 +8,20 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
 | 
			
		||||
	char const* buf_begin = buf;
 | 
			
		||||
	ssize       remaining = buf_size;
 | 
			
		||||
 | 
			
		||||
	local_persist
 | 
			
		||||
	TokenMap_FixedArena tok_map_arena;
 | 
			
		||||
	fixed_arena_init( & tok_map_arena);
 | 
			
		||||
 | 
			
		||||
	local_persist
 | 
			
		||||
	StringTable tok_map;
 | 
			
		||||
	if (_ctx->token_fmt_map.Hashes == nullptr) {
 | 
			
		||||
		_ctx->token_fmt_map = hashtable_init(Str, _ctx->Allocator_DyanmicContainers );
 | 
			
		||||
	}
 | 
			
		||||
	// Populate token pairs
 | 
			
		||||
	{
 | 
			
		||||
		tok_map = hashtable_init(Str, fixed_arena_allocator_info(& tok_map_arena) );
 | 
			
		||||
 | 
			
		||||
		s32 left = num_tokens - 1;
 | 
			
		||||
 | 
			
		||||
		while ( left-- )
 | 
			
		||||
		{
 | 
			
		||||
			char const* token = va_arg( va, char const* );
 | 
			
		||||
			Str        value = va_arg( va, Str );
 | 
			
		||||
			Str         value = va_arg( va, Str );
 | 
			
		||||
 | 
			
		||||
			u32 key = crc32( token, c_str_len(token) );
 | 
			
		||||
			hashtable_set( tok_map, key, value );
 | 
			
		||||
			hashtable_set( _ctx->token_fmt_map, key, value );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -60,8 +56,8 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
 | 
			
		||||
 | 
			
		||||
			char const* token = fmt + 1;
 | 
			
		||||
 | 
			
		||||
			u32       key   = crc32( token, tok_len );
 | 
			
		||||
			Str*     value = hashtable_get(tok_map, key );
 | 
			
		||||
			u32      key   = crc32( token, tok_len );
 | 
			
		||||
			Str*     value = hashtable_get(_ctx->token_fmt_map, key );
 | 
			
		||||
 | 
			
		||||
			if ( value )
 | 
			
		||||
			{
 | 
			
		||||
@@ -90,12 +86,8 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
 | 
			
		||||
			current = * fmt;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hashtable_clear(tok_map);
 | 
			
		||||
	fixed_arena_free(& tok_map_arena);
 | 
			
		||||
 | 
			
		||||
	hashtable_clear(_ctx->token_fmt_map);
 | 
			
		||||
	ssize result = buf_size - remaining;
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -109,7 +101,7 @@ Code untyped_str( Str content )
 | 
			
		||||
 | 
			
		||||
	Code
 | 
			
		||||
	result          = make_code();
 | 
			
		||||
	result->Name    = get_cached_string( content );
 | 
			
		||||
	result->Name    = cache_str( content );
 | 
			
		||||
	result->Type    = CT_Untyped;
 | 
			
		||||
	result->Content = result->Name;
 | 
			
		||||
 | 
			
		||||
@@ -137,15 +129,12 @@ Code untyped_fmt( char const* fmt, ...)
 | 
			
		||||
	va_start(va, fmt);
 | 
			
		||||
	ssize length = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
 | 
			
		||||
	va_end(va);
 | 
			
		||||
 | 
			
		||||
	Str buf_str      = { fmt, c_str_len_capped(fmt, MaxNameLength) };
 | 
			
		||||
    Str uncapped_str = { buf, length };
 | 
			
		||||
    Str content = { buf, length };
 | 
			
		||||
 | 
			
		||||
	Code
 | 
			
		||||
	result          = make_code();
 | 
			
		||||
	result->Name    = get_cached_string( buf_str );
 | 
			
		||||
	result->Type    = CT_Untyped;
 | 
			
		||||
	result->Content = get_cached_string( uncapped_str );
 | 
			
		||||
	result->Content = cache_str( content );
 | 
			
		||||
 | 
			
		||||
	if ( result->Name.Len == 0 )
 | 
			
		||||
	{
 | 
			
		||||
@@ -176,9 +165,8 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... )
 | 
			
		||||
 | 
			
		||||
	Code
 | 
			
		||||
	result          = make_code();
 | 
			
		||||
	result->Name    = get_cached_string( buf_str );
 | 
			
		||||
	result->Type    = CT_Untyped;
 | 
			
		||||
	result->Content = result->Name;
 | 
			
		||||
	result->Content = cache_str( buf_str );
 | 
			
		||||
 | 
			
		||||
	if ( result->Name.Len == 0 )
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -4,95 +4,9 @@
 | 
			
		||||
#include "gen/etoktype.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GEN_NS_PARSER_BEGIN
 | 
			
		||||
 | 
			
		||||
enum TokFlags : u32
 | 
			
		||||
{
 | 
			
		||||
	TF_Operator		   = bit(0),
 | 
			
		||||
	TF_Assign          = bit(1),
 | 
			
		||||
	TF_Preprocess      = bit(2),
 | 
			
		||||
	TF_Preprocess_Cond = bit(3),
 | 
			
		||||
	TF_Attribute       = bit(6),
 | 
			
		||||
	TF_AccessOperator  = bit( 7 ),
 | 
			
		||||
	TF_AccessSpecifier = bit( 8 ),
 | 
			
		||||
	TF_Specifier       = bit( 9 ),
 | 
			
		||||
	TF_EndDefinition   = bit( 10 ),    // Either ; or }
 | 
			
		||||
	TF_Formatting      = bit( 11 ),
 | 
			
		||||
	TF_Literal         = bit( 12 ),
 | 
			
		||||
 | 
			
		||||
	TF_Null = 0,
 | 
			
		||||
	TF_UnderlyingType = GEN_U32_MAX,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Token
 | 
			
		||||
{
 | 
			
		||||
	Str     Text;
 | 
			
		||||
	TokType Type;
 | 
			
		||||
	s32     Line;
 | 
			
		||||
	s32     Column;
 | 
			
		||||
	u32     Flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
constexpr Token NullToken { nullptr, 0, Tok_Invalid, false, 0, TF_Null };
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
AccessSpec tok_to_access_specifier(Token tok) {
 | 
			
		||||
	return scast(AccessSpec, tok.Type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
Str tok_to_str(Token tok) {
 | 
			
		||||
	return tok.Text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_valid( Token tok ) {
 | 
			
		||||
	return tok.Text.Ptr && tok.Text.Len && tok.Type != Tok_Invalid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_access_operator(Token tok) {
 | 
			
		||||
	return bitfield_is_equal( u32, tok.Flags, TF_AccessOperator );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_access_specifier(Token tok) {
 | 
			
		||||
	return bitfield_is_equal( u32, tok.Flags, TF_AccessSpecifier );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_attribute(Token tok) {
 | 
			
		||||
	return bitfield_is_equal( u32, tok.Flags, TF_Attribute );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_operator(Token tok) {
 | 
			
		||||
	return bitfield_is_equal( u32, tok.Flags, TF_Operator );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_preprocessor(Token tok) {
 | 
			
		||||
	return bitfield_is_equal( u32, tok.Flags, TF_Preprocess );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_preprocess_cond(Token tok) {
 | 
			
		||||
	return bitfield_is_equal( u32, tok.Flags, TF_Preprocess_Cond );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_specifier(Token tok) {
 | 
			
		||||
	return bitfield_is_equal( u32, tok.Flags, TF_Specifier );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_end_definition(Token tok) {
 | 
			
		||||
	return bitfield_is_equal( u32, tok.Flags, TF_EndDefinition );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StrBuilder tok_to_strbuilder(Token tok)
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder result   = strbuilder_make_reserve( GlobalAllocator, kilobytes(4) );
 | 
			
		||||
	StrBuilder result   = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(4) );
 | 
			
		||||
	Str        type_str = toktype_to_str( tok.Type );
 | 
			
		||||
 | 
			
		||||
	strbuilder_append_fmt( & result, "Line: %d Column: %d, Type: %.*s Content: %.*s"
 | 
			
		||||
@@ -103,12 +17,6 @@ StrBuilder tok_to_strbuilder(Token tok)
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct TokArray 
 | 
			
		||||
{
 | 
			
		||||
	Array(Token) Arr;
 | 
			
		||||
	s32          Idx;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool lex__eat( TokArray* self, TokType type );
 | 
			
		||||
 | 
			
		||||
Token* lex_current(TokArray* self, bool skip_formatting )
 | 
			
		||||
@@ -160,27 +68,12 @@ Token* lex_next(TokArray self, bool skip_formatting)
 | 
			
		||||
	return & self.Arr[idx + 1];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
global FixedArena_256KB Lexer_defines_map_arena;
 | 
			
		||||
global StringTable      Lexer_defines;
 | 
			
		||||
global Array(Token)     Lexer_Tokens;
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
	Lex_Continue,
 | 
			
		||||
	Lex_ReturnNull,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct LexContext
 | 
			
		||||
{
 | 
			
		||||
	Str             content;
 | 
			
		||||
	s32             left;
 | 
			
		||||
	char const*     scanner;
 | 
			
		||||
	s32             line;
 | 
			
		||||
	s32             column;
 | 
			
		||||
	StringTable     defines;
 | 
			
		||||
	Token           token;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
void lexer_move_forward( LexContext* ctx )
 | 
			
		||||
{
 | 
			
		||||
@@ -219,12 +112,164 @@ void lexer_end_line( LexContext* ctx )
 | 
			
		||||
}
 | 
			
		||||
#define end_line() lexer_end_line(ctx)
 | 
			
		||||
 | 
			
		||||
// TODO(Ed): We need to to attempt to recover from a lex failure?
 | 
			
		||||
s32 lex_preprocessor_define( LexContext* ctx )
 | 
			
		||||
{
 | 
			
		||||
	Token name = { { ctx->scanner, 1 }, Tok_Identifier, ctx->line, ctx->column, TF_Preprocess };
 | 
			
		||||
	move_forward();
 | 
			
		||||
 | 
			
		||||
	while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) {
 | 
			
		||||
		move_forward();
 | 
			
		||||
		name.Text.Len++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Specifier spec    = str_to_specifier( name.Text );
 | 
			
		||||
	TokType   attrib  = str_to_toktype( name.Text );
 | 
			
		||||
	b32 not_specifier = spec   == Spec_Invalid;
 | 
			
		||||
	b32 not_attribute = attrib <= Tok___Attributes_Start;
 | 
			
		||||
 | 
			
		||||
	Macro  macro            = { name.Text, MT_Expression, (MacroFlags)0 };
 | 
			
		||||
	Macro* registered_macro = lookup_macro(name.Text);
 | 
			
		||||
 | 
			
		||||
	if ( registered_macro == nullptr && not_specifier && not_attribute ) {
 | 
			
		||||
		log_fmt("Warning: '%S' was not registered before the lexer processed its #define directive, it will be registered as a expression macro\n"
 | 
			
		||||
			, name.Text 
 | 
			
		||||
		);
 | 
			
		||||
		// GEN_DEBUG_TRAP();
 | 
			
		||||
	}
 | 
			
		||||
	array_append( _ctx->Lexer_Tokens, name );
 | 
			
		||||
 | 
			
		||||
	if ( ctx->left && (* ctx->scanner) == '(' )
 | 
			
		||||
	{
 | 
			
		||||
		if (registered_macro && ! macro_is_functional(* registered_macro)) {
 | 
			
		||||
			log_fmt("Warning: %S registered macro is not flagged as functional yet the definition detects opening parenthesis '(' for arguments\n"
 | 
			
		||||
				, name.Text
 | 
			
		||||
			);
 | 
			
		||||
			// GEN_DEBUG_TRAP();
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			macro.Flags |= MF_Functional;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Token opening_paren = { { ctx->scanner, 1 }, Tok_Paren_Open, ctx->line, ctx->column, TF_Preprocess };
 | 
			
		||||
		array_append( _ctx->Lexer_Tokens, opening_paren );
 | 
			
		||||
		move_forward();
 | 
			
		||||
 | 
			
		||||
		Token last_parameter = {};
 | 
			
		||||
		// We need to tokenize the define's arguments now:
 | 
			
		||||
		while( ctx->left && * ctx->scanner != ')')
 | 
			
		||||
		{
 | 
			
		||||
			skip_whitespace();
 | 
			
		||||
			
 | 
			
		||||
			Str possible_varadic = { ctx->scanner, 3 };
 | 
			
		||||
			if ( ctx->left > 3 && str_are_equal( txt("..."), possible_varadic ) ) {
 | 
			
		||||
				Token parameter = { { ctx->scanner, 3 }, Tok_Preprocess_Define_Param, ctx->line, ctx->column, TF_Preprocess };
 | 
			
		||||
				move_forward();
 | 
			
		||||
				move_forward();
 | 
			
		||||
				move_forward();
 | 
			
		||||
 | 
			
		||||
				array_append(_ctx->Lexer_Tokens, parameter);
 | 
			
		||||
				skip_whitespace();
 | 
			
		||||
				last_parameter = parameter;
 | 
			
		||||
 | 
			
		||||
				while ( (* ctx->scanner) == '\\' ) {
 | 
			
		||||
					move_forward();
 | 
			
		||||
					skip_whitespace();
 | 
			
		||||
				}
 | 
			
		||||
				if (* ctx->scanner != ')' )
 | 
			
		||||
				{
 | 
			
		||||
					log_failure("lex_preprocessor_define(%d, %d): Expected a ')' after '...' (varaidc macro param) %S\n"
 | 
			
		||||
						, ctx->line
 | 
			
		||||
						, ctx->column
 | 
			
		||||
						, name.Text
 | 
			
		||||
					);
 | 
			
		||||
					return Lex_ReturnNull;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			else if ( (* ctx->scanner) == '\\' ) {
 | 
			
		||||
				move_forward();
 | 
			
		||||
				skip_whitespace();
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			else if ( char_is_alpha( (* ctx->scanner) ) || (* ctx->scanner) == '_' )
 | 
			
		||||
			{
 | 
			
		||||
				Token parameter = { { ctx->scanner, 1 }, Tok_Preprocess_Define_Param, ctx->line, ctx->column, TF_Preprocess };
 | 
			
		||||
				move_forward();
 | 
			
		||||
 | 
			
		||||
				while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
 | 
			
		||||
				{
 | 
			
		||||
					move_forward();
 | 
			
		||||
					parameter.Text.Len++;
 | 
			
		||||
				}
 | 
			
		||||
				array_append(_ctx->Lexer_Tokens, parameter);
 | 
			
		||||
				skip_whitespace();
 | 
			
		||||
				last_parameter = parameter;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				log_failure("lex_preprocessor_define(%d, %d): Expected a '_' or alpha character for a parameter name for %S\n"
 | 
			
		||||
					, ctx->line
 | 
			
		||||
					, ctx->column
 | 
			
		||||
					, name.Text
 | 
			
		||||
				);
 | 
			
		||||
				return Lex_ReturnNull;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (* ctx->scanner == ')' )
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			// There should be a comma
 | 
			
		||||
			if ( * ctx->scanner != ',' ) {
 | 
			
		||||
				log_failure("lex_preprocessor_define(%d, %d): Expected a comma after parameter %S for %S\n"
 | 
			
		||||
					, ctx->line
 | 
			
		||||
					, ctx->column
 | 
			
		||||
					, last_parameter.Text
 | 
			
		||||
					, name.Text
 | 
			
		||||
				);
 | 
			
		||||
				return Lex_ReturnNull;
 | 
			
		||||
			}
 | 
			
		||||
			Token comma = { { ctx->scanner, 1 }, Tok_Comma, ctx->line, ctx->column, TF_Preprocess };
 | 
			
		||||
			array_append(_ctx->Lexer_Tokens, comma);
 | 
			
		||||
			move_forward();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if ( * ctx->scanner != ')' ) {
 | 
			
		||||
			log_failure("lex_preprocessor_define(%d, %d): Expected a ')' after last_parameter %S for %S (ran out of characters...)\n"
 | 
			
		||||
				, ctx->line
 | 
			
		||||
				, ctx->column
 | 
			
		||||
				, last_parameter.Text
 | 
			
		||||
				, name.Text
 | 
			
		||||
			);
 | 
			
		||||
			return Lex_ReturnNull;
 | 
			
		||||
		}
 | 
			
		||||
		Token closing_paren = { { ctx->scanner, 1 }, Tok_Paren_Close, ctx->line, ctx->column, TF_Preprocess };
 | 
			
		||||
		array_append(_ctx->Lexer_Tokens, closing_paren);
 | 
			
		||||
		move_forward();
 | 
			
		||||
	}
 | 
			
		||||
	else if ( registered_macro && macro_is_functional( * registered_macro) ) {
 | 
			
		||||
		if (registered_macro && ! macro_is_functional(* registered_macro)) {
 | 
			
		||||
			log_fmt("Warning: %S registered macro is flagged as functional yet the definition detects no opening parenthesis '(' for arguments\n"
 | 
			
		||||
				, name.Text
 | 
			
		||||
			);
 | 
			
		||||
			GEN_DEBUG_TRAP();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( registered_macro == nullptr ) {
 | 
			
		||||
		register_macro(macro);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Define's content handled by lex_preprocessor_directive (the original caller of this)
 | 
			
		||||
	return Lex_Continue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO(Ed): We need to to attempt to recover from a lex failure?
 | 
			
		||||
forceinline
 | 
			
		||||
s32 lex_preprocessor_directive( LexContext* ctx )
 | 
			
		||||
{
 | 
			
		||||
	char const* hash = ctx->scanner;
 | 
			
		||||
	Token hash_tok = { { hash, 1 }, Tok_Preprocess_Hash, ctx->line, ctx->column, TF_Preprocess };
 | 
			
		||||
	array_append( Lexer_Tokens, hash_tok  );
 | 
			
		||||
	array_append( _ctx->Lexer_Tokens, hash_tok  );
 | 
			
		||||
 | 
			
		||||
	move_forward();
 | 
			
		||||
	skip_whitespace();
 | 
			
		||||
@@ -300,14 +345,14 @@ s32 lex_preprocessor_directive( LexContext* ctx )
 | 
			
		||||
 | 
			
		||||
		ctx->token.Text.Len = ctx->token.Text.Len + ctx->token.Text.Ptr - hash;
 | 
			
		||||
		ctx->token.Text.Ptr = hash;
 | 
			
		||||
		array_append( Lexer_Tokens, ctx->token );
 | 
			
		||||
		array_append( _ctx->Lexer_Tokens, ctx->token );
 | 
			
		||||
		return Lex_Continue; // Skip found token, its all handled here.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( ctx->token.Type == Tok_Preprocess_Else || ctx->token.Type == Tok_Preprocess_EndIf )
 | 
			
		||||
	{
 | 
			
		||||
		ctx->token.Flags |= TF_Preprocess_Cond;
 | 
			
		||||
		array_append( Lexer_Tokens, ctx->token );
 | 
			
		||||
		array_append( _ctx->Lexer_Tokens, ctx->token );
 | 
			
		||||
		end_line();
 | 
			
		||||
		return Lex_Continue;
 | 
			
		||||
	}
 | 
			
		||||
@@ -316,34 +361,15 @@ s32 lex_preprocessor_directive( LexContext* ctx )
 | 
			
		||||
		ctx->token.Flags |= TF_Preprocess_Cond;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	array_append( Lexer_Tokens, ctx->token );
 | 
			
		||||
	array_append( _ctx->Lexer_Tokens, ctx->token );
 | 
			
		||||
 | 
			
		||||
	skip_whitespace();
 | 
			
		||||
 | 
			
		||||
	if ( ctx->token.Type == Tok_Preprocess_Define )
 | 
			
		||||
	{
 | 
			
		||||
		Token name = { { ctx->scanner, 0 }, Tok_Identifier, ctx->line, ctx->column, TF_Preprocess };
 | 
			
		||||
 | 
			
		||||
		name.Text.Ptr = ctx->scanner;
 | 
			
		||||
		name.Text.Len = 1;
 | 
			
		||||
		move_forward();
 | 
			
		||||
 | 
			
		||||
		while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
 | 
			
		||||
		{
 | 
			
		||||
			move_forward();
 | 
			
		||||
			name.Text.Len++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ( ctx->left && (* ctx->scanner) == '(' )
 | 
			
		||||
		{
 | 
			
		||||
			move_forward();
 | 
			
		||||
			name.Text.Len++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		array_append( Lexer_Tokens, name );
 | 
			
		||||
 | 
			
		||||
		u64 key = crc32( name.Text.Ptr, name.Text.Len );
 | 
			
		||||
		hashtable_set(ctx->defines, key, tok_to_str(name) );
 | 
			
		||||
		u32 result = lex_preprocessor_define(ctx); // handles: #define <name>( <params> ) - define's content handled later on within this scope.
 | 
			
		||||
		if (result != Lex_Continue)
 | 
			
		||||
			return Lex_ReturnNull;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Token preprocess_content = { { ctx->scanner, 0 }, Tok_Preprocess_Content, ctx->line, ctx->column, TF_Preprocess };
 | 
			
		||||
@@ -354,7 +380,7 @@ s32 lex_preprocessor_directive( LexContext* ctx )
 | 
			
		||||
 | 
			
		||||
		if ( (* ctx->scanner) != '"' && (* ctx->scanner) != '<' )
 | 
			
		||||
		{
 | 
			
		||||
			StrBuilder directive_str = strbuilder_fmt_buf( GlobalAllocator, "%.*s", min( 80, ctx->left + preprocess_content.Text.Len ), ctx->token.Text.Ptr );
 | 
			
		||||
			StrBuilder directive_str = strbuilder_fmt_buf( _ctx->Allocator_Temp, "%.*s", min( 80, ctx->left + preprocess_content.Text.Len ), ctx->token.Text.Ptr );
 | 
			
		||||
 | 
			
		||||
			log_failure( "gen::Parser::lex: Expected '\"' or '<' after #include, not '%c' (%d, %d)\n%s"
 | 
			
		||||
				, (* ctx->scanner)
 | 
			
		||||
@@ -386,14 +412,14 @@ s32 lex_preprocessor_directive( LexContext* ctx )
 | 
			
		||||
			move_forward();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		array_append( Lexer_Tokens, preprocess_content );
 | 
			
		||||
		array_append( _ctx->Lexer_Tokens, preprocess_content );
 | 
			
		||||
		return Lex_Continue; // Skip found token, its all handled here.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s32 within_string = false;
 | 
			
		||||
	s32 within_char   = false;
 | 
			
		||||
 | 
			
		||||
	// SkipWhitespace();
 | 
			
		||||
	// Consume preprocess content
 | 
			
		||||
	while ( ctx->left )
 | 
			
		||||
	{
 | 
			
		||||
		if ( (* ctx->scanner) == '"' && ! within_char )
 | 
			
		||||
@@ -421,14 +447,15 @@ s32 lex_preprocessor_directive( LexContext* ctx )
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				StrBuilder directive_str = strbuilder_make_length( GlobalAllocator, ctx->token.Text.Ptr, ctx->token.Text.Len );
 | 
			
		||||
				StrBuilder content_str   = strbuilder_fmt_buf( GlobalAllocator, "%.*s", min( 400, ctx->left + preprocess_content.Text.Len ), preprocess_content.Text.Ptr );
 | 
			
		||||
				StrBuilder directive_str = strbuilder_make_length( _ctx->Allocator_Temp, ctx->token.Text.Ptr, ctx->token.Text.Len );
 | 
			
		||||
				StrBuilder content_str   = strbuilder_fmt_buf( _ctx->Allocator_Temp, "%.*s", min( 400, ctx->left + preprocess_content.Text.Len ), preprocess_content.Text.Ptr );
 | 
			
		||||
 | 
			
		||||
				log_failure( "gen::Parser::lex: Invalid escape sequence '\\%c' (%d, %d)"
 | 
			
		||||
							" in preprocessor directive '%s' (%d, %d)\n%s"
 | 
			
		||||
					, (* ctx->scanner), ctx->line, ctx->column
 | 
			
		||||
					, directive_str, preprocess_content.Line, preprocess_content.Column
 | 
			
		||||
					, content_str );
 | 
			
		||||
				return Lex_ReturnNull;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -449,117 +476,90 @@ s32 lex_preprocessor_directive( LexContext* ctx )
 | 
			
		||||
		preprocess_content.Text.Len++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	array_append( Lexer_Tokens, preprocess_content );
 | 
			
		||||
	array_append( _ctx->Lexer_Tokens, preprocess_content );
 | 
			
		||||
	return Lex_Continue; // Skip found token, its all handled here.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
void lex_found_token( LexContext* ctx )
 | 
			
		||||
{
 | 
			
		||||
	if ( ctx->token.Type != Tok_Invalid )
 | 
			
		||||
	{
 | 
			
		||||
		array_append( Lexer_Tokens, ctx->token );
 | 
			
		||||
	if ( ctx->token.Type != Tok_Invalid ) {
 | 
			
		||||
		array_append( _ctx->Lexer_Tokens, ctx->token );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	TokType type = str_to_toktype( tok_to_str(ctx->token) );
 | 
			
		||||
 | 
			
		||||
	if (type <= Tok_Access_Public && type >= Tok_Access_Private )
 | 
			
		||||
	{
 | 
			
		||||
	if (type <= Tok_Access_Public && type >= Tok_Access_Private ) {
 | 
			
		||||
		ctx->token.Flags |= TF_AccessSpecifier;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( type > Tok___Attributes_Start )
 | 
			
		||||
	{
 | 
			
		||||
	if ( type > Tok___Attributes_Start ) {
 | 
			
		||||
		ctx->token.Flags |= TF_Attribute;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( type == Tok_Decl_Extern_Linkage )
 | 
			
		||||
	{
 | 
			
		||||
		skip_whitespace();
 | 
			
		||||
 | 
			
		||||
		if ( (* ctx->scanner) != '"' )
 | 
			
		||||
		{
 | 
			
		||||
		if ( (* ctx->scanner) != '"' ) {
 | 
			
		||||
			type         = Tok_Spec_Extern;
 | 
			
		||||
			ctx->token.Flags |= TF_Specifier;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ctx->token.Type = type;
 | 
			
		||||
		array_append( Lexer_Tokens, ctx->token );
 | 
			
		||||
		array_append( _ctx->Lexer_Tokens, ctx->token );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( ( type <= Tok_Star && type >= Tok_Spec_Alignas)
 | 
			
		||||
			|| type == Tok_Ampersand
 | 
			
		||||
			|| type == Tok_Ampersand_DBL )
 | 
			
		||||
	{
 | 
			
		||||
		ctx->token.Type   = type;
 | 
			
		||||
		ctx->token.Flags |= TF_Specifier;
 | 
			
		||||
		array_append( Lexer_Tokens, ctx->token );
 | 
			
		||||
		array_append( _ctx->Lexer_Tokens, ctx->token );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if ( type != Tok_Invalid )
 | 
			
		||||
	{
 | 
			
		||||
		ctx->token.Type = type;
 | 
			
		||||
		array_append( Lexer_Tokens, ctx->token );
 | 
			
		||||
		array_append( _ctx->Lexer_Tokens, ctx->token );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	u64 key = 0;
 | 
			
		||||
	if ( (* ctx->scanner) == '(')
 | 
			
		||||
		key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len + 1 );
 | 
			
		||||
	else
 | 
			
		||||
		key = crc32( ctx->token.Text.Ptr, ctx->token.Text.Len );
 | 
			
		||||
 | 
			
		||||
	Str* define = hashtable_get(ctx->defines, key );
 | 
			
		||||
	if ( define )
 | 
			
		||||
	{
 | 
			
		||||
		ctx->token.Type = Tok_Preprocess_Macro;
 | 
			
		||||
 | 
			
		||||
		// Want to ignore any arguments the define may have as they can be execution expressions.
 | 
			
		||||
		if ( ctx->left && (* ctx->scanner) == '(' )
 | 
			
		||||
		{
 | 
			
		||||
			move_forward();
 | 
			
		||||
			ctx->token.Text.Len++;
 | 
			
		||||
 | 
			
		||||
			s32 level = 0;
 | 
			
		||||
			while ( ctx->left && ((* ctx->scanner) != ')' || level > 0) )
 | 
			
		||||
			{
 | 
			
		||||
				if ( (* ctx->scanner) == '(' )
 | 
			
		||||
					level++;
 | 
			
		||||
 | 
			
		||||
				else if ( (* ctx->scanner) == ')' && level > 0 )
 | 
			
		||||
					level--;
 | 
			
		||||
 | 
			
		||||
				move_forward();
 | 
			
		||||
				ctx->token.Text.Len++;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			move_forward();
 | 
			
		||||
			ctx->token.Text.Len++;
 | 
			
		||||
	Macro* macro = lookup_macro( ctx->token.Text );
 | 
			
		||||
	b32 has_args          = ctx->left && (* ctx->scanner) == '(';
 | 
			
		||||
	b32 resolved_to_macro = false;
 | 
			
		||||
	if (macro) {
 | 
			
		||||
		ctx->token.Type   = macrotype_to_toktype(macro->Type);
 | 
			
		||||
		b32 is_functional = macro_is_functional(* macro);
 | 
			
		||||
		resolved_to_macro = has_args ? is_functional : ! is_functional;
 | 
			
		||||
		if ( ! resolved_to_macro && GEN_BUILD_DEBUG ) {
 | 
			
		||||
			log_fmt("Info(%d, %d): %S identified as a macro but usage here does not resolve to one (interpreting as identifier)\n"
 | 
			
		||||
				, ctx->token.Line
 | 
			
		||||
				, ctx->token.Line
 | 
			
		||||
				, macro->Name
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if ( resolved_to_macro )
 | 
			
		||||
	{
 | 
			
		||||
		// TODO(Ed): When we introduce a macro AST (and expression support), we'll properly lex this section.
 | 
			
		||||
		// Want to ignore any arguments the define may have as they can be execution expressions.
 | 
			
		||||
		if ( has_args ) {
 | 
			
		||||
			ctx->token.Flags |= TF_Macro_Functional;
 | 
			
		||||
		}
 | 
			
		||||
		if ( bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Attribute) ) {
 | 
			
		||||
			ctx->token.Flags |= TF_Attribute;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//if ( (* ctx->scanner) == '\r' && ctx->scanner[1] == '\n' )
 | 
			
		||||
		//{
 | 
			
		||||
		//	move_forward();
 | 
			
		||||
		//	ctx->token..Text.Length++;
 | 
			
		||||
		//}
 | 
			
		||||
		//else if ( (* ctx->scanner) == '\n' )
 | 
			
		||||
		//{
 | 
			
		||||
		//	move_forward();
 | 
			
		||||
		//	ctx->token..Text.Length++;
 | 
			
		||||
		//}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		ctx->token.Type = Tok_Identifier;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	array_append( Lexer_Tokens, ctx->token );
 | 
			
		||||
	array_append( _ctx->Lexer_Tokens, ctx->token );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO(Ed): We need to to attempt to recover from a lex failure?
 | 
			
		||||
neverinline
 | 
			
		||||
// TokArray lex( Array<Token> tokens, Str content )
 | 
			
		||||
TokArray lex( Str content )
 | 
			
		||||
@@ -568,7 +568,6 @@ TokArray lex( Str content )
 | 
			
		||||
	c.content = content;
 | 
			
		||||
	c.left    = content.Len;
 | 
			
		||||
	c.scanner = content.Ptr;
 | 
			
		||||
	c.defines = Lexer_defines;
 | 
			
		||||
 | 
			
		||||
	char const* word        = c.scanner;
 | 
			
		||||
	s32         word_length = 0;
 | 
			
		||||
@@ -584,25 +583,9 @@ TokArray lex( Str content )
 | 
			
		||||
		return null_array;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for ( StringCached* entry = array_begin(PreprocessorDefines); entry != array_end(PreprocessorDefines); entry = array_next(PreprocessorDefines, entry))
 | 
			
		||||
	{
 | 
			
		||||
		s32         length  = 0;
 | 
			
		||||
		char const* entry_scanner = (*entry).Ptr;
 | 
			
		||||
		while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') )
 | 
			
		||||
		{
 | 
			
		||||
			entry_scanner++;
 | 
			
		||||
			length ++;
 | 
			
		||||
		}
 | 
			
		||||
		if ( entry_scanner[0] == '(' )
 | 
			
		||||
		{
 | 
			
		||||
			length++;
 | 
			
		||||
		}
 | 
			
		||||
	array_clear(_ctx->Lexer_Tokens);
 | 
			
		||||
 | 
			
		||||
		u64 key = crc32( entry->Ptr, length );
 | 
			
		||||
		hashtable_set(c.defines, key, * entry );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	array_clear(Lexer_Tokens);
 | 
			
		||||
	b32 preprocess_args = true;
 | 
			
		||||
 | 
			
		||||
	while (c.left )
 | 
			
		||||
	{
 | 
			
		||||
@@ -635,7 +618,7 @@ TokArray lex( Str content )
 | 
			
		||||
				c.token.Type = Tok_NewLine;
 | 
			
		||||
				c.token.Text.Len++;
 | 
			
		||||
 | 
			
		||||
				array_append( Lexer_Tokens, c.token );
 | 
			
		||||
				array_append( _ctx->Lexer_Tokens, c.token );
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -674,7 +657,7 @@ TokArray lex( Str content )
 | 
			
		||||
								c.token.Text.Len++;
 | 
			
		||||
								move_forward();
 | 
			
		||||
 | 
			
		||||
								array_append( Lexer_Tokens, c.token );
 | 
			
		||||
								array_append( _ctx->Lexer_Tokens, c.token );
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						continue;
 | 
			
		||||
@@ -710,7 +693,7 @@ TokArray lex( Str content )
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						StrBuilder context_str = strbuilder_fmt_buf( GlobalAllocator, "%s", c.scanner, min( 100, c.left ) );
 | 
			
		||||
						StrBuilder context_str = strbuilder_fmt_buf( _ctx->Allocator_Temp, "%s", c.scanner, min( 100, c.left ) );
 | 
			
		||||
 | 
			
		||||
						log_failure( "gen::lex: invalid varadic argument, expected '...' got '..%c' (%d, %d)\n%s", (* ctx->scanner), c.line, c.column, context_str );
 | 
			
		||||
					}
 | 
			
		||||
@@ -814,7 +797,7 @@ TokArray lex( Str content )
 | 
			
		||||
			{
 | 
			
		||||
				Str text = { c.scanner, 1 };
 | 
			
		||||
				c.token.Text   = text;
 | 
			
		||||
				c.token.Type   = Tok_Capture_Start;
 | 
			
		||||
				c.token.Type   = Tok_Paren_Open;
 | 
			
		||||
 | 
			
		||||
				if (c.left)
 | 
			
		||||
					move_forward();
 | 
			
		||||
@@ -824,7 +807,7 @@ TokArray lex( Str content )
 | 
			
		||||
			{
 | 
			
		||||
				Str text = { c.scanner, 1 };
 | 
			
		||||
				c.token.Text   = text;
 | 
			
		||||
				c.token.Type   = Tok_Capture_End;
 | 
			
		||||
				c.token.Type   = Tok_Paren_Close;
 | 
			
		||||
 | 
			
		||||
				if (c.left)
 | 
			
		||||
					move_forward();
 | 
			
		||||
@@ -1045,7 +1028,7 @@ TokArray lex( Str content )
 | 
			
		||||
				goto FoundToken;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Dash is unfortunatlly a bit more complicated...
 | 
			
		||||
			// Dash is unfortunately a bit more complicated...
 | 
			
		||||
			case '-':
 | 
			
		||||
			{
 | 
			
		||||
				Str text = { c.scanner, 1 };
 | 
			
		||||
@@ -1131,7 +1114,7 @@ TokArray lex( Str content )
 | 
			
		||||
							move_forward();
 | 
			
		||||
							c.token.Text.Len++;
 | 
			
		||||
						}
 | 
			
		||||
						array_append( Lexer_Tokens, c.token );
 | 
			
		||||
						array_append( _ctx->Lexer_Tokens, c.token );
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					else if ( (* ctx->scanner) == '*' )
 | 
			
		||||
@@ -1167,7 +1150,7 @@ TokArray lex( Str content )
 | 
			
		||||
							move_forward();
 | 
			
		||||
							c.token.Text.Len++;
 | 
			
		||||
						}
 | 
			
		||||
						array_append( Lexer_Tokens, c.token );
 | 
			
		||||
						array_append( _ctx->Lexer_Tokens, c.token );
 | 
			
		||||
						// end_line();
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
@@ -1182,8 +1165,7 @@ TokArray lex( Str content )
 | 
			
		||||
			c.token.Text = text;
 | 
			
		||||
			move_forward();
 | 
			
		||||
 | 
			
		||||
			while ( c.left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
 | 
			
		||||
			{
 | 
			
		||||
			while ( c.left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) {
 | 
			
		||||
				move_forward();
 | 
			
		||||
				c.token.Text.Len++;
 | 
			
		||||
			}
 | 
			
		||||
@@ -1209,8 +1191,7 @@ TokArray lex( Str content )
 | 
			
		||||
				move_forward();
 | 
			
		||||
				c.token.Text.Len++;
 | 
			
		||||
 | 
			
		||||
				while ( c.left && char_is_hex_digit((* ctx->scanner)) )
 | 
			
		||||
				{
 | 
			
		||||
				while ( c.left && char_is_hex_digit((* ctx->scanner)) ) {
 | 
			
		||||
					move_forward();
 | 
			
		||||
					c.token.Text.Len++;
 | 
			
		||||
				}
 | 
			
		||||
@@ -1218,8 +1199,7 @@ TokArray lex( Str content )
 | 
			
		||||
				goto FoundToken;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			while ( c.left && char_is_digit((* ctx->scanner)) )
 | 
			
		||||
			{
 | 
			
		||||
			while ( c.left && char_is_digit((* ctx->scanner)) ) {
 | 
			
		||||
				move_forward();
 | 
			
		||||
				c.token.Text.Len++;
 | 
			
		||||
			}
 | 
			
		||||
@@ -1229,8 +1209,7 @@ TokArray lex( Str content )
 | 
			
		||||
				move_forward();
 | 
			
		||||
				c.token.Text.Len++;
 | 
			
		||||
 | 
			
		||||
				while ( c.left && char_is_digit((* ctx->scanner)) )
 | 
			
		||||
				{
 | 
			
		||||
				while ( c.left && char_is_digit((* ctx->scanner)) ) {
 | 
			
		||||
					move_forward();
 | 
			
		||||
					c.token.Text.Len++;
 | 
			
		||||
				}
 | 
			
		||||
@@ -1248,8 +1227,7 @@ TokArray lex( Str content )
 | 
			
		||||
					c.token.Text.Len++;
 | 
			
		||||
 | 
			
		||||
					// Handle 'll'/'LL' as a special case when we just processed an 'l'/'L'
 | 
			
		||||
					if (c.left && (prev == 'l' || prev == 'L') && ((* ctx->scanner) == 'l' || (* ctx->scanner) == 'L'))
 | 
			
		||||
					{
 | 
			
		||||
					if (c.left && (prev == 'l' || prev == 'L') && ((* ctx->scanner) == 'l' || (* ctx->scanner) == 'L')) {
 | 
			
		||||
						move_forward();
 | 
			
		||||
						c.token.Text.Len++;
 | 
			
		||||
					}
 | 
			
		||||
@@ -1260,23 +1238,22 @@ TokArray lex( Str content )
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			s32 start = max( 0, array_num(Lexer_Tokens) - 100 );
 | 
			
		||||
			s32 start = max( 0, array_num(_ctx->Lexer_Tokens) - 100 );
 | 
			
		||||
			log_fmt("\n%d\n", start);
 | 
			
		||||
			for ( s32 idx = start; idx < array_num(Lexer_Tokens); idx++ )
 | 
			
		||||
			for ( s32 idx = start; idx < array_num(_ctx->Lexer_Tokens); idx++ )
 | 
			
		||||
			{
 | 
			
		||||
				log_fmt( "Token %d Type: %s : %.*s\n"
 | 
			
		||||
					, idx
 | 
			
		||||
					, toktype_to_str( Lexer_Tokens[ idx ].Type ).Ptr
 | 
			
		||||
					, Lexer_Tokens[ idx ].Text.Len, Lexer_Tokens[ idx ].Text.Ptr
 | 
			
		||||
					, toktype_to_str( _ctx->Lexer_Tokens[ idx ].Type ).Ptr
 | 
			
		||||
					, _ctx->Lexer_Tokens[ idx ].Text.Len, _ctx->Lexer_Tokens[ idx ].Text.Ptr
 | 
			
		||||
				);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			StrBuilder context_str = strbuilder_fmt_buf( GlobalAllocator, "%.*s", min( 100, c.left ), c.scanner );
 | 
			
		||||
			StrBuilder context_str = strbuilder_fmt_buf( _ctx->Allocator_Temp, "%.*s", min( 100, c.left ), c.scanner );
 | 
			
		||||
			log_failure( "Failed to lex token '%c' (%d, %d)\n%s", (* ctx->scanner), c.line, c.column, context_str );
 | 
			
		||||
 | 
			
		||||
			// Skip to next whitespace since we can't know if anything else is valid until then.
 | 
			
		||||
			while ( c.left && ! char_is_space( (* ctx->scanner) ) )
 | 
			
		||||
			{
 | 
			
		||||
			while ( c.left && ! char_is_space( (* ctx->scanner) ) ) {
 | 
			
		||||
				move_forward();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -1284,46 +1261,38 @@ TokArray lex( Str content )
 | 
			
		||||
		FoundToken:
 | 
			
		||||
		{
 | 
			
		||||
			lex_found_token( ctx );
 | 
			
		||||
			TokType last_type = array_back(Lexer_Tokens)->Type;
 | 
			
		||||
			if ( last_type == Tok_Preprocess_Macro )
 | 
			
		||||
			TokType last_type = array_back(_ctx->Lexer_Tokens)->Type;
 | 
			
		||||
			if ( last_type == Tok_Preprocess_Macro_Stmt || last_type == Tok_Preprocess_Macro_Expr )
 | 
			
		||||
			{
 | 
			
		||||
				Token thanks_c = { { c.scanner, 0 }, Tok_Invalid, c.line, c.column, TF_Null };
 | 
			
		||||
				c.token = thanks_c;
 | 
			
		||||
				if ( (* ctx->scanner) == '\r')
 | 
			
		||||
				{
 | 
			
		||||
				if ( (* ctx->scanner) == '\r') {
 | 
			
		||||
					move_forward();
 | 
			
		||||
					c.token.Text.Len = 1;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if ( (* ctx->scanner) == '\n' )
 | 
			
		||||
				if ( (* ctx->scanner) == '\n' ) 
 | 
			
		||||
				{
 | 
			
		||||
					c.token.Type = Tok_NewLine;
 | 
			
		||||
					c.token.Text.Len++;
 | 
			
		||||
					move_forward();
 | 
			
		||||
 | 
			
		||||
					array_append( Lexer_Tokens, c.token );
 | 
			
		||||
					array_append( _ctx->Lexer_Tokens, c.token );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( array_num(Lexer_Tokens) == 0 )
 | 
			
		||||
	{
 | 
			
		||||
	if ( array_num(_ctx->Lexer_Tokens) == 0 ) {
 | 
			
		||||
		log_failure( "Failed to lex any tokens" );
 | 
			
		||||
		{
 | 
			
		||||
			TokArray tok_array =  {};
 | 
			
		||||
			return tok_array;
 | 
			
		||||
		}
 | 
			
		||||
		TokArray tok_array =  {};
 | 
			
		||||
		return tok_array;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hashtable_clear(Lexer_defines);
 | 
			
		||||
	// defines_map_arena.free();
 | 
			
		||||
	TokArray result = { Lexer_Tokens, 0 };
 | 
			
		||||
	TokArray result = { _ctx->Lexer_Tokens, 0 };
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef move_forward
 | 
			
		||||
#undef skip_whitespace
 | 
			
		||||
#undef end_line
 | 
			
		||||
 | 
			
		||||
GEN_NS_PARSER_END
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										105
									
								
								base/components/parser_case_macros.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								base/components/parser_case_macros.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
// These macros are used in the swtich cases within parser.cpp
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_TOK_SPECIFIERS_CASES \
 | 
			
		||||
case Tok_Spec_Consteval:   \
 | 
			
		||||
case Tok_Spec_Constexpr:   \
 | 
			
		||||
case Tok_Spec_Constinit:   \
 | 
			
		||||
case Tok_Spec_Explicit:    \
 | 
			
		||||
case Tok_Spec_ForceInline: \
 | 
			
		||||
case Tok_Spec_Inline:      \
 | 
			
		||||
case Tok_Spec_Mutable:     \
 | 
			
		||||
case Tok_Spec_NeverInline: \
 | 
			
		||||
case Tok_Spec_Static:      \
 | 
			
		||||
case Tok_Spec_Volatile:    \
 | 
			
		||||
case Tok_Spec_Virtual
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Constexpr:   \
 | 
			
		||||
case Spec_Constinit:   \
 | 
			
		||||
case Spec_Explicit:    \
 | 
			
		||||
case Spec_Inline:      \
 | 
			
		||||
case Spec_ForceInline: \
 | 
			
		||||
case Spec_Mutable:     \
 | 
			
		||||
case Spec_NeverInline: \
 | 
			
		||||
case Spec_Static:      \
 | 
			
		||||
case Spec_Volatile:    \
 | 
			
		||||
case Spec_Virtual
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
 | 
			
		||||
case Tok_Spec_Consteval:        \
 | 
			
		||||
case Tok_Spec_Constexpr:        \
 | 
			
		||||
case Tok_Spec_Constinit:        \
 | 
			
		||||
case Tok_Spec_Extern:           \
 | 
			
		||||
case Tok_Spec_ForceInline:      \
 | 
			
		||||
case Tok_Spec_Global:           \
 | 
			
		||||
case Tok_Spec_Inline:           \
 | 
			
		||||
case Tok_Spec_Internal_Linkage: \
 | 
			
		||||
case Tok_Spec_NeverInline:      \
 | 
			
		||||
case Tok_Spec_Static
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIER_CASES \
 | 
			
		||||
case Spec_Constexpr:        \
 | 
			
		||||
case Spec_Constinit:        \
 | 
			
		||||
case Spec_ForceInline:      \
 | 
			
		||||
case Spec_Global:           \
 | 
			
		||||
case Spec_External_Linkage: \
 | 
			
		||||
case Spec_Internal_Linkage: \
 | 
			
		||||
case Spec_Inline:           \
 | 
			
		||||
case Spec_Mutable:          \
 | 
			
		||||
case Spec_NeverInline:      \
 | 
			
		||||
case Spec_Static:           \
 | 
			
		||||
case Spec_Volatile
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_FRIEND_ALLOWED_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Const:       \
 | 
			
		||||
case Spec_Inline:      \
 | 
			
		||||
case Spec_ForceInline
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_FUNCTION_ALLOWED_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Const:            \
 | 
			
		||||
case Spec_Consteval:        \
 | 
			
		||||
case Spec_Constexpr:        \
 | 
			
		||||
case Spec_External_Linkage: \
 | 
			
		||||
case Spec_Internal_Linkage: \
 | 
			
		||||
case Spec_ForceInline:      \
 | 
			
		||||
case Spec_Inline:           \
 | 
			
		||||
case Spec_NeverInline:      \
 | 
			
		||||
case Spec_Static
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_OPERATOR_ALLOWED_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Const:       \
 | 
			
		||||
case Spec_Constexpr:   \
 | 
			
		||||
case Spec_ForceInline: \
 | 
			
		||||
case Spec_Inline:      \
 | 
			
		||||
case Spec_NeverInline: \
 | 
			
		||||
case Spec_Static
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_TEMPLATE_ALLOWED_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Const:            \
 | 
			
		||||
case Spec_Constexpr:        \
 | 
			
		||||
case Spec_Constinit:        \
 | 
			
		||||
case Spec_External_Linkage: \
 | 
			
		||||
case Spec_Global:           \
 | 
			
		||||
case Spec_Inline:           \
 | 
			
		||||
case Spec_ForceInline:      \
 | 
			
		||||
case Spec_Local_Persist:    \
 | 
			
		||||
case Spec_Mutable:          \
 | 
			
		||||
case Spec_Static:           \
 | 
			
		||||
case Spec_Thread_Local:     \
 | 
			
		||||
case Spec_Volatile
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_VARIABLE_ALLOWED_SPECIFIER_CASES \
 | 
			
		||||
case Spec_Const:            \
 | 
			
		||||
case Spec_Constexpr:        \
 | 
			
		||||
case Spec_Constinit:        \
 | 
			
		||||
case Spec_External_Linkage: \
 | 
			
		||||
case Spec_Global:           \
 | 
			
		||||
case Spec_Inline:           \
 | 
			
		||||
case Spec_Local_Persist:    \
 | 
			
		||||
case Spec_Mutable:          \
 | 
			
		||||
case Spec_Static:           \
 | 
			
		||||
case Spec_Thread_Local:     \
 | 
			
		||||
case Spec_Volatile
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										225
									
								
								base/components/parser_types.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								base/components/parser_types.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,225 @@
 | 
			
		||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "types.hpp"
 | 
			
		||||
#include "gen/ecode.hpp"
 | 
			
		||||
#include "gen/eoperator.hpp"
 | 
			
		||||
#include "gen/especifier.hpp"
 | 
			
		||||
#include "gen/etoktype.hpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
enum TokFlags : u32
 | 
			
		||||
{
 | 
			
		||||
	TF_Operator              = bit(0),
 | 
			
		||||
	TF_Assign                = bit(1),
 | 
			
		||||
	TF_Preprocess            = bit(2),
 | 
			
		||||
	TF_Preprocess_Cond       = bit(3),
 | 
			
		||||
	TF_Attribute             = bit(6),
 | 
			
		||||
	TF_AccessOperator        = bit(7),
 | 
			
		||||
	TF_AccessSpecifier       = bit(8),
 | 
			
		||||
	TF_Specifier             = bit(9),
 | 
			
		||||
	TF_EndDefinition         = bit(10),    // Either ; or }
 | 
			
		||||
	TF_Formatting            = bit(11),
 | 
			
		||||
	TF_Literal               = bit(12),
 | 
			
		||||
	TF_Macro_Functional      = bit(13),
 | 
			
		||||
	TF_Macro_Expects_Body    = bit(14),
 | 
			
		||||
 | 
			
		||||
	TF_Null = 0,
 | 
			
		||||
	TF_UnderlyingType = GEN_U32_MAX,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Token
 | 
			
		||||
{
 | 
			
		||||
	Str     Text;
 | 
			
		||||
	TokType Type;
 | 
			
		||||
	s32     Line;
 | 
			
		||||
	s32     Column;
 | 
			
		||||
	u32     Flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
constexpr Token NullToken { {}, Tok_Invalid, 0, 0, TF_Null };
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
AccessSpec tok_to_access_specifier(Token tok) {
 | 
			
		||||
	return scast(AccessSpec, tok.Type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
Str tok_to_str(Token tok) {
 | 
			
		||||
	return tok.Text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_valid( Token tok ) {
 | 
			
		||||
	return tok.Text.Ptr && tok.Text.Len && tok.Type != Tok_Invalid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_access_operator(Token tok) {
 | 
			
		||||
	return bitfield_is_set( u32, tok.Flags, TF_AccessOperator );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_access_specifier(Token tok) {
 | 
			
		||||
	return bitfield_is_set( u32, tok.Flags, TF_AccessSpecifier );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_attribute(Token tok) {
 | 
			
		||||
	return bitfield_is_set( u32, tok.Flags, TF_Attribute );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_operator(Token tok) {
 | 
			
		||||
	return bitfield_is_set( u32, tok.Flags, TF_Operator );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_preprocessor(Token tok) {
 | 
			
		||||
	return bitfield_is_set( u32, tok.Flags, TF_Preprocess );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_preprocess_cond(Token tok) {
 | 
			
		||||
	return bitfield_is_set( u32, tok.Flags, TF_Preprocess_Cond );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_specifier(Token tok) {
 | 
			
		||||
	return bitfield_is_set( u32, tok.Flags, TF_Specifier );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
bool tok_is_end_definition(Token tok) {
 | 
			
		||||
	return bitfield_is_set( u32, tok.Flags, TF_EndDefinition );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StrBuilder tok_to_strbuilder(Token tok);
 | 
			
		||||
 | 
			
		||||
struct TokArray 
 | 
			
		||||
{
 | 
			
		||||
	Array(Token) Arr;
 | 
			
		||||
	s32          Idx;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct LexContext
 | 
			
		||||
{
 | 
			
		||||
	Str             content;
 | 
			
		||||
	s32             left;
 | 
			
		||||
	char const*     scanner;
 | 
			
		||||
	s32             line;
 | 
			
		||||
	s32             column;
 | 
			
		||||
	// StringTable     defines;
 | 
			
		||||
	Token           token;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct StackNode
 | 
			
		||||
{
 | 
			
		||||
	StackNode* Prev;
 | 
			
		||||
 | 
			
		||||
	Token* Start;
 | 
			
		||||
	Str    Name;          // The name of the AST node (if parsed)
 | 
			
		||||
	Str    ProcName;    // The name of the procedure
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ParseContext
 | 
			
		||||
{
 | 
			
		||||
	TokArray   Tokens;
 | 
			
		||||
	StackNode* Scope;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum MacroType : u16
 | 
			
		||||
{
 | 
			
		||||
	MT_Expression,     // A macro is assumed to be a expression if not resolved.
 | 
			
		||||
	MT_Statement,      
 | 
			
		||||
	MT_Typename,
 | 
			
		||||
	MT_Attribute,      // More of a note to the parser than anythign else (attributes should be defined in the user attribues def).
 | 
			
		||||
	MT_Specifier,      // More of a note to the parser than anythign else (specifiers should be defined in the user attribues def).
 | 
			
		||||
	MT_Block_Start,    // Not Supported yet
 | 
			
		||||
	MT_Block_End,      // Not Supported yet
 | 
			
		||||
	MT_Case_Statement, // Not Supported yet
 | 
			
		||||
 | 
			
		||||
	MT_UnderlyingType = GEN_U16_MAX,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
TokType macrotype_to_toktype( MacroType type ) {
 | 
			
		||||
	switch ( type ) {
 | 
			
		||||
		case MT_Statement  : return Tok_Preprocess_Macro_Stmt;
 | 
			
		||||
		case MT_Expression : return Tok_Preprocess_Macro_Expr;
 | 
			
		||||
		case MT_Typename   : return Tok_Preprocess_Macro_Typename;
 | 
			
		||||
	}
 | 
			
		||||
	// All others unsupported for now.
 | 
			
		||||
	return Tok_Invalid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
Str macrotype_to_str( MacroType type )
 | 
			
		||||
{
 | 
			
		||||
	local_persist
 | 
			
		||||
	Str lookup[] = {
 | 
			
		||||
		{ "Statement",        sizeof("Statement")        - 1 },
 | 
			
		||||
		{ "Expression",       sizeof("Expression")       - 1 },
 | 
			
		||||
		{ "Typename",         sizeof("Typename")         - 1 },
 | 
			
		||||
		{ "Attribute(Macro)", sizeof("Attribute(Macro)") - 1 },
 | 
			
		||||
		{ "Specifier(Macro)", sizeof("Specifier(Macro)") - 1 },
 | 
			
		||||
		{ "Block_Start",      sizeof("Block_Start")      - 1 },
 | 
			
		||||
		{ "Block_End",        sizeof("Block_End")        - 1 },
 | 
			
		||||
		{ "Case_Statement",   sizeof("Case_Statement")   - 1 },
 | 
			
		||||
	};
 | 
			
		||||
	local_persist
 | 
			
		||||
	Str invalid = { "Invalid", sizeof("Invalid") };
 | 
			
		||||
	if ( type > MT_Case_Statement )
 | 
			
		||||
		return invalid;
 | 
			
		||||
 | 
			
		||||
	return lookup[ type ];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum EMacroFlags : u16
 | 
			
		||||
{
 | 
			
		||||
	MF_Functional          = bit(0), // Macro has parameters (args expected to be passed)
 | 
			
		||||
	MF_Expects_Body        = bit(1), // Expects to assign a braced scope to its body.
 | 
			
		||||
 | 
			
		||||
	// lex__eat wil treat this macro as an identifier if the parser attempts to consume it as one.
 | 
			
		||||
	//  ^^^ This is a kludge because we don't support push/pop macro pragmas rn.
 | 
			
		||||
	MF_Allow_As_Identifier = bit(2), 
 | 
			
		||||
 | 
			
		||||
	// lex__eat wil treat this macro as an attribute if the parser attempts to consume it as one.
 | 
			
		||||
	//  ^^^ This a kludge because unreal has a macro that behaves as both a 'statement' and an attribute (UE_DEPRECATED, PRAGMA_ENABLE_DEPRECATION_WARNINGS, etc)
 | 
			
		||||
	// TODO(Ed): We can keep the MF_Allow_As_Attribute flag for macros, however, we need to add the ability of AST_Attributes to chain themselves.
 | 
			
		||||
	// Its thats already a thing in the standard language anyway
 | 
			
		||||
	// & it would allow UE_DEPRECATED, (UE_PROPERTY / UE_FUNCTION) to chain themselves as attributes of a resolved member function/varaible definition
 | 
			
		||||
	MF_Allow_As_Attribute  = bit(3),
 | 
			
		||||
 | 
			
		||||
	// When a macro is encountered after attributs and specifiers while parsing a function, or variable:
 | 
			
		||||
	// It will consume the macro and treat it as resolving the definition. (Yes this is for Unreal Engine)
 | 
			
		||||
	// (MUST BE OF MT_Statement TYPE)
 | 
			
		||||
	MF_Allow_As_Definition = bit(4),
 | 
			
		||||
 | 
			
		||||
	MF_Null           = 0,
 | 
			
		||||
	MF_UnderlyingType = GEN_U16_MAX,
 | 
			
		||||
};
 | 
			
		||||
typedef u16 MacroFlags;
 | 
			
		||||
 | 
			
		||||
struct Macro
 | 
			
		||||
{
 | 
			
		||||
	StrCached  Name;
 | 
			
		||||
	MacroType  Type;
 | 
			
		||||
	MacroFlags Flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
b32 macro_is_functional( Macro macro ) {
 | 
			
		||||
	return bitfield_is_set( b16, macro.Flags, MF_Functional );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
b32 macro_expects_body( Macro macro ) {
 | 
			
		||||
	return bitfield_is_set( b16, macro.Flags, MF_Expects_Body );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
 | 
			
		||||
forceinline b32 is_functional( Macro macro ) { return bitfield_is_set( b16, macro.Flags, MF_Functional ); }
 | 
			
		||||
forceinline b32 expects_body ( Macro macro ) { return bitfield_is_set( b16, macro.Flags, MF_Expects_Body ); }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef HashTable(Macro) MacroTable;
 | 
			
		||||
@@ -4,31 +4,14 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma region StaticData
 | 
			
		||||
 | 
			
		||||
// TODO : Convert global allocation strategy to use a slab allocation strategy.
 | 
			
		||||
global AllocatorInfo  GlobalAllocator;
 | 
			
		||||
global Array( Arena )   Global_AllocatorBuckets;
 | 
			
		||||
 | 
			
		||||
// TODO(Ed) : Make the code pool a dynamic arena
 | 
			
		||||
global Array( Pool )  CodePools         = { nullptr };
 | 
			
		||||
global Array( Arena ) StringArenas      = { nullptr };
 | 
			
		||||
 | 
			
		||||
global StringTable StringCache;
 | 
			
		||||
 | 
			
		||||
global Arena LexArena;
 | 
			
		||||
 | 
			
		||||
global AllocatorInfo Allocator_DataArrays  = {0};
 | 
			
		||||
global AllocatorInfo Allocator_CodePool    = {0};
 | 
			
		||||
global AllocatorInfo Allocator_Lexer       = {0};
 | 
			
		||||
global AllocatorInfo Allocator_StringArena = {0};
 | 
			
		||||
global AllocatorInfo Allocator_StringTable = {0};
 | 
			
		||||
global AllocatorInfo Allocator_TypeTable   = {0};
 | 
			
		||||
 | 
			
		||||
#pragma endregion StaticData
 | 
			
		||||
global Context* _ctx;
 | 
			
		||||
global u32      context_counter;
 | 
			
		||||
 | 
			
		||||
#pragma region Constants
 | 
			
		||||
global Macro enum_underlying_macro;
 | 
			
		||||
 | 
			
		||||
global Str enum_underlying_sig;
 | 
			
		||||
global Code Code_Global;
 | 
			
		||||
global Code Code_Invalid;
 | 
			
		||||
 | 
			
		||||
global Code access_public;
 | 
			
		||||
global Code access_protected;
 | 
			
		||||
@@ -84,8 +67,6 @@ global CodeTypename t_wchar_t;
 | 
			
		||||
global CodeTypename t_class;
 | 
			
		||||
global CodeTypename t_typename;
 | 
			
		||||
 | 
			
		||||
global Array(StringCached) PreprocessorDefines;
 | 
			
		||||
 | 
			
		||||
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
 | 
			
		||||
global CodeTypename t_b32;
 | 
			
		||||
 | 
			
		||||
@@ -107,3 +88,5 @@ global CodeTypename t_f64;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#pragma endregion Constants
 | 
			
		||||
 | 
			
		||||
#pragma endregion StaticData
 | 
			
		||||
 
 | 
			
		||||
@@ -143,13 +143,14 @@ Array<Type> array_init_reserve(AllocatorInfo allocator, ssize capacity)
 | 
			
		||||
	return {rcast(Type*, header + 1)};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
forceinline
 | 
			
		||||
usize array_grow_formula(ssize value) {
 | 
			
		||||
	return 2 * value + 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class Type> inline
 | 
			
		||||
bool array_append_array(Array<Type>* array, Array<Type> other) {
 | 
			
		||||
	return array_append_items(array, (Type*)other, num(other));
 | 
			
		||||
	return array_append_items(array, (Type*)other, array_num(other));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class Type> inline
 | 
			
		||||
@@ -179,13 +180,13 @@ bool array_append_items(Array<Type>* array, Type* items, usize item_num)
 | 
			
		||||
	GEN_ASSERT(* array != nullptr);
 | 
			
		||||
	GEN_ASSERT(items != nullptr);
 | 
			
		||||
	GEN_ASSERT(item_num > 0);
 | 
			
		||||
	ArrayHeader* header = array_get_header(array);
 | 
			
		||||
	ArrayHeader* header = array_get_header(* array);
 | 
			
		||||
 | 
			
		||||
	if (header->Num + item_num > header->Capacity)
 | 
			
		||||
	{
 | 
			
		||||
		if ( ! grow(array, header->Capacity + item_num))
 | 
			
		||||
		if ( ! array_grow(array, header->Capacity + item_num))
 | 
			
		||||
			return false;
 | 
			
		||||
		header = array_get_header(array);
 | 
			
		||||
		header = array_get_header(* array);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mem_copy((Type*)array + header->Num, items, item_num * sizeof(Type));
 | 
			
		||||
@@ -202,7 +203,7 @@ bool array_append_at(Array<Type>* array, Type item, usize idx)
 | 
			
		||||
	ArrayHeader* header = array_get_header(* array);
 | 
			
		||||
 | 
			
		||||
	ssize slot = idx;
 | 
			
		||||
	if (slot >= header->Num)
 | 
			
		||||
	if (slot >= (ssize)(header->Num))
 | 
			
		||||
		slot = header->Num - 1;
 | 
			
		||||
 | 
			
		||||
	if (slot < 0)
 | 
			
		||||
@@ -281,10 +282,9 @@ bool array_fill(Array<Type> array, usize begin, usize end, Type value)
 | 
			
		||||
	ArrayHeader* header = array_get_header(array);
 | 
			
		||||
 | 
			
		||||
	if (begin < 0 || end > header->Num)
 | 
			
		||||
	return false;
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	for (ssize idx = ssize(begin); idx < ssize(end); idx++)
 | 
			
		||||
	{
 | 
			
		||||
	for (ssize idx = ssize(begin); idx < ssize(end); idx++) {
 | 
			
		||||
		array[idx] = value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -354,7 +354,6 @@ bool array_reserve(Array<Type>* array, usize new_capacity)
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT(  array != nullptr);
 | 
			
		||||
	GEN_ASSERT(* array != nullptr);
 | 
			
		||||
	GEN_ASSERT(num > 0)
 | 
			
		||||
	ArrayHeader* header = array_get_header(array);
 | 
			
		||||
 | 
			
		||||
	if (header->Capacity < new_capacity)
 | 
			
		||||
@@ -754,7 +753,7 @@ HashTableFindResult hashtable__find(HashTable<Type> table, u64 key)
 | 
			
		||||
			if (table.Entries[result.EntryIndex].Key == key)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			result.PrevIndex = result.EntryIndex;
 | 
			
		||||
			result.PrevIndex  = result.EntryIndex;
 | 
			
		||||
			result.EntryIndex = table.Entries[result.EntryIndex].Next;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -763,7 +762,7 @@ HashTableFindResult hashtable__find(HashTable<Type> table, u64 key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename Type> forceinline
 | 
			
		||||
bool hashtable_full(HashTable<Type> table) {
 | 
			
		||||
b32 hashtable_full(HashTable<Type> table) {
 | 
			
		||||
	GEN_ASSERT_NOT_NULL(table.Hashes);
 | 
			
		||||
	GEN_ASSERT_NOT_NULL(table.Entries);
 | 
			
		||||
	usize critical_load = usize(HashTable_CriticalLoadScale * f32(array_num(table.Hashes)));
 | 
			
		||||
 
 | 
			
		||||
@@ -11,10 +11,10 @@
 | 
			
		||||
#if GEN_BUILD_DEBUG
 | 
			
		||||
#	if defined( GEN_COMPILER_MSVC )
 | 
			
		||||
#		if _MSC_VER < 1300
 | 
			
		||||
#pragma message("GEN_BUILD_DEBUG: __asm int 3")
 | 
			
		||||
// #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()")
 | 
			
		||||
// #pragma message("GEN_BUILD_DEBUG: __debugbreak()")
 | 
			
		||||
#			define GEN_DEBUG_TRAP() __debugbreak()
 | 
			
		||||
#		endif
 | 
			
		||||
#	elif defined( GEN_COMPILER_TINYC )
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
#		define GEN_DEBUG_TRAP() __builtin_trap()
 | 
			
		||||
#	endif
 | 
			
		||||
#else
 | 
			
		||||
#pragma message("GEN_BUILD_DEBUG: omitted")
 | 
			
		||||
// #pragma message("GEN_BUILD_DEBUG: omitted")
 | 
			
		||||
#	define GEN_DEBUG_TRAP()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -44,7 +44,7 @@
 | 
			
		||||
// NOTE: Things that shouldn't happen with a message!
 | 
			
		||||
#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
 | 
			
		||||
 | 
			
		||||
#if GEN_BULD_DEBUG
 | 
			
		||||
#if GEN_BUILD_DEBUG
 | 
			
		||||
	#define GEN_FATAL( ... )                               \
 | 
			
		||||
	do                                                     \
 | 
			
		||||
	{                                                      \
 | 
			
		||||
 
 | 
			
		||||
@@ -284,7 +284,7 @@ GEN_FILE_OPEN_PROC( _posix_file_open )
 | 
			
		||||
 | 
			
		||||
internal void _dirinfo_free_entry( DirEntry* entry );
 | 
			
		||||
 | 
			
		||||
// TODO : Is this a bad idea?
 | 
			
		||||
// TODO(zpl) : Is this a bad idea?
 | 
			
		||||
global b32      _std_file_set                     = false;
 | 
			
		||||
global FileInfo _std_files[ EFileStandard_COUNT ] = {
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,24 @@
 | 
			
		||||
 | 
			
		||||
#pragma region Macros
 | 
			
		||||
 | 
			
		||||
#if GEN_COMPILER_MSVC
 | 
			
		||||
    #ifdef GEN_DYN_LINK
 | 
			
		||||
        #ifdef GEN_DYN_EXPORT
 | 
			
		||||
            #define GEN_API __declspec(dllexport)
 | 
			
		||||
        #else
 | 
			
		||||
            #define GEN_API __declspec(dllimport)
 | 
			
		||||
        #endif
 | 
			
		||||
    #else
 | 
			
		||||
        #define GEN_API  // Empty for static builds
 | 
			
		||||
    #endif
 | 
			
		||||
#else
 | 
			
		||||
    #ifdef GEN_DYN_LINK
 | 
			
		||||
        #define GEN_API __attribute__((visibility("default")))
 | 
			
		||||
    #else
 | 
			
		||||
        #define GEN_API  // Empty for static builds
 | 
			
		||||
    #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef global
 | 
			
		||||
#define global        static    // Global variables
 | 
			
		||||
#endif
 | 
			
		||||
@@ -16,8 +34,8 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef bit
 | 
			
		||||
#define bit( Value )                             ( 1 << Value )
 | 
			
		||||
#define bitfield_is_equal( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) )
 | 
			
		||||
#define bit( Value )                         ( 1 << Value )
 | 
			
		||||
#define bitfield_is_set( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Mainly intended for forcing the base library to utilize only C-valid constructs or type coercion
 | 
			
		||||
@@ -68,8 +86,16 @@
 | 
			
		||||
#define stringize( ... )    stringize_va( __VA_ARGS__ )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define src_line_str stringize(__LINE__)
 | 
			
		||||
 | 
			
		||||
#ifndef do_once
 | 
			
		||||
#define do_once( statement ) for ( local_persist b32 once = true; once; once = false, (statement) )
 | 
			
		||||
#define do_once()                                                                            \
 | 
			
		||||
	local_persist int __do_once_counter_##src_line_str  = 0;                                 \
 | 
			
		||||
    for(;      __do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1 ) \
 | 
			
		||||
 | 
			
		||||
#define do_once_defer( expression )                                                                 \
 | 
			
		||||
    local_persist int __do_once_counter_##src_line_str  = 0;                                        \
 | 
			
		||||
    for(;__do_once_counter_##src_line_str != 1; __do_once_counter_##src_line_str = 1, (expression)) \
 | 
			
		||||
 | 
			
		||||
#define do_once_start      \
 | 
			
		||||
	do                     \
 | 
			
		||||
@@ -224,9 +250,9 @@
 | 
			
		||||
#	if ! GEN_COMPILER_C
 | 
			
		||||
#		define typeof decltype
 | 
			
		||||
#	elif defined(_MSC_VER)
 | 
			
		||||
#		define typeof(x) __typeof__(x)
 | 
			
		||||
#		define typeof __typeof__
 | 
			
		||||
#	elif defined(__GNUC__) || defined(__clang__)
 | 
			
		||||
#		define typeof(x) __typeof__(x)
 | 
			
		||||
#		define typeof __typeof__
 | 
			
		||||
#	else
 | 
			
		||||
#		error "Compiler not supported"
 | 
			
		||||
#	endif
 | 
			
		||||
 
 | 
			
		||||
@@ -346,25 +346,25 @@ void* arena_allocator_proc( void* allocator_data, AllocType type, ssize size, ss
 | 
			
		||||
	switch ( type )
 | 
			
		||||
	{
 | 
			
		||||
		case EAllocation_ALLOC :
 | 
			
		||||
		{
 | 
			
		||||
			void* end        = pointer_add( arena->PhysicalStart, arena->TotalUsed );
 | 
			
		||||
			ssize total_size = align_forward_s64( size, alignment );
 | 
			
		||||
 | 
			
		||||
			// NOTE: Out of memory
 | 
			
		||||
			if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize )
 | 
			
		||||
			{
 | 
			
		||||
				void* end        = pointer_add( arena->PhysicalStart, arena->TotalUsed );
 | 
			
		||||
				ssize total_size = align_forward_s64( size, alignment );
 | 
			
		||||
 | 
			
		||||
				// NOTE: Out of memory
 | 
			
		||||
				if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize )
 | 
			
		||||
				{
 | 
			
		||||
					// zpl__printf_err("%s", "Arena out of memory\n");
 | 
			
		||||
					GEN_FATAL("Arena out of memory! (Possibly could not fit for the largest size Arena!!)");
 | 
			
		||||
					return nullptr;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				ptr              = align_forward( end, alignment );
 | 
			
		||||
				arena->TotalUsed += total_size;
 | 
			
		||||
 | 
			
		||||
				if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
 | 
			
		||||
					zero_size( ptr, size );
 | 
			
		||||
				// zpl__printf_err("%s", "Arena out of memory\n");
 | 
			
		||||
				GEN_FATAL("Arena out of memory! (Possibly could not fit for the largest size Arena!!)");
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			ptr              = align_forward( end, alignment );
 | 
			
		||||
			arena->TotalUsed += total_size;
 | 
			
		||||
 | 
			
		||||
			if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
 | 
			
		||||
				zero_size( ptr, size );
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case EAllocation_FREE :
 | 
			
		||||
			// NOTE: Free all at once
 | 
			
		||||
 
 | 
			
		||||
@@ -225,11 +225,10 @@ forceinline ssize         size_remaining(Arena& arena, ssize alignment) { return
 | 
			
		||||
// This id is defined by Unreal for asserts
 | 
			
		||||
#pragma push_macro("check")
 | 
			
		||||
#undef check
 | 
			
		||||
forceinline void check(Arena& arena) { return arena_check(& arena); };
 | 
			
		||||
forceinline void check(Arena& arena) { return arena_check(& arena); }
 | 
			
		||||
#pragma pop_macro("check")
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
AllocatorInfo arena_allocator_info( Arena* arena ) {
 | 
			
		||||
	GEN_ASSERT(arena != nullptr);
 | 
			
		||||
@@ -392,9 +391,9 @@ void          pool_clear(Pool* pool);
 | 
			
		||||
void          pool_free(Pool* pool);
 | 
			
		||||
 | 
			
		||||
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
 | 
			
		||||
AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
 | 
			
		||||
void          clear(Pool& pool)          { return pool_clear(& pool); }
 | 
			
		||||
void          free(Pool& pool)           { return pool_free(& pool); }
 | 
			
		||||
forceinline AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }
 | 
			
		||||
forceinline void          clear(Pool& pool)          { return pool_clear(& pool); }
 | 
			
		||||
forceinline void          free(Pool& pool)           { return pool_free(& pool); }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct Pool
 | 
			
		||||
 
 | 
			
		||||
@@ -143,27 +143,15 @@
 | 
			
		||||
 | 
			
		||||
#if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C
 | 
			
		||||
#	if GEN_COMPILER_C
 | 
			
		||||
#		define GEN_NS_PARSER_BEGIN
 | 
			
		||||
#		define GEN_NS_PARSER_END
 | 
			
		||||
#		define GEN_USING_NS_PARSER
 | 
			
		||||
#		define GEN_NS_PARSER
 | 
			
		||||
#		define GEN_NS
 | 
			
		||||
#		define GEN_NS_BEGIN
 | 
			
		||||
#		define GEN_NS_END
 | 
			
		||||
#	else
 | 
			
		||||
#		define GEN_NS_PARSER_BEGIN namespace parser {
 | 
			
		||||
#		define GEN_NS_PARSER_END   }
 | 
			
		||||
#		define GEN_USING_NS_PARSER using namespace parser
 | 
			
		||||
#		define GEN_NS_PARSER       parser::
 | 
			
		||||
#		define GEN_NS              ::
 | 
			
		||||
#		define GEN_NS_BEGIN
 | 
			
		||||
#		define GEN_NS_END
 | 
			
		||||
#	endif
 | 
			
		||||
#else
 | 
			
		||||
#	define GEN_NS_PARSER_BEGIN namespace parser {
 | 
			
		||||
#	define GEN_NS_PARSER_END   }
 | 
			
		||||
#	define GEN_NS_PARSER       parser::
 | 
			
		||||
#	define GEN_USING_NS_PARSER using namespace parser
 | 
			
		||||
#	define GEN_NS              gen::
 | 
			
		||||
#	define GEN_NS_BEGIN        namespace gen {
 | 
			
		||||
#	define GEN_NS_END          }
 | 
			
		||||
 
 | 
			
		||||
@@ -40,9 +40,9 @@ struct Str
 | 
			
		||||
 | 
			
		||||
#ifndef txt
 | 
			
		||||
#	if GEN_COMPILER_CPP
 | 
			
		||||
#		define txt( text )          Str { ( text ), sizeof( text ) - 1 }
 | 
			
		||||
#		define txt( text )          GEN_NS Str { ( text ), sizeof( text ) - 1 }
 | 
			
		||||
#	else
 | 
			
		||||
#		define txt( text )         (Str){ ( text ), sizeof( text ) - 1 }
 | 
			
		||||
#		define txt( text )         (GEN_NS Str){ ( text ), sizeof( text ) - 1 }
 | 
			
		||||
#	endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -392,6 +392,7 @@ bool strbuilder_append_string(StrBuilder* str, StrBuilder const other) {
 | 
			
		||||
	return strbuilder_append_c_str_len(str, (char const*)other, strbuilder_length(other));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
bool strbuilder_append_fmt(StrBuilder* str, char const* fmt, ...) {
 | 
			
		||||
	GEN_ASSERT(str != nullptr);
 | 
			
		||||
	ssize res;
 | 
			
		||||
@@ -599,7 +600,7 @@ void strbuilder_skip_line(StrBuilder str)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
void strip_space(StrBuilder str)
 | 
			
		||||
void strbuilder_strip_space(StrBuilder str)
 | 
			
		||||
{
 | 
			
		||||
	char* write_pos = str;
 | 
			
		||||
	char* read_pos  = str;
 | 
			
		||||
@@ -737,8 +738,8 @@ Str str_visualize_whitespace(Str str, AllocatorInfo allocator)
 | 
			
		||||
 | 
			
		||||
// Represents strings cached with the string table.
 | 
			
		||||
// Should never be modified, if changed string is desired, cache_string( str ) another.
 | 
			
		||||
typedef Str StringCached;
 | 
			
		||||
typedef Str StrCached;
 | 
			
		||||
 | 
			
		||||
// Implements basic string interning. Data structure is based off the ZPL Hashtable.
 | 
			
		||||
typedef HashTable(StringCached) StringTable;
 | 
			
		||||
typedef HashTable(StrCached) StringTable;
 | 
			
		||||
#pragma endregion Strings
 | 
			
		||||
 
 | 
			
		||||
@@ -1,2 +1 @@
 | 
			
		||||
API_Export, GEN_API_Export_Code
 | 
			
		||||
API_Import, GEN_API_Import_Code
 | 
			
		||||
GEN_API,    GEN_API
 | 
			
		||||
 
 | 
			
		||||
		
		
			
  | 
@@ -37,6 +37,7 @@ Operator_Member_Fwd, "operator"
 | 
			
		||||
Operator_Cast,       "operator"
 | 
			
		||||
Operator_Cast_Fwd,   "operator"
 | 
			
		||||
Parameters,          "__NA__"
 | 
			
		||||
Parameters_Define,   "__NA__"
 | 
			
		||||
Preprocess_Define,   "define"
 | 
			
		||||
Preprocess_Include,  "include"
 | 
			
		||||
Preprocess_If,       "if"
 | 
			
		||||
 
 | 
			
		||||
		
		
			
  | 
@@ -1,95 +1,98 @@
 | 
			
		||||
Invalid,                "__invalid__"
 | 
			
		||||
Access_Private,         "private"
 | 
			
		||||
Access_Protected,       "protected"
 | 
			
		||||
Access_Public,          "public"
 | 
			
		||||
Access_MemberSymbol,    "."
 | 
			
		||||
Access_StaticSymbol,    "::"
 | 
			
		||||
Ampersand,              "&"
 | 
			
		||||
Ampersand_DBL,          "&&"
 | 
			
		||||
Assign_Classifer,       ":"
 | 
			
		||||
Attribute_Open,         "[["
 | 
			
		||||
Attribute_Close,        "]]"
 | 
			
		||||
BraceCurly_Open,        "{"
 | 
			
		||||
BraceCurly_Close,       "}"
 | 
			
		||||
BraceSquare_Open,       "["
 | 
			
		||||
BraceSquare_Close,      "]"
 | 
			
		||||
Capture_Start,          "("
 | 
			
		||||
Capture_End,            ")"
 | 
			
		||||
Comment,                "__comment__"
 | 
			
		||||
Comment_End,            "__comment_end__"
 | 
			
		||||
Comment_Start,          "__comment_start__"
 | 
			
		||||
Char,                   "__character__"
 | 
			
		||||
Comma,                  ","
 | 
			
		||||
Decl_Class,             "class"
 | 
			
		||||
Decl_GNU_Attribute,     "__attribute__"
 | 
			
		||||
Decl_MSVC_Attribute,    "__declspec"
 | 
			
		||||
Decl_Enum,              "enum"
 | 
			
		||||
Decl_Extern_Linkage,    "extern"
 | 
			
		||||
Decl_Friend,            "friend"
 | 
			
		||||
Decl_Module,            "module"
 | 
			
		||||
Decl_Namespace,         "namespace"
 | 
			
		||||
Decl_Operator,          "operator"
 | 
			
		||||
Decl_Struct,            "struct"
 | 
			
		||||
Decl_Template,          "template"
 | 
			
		||||
Decl_Typedef,           "typedef"
 | 
			
		||||
Decl_Using,             "using"
 | 
			
		||||
Decl_Union,             "union"
 | 
			
		||||
Identifier,             "__identifier__"
 | 
			
		||||
Module_Import,          "import"
 | 
			
		||||
Module_Export,          "export"
 | 
			
		||||
NewLine,                "__new_line__"
 | 
			
		||||
Number,                 "__number__"
 | 
			
		||||
Operator,               "__operator__"
 | 
			
		||||
Preprocess_Hash,        "#"
 | 
			
		||||
Preprocess_Define,      "define"
 | 
			
		||||
Preprocess_If,          "if"
 | 
			
		||||
Preprocess_IfDef,       "ifdef"
 | 
			
		||||
Preprocess_IfNotDef,    "ifndef"
 | 
			
		||||
Preprocess_ElIf,        "elif"
 | 
			
		||||
Preprocess_Else,        "else"
 | 
			
		||||
Preprocess_EndIf,       "endif"
 | 
			
		||||
Preprocess_Include,     "include"
 | 
			
		||||
Preprocess_Pragma,      "pragma"
 | 
			
		||||
Preprocess_Content,	    "__macro_content__"
 | 
			
		||||
Preprocess_Macro,       "__macro__"
 | 
			
		||||
Preprocess_Unsupported, "__unsupported__"
 | 
			
		||||
Spec_Alignas,           "alignas"
 | 
			
		||||
Spec_Const,             "const"
 | 
			
		||||
Spec_Consteval,         "consteval"
 | 
			
		||||
Spec_Constexpr,         "constexpr"
 | 
			
		||||
Spec_Constinit,         "constinit"
 | 
			
		||||
Spec_Explicit,          "explicit"
 | 
			
		||||
Spec_Extern,            "extern"
 | 
			
		||||
Spec_Final,             "final"
 | 
			
		||||
Spec_ForceInline,	    "forceinline"
 | 
			
		||||
Spec_Global,            "global"
 | 
			
		||||
Spec_Inline,            "inline"
 | 
			
		||||
Spec_Internal_Linkage,  "internal"
 | 
			
		||||
Spec_LocalPersist,      "local_persist"
 | 
			
		||||
Spec_Mutable,           "mutable"
 | 
			
		||||
Spec_NeverInline,       "neverinline"
 | 
			
		||||
Spec_Override,          "override"
 | 
			
		||||
Spec_Static,            "static"
 | 
			
		||||
Spec_ThreadLocal,       "thread_local"
 | 
			
		||||
Spec_Volatile,          "volatile"
 | 
			
		||||
Spec_Virtual,           "virtual"
 | 
			
		||||
Star,                   "*"
 | 
			
		||||
Statement_End,          ";"
 | 
			
		||||
StaticAssert,           "static_assert"
 | 
			
		||||
String,                 "__string__"
 | 
			
		||||
Type_Typename,          "typename"
 | 
			
		||||
Type_Unsigned,          "unsigned"
 | 
			
		||||
Type_Signed,            "signed"
 | 
			
		||||
Type_Short,             "short"
 | 
			
		||||
Type_Long,              "long"
 | 
			
		||||
Type_bool,              "bool"
 | 
			
		||||
Type_char,              "char"
 | 
			
		||||
Type_int,               "int"
 | 
			
		||||
Type_double,            "double"
 | 
			
		||||
Type_MS_int8,           "__int8"
 | 
			
		||||
Type_MS_int16,          "__int16"
 | 
			
		||||
Type_MS_int32,          "__int32"
 | 
			
		||||
Type_MS_int64,          "__int64"
 | 
			
		||||
Type_MS_W64,            "_W64"
 | 
			
		||||
Varadic_Argument,       "..."
 | 
			
		||||
__Attributes_Start,     "__attrib_start__"
 | 
			
		||||
Invalid,                    "__invalid__"
 | 
			
		||||
Access_Private,             "private"
 | 
			
		||||
Access_Protected,           "protected"
 | 
			
		||||
Access_Public,              "public"
 | 
			
		||||
Access_MemberSymbol,        "."
 | 
			
		||||
Access_StaticSymbol,        "::"
 | 
			
		||||
Ampersand,                  "&"
 | 
			
		||||
Ampersand_DBL,              "&&"
 | 
			
		||||
Assign_Classifer,           ":"
 | 
			
		||||
Attribute_Open,             "[["
 | 
			
		||||
Attribute_Close,            "]]"
 | 
			
		||||
BraceCurly_Open,            "{"
 | 
			
		||||
BraceCurly_Close,           "}"
 | 
			
		||||
BraceSquare_Open,           "["
 | 
			
		||||
BraceSquare_Close,          "]"
 | 
			
		||||
Paren_Open,                 "("
 | 
			
		||||
Paren_Close,                ")"
 | 
			
		||||
Comment,                    "__comment__"
 | 
			
		||||
Comment_End,                "__comment_end__"
 | 
			
		||||
Comment_Start,              "__comment_start__"
 | 
			
		||||
Char,                       "__character__"
 | 
			
		||||
Comma,                      ","
 | 
			
		||||
Decl_Class,                 "class"
 | 
			
		||||
Decl_GNU_Attribute,         "__attribute__"
 | 
			
		||||
Decl_MSVC_Attribute,        "__declspec"
 | 
			
		||||
Decl_Enum,                  "enum"
 | 
			
		||||
Decl_Extern_Linkage,        "extern"
 | 
			
		||||
Decl_Friend,                "friend"
 | 
			
		||||
Decl_Module,                "module"
 | 
			
		||||
Decl_Namespace,             "namespace"
 | 
			
		||||
Decl_Operator,              "operator"
 | 
			
		||||
Decl_Struct,                "struct"
 | 
			
		||||
Decl_Template,              "template"
 | 
			
		||||
Decl_Typedef,               "typedef"
 | 
			
		||||
Decl_Using,                 "using"
 | 
			
		||||
Decl_Union,                 "union"
 | 
			
		||||
Identifier,                 "__identifier__"
 | 
			
		||||
Module_Import,              "import"
 | 
			
		||||
Module_Export,              "export"
 | 
			
		||||
NewLine,                    "__new_line__"
 | 
			
		||||
Number,                     "__number__"
 | 
			
		||||
Operator,                   "__operator__"
 | 
			
		||||
Preprocess_Hash,            "#"
 | 
			
		||||
Preprocess_Define,          "define"
 | 
			
		||||
Preprocess_Define_Param,    "__define_param__"
 | 
			
		||||
Preprocess_If,              "if"
 | 
			
		||||
Preprocess_IfDef,           "ifdef"
 | 
			
		||||
Preprocess_IfNotDef,        "ifndef"
 | 
			
		||||
Preprocess_ElIf,            "elif"
 | 
			
		||||
Preprocess_Else,            "else"
 | 
			
		||||
Preprocess_EndIf,           "endif"
 | 
			
		||||
Preprocess_Include,         "include"
 | 
			
		||||
Preprocess_Pragma,          "pragma"
 | 
			
		||||
Preprocess_Content,         "__macro_content__"
 | 
			
		||||
Preprocess_Macro_Expr,      "__macro_expression__"
 | 
			
		||||
Preprocess_Macro_Stmt,      "__macro_statment__"
 | 
			
		||||
Preprocess_Macro_Typename,  "__macro_typename__"
 | 
			
		||||
Preprocess_Unsupported,     "__unsupported__"
 | 
			
		||||
Spec_Alignas,               "alignas"
 | 
			
		||||
Spec_Const,                 "const"
 | 
			
		||||
Spec_Consteval,             "consteval"
 | 
			
		||||
Spec_Constexpr,             "constexpr"
 | 
			
		||||
Spec_Constinit,             "constinit"
 | 
			
		||||
Spec_Explicit,              "explicit"
 | 
			
		||||
Spec_Extern,                "extern"
 | 
			
		||||
Spec_Final,                 "final"
 | 
			
		||||
Spec_ForceInline,           "forceinline"
 | 
			
		||||
Spec_Global,                "global"
 | 
			
		||||
Spec_Inline,                "inline"
 | 
			
		||||
Spec_Internal_Linkage,      "internal"
 | 
			
		||||
Spec_LocalPersist,          "local_persist"
 | 
			
		||||
Spec_Mutable,               "mutable"
 | 
			
		||||
Spec_NeverInline,           "neverinline"
 | 
			
		||||
Spec_Override,              "override"
 | 
			
		||||
Spec_Static,                "static"
 | 
			
		||||
Spec_ThreadLocal,           "thread_local"
 | 
			
		||||
Spec_Volatile,              "volatile"
 | 
			
		||||
Spec_Virtual,               "virtual"
 | 
			
		||||
Star,                       "*"
 | 
			
		||||
Statement_End,              ";"
 | 
			
		||||
StaticAssert,               "static_assert"
 | 
			
		||||
String,                     "__string__"
 | 
			
		||||
Type_Typename,              "typename"
 | 
			
		||||
Type_Unsigned,              "unsigned"
 | 
			
		||||
Type_Signed,                "signed"
 | 
			
		||||
Type_Short,                 "short"
 | 
			
		||||
Type_Long,                  "long"
 | 
			
		||||
Type_bool,                  "bool"
 | 
			
		||||
Type_char,                  "char"
 | 
			
		||||
Type_int,                   "int"
 | 
			
		||||
Type_double,                "double"
 | 
			
		||||
Type_MS_int8,               "__int8"
 | 
			
		||||
Type_MS_int16,              "__int16"
 | 
			
		||||
Type_MS_int32,              "__int32"
 | 
			
		||||
Type_MS_int64,              "__int64"
 | 
			
		||||
Type_MS_W64,                "_W64"
 | 
			
		||||
Varadic_Argument,           "..."
 | 
			
		||||
__Attributes_Start,         "__attrib_start__"
 | 
			
		||||
 
 | 
			
		||||
		
		
			
  | 
@@ -31,8 +31,8 @@ GEN_NS_BEGIN
 | 
			
		||||
 | 
			
		||||
#include "components/interface.cpp"
 | 
			
		||||
#include "components/interface.upfront.cpp"
 | 
			
		||||
#include "components/gen/etoktype.cpp"
 | 
			
		||||
#include "components/lexer.cpp"
 | 
			
		||||
#include "components/parser_case_macros.cpp"
 | 
			
		||||
#include "components/parser.cpp"
 | 
			
		||||
#include "components/interface.parsing.cpp"
 | 
			
		||||
#include "components/interface.untyped.cpp"
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,8 @@ GEN_NS_BEGIN
 | 
			
		||||
#include "components/gen/ecodetypes.hpp"
 | 
			
		||||
#include "components/gen/eoperator.hpp"
 | 
			
		||||
#include "components/gen/especifier.hpp"
 | 
			
		||||
#include "components/gen/etoktype.hpp"
 | 
			
		||||
#include "components/parser_types.hpp"
 | 
			
		||||
 | 
			
		||||
#include "components/ast.hpp"
 | 
			
		||||
#include "components/code_types.hpp"
 | 
			
		||||
 
 | 
			
		||||
@@ -9,13 +9,10 @@ using namespace gen;
 | 
			
		||||
 | 
			
		||||
CodeBody gen_ecode( char const* path, bool use_c_definition = false )
 | 
			
		||||
{
 | 
			
		||||
	FixedArena_32KB scratch;       fixed_arena_init(& scratch);
 | 
			
		||||
	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch);
 | 
			
		||||
 | 
			
		||||
	CSV_Columns2 csv_enum                 = parse_csv_two_columns( scratch_info, path );
 | 
			
		||||
	StrBuilder   enum_entries             = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) );
 | 
			
		||||
	StrBuilder   to_c_str_entries         = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) );
 | 
			
		||||
	StrBuilder   to_keyword_c_str_entries = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) );
 | 
			
		||||
	CSV_Columns2 csv_enum                 = parse_csv_two_columns( _ctx->Allocator_Temp, path );
 | 
			
		||||
	StrBuilder   enum_entries             = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
 | 
			
		||||
	StrBuilder   to_c_str_entries         = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
 | 
			
		||||
	StrBuilder   to_keyword_c_str_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
 | 
			
		||||
 | 
			
		||||
	for ( ssize idx = 0; idx < array_num(csv_enum.Col_1); ++ idx ) 	{
 | 
			
		||||
		char const* code    = csv_enum.Col_1[idx].string;
 | 
			
		||||
@@ -40,7 +37,7 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
 | 
			
		||||
 | 
			
		||||
#pragma push_macro("local_persist")
 | 
			
		||||
#undef local_persist
 | 
			
		||||
	Str      lookup_size  = strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) ));
 | 
			
		||||
	Str      lookup_size  = strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%d", array_num(csv_enum.Col_1) ));
 | 
			
		||||
	CodeBody to_c_str_fns = parse_global_body( token_fmt(
 | 
			
		||||
		"entries",  strbuilder_to_str(to_c_str_entries)
 | 
			
		||||
	,	"keywords", strbuilder_to_str(to_keyword_c_str_entries)
 | 
			
		||||
@@ -50,7 +47,7 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
 | 
			
		||||
		Str codetype_to_str( CodeType type )
 | 
			
		||||
		{
 | 
			
		||||
			local_persist
 | 
			
		||||
			Str lookup[<num>] = {
 | 
			
		||||
			Str lookup[] = {
 | 
			
		||||
				<entries>
 | 
			
		||||
			};
 | 
			
		||||
			return lookup[ type ];
 | 
			
		||||
@@ -60,7 +57,7 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false )
 | 
			
		||||
		Str codetype_to_keyword_str( CodeType type )
 | 
			
		||||
		{
 | 
			
		||||
			local_persist
 | 
			
		||||
			Str lookup[ <num> ] = {
 | 
			
		||||
			Str lookup[] = {
 | 
			
		||||
				<keywords>
 | 
			
		||||
			};
 | 
			
		||||
			return lookup[ type ];
 | 
			
		||||
@@ -93,12 +90,9 @@ CodeBody gen_ecode( 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);
 | 
			
		||||
	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch);
 | 
			
		||||
 | 
			
		||||
	CSV_Columns2 csv_enum       = parse_csv_two_columns( scratch_info, path );
 | 
			
		||||
	StrBuilder enum_entries     = strbuilder_make_reserve( GlobalAllocator, 32 );
 | 
			
		||||
	StrBuilder to_c_str_entries = strbuilder_make_reserve( GlobalAllocator, 32 );
 | 
			
		||||
	CSV_Columns2 csv_enum       = parse_csv_two_columns( _ctx->Allocator_Temp, path );
 | 
			
		||||
	StrBuilder enum_entries     = strbuilder_make_reserve( _ctx->Allocator_Temp, 32 );
 | 
			
		||||
	StrBuilder to_c_str_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, 32 );
 | 
			
		||||
 | 
			
		||||
	for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++) {
 | 
			
		||||
		char const* enum_str     = csv_enum.Col_1[idx].string;
 | 
			
		||||
@@ -136,7 +130,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
 | 
			
		||||
 | 
			
		||||
#pragma push_macro("local_persist")
 | 
			
		||||
#undef local_persist
 | 
			
		||||
	Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) ));
 | 
			
		||||
	Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%d", array_num(csv_enum.Col_1) ));
 | 
			
		||||
	CodeFn to_str   = parse_function(token_fmt(
 | 
			
		||||
		"entries", strbuilder_to_str(to_c_str_entries)
 | 
			
		||||
	,	"num",     lookup_size
 | 
			
		||||
@@ -145,7 +139,7 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false )
 | 
			
		||||
		Str operator_to_str( Operator op )
 | 
			
		||||
		{
 | 
			
		||||
			local_persist
 | 
			
		||||
			Str lookup[<num>] = {
 | 
			
		||||
			Str lookup[] = {
 | 
			
		||||
				<entries>
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
@@ -178,12 +172,9 @@ CodeBody gen_eoperator( 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);
 | 
			
		||||
	AllocatorInfo   scratch_info = fixed_arena_allocator_info(& scratch);
 | 
			
		||||
 | 
			
		||||
	CSV_Columns2 csv_enum       = parse_csv_two_columns(   scratch_info, path );
 | 
			
		||||
	StrBuilder enum_entries     = strbuilder_make_reserve( scratch_info, kilobytes(1) );
 | 
			
		||||
	StrBuilder to_c_str_entries = strbuilder_make_reserve( scratch_info, kilobytes(1) );
 | 
			
		||||
	CSV_Columns2 csv_enum       = parse_csv_two_columns( _ctx->Allocator_Temp, path );
 | 
			
		||||
	StrBuilder enum_entries     = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
 | 
			
		||||
	StrBuilder to_c_str_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) );
 | 
			
		||||
 | 
			
		||||
	for (usize idx = 0; idx < array_num(csv_enum.Col_1); idx++)
 | 
			
		||||
	{
 | 
			
		||||
@@ -237,7 +228,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
 | 
			
		||||
#undef do_once_end
 | 
			
		||||
#undef forceinline
 | 
			
		||||
#undef neverinline
 | 
			
		||||
	Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%d", array_num(csv_enum.Col_1) ));
 | 
			
		||||
	Str lookup_size = strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%d", array_num(csv_enum.Col_1) ));
 | 
			
		||||
	CodeFn to_str   = parse_function(token_fmt(
 | 
			
		||||
		"entries", strbuilder_to_str(to_c_str_entries)
 | 
			
		||||
	,	"num",     lookup_size
 | 
			
		||||
@@ -246,7 +237,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
 | 
			
		||||
		Str spec_to_str( Specifier type )
 | 
			
		||||
		{
 | 
			
		||||
			local_persist
 | 
			
		||||
			Str lookup[<num>] = {
 | 
			
		||||
			Str lookup[] = {
 | 
			
		||||
				<entries>
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
@@ -292,7 +283,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
 | 
			
		||||
	body_append(result, enum_code);
 | 
			
		||||
	if (use_c_definition)
 | 
			
		||||
	{
 | 
			
		||||
		CodeTypedef specifier_t = parse_typedef( code(typedef u32 Specifier; ));
 | 
			
		||||
		CodeTypedef specifier_t = parse_typedef( code(typedef enum Specifier Specifier; ));
 | 
			
		||||
		body_append(result, specifier_t);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -317,29 +308,24 @@ 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 )
 | 
			
		||||
{
 | 
			
		||||
	FixedArena_64KB scratch;       fixed_arena_init(& 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( _ctx->Allocator_Temp, file_zero_terminate, etok_path );
 | 
			
		||||
	CSV_Object csv_enum_nodes;
 | 
			
		||||
	csv_parse( &csv_enum_nodes, rcast(char*, enum_content.data), scratch_info, false );
 | 
			
		||||
 | 
			
		||||
	FileContents attrib_content = file_read_contents( scratch_info, file_zero_terminate, attr_path );
 | 
			
		||||
	csv_parse( &csv_enum_nodes, rcast(char*, enum_content.data), _ctx->Allocator_Temp, false );
 | 
			
		||||
 | 
			
		||||
	FileContents attrib_content = file_read_contents( _ctx->Allocator_Temp, file_zero_terminate, attr_path );
 | 
			
		||||
	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), _ctx->Allocator_Temp, false );
 | 
			
		||||
 | 
			
		||||
	Array<ADT_Node> enum_strs            = csv_enum_nodes.nodes[0].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_c_str_strs = csv_attr_nodes.nodes[1].nodes;
 | 
			
		||||
 | 
			
		||||
	StrBuilder enum_entries             = strbuilder_make_reserve( scratch_info, kilobytes(2) );
 | 
			
		||||
	StrBuilder to_c_str_entries         = strbuilder_make_reserve( scratch_info, kilobytes(4) );
 | 
			
		||||
	StrBuilder attribute_entries        = strbuilder_make_reserve( scratch_info, kilobytes(2) );
 | 
			
		||||
	StrBuilder to_c_str_attributes      = strbuilder_make_reserve( scratch_info, kilobytes(4) );
 | 
			
		||||
	StrBuilder attribute_define_entries = strbuilder_make_reserve( scratch_info, kilobytes(4) );
 | 
			
		||||
	StrBuilder enum_entries             = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(2) );
 | 
			
		||||
	StrBuilder to_c_str_entries         = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(4) );
 | 
			
		||||
	StrBuilder attribute_entries        = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(2) );
 | 
			
		||||
	StrBuilder to_c_str_attributes      = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(4) );
 | 
			
		||||
	StrBuilder attribute_define_entries = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(4) );
 | 
			
		||||
 | 
			
		||||
	for (usize idx = 0; idx < array_num(enum_strs); idx++)
 | 
			
		||||
	{
 | 
			
		||||
@@ -367,7 +353,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
 | 
			
		||||
 | 
			
		||||
#pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
 | 
			
		||||
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
 | 
			
		||||
	CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), strbuilder_to_str(attribute_define_entries)  );
 | 
			
		||||
	CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), MT_Statement, { {}, strbuilder_to_str(attribute_define_entries) }  );
 | 
			
		||||
#pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
 | 
			
		||||
 | 
			
		||||
	// We cannot parse this enum, it has Attribute names as enums
 | 
			
		||||
@@ -449,7 +435,6 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
 | 
			
		||||
#pragma pop_macro("do_once_end")
 | 
			
		||||
 | 
			
		||||
	CodeBody result = def_body(CT_Global_Body);
 | 
			
		||||
	body_append(result, untyped_str(txt("GEN_NS_PARSER_BEGIN\n\n")));
 | 
			
		||||
	body_append(result, attribute_entires_def);
 | 
			
		||||
	body_append(result, enum_code);
 | 
			
		||||
	if (use_c_definition)
 | 
			
		||||
@@ -459,7 +444,6 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_
 | 
			
		||||
	}
 | 
			
		||||
	body_append(result, to_str);
 | 
			
		||||
	body_append(result, to_type);
 | 
			
		||||
	body_append(result, untyped_str(txt("\nGEN_NS_PARSER_END\n\n")));
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -515,59 +499,60 @@ CodeBody gen_ast_inlines()
 | 
			
		||||
#pragma pop_macro("GEN_NS")
 | 
			
		||||
#pragma pop_macro("CodeInvalid")
 | 
			
		||||
 | 
			
		||||
	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", Str name(CodeBody),           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", Str name(CodeComment),        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", Str name(CodeClass),          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", Str name(CodeDestructor),     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", Str name(CodeExec),           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", Str name(CodeInclude),        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", Str name(CodeFn),             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", Str name(CodeNS),             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", Str name(CodeOpCast),         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", Str name(CodePragma),         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", Str name(CodeSpecifiers),     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", Str name(CodeTemplate),       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", Str name(CodeTypedef),        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", Str name(CodeUsing),          code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_var      = parse_global_body( token_fmt( "typename", Str name(CodeVar),            code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code               = parse_global_body( token_fmt( "typename", name(Code),               code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_body          = parse_global_body( token_fmt( "typename", name(CodeBody),           code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_attr          = parse_global_body( token_fmt( "typename", name(CodeAttributes),     code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_cmt           = parse_global_body( token_fmt( "typename", name(CodeComment),        code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_constr        = parse_global_body( token_fmt( "typename", name(CodeConstructor),    code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_class         = parse_global_body( token_fmt( "typename", name(CodeClass),          code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_define        = parse_global_body( token_fmt( "typename", name(CodeDefine),         code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_define_params = parse_global_body( token_fmt( "typename", name(CodeDefineParams),   code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_destruct      = parse_global_body( token_fmt( "typename", name(CodeDestructor),     code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_enum          = parse_global_body( token_fmt( "typename", name(CodeEnum),           code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_exec          = parse_global_body( token_fmt( "typename", name(CodeExec),           code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_extern        = parse_global_body( token_fmt( "typename", name(CodeExtern),         code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_include       = parse_global_body( token_fmt( "typename", name(CodeInclude),        code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_friend        = parse_global_body( token_fmt( "typename", name(CodeFriend),         code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_fn	         = parse_global_body( token_fmt( "typename", name(CodeFn),             code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_module        = parse_global_body( token_fmt( "typename", name(CodeModule),         code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_ns            = parse_global_body( token_fmt( "typename", name(CodeNS),             code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_op            = parse_global_body( token_fmt( "typename", name(CodeOperator),       code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_opcast        = parse_global_body( token_fmt( "typename", name(CodeOpCast),         code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_params        = parse_global_body( token_fmt( "typename", name(CodeParams),         code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_pragma        = parse_global_body( token_fmt( "typename", name(CodePragma),         code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_precond       = parse_global_body( token_fmt( "typename", name(CodePreprocessCond), code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_specs         = parse_global_body( token_fmt( "typename", name(CodeSpecifiers),     code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_struct        = parse_global_body( token_fmt( "typename", name(CodeStruct),         code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_tmpl          = parse_global_body( token_fmt( "typename", name(CodeTemplate),       code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_type          = parse_global_body( token_fmt( "typename", name(CodeTypename),       code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_typedef       = parse_global_body( token_fmt( "typename", name(CodeTypedef),        code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_union         = parse_global_body( token_fmt( "typename", name(CodeUnion),          code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_using         = parse_global_body( token_fmt( "typename", name(CodeUsing),          code_impl_tmpl ));
 | 
			
		||||
	CodeBody impl_code_var           = parse_global_body( token_fmt( "typename", name(CodeVar),            code_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", Str name(Comment),        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", Str name(Define),         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", Str name(Enum),           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", Str name(Extern),         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", Str name(Friend),         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", Str name(Module),         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", Str name(Operator),       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", Str name(Pragma),         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", Str name(Template),       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", Str name(Typedef),        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", Str name(Using),          codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_var,      parse_global_body( token_fmt( "typename", Str name(Var),            codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_attr,     parse_global_body( token_fmt( "typename", name(Attributes),     codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_cmt,      parse_global_body( token_fmt( "typename", name(Comment),        codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_constr,   parse_global_body( token_fmt( "typename", name(Constructor),    codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_define,   parse_global_body( token_fmt( "typename", name(Define),         codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_destruct, parse_global_body( token_fmt( "typename", name(Destructor),     codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_enum,     parse_global_body( token_fmt( "typename", name(Enum),           codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_exec,     parse_global_body( token_fmt( "typename", name(Exec),           codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_extern,   parse_global_body( token_fmt( "typename", name(Extern),         codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_include,  parse_global_body( token_fmt( "typename", name(Include),        codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_friend,   parse_global_body( token_fmt( "typename", name(Friend),         codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_fn,       parse_global_body( token_fmt( "typename", name(Fn),             codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_module,   parse_global_body( token_fmt( "typename", name(Module),         codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_ns,       parse_global_body( token_fmt( "typename", name(NS),             codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_op,       parse_global_body( token_fmt( "typename", name(Operator),       codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_opcast,   parse_global_body( token_fmt( "typename", name(OpCast),         codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_pragma,   parse_global_body( token_fmt( "typename", name(Pragma),         codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_precond,  parse_global_body( token_fmt( "typename", name(PreprocessCond), codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_tmpl,     parse_global_body( token_fmt( "typename", name(Template),       codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_type,     parse_global_body( token_fmt( "typename", name(Typename),       codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_typedef,  parse_global_body( token_fmt( "typename", name(Typedef),        codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_union,    parse_global_body( token_fmt( "typename", name(Union),          codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_using,    parse_global_body( token_fmt( "typename", name(Using),          codetype_impl_tmpl )));
 | 
			
		||||
	body_append(impl_code_var,      parse_global_body( token_fmt( "typename", name(Var),            codetype_impl_tmpl )));
 | 
			
		||||
 | 
			
		||||
	#pragma push_macro("forceinline")
 | 
			
		||||
	#undef forceinline
 | 
			
		||||
@@ -579,34 +564,35 @@ CodeBody gen_ast_inlines()
 | 
			
		||||
	);
 | 
			
		||||
	#pragma pop_macro("forceinline")
 | 
			
		||||
 | 
			
		||||
	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", Str name(Attributes),     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", Str name(Constructor),    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", Str name(Define),         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", Str name(Enum),           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", Str name(Extern),         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", Str name(Fn),             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", Str name(Module),         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", Str name(Operator),       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", Str name(Params),         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", Str name(PreprocessCond), 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", Str name(Struct),         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", Str name(Typename),       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", Str name(Union),          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", Str name(Var),            cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_body          = parse_global_body( token_fmt( "typename", name(Body),           cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_attribute     = parse_global_body( token_fmt( "typename", name(Attributes),     cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_cmt           = parse_global_body( token_fmt( "typename", name(Comment),        cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_constr        = parse_global_body( token_fmt( "typename", name(Constructor),    cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_class         = parse_global_body( token_fmt( "typename", name(Class),          cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_define        = parse_global_body( token_fmt( "typename", name(Define),         cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_define_params = parse_global_body( token_fmt( "typename", name(DefineParams),   cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_destruct      = parse_global_body( token_fmt( "typename", name(Destructor),     cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_enum          = parse_global_body( token_fmt( "typename", name(Enum),           cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_exec          = parse_global_body( token_fmt( "typename", name(Exec),           cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_extern        = parse_global_body( token_fmt( "typename", name(Extern),         cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_friend        = parse_global_body( token_fmt( "typename", name(Friend),         cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_fn            = parse_global_body( token_fmt( "typename", name(Fn),             cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_include       = parse_global_body( token_fmt( "typename", name(Include),        cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_module        = parse_global_body( token_fmt( "typename", name(Module),         cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_ns            = parse_global_body( token_fmt( "typename", name(NS),             cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_op            = parse_global_body( token_fmt( "typename", name(Operator),       cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_opcast        = parse_global_body( token_fmt( "typename", name(OpCast),         cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_params        = parse_global_body( token_fmt( "typename", name(Params),         cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_pragma        = parse_global_body( token_fmt( "typename", name(Pragma),         cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_precond       = parse_global_body( token_fmt( "typename", name(PreprocessCond), cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_specs         = parse_global_body( token_fmt( "typename", name(Specifiers),     cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_struct        = parse_global_body( token_fmt( "typename", name(Struct),         cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_tmpl          = parse_global_body( token_fmt( "typename", name(Template),       cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_type          = parse_global_body( token_fmt( "typename", name(Typename),       cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_typedef       = parse_global_body( token_fmt( "typename", name(Typedef),        cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_union         = parse_global_body( token_fmt( "typename", name(Union),          cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_using         = parse_global_body( token_fmt( "typename", name(Using),          cast_tmpl ));
 | 
			
		||||
	CodeBody impl_cast_var           = parse_global_body( token_fmt( "typename", name(Var),            cast_tmpl ));
 | 
			
		||||
 | 
			
		||||
	CodeBody result = def_global_body( args(
 | 
			
		||||
		def_pragma( txt("region generated code inline implementation")),
 | 
			
		||||
@@ -618,6 +604,7 @@ CodeBody gen_ast_inlines()
 | 
			
		||||
		impl_code_constr,
 | 
			
		||||
		impl_code_class,
 | 
			
		||||
		impl_code_define,
 | 
			
		||||
		impl_code_define_params,
 | 
			
		||||
		impl_code_destruct,
 | 
			
		||||
		impl_code_enum,
 | 
			
		||||
		impl_code_exec,
 | 
			
		||||
@@ -652,6 +639,7 @@ CodeBody gen_ast_inlines()
 | 
			
		||||
		impl_cast_constr,
 | 
			
		||||
		impl_cast_class,
 | 
			
		||||
		impl_cast_define,
 | 
			
		||||
		impl_cast_define_params,
 | 
			
		||||
		impl_cast_destruct,
 | 
			
		||||
		impl_cast_enum,
 | 
			
		||||
		impl_cast_exec,
 | 
			
		||||
 
 | 
			
		||||
@@ -21,10 +21,10 @@ using namespace gen;
 | 
			
		||||
void clang_format_file( char const* path, char const* style_path )
 | 
			
		||||
{
 | 
			
		||||
	GEN_ASSERT_NOT_NULL(path);
 | 
			
		||||
	StrBuilder resolved_path = strbuilder_make_str(GlobalAllocator, to_str_from_c_str(path));
 | 
			
		||||
	StrBuilder resolved_path = strbuilder_make_str(_ctx->Allocator_Temp, to_str_from_c_str(path));
 | 
			
		||||
	StrBuilder style_arg;
 | 
			
		||||
	if (style_path) {
 | 
			
		||||
		style_arg = strbuilder_make_str(GlobalAllocator, txt("-style=file:"));
 | 
			
		||||
		style_arg = strbuilder_make_str(_ctx->Allocator_Temp, txt("-style=file:"));
 | 
			
		||||
		strbuilder_append_fmt( & style_arg, "%s ", style_path );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -32,7 +32,7 @@ void clang_format_file( char const* path, char const* style_path )
 | 
			
		||||
	Str cf_format_inplace = txt("-i ");
 | 
			
		||||
	Str cf_verbose        = txt("-verbose ");
 | 
			
		||||
 | 
			
		||||
	StrBuilder command = strbuilder_make_str( GlobalAllocator, clang_format );
 | 
			
		||||
	StrBuilder command = strbuilder_make_str( _ctx->Allocator_Temp, clang_format );
 | 
			
		||||
	strbuilder_append_str( & command, cf_format_inplace );
 | 
			
		||||
	strbuilder_append_str( & command, cf_verbose );
 | 
			
		||||
	strbuilder_append_string( & command, style_arg );
 | 
			
		||||
@@ -48,7 +48,7 @@ void refactor_file( char const* path, char const* refactor_script )
 | 
			
		||||
	GEN_ASSERT_NOT_NULL(path);
 | 
			
		||||
	GEN_ASSERT_NOT_NULL(refactor_script);
 | 
			
		||||
 | 
			
		||||
	StrBuilder command = strbuilder_make_str(GlobalAllocator, txt("refactor "));
 | 
			
		||||
	StrBuilder command = strbuilder_make_str(_ctx->Allocator_Temp, txt("refactor "));
 | 
			
		||||
	// strbuilder_append_str( & command, txt("-debug ") );
 | 
			
		||||
	strbuilder_append_str( & command, txt("-num=1 ") );
 | 
			
		||||
	strbuilder_append_fmt( & command, "-src=%s ", path );
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@
 | 
			
		||||
#undef local_persist
 | 
			
		||||
 | 
			
		||||
#undef bit
 | 
			
		||||
#undef bitfield_is_equal
 | 
			
		||||
#undef bitfield_is_set
 | 
			
		||||
 | 
			
		||||
#undef cast
 | 
			
		||||
 | 
			
		||||
@@ -173,12 +173,12 @@
 | 
			
		||||
 | 
			
		||||
#undef GEN_DEFINE_ATTRIBUTE_TOKENS
 | 
			
		||||
 | 
			
		||||
#undef GEN_AST_BODY_CLASS_UNALLOWED_TYPES
 | 
			
		||||
#undef GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES
 | 
			
		||||
#undef GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
 | 
			
		||||
#undef GEN_AST_BODY_EXPORT_UNALLOWED_TYPES
 | 
			
		||||
#undef GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES
 | 
			
		||||
#undef GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES
 | 
			
		||||
#undef GEN_AST_BODY_CLASS_UNALLOWED_TYPES_CASES
 | 
			
		||||
#undef GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES_CASES
 | 
			
		||||
#undef GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES_CASES
 | 
			
		||||
#undef GEN_AST_BODY_EXPORT_UNALLOWED_TYPES_CASES
 | 
			
		||||
#undef GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES_CASES
 | 
			
		||||
#undef GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES_CASES
 | 
			
		||||
 | 
			
		||||
#undef GEN_GLOBAL_BUCKET_SIZE
 | 
			
		||||
#undef GEN_CODEPOOL_NUM_BLOCKS
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ These are containers representing a scope body of a definition that can be of th
 | 
			
		||||
Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Front;
 | 
			
		||||
Code           Back;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -56,8 +56,8 @@ Represent standard or vendor specific C/C++ attributes.
 | 
			
		||||
Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
StringCached   Content;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Content;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -80,8 +80,8 @@ Stores a comment.
 | 
			
		||||
Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
StringCached   Content;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Content;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -109,7 +109,7 @@ CodeComment    InlineCmt;  // Only supported by forward declarations
 | 
			
		||||
CodeAttributes Attributes;
 | 
			
		||||
CodeType       ParentType;
 | 
			
		||||
CodeBody       Body;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
CodeType       Prev;
 | 
			
		||||
CodeType       Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -143,7 +143,7 @@ CodeComment    InlineCmt;  // Only supported by forward declarations
 | 
			
		||||
Code           InitializerList;
 | 
			
		||||
CodeParams     Params;
 | 
			
		||||
Code           Body;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -178,8 +178,8 @@ Represents a preprocessor define
 | 
			
		||||
Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
StringCached   Content;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Content;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -201,7 +201,7 @@ Fields:
 | 
			
		||||
CodeComment    InlineCmt;
 | 
			
		||||
CodeSpecifiers Specs;
 | 
			
		||||
Code           Body;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -242,7 +242,7 @@ Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
Code           Parent;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
CodeT          Type;
 | 
			
		||||
ModuleFlag     ModuleFlags;
 | 
			
		||||
```
 | 
			
		||||
@@ -271,8 +271,8 @@ Will be obsolute when function body parsing is implemented.
 | 
			
		||||
Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
StringCached   Content;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Content;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -292,7 +292,7 @@ Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
CodeBody       Body;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -314,8 +314,8 @@ extern "<Name>"
 | 
			
		||||
Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
StringCached   Content;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Content;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Code           Parent;
 | 
			
		||||
@@ -338,7 +338,7 @@ Fields:
 | 
			
		||||
```cpp
 | 
			
		||||
CodeComment    InlineCmt;
 | 
			
		||||
Code           Declaration;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -363,7 +363,7 @@ CodeSpecifiers Specs;
 | 
			
		||||
CodeType       ReturnType;
 | 
			
		||||
CodeParams     Params;
 | 
			
		||||
CodeBody       Body;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -390,7 +390,7 @@ Serialization:
 | 
			
		||||
Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -411,7 +411,7 @@ Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
CodeBody       Body;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -440,7 +440,7 @@ CodeSpecifiers Specs;
 | 
			
		||||
CodeType       ReturnType;
 | 
			
		||||
CodeParams     Params;
 | 
			
		||||
CodeBody       Body;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -472,7 +472,7 @@ CodeComment    InlineCmt;
 | 
			
		||||
CodeSpecifiers Specs;
 | 
			
		||||
CodeType       ValueType;
 | 
			
		||||
CodeBody       Body;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -502,7 +502,7 @@ CodeType       ValueType;
 | 
			
		||||
Code           Macro;
 | 
			
		||||
Code           Value;
 | 
			
		||||
Code           PostNameMacro;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
CodeParams     Last;
 | 
			
		||||
CodeParams     Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -524,8 +524,8 @@ Serialization:
 | 
			
		||||
Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
StringCached   Content;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Content;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -544,8 +544,8 @@ Serialization:
 | 
			
		||||
Fields:
 | 
			
		||||
 | 
			
		||||
```cpp
 | 
			
		||||
StringCached  Content;
 | 
			
		||||
StringCached  Name;
 | 
			
		||||
StrCached  Content;
 | 
			
		||||
StrCached  Name;
 | 
			
		||||
Code          Prev;
 | 
			
		||||
Code          Next;
 | 
			
		||||
Token*        Tok;
 | 
			
		||||
@@ -566,7 +566,7 @@ Fields:
 | 
			
		||||
```cpp
 | 
			
		||||
SpecifierT     ArrSpecs[ AST_ArrSpecs_Cap ];
 | 
			
		||||
CodeSpecifiers NextSpecs;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -588,7 +588,7 @@ Fields:
 | 
			
		||||
```cpp
 | 
			
		||||
CodeParams     Params;
 | 
			
		||||
Code           Declaration;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -621,7 +621,7 @@ Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
Code           Parent;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
CodeT          Type;
 | 
			
		||||
b32            IsParamPack;
 | 
			
		||||
ETypenameTag   TypeTag;
 | 
			
		||||
@@ -649,7 +649,7 @@ Fields:
 | 
			
		||||
```cpp
 | 
			
		||||
CodeComment   InlineCmt;
 | 
			
		||||
Code          UnderlyingType;
 | 
			
		||||
StringCached  Name;
 | 
			
		||||
StrCached  Name;
 | 
			
		||||
Code          Prev;
 | 
			
		||||
Code          Next;
 | 
			
		||||
Token*        Tok
 | 
			
		||||
@@ -682,7 +682,7 @@ Fields:
 | 
			
		||||
```cpp
 | 
			
		||||
CodeAttributes Attributes;
 | 
			
		||||
CodeBody       Body;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -708,7 +708,7 @@ Fields:
 | 
			
		||||
CodeComment    InlineCmt;
 | 
			
		||||
CodeAttributes Attributes;
 | 
			
		||||
CodeType       UnderlyingType;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
Token*         Tok;
 | 
			
		||||
@@ -740,7 +740,7 @@ CodeSpecifiers Specs;
 | 
			
		||||
CodeType       ValueType;
 | 
			
		||||
Code           BitfieldSize;
 | 
			
		||||
Code           Value;
 | 
			
		||||
StringCached   Name;
 | 
			
		||||
StrCached   Name;
 | 
			
		||||
CodeVar        NextVar;
 | 
			
		||||
Code           Prev;
 | 
			
		||||
Code           Next;
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ int AST_ArrSpecs_Cap =
 | 
			
		||||
(
 | 
			
		||||
    AST_POD_Size
 | 
			
		||||
    - sizeof(Code)
 | 
			
		||||
    - sizeof(StringCached)
 | 
			
		||||
    - sizeof(StrCached)
 | 
			
		||||
    - sizeof(Code) * 2
 | 
			
		||||
    - sizeof(Token*)
 | 
			
		||||
    - sizeof(Code)
 | 
			
		||||
@@ -79,7 +79,7 @@ int AST_ArrSpecs_Cap =
 | 
			
		||||
Data Notes:
 | 
			
		||||
 | 
			
		||||
* 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_strbuilder_allocator`, `get_cached_string`, `make_code`.
 | 
			
		||||
  * You'll find the memory handling in `init`, `deinit`, `reset`, `gen_strbuilder_allocator`, `cache_str`, `make_code`.
 | 
			
		||||
  * 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:
 | 
			
		||||
 | 
			
		||||
@@ -93,7 +93,7 @@ Data Notes:
 | 
			
		||||
* Cached Strings are stored in their own set of arenas. AST constructors use cached strings for names, and content.
 | 
			
		||||
  * `StringArenas`, `StringCache`, `Allocator_StringArena`, and `Allocator_StringTable` are the associated containers or allocators.
 | 
			
		||||
* Strings used for serialization and file buffers are not contained by those used for cached strings.
 | 
			
		||||
  * They are currently using `GlobalAllocator`, which are tracked array of arenas that grows as needed (adds buckets when one runs out).
 | 
			
		||||
  * They are currently using `FallbackAllocator`, which are tracked array of arenas that grows as needed (adds buckets when one runs out).
 | 
			
		||||
  * Memory within the buckets is not reused, so its inherently wasteful.
 | 
			
		||||
  * I will be augmenting the default allocator with virtual memory & a slab allocator in the [future](https://github.com/Ed94/gencpp/issues/12)
 | 
			
		||||
* Intrusive linked lists used children nodes on bodies, and parameters.
 | 
			
		||||
@@ -238,6 +238,7 @@ Interface :
 | 
			
		||||
 | 
			
		||||
* parse_class
 | 
			
		||||
* parse_constructor
 | 
			
		||||
* parse_define
 | 
			
		||||
* parse_destructor
 | 
			
		||||
* parse_enum
 | 
			
		||||
* parse_export_body
 | 
			
		||||
@@ -322,6 +323,7 @@ Code        <name>       = parse_<function name>( gen_code_str );
 | 
			
		||||
 | 
			
		||||
The following are provided predefined by the library as they are commonly used:
 | 
			
		||||
 | 
			
		||||
* `enum_underlying_macro`
 | 
			
		||||
* `access_public`
 | 
			
		||||
* `access_protected`
 | 
			
		||||
* `access_private`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docs/assets/Code_-_Insiders_2024-12-15_22-52-13.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/assets/Code_-_Insiders_2024-12-15_22-52-13.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 150 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/assets/Code_-_Insiders_2024-12-15_22-57-58.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/assets/Code_-_Insiders_2024-12-15_22-57-58.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 250 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/assets/Code_-_Insiders_2024-12-15_23-04-07.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/assets/Code_-_Insiders_2024-12-15_23-04-07.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 175 KiB  | 
@@ -1,7 +1,5 @@
 | 
			
		||||
## Navigation
 | 
			
		||||
 | 
			
		||||
# base
 | 
			
		||||
 | 
			
		||||
[Top](../Readme.md)
 | 
			
		||||
 | 
			
		||||
* [docs](../docs/Readme.md)
 | 
			
		||||
@@ -15,9 +13,133 @@ The output will be in the `gen_segmented/gen` directory (if the directory does n
 | 
			
		||||
If using the library's provided build scripts:
 | 
			
		||||
 | 
			
		||||
```ps1
 | 
			
		||||
.\build.ps1 <compiler> <debug or omit> c_library
 | 
			
		||||
.\build.ps1 <compiler> <debug or omit> c_lib
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
All free from tag identifiers will be prefixed with `gen_` or `GEN_` as the namespace. This can either be changed after generation with a `.refactor` script (or your preferred subst method), OR by modifying c_library.refactor.
 | 
			
		||||
To generate a static or dynamic library:
 | 
			
		||||
 | 
			
		||||
```ps1
 | 
			
		||||
.\build.ps1 <compiler> <debug or omit> c_lib_static c_lib_dyn
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
All free from tag identifiers will be prefixed with `gen_` or `GEN_` as the namespace. This can either be changed after generation with a `.refactor` script (or your preferred subst method), OR by modifying [c_library.refactor](./c_library.refactor).
 | 
			
		||||
 | 
			
		||||
**If c_library.refactor is modified you may need to modify c_library.cpp and its [components](./components/). As some of the container generation relies on that prefix.**
 | 
			
		||||
 | 
			
		||||
## Generation structure
 | 
			
		||||
 | 
			
		||||
1. Files are scanned in or parsed.
 | 
			
		||||
    * If they are parsed, its dude to requiring some changes to either naming, or adding additonal definitions (container generation, typedefs, etc).
 | 
			
		||||
2. All scanned or parsed code is refactored (identifiers substs) and/or formatted.
 | 
			
		||||
3. Singleheader generated.
 | 
			
		||||
4. Segemented headers and source generated.
 | 
			
		||||
 | 
			
		||||
## Templated container generation
 | 
			
		||||
 | 
			
		||||
The array and hashtable containers used across this library are generated using the following implementatioon:
 | 
			
		||||
 | 
			
		||||
* [containers.array.hpp](./components/containers.array.hpp)
 | 
			
		||||
* [containers.hashtable.hpp](./components/containers.hashtable.hpp)
 | 
			
		||||
 | 
			
		||||
These are functionally (and interface wise) equivalent to the library's `Array<Type>` `HashTable<Type>` within [containers.hpp](../base/dependencies/containers.hpp)
 | 
			
		||||
 | 
			
		||||
Both files follow the same patter of providing three procedures:
 | 
			
		||||
 | 
			
		||||
* `gen_<container>_base` : Intended to be called once, defines universal "base" definitions.
 | 
			
		||||
* `gen_<container>` : Called per instatiation of the container for a given set of dependent args.
 | 
			
		||||
* `gen_<container>_generic_selection_interface` : Intended to be called once after all of the instantiated containers have finished generating. It will generate a set of generic selection macros as described by Macro Usage section below.
 | 
			
		||||
 | 
			
		||||
A simple `<container>_DefinitionCounter` is used to know how many instantiations of the template have occured. This is used to determine how to define `GENERIC_SLOT_<ID>_<functionID>` for the generic interface along with how many slots the `_Generic` macro will need to have generated.
 | 
			
		||||
 | 
			
		||||
## Macro Usage
 | 
			
		||||
 | 
			
		||||
For the most part macros are kept minimal with exception to `_Generic`...  
 | 
			
		||||
*(I will be explaining this thing for the rest of this seciton along with gencpp c library's usage of it)*
 | 
			
		||||
 | 
			
		||||
The `_Generic` macro plays a key role in reducing direct need of the user to wrangle with mangled definition identifiers of 'templated' containers or for type coercion to map distinct data types to a common code path.
 | 
			
		||||
 | 
			
		||||
Because of its lack of use in many C11 libraries.. and, of those that do; they usually end up obfuscating it with excessive preprocessor abuse; Effort was put into minimizing how much of these macros are handled by the preprocessor vs gencpp itself.
 | 
			
		||||
 | 
			
		||||
The usual presentation (done bare) is the following:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
#define macro_that_selects_typeof_arg(arg, y) \
 | 
			
		||||
_Generic( (arg),                              \
 | 
			
		||||
    int            : some expression,         \
 | 
			
		||||
    double         : some other expression,   \
 | 
			
		||||
    struct Whatnot : something else again,    \
 | 
			
		||||
    default        : fallback expression      \
 | 
			
		||||
)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Where `_Generic` can be considered the follwoing (psuedo-C):
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
#define type_expr_pair(type, expr) type: expr
 | 
			
		||||
 | 
			
		||||
C_Expression _Generic( selector_arg, a_type_expr_pair, ... ) {
 | 
			
		||||
    switch( typeof(selector_arg)) {
 | 
			
		||||
        case a_type_expr_pair:
 | 
			
		||||
            return a_type_expr_pari.expr;
 | 
			
		||||
        ...
 | 
			
		||||
        default:
 | 
			
		||||
            return default.expr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The first `arg` of _Generic behaves as the "controlling expression" or the expression that resolves to a type which will dictate which of the following expressions provided after to `_Generic` will be resolved as the one used inline for the implemenation.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
For this library's purposes we'll be using the functional macro equivalent *(if there is an excpetion I'll link it at the end fo the section)*:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
#define macro_that_uses_selector_arg_for_resolving_a_fucntion( selecting_exp) \
 | 
			
		||||
_Generic( (arg),                                                              \
 | 
			
		||||
    int            : func_use_int,                                            \
 | 
			
		||||
    double         : func_use_double,                                         \
 | 
			
		||||
    struct Whatnot : func_use_Whatnot,                                        \
 | 
			
		||||
    default        : struct SIGNALS_FAILURE                                   \
 | 
			
		||||
) (selecting_exp)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In this case, we directly added `(selecting_exp)` to the end there.. as we want to directly have the macro resolve to calling a resolved procedure. A default has been set to a struct as that leads to a neat compiler message that would otherwise be impossible beause static_assert is a statement and thus cannot be used within a slot.
 | 
			
		||||
 | 
			
		||||
Now, even with gencpp generating this type-expression table, we still need wrapper macros to achieve function 'overloading' for the templated containers as _Generic has a [significant drawback](https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/c11-generic/):  
 | 
			
		||||
 | 
			
		||||
> Discarded expressions still have to be semantically valid.
 | 
			
		||||
 | 
			
		||||
The only way to absolve this issue [(without resorting to nasty preprocessor hacks)](https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md) is with wrapping expressions in 'slot' resolving macros that do not expand if the slot is not defined:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_1__function_sig )
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`GENERIC_SLOT_1__function_sig` is our warpper of a "`int, func_use_int`" pair. The `GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT` is a verbse named macro to indicate that that pair will be expanded ***ONLY IF*** its defined.
 | 
			
		||||
 | 
			
		||||
So for any given templated container interface. Expect the follwoing (taken straight from generation, and just cleaned up formatting):
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
#define gen_array_append( selector_arg, ... ) _Generic(                         \
 | 
			
		||||
(selector_arg ),                                                                \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_1__array_append )  \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_2__array_append )  \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_3__array_append )  \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_4__array_append )  \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_5__array_append )  \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_6__array_append )  \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_7__array_append )  \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_8__array_append )  \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_9__array_append )  \
 | 
			
		||||
    GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GEN_GENERIC_SLOT_10__array_append ) \
 | 
			
		||||
    default: gen_generic_selection_fail                                         \
 | 
			
		||||
) GEN_RESOLVED_FUNCTION_CALL( &selector_arg, __VA_ARGS__ )
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
*Note(Ed): Unfortunately I cannot get clang-format to output these macros sanely like the above..*  
 | 
			
		||||
*Eventually I'll add some basic builtin formatting but if the user has suggestions for something better I'm open ears...*
 | 
			
		||||
 | 
			
		||||
`GEN_RESOLVED_FUNCTION_CALL` is an empty define, its just to indicate that its intended to expand to a function call.
 | 
			
		||||
 | 
			
		||||
To see the thea actual macro definitions used: [generic_macros.h](./components/generic_macros.h) has them. They'll be injected right after the usual macros are positioned in the header file.
 | 
			
		||||
 
 | 
			
		||||
@@ -62,21 +62,126 @@ constexpr bool helper_use_c_definition = true;
 | 
			
		||||
 | 
			
		||||
int gen_main()
 | 
			
		||||
{
 | 
			
		||||
	gen::init();
 | 
			
		||||
	Context ctx {};
 | 
			
		||||
	gen::init(& ctx);
 | 
			
		||||
 | 
			
		||||
	PreprocessorDefines.append(txt("GEN_API_C_BEGIN"));
 | 
			
		||||
	PreprocessorDefines.append(txt("GEN_API_C_END"));
 | 
			
		||||
	PreprocessorDefines.append(txt("Array("));
 | 
			
		||||
	PreprocessorDefines.append(txt("HashTable("));
 | 
			
		||||
	PreprocessorDefines.append(txt("GEN_NS_PARSER"));
 | 
			
		||||
	PreprocessorDefines.append(txt("GEN_NS_PARSER_BEGIN"));
 | 
			
		||||
	PreprocessorDefines.append(txt("GEN_NS_PARSER_END"));
 | 
			
		||||
	PreprocessorDefines.append(txt("Using_Code("));
 | 
			
		||||
	PreprocessorDefines.append(txt("Using_CodeOps("));
 | 
			
		||||
	PreprocessorDefines.append(txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"));
 | 
			
		||||
	PreprocessorDefines.append(txt("GEN_OPITMIZE_MAPPINGS_END"));
 | 
			
		||||
	PreprocessorDefines.append(txt("GEN_PARAM_DEFAULT"));
 | 
			
		||||
	//PreprocessorDefines.append(txt("GEN_EXECUTION_EXPRESSION_SUPPORT"));
 | 
			
		||||
	register_macros( args(
 | 
			
		||||
		(Macro { txt("bit"),                          MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("bitfield_is_set"),              MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN_C_LIKE_CPP"),               MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("cast"),                         MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("ccast"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("rcast"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("pcast"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("scast"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("stringize_va"),                 MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("stringize"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("do_once"),                      MT_Expression, MF_Functional }), 
 | 
			
		||||
		(Macro { txt("do_once_defer"),                MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("do_once_start"),                MT_Statement,  MF_Null       }), 
 | 
			
		||||
		(Macro { txt("do_once_end"),                  MT_Statement,  MF_Null       }), 
 | 
			
		||||
		(Macro { txt("labeled_scope_start"),          MT_Statement,  MF_Null       }), 
 | 
			
		||||
		(Macro { txt("labeled_scope_end"),            MT_Statement,  MF_Null       }), 
 | 
			
		||||
		(Macro { txt("compiler_decorated_func_name"), MT_Expression, MF_Null       }), 
 | 
			
		||||
		(Macro { txt("num_args_impl"),                MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("num_args"),                     MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("count_of"),                     MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("clamp"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("is_between"),                   MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("size_of"),                      MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("min"),                          MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("max"),                          MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("offset_of"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("static_assert"),                MT_Statement,  MF_Functional }),
 | 
			
		||||
		(Macro { txt("typeof"),                       MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN_API_C_BEGIN"),              MT_Statement,  MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN_API_C_END"),                MT_Statement,  MF_Null       }),
 | 
			
		||||
		(Macro { txt("nullptr"),                      MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN_REMOVE_PTR"),               MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN_PARAM_DEFAULT"),            MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("struct_init"),                  MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"),  MT_Statement,  MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN_OPITMIZE_MAPPINGS_END"),    MT_Statement,  MF_Null       }),
 | 
			
		||||
		(Macro { txt("Array"),                        MT_Typename,   MF_Functional }),
 | 
			
		||||
		(Macro { txt("HashTable"),                    MT_Typename,   MF_Functional }),
 | 
			
		||||
		(Macro { txt("Using_Code"),                   MT_Statement,  MF_Functional }),
 | 
			
		||||
		(Macro { txt("Using_CodeOps"),                MT_Statement,  MF_Functional }),
 | 
			
		||||
		(Macro { txt("kilobytes"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("megabytes"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("gigabytes"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("terabytes"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN__ONES"),                    MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN__HIGHS"),                   MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN__HAS_ZERO"),                MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("zero_item"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("zero_array"),                   MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN_DEFAULT_MEMORY_ALIGNMENT"), MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN_DEFAULT_ALLOCATOR_FLAGS"),  MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("alloc_item"),                   MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("alloc_array"),                  MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("malloc"),                       MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("mfree"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN_PRINTF_MAXLEN"),            MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("cast_to_str"),                  MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("current"),                      MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("txt"),                          MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN_FILE_OPEN_PROC"),           MT_Statement,  MF_Functional | MF_Expects_Body }),
 | 
			
		||||
		(Macro { txt("GEN_FILE_READ_AT_PROC"),        MT_Statement,  MF_Functional | MF_Expects_Body }),
 | 
			
		||||
		(Macro { txt("GEN_FILE_WRITE_AT_PROC"),       MT_Statement,  MF_Functional | MF_Expects_Body }),
 | 
			
		||||
		(Macro { txt("GEN_FILE_SEEK_PROC"),           MT_Statement,  MF_Functional | MF_Expects_Body }),
 | 
			
		||||
		(Macro { txt("GEN_FILE_CLOSE_PROC"),          MT_Statement,  MF_Functional | MF_Expects_Body }),
 | 
			
		||||
		(Macro { txt("log_failure"),                  MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("operator"),                     MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("InvalidCode"),                  MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("NullCode"),                     MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("Verify_POD"),                   MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("gen_main"),                     MT_Statement,  MF_Null       })
 | 
			
		||||
	));
 | 
			
		||||
	register_macros( args(
 | 
			
		||||
		(Macro { txt("name"),                         MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("code"),                         MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("args"),                         MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("code_str"),                     MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("code_fmt"),                     MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("parse_fmt"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("token_fmt"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("check_member_val"),             MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("check_member_str"),             MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("check_member_content"),         MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("check_member_ast"),             MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("check_params"),                 MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("check_param_eq_ret"),           MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("specs"),                        MT_Expression, MF_Functional | MF_Allow_As_Identifier }),
 | 
			
		||||
		(Macro { txt("name_check"),                   MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("null_check"),                   MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("def_body_start"),               MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("def_body_code_array_start"),    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("move_forward"),                 MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("skip_whitespace"),              MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("end_line"),                     MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("check_parse_args"),             MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("currtok_noskip"),               MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("currtok"),                      MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("peektok"),                      MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("prevtok"),                      MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("nexttok"),                      MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("nexttok_noskip"),               MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("eat"),                          MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("left"),                         MT_Expression, MF_Null       | MF_Allow_As_Identifier }),
 | 
			
		||||
		(Macro { txt("def_assign"),                   MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("CHECK_WAS_DEFINED"),            MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("check_noskip"),                 MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("check"),                        MT_Expression, MF_Functional | MF_Allow_As_Identifier }),
 | 
			
		||||
		(Macro { txt("push_scope"),                   MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("cut_length"),                   MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("cut_ptr"),                      MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("pos"),                          MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("move_fwd"),                     MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("Entry"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("CheckEndParams"),               MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("UseTemplateCapture"),           MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("check_current"),                MT_Expression, MF_Functional })
 | 
			
		||||
	));
 | 
			
		||||
 | 
			
		||||
	Code push_ignores           = scan_file( path_base "helpers/push_ignores.inline.hpp" );
 | 
			
		||||
	Code pop_ignores            = scan_file( path_base "helpers/pop_ignores.inline.hpp" );
 | 
			
		||||
@@ -138,8 +243,8 @@ int gen_main()
 | 
			
		||||
			CodeTemplate tmpl = cast(CodeTemplate, entry);
 | 
			
		||||
			if ( tmpl->Declaration->Name.contains(txt("swap")))
 | 
			
		||||
			{
 | 
			
		||||
				log_fmt("SWAPPED");
 | 
			
		||||
				CodeBody macro_swap = parse_global_body( txt(R"(
 | 
			
		||||
				register_macro({ txt("swap"), MT_Expression, MF_Functional });
 | 
			
		||||
				CodeDefine macro_swap = parse_define( txt(R"(
 | 
			
		||||
#define swap( a, b )        \
 | 
			
		||||
do                          \
 | 
			
		||||
{                           \
 | 
			
		||||
@@ -240,7 +345,8 @@ do                          \
 | 
			
		||||
		{
 | 
			
		||||
			if ( str_contains(entry->Name, txt("Msg_Invalid_Value")))
 | 
			
		||||
			{
 | 
			
		||||
				CodeDefine define = def_define(entry->Name, entry->Value->Content);
 | 
			
		||||
				Opts_def_define opts = { {}, entry->Value->Content };
 | 
			
		||||
				CodeDefine define = def_define(entry->Name, MT_Expression, opts );
 | 
			
		||||
				header_printing.append(define);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
@@ -253,7 +359,7 @@ do                          \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Code array_ssize         = gen_array(txt("gen_ssize"), txt("Array_gen_ssize"));
 | 
			
		||||
	Code array_string_cached = gen_array(txt("gen_StringCached"), txt("Array_gen_StringCached"));
 | 
			
		||||
	Code array_string_cached = gen_array(txt("gen_StrCached"), txt("Array_gen_StrCached"));
 | 
			
		||||
 | 
			
		||||
	CodeBody parsed_header_strings = parse_file( path_base "dependencies/strings.hpp" );
 | 
			
		||||
	CodeBody header_strings        = def_body(CT_Global_Body);
 | 
			
		||||
@@ -406,7 +512,8 @@ do                          \
 | 
			
		||||
			CodeVar var = cast(CodeVar, entry);
 | 
			
		||||
			if (var->Specs.has(Spec_Constexpr) > -1)
 | 
			
		||||
			{
 | 
			
		||||
				CodeDefine define = def_define(entry->Name, entry->Value->Content);
 | 
			
		||||
				Opts_def_define opts = { {}, entry->Value->Content };
 | 
			
		||||
				CodeDefine define = def_define(entry->Name, MT_Expression, opts);
 | 
			
		||||
				header_filesystem.append(define);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
@@ -588,8 +695,102 @@ do                          \
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CodeBody array_token = gen_array(txt("gen_Token"), txt("Array_gen_Token"));
 | 
			
		||||
 | 
			
		||||
	CodeBody parsed_parser_types = parse_file( path_base "components/parser_types.hpp" );
 | 
			
		||||
	CodeBody parser_types        = def_body(CT_Global_Body);
 | 
			
		||||
	for ( Code entry = parsed_parser_types.begin(); entry != parsed_parser_types.end(); ++ entry ) switch(entry->Type)
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Preprocess_IfDef:
 | 
			
		||||
		{
 | 
			
		||||
			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_parser_types, parser_types );
 | 
			
		||||
			if (found) break;
 | 
			
		||||
 | 
			
		||||
			parser_types.append(entry);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Enum:
 | 
			
		||||
		{
 | 
			
		||||
			if (entry->Name.Len)
 | 
			
		||||
			{
 | 
			
		||||
				convert_cpp_enum_to_c(cast(CodeEnum, entry), parser_types);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			parser_types.append(entry);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Struct:
 | 
			
		||||
		{
 | 
			
		||||
			if ( entry->Name.is_equal(txt("Token")))
 | 
			
		||||
			{
 | 
			
		||||
				// Add struct Token forward and typedef early.
 | 
			
		||||
				CodeStruct  token_fwd     = parse_struct(code( struct Token; ));
 | 
			
		||||
				CodeTypedef token_typedef = parse_typedef(code( typedef struct Token Token; ));
 | 
			
		||||
				parser_types.append(token_fwd);
 | 
			
		||||
				parser_types.append(token_typedef);
 | 
			
		||||
 | 
			
		||||
				// Skip typedef since we added it
 | 
			
		||||
				b32 continue_for = true;
 | 
			
		||||
				for (Code array_entry = array_token.begin(); continue_for && array_entry != array_token.end(); ++ array_entry) switch (array_entry->Type)
 | 
			
		||||
				{
 | 
			
		||||
					case CT_Typedef:
 | 
			
		||||
					{
 | 
			
		||||
						// pop the array entry
 | 
			
		||||
						array_token->NumEntries -= 1;
 | 
			
		||||
						Code next                   = array_entry->Next;
 | 
			
		||||
						Code prev                   = array_entry->Prev;
 | 
			
		||||
						next->Prev                  = array_entry->Prev;
 | 
			
		||||
						prev->Next                  = next;
 | 
			
		||||
						if ( array_token->Front == array_entry )
 | 
			
		||||
							array_token->Front = next;
 | 
			
		||||
 | 
			
		||||
						parser_types.append(array_entry);
 | 
			
		||||
						continue_for = false;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Append the struct
 | 
			
		||||
				parser_types.append(entry);
 | 
			
		||||
 | 
			
		||||
				// Append the token array
 | 
			
		||||
				parser_types.append(array_token);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			CodeTypedef struct_tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; )));
 | 
			
		||||
			parser_types.append(struct_tdef);
 | 
			
		||||
			parser_types.append(entry);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Variable:
 | 
			
		||||
		{
 | 
			
		||||
			CodeVar var = cast(CodeVar, entry);
 | 
			
		||||
			if (var->Specs && var->Specs.has(Spec_Constexpr) > -1) {
 | 
			
		||||
				Code define_ver = untyped_str(token_fmt(
 | 
			
		||||
						"name",  var->Name
 | 
			
		||||
					,	"value", var->Value->Content
 | 
			
		||||
					,	"type",  var->ValueType.to_strbuilder().to_str()
 | 
			
		||||
					,	"#define <name> (<type>) <value>\n"
 | 
			
		||||
				));
 | 
			
		||||
				parser_types.append(define_ver);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			parser_types.append(entry);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			parser_types.append(entry);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Used to track which functions need generic selectors.
 | 
			
		||||
	Array(CodeFn) code_c_interface = array_init_reserve<CodeFn>(GlobalAllocator, 16);
 | 
			
		||||
	Array(CodeFn) code_c_interface = array_init_reserve<CodeFn>(_ctx->Allocator_Temp, 16);
 | 
			
		||||
 | 
			
		||||
	CodeBody parsed_ast = parse_file( path_base "components/ast.hpp" );
 | 
			
		||||
	CodeBody ast        = def_body(CT_Global_Body);
 | 
			
		||||
@@ -647,9 +848,9 @@ do                          \
 | 
			
		||||
					{
 | 
			
		||||
						Str   old_prefix  = txt("code_");
 | 
			
		||||
						Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len };
 | 
			
		||||
						StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name );
 | 
			
		||||
						StrBuilder new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "code__%S", actual_name );
 | 
			
		||||
 | 
			
		||||
						fn->Name = get_cached_string(new_name);
 | 
			
		||||
						fn->Name = cache_str(new_name);
 | 
			
		||||
						code_c_interface.append(fn);
 | 
			
		||||
					}
 | 
			
		||||
					ast.append(entry);
 | 
			
		||||
@@ -702,7 +903,7 @@ R"(#define AST_ArrSpecs_Cap \
 | 
			
		||||
(                           \
 | 
			
		||||
	AST_POD_Size              \
 | 
			
		||||
	- sizeof(Code)            \
 | 
			
		||||
	- sizeof(StringCached)    \
 | 
			
		||||
	- sizeof(StrCached)    \
 | 
			
		||||
	- sizeof(Code) * 2        \
 | 
			
		||||
	- sizeof(Token*)          \
 | 
			
		||||
	- sizeof(Code)            \
 | 
			
		||||
@@ -716,7 +917,8 @@ R"(#define AST_ArrSpecs_Cap \
 | 
			
		||||
					ast.append(def);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				CodeDefine def = def_define(var->Name, var->Value.to_strbuilder());
 | 
			
		||||
				Opts_def_define opts = { {}, var->Value.to_strbuilder() };
 | 
			
		||||
				CodeDefine def = def_define(var->Name, MT_Expression, opts );
 | 
			
		||||
				ast.append(def);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
@@ -737,6 +939,7 @@ R"(#define AST_ArrSpecs_Cap \
 | 
			
		||||
		txt("CodeClass"),
 | 
			
		||||
		txt("CodeConstructor"),
 | 
			
		||||
		txt("CodeDefine"),
 | 
			
		||||
		txt("CodeDefineParams"),
 | 
			
		||||
		txt("CodeDestructor"),
 | 
			
		||||
		txt("CodeEnum"),
 | 
			
		||||
		txt("CodeExec"),
 | 
			
		||||
@@ -791,17 +994,17 @@ R"(#define AST_ArrSpecs_Cap \
 | 
			
		||||
				default: gen_generic_selection (Fail case)                                    \
 | 
			
		||||
			) GEN_RESOLVED_FUNCTION_CALL( code, ... )                                       \
 | 
			
		||||
			*/
 | 
			
		||||
			StrBuilder generic_selector = StrBuilder::make_reserve(GlobalAllocator, kilobytes(2));
 | 
			
		||||
			StrBuilder generic_selector = StrBuilder::make_reserve(_ctx->Allocator_Temp, kilobytes(2));
 | 
			
		||||
			for ( CodeFn fn : code_c_interface )
 | 
			
		||||
			{
 | 
			
		||||
				generic_selector.clear();
 | 
			
		||||
				Str   private_prefix  = txt("code__");
 | 
			
		||||
				Str   actual_name     = { fn->Name.Ptr + private_prefix.Len, fn->Name.Len - private_prefix.Len };
 | 
			
		||||
				StrBuilder interface_name  = StrBuilder::fmt_buf(GlobalAllocator, "code_%S", actual_name );
 | 
			
		||||
				StrBuilder interface_name  = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "code_%S", actual_name );
 | 
			
		||||
 | 
			
		||||
				// Resolve generic's arguments
 | 
			
		||||
				b32    has_args   = fn->Params->NumEntries > 1;
 | 
			
		||||
				StrBuilder params_str = StrBuilder::make_reserve(GlobalAllocator, 32);
 | 
			
		||||
				StrBuilder params_str = StrBuilder::make_reserve(_ctx->Allocator_Temp, 32);
 | 
			
		||||
				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
 | 
			
		||||
					if (param->Next == nullptr) {
 | 
			
		||||
@@ -910,6 +1113,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CodeBody array_arena           = gen_array(txt("gen_Arena"), txt("Array_gen_Arena"));
 | 
			
		||||
	CodeBody array_pool            = gen_array(txt("gen_Pool"),  txt("Array_gen_Pool"));
 | 
			
		||||
	CodeBody ht_preprocessor_macro = gen_hashtable(txt("gen_Macro"), txt("MacroTable"));
 | 
			
		||||
 | 
			
		||||
	CodeBody parsed_interface = parse_file( path_base "components/interface.hpp" );
 | 
			
		||||
	CodeBody interface        = def_body(CT_Global_Body);
 | 
			
		||||
	for ( Code entry = parsed_interface.begin(); entry != parsed_interface.end(); ++ entry ) switch( entry->Type )
 | 
			
		||||
@@ -919,6 +1126,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
			b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_interface, interface );
 | 
			
		||||
			if (found) break;
 | 
			
		||||
 | 
			
		||||
			found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_interface, interface);
 | 
			
		||||
			if (found) break;
 | 
			
		||||
 | 
			
		||||
			interface.append(entry);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
@@ -929,24 +1139,17 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
			CodeFn fn = cast(CodeFn, entry);
 | 
			
		||||
			Code prev = entry->Prev;
 | 
			
		||||
 | 
			
		||||
			if (prev && prev->Name.is_equal(entry->Name)) {
 | 
			
		||||
				// rename second definition so there isn't a symbol conflict
 | 
			
		||||
				StrBuilder postfix_arr = StrBuilder::fmt_buf(GlobalAllocator, "%S_arr", entry->Name);
 | 
			
		||||
				entry->Name = get_cached_string(postfix_arr.to_str());
 | 
			
		||||
				postfix_arr.free();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			b32 handled= false;
 | 
			
		||||
			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
 | 
			
		||||
				Str prefix      = txt("def_");
 | 
			
		||||
				Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len  - prefix.Len };
 | 
			
		||||
				Str new_name    = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str();
 | 
			
		||||
				Str new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str();
 | 
			
		||||
 | 
			
		||||
				// Resolve define's arguments
 | 
			
		||||
				b32    has_args   = fn->Params->NumEntries > 1;
 | 
			
		||||
				StrBuilder params_str = StrBuilder::make_reserve(GlobalAllocator, 32);
 | 
			
		||||
				StrBuilder params_str = StrBuilder::make_reserve(_ctx->Allocator_Temp, 32);
 | 
			
		||||
				for (CodeParams other_param = fn->Params; other_param != opt_param; ++ other_param) {
 | 
			
		||||
					if ( other_param == opt_param ) {
 | 
			
		||||
						params_str.append_fmt( "%S", other_param->Name );
 | 
			
		||||
@@ -970,7 +1173,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
				,	tmpl_fn_macro
 | 
			
		||||
				));
 | 
			
		||||
 | 
			
		||||
				fn->Name = get_cached_string(new_name);
 | 
			
		||||
				fn->Name = cache_str(new_name);
 | 
			
		||||
				interface.append(fn);
 | 
			
		||||
				interface.append(fn_macro);
 | 
			
		||||
				if (entry->Next && entry->Next->Type != CT_NewLine) {
 | 
			
		||||
@@ -1021,9 +1224,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
			{
 | 
			
		||||
				Str   old_prefix  = txt("code_");
 | 
			
		||||
				Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len };
 | 
			
		||||
				StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name );
 | 
			
		||||
				StrBuilder new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "code__%S", actual_name );
 | 
			
		||||
 | 
			
		||||
				fn->Name = get_cached_string(new_name);
 | 
			
		||||
				fn->Name = cache_str(new_name);
 | 
			
		||||
			}
 | 
			
		||||
			inlines.append(entry);
 | 
			
		||||
		}
 | 
			
		||||
@@ -1111,8 +1314,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
			if (var->Specs)
 | 
			
		||||
			{
 | 
			
		||||
				s32 constexpr_found = var->Specs.remove( Spec_Constexpr );
 | 
			
		||||
				if (constexpr_found > -1) {
 | 
			
		||||
					CodeDefine define = def_define(entry->Name, entry->Value->Content);
 | 
			
		||||
				if (constexpr_found > -1)
 | 
			
		||||
				{
 | 
			
		||||
					Opts_def_define opts = { {},  entry->Value->Content };
 | 
			
		||||
					CodeDefine define = def_define(entry->Name, MT_Expression, opts );
 | 
			
		||||
					header_end.append(define);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
@@ -1142,17 +1347,31 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
#pragma endregion Resolve Dependencies
 | 
			
		||||
 | 
			
		||||
#pragma region Resolve Components
 | 
			
		||||
	CodeBody array_arena = gen_array(txt("gen_Arena"), txt("Array_gen_Arena"));
 | 
			
		||||
	CodeBody array_pool  = gen_array(txt("gen_Pool"),  txt("Array_gen_Pool"));
 | 
			
		||||
	CodeBody array_token = gen_array(txt("gen_Token"), txt("Array_gen_Token"));
 | 
			
		||||
 | 
			
		||||
	Code src_start              = scan_file(           "components/src_start.c" );
 | 
			
		||||
	Code src_static_data 	      = scan_file( path_base "components/static_data.cpp" );
 | 
			
		||||
	Code src_ast_case_macros    = scan_file( path_base "components/ast_case_macros.cpp" );
 | 
			
		||||
	Code src_code_serialization = scan_file( path_base "components/code_serialization.cpp" );
 | 
			
		||||
	Code src_interface          = scan_file( path_base "components/interface.cpp" );
 | 
			
		||||
 | 
			
		||||
	Code src_parsing_interface  = scan_file( path_base "components/interface.parsing.cpp" );
 | 
			
		||||
	Code src_untyped            = scan_file( path_base "components/interface.untyped.cpp" );
 | 
			
		||||
	Code src_parser_case_macros = scan_file( path_base "components/parser_case_macros.cpp" );
 | 
			
		||||
 | 
			
		||||
	CodeBody parsed_src_interface = parse_file( path_base "components/interface.cpp" );
 | 
			
		||||
	CodeBody src_interface        = def_body(CT_Global_Body);
 | 
			
		||||
	for ( Code entry = parsed_src_interface.begin(); entry != parsed_src_interface.end(); ++ entry ) switch( entry ->Type )
 | 
			
		||||
	{
 | 
			
		||||
		case CT_Function:
 | 
			
		||||
		{
 | 
			
		||||
			CodeFn fn = cast(CodeFn, entry);
 | 
			
		||||
			Code prev = entry->Prev;
 | 
			
		||||
			src_interface.append(fn);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			src_interface.append(entry);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CodeBody parsed_src_ast = parse_file( path_base "components/ast.cpp" );
 | 
			
		||||
	CodeBody src_ast        = def_body(CT_Global_Body);
 | 
			
		||||
@@ -1176,9 +1395,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
			{
 | 
			
		||||
				Str   old_prefix  = txt("code_");
 | 
			
		||||
				Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len };
 | 
			
		||||
				StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name );
 | 
			
		||||
				StrBuilder new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "code__%S", actual_name );
 | 
			
		||||
 | 
			
		||||
				fn->Name = get_cached_string(new_name);
 | 
			
		||||
				fn->Name = cache_str(new_name);
 | 
			
		||||
			}
 | 
			
		||||
			src_ast.append(entry);
 | 
			
		||||
		}
 | 
			
		||||
@@ -1211,28 +1430,14 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		{
 | 
			
		||||
			CodeFn fn = cast(CodeFn, entry);
 | 
			
		||||
			Code prev = entry->Prev;
 | 
			
		||||
 | 
			
		||||
			for ( CodeParams arr_param : fn->Params )
 | 
			
		||||
				if (	fn->Name.starts_with(txt("def_"))
 | 
			
		||||
					&&	(		(arr_param->ValueType->Name.starts_with(txt("Specifier")) && fn->Params->NumEntries > 1)
 | 
			
		||||
							||	arr_param->ValueType->Name.starts_with(txt("Code")) )
 | 
			
		||||
				)
 | 
			
		||||
				{
 | 
			
		||||
					// rename second definition so there isn't a symbol conflict
 | 
			
		||||
					StrBuilder postfix_arr = StrBuilder::fmt_buf(GlobalAllocator, "%S_arr", fn->Name);
 | 
			
		||||
					fn->Name = get_cached_string(postfix_arr.to_str());
 | 
			
		||||
					postfix_arr.free();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_")))
 | 
			
		||||
			{
 | 
			
		||||
				// The frontend names are warapped in macros so we need to give it the intenral symbol name
 | 
			
		||||
				Str prefix      = txt("def_");
 | 
			
		||||
				Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len  - prefix.Len };
 | 
			
		||||
				Str new_name    = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str();
 | 
			
		||||
 | 
			
		||||
				fn->Name = get_cached_string(new_name);
 | 
			
		||||
				Str new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str();
 | 
			
		||||
				fn->Name = cache_str(new_name);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			src_upfront.append(fn);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
@@ -1267,51 +1472,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Struct:
 | 
			
		||||
		{
 | 
			
		||||
			if ( entry->Name.is_equal(txt("Token")))
 | 
			
		||||
			{
 | 
			
		||||
				// Add struct Token forward and typedef early.
 | 
			
		||||
				CodeStruct  token_fwd     = parse_struct(code( struct Token; ));
 | 
			
		||||
				CodeTypedef token_typedef = parse_typedef(code( typedef struct Token Token; ));
 | 
			
		||||
				src_lexer.append(token_fwd);
 | 
			
		||||
				src_lexer.append(token_typedef);
 | 
			
		||||
 | 
			
		||||
				// Skip typedef since we added it
 | 
			
		||||
				b32 continue_for = true;
 | 
			
		||||
				for (Code array_entry = array_token.begin(); continue_for && array_entry != array_token.end(); ++ array_entry) switch (array_entry->Type)
 | 
			
		||||
				{
 | 
			
		||||
					case CT_Typedef:
 | 
			
		||||
					{
 | 
			
		||||
						// pop the array entry
 | 
			
		||||
						array_token->NumEntries -= 1;
 | 
			
		||||
						Code next                   = array_entry->Next;
 | 
			
		||||
						Code prev                   = array_entry->Prev;
 | 
			
		||||
						next->Prev                  = array_entry->Prev;
 | 
			
		||||
						prev->Next                  = next;
 | 
			
		||||
						if ( array_token->Front == array_entry )
 | 
			
		||||
							array_token->Front = next;
 | 
			
		||||
 | 
			
		||||
						src_lexer.append(array_entry);
 | 
			
		||||
						continue_for = false;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Append the struct
 | 
			
		||||
				src_lexer.append(entry);
 | 
			
		||||
 | 
			
		||||
				// Append the token array
 | 
			
		||||
				src_lexer.append(array_token);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			CodeTypedef struct_tdef = parse_typedef(token_fmt("name", entry->Name, stringize( typedef struct <name> <name>; )));
 | 
			
		||||
			src_lexer.append(entry);
 | 
			
		||||
			src_lexer.append(struct_tdef);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
		case CT_Variable:
 | 
			
		||||
		{
 | 
			
		||||
			CodeVar var = cast(CodeVar, entry);
 | 
			
		||||
@@ -1416,21 +1576,23 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
	Code r_header_timing       = refactor(header_timing);
 | 
			
		||||
	Code rf_header_parsing     = refactor_and_format(header_parsing);
 | 
			
		||||
 | 
			
		||||
	Code rf_types      = refactor_and_format(types);
 | 
			
		||||
	Code rf_ecode      = refactor_and_format(ecode);
 | 
			
		||||
	Code rf_eoperator  = refactor_and_format(eoperator);
 | 
			
		||||
	Code rf_especifier = refactor_and_format(especifier);
 | 
			
		||||
	Code rf_ast        = refactor_and_format(ast);
 | 
			
		||||
	Code rf_code_types = refactor_and_format(code_types);
 | 
			
		||||
	Code rf_ast_types  = refactor_and_format(ast_types);
 | 
			
		||||
	Code rf_types        = refactor_and_format(types);
 | 
			
		||||
	Code rf_parser_types = refactor_and_format(parser_types);
 | 
			
		||||
	Code rf_ecode        = refactor_and_format(ecode);
 | 
			
		||||
	Code rf_eoperator    = refactor_and_format(eoperator);
 | 
			
		||||
	Code rf_especifier   = refactor_and_format(especifier);
 | 
			
		||||
	Code rf_ast          = refactor_and_format(ast);
 | 
			
		||||
	Code rf_code_types   = refactor_and_format(code_types);
 | 
			
		||||
	Code rf_ast_types    = refactor_and_format(ast_types);
 | 
			
		||||
 | 
			
		||||
	Code rf_interface = refactor_and_format(interface);
 | 
			
		||||
	Code rf_inlines   = refactor_and_format(inlines);
 | 
			
		||||
 | 
			
		||||
	Code rf_array_string_cached = refactor_and_format(array_string_cached);
 | 
			
		||||
	Code rf_header_end          = refactor_and_format(header_end);
 | 
			
		||||
	Code rf_header_builder      = refactor_and_format(header_builder);
 | 
			
		||||
	Code rf_header_scanner      = refactor_and_format( scan_file( path_base "auxillary/scanner.hpp" ));
 | 
			
		||||
	Code rf_ht_preprocessor_macro = refactor_and_format(ht_preprocessor_macro);
 | 
			
		||||
	Code rf_array_string_cached   = refactor_and_format(array_string_cached);
 | 
			
		||||
	Code rf_header_end            = refactor_and_format(header_end);
 | 
			
		||||
	Code rf_header_builder        = refactor_and_format(header_builder);
 | 
			
		||||
	Code rf_header_scanner        = refactor_and_format( scan_file( path_base "auxillary/scanner.hpp" ));
 | 
			
		||||
 | 
			
		||||
	Code r_src_dep_start  = refactor(src_dep_start);
 | 
			
		||||
	Code r_src_debug      = refactor(src_debug);
 | 
			
		||||
@@ -1450,8 +1612,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
	Code r_src_ast_case_macros    = refactor(src_ast_case_macros);
 | 
			
		||||
	Code r_src_ast                = refactor(src_ast);
 | 
			
		||||
	Code r_src_code_serialization = refactor(src_code_serialization);
 | 
			
		||||
	Code r_src_parser_case_macros = refactor(src_parser_case_macros);
 | 
			
		||||
 | 
			
		||||
	Code r_src_interface        = refactor(src_interface);
 | 
			
		||||
	Code r_src_interface        = refactor_and_format(src_interface);
 | 
			
		||||
	Code r_src_upfront          = refactor_and_format(src_upfront);
 | 
			
		||||
	Code r_src_lexer            = refactor_and_format(src_lexer);
 | 
			
		||||
	Code rf_array_code_typename = refactor_and_format(array_code_typename);
 | 
			
		||||
@@ -1481,10 +1644,11 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		header.print_fmt( roll_own_dependencies_guard_start );
 | 
			
		||||
		header.print( r_header_platform );
 | 
			
		||||
		header.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
			
		||||
		header.print_fmt( "GEN_API_C_BEGIN\n" );
 | 
			
		||||
 | 
			
		||||
		header.print( r_header_macros );
 | 
			
		||||
		header.print( header_generic_macros );
 | 
			
		||||
 | 
			
		||||
		header.print_fmt( "\nGEN_API_C_BEGIN\n" );
 | 
			
		||||
 | 
			
		||||
		header.print( r_header_basic_types );
 | 
			
		||||
		header.print( r_header_debug );
 | 
			
		||||
		header.print( rf_header_memory );
 | 
			
		||||
@@ -1517,6 +1681,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		header.print( rf_eoperator );
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
		header.print( rf_especifier );
 | 
			
		||||
		header.print( rf_etoktype );
 | 
			
		||||
		header.print( rf_parser_types );
 | 
			
		||||
		header.print_fmt("#pragma endregion Types\n\n");
 | 
			
		||||
 | 
			
		||||
		header.print_fmt("#pragma region AST\n");
 | 
			
		||||
@@ -1525,6 +1691,15 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		header.print( rf_ast_types );
 | 
			
		||||
		header.print_fmt("\n#pragma endregion AST\n");
 | 
			
		||||
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
		header.print( rf_array_arena );
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
		header.print( rf_array_pool);
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
		header.print( rf_array_string_cached );
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
		header.print( rf_ht_preprocessor_macro );
 | 
			
		||||
 | 
			
		||||
		header.print( rf_interface );
 | 
			
		||||
		header.print(fmt_newline);
 | 
			
		||||
 | 
			
		||||
@@ -1533,7 +1708,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		header.print_fmt("#pragma endregion Inlines\n");
 | 
			
		||||
 | 
			
		||||
		header.print(fmt_newline);
 | 
			
		||||
		header.print( rf_array_string_cached );
 | 
			
		||||
 | 
			
		||||
		header.print( rf_header_end );
 | 
			
		||||
		header.print( rf_header_builder );
 | 
			
		||||
@@ -1573,11 +1747,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		header.print_fmt( "\nGEN_NS_BEGIN\n");
 | 
			
		||||
		header.print_fmt( "GEN_API_C_BEGIN\n" );
 | 
			
		||||
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
		header.print( rf_array_arena );
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
		header.print( rf_array_pool);
 | 
			
		||||
 | 
			
		||||
		header.print( r_src_static_data );
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
 | 
			
		||||
@@ -1591,11 +1760,11 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		header.print( r_src_interface );
 | 
			
		||||
		header.print( r_src_upfront );
 | 
			
		||||
		header.print_fmt( "\n#pragma region Parsing\n\n" );
 | 
			
		||||
		header.print( rf_etoktype );
 | 
			
		||||
		header.print( r_src_lexer );
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
		header.print( rf_array_code_typename );
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
		header.print( r_src_parser_case_macros );
 | 
			
		||||
		header.print( rf_src_parser );
 | 
			
		||||
		header.print( r_src_parsing );
 | 
			
		||||
		header.print_fmt( "\n#pragma endregion Parsing\n" );
 | 
			
		||||
@@ -1646,7 +1815,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
	{
 | 
			
		||||
		Builder src = Builder::open( "gen/gen.dep.c" );
 | 
			
		||||
		src.print_fmt( "GEN_NS_BEGIN\n");
 | 
			
		||||
		src.print_fmt( "GEN_API_C_BEGIN\n" );
 | 
			
		||||
 | 
			
		||||
		builder_print_fmt(src, generation_notice );
 | 
			
		||||
		builder_print_fmt( src, "// This file is intended to be included within gen.cpp (There is no pragma diagnostic ignores)\n" );
 | 
			
		||||
@@ -1684,6 +1852,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		header.print( rf_eoperator );
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
		header.print( rf_especifier );
 | 
			
		||||
		header.print( rf_etoktype );
 | 
			
		||||
		header.print( rf_parser_types );
 | 
			
		||||
		header.print_fmt("#pragma endregion Types\n\n");
 | 
			
		||||
 | 
			
		||||
		header.print_fmt("#pragma region AST\n");
 | 
			
		||||
@@ -1737,7 +1907,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		src.print( r_src_interface );
 | 
			
		||||
		src.print( r_src_upfront );
 | 
			
		||||
		src.print_fmt( "\n#pragma region Parsing\n\n" );
 | 
			
		||||
		src.print( rf_etoktype );
 | 
			
		||||
		src.print( r_src_lexer );
 | 
			
		||||
		src.print( fmt_newline);
 | 
			
		||||
		src.print( rf_array_code_typename );
 | 
			
		||||
@@ -1751,11 +1920,11 @@ R"(#define <interface_name>( code ) _Generic( (code), \
 | 
			
		||||
		src.print( rf_src_builder );
 | 
			
		||||
		src.print( rf_src_scanner );
 | 
			
		||||
 | 
			
		||||
		src.print_fmt( "GEN_API_C_END\n" );
 | 
			
		||||
		src.print_fmt( "\nGEN_NS_END\n");
 | 
			
		||||
		src.write();
 | 
			
		||||
	}
 | 
			
		||||
#pragma endregion Segmented
 | 
			
		||||
 | 
			
		||||
	gen::deinit();
 | 
			
		||||
	gen::deinit( & ctx);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ word global,                       gen_global
 | 
			
		||||
word internal,                     gen_internal
 | 
			
		||||
word local_persist,                gen_local_persist
 | 
			
		||||
word bit,                          gen_bit
 | 
			
		||||
word bitfield_is_equal,            gen_bitfield_is_equal
 | 
			
		||||
word bitfield_is_set,              gen_bitfield_is_set
 | 
			
		||||
word cast,                         gen_cast
 | 
			
		||||
word ccast,                        gen_ccast
 | 
			
		||||
word pcast,                        gen_pcast
 | 
			
		||||
@@ -224,7 +224,7 @@ word StrBuilder,       gen_StrBuilder
 | 
			
		||||
 | 
			
		||||
namespace strbuilder_, gen_strbuilder_
 | 
			
		||||
 | 
			
		||||
word StringCached, gen_StringCached
 | 
			
		||||
word StrCached, gen_StrCached
 | 
			
		||||
 | 
			
		||||
word StringTable, gen_StringTable
 | 
			
		||||
 | 
			
		||||
@@ -310,6 +310,14 @@ word spec_to_str,      gen_spec_to_str
 | 
			
		||||
word spec_is_trailing, gen_spec_is_trailing
 | 
			
		||||
// word str_to_specifier, gen_str_to_specifier
 | 
			
		||||
 | 
			
		||||
word MacroType,   gen_MacroType
 | 
			
		||||
word EMacroFlags, gen_EMacroFlags
 | 
			
		||||
word MacroFlags,  gen_MacroFlags
 | 
			
		||||
word Macro,       gen_Macro
 | 
			
		||||
 | 
			
		||||
namespace macro_,    gen_macro_
 | 
			
		||||
namespace macrotype, gen_macrotype_
 | 
			
		||||
 | 
			
		||||
// AST
 | 
			
		||||
 | 
			
		||||
word AST, gen_AST
 | 
			
		||||
@@ -325,6 +333,7 @@ word CodeComment,        gen_CodeComment
 | 
			
		||||
word CodeClass,          gen_CodeClass
 | 
			
		||||
word CodeConstructor,    gen_CodeConstructor
 | 
			
		||||
word CodeDefine,         gen_CodeDefine
 | 
			
		||||
word CodeDefineParams,   gen_CodeDefineParams
 | 
			
		||||
word CodeDestructor,     gen_CodeDestructor
 | 
			
		||||
word CodeEnum,           gen_CodeEnum
 | 
			
		||||
word CodeExec,           gen_CodeExec
 | 
			
		||||
@@ -350,6 +359,8 @@ word CodeVar,            gen_CodeVar
 | 
			
		||||
 | 
			
		||||
// Code Interface
 | 
			
		||||
 | 
			
		||||
word Context, gen_Context
 | 
			
		||||
 | 
			
		||||
namespace code_, gen_code_
 | 
			
		||||
 | 
			
		||||
word Code_Global,  gen_Code_Global
 | 
			
		||||
@@ -397,11 +408,13 @@ namespace var_,        gen_var_
 | 
			
		||||
 | 
			
		||||
// Gen Interface
 | 
			
		||||
 | 
			
		||||
word _ctx, gen__ctx
 | 
			
		||||
 | 
			
		||||
word init,   gen_init
 | 
			
		||||
word deinit, gen_deinit
 | 
			
		||||
word reset,  gen_reset
 | 
			
		||||
 | 
			
		||||
word get_cached_string, gen_get_cached_string
 | 
			
		||||
word cache_str, gen_cache_str
 | 
			
		||||
 | 
			
		||||
word make_code, gen_make_code
 | 
			
		||||
 | 
			
		||||
@@ -414,20 +427,6 @@ namespace untyped_, gen_untyped_
 | 
			
		||||
 | 
			
		||||
// Constants
 | 
			
		||||
 | 
			
		||||
word TokenMap_FixedArena, gen_TokenMap_FixedArena
 | 
			
		||||
word InitSize_DataArrays, gen_InitSize_DataArrays
 | 
			
		||||
 | 
			
		||||
word Global_BucketSize,   gen_Global_BucketSize
 | 
			
		||||
word CodePool_NumBlocks,  gen_CodePool_NumBlocks
 | 
			
		||||
word SizePer_StringArena, gen_SizePer_StringArena
 | 
			
		||||
 | 
			
		||||
word MaxCommentLineLength, gen_MaxCommentLineLength
 | 
			
		||||
word MaxNameLength,        gen_MaxNameLength
 | 
			
		||||
word MaxUntypedStrLength,  gen_MaxUntypedStrLength
 | 
			
		||||
 | 
			
		||||
word LexAllocator_Size,        gen_LexAllocator_Size
 | 
			
		||||
word Builder_StrBufferReserve, gen_Builder_StrBufferReserve
 | 
			
		||||
 | 
			
		||||
word access_public,    gen_access_public
 | 
			
		||||
word access_protected, gen_access_protected
 | 
			
		||||
word access_private,   gen_access_private
 | 
			
		||||
@@ -446,23 +445,8 @@ word preprocess_else, gen_preprocess_else
 | 
			
		||||
namespace spec_, gen_spec_
 | 
			
		||||
namespace t_,    gen_t_
 | 
			
		||||
 | 
			
		||||
word PreprocessorDefines, gen_PreprocessorDefines
 | 
			
		||||
 | 
			
		||||
// Backend
 | 
			
		||||
 | 
			
		||||
word GlobalAllocator,         gen_GlobalAllocator
 | 
			
		||||
word Global_AllocatorBuckets, gen_Global_AllocatorBuckets
 | 
			
		||||
word CodePools,               gen_CodePools
 | 
			
		||||
word StringArenas,            gen_StringArenas
 | 
			
		||||
word StringCache,             gen_StringCache
 | 
			
		||||
word LexArena,                gen_LexArena
 | 
			
		||||
word Allocator_DataArrays,    gen_Allocator_DataArrays
 | 
			
		||||
word Allocator_CodePool,      gen_Allocator_CodePool
 | 
			
		||||
word Allocator_Lexer,         gen_Allocator_Lexer
 | 
			
		||||
word Allocator_StringArena,   gen_Allocator_StringArena
 | 
			
		||||
word Allocator_StringTable,   gen_Allocator_StringTable
 | 
			
		||||
word Allocator_TypeTable,     gen_Allocator_TypeTable
 | 
			
		||||
 | 
			
		||||
// Builder
 | 
			
		||||
 | 
			
		||||
word      Builder,  gen_Builder
 | 
			
		||||
@@ -472,6 +456,9 @@ namespace builder_, gen_builder_
 | 
			
		||||
 | 
			
		||||
word scan_file, gen_scan_file
 | 
			
		||||
 | 
			
		||||
word CSV_Column,   gen_CSV_Column
 | 
			
		||||
word CSV_Columns2, gen_CSV_Columns2
 | 
			
		||||
 | 
			
		||||
// Implementation (prviate)
 | 
			
		||||
 | 
			
		||||
word _format_info, gen__format_info
 | 
			
		||||
@@ -518,7 +505,7 @@ word _adt_get_field, gen__adt_get_field
 | 
			
		||||
word _csv_write_record, gen__csv_write_record
 | 
			
		||||
word _csv_write_header, gen__csv_write_header
 | 
			
		||||
 | 
			
		||||
word Global_Allocator_Proc, gen_Global_Allocator_Proc
 | 
			
		||||
word fallback_allocator_proc, gen_Global_Allocator_Proc
 | 
			
		||||
word define_constants,      gen_define_constants
 | 
			
		||||
word operator__validate,    gen_operator__validate
 | 
			
		||||
 | 
			
		||||
@@ -527,7 +514,6 @@ word parser_deinit, gen_parser_deinit
 | 
			
		||||
 | 
			
		||||
word TokType,         gen_TokType
 | 
			
		||||
word toktype_to_str,  gen_toktype_to_str
 | 
			
		||||
// word str_to_toktype, gen_str_to_toktype
 | 
			
		||||
word NullToken,       gen_NullToken
 | 
			
		||||
 | 
			
		||||
namespace tok_, gen_tok_
 | 
			
		||||
 
 | 
			
		||||
@@ -22,9 +22,9 @@ CodeBody gen_array_base()
 | 
			
		||||
	Code get_header   = untyped_str( txt( "#define array_get_header( self ) ( (ArrayHeader*)( self ) - 1)\n" ));
 | 
			
		||||
	Code type_define  = untyped_str( txt( "#define Array(Type) gen_Array_##Type\n"));
 | 
			
		||||
 | 
			
		||||
	Code array_begin = def_define(txt("array_begin(array)"),       code( (array) ));
 | 
			
		||||
	Code array_end   = def_define(txt("array_end(array)"),         code( (array + array_get_header(array)->Num ) ));
 | 
			
		||||
	Code array_next  = def_define(txt("array_next(array, entry)"), code( (entry + 1) ));
 | 
			
		||||
	Code array_begin = def_define(txt("array_begin(array)"),       MT_Expression, { {}, code( (array) ) } );
 | 
			
		||||
	Code array_end   = def_define(txt("array_end(array)"),         MT_Expression, { {}, code( (array + array_get_header(array)->Num ) ) } );
 | 
			
		||||
	Code array_next  = def_define(txt("array_next(array, entry)"), MT_Expression, { {}, code( (entry + 1) ) } );
 | 
			
		||||
 | 
			
		||||
	return def_global_body( args(
 | 
			
		||||
		fmt_newline,
 | 
			
		||||
@@ -42,8 +42,8 @@ CodeBody gen_array_base()
 | 
			
		||||
 | 
			
		||||
CodeBody gen_array( Str type, Str array_name )
 | 
			
		||||
{
 | 
			
		||||
	StrBuilder array_type = StrBuilder::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
 | 
			
		||||
	StrBuilder fn         = StrBuilder::fmt_buf( GlobalAllocator, "%.*s", array_name.Len, array_name.Ptr );
 | 
			
		||||
	StrBuilder array_type = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "%.*s", array_name.Len, array_name.Ptr );
 | 
			
		||||
	StrBuilder fn         = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "%.*s", array_name.Len, array_name.Ptr );
 | 
			
		||||
	// c_str_to_lower(fn.Data);
 | 
			
		||||
 | 
			
		||||
#pragma push_macro( "GEN_ASSERT" )
 | 
			
		||||
@@ -238,10 +238,10 @@ CodeBody gen_array( Str type, Str array_name )
 | 
			
		||||
			GEN_ASSERT(begin <= end);
 | 
			
		||||
			ArrayHeader* header = array_get_header( self );
 | 
			
		||||
 | 
			
		||||
			if ( begin < 0 || end >= header->Num )
 | 
			
		||||
			if ( begin < 0 || end > header->Num )
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			for ( ssize idx = begin; idx < end; idx ++ )
 | 
			
		||||
			for ( ssize idx = (ssize)begin; idx < (ssize)end; idx ++ )
 | 
			
		||||
				self[ idx ] = value;
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
@@ -375,7 +375,7 @@ CodeBody gen_array( Str type, Str array_name )
 | 
			
		||||
#pragma pop_macro( "forceinline" )
 | 
			
		||||
 | 
			
		||||
	++ Array_DefinitionCounter;
 | 
			
		||||
	Str slot_str = StrBuilder::fmt_buf(GlobalAllocator, "%d", Array_DefinitionCounter).to_str();
 | 
			
		||||
	Str slot_str = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%d", Array_DefinitionCounter).to_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
 | 
			
		||||
@@ -399,13 +399,13 @@ R"(#define GENERIC_SLOT_<slot>__array_init         <type>,        <array_type>_i
 | 
			
		||||
	));
 | 
			
		||||
 | 
			
		||||
	return def_global_body( args(
 | 
			
		||||
		def_pragma( strbuilder_to_str( strbuilder_fmt_buf( GlobalAllocator, "region %SB", array_type ))),
 | 
			
		||||
		def_pragma( strbuilder_to_str( strbuilder_fmt_buf( _ctx->Allocator_Temp, "region %SB", array_type ))),
 | 
			
		||||
		fmt_newline,
 | 
			
		||||
		generic_interface_slot,
 | 
			
		||||
		fmt_newline,
 | 
			
		||||
		result,
 | 
			
		||||
		fmt_newline,
 | 
			
		||||
		def_pragma( strbuilder_to_str(strbuilder_fmt_buf( GlobalAllocator, "endregion %SB", array_type ))),
 | 
			
		||||
		def_pragma( strbuilder_to_str(strbuilder_fmt_buf( _ctx->Allocator_Temp, "endregion %SB", array_type ))),
 | 
			
		||||
		fmt_newline
 | 
			
		||||
	));
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ CodeBody gen_hashtable_base()
 | 
			
		||||
	));
 | 
			
		||||
 | 
			
		||||
	Code define_type = untyped_str(txt(
 | 
			
		||||
R"(#define HashTable(_type) struct _type
 | 
			
		||||
R"(#define HashTable(_type) struct gen_HashTable_##_type
 | 
			
		||||
)"
 | 
			
		||||
	));
 | 
			
		||||
 | 
			
		||||
@@ -30,16 +30,16 @@ R"(#define HashTable(_type) struct _type
 | 
			
		||||
CodeBody gen_hashtable( Str type, Str hashtable_name )
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	StrBuilder tbl_type = {(char*) hashtable_name.duplicate(GlobalAllocator).Ptr};
 | 
			
		||||
	StrBuilder fn       = tbl_type.duplicate(GlobalAllocator);
 | 
			
		||||
	StrBuilder tbl_type = {(char*) hashtable_name.duplicate(_ctx->Allocator_Temp).Ptr};
 | 
			
		||||
	StrBuilder fn       = tbl_type.duplicate(_ctx->Allocator_Temp);
 | 
			
		||||
	// c_str_to_lower(fn.Data);
 | 
			
		||||
 | 
			
		||||
	StrBuilder name_lower = StrBuilder::make( GlobalAllocator, hashtable_name );
 | 
			
		||||
	StrBuilder name_lower = StrBuilder::make( _ctx->Allocator_Temp, hashtable_name );
 | 
			
		||||
	// c_str_to_lower( name_lower.Data );
 | 
			
		||||
 | 
			
		||||
	StrBuilder hashtable_entry   = StrBuilder::fmt_buf( GlobalAllocator, "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 );
 | 
			
		||||
	StrBuilder entry_array_fn_ns = StrBuilder::fmt_buf( GlobalAllocator, "arr_hte_%.*s", name_lower.length(), name_lower.Data );
 | 
			
		||||
	StrBuilder hashtable_entry   = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "HTE_%.*s",     hashtable_name.Len, hashtable_name.Ptr );
 | 
			
		||||
	StrBuilder entry_array_name  = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "Arr_HTE_%.*s", hashtable_name.Len, hashtable_name.Ptr );
 | 
			
		||||
	StrBuilder entry_array_fn_ns = StrBuilder::fmt_buf( _ctx->Allocator_Temp, "arr_hte_%.*s", name_lower.length(), name_lower.Data );
 | 
			
		||||
 | 
			
		||||
	CodeBody hashtable_types = parse_global_body( token_fmt(
 | 
			
		||||
		"type",        (Str) type,
 | 
			
		||||
@@ -372,7 +372,7 @@ CodeBody gen_hashtable( Str type, Str hashtable_name )
 | 
			
		||||
#pragma pop_macro( "forceinline" )
 | 
			
		||||
 | 
			
		||||
	++ HashTable_DefinitionCounter;
 | 
			
		||||
	Str slot_str = StrBuilder::fmt_buf(GlobalAllocator, "%d", HashTable_DefinitionCounter).to_str();
 | 
			
		||||
	Str slot_str = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%d", HashTable_DefinitionCounter).to_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
 | 
			
		||||
@@ -400,7 +400,7 @@ R"(#define GENERIC_SLOT_<slot>__hashtable_init          <type>,      <tbl_type>_
 | 
			
		||||
		, type.Len, type.Ptr );
 | 
			
		||||
 | 
			
		||||
	return def_global_body(args(
 | 
			
		||||
		def_pragma( strbuilder_to_str( strbuilder_fmt_buf( GlobalAllocator, "region %SB", tbl_type ))),
 | 
			
		||||
		def_pragma( strbuilder_to_str( strbuilder_fmt_buf( _ctx->Allocator_Temp, "region %SB", tbl_type ))),
 | 
			
		||||
		fmt_newline,
 | 
			
		||||
		generic_interface_slot,
 | 
			
		||||
		fmt_newline,
 | 
			
		||||
@@ -409,7 +409,7 @@ R"(#define GENERIC_SLOT_<slot>__hashtable_init          <type>,      <tbl_type>_
 | 
			
		||||
		entry_array,
 | 
			
		||||
		hashtable_def,
 | 
			
		||||
		fmt_newline,
 | 
			
		||||
		def_pragma( strbuilder_to_str( strbuilder_fmt_buf( GlobalAllocator, "endregion %SB", tbl_type ))),
 | 
			
		||||
		def_pragma( strbuilder_to_str( strbuilder_fmt_buf( _ctx->Allocator_Temp, "endregion %SB", tbl_type ))),
 | 
			
		||||
		fmt_newline
 | 
			
		||||
	));
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
	|  \_____|\___}_l |_|\___} .__/| .__/ {_____/ \__\__/_l\__. |\___/\__,_l   \____}{_____}{_____} |
 | 
			
		||||
	|                        | |   | |                      __} |                                   |
 | 
			
		||||
	|                        l_l   l_l                     {___/                                    |
 | 
			
		||||
	! ----------------------------------------------------------------------- VERSION: v0.20-Alpha  |
 | 
			
		||||
	! ----------------------------------------------------------------------- VERSION: v0.23-Alpha  |
 | 
			
		||||
	! ============================================================================================= |
 | 
			
		||||
	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                  |
 | 
			
		||||
	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL  |
 | 
			
		||||
 
 | 
			
		||||
@@ -89,7 +89,14 @@ CodeBody gen_fixed_arenas()
 | 
			
		||||
	result.append(arena_interface_2mb);
 | 
			
		||||
	result.append(arena_interface_4mb);
 | 
			
		||||
 | 
			
		||||
	CodeDefine def = def_define(txt("fixed_arena_allocator_info(fixed_arena)"), txt("( (AllocatorInfo) { arena_allocator_proc, & (fixed_arena)->arena } )"));
 | 
			
		||||
	register_macros( args(
 | 
			
		||||
		( Macro { txt("fixed_arena_allocator_info"), MT_Expression, MF_Functional }),
 | 
			
		||||
		( Macro { txt("fixed_arena_init"),           MT_Expression, MF_Functional }),
 | 
			
		||||
		( Macro { txt("fixed_arena_free"),           MT_Expression, MF_Functional }),
 | 
			
		||||
		( Macro { txt("fixed_arena_size_remaining"), MT_Expression, MF_Functional })
 | 
			
		||||
	));
 | 
			
		||||
 | 
			
		||||
	CodeDefine def = parse_define(txt("#define fixed_arena_allocator_info(fixed_arena) ( (AllocatorInfo) { arena_allocator_proc, & (fixed_arena)->arena } )\n"));
 | 
			
		||||
	result.append(def);
 | 
			
		||||
	result.append(fmt_newline);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,12 +7,13 @@ void convert_cpp_enum_to_c( CodeEnum to_convert, CodeBody to_append )
 | 
			
		||||
{
 | 
			
		||||
#pragma push_macro("enum_underlying")
 | 
			
		||||
#undef enum_underlying
 | 
			
		||||
	StrCached type = to_convert->UnderlyingType ? to_convert->UnderlyingType.to_strbuilder().to_str() : to_convert->Name;
 | 
			
		||||
	CodeTypedef tdef = parse_typedef(token_fmt("type", type, "name", to_convert->Name, stringize( typedef enum <type> <name>; )));
 | 
			
		||||
	if (to_convert->UnderlyingType)
 | 
			
		||||
	{
 | 
			
		||||
		to_convert->UnderlyingTypeMacro = untyped_str(token_fmt("type", to_convert->UnderlyingType->Name, stringize(enum_underlying(<type>))));
 | 
			
		||||
		to_convert->UnderlyingType      = CodeTypename{nullptr};
 | 
			
		||||
	}
 | 
			
		||||
	CodeTypedef tdef = parse_typedef(token_fmt("name", to_convert->Name, stringize( typedef enum <name> <name>; )));
 | 
			
		||||
	to_append.append(to_convert);
 | 
			
		||||
	to_append.append(tdef);
 | 
			
		||||
#pragma pop_macro("enum_underlying")
 | 
			
		||||
@@ -84,7 +85,7 @@ Code gen_generic_selection_function_macro( s32 num_slots, Str macro_name, Generi
 | 
			
		||||
	) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
 | 
			
		||||
*/
 | 
			
		||||
	local_persist
 | 
			
		||||
	StrBuilder define_builder = StrBuilder::make_reserve(GlobalAllocator, kilobytes(64));
 | 
			
		||||
	StrBuilder define_builder = StrBuilder::make_reserve(_ctx->Allocator_Temp, kilobytes(64));
 | 
			
		||||
	define_builder.clear();
 | 
			
		||||
 | 
			
		||||
	Str macro_begin;
 | 
			
		||||
@@ -104,49 +105,32 @@ R"(#define <macro_name>(selector_arg, ...) _Generic( (selector_arg), \
 | 
			
		||||
 | 
			
		||||
	for ( s32 slot = 1; slot <= num_slots; ++ slot )
 | 
			
		||||
	{
 | 
			
		||||
		Str slot_str = StrBuilder::fmt_buf(GlobalAllocator, "%d", slot).to_str();
 | 
			
		||||
		if (slot == num_slots && false)
 | 
			
		||||
		{
 | 
			
		||||
			define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str,
 | 
			
		||||
R"(		GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT_LAST(  GENERIC_SLOT_<slot>__<macro_name> ) \
 | 
			
		||||
)"
 | 
			
		||||
			));
 | 
			
		||||
			// if ( one_arg )
 | 
			
		||||
			// 	define_builder.append(token_fmt( "macro_name", macro_name, stringize(
 | 
			
		||||
			// 		default: static_assert(false, "<macro_name>: Failed to select correct function signature (Did you pass the type?)")
 | 
			
		||||
			// 	)));
 | 
			
		||||
			// else
 | 
			
		||||
			// 	define_builder.append(token_fmt( "macro_name", macro_name, stringize(
 | 
			
		||||
			// 		default: static_assert(false, "<macro_name>: Failed to select correct function signature")
 | 
			
		||||
			// 	)));
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Str slot_str = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%d", slot).to_str();
 | 
			
		||||
		define_builder.append( token_fmt( "macro_name", macro_name, "slot", slot_str,
 | 
			
		||||
R"(		GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_<slot>__<macro_name> ) \
 | 
			
		||||
R"(GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( GENERIC_SLOT_<slot>__<macro_name> ) \
 | 
			
		||||
)"
 | 
			
		||||
		));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	define_builder.append( txt("default: gen_generic_selection_fail") );
 | 
			
		||||
	define_builder.append( txt("default: gen_generic_selection_fail\\\n") );
 | 
			
		||||
 | 
			
		||||
	if ( ! one_arg )
 | 
			
		||||
	{
 | 
			
		||||
		if (opts == GenericSel_By_Ref)
 | 
			
		||||
			define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( & selector_arg, __VA_ARGS__ )"));
 | 
			
		||||
			define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( & selector_arg, __VA_ARGS__ )"));
 | 
			
		||||
		else if (opts == GenericSel_Direct_Type)
 | 
			
		||||
			define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( __VA_ARGS__ )"));
 | 
			
		||||
			define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( __VA_ARGS__ )"));
 | 
			
		||||
		else
 | 
			
		||||
			define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARGS__ )"));
 | 
			
		||||
			define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARGS__ )"));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (opts == GenericSel_By_Ref)
 | 
			
		||||
			define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( & selector_arg )"));
 | 
			
		||||
			define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( & selector_arg )"));
 | 
			
		||||
		else if (opts == GenericSel_Direct_Type)
 | 
			
		||||
			define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL()"));
 | 
			
		||||
			define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL()"));
 | 
			
		||||
		else
 | 
			
		||||
			define_builder.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( selector_arg )"));
 | 
			
		||||
			define_builder.append(txt(")\\\nGEN_RESOLVED_FUNCTION_CALL( selector_arg )"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add gap for next definition
 | 
			
		||||
@@ -164,9 +148,9 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, Str optional_prefix = txt("")
 | 
			
		||||
 | 
			
		||||
    // Add prefix if provided
 | 
			
		||||
    if (optional_prefix.Len)
 | 
			
		||||
        new_name = strbuilder_fmt_buf(GlobalAllocator, "%S_%S_", optional_prefix, old_name);
 | 
			
		||||
        new_name = strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S_%S_", optional_prefix, old_name);
 | 
			
		||||
    else
 | 
			
		||||
        new_name = strbuilder_fmt_buf(GlobalAllocator, "%S_", old_name);
 | 
			
		||||
        new_name = strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S_", old_name);
 | 
			
		||||
 | 
			
		||||
    // Add return type to the signature
 | 
			
		||||
    if (fn->ReturnType)
 | 
			
		||||
@@ -228,8 +212,8 @@ bool swap_pragma_region_implementation( Str region_name, SwapContentProc* swap_c
 | 
			
		||||
	bool found = false;
 | 
			
		||||
	CodePragma possible_region = cast(CodePragma, entry_iter);
 | 
			
		||||
 | 
			
		||||
	StrBuilder region_sig    = strbuilder_fmt_buf(GlobalAllocator, "region %s",    region_name.Ptr);
 | 
			
		||||
	StrBuilder endregion_sig = strbuilder_fmt_buf(GlobalAllocator, "endregion %s", region_name.Ptr);
 | 
			
		||||
	StrBuilder region_sig    = strbuilder_fmt_buf(_ctx->Allocator_Temp, "region %s",    region_name.Ptr);
 | 
			
		||||
	StrBuilder endregion_sig = strbuilder_fmt_buf(_ctx->Allocator_Temp, "endregion %s", region_name.Ptr);
 | 
			
		||||
	if ( possible_region->Content.contains(region_sig))
 | 
			
		||||
	{
 | 
			
		||||
		found = true;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
#define GEN_IMPLEMENTATION
 | 
			
		||||
#include "gen/gen.c"
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
	// init();
 | 
			
		||||
	__debugbreak();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								gen_c_library/gen_c_lib.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								gen_c_library/gen_c_lib.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
#define GEN_IMPLEMENTATION
 | 
			
		||||
#define GEN_DONT_ENFORCE_GEN_TIME_GUARD
 | 
			
		||||
#include "gen/gen_singleheader.h"
 | 
			
		||||
@@ -32,7 +32,10 @@ Code format( Code code ) {
 | 
			
		||||
 | 
			
		||||
int gen_main()
 | 
			
		||||
{
 | 
			
		||||
	gen::init();
 | 
			
		||||
	Context ctx {
 | 
			
		||||
		
 | 
			
		||||
	};
 | 
			
		||||
	gen::init(& ctx);
 | 
			
		||||
 | 
			
		||||
	Code push_ignores = scan_file( (path_base "helpers/push_ignores.inline.hpp") );
 | 
			
		||||
	Code pop_ignores  = scan_file( (path_base "helpers/pop_ignores.inline.hpp") );
 | 
			
		||||
@@ -124,6 +127,7 @@ int gen_main()
 | 
			
		||||
	{
 | 
			
		||||
		Code header_start = scan_file( path_base "components/header_start.hpp" );
 | 
			
		||||
		Code types        = scan_file( path_base "components/types.hpp" );
 | 
			
		||||
		Code parser_types = scan_file( path_base "components/parser_types.hpp" );
 | 
			
		||||
		Code ast          = scan_file( path_base "components/ast.hpp" );
 | 
			
		||||
		Code ast_types    = scan_file( path_base "components/ast_types.hpp" );
 | 
			
		||||
		Code code_types   = scan_file( path_base "components/code_types.hpp" );
 | 
			
		||||
@@ -134,6 +138,7 @@ int gen_main()
 | 
			
		||||
		CodeBody ecode       = gen_ecode     ( path_base "enums/ECodeTypes.csv" );
 | 
			
		||||
		CodeBody eoperator   = gen_eoperator ( path_base "enums/EOperator.csv" );
 | 
			
		||||
		CodeBody especifier  = gen_especifier( path_base "enums/ESpecifier.csv" );
 | 
			
		||||
		CodeBody etoktype    = gen_etoktype  ( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" );
 | 
			
		||||
		CodeBody ast_inlines = gen_ast_inlines();
 | 
			
		||||
 | 
			
		||||
		Builder _header = builder_open( "gen/gen.hpp" );
 | 
			
		||||
@@ -153,6 +158,8 @@ int gen_main()
 | 
			
		||||
		builder_print( header, fmt_newline);
 | 
			
		||||
		builder_print( header, format(especifier) );
 | 
			
		||||
		builder_print( header, fmt_newline);
 | 
			
		||||
		builder_print( header, format(etoktype));
 | 
			
		||||
		builder_print( header, parser_types);
 | 
			
		||||
		builder_print_fmt( header, "#pragma endregion Types\n\n" );
 | 
			
		||||
 | 
			
		||||
		builder_print_fmt( header, "#pragma region AST\n" );
 | 
			
		||||
@@ -186,16 +193,11 @@ int gen_main()
 | 
			
		||||
		Code        interface	       = scan_file( path_base "components/interface.cpp" );
 | 
			
		||||
		Code        upfront 	       = scan_file( path_base "components/interface.upfront.cpp" );
 | 
			
		||||
		Code        lexer              = scan_file( path_base "components/lexer.cpp" );
 | 
			
		||||
		Code        parser_case_macros = scan_file( path_base "components/parser_case_macros.cpp" );
 | 
			
		||||
		Code        parser             = scan_file( path_base "components/parser.cpp" );
 | 
			
		||||
		Code 	    parsing_interface  = scan_file( path_base "components/interface.parsing.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 nspaced_etoktype = def_global_body( args(
 | 
			
		||||
			etoktype
 | 
			
		||||
		));
 | 
			
		||||
		Code formatted_toktype = format(nspaced_etoktype);
 | 
			
		||||
 | 
			
		||||
		Builder _src = builder_open( "gen/gen.cpp" );
 | 
			
		||||
		Builder* src = & _src;
 | 
			
		||||
		builder_print_fmt( src, generation_notice );
 | 
			
		||||
@@ -215,8 +217,8 @@ int gen_main()
 | 
			
		||||
		builder_print( src, interface );
 | 
			
		||||
		builder_print( src, upfront );
 | 
			
		||||
		builder_print_fmt( src, "\n#pragma region Parsing\n\n" );
 | 
			
		||||
		builder_print( src, formatted_toktype );
 | 
			
		||||
		builder_print( src, lexer );
 | 
			
		||||
		builder_print( src, parser_case_macros );
 | 
			
		||||
		builder_print( src, parser );
 | 
			
		||||
		builder_print( src, parsing_interface );
 | 
			
		||||
		builder_print_fmt( src, "\n#pragma endregion Parsing\n\n" );
 | 
			
		||||
@@ -282,6 +284,6 @@ int gen_main()
 | 
			
		||||
		builder_write( & src);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gen::deinit();
 | 
			
		||||
	gen::deinit( & ctx);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
	|  \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l                       |
 | 
			
		||||
	|     Singleheader       | |   | |                      __} |                                  |
 | 
			
		||||
	|                        l_l   l_l                     {___/                                   |
 | 
			
		||||
	! ----------------------------------------------------------------------- VERSION: v0.20-Alpha |
 | 
			
		||||
	! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
 | 
			
		||||
	! ============================================================================================ |
 | 
			
		||||
	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                 |
 | 
			
		||||
	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,8 @@ Code format( Code code ) {
 | 
			
		||||
 | 
			
		||||
int gen_main()
 | 
			
		||||
{
 | 
			
		||||
	gen::init();
 | 
			
		||||
	Context ctx {};
 | 
			
		||||
	gen::init( & ctx);
 | 
			
		||||
 | 
			
		||||
	Code push_ignores        = scan_file( path_base "helpers/push_ignores.inline.hpp" );
 | 
			
		||||
	Code pop_ignores         = scan_file( path_base "helpers/pop_ignores.inline.hpp" );
 | 
			
		||||
@@ -111,17 +112,19 @@ int gen_main()
 | 
			
		||||
			header.print( fmt_newline );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Code types      = scan_file( path_base "components/types.hpp" );
 | 
			
		||||
		Code ast        = scan_file( path_base "components/ast.hpp" );
 | 
			
		||||
		Code ast_types  = scan_file( path_base "components/ast_types.hpp" );
 | 
			
		||||
		Code code_types = scan_file( path_base "components/code_types.hpp" );
 | 
			
		||||
		Code interface  = scan_file( path_base "components/interface.hpp" );
 | 
			
		||||
		Code inlines 	= scan_file( path_base "components/inlines.hpp" );
 | 
			
		||||
		Code header_end = scan_file( path_base "components/header_end.hpp" );
 | 
			
		||||
		Code types        = scan_file( path_base "components/types.hpp" );
 | 
			
		||||
		Code parser_types = scan_file( path_base "components/parser_types.hpp");
 | 
			
		||||
		Code ast          = scan_file( path_base "components/ast.hpp" );
 | 
			
		||||
		Code ast_types    = scan_file( path_base "components/ast_types.hpp" );
 | 
			
		||||
		Code code_types   = scan_file( path_base "components/code_types.hpp" );
 | 
			
		||||
		Code interface    = scan_file( path_base "components/interface.hpp" );
 | 
			
		||||
		Code inlines 	  = scan_file( path_base "components/inlines.hpp" );
 | 
			
		||||
		Code header_end   = scan_file( path_base "components/header_end.hpp" );
 | 
			
		||||
 | 
			
		||||
		CodeBody ecode       = gen_ecode     ( path_base "enums/ECodeTypes.csv" );
 | 
			
		||||
		CodeBody eoperator   = gen_eoperator ( path_base "enums/EOperator.csv" );
 | 
			
		||||
		CodeBody especifier  = gen_especifier( path_base "enums/ESpecifier.csv" );
 | 
			
		||||
		CodeBody etoktype    = gen_etoktype  ( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" );
 | 
			
		||||
		CodeBody ast_inlines = gen_ast_inlines();
 | 
			
		||||
 | 
			
		||||
		header.print_fmt( "GEN_NS_BEGIN\n\n" );
 | 
			
		||||
@@ -135,6 +138,9 @@ int gen_main()
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
		header.print( format( especifier ));
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
		header.print( format( etoktype ));
 | 
			
		||||
		header.print( parser_types );
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
		header.print_fmt("#pragma endregion Types\n\n");
 | 
			
		||||
 | 
			
		||||
		header.print_fmt("#pragma region AST\n");
 | 
			
		||||
@@ -204,21 +210,21 @@ int gen_main()
 | 
			
		||||
			header.print_fmt( roll_own_dependencies_guard_end );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Code static_data 	   = scan_file( path_base "components/static_data.cpp" );
 | 
			
		||||
		Code ast_case_macros   = scan_file( path_base "components/ast_case_macros.cpp" );
 | 
			
		||||
		Code ast               = scan_file( path_base "components/ast.cpp" );
 | 
			
		||||
		Code code              = scan_file( path_base "components/code_serialization.cpp" );
 | 
			
		||||
		Code interface         = scan_file( path_base "components/interface.cpp" );
 | 
			
		||||
		Code upfront           = scan_file( path_base "components/interface.upfront.cpp" );
 | 
			
		||||
		Code lexer             = scan_file( path_base "components/lexer.cpp" );
 | 
			
		||||
		Code parser            = scan_file( path_base "components/parser.cpp" );
 | 
			
		||||
		Code parsing_interface = scan_file( path_base "components/interface.parsing.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" );
 | 
			
		||||
		Code static_data 	    = scan_file( path_base "components/static_data.cpp" );
 | 
			
		||||
		Code ast_case_macros    = scan_file( path_base "components/ast_case_macros.cpp" );
 | 
			
		||||
		Code ast                = scan_file( path_base "components/ast.cpp" );
 | 
			
		||||
		Code code               = scan_file( path_base "components/code_serialization.cpp" );
 | 
			
		||||
		Code interface          = scan_file( path_base "components/interface.cpp" );
 | 
			
		||||
		Code upfront            = scan_file( path_base "components/interface.upfront.cpp" );
 | 
			
		||||
		Code lexer              = scan_file( path_base "components/lexer.cpp" );
 | 
			
		||||
		Code parser_case_macros = scan_file( path_base "components/parser_case_macros.cpp" );
 | 
			
		||||
		Code parser             = scan_file( path_base "components/parser.cpp" );
 | 
			
		||||
		Code parsing_interface  = scan_file( path_base "components/interface.parsing.cpp" );
 | 
			
		||||
		Code untyped            = scan_file( path_base "components/interface.untyped.cpp" );
 | 
			
		||||
 | 
			
		||||
		header.print_fmt( "\nGEN_NS_BEGIN\n");
 | 
			
		||||
		header.print( static_data );
 | 
			
		||||
		header.print( fmt_newline);
 | 
			
		||||
 | 
			
		||||
		header.print_fmt( "#pragma region AST\n\n" );
 | 
			
		||||
		header.print( ast_case_macros );
 | 
			
		||||
@@ -230,12 +236,14 @@ int gen_main()
 | 
			
		||||
		header.print( interface );
 | 
			
		||||
		header.print( upfront );
 | 
			
		||||
		header.print_fmt( "\n#pragma region Parsing\n\n" );
 | 
			
		||||
		header.print( format(etoktype) );
 | 
			
		||||
		header.print( lexer );
 | 
			
		||||
		header.print( parser_case_macros );
 | 
			
		||||
		header.print( parser );
 | 
			
		||||
		header.print( parsing_interface );
 | 
			
		||||
		header.print_fmt( "\n#pragma endregion Parsing\n" );
 | 
			
		||||
		header.print_fmt("\n#pragma region Untyped\n");
 | 
			
		||||
		header.print( untyped );
 | 
			
		||||
		header.print_fmt("\n#pragma endregion Untyped\n");
 | 
			
		||||
		header.print_fmt( "\n#pragma endregion Interface\n");
 | 
			
		||||
 | 
			
		||||
		if ( generate_builder ) {
 | 
			
		||||
@@ -255,6 +263,6 @@ int gen_main()
 | 
			
		||||
	header.print( pop_ignores );
 | 
			
		||||
	header.write();
 | 
			
		||||
 | 
			
		||||
	gen::deinit();
 | 
			
		||||
	gen::deinit( & ctx);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,12 +7,20 @@
 | 
			
		||||
	https://github.com/Ed94/gencpp
 | 
			
		||||
 | 
			
		||||
	This is a variant intended for use with Unreal Engine 5
 | 
			
		||||
 | 
			
		||||
	! ----------------------------------------------------------------------- VERSION: v0.20-Alpha !
 | 
			
		||||
	! ============================================================================================ !
 | 
			
		||||
	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                 !
 | 
			
		||||
	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL !
 | 
			
		||||
	! ============================================================================================ !
 | 
			
		||||
	https://github.com/Ed94/gencpp  --------------------------------------------------------------.
 | 
			
		||||
	|   _____                               _____ _                       _                        |
 | 
			
		||||
	|  / ____)                             / ____} |                     | |                       |
 | 
			
		||||
	| | / ___  ___ _ __   ___ _ __  _ __  | {___ | |__ _ _, __ _, ___  __| |                       |
 | 
			
		||||
	| | |{_  |/ _ \ '_ \ / __} '_ l| '_ l `\___ \| __/ _` |/ _` |/ _ \/ _` |                       |
 | 
			
		||||
	| | l__j | ___/ | | | {__; |+l } |+l | ____) | l| (_| | {_| | ___/ (_| |                       |
 | 
			
		||||
	|  \_____|\___}_l |_|\___} ,__/| ,__/ (_____/ \__\__/_|\__, |\___}\__,_l                       |
 | 
			
		||||
	|  Unreal Engine         | |   | |                      __} |                                  |
 | 
			
		||||
	|                        l_l   l_l                     {___/                                   |
 | 
			
		||||
	! ----------------------------------------------------------------------- VERSION: v0.23-Alpha |
 | 
			
		||||
	! ============================================================================================ |
 | 
			
		||||
	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                 |
 | 
			
		||||
	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL |
 | 
			
		||||
	! ============================================================================================ /
 | 
			
		||||
*/
 | 
			
		||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
 | 
			
		||||
#	error Gen.hpp : GEN_TIME not defined
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										108
									
								
								gen_unreal_engine/components/parser_case_macros.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								gen_unreal_engine/components/parser_case_macros.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
// These macros are used in the swtich cases within parser.cpp
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_TOK_SPECIFIERS_CASES \
 | 
			
		||||
case Tok_Spec_Consteval:              \
 | 
			
		||||
case Tok_Spec_Constexpr:              \
 | 
			
		||||
case Tok_Spec_Constinit:              \
 | 
			
		||||
case Tok_Spec_Explicit:               \
 | 
			
		||||
case Tok_Spec_ForceInline:            \
 | 
			
		||||
case Tok_Spec_ForceInline_Debuggable: \
 | 
			
		||||
case Tok_Spec_Inline:                 \
 | 
			
		||||
case Tok_Spec_Mutable:                \
 | 
			
		||||
case Tok_Spec_NeverInline:            \
 | 
			
		||||
case Tok_Spec_Static:                 \
 | 
			
		||||
case Tok_Spec_Volatile:               \
 | 
			
		||||
case Tok_Spec_Virtual
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_CLASS_STRUCT_BODY_ALLOWED_MEMBER_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Constexpr:              \
 | 
			
		||||
case Spec_Constinit:              \
 | 
			
		||||
case Spec_Explicit:               \
 | 
			
		||||
case Spec_Inline:                 \
 | 
			
		||||
case Spec_ForceInline:            \
 | 
			
		||||
case Spec_ForceInline_Debuggable: \
 | 
			
		||||
case Spec_Mutable:                \
 | 
			
		||||
case Spec_NeverInline:            \
 | 
			
		||||
case Spec_Static:                 \
 | 
			
		||||
case Spec_Volatile:               \
 | 
			
		||||
case Spec_Virtual
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
 | 
			
		||||
case Tok_Spec_Consteval:              \
 | 
			
		||||
case Tok_Spec_Constexpr:              \
 | 
			
		||||
case Tok_Spec_Constinit:              \
 | 
			
		||||
case Tok_Spec_Extern:                 \
 | 
			
		||||
case Tok_Spec_ForceInline:            \
 | 
			
		||||
case Tok_Spec_ForceInline_Debuggable: \
 | 
			
		||||
case Tok_Spec_Global:                 \
 | 
			
		||||
case Tok_Spec_Inline:                 \
 | 
			
		||||
case Tok_Spec_Internal_Linkage:       \
 | 
			
		||||
case Tok_Spec_NeverInline:            \
 | 
			
		||||
case Tok_Spec_Static
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIER_CASES \
 | 
			
		||||
case Spec_Constexpr:              \
 | 
			
		||||
case Spec_Constinit:              \
 | 
			
		||||
case Spec_ForceInline:            \
 | 
			
		||||
case Spec_ForceInline_Debuggable: \
 | 
			
		||||
case Spec_Global:                 \
 | 
			
		||||
case Spec_External_Linkage:       \
 | 
			
		||||
case Spec_Internal_Linkage:       \
 | 
			
		||||
case Spec_Inline:                 \
 | 
			
		||||
case Spec_Mutable:                \
 | 
			
		||||
case Spec_NeverInline:            \
 | 
			
		||||
case Spec_Static:                 \
 | 
			
		||||
case Spec_Volatile
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_FRIEND_ALLOWED_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Const:       \
 | 
			
		||||
case Spec_Inline:      \
 | 
			
		||||
case Spec_ForceInline
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_FUNCTION_ALLOWED_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Const:                  \
 | 
			
		||||
case Spec_Consteval:              \
 | 
			
		||||
case Spec_Constexpr:              \
 | 
			
		||||
case Spec_External_Linkage:       \
 | 
			
		||||
case Spec_Internal_Linkage:       \
 | 
			
		||||
case Spec_ForceInline:            \
 | 
			
		||||
case Spec_ForceInline_Debuggable: \
 | 
			
		||||
case Spec_Inline:                 \
 | 
			
		||||
case Spec_NeverInline:            \
 | 
			
		||||
case Spec_Static
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_OPERATOR_ALLOWED_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Const:       \
 | 
			
		||||
case Spec_Constexpr:   \
 | 
			
		||||
case Spec_ForceInline: \
 | 
			
		||||
case Spec_Inline:      \
 | 
			
		||||
case Spec_NeverInline: \
 | 
			
		||||
case Spec_Static
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_TEMPLATE_ALLOWED_SPECIFIERS_CASES \
 | 
			
		||||
case Spec_Const:                  \
 | 
			
		||||
case Spec_Constexpr:              \
 | 
			
		||||
case Spec_Constinit:              \
 | 
			
		||||
case Spec_External_Linkage:       \
 | 
			
		||||
case Spec_Global:                 \
 | 
			
		||||
case Spec_Inline:                 \
 | 
			
		||||
case Spec_ForceInline:            \
 | 
			
		||||
case Spec_ForceInline_Debuggable: \
 | 
			
		||||
case Spec_Local_Persist:          \
 | 
			
		||||
case Spec_Mutable:                \
 | 
			
		||||
case Spec_Static:                 \
 | 
			
		||||
case Spec_Thread_Local:           \
 | 
			
		||||
case Spec_Volatile
 | 
			
		||||
 | 
			
		||||
#define GEN_PARSER_VARIABLE_ALLOWED_SPECIFIER_CASES \
 | 
			
		||||
case Spec_Const:            \
 | 
			
		||||
case Spec_Constexpr:        \
 | 
			
		||||
case Spec_Constinit:        \
 | 
			
		||||
case Spec_External_Linkage: \
 | 
			
		||||
case Spec_Global:           \
 | 
			
		||||
case Spec_Inline:           \
 | 
			
		||||
case Spec_Local_Persist:    \
 | 
			
		||||
case Spec_Mutable:          \
 | 
			
		||||
case Spec_Static:           \
 | 
			
		||||
case Spec_Thread_Local:     \
 | 
			
		||||
case Spec_Volatile
 | 
			
		||||
@@ -4,4 +4,4 @@ COREUOBJECT_API,       COREUOBJECT_API
 | 
			
		||||
ENGINE_API,            ENGINE_API
 | 
			
		||||
GAMEPLAYABILITIES_API, GAMEPLAYABILITIES_API
 | 
			
		||||
UMG_API,               UMG_API
 | 
			
		||||
UE_DEPRECATED,         UE_DEPRECATED
 | 
			
		||||
GASA_API,              GASA_API
 | 
			
		||||
		
		
			
  | 
							
								
								
									
										27
									
								
								gen_unreal_engine/enums/ESpecifier.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								gen_unreal_engine/enums/ESpecifier.csv
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
Invalid,                INVALID
 | 
			
		||||
Consteval,              consteval
 | 
			
		||||
Constexpr,              constexpr
 | 
			
		||||
Constinit,              constinit
 | 
			
		||||
Explicit,               explicit
 | 
			
		||||
External_Linkage,       extern
 | 
			
		||||
ForceInline, 	        FORCEINLINE
 | 
			
		||||
ForceInline_Debuggable, FORCEINLINE_DEBUGGABLE
 | 
			
		||||
Global,                 global
 | 
			
		||||
Inline,                 inline
 | 
			
		||||
Internal_Linkage,       internal
 | 
			
		||||
Local_Persist,          local_persist
 | 
			
		||||
Mutable,                mutable
 | 
			
		||||
NeverInline,            neverinline
 | 
			
		||||
Ptr,                    *
 | 
			
		||||
Ref,                    &
 | 
			
		||||
Register,               register
 | 
			
		||||
RValue,                 &&
 | 
			
		||||
Static,                 static
 | 
			
		||||
Thread_Local,           thread_local
 | 
			
		||||
Virtual,                virtual
 | 
			
		||||
Const,                  const
 | 
			
		||||
Final,                  final
 | 
			
		||||
NoExceptions,           noexcept
 | 
			
		||||
Override,               override
 | 
			
		||||
Pure,                   = 0
 | 
			
		||||
Volatile,               volatile
 | 
			
		||||
		
		
			
  | 
							
								
								
									
										99
									
								
								gen_unreal_engine/enums/ETokType.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								gen_unreal_engine/enums/ETokType.csv
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
Invalid,                     "__invalid__"
 | 
			
		||||
Access_Private,              "private"
 | 
			
		||||
Access_Protected,            "protected"
 | 
			
		||||
Access_Public,               "public"
 | 
			
		||||
Access_MemberSymbol,         "."
 | 
			
		||||
Access_StaticSymbol,         "::"
 | 
			
		||||
Ampersand,                   "&"
 | 
			
		||||
Ampersand_DBL,               "&&"
 | 
			
		||||
Assign_Classifer,            ":"
 | 
			
		||||
Attribute_Open,              "[["
 | 
			
		||||
Attribute_Close,             "]]"
 | 
			
		||||
BraceCurly_Open,             "{"
 | 
			
		||||
BraceCurly_Close,            "}"
 | 
			
		||||
BraceSquare_Open,            "["
 | 
			
		||||
BraceSquare_Close,           "]"
 | 
			
		||||
Capture_Start,               "("
 | 
			
		||||
Capture_End,                 ")"
 | 
			
		||||
Comment,                     "__comment__"
 | 
			
		||||
Comment_End,                 "__comment_end__"
 | 
			
		||||
Comment_Start,               "__comment_start__"
 | 
			
		||||
Char,                        "__character__"
 | 
			
		||||
Comma,                       ","
 | 
			
		||||
Decl_Class,                  "class"
 | 
			
		||||
Decl_GNU_Attribute,          "__attribute__"
 | 
			
		||||
Decl_MSVC_Attribute,         "__declspec"
 | 
			
		||||
Decl_Enum,                   "enum"
 | 
			
		||||
Decl_Extern_Linkage,         "extern"
 | 
			
		||||
Decl_Friend,                 "friend"
 | 
			
		||||
Decl_Module,                 "module"
 | 
			
		||||
Decl_Namespace,              "namespace"
 | 
			
		||||
Decl_Operator,               "operator"
 | 
			
		||||
Decl_Struct,                 "struct"
 | 
			
		||||
Decl_Template,               "template"
 | 
			
		||||
Decl_Typedef,                "typedef"
 | 
			
		||||
Decl_Using,                  "using"
 | 
			
		||||
Decl_Union,                  "union"
 | 
			
		||||
Identifier,                  "__identifier__"
 | 
			
		||||
Module_Import,               "import"
 | 
			
		||||
Module_Export,               "export"
 | 
			
		||||
NewLine,                     "__new_line__"
 | 
			
		||||
Number,                      "__number__"
 | 
			
		||||
Operator,                    "__operator__"
 | 
			
		||||
Preprocess_Hash,             "#"
 | 
			
		||||
Preprocess_Define,           "define"
 | 
			
		||||
Preprocess_Define_Param,     "__define_param__"
 | 
			
		||||
Preprocess_If,               "if"
 | 
			
		||||
Preprocess_IfDef,            "ifdef"
 | 
			
		||||
Preprocess_IfNotDef,         "ifndef"
 | 
			
		||||
Preprocess_ElIf,             "elif"
 | 
			
		||||
Preprocess_Else,             "else"
 | 
			
		||||
Preprocess_EndIf,            "endif"
 | 
			
		||||
Preprocess_Include,          "include"
 | 
			
		||||
Preprocess_Pragma,           "pragma"
 | 
			
		||||
Preprocess_Content,          "__macro_content__"
 | 
			
		||||
Preprocess_Macro_Expr,      "__macro_expression__"
 | 
			
		||||
Preprocess_Macro_Stmt,      "__macro_statment__"
 | 
			
		||||
Preprocess_Macro_Typename,  "__macro_typename__"
 | 
			
		||||
Preprocess_Unsupported,      "__unsupported__"
 | 
			
		||||
Spec_Alignas,                "alignas"
 | 
			
		||||
Spec_Const,                  "const"
 | 
			
		||||
Spec_Consteval,              "consteval"
 | 
			
		||||
Spec_Constexpr,              "constexpr"
 | 
			
		||||
Spec_Constinit,              "constinit"
 | 
			
		||||
Spec_Explicit,               "explicit"
 | 
			
		||||
Spec_Extern,                 "extern"
 | 
			
		||||
Spec_Final,                  "final"
 | 
			
		||||
Spec_ForceInline,            "FORCEINLINE"
 | 
			
		||||
Spec_ForceInline_Debuggable, "FORCEINLINE_DEBUGGABLE"
 | 
			
		||||
Spec_Global,                 "global"
 | 
			
		||||
Spec_Inline,                 "inline"
 | 
			
		||||
Spec_Internal_Linkage,       "internal"
 | 
			
		||||
Spec_LocalPersist,           "local_persist"
 | 
			
		||||
Spec_Mutable,                "mutable"
 | 
			
		||||
Spec_NeverInline,            "neverinline"
 | 
			
		||||
Spec_Override,               "override"
 | 
			
		||||
Spec_Static,                 "static"
 | 
			
		||||
Spec_ThreadLocal,            "thread_local"
 | 
			
		||||
Spec_Volatile,               "volatile"
 | 
			
		||||
Spec_Virtual,                "virtual"
 | 
			
		||||
Star,                        "*"
 | 
			
		||||
Statement_End,               ";"
 | 
			
		||||
StaticAssert,                "static_assert"
 | 
			
		||||
String,                      "__string__"
 | 
			
		||||
Type_Typename,               "typename"
 | 
			
		||||
Type_Unsigned,               "unsigned"
 | 
			
		||||
Type_Signed,                 "signed"
 | 
			
		||||
Type_Short,                  "short"
 | 
			
		||||
Type_Long,                   "long"
 | 
			
		||||
Type_bool,                   "bool"
 | 
			
		||||
Type_char,                   "char"
 | 
			
		||||
Type_int,                    "int"
 | 
			
		||||
Type_double,                 "double"
 | 
			
		||||
Type_MS_int8,                "__int8"
 | 
			
		||||
Type_MS_int16,               "__int16"
 | 
			
		||||
Type_MS_int32,               "__int32"
 | 
			
		||||
Type_MS_int64,               "__int64"
 | 
			
		||||
Type_MS_W64,                 "_W64"
 | 
			
		||||
Varadic_Argument,            "..."
 | 
			
		||||
__Attributes_Start,          "__attrib_start__"
 | 
			
		||||
		
		
			
  | 
@@ -55,7 +55,8 @@ Code format( Code code ) {
 | 
			
		||||
 | 
			
		||||
int gen_main()
 | 
			
		||||
{
 | 
			
		||||
	gen::init();
 | 
			
		||||
	Context ctx {};
 | 
			
		||||
	gen::init( & ctx);
 | 
			
		||||
 | 
			
		||||
	Code push_ignores        = scan_file( path_base "helpers/push_ignores.inline.hpp" );
 | 
			
		||||
	Code pop_ignores         = scan_file( path_base "helpers/pop_ignores.inline.hpp" );
 | 
			
		||||
@@ -63,11 +64,51 @@ int gen_main()
 | 
			
		||||
	Code ue_forceinline = code_str(FORCEINLINE);
 | 
			
		||||
	// Code
 | 
			
		||||
 | 
			
		||||
	register_macros( args(
 | 
			
		||||
		(Macro { txt("bit"),                          MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("bitfield_is_set"),              MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN_C_LIKE_CPP"),               MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("cast"),                         MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("ccast"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("rcast"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("pcast"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("scast"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("stringize_va"),                 MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("stringize"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("do_once"),                      MT_Expression, MF_Functional }), 
 | 
			
		||||
		(Macro { txt("do_once_defer"),                MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("do_once_start"),                MT_Statement,  MF_Null       }), 
 | 
			
		||||
		(Macro { txt("do_once_end"),                  MT_Statement,  MF_Null       }), 
 | 
			
		||||
		(Macro { txt("labeled_scope_start"),          MT_Statement,  MF_Null       }), 
 | 
			
		||||
		(Macro { txt("labeled_scope_end"),            MT_Statement,  MF_Null       }), 
 | 
			
		||||
		(Macro { txt("compiler_decorated_func_name"), MT_Expression, MF_Null       }), 
 | 
			
		||||
		(Macro { txt("num_args_impl"),                MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("num_args"),                     MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("count_of"),                     MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("clamp"),                        MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("is_between"),                   MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("size_of"),                      MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("min"),                          MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("max"),                          MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("offset_of"),                    MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("static_assert"),                MT_Statement,  MF_Functional }),
 | 
			
		||||
		(Macro { txt("typeof"),                       MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN_API_C_BEGIN"),              MT_Statement,  MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN_API_C_END"),                MT_Statement,  MF_Null       }),
 | 
			
		||||
		(Macro { txt("nullptr"),                      MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN_REMOVE_PTR"),               MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN_PARAM_DEFAULT"),            MT_Expression, MF_Null       }),
 | 
			
		||||
		(Macro { txt("struct_init"),                  MT_Expression, MF_Functional }),
 | 
			
		||||
		(Macro { txt("GEN_OPTIMIZE_MAPPINGS_BEGIN"),  MT_Statement,  MF_Null       }),
 | 
			
		||||
		(Macro { txt("GEN_OPITMIZE_MAPPINGS_END"),    MT_Statement,  MF_Null       }),
 | 
			
		||||
		(Macro { txt("src_line_str"),                 MT_Expression, MF_Null       })
 | 
			
		||||
	));
 | 
			
		||||
 | 
			
		||||
	// gen_dep.hpp
 | 
			
		||||
	{
 | 
			
		||||
		CodeBody macros = def_body( CT_Global_Body );
 | 
			
		||||
		{
 | 
			
		||||
			FileContents content    = file_read_contents( GlobalAllocator, true, path_base "dependencies/macros.hpp" );
 | 
			
		||||
			FileContents content    = file_read_contents( ctx.Allocator_Temp, file_zero_terminate, path_base "dependencies/macros.hpp" );
 | 
			
		||||
			CodeBody     ori_macros = parse_global_body( Str { (char const*)content.data, content.size });
 | 
			
		||||
 | 
			
		||||
			for (Code	code =  ori_macros.begin();
 | 
			
		||||
@@ -107,6 +148,7 @@ int gen_main()
 | 
			
		||||
		Code strings      = scan_file( path_base "dependencies/strings.hpp" );
 | 
			
		||||
		Code filesystem   = scan_file( path_base "dependencies/filesystem.hpp" );
 | 
			
		||||
		Code timing       = scan_file( path_base "dependencies/timing.hpp" );
 | 
			
		||||
		Code parsing      = scan_file( path_base "dependencies/parsing.hpp" );
 | 
			
		||||
 | 
			
		||||
		Builder
 | 
			
		||||
		header = Builder::open("gen/gen.dep.hpp");
 | 
			
		||||
@@ -128,6 +170,7 @@ int gen_main()
 | 
			
		||||
		header.print( strings );
 | 
			
		||||
		header.print( filesystem );
 | 
			
		||||
		header.print( timing );
 | 
			
		||||
		header.print(parsing);
 | 
			
		||||
 | 
			
		||||
		header.print_fmt( "\nGEN_NS_END\n" );
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
@@ -146,6 +189,7 @@ int gen_main()
 | 
			
		||||
		Code strings    = scan_file( path_base "dependencies/strings.cpp" );
 | 
			
		||||
		Code filesystem = scan_file( path_base "dependencies/filesystem.cpp" );
 | 
			
		||||
		Code timing     = scan_file( path_base "dependencies/timing.cpp" );
 | 
			
		||||
		Code parsing    = scan_file( path_base "dependencies/parsing.cpp" );
 | 
			
		||||
 | 
			
		||||
		Builder
 | 
			
		||||
		src = Builder::open( "gen/gen.dep.cpp" );
 | 
			
		||||
@@ -164,6 +208,7 @@ int gen_main()
 | 
			
		||||
		src.print( strings );
 | 
			
		||||
		src.print( filesystem );
 | 
			
		||||
		src.print( timing );
 | 
			
		||||
		src.print( parsing );
 | 
			
		||||
 | 
			
		||||
		src.print_fmt( "\nGEN_NS_END\n" );
 | 
			
		||||
		src.print( fmt_newline );
 | 
			
		||||
@@ -175,6 +220,7 @@ int gen_main()
 | 
			
		||||
	{
 | 
			
		||||
		Code header_start = scan_file(           "components/header_start.hpp" );
 | 
			
		||||
		Code types        = scan_file( path_base "components/types.hpp" );
 | 
			
		||||
		Code parser_types = scan_file( path_base "components/parser_types.hpp");
 | 
			
		||||
		Code ast          = scan_file( path_base "components/ast.hpp" );
 | 
			
		||||
		Code ast_types    = scan_file( path_base "components/ast_types.hpp" );
 | 
			
		||||
		Code code_types   = scan_file( path_base "components/code_types.hpp" );
 | 
			
		||||
@@ -184,9 +230,14 @@ int gen_main()
 | 
			
		||||
 | 
			
		||||
		CodeBody ecode       = gen_ecode     ( path_base "enums/ECodeTypes.csv" );
 | 
			
		||||
		CodeBody eoperator   = gen_eoperator ( path_base "enums/EOperator.csv" );
 | 
			
		||||
		CodeBody especifier  = gen_especifier( path_base "enums/ESpecifier.csv" );
 | 
			
		||||
		CodeBody especifier  = gen_especifier(           "enums/ESpecifier.csv" );
 | 
			
		||||
		CodeBody ast_inlines = gen_ast_inlines();
 | 
			
		||||
 | 
			
		||||
		// Note(Ed): The Attribute tokens need to be expanded and regenerated on a per-project/installation of this library for a specific codebase of Unreal.
 | 
			
		||||
		// We can support an arbitrary set of modules or plugin apis for parsing
 | 
			
		||||
		// but its up to the user to define them all (This will just provide whats I've used up till now).
 | 
			
		||||
		CodeBody etoktype = gen_etoktype( "enums/ETokType.csv", "enums/AttributeTokens.csv" );
 | 
			
		||||
 | 
			
		||||
		Builder
 | 
			
		||||
		header = Builder::open( "gen/gen.hpp" );
 | 
			
		||||
		header.print_fmt( generation_notice );
 | 
			
		||||
@@ -205,6 +256,8 @@ int gen_main()
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
		header.print( format(especifier) );
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
		header.print( format(etoktype) );
 | 
			
		||||
		header.print( parser_types );
 | 
			
		||||
		header.print_fmt( "#pragma endregion Types\n\n" );
 | 
			
		||||
 | 
			
		||||
		header.print_fmt( "#pragma region AST\n" );
 | 
			
		||||
@@ -230,7 +283,7 @@ int gen_main()
 | 
			
		||||
 | 
			
		||||
	// gen.cpp
 | 
			
		||||
	{
 | 
			
		||||
		Code        src_start          = scan_file(             "components/src_start.cpp" );
 | 
			
		||||
		Code        src_start          = scan_file(           "components/src_start.cpp" );
 | 
			
		||||
		Code        static_data 	   = scan_file( path_base "components/static_data.cpp" );
 | 
			
		||||
		Code        ast_case_macros    = scan_file( path_base "components/ast_case_macros.cpp" );
 | 
			
		||||
		Code        ast			       = scan_file( path_base "components/ast.cpp" );
 | 
			
		||||
@@ -238,15 +291,11 @@ int gen_main()
 | 
			
		||||
		Code        interface	       = scan_file( path_base "components/interface.cpp" );
 | 
			
		||||
		Code        upfront 	       = scan_file( path_base "components/interface.upfront.cpp" );
 | 
			
		||||
		Code        lexer              = scan_file( path_base "components/lexer.cpp" );
 | 
			
		||||
		Code        parser_case_macros = scan_file(           "components/parser_case_macros.cpp" );
 | 
			
		||||
		Code        parser             = scan_file( path_base "components/parser.cpp" );
 | 
			
		||||
		Code 	    parsing_interface  = scan_file( path_base "components/interface.parsing.cpp" );
 | 
			
		||||
		Code        untyped 	       = scan_file( path_base "components/interface.untyped.cpp" );
 | 
			
		||||
 | 
			
		||||
		// Note(Ed): The Attribute tokens need to be expanded and regenerated on a per-project/installation of this library for a specific codebase of Unreal.
 | 
			
		||||
		// We can support an arbitrary set of modules or plugin apis for parsing
 | 
			
		||||
		// but its up to the user to define them all (This will just provide whats I've used up till now).
 | 
			
		||||
		CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", "enums/AttributeTokens.csv" );
 | 
			
		||||
 | 
			
		||||
		Builder
 | 
			
		||||
		src = Builder::open( "gen/gen.cpp" );
 | 
			
		||||
		src.print_fmt( generation_notice );
 | 
			
		||||
@@ -266,14 +315,20 @@ int gen_main()
 | 
			
		||||
 | 
			
		||||
		src.print_fmt( "\n#pragma region Interface\n" );
 | 
			
		||||
		src.print( interface );
 | 
			
		||||
 | 
			
		||||
		src.print( upfront );
 | 
			
		||||
 | 
			
		||||
		src.print_fmt( "\n#pragma region Parsing\n\n" );
 | 
			
		||||
		src.print( format(etoktype) );
 | 
			
		||||
		src.print( lexer );
 | 
			
		||||
		src.print( parser_case_macros );
 | 
			
		||||
		src.print( parser );
 | 
			
		||||
		src.print( parsing_interface );
 | 
			
		||||
		src.print( untyped );
 | 
			
		||||
		src.print_fmt( "\n#pragma endregion Parsing\n\n" );
 | 
			
		||||
 | 
			
		||||
		src.print_fmt( "\n#pragma region Untyped\n\n" );
 | 
			
		||||
		src.print( untyped );
 | 
			
		||||
		src.print_fmt( "#pragma endregion \n\n" );
 | 
			
		||||
 | 
			
		||||
		src.print_fmt( "#pragma endregion Interface\n\n" );
 | 
			
		||||
 | 
			
		||||
		src.print_fmt( "GEN_NS_END\n\n");
 | 
			
		||||
@@ -320,7 +375,6 @@ int gen_main()
 | 
			
		||||
 | 
			
		||||
	// gen_scanner.hpp
 | 
			
		||||
	{
 | 
			
		||||
		Code parsing = scan_file( path_base "dependencies/parsing.hpp" );
 | 
			
		||||
		Code scanner = scan_file( path_base "auxillary/scanner.hpp" );
 | 
			
		||||
 | 
			
		||||
		Builder
 | 
			
		||||
@@ -331,7 +385,6 @@ int gen_main()
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
		header.print( def_include( txt("gen.hpp") ) );
 | 
			
		||||
		header.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
			
		||||
		header.print( parsing );
 | 
			
		||||
		header.print( scanner );
 | 
			
		||||
		header.print_fmt( "\nGEN_NS_END\n" );
 | 
			
		||||
		header.print( fmt_newline );
 | 
			
		||||
@@ -341,7 +394,6 @@ int gen_main()
 | 
			
		||||
 | 
			
		||||
	// gen.scanner.cpp
 | 
			
		||||
	{
 | 
			
		||||
		Code parsing = scan_file( path_base "dependencies/parsing.cpp" );
 | 
			
		||||
		Code scanner = scan_file( path_base "auxillary/scanner.cpp" );
 | 
			
		||||
 | 
			
		||||
		Builder
 | 
			
		||||
@@ -351,8 +403,7 @@ int gen_main()
 | 
			
		||||
		src.print( fmt_newline );
 | 
			
		||||
		src.print( def_include( txt("gen.scanner.hpp") ) );
 | 
			
		||||
		src.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
			
		||||
		src.print( parsing );
 | 
			
		||||
		// src.print( scanner );
 | 
			
		||||
		src.print( scanner );
 | 
			
		||||
		src.print_fmt( "\nGEN_NS_END\n" );
 | 
			
		||||
		src.print( fmt_newline );
 | 
			
		||||
		src.print( pop_ignores );
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								gencpp.10x
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								gencpp.10x
									
									
									
									
									
								
							@@ -1,79 +0,0 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<N10X>
 | 
			
		||||
	<Workspace>
 | 
			
		||||
		<IncludeFilter>&apos;.&apos;,**/project/**,</IncludeFilter>
 | 
			
		||||
		<ExcludeFilter>*.obj,*.lib,*.pch,*.dll,*.pdb,.vs,Debug,Release,x64,obj,*.user,Intermediate,**/sanity.gen.hpp,**/gen_c_library,**/gen_segmented,**/gen_singlheader,**/test,**/gen_unreal_engine,**/scripts,**/docs,</ExcludeFilter>
 | 
			
		||||
		<SyncFiles>true</SyncFiles>
 | 
			
		||||
		<Recursive>true</Recursive>
 | 
			
		||||
		<ShowEmptyFolders>true</ShowEmptyFolders>
 | 
			
		||||
		<IncludeFilesWithoutExt>false</IncludeFilesWithoutExt>
 | 
			
		||||
		<IsVirtual>false</IsVirtual>
 | 
			
		||||
		<IsFolder>false</IsFolder>
 | 
			
		||||
		<BuildCommand>pwsh ./scripts/build.ps1 msvc debug bootstrap</BuildCommand>
 | 
			
		||||
		<RebuildCommand>pwsh ./scripts/build.ps1 msvc debug c_library</RebuildCommand>
 | 
			
		||||
		<BuildFileCommand></BuildFileCommand>
 | 
			
		||||
		<CleanCommand>pwsh ./scripts/clean.ps1</CleanCommand>
 | 
			
		||||
		<BuildWorkingDirectory></BuildWorkingDirectory>
 | 
			
		||||
		<CancelBuild></CancelBuild>
 | 
			
		||||
		<Exe>./test/gen/build/gencpp.exe</Exe>
 | 
			
		||||
		<Args></Args>
 | 
			
		||||
		<WorkingDirectory></WorkingDirectory>
 | 
			
		||||
		<DebugCommand>pwsh ./scripts/build.ps1</DebugCommand>
 | 
			
		||||
		<DebugSln></DebugSln>
 | 
			
		||||
		<UseVisualStudioEnvBat>true</UseVisualStudioEnvBat>
 | 
			
		||||
		<CaptureExeOutput>false</CaptureExeOutput>
 | 
			
		||||
		<Configurations>
 | 
			
		||||
			<Configuration>Debug</Configuration>
 | 
			
		||||
			<Configuration>Release</Configuration>
 | 
			
		||||
			<Configuration>bootstrap debug</Configuration>
 | 
			
		||||
		</Configurations>
 | 
			
		||||
		<Platforms>
 | 
			
		||||
			<Platform>x64</Platform>
 | 
			
		||||
		</Platforms>
 | 
			
		||||
		<AdditionalIncludePaths>
 | 
			
		||||
			<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.36.32532\include</AdditionalIncludePath>
 | 
			
		||||
			<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.36.32532\ATLMFC\include</AdditionalIncludePath>
 | 
			
		||||
			<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\VS\include</AdditionalIncludePath>
 | 
			
		||||
			<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt</AdditionalIncludePath>
 | 
			
		||||
			<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um</AdditionalIncludePath>
 | 
			
		||||
			<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared</AdditionalIncludePath>
 | 
			
		||||
			<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt</AdditionalIncludePath>
 | 
			
		||||
			<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt</AdditionalIncludePath>
 | 
			
		||||
			<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um</AdditionalIncludePath>
 | 
			
		||||
		</AdditionalIncludePaths>
 | 
			
		||||
		<Defines>
 | 
			
		||||
			<Define>GEN_TIME</Define>
 | 
			
		||||
			<Define>GEN_SYSTEM_WINDOWS</Define>
 | 
			
		||||
			<Define>GEN_INTELLISENSE_DIRECTIVES</Define>
 | 
			
		||||
			<Define>GEN_EXECUTION_EXPRESSION_SUPPORT</Define>
 | 
			
		||||
			<Define>GEN_BENCHMARK</Define>
 | 
			
		||||
			<Define>GEN_COMPILER_MSVC</Define>
 | 
			
		||||
			<Define>GEN_IMPLEMENTATION</Define>
 | 
			
		||||
		</Defines>
 | 
			
		||||
		<ConfigProperties>
 | 
			
		||||
			<ConfigAndPlatform>
 | 
			
		||||
				<Name>Debug:x64</Name>
 | 
			
		||||
				<Defines></Defines>
 | 
			
		||||
				<ForceIncludes></ForceIncludes>
 | 
			
		||||
			</ConfigAndPlatform>
 | 
			
		||||
			<ConfigAndPlatform>
 | 
			
		||||
				<Name>bootstrap debug:x64</Name>
 | 
			
		||||
				<Defines></Defines>
 | 
			
		||||
				<ForceIncludes></ForceIncludes>
 | 
			
		||||
			</ConfigAndPlatform>
 | 
			
		||||
			<Config>
 | 
			
		||||
				<Name>Debug</Name>
 | 
			
		||||
				<Defines></Defines>
 | 
			
		||||
			</Config>
 | 
			
		||||
			<Config>
 | 
			
		||||
				<Name>bootstrap debug</Name>
 | 
			
		||||
				<Defines></Defines>
 | 
			
		||||
			</Config>
 | 
			
		||||
			<Platform>
 | 
			
		||||
				<Name>x64</Name>
 | 
			
		||||
				<Defines></Defines>
 | 
			
		||||
			</Platform>
 | 
			
		||||
		</ConfigProperties>
 | 
			
		||||
		<Children></Children>
 | 
			
		||||
	</Workspace>
 | 
			
		||||
</N10X>
 | 
			
		||||
							
								
								
									
										48
									
								
								gencpp.sln
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								gencpp.sln
									
									
									
									
									
								
							@@ -1,48 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Microsoft Visual Studio Solution File, Format Version 12.00
 | 
			
		||||
# Visual Studio Version 17
 | 
			
		||||
VisualStudioVersion = 17.5.33516.290
 | 
			
		||||
MinimumVisualStudioVersion = 10.0.40219.1
 | 
			
		||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencpp", "gencpp.vcxproj", "{53AF600D-C09C-4F39-83E0-E022AA9479F2}"
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
		bootstrap debug|x64 = bootstrap debug|x64
 | 
			
		||||
		bootstrap debug|x86 = bootstrap debug|x86
 | 
			
		||||
		bootstrap release|x64 = bootstrap release|x64
 | 
			
		||||
		bootstrap release|x86 = bootstrap release|x86
 | 
			
		||||
		singleheader debug|x64 = singleheader debug|x64
 | 
			
		||||
		singleheader debug|x86 = singleheader debug|x86
 | 
			
		||||
		singleheader release|x64 = singleheader release|x64
 | 
			
		||||
		singleheader release|x86 = singleheader release|x86
 | 
			
		||||
		test debug|x64 = test debug|x64
 | 
			
		||||
		test debug|x86 = test debug|x86
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap debug|x64.ActiveCfg = bootstrap release|x64
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap debug|x64.Build.0 = bootstrap release|x64
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap debug|x86.ActiveCfg = bootstrap debug|Win32
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap debug|x86.Build.0 = bootstrap debug|Win32
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap release|x64.ActiveCfg = bootstrap release|x64
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap release|x86.ActiveCfg = bootstrap release|Win32
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap release|x86.Build.0 = bootstrap release|Win32
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader debug|x64.ActiveCfg = singleheader debug|x64
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader debug|x64.Build.0 = singleheader debug|x64
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader debug|x86.ActiveCfg = singleheader debug|Win32
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader debug|x86.Build.0 = singleheader debug|Win32
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader release|x64.ActiveCfg = bootstrap debug|x64
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader release|x64.Build.0 = bootstrap debug|x64
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader release|x86.ActiveCfg = singleheader release|Win32
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader release|x86.Build.0 = singleheader release|Win32
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.test debug|x64.ActiveCfg = test debug|x64
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.test debug|x64.Build.0 = test debug|x64
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.test debug|x86.ActiveCfg = test debug|Win32
 | 
			
		||||
		{53AF600D-C09C-4F39-83E0-E022AA9479F2}.test debug|x86.Build.0 = test debug|Win32
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ExtensibilityGlobals) = postSolution
 | 
			
		||||
		SolutionGuid = {B12D2F1D-037C-44E1-B24B-2612E3DE0193}
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
EndGlobal
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
<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:StrBuilder x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=53AF600D_002DC09C_002D4F39_002D83E0_002DE022AA9479F2_002Fd_003Athirdparty_002Ff_003Azpl_002Eh/@EntryIndexedValue">ForceIncluded</s:StrBuilder>
 | 
			
		||||
	<s:StrBuilder x:Key="/Default/CodeInspection/Highlighting/SweaWarningsMode/@EntryValue">ShowAndRun</s:StrBuilder></wpf:ResourceDictionary>
 | 
			
		||||
							
								
								
									
										376
									
								
								gencpp.vcxproj
									
									
									
									
									
								
							
							
						
						
									
										376
									
								
								gencpp.vcxproj
									
									
									
									
									
								
							@@ -1,376 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <ItemGroup Label="ProjectConfigurations">
 | 
			
		||||
    <ProjectConfiguration Include="bootstrap debug|Win32">
 | 
			
		||||
      <Configuration>bootstrap debug</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="bootstrap debug|x64">
 | 
			
		||||
      <Configuration>bootstrap debug</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="bootstrap release|Win32">
 | 
			
		||||
      <Configuration>bootstrap release</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="bootstrap release|x64">
 | 
			
		||||
      <Configuration>bootstrap release</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="singleheader debug|Win32">
 | 
			
		||||
      <Configuration>singleheader debug</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="singleheader debug|x64">
 | 
			
		||||
      <Configuration>singleheader debug</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="singleheader release|Win32">
 | 
			
		||||
      <Configuration>singleheader release</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="singleheader release|x64">
 | 
			
		||||
      <Configuration>singleheader release</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="test debug|Win32">
 | 
			
		||||
      <Configuration>test debug</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="test debug|x64">
 | 
			
		||||
      <Configuration>test debug</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <PropertyGroup Label="Globals">
 | 
			
		||||
    <VCProjectVersion>17.0</VCProjectVersion>
 | 
			
		||||
    <ProjectGuid>{53AF600D-C09C-4F39-83E0-E022AA9479F2}</ProjectGuid>
 | 
			
		||||
    <Keyword>MakeFileProj</Keyword>
 | 
			
		||||
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Makefile</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v143</PlatformToolset>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
 | 
			
		||||
  <ImportGroup Label="ExtensionSettings">
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Label="Shared">
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='test debug|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|Win32'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'" Label="PropertySheets">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <PropertyGroup Label="UserMacros" />
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|Win32'">
 | 
			
		||||
    <NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|Win32'">
 | 
			
		||||
    <NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|Win32'">
 | 
			
		||||
    <NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|Win32'">
 | 
			
		||||
    <NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|Win32'">
 | 
			
		||||
    <NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'">
 | 
			
		||||
    <NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug bootstrap</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine>
 | 
			
		||||
    </NMakeReBuildCommandLine>
 | 
			
		||||
    <NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
    <IncludePath>$(ProjectDir)project;$(IncludePath)</IncludePath>
 | 
			
		||||
    <SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'">
 | 
			
		||||
    <NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug test</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine />
 | 
			
		||||
    <NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
    <IncludePath>$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
 | 
			
		||||
    <SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'">
 | 
			
		||||
    <NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug singleheader</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine>
 | 
			
		||||
    </NMakeReBuildCommandLine>
 | 
			
		||||
    <NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
    <IncludePath>$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
 | 
			
		||||
    <SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'">
 | 
			
		||||
    <NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc release singleheader</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine>
 | 
			
		||||
    </NMakeReBuildCommandLine>
 | 
			
		||||
    <NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
    <IncludePath>$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
 | 
			
		||||
    <SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'">
 | 
			
		||||
    <NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc release bootstrap</NMakeBuildCommandLine>
 | 
			
		||||
    <NMakeReBuildCommandLine>
 | 
			
		||||
    </NMakeReBuildCommandLine>
 | 
			
		||||
    <NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
 | 
			
		||||
    <NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
 | 
			
		||||
    <IncludePath>$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
 | 
			
		||||
    <SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <LanguageStandard_C>stdc11</LanguageStandard_C>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <LanguageStandard_C>stdc11</LanguageStandard_C>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <LanguageStandard_C>stdc11</LanguageStandard_C>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <LanguageStandard_C>stdc11</LanguageStandard_C>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <LanguageStandard_C>stdc11</LanguageStandard_C>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Include=".editorconfig" />
 | 
			
		||||
    <None Include="project\enums\AttributeTokens.csv" />
 | 
			
		||||
    <None Include="project\enums\ECode.csv" />
 | 
			
		||||
    <None Include="project\enums\EOperator.csv" />
 | 
			
		||||
    <None Include="project\enums\ESpecifier.csv" />
 | 
			
		||||
    <None Include="project\enums\ETokType.csv" />
 | 
			
		||||
    <None Include="Readme.md" />
 | 
			
		||||
    <None Include="scripts\.clang-format" />
 | 
			
		||||
    <None Include="scripts\build.ci.ps1" />
 | 
			
		||||
    <None Include="scripts\build.ps1" />
 | 
			
		||||
    <None Include="scripts\clean.ps1" />
 | 
			
		||||
    <None Include="scripts\genccp.natstepfilter" />
 | 
			
		||||
    <None Include="scripts\gencpp.refactor" />
 | 
			
		||||
    <None Include="scripts\helpers\devshell.ps1" />
 | 
			
		||||
    <None Include="scripts\helpers\target_arch.psm1" />
 | 
			
		||||
    <None Include="scripts\package_release.ps1" />
 | 
			
		||||
    <None Include="scripts\refactor.ps1" />
 | 
			
		||||
    <None Include="test\gen\meson.build" />
 | 
			
		||||
    <None Include="test\meson.build" />
 | 
			
		||||
    <None Include="test\Readme.md" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClInclude Include="gen_c_library\gen\gen.h" />
 | 
			
		||||
    <ClInclude Include="project\auxillary\builder.hpp" />
 | 
			
		||||
    <ClInclude Include="project\auxillary\editor.hpp" />
 | 
			
		||||
    <ClInclude Include="project\auxillary\scanner.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\ast.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\ast_types.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\code_types.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\gen\ast_inlines.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\gen\ecode.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\gen\eoperator.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\gen\especifier.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\header_end.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\header_start.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\inlines.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\interface.hpp" />
 | 
			
		||||
    <ClInclude Include="project\components\types.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\basic_types.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\containers.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\debug.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\filesystem.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\hashing.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\header_start.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\macros.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\memory.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\parsing.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\printing.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\strings.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\string_ops.hpp" />
 | 
			
		||||
    <ClInclude Include="project\dependencies\timing.hpp" />
 | 
			
		||||
    <ClInclude Include="project\gen.dep.hpp" />
 | 
			
		||||
    <ClInclude Include="project\gen.hpp" />
 | 
			
		||||
    <ClInclude Include="project\helpers\helper.hpp" />
 | 
			
		||||
    <ClInclude Include="project\helpers\pop_ignores.inline.hpp" />
 | 
			
		||||
    <ClInclude Include="project\helpers\push_ignores.inline.hpp" />
 | 
			
		||||
    <ClInclude Include="project\helpers\undef.macros.hpp" />
 | 
			
		||||
    <ClInclude Include="singleheader\components\header_start.hpp" />
 | 
			
		||||
    <ClInclude Include="test\CURSED_TYPEDEF.h" />
 | 
			
		||||
    <ClInclude Include="test\DummyInclude.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Parsed\Buffer.Parsed.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Parsed\HashTable.Parsed.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Parsed\Ring.Parsed.hpp" />
 | 
			
		||||
    <ClInclude Include="test\parsing.hpp" />
 | 
			
		||||
    <ClInclude Include="test\SOA.hpp" />
 | 
			
		||||
    <ClInclude Include="test\upfront.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Upfront\Array.Upfront.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Upfront\Buffer.Upfront.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Upfront\HashTable.Upfront.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Upfront\Ring.Upfront.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Upfront\Sanity.Upfront.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Parsed\Array.Parsed.hpp" />
 | 
			
		||||
    <ClInclude Include="test\Parsed\Sanity.Parsed.hpp" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClCompile Include="project\auxillary\builder.cpp" />
 | 
			
		||||
    <ClCompile Include="project\auxillary\scanner.cpp" />
 | 
			
		||||
    <ClCompile Include="project\bootstrap.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\ast.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\ast_case_macros.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\code_serialization.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\gen\etoktype.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\interface.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\interface.parsing.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\interface.untyped.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\interface.upfront.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\lexer.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\parser.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\src_start.cpp" />
 | 
			
		||||
    <ClCompile Include="project\components\static_data.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\debug.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\filesystem.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\hashing.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\memory.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\parsing.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\printing.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\src_start.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\strings.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\string_ops.cpp" />
 | 
			
		||||
    <ClCompile Include="project\dependencies\timing.cpp" />
 | 
			
		||||
    <ClCompile Include="project\Example.cpp" />
 | 
			
		||||
    <ClCompile Include="project\gen.cpp" />
 | 
			
		||||
    <ClCompile Include="project\gen.dep.cpp" />
 | 
			
		||||
    <ClCompile Include="singleheader\singleheader.cpp" />
 | 
			
		||||
    <ClCompile Include="test\parsed\test.parsing.cpp" />
 | 
			
		||||
    <ClCompile Include="test\parsing.cpp" />
 | 
			
		||||
    <ClCompile Include="test\sanity.cpp" />
 | 
			
		||||
    <ClCompile Include="test\SOA.cpp" />
 | 
			
		||||
    <ClCompile Include="test\test.cpp" />
 | 
			
		||||
    <ClCompile Include="test\test.parsing.cpp" />
 | 
			
		||||
    <ClCompile Include="test\test.singleheader_ast.cpp" />
 | 
			
		||||
    <ClCompile Include="test\test.Upfront.cpp" />
 | 
			
		||||
    <ClCompile Include="test\upfront.cpp" />
 | 
			
		||||
    <ClCompile Include="test\upfront\test.upfront.cpp" />
 | 
			
		||||
    <ClCompile Include="test\validate_bootstrap.cpp" />
 | 
			
		||||
    <ClCompile Include="test\validate_singleheader.cpp" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Natvis Include=".vscode\gencpp.natvis" />
 | 
			
		||||
    <Natvis Include="scripts\gencpp.natvis" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Content Include="project\enums\AttributeTokens.csv" />
 | 
			
		||||
    <Content Include="project\enums\ECode.csv" />
 | 
			
		||||
    <Content Include="project\enums\EOperator.csv" />
 | 
			
		||||
    <Content Include="project\enums\ESpecifier.csv" />
 | 
			
		||||
    <Content Include="project\enums\ETokType.csv" />
 | 
			
		||||
    <Content Include="scripts\.clang-format" />
 | 
			
		||||
    <Content Include="scripts\helpers\devshell.ps1" />
 | 
			
		||||
    <Content Include="scripts\helpers\target_arch.psm1" />
 | 
			
		||||
    <Content Include="scripts\refactor.ps1" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Folder Include="singleheader\gen\" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
 | 
			
		||||
  <ImportGroup Label="ExtensionTargets">
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
@@ -1,320 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Filter Include="Source Files">
 | 
			
		||||
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
 | 
			
		||||
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
 | 
			
		||||
    </Filter>
 | 
			
		||||
    <Filter Include="Header Files">
 | 
			
		||||
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
 | 
			
		||||
      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
 | 
			
		||||
    </Filter>
 | 
			
		||||
    <Filter Include="Resource Files">
 | 
			
		||||
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
 | 
			
		||||
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
 | 
			
		||||
    </Filter>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClCompile Include="project\gen.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\test.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\test.Upfront.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\gen.dep.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\parsing.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\sanity.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\SOA.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\upfront.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\test.parsing.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\ast.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\ast_case_macros.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\interface.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\interface.parsing.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\interface.upfront.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\src_start.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\static_data.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\bootstrap.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\debug.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\filesystem.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\hashing.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\memory.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\parsing.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\printing.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\src_start.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\string_ops.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\strings.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\dependencies\timing.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\auxillary\builder.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\auxillary\scanner.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="singleheader\singleheader.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\test.singleheader_ast.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\parsed\test.parsing.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\upfront\test.upfront.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\validate_singleheader.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="test\validate_bootstrap.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\interface.untyped.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\gen\etoktype.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\Example.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\parser.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\lexer.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="project\components\code_serialization.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClInclude Include="project\gen.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\DummyInclude.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Parsed\Buffer.Parsed.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Parsed\HashTable.Parsed.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Parsed\Ring.Parsed.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\SOA.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Upfront\Array.Upfront.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Upfront\Buffer.Upfront.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Upfront\HashTable.Upfront.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Upfront\Ring.Upfront.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Upfront\Sanity.Upfront.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Parsed\Array.Parsed.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\Parsed\Sanity.Parsed.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\gen.dep.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\parsing.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\upfront.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\ast.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\ast_types.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\header_end.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\header_start.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\inlines.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\interface.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\types.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\helpers\helper.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\helpers\pop_ignores.inline.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\helpers\push_ignores.inline.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\helpers\undef.macros.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\basic_types.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\containers.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\debug.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\filesystem.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\hashing.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\header_start.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\macros.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\memory.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\parsing.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\printing.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\string_ops.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\strings.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\dependencies\timing.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\auxillary\builder.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\auxillary\editor.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\auxillary\scanner.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="singleheader\components\header_start.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\gen\ast_inlines.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\gen\ecode.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\gen\eoperator.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\gen\especifier.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="test\CURSED_TYPEDEF.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="project\components\code_types.hpp">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Include=".editorconfig" />
 | 
			
		||||
    <None Include="Readme.md" />
 | 
			
		||||
    <None Include="scripts\build.ci.ps1" />
 | 
			
		||||
    <None Include="scripts\build.ps1" />
 | 
			
		||||
    <None Include="scripts\clean.ps1" />
 | 
			
		||||
    <None Include="test\gen\meson.build" />
 | 
			
		||||
    <None Include="test\meson.build" />
 | 
			
		||||
    <None Include="test\Readme.md" />
 | 
			
		||||
    <None Include="scripts\genccp.natstepfilter" />
 | 
			
		||||
    <None Include="scripts\gencpp.refactor" />
 | 
			
		||||
    <None Include="project\enums\AttributeTokens.csv" />
 | 
			
		||||
    <None Include="project\enums\ECode.csv" />
 | 
			
		||||
    <None Include="project\enums\EOperator.csv" />
 | 
			
		||||
    <None Include="project\enums\ESpecifier.csv" />
 | 
			
		||||
    <None Include="project\enums\ETokType.csv" />
 | 
			
		||||
    <None Include="scripts\helpers\devshell.ps1" />
 | 
			
		||||
    <None Include="scripts\helpers\target_arch.psm1" />
 | 
			
		||||
    <None Include="scripts\package_release.ps1" />
 | 
			
		||||
    <None Include="scripts\refactor.ps1" />
 | 
			
		||||
    <None Include="scripts\.clang-format" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Natvis Include=".vscode\gencpp.natvis" />
 | 
			
		||||
    <Natvis Include="scripts\gencpp.natvis" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <ShowAllFiles>true</ShowAllFiles>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'">
 | 
			
		||||
    <LocalDebuggerAttach>false</LocalDebuggerAttach>
 | 
			
		||||
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
 | 
			
		||||
    <LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'">
 | 
			
		||||
    <LocalDebuggerAttach>false</LocalDebuggerAttach>
 | 
			
		||||
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
 | 
			
		||||
    <LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'">
 | 
			
		||||
    <LocalDebuggerAttach>false</LocalDebuggerAttach>
 | 
			
		||||
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
 | 
			
		||||
    <LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'">
 | 
			
		||||
    <LocalDebuggerAttach>false</LocalDebuggerAttach>
 | 
			
		||||
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
 | 
			
		||||
    <LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'">
 | 
			
		||||
    <LocalDebuggerAttach>false</LocalDebuggerAttach>
 | 
			
		||||
    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
 | 
			
		||||
    <LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
@@ -1,8 +1,9 @@
 | 
			
		||||
# Format Style Options - Created with Clang Power Tools
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
# AttributeMacros: [
 | 
			
		||||
# ]
 | 
			
		||||
AttributeMacros: [
 | 
			
		||||
  GEN_API
 | 
			
		||||
]
 | 
			
		||||
StatementMacros: [
 | 
			
		||||
  GEN_NS_BEGIN, 
 | 
			
		||||
  GEN_NS_END, 
 | 
			
		||||
@@ -15,6 +16,8 @@ StatementMacros: [
 | 
			
		||||
Macros:
 | 
			
		||||
- enum_underlying(type)=type
 | 
			
		||||
- gen_enum_underlying(type)=type
 | 
			
		||||
# WhitespaceSensitiveMacros: [
 | 
			
		||||
# ]
 | 
			
		||||
 | 
			
		||||
TypenameMacros: [Array, Hashtable]
 | 
			
		||||
SkipMacroDefinitionBody: false
 | 
			
		||||
 
 | 
			
		||||
@@ -15,11 +15,13 @@ Its main uage is the [c_library generation](../gen_c_library/).
 | 
			
		||||
Remove any generated content from the repository.
 | 
			
		||||
 | 
			
		||||
**`build.ps1`**  
 | 
			
		||||
Build c_library, segmented, singleheader, unreal. Supports msvc or clang, release or debug.
 | 
			
		||||
Build c library (segmented, singleheader, static, or dynamic), cpp library (segmented, singleheader, or unreal). Supports msvc or clang, release or debug.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
```erlang
 | 
			
		||||
args:
 | 
			
		||||
    c_library
 | 
			
		||||
    c_lib        : Build c11 library (singleheader & segmented)
 | 
			
		||||
    c_lib_static : Build static  c11 library
 | 
			
		||||
    c_lib_dyn    : Buidl dyanmic c11
 | 
			
		||||
    segemented
 | 
			
		||||
    singleheader
 | 
			
		||||
    unreal
 | 
			
		||||
 
 | 
			
		||||
@@ -17,11 +17,13 @@ Push-Location $path_root
 | 
			
		||||
#region Arguments
 | 
			
		||||
       $vendor       = $null
 | 
			
		||||
       $release      = $null
 | 
			
		||||
	   $verbose      = $false
 | 
			
		||||
	   $base         = $false
 | 
			
		||||
[bool] $verbose      = $false
 | 
			
		||||
[bool] $base         = $false
 | 
			
		||||
[bool] $segmented    = $false
 | 
			
		||||
[bool] $singleheader = $false
 | 
			
		||||
[bool] $c_library    = $false
 | 
			
		||||
[bool] $c_lib        = $false
 | 
			
		||||
[bool] $c_lib_static = $false
 | 
			
		||||
[bool] $c_lib_dyn    = $false
 | 
			
		||||
[bool] $unreal       = $false
 | 
			
		||||
[bool] $test         = $false
 | 
			
		||||
 | 
			
		||||
@@ -36,9 +38,11 @@ if ( $args ) { $args | ForEach-Object {
 | 
			
		||||
		"release"             { $release      = $true }
 | 
			
		||||
		"debug"               { $release      = $false }
 | 
			
		||||
		"base"                { $base         = $true }
 | 
			
		||||
		"segmented"          { $segmented     = $true }
 | 
			
		||||
		"segmented"           { $segmented    = $true }
 | 
			
		||||
		"singleheader"        { $singleheader = $true }
 | 
			
		||||
		"c_library"           { $c_library    = $true }
 | 
			
		||||
		"c_lib"               { $c_lib        = $true }
 | 
			
		||||
		"c_lib_static"        { $c_lib_static = $true }
 | 
			
		||||
		"c_lib_dyn"           { $c_lib_dyn    = $true }
 | 
			
		||||
		"unreal"              { $unreal       = $true }
 | 
			
		||||
		"test"                { $test         = $true }
 | 
			
		||||
	}
 | 
			
		||||
@@ -71,7 +75,9 @@ else {
 | 
			
		||||
$cannot_build =                     $base         -eq $false
 | 
			
		||||
$cannot_build = $cannot_build -and  $segmented    -eq $false
 | 
			
		||||
$cannot_build = $cannot_build -and  $singleheader -eq $false
 | 
			
		||||
$cannot_build = $cannot_build -and  $c_library    -eq $false
 | 
			
		||||
$cannot_build = $cannot_build -and  $c_lib        -eq $false
 | 
			
		||||
$cannot_build = $cannot_build -and  $c_lib_static -eq $false
 | 
			
		||||
$cannot_build = $cannot_build -and  $c_lib_dyn    -eq $false
 | 
			
		||||
$cannot_build = $cannot_build -and  $unreal       -eq $false
 | 
			
		||||
$cannot_build = $cannot_build -and  $test         -eq $false
 | 
			
		||||
if ( $cannot_build ) {
 | 
			
		||||
@@ -209,7 +215,7 @@ if ( $singleheader )
 | 
			
		||||
	Pop-Location
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if ( $c_library )
 | 
			
		||||
if ( $c_lib -or $c_lib_static -or $c_lib_dyn )
 | 
			
		||||
{
 | 
			
		||||
	$path_build = join-path $path_c_library build
 | 
			
		||||
	$path_gen   = join-path $path_c_library gen
 | 
			
		||||
@@ -245,34 +251,38 @@ if ( $c_library )
 | 
			
		||||
			write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
 | 
			
		||||
		}
 | 
			
		||||
	Pop-Location
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	$includes    = @( $path_c_library )
 | 
			
		||||
	$unit       = join-path $path_c_library "gen.c"
 | 
			
		||||
	$executable = join-path $path_build     "gen_c_library_test.exe"
 | 
			
		||||
if ( $c_lib_static )
 | 
			
		||||
{
 | 
			
		||||
	$includes = @( $path_c_library )
 | 
			
		||||
	$unit     = join-path $path_c_library "gen_c_lib.c"
 | 
			
		||||
	$path_lib = join-path $path_build     "gencpp_c11.lib"
 | 
			
		||||
 | 
			
		||||
	if ($vendor -eq "clang") {
 | 
			
		||||
		$compiler_args += '-x'
 | 
			
		||||
		$compiler_args += 'c'
 | 
			
		||||
		$compiler_args += '-std=c11'
 | 
			
		||||
	} elseif ($vendor -eq "msvc") {
 | 
			
		||||
		$compiler_args += "/TC"       # Compile as C
 | 
			
		||||
		$compiler_args += "/Zc:__cplusplus" # Fix __cplusplus macro
 | 
			
		||||
		$compiler_args += "/std:c11"
 | 
			
		||||
	}
 | 
			
		||||
	$compiler_args = @()
 | 
			
		||||
	$compiler_args += $flag_all_c
 | 
			
		||||
	$compiler_args += $flag_updated_cpp_macro
 | 
			
		||||
	$compiler_args += $flag_c11
 | 
			
		||||
 | 
			
		||||
	$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
 | 
			
		||||
	$linker_args = @()
 | 
			
		||||
	$result = build-simple $path_build $includes $compiler_args $linker_args $unit $path_lib
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	Push-Location $path_c_library
 | 
			
		||||
		if ( Test-Path( $executable ) ) {
 | 
			
		||||
			write-host "`nRunning c_library test"
 | 
			
		||||
			$time_taken = Measure-Command { & $executable
 | 
			
		||||
					| ForEach-Object {
 | 
			
		||||
						write-host `t $_ -ForegroundColor Green
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
 | 
			
		||||
		}
 | 
			
		||||
	Pop-Location
 | 
			
		||||
if ( $c_lib_dyn )
 | 
			
		||||
{
 | 
			
		||||
	$includes = @( $path_c_library )
 | 
			
		||||
	$unit     = join-path $path_c_library "gen_c_lib.c"
 | 
			
		||||
	$path_dll = join-path $path_build     "gencpp_c11.dll"
 | 
			
		||||
 
 | 
			
		||||
	$compiler_args = @()
 | 
			
		||||
	$compiler_args += $flag_all_c
 | 
			
		||||
	$compiler_args += $flag_updated_cpp_macro
 | 
			
		||||
	$compiler_args += $flag_c11
 | 
			
		||||
	$compiler_args += ( $flag_define + 'GEN_DYN_LINK' )
 | 
			
		||||
	$compiler_args += ( $flag_define + 'GEN_DYN_EXPORT' )
 | 
			
		||||
 
 | 
			
		||||
	$linker_args = @()
 | 
			
		||||
	$result = build-simple $path_build $includes $compiler_args $linker_args $unit $path_dll
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if ( $unreal )
 | 
			
		||||
@@ -315,44 +325,65 @@ if ( $unreal )
 | 
			
		||||
	. $refactor_unreal
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# TODO(Ed): The unit testing needs a full rewrite
 | 
			
		||||
# C Library testing
 | 
			
		||||
if ( $test -and $false )
 | 
			
		||||
{
 | 
			
		||||
	$path_gen          = join-path $path_test gen
 | 
			
		||||
	$path_gen_build    = join-path $path_gen  build
 | 
			
		||||
	$path_build        = join-path $path_test build
 | 
			
		||||
	$path_original     = join-path $path_gen  original
 | 
			
		||||
	$path_components   = join-path $path_original components
 | 
			
		||||
	$path_dependencies = join-path $path_original dependencies
 | 
			
		||||
	$path_helpers      = join-path $path_original helpers
 | 
			
		||||
 | 
			
		||||
	$path_test_c = join-path $path_test   c_library
 | 
			
		||||
	$path_build  = join-path $path_test_c build
 | 
			
		||||
	$path_gen    = join-path $path_test_c gen
 | 
			
		||||
	if ( -not(Test-Path($path_build) )) {
 | 
			
		||||
		New-Item -ItemType Directory -Path $path_build
 | 
			
		||||
	}
 | 
			
		||||
	if ( -not(Test-Path($path_gen) )) {
 | 
			
		||||
		New-Item -ItemType Directory -Path $path_gen
 | 
			
		||||
	}
 | 
			
		||||
	if ( -not(Test-Path($path_gen_build) ))  {
 | 
			
		||||
		New-Item -ItemType Directory -Path $path_gen_build
 | 
			
		||||
 | 
			
		||||
	$path_singleheader_include = join-path $path_c_library gen
 | 
			
		||||
	$includes    = @( $path_singleheader_include )
 | 
			
		||||
	$unit       = join-path $path_test_c "test.c"
 | 
			
		||||
	$executable = join-path $path_build  "test.exe"
 | 
			
		||||
 | 
			
		||||
	$compiler_args = @()
 | 
			
		||||
	$compiler_args += ( $flag_define + 'GEN_TIME' )
 | 
			
		||||
	$compiler_args += $flag_all_c
 | 
			
		||||
	$compiler_args += $flag_updated_cpp_macro
 | 
			
		||||
	$compiler_args += $flag_c11
 | 
			
		||||
 | 
			
		||||
	$linker_args   = @(
 | 
			
		||||
		$flag_link_win_subsystem_console
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
 | 
			
		||||
 | 
			
		||||
	Push-Location $path_test_c
 | 
			
		||||
		if ( Test-Path( $executable ) ) {
 | 
			
		||||
			write-host "`nRunning c_library test"
 | 
			
		||||
			$time_taken = Measure-Command { & $executable
 | 
			
		||||
					| ForEach-Object {
 | 
			
		||||
						write-host `t $_ -ForegroundColor Green
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
 | 
			
		||||
		}
 | 
			
		||||
	Pop-Location
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if ($test -and $true)
 | 
			
		||||
{
 | 
			
		||||
	$path_test_cpp = join-path $path_test     cpp_library
 | 
			
		||||
	$path_build    = join-path $path_test_cpp build
 | 
			
		||||
	$path_gen      = join-path $path_test_cpp gen
 | 
			
		||||
	if ( -not(Test-Path($path_build) )) {
 | 
			
		||||
		New-Item -ItemType Directory -Path $path_build
 | 
			
		||||
	}
 | 
			
		||||
	if ( -not(test-path $path_original)) {
 | 
			
		||||
		new-item -ItemType Directory -Path $path_original
 | 
			
		||||
	}
 | 
			
		||||
	if ( -not(test-path $path_components)) {
 | 
			
		||||
		new-item -ItemType Directory -Path $path_components
 | 
			
		||||
	}
 | 
			
		||||
	if ( -not(test-path $path_dependencies)) {
 | 
			
		||||
		new-item -ItemType Directory -Path $path_dependencies
 | 
			
		||||
	}
 | 
			
		||||
	if ( -not(test-path $path_helpers)) {
 | 
			
		||||
		new-item -ItemType Directory -Path $path_helpers
 | 
			
		||||
	if ( -not(Test-Path($path_gen) )) {
 | 
			
		||||
		New-Item -ItemType Directory -Path $path_gen
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	$path_bootstrap = join-path $path_project gen
 | 
			
		||||
 | 
			
		||||
	$includes    = @( $path_bootstrap )
 | 
			
		||||
	$unit       = join-path $path_test  "test.cpp"
 | 
			
		||||
	$executable = join-path $path_build "test.exe"
 | 
			
		||||
	$path_singleheader_include = join-path $path_singleheader gen
 | 
			
		||||
	$includes    = @( $path_singleheader_include )
 | 
			
		||||
	$unit       = join-path $path_test_cpp "test.cpp"
 | 
			
		||||
	$executable = join-path $path_build    "test.exe"
 | 
			
		||||
 | 
			
		||||
	$compiler_args = @()
 | 
			
		||||
	$compiler_args += ( $flag_define + 'GEN_TIME' )
 | 
			
		||||
@@ -363,16 +394,15 @@ if ( $test -and $false )
 | 
			
		||||
 | 
			
		||||
	$result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
 | 
			
		||||
 | 
			
		||||
	Push-Location $path_test
 | 
			
		||||
		Write-Host $path_test
 | 
			
		||||
	Push-Location $path_test_cpp
 | 
			
		||||
		if ( Test-Path( $executable ) ) {
 | 
			
		||||
			write-host "`nRunning test generator"
 | 
			
		||||
			write-host "`nRunning cpp_library test"
 | 
			
		||||
			$time_taken = Measure-Command { & $executable
 | 
			
		||||
					| ForEach-Object {
 | 
			
		||||
						write-host `t $_ -ForegroundColor Green
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			write-host "`nTest generator completed in $($time_taken.TotalMilliseconds) ms"
 | 
			
		||||
			write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
 | 
			
		||||
		}
 | 
			
		||||
	Pop-Location
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,40 @@ if ( $dev ) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Add new function for running lib.exe
 | 
			
		||||
function run-archiver
 | 
			
		||||
{
 | 
			
		||||
    param( $archiver, $library, $lib_args )
 | 
			
		||||
 | 
			
		||||
    write-host "`Creating library $library"
 | 
			
		||||
    if ( $verbose ) {
 | 
			
		||||
        write-host "Lib manager config:"
 | 
			
		||||
        $lib_args | ForEach-Object {
 | 
			
		||||
            write-host $_ -ForegroundColor Cyan
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $time_taken = Measure-Command {
 | 
			
		||||
        & $archiver $lib_args 2>&1 | ForEach-Object {
 | 
			
		||||
            $color = 'White'
 | 
			
		||||
            switch ($_){
 | 
			
		||||
                { $_ -match "error"   } { $color = 'Red'   ; break }
 | 
			
		||||
                { $_ -match "warning" } { $color = 'Yellow'; break }
 | 
			
		||||
            }
 | 
			
		||||
            write-host `t $_ -ForegroundColor $color
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( $LASTEXITCODE -eq 0 ) {
 | 
			
		||||
        write-host "$library creation finished in $($time_taken.TotalMilliseconds) ms`n"
 | 
			
		||||
        return $true
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        write-host "Library creation failed for $library`n" -ForegroundColor Red
 | 
			
		||||
        return $false
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function run-compiler
 | 
			
		||||
{
 | 
			
		||||
	param( $compiler, $unit, $compiler_args )
 | 
			
		||||
@@ -95,7 +129,8 @@ function run-linker
 | 
			
		||||
if ( $vendor -match "clang" )
 | 
			
		||||
{
 | 
			
		||||
	# https://clang.llvm.org/docs/ClangCommandLineReference.html
 | 
			
		||||
	$flag_all_c 					   = '-x c'
 | 
			
		||||
	$flag_all_c 					   = @('-x', 'c')
 | 
			
		||||
	$flag_c11                          = '-std=c11'
 | 
			
		||||
	$flag_all_cpp                      = '-x c++'
 | 
			
		||||
	$flag_compile                      = '-c'
 | 
			
		||||
	$flag_color_diagnostics            = '-fcolor-diagnostics'
 | 
			
		||||
@@ -174,8 +209,8 @@ if ( $vendor -match "clang" )
 | 
			
		||||
		$map    = join-path $path_output (split-path $map    -Leaf)
 | 
			
		||||
 | 
			
		||||
		# This allows dll reloads at runtime to work (jankily, use below if not interested)
 | 
			
		||||
		$pdb    = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
 | 
			
		||||
		# $pdb    = $binary -replace '\.(exe|dll)$', ".pdb"
 | 
			
		||||
		# $pdb    = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
 | 
			
		||||
		$pdb    = $binary -replace '\.(exe|dll)$', ".pdb"
 | 
			
		||||
 | 
			
		||||
		$compiler_args += @(
 | 
			
		||||
			$flag_no_color_diagnostics,
 | 
			
		||||
@@ -253,8 +288,8 @@ if ( $vendor -match "clang" )
 | 
			
		||||
		$map    = join-path $path_output (split-path $map    -Leaf)
 | 
			
		||||
 | 
			
		||||
		# This allows dll reloads at runtime to work (jankily, use below if not interested)
 | 
			
		||||
		$pdb    = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
 | 
			
		||||
		# $pdb    = $binary -replace '\.(exe|dll)$', ".pdb"
 | 
			
		||||
		# $pdb    = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
 | 
			
		||||
		$pdb    = $binary -replace '\.(exe|dll)$', ".pdb"
 | 
			
		||||
 | 
			
		||||
		$compiler_args += @(
 | 
			
		||||
			$flag_no_color_diagnostics,
 | 
			
		||||
@@ -308,10 +343,22 @@ if ( $vendor -match "clang" )
 | 
			
		||||
			$linker_args += $_ + '.lib'
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		# Check if output is a static library
 | 
			
		||||
		# if ( $binary -match '\.lib$' )
 | 
			
		||||
		# {
 | 
			
		||||
			# $lib_args  = @()
 | 
			
		||||
			# $lib_args += $flag_nologo
 | 
			
		||||
			# $lib_args += $flag_link_win_machine_64
 | 
			
		||||
			# $lib_args += ( $flag_link_win_path_output + $binary )
 | 
			
		||||
			# $lib_args += $object
 | 
			
		||||
			# return run-archiver $archiver $binary $lib_args
 | 
			
		||||
		# }
 | 
			
		||||
 | 
			
		||||
		$linker_args += $object
 | 
			
		||||
		return run-linker $linker $binary $linker_args
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	$archiver = 'llvm-ar'
 | 
			
		||||
	$compiler = 'clang++'
 | 
			
		||||
	$linker   = 'lld-link'
 | 
			
		||||
}
 | 
			
		||||
@@ -320,6 +367,7 @@ if ( $vendor -match "msvc" )
 | 
			
		||||
{
 | 
			
		||||
	# https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170
 | 
			
		||||
	$flag_all_c 					  = '/TC'
 | 
			
		||||
	$flag_c11                         = '/std:c11'
 | 
			
		||||
	$flag_all_cpp                     = '/TP'
 | 
			
		||||
	$flag_compile			          = '/c'
 | 
			
		||||
	$flag_debug                       = '/Zi'
 | 
			
		||||
@@ -332,6 +380,7 @@ if ( $vendor -match "msvc" )
 | 
			
		||||
	$flag_dll 				          = '/LD'
 | 
			
		||||
	$flag_dll_debug 			      = '/LDd'
 | 
			
		||||
	$flag_linker 		              = '/link'
 | 
			
		||||
	# $flag_link_lib                    = '/lib'
 | 
			
		||||
	$flag_link_dll                    = '/DLL'
 | 
			
		||||
	$flag_link_no_incremental 	      = '/INCREMENTAL:NO'
 | 
			
		||||
	$flag_link_mapfile 				  = '/MAP:'
 | 
			
		||||
@@ -354,15 +403,17 @@ if ( $vendor -match "msvc" )
 | 
			
		||||
	$flag_optimized_debug_forceinline = '/d2Obforceinline'
 | 
			
		||||
	$flag_optimized_debug			  = '/Zo'
 | 
			
		||||
	$flag_
 | 
			
		||||
	$flag_out_name                    = '/OUT:'
 | 
			
		||||
	# $flag_out_name                    = '/OUT:'
 | 
			
		||||
	$flag_path_interm                 = '/Fo'
 | 
			
		||||
	$flag_path_debug                  = '/Fd'
 | 
			
		||||
	$flag_path_output                 = '/Fe'
 | 
			
		||||
	$flag_preprocess_conform          = '/Zc:preprocessor'
 | 
			
		||||
	$flag_updated_cpp_macro           = "/Zc:__cplusplus"
 | 
			
		||||
	$flag_set_stack_size			  = '/F'
 | 
			
		||||
	$flag_syntax_only				  = '/Zs'
 | 
			
		||||
	$flag_wall 					      = '/Wall'
 | 
			
		||||
	$flag_warnings_as_errors 		  = '/WX'
 | 
			
		||||
	$flag_lib_list                    = '/LIST'
 | 
			
		||||
 | 
			
		||||
	function build
 | 
			
		||||
	{
 | 
			
		||||
@@ -374,8 +425,8 @@ if ( $vendor -match "msvc" )
 | 
			
		||||
		$map    = join-path $path_output (split-path $map    -Leaf)
 | 
			
		||||
 | 
			
		||||
		# This allows dll reloads at runtime to work (jankily, use below if not interested)
 | 
			
		||||
		$pdb    = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
 | 
			
		||||
		# $pdb    = $binary -replace '\.(exe|dll)$', ".pdb"
 | 
			
		||||
		# $pdb    = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
 | 
			
		||||
		$pdb    = $binary -replace '\.(exe|dll)$', ".pdb"
 | 
			
		||||
 | 
			
		||||
		$compiler_args += @(
 | 
			
		||||
			$flag_nologo,
 | 
			
		||||
@@ -461,8 +512,8 @@ if ( $vendor -match "msvc" )
 | 
			
		||||
		$map    = join-path $path_output (split-path $map    -Leaf)
 | 
			
		||||
 | 
			
		||||
		# This allows dll reloads at runtime to work (jankily, use below if not interested)
 | 
			
		||||
		$pdb    = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
 | 
			
		||||
		# $pdb    = $binary -replace '\.(exe|dll)$', ".pdb"
 | 
			
		||||
		# $pdb    = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
 | 
			
		||||
		$pdb    = $binary -replace '\.(exe|dll)$', ".pdb"
 | 
			
		||||
 | 
			
		||||
		$compiler_args += @(
 | 
			
		||||
			$flag_nologo,
 | 
			
		||||
@@ -508,6 +559,17 @@ if ( $vendor -match "msvc" )
 | 
			
		||||
			return $false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		# Check if output is a static library
 | 
			
		||||
		if ( $binary -match '\.lib$' )
 | 
			
		||||
		{
 | 
			
		||||
			$lib_args  = @()
 | 
			
		||||
			$lib_args += $flag_nologo
 | 
			
		||||
			$lib_args += $flag_link_win_machine_64
 | 
			
		||||
			$lib_args += ( $flag_link_win_path_output + $binary )
 | 
			
		||||
			$lib_args += $object
 | 
			
		||||
			return run-archiver $archiver $binary $lib_args
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$linker_args += @(
 | 
			
		||||
			$flag_nologo,
 | 
			
		||||
			$flag_link_win_machine_64,
 | 
			
		||||
@@ -522,10 +584,19 @@ if ( $vendor -match "msvc" )
 | 
			
		||||
		else {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		# Check if output is a dynamic library
 | 
			
		||||
		if ( $binary -match '\.dll$' ) {
 | 
			
		||||
			$linker_args += $flag_link_dll
 | 
			
		||||
		}
 | 
			
		||||
		$linker_args += $object
 | 
			
		||||
		# Write-Host "link args:"
 | 
			
		||||
		# $linker_args | ForEach-Object {
 | 
			
		||||
		# 	Write-Host "`t$_" -ForegroundColor Yellow
 | 
			
		||||
		# }
 | 
			
		||||
		return run-linker $linker $binary $linker_args
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	$archiver = 'lib'
 | 
			
		||||
	$compiler = 'cl'
 | 
			
		||||
	$linker   = 'link'
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,16 +4,14 @@ Import-Module $misc
 | 
			
		||||
$build = Join-Path $PSScriptRoot 'build.ci.ps1'
 | 
			
		||||
 | 
			
		||||
if ( $IsWindows ) {
 | 
			
		||||
	& $build release msvc base segmented singleheader unreal c_library msvc debug
 | 
			
		||||
}
 | 
			
		||||
else {
 | 
			
		||||
	& $build release clang base segmented singleheader unreal c_library msvc debug
 | 
			
		||||
	& $build release msvc debug base segmented singleheader unreal c_lib c_lib_static c_lib_dyn
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$path_root             = Get-ScriptRepoRoot
 | 
			
		||||
$path_docs			   = Join-Path $path_root          docs
 | 
			
		||||
$path_base             = Join-Path $path_root          base
 | 
			
		||||
$path_c_library        = Join-Path $path_root          gen_c_library
 | 
			
		||||
$path_c_library_build  = Join-Path $path_c_library     build
 | 
			
		||||
$path_c_library_gen    = Join-Path $path_c_library     gen
 | 
			
		||||
$path_segmented        = Join-Path $path_root          gen_segmented
 | 
			
		||||
$path_segmented_gen    = Join-Path $path_segmented     gen
 | 
			
		||||
@@ -74,7 +72,7 @@ Remove-Item -Path $path_release_content -Recurse
 | 
			
		||||
prep-ReleaseContent
 | 
			
		||||
Copy-Item        -Verbose -Path $path_c_library\Readme.md              -Destination $path_release_content
 | 
			
		||||
Copy-Item        -Verbose -Path $path_c_library_gen\gen_singleheader.h -Destination $path_release_content\gen.h
 | 
			
		||||
Compress-Archive -Path $path_release_content\*                -DestinationPath $path_release\gencpp_c11_singleheader.zip -Force
 | 
			
		||||
Compress-Archive -Path $path_release_content\*                         -DestinationPath $path_release\gencpp_c11_singleheader.zip -Force
 | 
			
		||||
Remove-Item -Path $path_release_content -Recurse
 | 
			
		||||
 | 
			
		||||
# C Library Segmented
 | 
			
		||||
@@ -87,6 +85,20 @@ Copy-Item        -Verbose -Path $path_c_library_gen\gen.h     -Destination $path
 | 
			
		||||
Compress-Archive -Path $path_release_content\*       -DestinationPath $path_release\gencpp_c11_segmented.zip -Force
 | 
			
		||||
Remove-Item -Path $path_release_content -Recurse
 | 
			
		||||
 | 
			
		||||
# C Library Segmented
 | 
			
		||||
prep-ReleaseContent
 | 
			
		||||
Copy-Item        -Verbose -Path $path_c_library\Readme.md     -Destination $path_release_content
 | 
			
		||||
Copy-Item        -Verbose -Path $path_c_library_gen\gen.dep.c -Destination $path_release_content
 | 
			
		||||
Copy-Item        -Verbose -Path $path_c_library_gen\gen.dep.h -Destination $path_release_content
 | 
			
		||||
Copy-Item        -Verbose -Path $path_c_library_gen\gen.c     -Destination $path_release_content
 | 
			
		||||
Copy-Item        -Verbose -Path $path_c_library_gen\gen.h     -Destination $path_release_content
 | 
			
		||||
Compress-Archive -Path $path_release_content\*                -DestinationPath $path_release\gencpp_c11_segmented.zip -Force
 | 
			
		||||
Remove-Item -Path $path_release_content -Recurse
 | 
			
		||||
 | 
			
		||||
# C Lib Static & Dyanmic Libs
 | 
			
		||||
Copy-Item -Verbose -Path $path_c_library_build\gencpp_c11.lib -Destination $path_release
 | 
			
		||||
Copy-Item -Verbose -Path $path_c_library_build\gencpp_c11.dll -Destination $path_release
 | 
			
		||||
 | 
			
		||||
# Base
 | 
			
		||||
 | 
			
		||||
prep-ReleaseContent
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								test/c_library/test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								test/c_library/test.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
#define GEN_IMPLEMENTATION
 | 
			
		||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
 | 
			
		||||
#include "gen_singleheader.h"
 | 
			
		||||
 | 
			
		||||
#define gen_iterator( Type, container, iter )   \
 | 
			
		||||
	        gen_begin_ ## Type(container);      \
 | 
			
		||||
	iter != gen_end_   ## Type(container);      \
 | 
			
		||||
	code  = gen_next_  ## Type(container, iter)
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
	gen_Context ctx = {0};
 | 
			
		||||
	gen_init(& ctx);
 | 
			
		||||
 | 
			
		||||
	gen_Builder src_hello = gen_builder_open("gen/hello.c");
 | 
			
		||||
	gen_CodeVar hello_var = gen_parse_variable(code(
 | 
			
		||||
		char const* hello_gencpp_str = "HELLO GENCPP C11 !";
 | 
			
		||||
	));
 | 
			
		||||
	gen_builder_print( & src_hello, (gen_Code)hello_var );
 | 
			
		||||
	gen_builder_write(& src_hello);
 | 
			
		||||
 | 
			
		||||
	gen_CodeBody body = gen_parse_file("gen/hello.c");
 | 
			
		||||
	for (gen_Code code = gen_iterator(CodeBody, body, code)) switch (code->Type) {
 | 
			
		||||
		case CT_Variable:
 | 
			
		||||
			gen_CodeVar var = (gen_CodeVar) code;
 | 
			
		||||
			gen_log_fmt("%S", var->Value);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gen_deinit(& ctx);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								test/cpp_library/test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								test/cpp_library/test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
#define GEN_IMPLEMENTATION
 | 
			
		||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
 | 
			
		||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
 | 
			
		||||
#include "gen.hpp"
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
	using namespace gen;
 | 
			
		||||
	Context ctx = {};
 | 
			
		||||
	gen::init( & ctx);
 | 
			
		||||
 | 
			
		||||
	Builder src_hello = builder_open("gen/hello.cpp");
 | 
			
		||||
	CodeVar hello_var = parse_variable( code(
 | 
			
		||||
		constexpr char const* hello_gencpp_str = "HELLO GENCPP !";
 | 
			
		||||
	));
 | 
			
		||||
	src_hello.print(hello_var);
 | 
			
		||||
	src_hello.write();
 | 
			
		||||
 | 
			
		||||
	CodeBody body = parse_file("gen/hello.cpp");
 | 
			
		||||
	for ( Code code : body ) switch (code->Type) {
 | 
			
		||||
		case CT_Variable:
 | 
			
		||||
			CodeVar var = cast(CodeVar, code);
 | 
			
		||||
			log_fmt("%S", var->Value);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	gen::deinit(& ctx);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user