mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 14:30:53 -07:00 
			
		
		
		
	Compare commits
	
		
			14 Commits
		
	
	
		
			e3172057d3
			...
			v0.22-Alph
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 967a044637 | |||
| b5cf633e98 | |||
| 16d0e0834f | |||
| 76ac3a0f93 | |||
| 78bcc21130 | |||
| a125653448 | |||
| aa2170ba80 | |||
| 5705196710 | |||
| cf0d787196 | |||
| 8d436fe546 | |||
| e15ac22132 | |||
| bac57a5872 | |||
| 012fcb6bd5 | |||
| 6ffdca8595 | 
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.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, | ||||
|   | ||||
| @@ -148,9 +148,9 @@ The convention you'll see used throughout the upfront interface of the library i | ||||
| 1. Check name or parameters to make sure they are valid for the construction requested | ||||
| 2. Create a code object using `make_code`. | ||||
| 3. Populate immediate fields (Name, Type, ModuleFlags, etc) | ||||
| 4. Populate sub-entires using `add_entry`. If using the default serialization function `to_string`, follow the order at which entires are expected to appear (there is a strong ordering expected). | ||||
| 4. Populate sub-entires using `add_entry`. If using the default serialization function `to_strbuilder`, follow the order at which entires are expected to appear (there is a strong ordering expected). | ||||
|  | ||||
| Names or Content fields are interned strings and thus showed be cached using `get_cached_string` if its desired to preserve that behavior. | ||||
| Names or Content fields are interned strings and thus showed be cached using `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,7 @@ Builder builder_open( char const* path ) | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	result.Buffer = strbuilder_make_reserve( GlobalAllocator, Builder_StrBufferReserve ); | ||||
| 	result.Buffer = strbuilder_make_reserve( _ctx->Allocator_Temp, _ctx->InitSize_BuilderBuffer ); | ||||
|  | ||||
| 	// log_fmt("$Builder - Opened file: %s\n", result.File.filename ); | ||||
| 	return result; | ||||
| @@ -28,7 +28,7 @@ void builder_pad_lines( Builder* builder, s32 num ) | ||||
|  | ||||
| void builder_print( Builder* builder, Code code ) | ||||
| { | ||||
| 	StrBuilder   str = code_to_string(code); | ||||
| 	StrBuilder   str = code_to_strbuilder(code); | ||||
| 	// const ssize len = str.length(); | ||||
| 	// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data ); | ||||
| 	strbuilder_append_string( & builder->Buffer, str ); | ||||
|   | ||||
| @@ -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( _ctx->Allocator_Temp, fsize ); | ||||
| 		file_read( & file, str, fsize ); | ||||
| 		strbuilder_get_header(str)->Length = fsize; | ||||
|  | ||||
| @@ -117,8 +117,8 @@ Code scan_file( char const* path ) | ||||
| } | ||||
|  | ||||
| CodeBody parse_file( const char* path ) { | ||||
| 	FileContents file    = file_read_contents( GlobalAllocator, true, path ); | ||||
| 	Str         content = { file.size, (char const*)file.data }; | ||||
| 	FileContents file    = file_read_contents( _ctx->Allocator_Temp, true, path ); | ||||
| 	Str          content = { (char const*)file.data, file.size }; | ||||
| 	CodeBody     code    = parse_global_body( content ); | ||||
| 	log_fmt("\nParsed: %s\n", path); | ||||
| 	return code; | ||||
|   | ||||
| @@ -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") ), | ||||
| @@ -41,6 +42,7 @@ int gen_main() | ||||
| 	CodeBody ecode       = gen_ecode     ( "enums/ECodeTypes.csv" ); | ||||
| 	CodeBody eoperator   = gen_eoperator ( "enums/EOperator.csv" ); | ||||
| 	CodeBody especifier  = gen_especifier( "enums/ESpecifier.csv" ); | ||||
| 	CodeBody etoktype    = gen_etoktype  ( "enums/ETokType.csv", "enums/AttributeTokens.csv" ); | ||||
| 	CodeBody ast_inlines = gen_ast_inlines(); | ||||
|  | ||||
| 	Builder header_ecode = builder_open( "components/gen/ecodetypes.hpp" ); | ||||
| @@ -57,12 +59,17 @@ int gen_main() | ||||
| 	builder_print( & header_especifier, gen_component_header ); | ||||
| 	builder_print( & header_especifier, format(especifier) ); | ||||
| 	builder_write( & header_especifier); | ||||
| 	 | ||||
| 	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); | ||||
|  | ||||
| 	Builder header_ast_inlines = builder_open( "components/gen/ast_inlines.hpp" ); | ||||
| 	builder_print( & header_ast_inlines, gen_component_header ); | ||||
| 	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 ) | ||||
| @@ -62,11 +59,11 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt   : %S", self->InlineCmt  ? self->InlineCmt->Content                           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes  : %S", self->Attributes ? strbuilder_to_str( code_to_string(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParentAccess: %S", self->ParentType ? access_spec_to_str( self->ParentAccess )           : txt("No Parent") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParentType  : %S", self->ParentType ? code_type_str(self->ParentType)                    : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody        : %S", self->Body       ? code_debug_str(self->Body)                         : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt   : %S", self->InlineCmt  ? self->InlineCmt->Content                                  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes  : %S", self->Attributes ? strbuilder_to_str( code_to_strbuilder(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParentAccess: %S", self->ParentType ? access_spec_to_str( self->ParentAccess )                  : txt("No Parent") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParentType  : %S", self->ParentType ? code_type_str(self->ParentType)                           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody        : %S", self->Body       ? code_debug_str(self->Body)                                : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Class_Fwd: | ||||
| @@ -76,10 +73,10 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt   : %S", self->InlineCmt  ? self->InlineCmt->Content                           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes  : %S", self->Attributes ? strbuilder_to_str( code_to_string(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParentAccess: %S", self->ParentType ? access_spec_to_str( self->ParentAccess )           : txt("No Parent") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParentType  : %S", self->ParentType ? code_type_str(self->ParentType)                    : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt   : %S", self->InlineCmt  ? self->InlineCmt->Content                                  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes  : %S", self->Attributes ? strbuilder_to_str( code_to_strbuilder(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParentAccess: %S", self->ParentType ? access_spec_to_str( self->ParentAccess )                  : txt("No Parent") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParentType  : %S", self->ParentType ? code_type_str(self->ParentType)                           : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Constructor: | ||||
| @@ -88,11 +85,11 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt      : %S", self->InlineCmt       ? self->InlineCmt->Content                                : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs          : %S", self->Specs           ? strbuilder_to_str( code_to_string(self->Specs) )           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? strbuilder_to_str( code_to_string(self->InitializerList) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams         : %S", self->Params          ? strbuilder_to_str( code_to_string(self->Params) )          : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody           : %S", self->Body            ? code_debug_str(self->Body)                              : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt      : %S", self->InlineCmt       ? self->InlineCmt->Content                                       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs          : %S", self->Specs           ? strbuilder_to_str( code_to_strbuilder(self->Specs) )           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? strbuilder_to_str( code_to_strbuilder(self->InitializerList) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams         : %S", self->Params          ? strbuilder_to_str( code_to_strbuilder(self->Params) )          : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody           : %S", self->Body            ? code_debug_str(self->Body)                                     : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Constructor_Fwd: | ||||
| @@ -101,10 +98,10 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt      : %S", self->InlineCmt       ? self->InlineCmt->Content                                : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs          : %S", self->Specs           ? strbuilder_to_str( code_to_string(self->Specs) )           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? strbuilder_to_str( code_to_string(self->InitializerList) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams         : %S", self->Params          ? strbuilder_to_str( code_to_string(self->Params) )          : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt      : %S", self->InlineCmt       ? self->InlineCmt->Content                                       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs          : %S", self->Specs           ? strbuilder_to_str( code_to_strbuilder(self->Specs) )           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? strbuilder_to_str( code_to_strbuilder(self->InitializerList) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams         : %S", self->Params          ? strbuilder_to_str( code_to_strbuilder(self->Params) )          : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Destructor: | ||||
| @@ -113,9 +110,9 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt      : %S", self->InlineCmt       ? self->InlineCmt->Content                      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs          : %S", self->Specs           ? strbuilder_to_str( code_to_string(self->Specs) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody           : %S", self->Body            ? code_debug_str(self->Body)                    : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt      : %S", self->InlineCmt       ? self->InlineCmt->Content                             : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs          : %S", self->Specs           ? strbuilder_to_str( code_to_strbuilder(self->Specs) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody           : %S", self->Body            ? code_debug_str(self->Body)                           : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Destructor_Fwd: | ||||
| @@ -128,10 +125,10 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt       : %S", self->InlineCmt      ? self->InlineCmt->Content                              : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes      : %S", self->Attributes     ? strbuilder_to_str( code_to_string(self->Attributes) )    : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? strbuilder_to_str( code_to_string(self->UnderlyingType)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody            : %S", self->Body           ? code_debug_str(self->Body)                            : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt       : %S", self->InlineCmt      ? self->InlineCmt->Content                                     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes      : %S", self->Attributes     ? strbuilder_to_str( code_to_strbuilder(self->Attributes) )    : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? strbuilder_to_str( code_to_strbuilder(self->UnderlyingType)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody            : %S", self->Body           ? code_debug_str(self->Body)                                   : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Enum_Fwd: | ||||
| @@ -141,9 +138,9 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt       : %S", self->InlineCmt      ? self->InlineCmt->Content                              : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes      : %S", self->Attributes     ? strbuilder_to_str( code_to_string(self->Attributes) )    : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? strbuilder_to_str( code_to_string(self->UnderlyingType)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt       : %S", self->InlineCmt      ? self->InlineCmt->Content                                     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes      : %S", self->Attributes     ? strbuilder_to_str( code_to_strbuilder(self->Attributes) )    : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? strbuilder_to_str( code_to_strbuilder(self->UnderlyingType)) : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Extern_Linkage: | ||||
| @@ -162,8 +159,8 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt  : %S", self->InlineCmt   ? self->InlineCmt->Content                           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? strbuilder_to_str( code_to_string(self->Declaration)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt  : %S", self->InlineCmt   ? self->InlineCmt->Content                                  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? strbuilder_to_str( code_to_strbuilder(self->Declaration)) : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Function: | ||||
| @@ -172,12 +169,12 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_string(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_string(self->Specs))       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? strbuilder_to_str( code_to_string(self->ReturnType))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams    : %S", self->Params     ? strbuilder_to_str( code_to_string(self->Params))      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody      : %S", self->Body       ? code_debug_str(self->Body)                         : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                                  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_strbuilder(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_strbuilder(self->Specs))       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? strbuilder_to_str( code_to_strbuilder(self->ReturnType))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams    : %S", self->Params     ? strbuilder_to_str( code_to_strbuilder(self->Params))      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody      : %S", self->Body       ? code_debug_str(self->Body)                                : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Function_Fwd: | ||||
| @@ -186,11 +183,11 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_string(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_string(self->Specs))       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? strbuilder_to_str( code_to_string(self->ReturnType))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams    : %S", self->Params     ? strbuilder_to_str( code_to_string(self->Params))      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                                  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_strbuilder(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_strbuilder(self->Specs))       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? strbuilder_to_str( code_to_strbuilder(self->ReturnType))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams    : %S", self->Params     ? strbuilder_to_str( code_to_strbuilder(self->Params))      : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Module: | ||||
| @@ -207,12 +204,12 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_string(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_string(self->Specs))       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? strbuilder_to_str( code_to_string(self->ReturnType))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams    : %S", self->Params     ? strbuilder_to_str( code_to_string(self->Params))      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody      : %S", self->Body       ? code_debug_str(self->Body)                         : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                                  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_strbuilder(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_strbuilder(self->Specs))       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? strbuilder_to_str( code_to_strbuilder(self->ReturnType))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams    : %S", self->Params     ? strbuilder_to_str( code_to_strbuilder(self->Params))      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody      : %S", self->Body       ? code_debug_str(self->Body)                                : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tOp        : %S", operator_to_str( self->Op ) ); | ||||
| 		break; | ||||
|  | ||||
| @@ -223,11 +220,11 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                           : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_string(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_string(self->Specs) )      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? strbuilder_to_str( code_to_string(self->ReturnType) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams    : %S", self->Params     ? strbuilder_to_str( code_to_string(self->Params) )     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                                  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_strbuilder(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_strbuilder(self->Specs) )      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? strbuilder_to_str( code_to_strbuilder(self->ReturnType) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams    : %S", self->Params     ? strbuilder_to_str( code_to_strbuilder(self->Params) )     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tOp        : %S", operator_to_str( self->Op ) ); | ||||
| 		break; | ||||
|  | ||||
| @@ -237,10 +234,10 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                         : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_string(self->Specs))     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValueType : %S", self->ValueType  ? strbuilder_to_str( code_to_string(self->ValueType)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody      : %S", self->Body       ? code_debug_str(self->Body)                       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                                : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_strbuilder(self->Specs))     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValueType : %S", self->ValueType  ? strbuilder_to_str( code_to_strbuilder(self->ValueType)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody      : %S", self->Body       ? code_debug_str(self->Body)                              : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Operator_Cast_Fwd: | ||||
| @@ -249,17 +246,17 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                         : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_string(self->Specs))     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValueType : %S", self->ValueType  ? strbuilder_to_str( code_to_string(self->ValueType)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt  ? self->InlineCmt->Content                                : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs     : %S", self->Specs      ? strbuilder_to_str( code_to_strbuilder(self->Specs))     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValueType : %S", self->ValueType  ? strbuilder_to_str( code_to_strbuilder(self->ValueType)) : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Parameters: | ||||
| 			strbuilder_append_fmt( result, "\n\tNumEntries: %d", self->NumEntries ); | ||||
| 			strbuilder_append_fmt( result, "\n\tLast      : %S", self->Last->Name ); | ||||
| 			strbuilder_append_fmt( result, "\n\tNext      : %S", self->Next->Name ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValueType : %S", self->ValueType ? strbuilder_to_str( code_to_string(self->ValueType)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValue     : %S", self->Value     ? strbuilder_to_str( code_to_string(self->Value))     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValueType : %S", self->ValueType ? strbuilder_to_str( code_to_strbuilder(self->ValueType)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValue     : %S", self->Value     ? strbuilder_to_str( code_to_strbuilder(self->Value))     : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Specifiers: | ||||
| @@ -285,8 +282,8 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tParams     : %S", self->Params      ? strbuilder_to_str( code_to_string(self->Params))      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? strbuilder_to_str( code_to_string(self->Declaration)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams     : %S", self->Params      ? strbuilder_to_str( code_to_strbuilder(self->Params))      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? strbuilder_to_str( code_to_strbuilder(self->Declaration)) : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Typedef: | ||||
| @@ -295,16 +292,16 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt     : %S", self->InlineCmt      ? self->InlineCmt->Content                              : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? strbuilder_to_str( code_to_string(self->UnderlyingType)) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt     : %S", self->InlineCmt      ? self->InlineCmt->Content                                     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? strbuilder_to_str( code_to_strbuilder(self->UnderlyingType)) : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Typename: | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes     : %S", self->Attributes ? strbuilder_to_str( code_to_string(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs          : %S", self->Specs      ? strbuilder_to_str( code_to_string(self->Specs))       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType     : %S", self->ReturnType ? strbuilder_to_str( code_to_string(self->ReturnType))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams         : %S", self->Params     ? strbuilder_to_str( code_to_string(self->Params))      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tArrExpr        : %S", self->ArrExpr    ? strbuilder_to_str( code_to_string(self->ArrExpr))     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes     : %S", self->Attributes ? strbuilder_to_str( code_to_strbuilder(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs          : %S", self->Specs      ? strbuilder_to_str( code_to_strbuilder(self->Specs))       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tReturnType     : %S", self->ReturnType ? strbuilder_to_str( code_to_strbuilder(self->ReturnType))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tParams         : %S", self->Params     ? strbuilder_to_str( code_to_strbuilder(self->Params))      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tArrExpr        : %S", self->ArrExpr    ? strbuilder_to_str( code_to_strbuilder(self->ArrExpr))     : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Union: | ||||
| @@ -313,8 +310,8 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_string(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody      : %S", self->Body       ? code_debug_str(self->Body)       : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes: %S", self->Attributes ? strbuilder_to_str( code_to_strbuilder(self->Attributes) ) : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBody      : %S", self->Body       ? code_debug_str(self->Body)                                : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Using: | ||||
| @@ -323,9 +320,9 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt     : %S", self->InlineCmt      ? self->InlineCmt->Content                               : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes    : %S", self->Attributes     ? strbuilder_to_str( code_to_string(self->Attributes) )     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? strbuilder_to_str( code_to_string(self->UnderlyingType))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt     : %S", self->InlineCmt      ? self->InlineCmt->Content                                      : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes    : %S", self->Attributes     ? strbuilder_to_str( code_to_strbuilder(self->Attributes) )     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? strbuilder_to_str( code_to_strbuilder(self->UnderlyingType))  : txt("Null") ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Variable: | ||||
| @@ -333,10 +330,10 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Parent && self->Parent->Type == CT_Variable ) | ||||
| 			{ | ||||
| 				// Its a NextVar | ||||
| 				strbuilder_append_fmt( result, "\n\tSpecs       : %S", self->Specs        ? strbuilder_to_str( code_to_string(self->Specs))        : txt("Null") ); | ||||
| 				strbuilder_append_fmt( result, "\n\tValue       : %S", self->Value        ? strbuilder_to_str( code_to_string(self->Value))        : txt("Null") ); | ||||
| 				strbuilder_append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? strbuilder_to_str( code_to_string(self->BitfieldSize)) : txt("Null") ); | ||||
| 				strbuilder_append_fmt( result, "\n\tNextVar     : %S", self->NextVar      ? code_debug_str(self->NextVar)                       : txt("Null") ); | ||||
| 				strbuilder_append_fmt( result, "\n\tSpecs       : %S", self->Specs        ? strbuilder_to_str( code_to_strbuilder(self->Specs))        : txt("Null") ); | ||||
| 				strbuilder_append_fmt( result, "\n\tValue       : %S", self->Value        ? strbuilder_to_str( code_to_strbuilder(self->Value))        : txt("Null") ); | ||||
| 				strbuilder_append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? strbuilder_to_str( code_to_strbuilder(self->BitfieldSize)) : txt("Null") ); | ||||
| 				strbuilder_append_fmt( result, "\n\tNextVar     : %S", self->NextVar      ? code_debug_str(self->NextVar)                              : txt("Null") ); | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| @@ -345,13 +342,13 @@ Str code_debug_str(Code self) | ||||
| 			if ( self->Next ) | ||||
| 				strbuilder_append_fmt( result, "\n\tNext: %S %S", code_type_str(self->Prev), self->Prev->Name.Len ? self->Prev->Name : txt("Null") ); | ||||
|  | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt   : %S", self->InlineCmt    ? self->InlineCmt->Content                             : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes  : %S", self->Attributes   ? strbuilder_to_str( code_to_string(self->Attributes) )   : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs       : %S", self->Specs        ? strbuilder_to_str( code_to_string(self->Specs))         : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValueType   : %S", self->ValueType    ? strbuilder_to_str( code_to_string(self->ValueType))     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? strbuilder_to_str( code_to_string(self->BitfieldSize))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValue       : %S", self->Value        ? strbuilder_to_str( code_to_string(self->Value))         : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tNextVar     : %S", self->NextVar      ? code_debug_str(self->NextVar)                        : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tInlineCmt   : %S", self->InlineCmt    ? self->InlineCmt->Content                                    : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tAttributes  : %S", self->Attributes   ? strbuilder_to_str( code_to_strbuilder(self->Attributes) )   : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tSpecs       : %S", self->Specs        ? strbuilder_to_str( code_to_strbuilder(self->Specs))         : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValueType   : %S", self->ValueType    ? strbuilder_to_str( code_to_strbuilder(self->ValueType))     : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? strbuilder_to_str( code_to_strbuilder(self->BitfieldSize))  : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tValue       : %S", self->Value        ? strbuilder_to_str( code_to_strbuilder(self->Value))         : txt("Null") ); | ||||
| 			strbuilder_append_fmt( result, "\n\tNextVar     : %S", self->NextVar      ? code_debug_str(self->NextVar)                               : txt("Null") ); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| @@ -370,9 +367,9 @@ Code code_duplicate(Code self) | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| StrBuilder code_to_string(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; | ||||
| } | ||||
| @@ -455,7 +452,7 @@ void code_to_strbuilder_ptr( Code self, StrBuilder* result ) | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Extern_Linkage: | ||||
| 			extern_to_string(cast(CodeExtern, self), result ); | ||||
| 			extern_to_strbuilder(cast(CodeExtern, self), result ); | ||||
| 		break; | ||||
|  | ||||
| 		case CT_Friend: | ||||
| @@ -612,7 +609,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; | ||||
| @@ -624,8 +621,8 @@ bool code_is_equal( Code self, Code other ) | ||||
| 	if ( self->val != other->val )                            \ | ||||
| 	{                                                         \ | ||||
| 		log_fmt("\nAST::is_equal: Member - " #val " failed\n" \ | ||||
| 		        "AST  : %S\n"                                \ | ||||
| 		        "Other: %S\n"                                \ | ||||
| 		        "AST  : %S\n"                                 \ | ||||
| 		        "Other: %S\n"                                 \ | ||||
| 		    , code_debug_str(self)                            \ | ||||
| 		    ,code_debug_str(other)                            \ | ||||
| 		);                                                    \ | ||||
| @@ -634,11 +631,11 @@ bool code_is_equal( Code self, Code other ) | ||||
| 	} | ||||
|  | ||||
| 	#define check_member_str( str )                                 \ | ||||
| 	if ( ! str_are_equal( self->str, other->str ) )                \ | ||||
| 	if ( ! str_are_equal( self->str, other->str ) )                 \ | ||||
| 	{                                                               \ | ||||
| 		log_fmt("\nAST::is_equal: Member string - "#str " failed\n" \ | ||||
| 				"AST  : %S\n"                                      \ | ||||
| 				"Other: %S\n"                                      \ | ||||
| 				"AST  : %S\n"                                       \ | ||||
| 				"Other: %S\n"                                       \ | ||||
| 			, code_debug_str(self)                                  \ | ||||
| 			,code_debug_str(other)                                  \ | ||||
| 		);                                                          \ | ||||
| @@ -646,23 +643,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 )                                                                \ | ||||
| @@ -671,9 +668,9 @@ bool code_is_equal( Code self, Code other ) | ||||
| 		if ( other->ast == nullptr )                                                               \ | ||||
| 		{                                                                                          \ | ||||
| 			log_fmt("\nAST::is_equal: Failed for member " #ast " other equivalent param is null\n" \ | ||||
| 					"AST  : %S\n"                                                                 \ | ||||
| 					"Other: %S\n"                                                                 \ | ||||
| 					"For ast member: %S\n"                                                        \ | ||||
| 					"AST  : %S\n"                                                                  \ | ||||
| 					"Other: %S\n"                                                                  \ | ||||
| 					"For ast member: %S\n"                                                         \ | ||||
| 				, code_debug_str(self)                                                             \ | ||||
| 				, code_debug_str(other)                                                            \ | ||||
| 				, code_debug_str(self->ast)                                                        \ | ||||
| @@ -685,10 +682,10 @@ bool code_is_equal( Code self, Code other ) | ||||
| 		if ( ! code_is_equal(self->ast, other->ast ) )                                             \ | ||||
| 		{                                                                                          \ | ||||
| 			log_fmt( "\nAST::is_equal: Failed for " #ast"\n"                                       \ | ||||
| 					"AST  : %S\n"                                                                 \ | ||||
| 					"Other: %S\n"                                                                 \ | ||||
| 					"For     ast member: %S\n"                                                    \ | ||||
| 					"other's ast member: %S\n"                                                    \ | ||||
| 					"AST  : %S\n"                                                                  \ | ||||
| 					"Other: %S\n"                                                                  \ | ||||
| 					"For     ast member: %S\n"                                                     \ | ||||
| 					"other's ast member: %S\n"                                                     \ | ||||
| 				, code_debug_str(self)                                                             \ | ||||
| 				, code_debug_str(other)                                                            \ | ||||
| 				, code_debug_str(self->ast)                                                        \ | ||||
| @@ -1283,6 +1280,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; | ||||
| } | ||||
|   | ||||
| @@ -230,40 +230,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_string    (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 | ||||
|  | ||||
| @@ -278,7 +263,7 @@ struct Code | ||||
| 	AST* ast; | ||||
|  | ||||
| #	define Using_Code( Typename )                                                        \ | ||||
| 	forceinline Str debug_str()                { return code_debug_str(* this); }       \ | ||||
| 	forceinline Str  debug_str()                { return code_debug_str(* this); }       \ | ||||
| 	forceinline Code duplicate()                { return code_duplicate(* this); }	     \ | ||||
| 	forceinline bool is_equal( Code other )     { return code_is_equal(* this, other); } \ | ||||
| 	forceinline bool is_body()                  { return code_is_body(* this); }         \ | ||||
| @@ -295,16 +280,17 @@ struct Code | ||||
|  | ||||
| #if ! GEN_C_LIKE_CPP | ||||
| 	Using_Code( Code ); | ||||
| 	forceinline void   append(Code other)        { return code_append(* this, other); } | ||||
| 	forceinline Code*  entry(u32 idx)            { return code_entry(* this, idx); } | ||||
| 	forceinline bool   has_entries()             { return code_has_entries(* this); } | ||||
| 	forceinline StrBuilder to_string()               { return code_to_string(* this); } | ||||
| 	forceinline void   to_string(StrBuilder& result) { return code_to_strbuilder_ptr(* this, & result); } | ||||
| 	forceinline Str   type_str()                { return code_type_str(* this); } | ||||
| 	forceinline bool   validate_body()           { return code_validate_body(*this); } | ||||
| 	forceinline void       append(Code other)                { return code_append(* this, other); } | ||||
| 	forceinline Code*      entry(u32 idx)                    { return code_entry(* this, idx); } | ||||
| 	forceinline bool       has_entries()                     { return code_has_entries(* this); } | ||||
| 	forceinline StrBuilder to_strbuilder()                   { return code_to_strbuilder(* this); } | ||||
| 	forceinline void       to_strbuilder(StrBuilder& result) { return code_to_strbuilder_ptr(* this, & result); } | ||||
| 	forceinline Str        type_str()                        { return code_type_str(* this); } | ||||
| 	forceinline bool       validate_body()                   { return code_validate_body(*this); } | ||||
| #endif | ||||
|  | ||||
| 	Using_CodeOps( Code ); | ||||
| 	forceinline Code operator *() { return * this; } // Required to support for-range iteration. | ||||
| 	forceinline AST* operator ->() { return ast; } | ||||
|  | ||||
| 	Code& operator ++(); | ||||
| @@ -367,7 +353,7 @@ int AST_ArrSpecs_Cap = | ||||
| ( | ||||
| 	AST_POD_Size | ||||
| 	- sizeof(Code) | ||||
| 	- sizeof(StringCached) | ||||
| 	- sizeof(StrCached) | ||||
| 	- sizeof(Code) * 2 | ||||
| 	- sizeof(Token*) | ||||
| 	- sizeof(Code) | ||||
| @@ -413,13 +399,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; | ||||
|   | ||||
| @@ -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; | ||||
| @@ -46,9 +46,9 @@ 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 +64,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 +79,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 +106,7 @@ struct AST_Class | ||||
| 			char 	        _PAD_PROPERTIES_2_[ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached            Name; | ||||
| 	StrCached            Name; | ||||
| 	CodeTypename            Prev; | ||||
| 	CodeTypename            Next; | ||||
| 	Token*                  Tok; | ||||
| @@ -132,7 +132,7 @@ struct AST_Constructor | ||||
| 			char 		   _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached      Name; | ||||
| 	StrCached      Name; | ||||
| 	Code              Prev; | ||||
| 	Code              Next; | ||||
| 	Token*            Tok; | ||||
| @@ -146,9 +146,9 @@ struct AST_Define | ||||
| { | ||||
| 	union { | ||||
| 		char          _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; | ||||
| 		StringCached  Content; | ||||
| 		StrCached  Content; | ||||
| 	}; | ||||
| 	StringCached      Name; | ||||
| 	StrCached      Name; | ||||
| 	Code              Prev; | ||||
| 	Code              Next; | ||||
| 	Token*            Tok; | ||||
| @@ -172,7 +172,7 @@ struct AST_Destructor | ||||
| 			char 		   _PAD_PROPERTIES_3_ [ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached           Name; | ||||
| 	StrCached           Name; | ||||
| 	Code                   Prev; | ||||
| 	Code                   Next; | ||||
| 	Token*                 Tok; | ||||
| @@ -197,7 +197,7 @@ struct AST_Enum | ||||
| 			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached           Name; | ||||
| 	StrCached           Name; | ||||
| 	Code                   Prev; | ||||
| 	Code                   Next; | ||||
| 	Token*                 Tok; | ||||
| @@ -212,9 +212,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 +230,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 +245,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 +260,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 +275,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 +290,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 +305,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 +320,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 +335,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 +350,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 +365,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 +380,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 +395,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 +410,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 +425,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 +440,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 +455,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 +470,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 +492,7 @@ struct AST_Extern | ||||
| 			char      _PAD_PROPERTIES_2_[ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached      Name; | ||||
| 	StrCached      Name; | ||||
| 	Code              Prev; | ||||
| 	Code              Next; | ||||
| 	Token*            Tok; | ||||
| @@ -506,9 +506,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 +530,7 @@ struct AST_Friend | ||||
| 			char 	    _PAD_PROPERTIES_2_[ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached      Name; | ||||
| 	StrCached      Name; | ||||
| 	Code              Prev; | ||||
| 	Code              Next; | ||||
| 	Token*            Tok; | ||||
| @@ -555,7 +555,7 @@ struct AST_Fn | ||||
| 			char 	        _PAD_PROPERTIES_ [ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached            Name; | ||||
| 	StrCached            Name; | ||||
| 	Code                    Prev; | ||||
| 	Code                    Next; | ||||
| 	Token*                  Tok; | ||||
| @@ -571,7 +571,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 +592,7 @@ struct AST_NS | ||||
| 			char 	  _PAD_PROPERTIES_2_[ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached      Name; | ||||
| 	StrCached      Name; | ||||
| 	Code              Prev; | ||||
| 	Code              Next; | ||||
| 	Token*            Tok; | ||||
| @@ -618,7 +618,7 @@ struct AST_Operator | ||||
| 			char 	        _PAD_PROPERTIES_ [ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached   Name; | ||||
| 	StrCached   Name; | ||||
| 	Code           Prev; | ||||
| 	Code           Next; | ||||
| 	Token*         Tok; | ||||
| @@ -644,7 +644,7 @@ struct AST_OpCast | ||||
| 			char 	        _PAD_PROPERTIES_3_[ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached      Name; | ||||
| 	StrCached      Name; | ||||
| 	Code              Prev; | ||||
| 	Code              Next; | ||||
| 	Token*            Tok; | ||||
| @@ -668,7 +668,7 @@ struct AST_Params | ||||
| 			// char     _PAD_PROPERTIES_3_[sizeof( AST* )]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached      Name; | ||||
| 	StrCached      Name; | ||||
| 	CodeParams        Last; | ||||
| 	CodeParams        Next; | ||||
| 	Token*            Tok; | ||||
| @@ -683,9 +683,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 +699,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 +714,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 +732,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 +747,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 +762,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 +777,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 +792,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 +807,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 +822,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 +837,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 +852,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 +867,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 +882,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 +897,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 +912,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 +927,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 +953,7 @@ struct AST_Struct | ||||
| 			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached           Name; | ||||
| 	StrCached           Name; | ||||
| 	CodeTypename           Prev; | ||||
| 	CodeTypename           Next; | ||||
| 	Token*                 Tok; | ||||
| @@ -976,7 +976,7 @@ struct AST_Template | ||||
| 			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached           Name; | ||||
| 	StrCached           Name; | ||||
| 	Code                   Prev; | ||||
| 	Code                   Next; | ||||
| 	Token*                 Tok; | ||||
| @@ -1005,7 +1005,7 @@ struct AST_Type | ||||
| 			// CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached           Name; | ||||
| 	StrCached           Name; | ||||
| 	Code                   Prev; | ||||
| 	Code                   Next; | ||||
| 	Token*                  Tok; | ||||
| @@ -1032,7 +1032,7 @@ struct AST_Typename | ||||
| 			CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached           Name; | ||||
| 	StrCached           Name; | ||||
| 	Code                   Prev; | ||||
| 	Code                   Next; | ||||
| 	Token*                 Tok; | ||||
| @@ -1058,7 +1058,7 @@ struct AST_Typedef | ||||
| 			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached           Name; | ||||
| 	StrCached           Name; | ||||
| 	Code                   Prev; | ||||
| 	Code                   Next; | ||||
| 	Token*                 Tok; | ||||
| @@ -1082,7 +1082,7 @@ struct AST_Union | ||||
| 			char 	       _PAD_PROPERTIES_2_[ sizeof(AST*) ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached           Name; | ||||
| 	StrCached           Name; | ||||
| 	Code                   Prev; | ||||
| 	Code                   Next; | ||||
| 	Token*                 Tok; | ||||
| @@ -1106,7 +1106,7 @@ struct AST_Using | ||||
| 			char 	        _PAD_PROPERTIES_[ sizeof(AST*) * 3 ]; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached            Name; | ||||
| 	StrCached            Name; | ||||
| 	Code                    Prev; | ||||
| 	Code                    Next; | ||||
| 	Token*                  Tok; | ||||
| @@ -1132,7 +1132,7 @@ struct AST_Var | ||||
| 			CodeVar		   NextVar; | ||||
| 		}; | ||||
| 	}; | ||||
| 	StringCached           Name; | ||||
| 	StrCached           Name; | ||||
| 	Code                   Prev; | ||||
| 	Code                   Next; | ||||
| 	Token*                 Tok; | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -64,7 +64,7 @@ inline AST_Attributes* CodeAttributes::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -95,7 +95,7 @@ inline AST_Comment* CodeComment::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -126,7 +126,7 @@ inline AST_Constructor* CodeConstructor::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -173,7 +173,7 @@ inline AST_Define* CodeDefine::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -204,7 +204,7 @@ inline AST_Destructor* CodeDestructor::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -235,7 +235,7 @@ inline AST_Enum* CodeEnum::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -266,7 +266,7 @@ inline AST_Exec* CodeExec::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -297,7 +297,7 @@ inline AST_Extern* CodeExtern::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -328,7 +328,7 @@ inline AST_Friend* CodeFriend::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -359,7 +359,7 @@ inline AST_Fn* CodeFn::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -390,7 +390,7 @@ inline AST_Include* CodeInclude::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -421,7 +421,7 @@ inline AST_Module* CodeModule::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -452,7 +452,7 @@ inline AST_NS* CodeNS::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -483,7 +483,7 @@ inline AST_Operator* CodeOperator::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -514,7 +514,7 @@ inline AST_OpCast* CodeOpCast::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -561,7 +561,7 @@ inline AST_Pragma* CodePragma::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -592,7 +592,7 @@ inline AST_PreprocessCond* CodePreprocessCond::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -655,7 +655,7 @@ inline AST_Template* CodeTemplate::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -686,7 +686,7 @@ inline AST_Typename* CodeTypename::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -717,7 +717,7 @@ inline AST_Typedef* CodeTypedef::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -748,7 +748,7 @@ inline AST_Union* CodeUnion::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -779,7 +779,7 @@ inline AST_Using* CodeUsing::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
| @@ -810,7 +810,7 @@ inline AST_Var* CodeVar::operator->() | ||||
| { | ||||
| 	if ( ast == nullptr ) | ||||
| 	{ | ||||
| 		log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 		log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	return ast; | ||||
|   | ||||
| @@ -75,67 +75,67 @@ enum CodeType : u32 | ||||
| inline Str codetype_to_str( CodeType type ) | ||||
| { | ||||
| 	local_persist Str lookup[61] = { | ||||
| 		{ sizeof( "Invalid" ),             "Invalid"             }, | ||||
| 		{ sizeof( "Untyped" ),             "Untyped"             }, | ||||
| 		{ sizeof( "NewLine" ),             "NewLine"             }, | ||||
| 		{ sizeof( "Comment" ),             "Comment"             }, | ||||
| 		{ sizeof( "Access_Private" ),      "Access_Private"      }, | ||||
| 		{ sizeof( "Access_Protected" ),    "Access_Protected"    }, | ||||
| 		{ sizeof( "Access_Public" ),       "Access_Public"       }, | ||||
| 		{ sizeof( "PlatformAttributes" ),  "PlatformAttributes"  }, | ||||
| 		{ sizeof( "Class" ),               "Class"               }, | ||||
| 		{ sizeof( "Class_Fwd" ),           "Class_Fwd"           }, | ||||
| 		{ sizeof( "Class_Body" ),          "Class_Body"          }, | ||||
| 		{ sizeof( "Constructor" ),         "Constructor"         }, | ||||
| 		{ sizeof( "Constructor_Fwd" ),     "Constructor_Fwd"     }, | ||||
| 		{ sizeof( "Destructor" ),          "Destructor"          }, | ||||
| 		{ sizeof( "Destructor_Fwd" ),      "Destructor_Fwd"      }, | ||||
| 		{ sizeof( "Enum" ),                "Enum"                }, | ||||
| 		{ sizeof( "Enum_Fwd" ),            "Enum_Fwd"            }, | ||||
| 		{ sizeof( "Enum_Body" ),           "Enum_Body"           }, | ||||
| 		{ sizeof( "Enum_Class" ),          "Enum_Class"          }, | ||||
| 		{ sizeof( "Enum_Class_Fwd" ),      "Enum_Class_Fwd"      }, | ||||
| 		{ sizeof( "Execution" ),           "Execution"           }, | ||||
| 		{ sizeof( "Export_Body" ),         "Export_Body"         }, | ||||
| 		{ sizeof( "Extern_Linkage" ),      "Extern_Linkage"      }, | ||||
| 		{ sizeof( "Extern_Linkage_Body" ), "Extern_Linkage_Body" }, | ||||
| 		{ sizeof( "Friend" ),              "Friend"              }, | ||||
| 		{ sizeof( "Function" ),            "Function"            }, | ||||
| 		{ sizeof( "Function_Fwd" ),        "Function_Fwd"        }, | ||||
| 		{ sizeof( "Function_Body" ),       "Function_Body"       }, | ||||
| 		{ sizeof( "Global_Body" ),         "Global_Body"         }, | ||||
| 		{ sizeof( "Module" ),              "Module"              }, | ||||
| 		{ sizeof( "Namespace" ),           "Namespace"           }, | ||||
| 		{ sizeof( "Namespace_Body" ),      "Namespace_Body"      }, | ||||
| 		{ sizeof( "Operator" ),            "Operator"            }, | ||||
| 		{ sizeof( "Operator_Fwd" ),        "Operator_Fwd"        }, | ||||
| 		{ sizeof( "Operator_Member" ),     "Operator_Member"     }, | ||||
| 		{ sizeof( "Operator_Member_Fwd" ), "Operator_Member_Fwd" }, | ||||
| 		{ sizeof( "Operator_Cast" ),       "Operator_Cast"       }, | ||||
| 		{ sizeof( "Operator_Cast_Fwd" ),   "Operator_Cast_Fwd"   }, | ||||
| 		{ sizeof( "Parameters" ),          "Parameters"          }, | ||||
| 		{ sizeof( "Preprocess_Define" ),   "Preprocess_Define"   }, | ||||
| 		{ sizeof( "Preprocess_Include" ),  "Preprocess_Include"  }, | ||||
| 		{ sizeof( "Preprocess_If" ),       "Preprocess_If"       }, | ||||
| 		{ sizeof( "Preprocess_IfDef" ),    "Preprocess_IfDef"    }, | ||||
| 		{ sizeof( "Preprocess_IfNotDef" ), "Preprocess_IfNotDef" }, | ||||
| 		{ sizeof( "Preprocess_ElIf" ),     "Preprocess_ElIf"     }, | ||||
| 		{ sizeof( "Preprocess_Else" ),     "Preprocess_Else"     }, | ||||
| 		{ sizeof( "Preprocess_EndIf" ),    "Preprocess_EndIf"    }, | ||||
| 		{ sizeof( "Preprocess_Pragma" ),   "Preprocess_Pragma"   }, | ||||
| 		{ sizeof( "Specifiers" ),          "Specifiers"          }, | ||||
| 		{ sizeof( "Struct" ),              "Struct"              }, | ||||
| 		{ sizeof( "Struct_Fwd" ),          "Struct_Fwd"          }, | ||||
| 		{ sizeof( "Struct_Body" ),         "Struct_Body"         }, | ||||
| 		{ sizeof( "Template" ),            "Template"            }, | ||||
| 		{ sizeof( "Typedef" ),             "Typedef"             }, | ||||
| 		{ sizeof( "Typename" ),            "Typename"            }, | ||||
| 		{ sizeof( "Union" ),               "Union"               }, | ||||
| 		{ sizeof( "Union_Fwd" ),           "Union_Fwd"           }, | ||||
| 		{ sizeof( "Union_Body" ),          "Union_Body"          }, | ||||
| 		{ sizeof( "Using" ),               "Using"               }, | ||||
| 		{ sizeof( "Using_Namespace" ),     "Using_Namespace"     }, | ||||
| 		{ sizeof( "Variable" ),            "Variable"            }, | ||||
| 		{ "Invalid",             sizeof( "Invalid" ) - 1             }, | ||||
| 		{ "Untyped",             sizeof( "Untyped" ) - 1             }, | ||||
| 		{ "NewLine",             sizeof( "NewLine" ) - 1             }, | ||||
| 		{ "Comment",             sizeof( "Comment" ) - 1             }, | ||||
| 		{ "Access_Private",      sizeof( "Access_Private" ) - 1      }, | ||||
| 		{ "Access_Protected",    sizeof( "Access_Protected" ) - 1    }, | ||||
| 		{ "Access_Public",       sizeof( "Access_Public" ) - 1       }, | ||||
| 		{ "PlatformAttributes",  sizeof( "PlatformAttributes" ) - 1  }, | ||||
| 		{ "Class",               sizeof( "Class" ) - 1               }, | ||||
| 		{ "Class_Fwd",           sizeof( "Class_Fwd" ) - 1           }, | ||||
| 		{ "Class_Body",          sizeof( "Class_Body" ) - 1          }, | ||||
| 		{ "Constructor",         sizeof( "Constructor" ) - 1         }, | ||||
| 		{ "Constructor_Fwd",     sizeof( "Constructor_Fwd" ) - 1     }, | ||||
| 		{ "Destructor",          sizeof( "Destructor" ) - 1          }, | ||||
| 		{ "Destructor_Fwd",      sizeof( "Destructor_Fwd" ) - 1      }, | ||||
| 		{ "Enum",                sizeof( "Enum" ) - 1                }, | ||||
| 		{ "Enum_Fwd",            sizeof( "Enum_Fwd" ) - 1            }, | ||||
| 		{ "Enum_Body",           sizeof( "Enum_Body" ) - 1           }, | ||||
| 		{ "Enum_Class",          sizeof( "Enum_Class" ) - 1          }, | ||||
| 		{ "Enum_Class_Fwd",      sizeof( "Enum_Class_Fwd" ) - 1      }, | ||||
| 		{ "Execution",           sizeof( "Execution" ) - 1           }, | ||||
| 		{ "Export_Body",         sizeof( "Export_Body" ) - 1         }, | ||||
| 		{ "Extern_Linkage",      sizeof( "Extern_Linkage" ) - 1      }, | ||||
| 		{ "Extern_Linkage_Body", sizeof( "Extern_Linkage_Body" ) - 1 }, | ||||
| 		{ "Friend",              sizeof( "Friend" ) - 1              }, | ||||
| 		{ "Function",            sizeof( "Function" ) - 1            }, | ||||
| 		{ "Function_Fwd",        sizeof( "Function_Fwd" ) - 1        }, | ||||
| 		{ "Function_Body",       sizeof( "Function_Body" ) - 1       }, | ||||
| 		{ "Global_Body",         sizeof( "Global_Body" ) - 1         }, | ||||
| 		{ "Module",              sizeof( "Module" ) - 1              }, | ||||
| 		{ "Namespace",           sizeof( "Namespace" ) - 1           }, | ||||
| 		{ "Namespace_Body",      sizeof( "Namespace_Body" ) - 1      }, | ||||
| 		{ "Operator",            sizeof( "Operator" ) - 1            }, | ||||
| 		{ "Operator_Fwd",        sizeof( "Operator_Fwd" ) - 1        }, | ||||
| 		{ "Operator_Member",     sizeof( "Operator_Member" ) - 1     }, | ||||
| 		{ "Operator_Member_Fwd", sizeof( "Operator_Member_Fwd" ) - 1 }, | ||||
| 		{ "Operator_Cast",       sizeof( "Operator_Cast" ) - 1       }, | ||||
| 		{ "Operator_Cast_Fwd",   sizeof( "Operator_Cast_Fwd" ) - 1   }, | ||||
| 		{ "Parameters",          sizeof( "Parameters" ) - 1          }, | ||||
| 		{ "Preprocess_Define",   sizeof( "Preprocess_Define" ) - 1   }, | ||||
| 		{ "Preprocess_Include",  sizeof( "Preprocess_Include" ) - 1  }, | ||||
| 		{ "Preprocess_If",       sizeof( "Preprocess_If" ) - 1       }, | ||||
| 		{ "Preprocess_IfDef",    sizeof( "Preprocess_IfDef" ) - 1    }, | ||||
| 		{ "Preprocess_IfNotDef", sizeof( "Preprocess_IfNotDef" ) - 1 }, | ||||
| 		{ "Preprocess_ElIf",     sizeof( "Preprocess_ElIf" ) - 1     }, | ||||
| 		{ "Preprocess_Else",     sizeof( "Preprocess_Else" ) - 1     }, | ||||
| 		{ "Preprocess_EndIf",    sizeof( "Preprocess_EndIf" ) - 1    }, | ||||
| 		{ "Preprocess_Pragma",   sizeof( "Preprocess_Pragma" ) - 1   }, | ||||
| 		{ "Specifiers",          sizeof( "Specifiers" ) - 1          }, | ||||
| 		{ "Struct",              sizeof( "Struct" ) - 1              }, | ||||
| 		{ "Struct_Fwd",          sizeof( "Struct_Fwd" ) - 1          }, | ||||
| 		{ "Struct_Body",         sizeof( "Struct_Body" ) - 1         }, | ||||
| 		{ "Template",            sizeof( "Template" ) - 1            }, | ||||
| 		{ "Typedef",             sizeof( "Typedef" ) - 1             }, | ||||
| 		{ "Typename",            sizeof( "Typename" ) - 1            }, | ||||
| 		{ "Union",               sizeof( "Union" ) - 1               }, | ||||
| 		{ "Union_Fwd",           sizeof( "Union_Fwd" ) - 1           }, | ||||
| 		{ "Union_Body",          sizeof( "Union_Body" ) - 1          }, | ||||
| 		{ "Using",               sizeof( "Using" ) - 1               }, | ||||
| 		{ "Using_Namespace",     sizeof( "Using_Namespace" ) - 1     }, | ||||
| 		{ "Variable",            sizeof( "Variable" ) - 1            }, | ||||
| 	}; | ||||
| 	return lookup[type]; | ||||
| } | ||||
| @@ -143,67 +143,67 @@ inline Str codetype_to_str( CodeType type ) | ||||
| inline Str codetype_to_keyword_str( CodeType type ) | ||||
| { | ||||
| 	local_persist Str lookup[61] = { | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "//" ) - 1,              "//"              }, | ||||
| 		{ sizeof( "private" ) - 1,         "private"         }, | ||||
| 		{ sizeof( "protected" ) - 1,       "protected"       }, | ||||
| 		{ sizeof( "public" ) - 1,          "public"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "class" ) - 1,           "class"           }, | ||||
| 		{ sizeof( "clsss" ) - 1,           "clsss"           }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "enum" ) - 1,            "enum"            }, | ||||
| 		{ sizeof( "enum" ) - 1,            "enum"            }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "enum class" ) - 1,      "enum class"      }, | ||||
| 		{ sizeof( "enum class" ) - 1,      "enum class"      }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "extern" ) - 1,          "extern"          }, | ||||
| 		{ sizeof( "extern" ) - 1,          "extern"          }, | ||||
| 		{ sizeof( "friend" ) - 1,          "friend"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "module" ) - 1,          "module"          }, | ||||
| 		{ sizeof( "namespace" ) - 1,       "namespace"       }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | ||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | ||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | ||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | ||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | ||||
| 		{ sizeof( "operator" ) - 1,        "operator"        }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "define" ) - 1,          "define"          }, | ||||
| 		{ sizeof( "include" ) - 1,         "include"         }, | ||||
| 		{ sizeof( "if" ) - 1,              "if"              }, | ||||
| 		{ sizeof( "ifdef" ) - 1,           "ifdef"           }, | ||||
| 		{ sizeof( "ifndef" ) - 1,          "ifndef"          }, | ||||
| 		{ sizeof( "elif" ) - 1,            "elif"            }, | ||||
| 		{ sizeof( "else" ) - 1,            "else"            }, | ||||
| 		{ sizeof( "endif" ) - 1,           "endif"           }, | ||||
| 		{ sizeof( "pragma" ) - 1,          "pragma"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "struct" ) - 1,          "struct"          }, | ||||
| 		{ sizeof( "struct" ) - 1,          "struct"          }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "template" ) - 1,        "template"        }, | ||||
| 		{ sizeof( "typedef" ) - 1,         "typedef"         }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "union" ) - 1,           "union"           }, | ||||
| 		{ sizeof( "union" ) - 1,           "union"           }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ sizeof( "using" ) - 1,           "using"           }, | ||||
| 		{ sizeof( "using namespace" ) - 1, "using namespace" }, | ||||
| 		{ sizeof( "__NA__" ) - 1,          "__NA__"          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "//",              sizeof( "//" ) - 1              }, | ||||
| 		{ "private",         sizeof( "private" ) - 1         }, | ||||
| 		{ "protected",       sizeof( "protected" ) - 1       }, | ||||
| 		{ "public",          sizeof( "public" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "class",           sizeof( "class" ) - 1           }, | ||||
| 		{ "clsss",           sizeof( "clsss" ) - 1           }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "enum",            sizeof( "enum" ) - 1            }, | ||||
| 		{ "enum",            sizeof( "enum" ) - 1            }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "enum class",      sizeof( "enum class" ) - 1      }, | ||||
| 		{ "enum class",      sizeof( "enum class" ) - 1      }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "extern",          sizeof( "extern" ) - 1          }, | ||||
| 		{ "extern",          sizeof( "extern" ) - 1          }, | ||||
| 		{ "friend",          sizeof( "friend" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "module",          sizeof( "module" ) - 1          }, | ||||
| 		{ "namespace",       sizeof( "namespace" ) - 1       }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||
| 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||
| 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||
| 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||
| 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||
| 		{ "operator",        sizeof( "operator" ) - 1        }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "define",          sizeof( "define" ) - 1          }, | ||||
| 		{ "include",         sizeof( "include" ) - 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           }, | ||||
| 		{ "pragma",          sizeof( "pragma" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "struct",          sizeof( "struct" ) - 1          }, | ||||
| 		{ "struct",          sizeof( "struct" ) - 1          }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "template",        sizeof( "template" ) - 1        }, | ||||
| 		{ "typedef",         sizeof( "typedef" ) - 1         }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "union",           sizeof( "union" ) - 1           }, | ||||
| 		{ "union",           sizeof( "union" ) - 1           }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 		{ "using",           sizeof( "using" ) - 1           }, | ||||
| 		{ "using namespace", sizeof( "using namespace" ) - 1 }, | ||||
| 		{ "__NA__",          sizeof( "__NA__" ) - 1          }, | ||||
| 	}; | ||||
| 	return lookup[type]; | ||||
| } | ||||
|   | ||||
| @@ -61,53 +61,53 @@ enum Operator : u32 | ||||
| inline Str operator_to_str( Operator op ) | ||||
| { | ||||
| 	local_persist Str lookup[47] = { | ||||
| 		{ sizeof( "INVALID" ),  "INVALID"  }, | ||||
| 		{ sizeof( "=" ),        "="        }, | ||||
| 		{ sizeof( "+=" ),       "+="       }, | ||||
| 		{ sizeof( "-=" ),       "-="       }, | ||||
| 		{ sizeof( "*=" ),       "*="       }, | ||||
| 		{ sizeof( "/=" ),       "/="       }, | ||||
| 		{ sizeof( "%=" ),       "%="       }, | ||||
| 		{ sizeof( "&=" ),       "&="       }, | ||||
| 		{ sizeof( "|=" ),       "|="       }, | ||||
| 		{ sizeof( "^=" ),       "^="       }, | ||||
| 		{ sizeof( "<<=" ),      "<<="      }, | ||||
| 		{ sizeof( ">>=" ),      ">>="      }, | ||||
| 		{ sizeof( "++" ),       "++"       }, | ||||
| 		{ sizeof( "--" ),       "--"       }, | ||||
| 		{ sizeof( "+" ),        "+"        }, | ||||
| 		{ sizeof( "-" ),        "-"        }, | ||||
| 		{ sizeof( "!" ),        "!"        }, | ||||
| 		{ sizeof( "+" ),        "+"        }, | ||||
| 		{ sizeof( "-" ),        "-"        }, | ||||
| 		{ sizeof( "*" ),        "*"        }, | ||||
| 		{ sizeof( "/" ),        "/"        }, | ||||
| 		{ sizeof( "%" ),        "%"        }, | ||||
| 		{ sizeof( "~" ),        "~"        }, | ||||
| 		{ sizeof( "&" ),        "&"        }, | ||||
| 		{ sizeof( "|" ),        "|"        }, | ||||
| 		{ sizeof( "^" ),        "^"        }, | ||||
| 		{ sizeof( "<<" ),       "<<"       }, | ||||
| 		{ sizeof( ">>" ),       ">>"       }, | ||||
| 		{ sizeof( "&&" ),       "&&"       }, | ||||
| 		{ sizeof( "||" ),       "||"       }, | ||||
| 		{ sizeof( "==" ),       "=="       }, | ||||
| 		{ sizeof( "!=" ),       "!="       }, | ||||
| 		{ sizeof( "<" ),        "<"        }, | ||||
| 		{ sizeof( ">" ),        ">"        }, | ||||
| 		{ sizeof( "<=" ),       "<="       }, | ||||
| 		{ sizeof( ">=" ),       ">="       }, | ||||
| 		{ sizeof( "[]" ),       "[]"       }, | ||||
| 		{ sizeof( "*" ),        "*"        }, | ||||
| 		{ sizeof( "&" ),        "&"        }, | ||||
| 		{ sizeof( "->" ),       "->"       }, | ||||
| 		{ sizeof( "->*" ),      "->*"      }, | ||||
| 		{ sizeof( "()" ),       "()"       }, | ||||
| 		{ sizeof( "," ),        ","        }, | ||||
| 		{ sizeof( "new" ),      "new"      }, | ||||
| 		{ sizeof( "new[]" ),    "new[]"    }, | ||||
| 		{ sizeof( "delete" ),   "delete"   }, | ||||
| 		{ sizeof( "delete[]" ), "delete[]" }, | ||||
| 		{ "INVALID",  sizeof( "INVALID" ) - 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       }, | ||||
| 		{ "+",        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       }, | ||||
| 		{ ">>",       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       }, | ||||
| 		{ "->*",      sizeof( "->*" ) - 1      }, | ||||
| 		{ "()",       sizeof( "()" ) - 1       }, | ||||
| 		{ ",",        sizeof( "," ) - 1        }, | ||||
| 		{ "new",      sizeof( "new" ) - 1      }, | ||||
| 		{ "new[]",    sizeof( "new[]" ) - 1    }, | ||||
| 		{ "delete",   sizeof( "delete" ) - 1   }, | ||||
| 		{ "delete[]", sizeof( "delete[]" ) - 1 }, | ||||
| 	}; | ||||
| 	return lookup[op]; | ||||
| } | ||||
|   | ||||
| @@ -40,32 +40,32 @@ enum Specifier : u32 | ||||
| inline Str spec_to_str( Specifier type ) | ||||
| { | ||||
| 	local_persist Str lookup[26] = { | ||||
| 		{ sizeof( "INVALID" ),       "INVALID"       }, | ||||
| 		{ sizeof( "consteval" ),     "consteval"     }, | ||||
| 		{ sizeof( "constexpr" ),     "constexpr"     }, | ||||
| 		{ sizeof( "constinit" ),     "constinit"     }, | ||||
| 		{ sizeof( "explicit" ),      "explicit"      }, | ||||
| 		{ sizeof( "extern" ),        "extern"        }, | ||||
| 		{ sizeof( "forceinline" ),   "forceinline"   }, | ||||
| 		{ sizeof( "global" ),        "global"        }, | ||||
| 		{ sizeof( "inline" ),        "inline"        }, | ||||
| 		{ sizeof( "internal" ),      "internal"      }, | ||||
| 		{ sizeof( "local_persist" ), "local_persist" }, | ||||
| 		{ sizeof( "mutable" ),       "mutable"       }, | ||||
| 		{ sizeof( "neverinline" ),   "neverinline"   }, | ||||
| 		{ sizeof( "*" ),             "*"             }, | ||||
| 		{ sizeof( "&" ),             "&"             }, | ||||
| 		{ sizeof( "register" ),      "register"      }, | ||||
| 		{ sizeof( "&&" ),            "&&"            }, | ||||
| 		{ sizeof( "static" ),        "static"        }, | ||||
| 		{ sizeof( "thread_local" ),  "thread_local"  }, | ||||
| 		{ sizeof( "virtual" ),       "virtual"       }, | ||||
| 		{ sizeof( "const" ),         "const"         }, | ||||
| 		{ sizeof( "final" ),         "final"         }, | ||||
| 		{ sizeof( "noexcept" ),      "noexcept"      }, | ||||
| 		{ sizeof( "override" ),      "override"      }, | ||||
| 		{ sizeof( "= 0" ),           "= 0"           }, | ||||
| 		{ sizeof( "volatile" ),      "volatile"      }, | ||||
| 		{ "INVALID",       sizeof( "INVALID" ) - 1       }, | ||||
| 		{ "consteval",     sizeof( "consteval" ) - 1     }, | ||||
| 		{ "constexpr",     sizeof( "constexpr" ) - 1     }, | ||||
| 		{ "constinit",     sizeof( "constinit" ) - 1     }, | ||||
| 		{ "explicit",      sizeof( "explicit" ) - 1      }, | ||||
| 		{ "extern",        sizeof( "extern" ) - 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   }, | ||||
| 		{ "*",             sizeof( "*" ) - 1             }, | ||||
| 		{ "&",             sizeof( "&" ) - 1             }, | ||||
| 		{ "register",      sizeof( "register" ) - 1      }, | ||||
| 		{ "&&",            sizeof( "&&" ) - 1            }, | ||||
| 		{ "static",        sizeof( "static" ) - 1        }, | ||||
| 		{ "thread_local",  sizeof( "thread_local" ) - 1  }, | ||||
| 		{ "virtual",       sizeof( "virtual" ) - 1       }, | ||||
| 		{ "const",         sizeof( "const" ) - 1         }, | ||||
| 		{ "final",         sizeof( "final" ) - 1         }, | ||||
| 		{ "noexcept",      sizeof( "noexcept" ) - 1      }, | ||||
| 		{ "override",      sizeof( "override" ) - 1      }, | ||||
| 		{ "= 0",           sizeof( "= 0" ) - 1           }, | ||||
| 		{ "volatile",      sizeof( "volatile" ) - 1      }, | ||||
| 	}; | ||||
| 	return lookup[type]; | ||||
| } | ||||
| @@ -81,7 +81,7 @@ inline Specifier str_to_specifier( Str str ) | ||||
| 	do_once_start for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) | ||||
| 	{ | ||||
| 		Str enum_str  = spec_to_str( (Specifier)index ); | ||||
| 		keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1 ); | ||||
| 		keymap[index] = crc32( enum_str.Ptr, enum_str.Len ); | ||||
| 	} | ||||
| 	do_once_end u32 hash = crc32( str.Ptr, str.Len ); | ||||
| 	for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) | ||||
|   | ||||
| @@ -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[] = { | ||||
| 		{ sizeof( "__invalid__" ),         "__invalid__"         }, | ||||
| 		{ sizeof( "private" ),             "private"             }, | ||||
| 		{ sizeof( "protected" ),           "protected"           }, | ||||
| 		{ sizeof( "public" ),              "public"              }, | ||||
| 		{ sizeof( "." ),                   "."                   }, | ||||
| 		{ sizeof( "::" ),                  "::"                  }, | ||||
| 		{ sizeof( "&" ),                   "&"                   }, | ||||
| 		{ sizeof( "&&" ),                  "&&"                  }, | ||||
| 		{ sizeof( ":" ),                   ":"                   }, | ||||
| 		{ sizeof( "[[" ),                  "[["                  }, | ||||
| 		{ sizeof( "]]" ),                  "]]"                  }, | ||||
| 		{ sizeof( "{" ),                   "{"                   }, | ||||
| 		{ sizeof( "}" ),                   "}"                   }, | ||||
| 		{ sizeof( "[" ),                   "["                   }, | ||||
| 		{ sizeof( "]" ),                   "]"                   }, | ||||
| 		{ sizeof( "(" ),                   "("                   }, | ||||
| 		{ sizeof( ")" ),                   ")"                   }, | ||||
| 		{ sizeof( "__comment__" ),         "__comment__"         }, | ||||
| 		{ sizeof( "__comment_end__" ),     "__comment_end__"     }, | ||||
| 		{ sizeof( "__comment_start__" ),   "__comment_start__"   }, | ||||
| 		{ sizeof( "__character__" ),       "__character__"       }, | ||||
| 		{ sizeof( "," ),                   ","                   }, | ||||
| 		{ sizeof( "class" ),               "class"               }, | ||||
| 		{ sizeof( "__attribute__" ),       "__attribute__"       }, | ||||
| 		{ sizeof( "__declspec" ),          "__declspec"          }, | ||||
| 		{ sizeof( "enum" ),                "enum"                }, | ||||
| 		{ sizeof( "extern" ),              "extern"              }, | ||||
| 		{ sizeof( "friend" ),              "friend"              }, | ||||
| 		{ sizeof( "module" ),              "module"              }, | ||||
| 		{ sizeof( "namespace" ),           "namespace"           }, | ||||
| 		{ sizeof( "operator" ),            "operator"            }, | ||||
| 		{ sizeof( "struct" ),              "struct"              }, | ||||
| 		{ sizeof( "template" ),            "template"            }, | ||||
| 		{ sizeof( "typedef" ),             "typedef"             }, | ||||
| 		{ sizeof( "using" ),               "using"               }, | ||||
| 		{ sizeof( "union" ),               "union"               }, | ||||
| 		{ sizeof( "__identifier__" ),      "__identifier__"      }, | ||||
| 		{ sizeof( "import" ),              "import"              }, | ||||
| 		{ sizeof( "export" ),              "export"              }, | ||||
| 		{ sizeof( "__new_line__" ),        "__new_line__"        }, | ||||
| 		{ sizeof( "__number__" ),          "__number__"          }, | ||||
| 		{ sizeof( "__operator__" ),        "__operator__"        }, | ||||
| 		{ sizeof( "#" ),                   "#"                   }, | ||||
| 		{ sizeof( "define" ),              "define"              }, | ||||
| 		{ sizeof( "if" ),                  "if"                  }, | ||||
| 		{ sizeof( "ifdef" ),               "ifdef"               }, | ||||
| 		{ sizeof( "ifndef" ),              "ifndef"              }, | ||||
| 		{ sizeof( "elif" ),                "elif"                }, | ||||
| 		{ sizeof( "else" ),                "else"                }, | ||||
| 		{ sizeof( "endif" ),               "endif"               }, | ||||
| 		{ sizeof( "include" ),             "include"             }, | ||||
| 		{ sizeof( "pragma" ),              "pragma"              }, | ||||
| 		{ sizeof( "__macro_content__" ),   "__macro_content__"   }, | ||||
| 		{ sizeof( "__macro__" ),           "__macro__"           }, | ||||
| 		{ sizeof( "__unsupported__" ),     "__unsupported__"     }, | ||||
| 		{ sizeof( "alignas" ),             "alignas"             }, | ||||
| 		{ sizeof( "const" ),               "const"               }, | ||||
| 		{ sizeof( "consteval" ),           "consteval"           }, | ||||
| 		{ sizeof( "constexpr" ),           "constexpr"           }, | ||||
| 		{ sizeof( "constinit" ),           "constinit"           }, | ||||
| 		{ sizeof( "explicit" ),            "explicit"            }, | ||||
| 		{ sizeof( "extern" ),              "extern"              }, | ||||
| 		{ sizeof( "final" ),               "final"               }, | ||||
| 		{ sizeof( "forceinline" ),         "forceinline"         }, | ||||
| 		{ sizeof( "global" ),              "global"              }, | ||||
| 		{ sizeof( "inline" ),              "inline"              }, | ||||
| 		{ sizeof( "internal" ),            "internal"            }, | ||||
| 		{ sizeof( "local_persist" ),       "local_persist"       }, | ||||
| 		{ sizeof( "mutable" ),             "mutable"             }, | ||||
| 		{ sizeof( "neverinline" ),         "neverinline"         }, | ||||
| 		{ sizeof( "override" ),            "override"            }, | ||||
| 		{ sizeof( "static" ),              "static"              }, | ||||
| 		{ sizeof( "thread_local" ),        "thread_local"        }, | ||||
| 		{ sizeof( "volatile" ),            "volatile"            }, | ||||
| 		{ sizeof( "virtual" ),             "virtual"             }, | ||||
| 		{ sizeof( "*" ),                   "*"                   }, | ||||
| 		{ sizeof( ";" ),                   ";"                   }, | ||||
| 		{ sizeof( "static_assert" ),       "static_assert"       }, | ||||
| 		{ sizeof( "__strbuilder__" ),          "__strbuilder__"          }, | ||||
| 		{ sizeof( "typename" ),            "typename"            }, | ||||
| 		{ sizeof( "unsigned" ),            "unsigned"            }, | ||||
| 		{ sizeof( "signed" ),              "signed"              }, | ||||
| 		{ sizeof( "short" ),               "short"               }, | ||||
| 		{ sizeof( "long" ),                "long"                }, | ||||
| 		{ sizeof( "bool" ),                "bool"                }, | ||||
| 		{ sizeof( "char" ),                "char"                }, | ||||
| 		{ sizeof( "int" ),                 "int"                 }, | ||||
| 		{ sizeof( "double" ),              "double"              }, | ||||
| 		{ sizeof( "__int8" ),              "__int8"              }, | ||||
| 		{ sizeof( "__int16" ),             "__int16"             }, | ||||
| 		{ sizeof( "__int32" ),             "__int32"             }, | ||||
| 		{ sizeof( "__int64" ),             "__int64"             }, | ||||
| 		{ sizeof( "_W64" ),                "_W64"                }, | ||||
| 		{ sizeof( "..." ),                 "..."                 }, | ||||
| 		{ sizeof( "__attrib_start__" ),    "__attrib_start__"    }, | ||||
| 		{ sizeof( "GEN_API_Export_Code" ), "GEN_API_Export_Code" }, | ||||
| 		{ sizeof( "GEN_API_Import_Code" ), "GEN_API_Import_Code" }, | ||||
| 	}; | ||||
| 	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 - 1 ); | ||||
| 	} | ||||
| 	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 | ||||
							
								
								
									
										229
									
								
								base/components/gen/etoktype.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								base/components/gen/etoktype.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,229 @@ | ||||
| #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_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_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            }, | ||||
| 		{ "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",           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,53 +6,6 @@ | ||||
|  | ||||
| #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 Code access_public; | ||||
| @@ -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 | ||||
|   | ||||
| @@ -408,7 +408,7 @@ Str token_fmt_impl( ssize num, ... ) | ||||
| 	ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va); | ||||
| 	va_end(va); | ||||
|  | ||||
| 	Str str = { result, buf }; | ||||
| 	Str str = { buf, result }; | ||||
| 	return str; | ||||
| } | ||||
| #pragma endregion Interface | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
| @@ -205,249 +209,264 @@ void define_constants() | ||||
| 	if (enum_underlying_sig.Len == 0) { | ||||
| 		enum_underlying_sig = txt("enum_underlying("); | ||||
| 	} | ||||
| 	array_append(PreprocessorDefines, enum_underlying_sig); | ||||
|  | ||||
| #	undef def_constant_spec | ||||
| 	array_append( _ctx->PreprocessorDefines, enum_underlying_sig); | ||||
| } | ||||
|  | ||||
| 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_LexArena == 0 ) { | ||||
| 		ctx->InitSize_LexArena = megabytes(4); | ||||
| 	} | ||||
| 	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): This is going to be phased out most likely. | ||||
| 		ctx->LexArena = arena_init_from_allocator( ctx->Allocator_DyanmicContainers, ctx->InitSize_LexArena ); | ||||
|  | ||||
| 		// 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"); | ||||
| 	} | ||||
|  | ||||
| 	// Preprocessor Defines | ||||
| 	PreprocessorDefines = array_init_reserve(StringCached, GlobalAllocator, kilobytes(1) ); | ||||
| 	ctx->PreprocessorDefines = array_init_reserve(StrCached, ctx->Allocator_DyanmicContainers, 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); | ||||
| 	arena_free(& ctx->LexArena); | ||||
|  | ||||
| 	array_free(PreprocessorDefines); | ||||
| 	array_free(ctx->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; | ||||
| } | ||||
|  | ||||
| void reset() | ||||
| 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); | ||||
| 	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; | ||||
| } | ||||
|  | ||||
| void set_allocator_code_pool( AllocatorInfo allocator ) | ||||
| { | ||||
| 	Allocator_CodePool = allocator; | ||||
| } | ||||
|  | ||||
| void set_allocator_lexer( AllocatorInfo allocator ) | ||||
| { | ||||
| 	Allocator_Lexer = allocator; | ||||
| } | ||||
|  | ||||
| void set_allocator_strbuilder_arena( AllocatorInfo allocator ) | ||||
| { | ||||
| 	Allocator_StringArena = allocator; | ||||
| } | ||||
|  | ||||
| void set_allocator_strbuilder_table( AllocatorInfo allocator ) | ||||
| { | ||||
| 	Allocator_StringArena = allocator; | ||||
| void set_preprocess_define( Str id, b32 is_functional ) { | ||||
| 	StrBuilder builder = strbuilder_make_str( _ctx->Allocator_Temp, id ); | ||||
| 	if (is_functional) { | ||||
| 		strbuilder_append_char( & builder, '(' ); | ||||
| 	} | ||||
| 	array_append( _ctx->PreprocessorDefines, cache_str( strbuilder_to_str(builder)) );  | ||||
| } | ||||
|   | ||||
| @@ -15,41 +15,121 @@ | ||||
|   \▓▓▓▓▓▓  \▓▓▓▓▓▓▓\▓▓   \▓▓     \▓▓▓▓▓▓\▓▓   \▓▓   \▓▓▓▓  \▓▓▓▓▓▓▓\▓▓      \▓▓       \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ \▓▓▓▓▓▓▓ | ||||
| */ | ||||
|  | ||||
| // 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_LexArena; | ||||
| 	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. | ||||
| 	Array(StrCached) PreprocessorDefines; | ||||
|  | ||||
| // 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; | ||||
|  | ||||
| 	// Array(Token) LexerTokens; | ||||
|  | ||||
| 	Array(Pool)  CodePools; | ||||
| 	Array(Arena) StringArenas; | ||||
|  | ||||
| 	StringTable StrCache; | ||||
|  | ||||
| 	// TODO(Ed): This needs to be just handled by a parser context | ||||
|  | ||||
| 	Arena LexArena; | ||||
| 	StringTable  Lexer_defines; | ||||
| 	Array(Token) Lexer_Tokens; | ||||
|  | ||||
| 	// TODO(Ed): Active parse context vs a parse result need to be separated conceptually | ||||
| 	ParseContext parser; | ||||
| }; | ||||
|  | ||||
| // 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. | ||||
| // 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); | ||||
|  | ||||
| // Alternative way to add a preprocess define entry for the lexer & parser to utilize  | ||||
| // if the user doesn't want to use def_define | ||||
| GEN_API void set_preprocess_define( Str id, b32 is_functional ); | ||||
|  | ||||
| // 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 +140,25 @@ 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; | ||||
| }; | ||||
| CodeDefine def_define( Str name, Str content, Opts_def_define opts GEN_PARAM_DEFAULT ); | ||||
| GEN_API CodeDefine def_define( Str name, Str content, 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 +168,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 +182,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 +199,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 +226,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 +255,36 @@ 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      ( s32 num, Code* codes ); | ||||
| GEN_API CodeBody       def_enum_body       ( s32 num, ... ); | ||||
| GEN_API CodeBody       def_enum_body       ( s32 num, Code* codes ); | ||||
| GEN_API CodeBody       def_export_body     ( s32 num, ... ); | ||||
| GEN_API CodeBody       def_export_body     ( s32 num, Code* codes); | ||||
| GEN_API CodeBody       def_extern_link_body( s32 num, ... ); | ||||
| GEN_API CodeBody       def_extern_link_body( s32 num, Code* codes ); | ||||
| GEN_API CodeBody       def_function_body   ( s32 num, ... ); | ||||
| GEN_API CodeBody       def_function_body   ( s32 num, Code* codes ); | ||||
| GEN_API CodeBody       def_global_body     ( s32 num, ... ); | ||||
| GEN_API CodeBody       def_global_body     ( s32 num, Code* codes ); | ||||
| GEN_API CodeBody       def_namespace_body  ( s32 num, ... ); | ||||
| GEN_API CodeBody       def_namespace_body  ( s32 num, Code* codes ); | ||||
| GEN_API CodeParams     def_params          ( s32 num, ... ); | ||||
| GEN_API CodeParams     def_params          ( s32 num, CodeParams* params ); | ||||
| GEN_API CodeSpecifiers def_specifiers      ( s32 num, ... ); | ||||
| GEN_API CodeSpecifiers def_specifiers      ( s32 num, Specifier* specs ); | ||||
| GEN_API CodeBody       def_struct_body     ( s32 num, ... ); | ||||
| GEN_API CodeBody       def_struct_body     ( s32 num, Code* codes ); | ||||
| GEN_API CodeBody       def_union_body      ( s32 num, ... ); | ||||
| GEN_API CodeBody       def_union_body      ( s32 num, Code* codes ); | ||||
|  | ||||
| #pragma endregion Upfront | ||||
|  | ||||
| @@ -213,7 +293,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 +308,6 @@ struct Error | ||||
| 	StrBuilder     message; | ||||
| 	StackNode* context_stack; | ||||
| }; | ||||
| GEN_NS_PARSER_END | ||||
|  | ||||
| struct ParseInfo | ||||
| { | ||||
| @@ -246,37 +324,37 @@ 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 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 +367,12 @@ 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_ )   { sizeof(stringize( Id_ )) - 1, stringize(Id_) } | ||||
| #define name( Id_ )   { stringize(Id_), sizeof(stringize( Id_ )) - 1 } | ||||
| #endif | ||||
|  | ||||
| #ifndef code | ||||
| //  Same as name just used to indicate intention of literal for code instead of names. | ||||
| #define code( ... ) { sizeof(stringize(__VA_ARGS__)) - 1, stringize( __VA_ARGS__ ) } | ||||
| #define code( ... ) { stringize( __VA_ARGS__ ), sizeof(stringize(__VA_ARGS__)) - 1 } | ||||
| #endif | ||||
|  | ||||
| #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_string(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; | ||||
| 		} | ||||
|  | ||||
| @@ -79,14 +77,13 @@ CodeConstructor parse_constructor( Str def ) | ||||
| 		// <specifiers> ... | ||||
| 	} | ||||
|  | ||||
| 	Context.Tokens         = toks; | ||||
| 	_ctx->parser.Tokens         = toks; | ||||
| 	CodeConstructor result = parser_parse_constructor( specifiers ); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| CodeDestructor parse_destructor( Str def ) | ||||
| { | ||||
| 	GEN_USING_NS_PARSER; | ||||
| 	check_parse_args( def ); | ||||
|  | ||||
| 	TokArray toks = lex( def ); | ||||
| @@ -96,225 +93,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,21 +8,18 @@ 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; | ||||
| 	local_persist StringTable tok_map; | ||||
| 	do_once() { | ||||
| 		tok_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 ); | ||||
| @@ -90,12 +87,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); | ||||
|  | ||||
| 	ssize result = buf_size - remaining; | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -109,7 +102,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 +130,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      = { c_str_len_capped(fmt, MaxNameLength), fmt }; | ||||
|     Str uncapped_str = { length, buf }; | ||||
|     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 ) | ||||
| 	{ | ||||
| @@ -172,13 +162,12 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ) | ||||
| 	ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va); | ||||
| 	va_end(va); | ||||
|  | ||||
| 	Str buf_str = { length, buf }; | ||||
| 	Str buf_str = { buf, length }; | ||||
|  | ||||
| 	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 ) | ||||
| 	{ | ||||
|   | ||||
| @@ -419,7 +419,7 @@ CodeAttributes def_attributes( Str content ) | ||||
| 	Code | ||||
| 	result          = make_code(); | ||||
| 	result->Type    = CT_PlatformAttributes; | ||||
| 	result->Name    = get_cached_string( content ); | ||||
| 	result->Name    = cache_str( content ); | ||||
| 	result->Content = result->Name; | ||||
| 	return (CodeAttributes) result; | ||||
| } | ||||
| @@ -433,9 +433,7 @@ CodeComment def_comment( Str content ) | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
|  | ||||
| 	static char line[ MaxCommentLineLength ]; | ||||
|  | ||||
| 	StrBuilder      cmt_formatted = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
| 	StrBuilder  cmt_formatted = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) ); | ||||
| 	char const* end           = content.Ptr + content.Len; | ||||
| 	char const* scanner       = content.Ptr; | ||||
| 	s32         curr          = 0; | ||||
| @@ -450,10 +448,7 @@ CodeComment def_comment( Str content ) | ||||
| 		} | ||||
| 		length++; | ||||
|  | ||||
| 		c_str_copy( line, scanner, length ); | ||||
| 		strbuilder_append_fmt(& cmt_formatted, "//%.*s", length, line ); | ||||
| 		mem_set( line, 0, MaxCommentLineLength ); | ||||
|  | ||||
| 		strbuilder_append_fmt(& cmt_formatted, "//%.*s", length, scanner ); | ||||
| 		scanner += length; | ||||
| 	} | ||||
| 	while ( scanner <= end ); | ||||
| @@ -461,12 +456,12 @@ CodeComment def_comment( Str content ) | ||||
| 	if ( * strbuilder_back(cmt_formatted) != '\n' ) | ||||
| 		strbuilder_append_str( & cmt_formatted, txt("\n") ); | ||||
|  | ||||
| 	Str name = { strbuilder_length(cmt_formatted), cmt_formatted }; | ||||
| 	Str name = strbuilder_to_str(cmt_formatted); | ||||
|  | ||||
| 	Code | ||||
| 	result          = make_code(); | ||||
| 	result->Type    = CT_Comment; | ||||
| 	result->Name    = get_cached_string( name ); | ||||
| 	result->Name    = cache_str( name ); | ||||
| 	result->Content = result->Name; | ||||
|  | ||||
| 	strbuilder_free(& cmt_formatted); | ||||
| @@ -531,7 +526,7 @@ CodeClass def_class( Str name, Opts_def_struct p ) | ||||
|  | ||||
| 	CodeClass | ||||
| 	result              = (CodeClass) make_code(); | ||||
| 	result->Name        = get_cached_string( name ); | ||||
| 	result->Name        = cache_str( name ); | ||||
| 	result->ModuleFlags = p.mflags; | ||||
| 	if ( p.body ) | ||||
| 	{ | ||||
| @@ -574,12 +569,12 @@ CodeDefine def_define( Str name, Str content, Opts_def_define p ) | ||||
| 	CodeDefine | ||||
| 	result          = (CodeDefine) make_code(); | ||||
| 	result->Type    = CT_Preprocess_Define; | ||||
| 	result->Name    = get_cached_string( name ); | ||||
| 	result->Name    = cache_str( name ); | ||||
|  | ||||
| 	if ( content.Len <= 0 || content.Ptr == nullptr ) | ||||
| 		result->Content = get_cached_string( txt("") ); | ||||
| 		result->Content = cache_str( txt("") ); | ||||
| 	else | ||||
| 		result->Content = get_cached_string( strbuilder_to_str(strbuilder_fmt_buf(GlobalAllocator, "%S\n", content)) ); | ||||
| 		result->Content = cache_str( strbuilder_to_str(strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S\n", content)) ); | ||||
|  | ||||
| 	b32  append_preprocess_defines = ! p.dont_append_preprocess_defines; | ||||
| 	if ( append_preprocess_defines ) { | ||||
| @@ -589,8 +584,8 @@ CodeDefine def_define( Str name, Str content, Opts_def_define p ) | ||||
| 			if ( result->Name.Ptr[lex_id_len] == '(' ) | ||||
| 				break; | ||||
| 		} | ||||
| 		Str lex_id = { lex_id_len, result->Name.Ptr }; | ||||
| 		array_append(PreprocessorDefines, lex_id ); | ||||
| 		Str lex_id = { result->Name.Ptr,  lex_id_len }; | ||||
| 		array_append(_ctx->PreprocessorDefines, cache_str(lex_id) ); | ||||
| 	} | ||||
| 	return result; | ||||
| } | ||||
| @@ -648,7 +643,7 @@ CodeEnum def_enum( Str name, Opts_def_enum p ) | ||||
|  | ||||
| 	CodeEnum | ||||
| 	result              = (CodeEnum) make_code(); | ||||
| 	result->Name        = get_cached_string( name ); | ||||
| 	result->Name        = cache_str( name ); | ||||
| 	result->ModuleFlags = p.mflags; | ||||
| 	if ( p.body ) | ||||
| 	{ | ||||
| @@ -700,7 +695,7 @@ CodeExec def_execution( Str content ) | ||||
| 	CodeExec | ||||
| 	result          = (CodeExec) make_code(); | ||||
| 	result->Type    = CT_Execution; | ||||
| 	result->Content = get_cached_string( content ); | ||||
| 	result->Content = cache_str( content ); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -718,7 +713,7 @@ CodeExtern def_extern_link( Str name, CodeBody body ) | ||||
| 	CodeExtern | ||||
| 	result        = (CodeExtern)make_code(); | ||||
| 	result->Type  = CT_Extern_Linkage; | ||||
| 	result->Name  = get_cached_string( name ); | ||||
| 	result->Name  = cache_str( name ); | ||||
| 	result->Body  = body; | ||||
| 	return result; | ||||
| } | ||||
| @@ -781,7 +776,7 @@ CodeFn def_function( Str name, Opts_def_function p ) | ||||
|  | ||||
| 	CodeFn | ||||
| 	result              = (CodeFn) make_code(); | ||||
| 	result->Name        = get_cached_string( name ); | ||||
| 	result->Name        = cache_str( name ); | ||||
| 	result->ModuleFlags = p.mflags; | ||||
| 	if ( p.body ) | ||||
| 	{ | ||||
| @@ -820,13 +815,13 @@ CodeInclude def_include( Str path, Opts_def_include p ) | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
| 	StrBuilder content = p.foreign ? | ||||
| 			strbuilder_fmt_buf( GlobalAllocator, "<%.*s>",   path.Len, path.Ptr ) | ||||
| 		:	strbuilder_fmt_buf( GlobalAllocator, "\"%.*s\"", path.Len, path.Ptr ); | ||||
| 			strbuilder_fmt_buf( _ctx->Allocator_Temp, "<%.*s>",   path.Len, path.Ptr ) | ||||
| 		:	strbuilder_fmt_buf( _ctx->Allocator_Temp, "\"%.*s\"", path.Len, path.Ptr ); | ||||
|  | ||||
| 	CodeInclude | ||||
| 	result          = (CodeInclude) make_code(); | ||||
| 	result->Type    = CT_Preprocess_Include; | ||||
| 	result->Name    = get_cached_string( strbuilder_to_str(content) ); | ||||
| 	result->Name    = cache_str( strbuilder_to_str(content) ); | ||||
| 	result->Content = result->Name; | ||||
| 	return result; | ||||
| } | ||||
| @@ -840,7 +835,7 @@ CodeModule def_module( Str name, Opts_def_module p ) | ||||
| 	CodeModule | ||||
| 	result              = (CodeModule) make_code(); | ||||
| 	result->Type        = CT_Module; | ||||
| 	result->Name        = get_cached_string( name ); | ||||
| 	result->Name        = cache_str( name ); | ||||
| 	result->ModuleFlags = p.mflags; | ||||
| 	return result; | ||||
| } | ||||
| @@ -863,7 +858,7 @@ CodeNS def_namespace( Str name, CodeBody body, Opts_def_namespace p ) | ||||
| 	CodeNS | ||||
| 	result              = (CodeNS) make_code(); | ||||
| 	result->Type        = CT_Namespace; | ||||
| 	result->Name        = get_cached_string( name ); | ||||
| 	result->Name        = cache_str( name ); | ||||
| 	result->ModuleFlags = p.mflags; | ||||
| 	result->Body        = body; | ||||
| 	return result; | ||||
| @@ -895,11 +890,11 @@ CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator p ) | ||||
| 	else | ||||
| 		name = c_str_fmt_buf( "operator %.*s", op_str.Len, op_str.Ptr ); | ||||
|  | ||||
| 	Str name_resolved = { c_str_len(name), name }; | ||||
| 	Str name_resolved = { name, c_str_len(name) }; | ||||
|  | ||||
| 	CodeOperator | ||||
| 	result              = (CodeOperator) make_code(); | ||||
| 	result->Name        = get_cached_string( name_resolved ); | ||||
| 	result->Name        = cache_str( name_resolved ); | ||||
| 	result->ModuleFlags = p.mflags; | ||||
| 	result->Op          = op; | ||||
| 	if ( p.body ) | ||||
| @@ -986,7 +981,7 @@ CodeParams def_param( CodeTypename type, Str name, Opts_def_param p ) | ||||
| 	CodeParams | ||||
| 	result            = (CodeParams) make_code(); | ||||
| 	result->Type      = CT_Parameters; | ||||
| 	result->Name      = get_cached_string( name ); | ||||
| 	result->Name      = cache_str( name ); | ||||
| 	result->ValueType = type; | ||||
| 	result->Value     = p.value; | ||||
| 	result->NumEntries++; | ||||
| @@ -1003,7 +998,7 @@ CodePragma def_pragma( Str directive ) | ||||
| 	CodePragma | ||||
| 	result          = (CodePragma) make_code(); | ||||
| 	result->Type    = CT_Preprocess_Pragma; | ||||
| 	result->Content = get_cached_string( directive ); | ||||
| 	result->Content = cache_str( directive ); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -1016,7 +1011,7 @@ CodePreprocessCond def_preprocess_cond( EPreprocessCond type, Str expr ) | ||||
| 	} | ||||
| 	CodePreprocessCond | ||||
| 	result          = (CodePreprocessCond) make_code(); | ||||
| 	result->Content = get_cached_string( expr ); | ||||
| 	result->Content = cache_str( expr ); | ||||
| 	switch (type) | ||||
| 	{ | ||||
| 		case PreprocessCond_If: | ||||
| @@ -1066,7 +1061,7 @@ CodeStruct def_struct( Str name, Opts_def_struct p ) | ||||
| 	result              = (CodeStruct) make_code(); | ||||
| 	result->ModuleFlags = p.mflags; | ||||
| 	if ( name.Len ) | ||||
| 		result->Name = get_cached_string( name ); | ||||
| 		result->Name = cache_str( name ); | ||||
|  | ||||
| 	if ( p.body ) { | ||||
| 		result->Type = CT_Struct; | ||||
| @@ -1143,7 +1138,7 @@ CodeTypename def_type( Str name, Opts_def_type p ) | ||||
| 	} | ||||
| 	CodeTypename | ||||
| 	result             = (CodeTypename) make_code(); | ||||
| 	result->Name       = get_cached_string( name ); | ||||
| 	result->Name       = cache_str( name ); | ||||
| 	result->Type       = CT_Typename; | ||||
| 	result->Attributes = p.attributes; | ||||
| 	result->Specs      = p.specifiers; | ||||
| @@ -1204,12 +1199,12 @@ CodeTypedef def_typedef( Str name, Code type, Opts_def_typedef p ) | ||||
| 			GEN_DEBUG_TRAP(); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
| 		result->Name       = get_cached_string( type->Name ); | ||||
| 		result->Name       = cache_str( type->Name ); | ||||
| 		result->IsFunction = true; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		result->Name       = get_cached_string( name ); | ||||
| 		result->Name       = cache_str( name ); | ||||
| 		result->IsFunction = false; | ||||
| 	} | ||||
| 	return result; | ||||
| @@ -1238,7 +1233,7 @@ CodeUnion def_union( Str name, CodeBody body, Opts_def_union p ) | ||||
| 	result->Body        = body; | ||||
| 	result->Attributes  = p.attributes; | ||||
| 	if ( name.Ptr ) | ||||
| 		result->Name = get_cached_string( name ); | ||||
| 		result->Name = cache_str( name ); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -1262,7 +1257,7 @@ CodeUsing def_using( Str name, CodeTypename type, Opts_def_using p ) | ||||
| 	} | ||||
| 	CodeUsing | ||||
| 	result                 = (CodeUsing) make_code(); | ||||
| 	result->Name           = get_cached_string( name ); | ||||
| 	result->Name           = cache_str( name ); | ||||
| 	result->ModuleFlags    = p.mflags; | ||||
| 	result->Type           = CT_Using; | ||||
| 	result->UnderlyingType = type; | ||||
| @@ -1278,7 +1273,7 @@ CodeUsing def_using_namespace( Str name ) | ||||
| 	} | ||||
| 	CodeUsing | ||||
| 	result          = (CodeUsing) make_code(); | ||||
| 	result->Name    = get_cached_string( name ); | ||||
| 	result->Name    = cache_str( name ); | ||||
| 	result->Type    = CT_Using_Namespace; | ||||
| 	return result; | ||||
| } | ||||
| @@ -1311,7 +1306,7 @@ CodeVar def_variable( CodeTypename type, Str name, Opts_def_variable p ) | ||||
| 	} | ||||
| 	CodeVar | ||||
| 	result              = (CodeVar) make_code(); | ||||
| 	result->Name        = get_cached_string( name ); | ||||
| 	result->Name        = cache_str( name ); | ||||
| 	result->Type        = CT_Variable; | ||||
| 	result->ModuleFlags = p.mflags; | ||||
| 	result->ValueType   = type; | ||||
| @@ -1357,15 +1352,12 @@ CodeBody def_class_body( s32 num, ... ) | ||||
| 	{ | ||||
| 		Code_POD pod   = va_arg(va, Code_POD); | ||||
| 		Code     entry = pcast(Code, pod); | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" | ||||
| 						"def_class_body" | ||||
| 						": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_CLASS_UNALLOWED_TYPES: | ||||
| @@ -1375,7 +1367,6 @@ CodeBody def_class_body( s32 num, ... ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1391,18 +1382,14 @@ CodeBody def_class_body( s32 num, Code* codes ) | ||||
| 	CodeBody | ||||
| 	result       = (CodeBody) make_code(); | ||||
| 	result->Type = CT_Function_Body; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		Code entry = *codes; | ||||
| 		codes++; | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" "def_class_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_CLASS_UNALLOWED_TYPES: | ||||
| @@ -1412,7 +1399,6 @@ CodeBody def_class_body( s32 num, Code* codes ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1434,19 +1420,14 @@ CodeBody def_enum_body( s32 num, ... ) | ||||
| 	{ | ||||
| 		Code_POD pod   = va_arg(va, Code_POD); | ||||
| 		Code     entry = pcast(Code, pod); | ||||
|  | ||||
| 		if ( ! entry ) | ||||
| 		{ | ||||
| 		if ( ! entry ) { | ||||
| 			log_failure("gen::def_enum_body: Provided a null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		if ( entry->Type != CT_Untyped && entry->Type != CT_Comment ) | ||||
| 		{ | ||||
| 		if ( entry->Type != CT_Untyped && entry->Type != CT_Comment ) { | ||||
| 			log_failure("gen::def_enum_body: Entry type is not allowed - %s. Must be of untyped or comment type.", code_debug_str(entry) ); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry ); | ||||
| 	} | ||||
| 	while ( num--, num > 0 ); | ||||
| @@ -1462,23 +1443,17 @@ CodeBody def_enum_body( s32 num, Code* codes ) | ||||
| 	CodeBody | ||||
| 	result       = (CodeBody) make_code(); | ||||
| 	result->Type = CT_Enum_Body; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		Code entry = *codes; | ||||
|  | ||||
| 		if ( ! entry ) | ||||
| 		{ | ||||
| 		if ( ! entry ) { | ||||
| 			log_failure("gen::def_enum_body: Provided a null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		if ( entry->Type != CT_Untyped && entry->Type != CT_Comment ) | ||||
| 		{ | ||||
| 		if ( entry->Type != CT_Untyped && entry->Type != CT_Comment ) { | ||||
| 			log_failure("gen::def_enum_body: Entry type is not allowed: %s", code_debug_str(entry) ); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry ); | ||||
| 	} | ||||
| 	while ( codes++, num--, num > 0 ); | ||||
| @@ -1500,13 +1475,11 @@ CodeBody def_export_body( s32 num, ... ) | ||||
| 	{ | ||||
| 		Code_POD pod = va_arg(va, Code_POD); | ||||
| 		Code     entry = pcast(Code, pod); | ||||
|  | ||||
| 		if (!entry) | ||||
| 		if ( ! entry) | ||||
| 		{ | ||||
| 			log_failure("gen::" "def_export_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_EXPORT_UNALLOWED_TYPES: | ||||
| @@ -1516,7 +1489,6 @@ CodeBody def_export_body( s32 num, ... ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1532,18 +1504,14 @@ CodeBody def_export_body( s32 num, Code* codes ) | ||||
| 	CodeBody | ||||
| 	result       = (CodeBody) make_code(); | ||||
| 	result->Type = CT_Export_Body; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		Code entry = *codes; | ||||
| 		codes++; | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" "def_export_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_EXPORT_UNALLOWED_TYPES: | ||||
| @@ -1553,7 +1521,6 @@ CodeBody def_export_body( s32 num, Code* codes ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1575,13 +1542,10 @@ CodeBody def_extern_link_body( s32 num, ... ) | ||||
| 	{ | ||||
| 		Code_POD pod   = va_arg(va, Code_POD); | ||||
| 		Code     entry = pcast(Code, pod); | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES: | ||||
| @@ -1591,7 +1555,6 @@ CodeBody def_extern_link_body( s32 num, ... ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1607,18 +1570,15 @@ CodeBody def_extern_link_body( s32 num, Code* codes ) | ||||
| 	CodeBody | ||||
| 	result       = (CodeBody) make_code(); | ||||
| 	result->Type = CT_Extern_Linkage_Body; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		Code entry = *codes; | ||||
| 		codes++; | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 			log_failure("gen::" "def_extern_linkage_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES: | ||||
| @@ -1628,7 +1588,6 @@ CodeBody def_extern_link_body( s32 num, Code* codes ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1650,16 +1609,12 @@ CodeBody def_function_body( s32 num, ... ) | ||||
| 	{ | ||||
| 		Code_POD pod   = va_arg(va, Code_POD); | ||||
| 		Code     entry = pcast(Code, pod); | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" stringize(def_function_body) ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
|  | ||||
| 			GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES: | ||||
| 				log_failure("gen::" stringize(def_function_body) ": Entry type is not allowed: %s", code_debug_str(entry)); | ||||
| 				return InvalidCode; | ||||
| @@ -1667,7 +1622,6 @@ CodeBody def_function_body( s32 num, ... ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1683,18 +1637,14 @@ CodeBody def_function_body( s32 num, Code* codes ) | ||||
| 	CodeBody | ||||
| 	result       = (CodeBody) make_code(); | ||||
| 	result->Type = CT_Function_Body; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		Code entry = *codes; | ||||
| 		codes++; | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if (!entry) { | ||||
| 			log_failure("gen::" "def_function_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES: | ||||
| @@ -1725,13 +1675,10 @@ CodeBody def_global_body( s32 num, ... ) | ||||
| 	{ | ||||
| 		Code_POD pod   = va_arg(va, Code_POD); | ||||
| 		Code     entry = pcast(Code, pod); | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" "def_global_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			case CT_Global_Body: | ||||
| @@ -1746,7 +1693,6 @@ CodeBody def_global_body( s32 num, ... ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1762,18 +1708,14 @@ CodeBody def_global_body( s32 num, Code* codes ) | ||||
| 	CodeBody | ||||
| 	result       = (CodeBody) make_code(); | ||||
| 	result->Type = CT_Global_Body; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		Code entry = *codes; | ||||
| 		codes++; | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" "def_global_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			case CT_Global_Body: | ||||
| @@ -1809,13 +1751,10 @@ CodeBody def_namespace_body( s32 num, ... ) | ||||
| 	{ | ||||
| 		Code_POD pod   = va_arg(va, Code_POD); | ||||
| 		Code     entry = pcast(Code, pod); | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" "def_namespace_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES: | ||||
| @@ -1825,7 +1764,6 @@ CodeBody def_namespace_body( s32 num, ... ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1841,18 +1779,14 @@ CodeBody def_namespace_body( s32 num, Code* codes ) | ||||
| 	CodeBody | ||||
| 	result       = (CodeBody) make_code(); | ||||
| 	result->Type = CT_Global_Body; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		Code entry = *codes; | ||||
| 		codes++; | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" "def_namespace_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES: | ||||
| @@ -1861,7 +1795,6 @@ CodeBody def_namespace_body( s32 num, Code* codes ) | ||||
|  | ||||
| 			default: break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -1880,26 +1813,20 @@ CodeParams def_params( s32 num, ... ) | ||||
| 	CodeParams param = pcast( CodeParams, pod ); | ||||
|  | ||||
| 	null_check( def_params, param ); | ||||
|  | ||||
| 	if ( param->Type != CT_Parameters ) | ||||
| 	{ | ||||
| 	if ( param->Type != CT_Parameters ) { | ||||
| 		log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 ); | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
|  | ||||
| 	CodeParams result = (CodeParams) code_duplicate(param); | ||||
|  | ||||
| 	while ( -- num ) | ||||
| 	{ | ||||
| 		pod   = va_arg(va, Code_POD); | ||||
| 		param = pcast( CodeParams, pod ); | ||||
|  | ||||
| 		if ( param->Type != CT_Parameters ) | ||||
| 		{ | ||||
| 		if ( param->Type != CT_Parameters ) { | ||||
| 			log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 ); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		params_append(result, param ); | ||||
| 	} | ||||
| 	va_end(va); | ||||
| @@ -1912,18 +1839,14 @@ CodeParams def_params( s32 num, CodeParams* codes ) | ||||
| 	def_body_code_array_start( def_params ); | ||||
|  | ||||
| #	define check_current(current)                                                                                      \ | ||||
| 	if ( current == nullptr )                                                                                          \ | ||||
| 	{                                                                                                                  \ | ||||
| 	if ( current == nullptr ) {                                                                                        \ | ||||
| 		log_failure("gen::def_params: Provide a null code in codes array");                                            \ | ||||
| 		return InvalidCode;                                                                                            \ | ||||
| 	}                                                                                                                  \ | ||||
| 																												       \ | ||||
| 	if (current->Type != CT_Parameters )                                                                               \ | ||||
| 	{                                                                                                                  \ | ||||
| 	if (current->Type != CT_Parameters ) {                                                                             \ | ||||
| 		log_failure("gen::def_params: Code in coes array is not of paramter type - %s", code_debug_str(current) );     \ | ||||
| 		return InvalidCode;                                                                                            \ | ||||
| 	} | ||||
|  | ||||
| 	CodeParams current = (CodeParams)code_duplicate(* codes); | ||||
| 	check_current(current); | ||||
|  | ||||
| @@ -1932,9 +1855,7 @@ CodeParams def_params( s32 num, CodeParams* codes ) | ||||
| 	result->Name      = current->Name; | ||||
| 	result->Type      = current->Type; | ||||
| 	result->ValueType = current->ValueType; | ||||
|  | ||||
| 	while( codes++, current = * codes, num--, num > 0 ) | ||||
| 	{ | ||||
| 	while( codes++, current = * codes, num--, num > 0 ) { | ||||
| 		check_current(current); | ||||
| 		params_append(result, current ); | ||||
| 	} | ||||
| @@ -1945,28 +1866,22 @@ CodeParams def_params( s32 num, CodeParams* codes ) | ||||
|  | ||||
| CodeSpecifiers def_specifiers( s32 num, ... ) | ||||
| { | ||||
| 	if ( num <= 0 ) | ||||
| 	{ | ||||
| 	if ( num <= 0 ) { | ||||
| 		log_failure("gen::def_specifiers: num cannot be zero or less"); | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
|  | ||||
| 	if ( num > AST_ArrSpecs_Cap ) | ||||
| 	{ | ||||
| 	if ( num > AST_ArrSpecs_Cap ) { | ||||
| 		log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num); | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
|  | ||||
| 	CodeSpecifiers | ||||
| 	result       = (CodeSpecifiers) make_code(); | ||||
| 	result->Type = CT_Specifiers; | ||||
|  | ||||
| 	va_list va; | ||||
| 	va_start(va, num); | ||||
| 	do | ||||
| 	{ | ||||
| 	do { | ||||
| 		Specifier type = (Specifier)va_arg(va, int); | ||||
|  | ||||
| 		specifiers_append(result, type ); | ||||
| 	} | ||||
| 	while ( --num, num ); | ||||
| @@ -1977,25 +1892,20 @@ CodeSpecifiers def_specifiers( s32 num, ... ) | ||||
|  | ||||
| CodeSpecifiers def_specifiers( s32 num, Specifier* specs ) | ||||
| { | ||||
| 	if ( num <= 0 ) | ||||
| 	{ | ||||
| 	if ( num <= 0 ) { | ||||
| 		log_failure("gen::def_specifiers: num cannot be zero or less"); | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
|  | ||||
| 	if ( num > AST_ArrSpecs_Cap ) | ||||
| 	{ | ||||
| 	if ( num > AST_ArrSpecs_Cap ) { | ||||
| 		log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num); | ||||
| 		return InvalidCode; | ||||
| 	} | ||||
|  | ||||
| 	CodeSpecifiers | ||||
| 	result       = (CodeSpecifiers) make_code(); | ||||
| 	result->Type = CT_Specifiers; | ||||
|  | ||||
| 	s32 idx = 0; | ||||
| 	do | ||||
| 	{ | ||||
| 	do { | ||||
| 		specifiers_append(result, specs[idx] ); | ||||
| 		idx++; | ||||
| 	} | ||||
| @@ -2018,13 +1928,10 @@ CodeBody def_struct_body( s32 num, ... ) | ||||
| 	{ | ||||
| 		Code_POD pod   = va_arg(va, Code_POD); | ||||
| 		Code     entry = pcast(Code, pod); | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" "def_struct_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_STRUCT_UNALLOWED_TYPES: | ||||
| @@ -2034,7 +1941,6 @@ CodeBody def_struct_body( s32 num, ... ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -2050,18 +1956,14 @@ CodeBody def_struct_body( s32 num, Code* codes ) | ||||
| 	CodeBody | ||||
| 	result       = (CodeBody) make_code(); | ||||
| 	result->Type = CT_Struct_Body; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		Code entry = *codes; | ||||
| 		codes++; | ||||
|  | ||||
| 		if (!entry) | ||||
| 		{ | ||||
| 		if ( ! entry) { | ||||
| 			log_failure("gen::" "def_struct_body" ": Provided an null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		switch (entry->Type) | ||||
| 		{ | ||||
| 			GEN_AST_BODY_STRUCT_UNALLOWED_TYPES: | ||||
| @@ -2071,7 +1973,6 @@ CodeBody def_struct_body( s32 num, Code* codes ) | ||||
| 			default: | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry); | ||||
| 	} | ||||
| 	while (num--, num > 0); | ||||
| @@ -2093,19 +1994,14 @@ CodeBody def_union_body( s32 num, ... ) | ||||
| 	{ | ||||
| 		Code_POD pod   = va_arg(va, Code_POD); | ||||
| 		Code     entry = pcast( Code, pod ); | ||||
|  | ||||
| 		if ( ! entry ) | ||||
| 		{ | ||||
| 		if ( ! entry ) { | ||||
| 			log_failure("gen::def_union_body: Provided a null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		if ( entry->Type != CT_Untyped && entry->Type != CT_Comment ) | ||||
| 		{ | ||||
| 		if ( entry->Type != CT_Untyped && entry->Type != CT_Comment ) { | ||||
| 			log_failure("gen::def_union_body: Entry type is not allowed - %s. Must be of untyped or comment type.", code_debug_str(entry) ); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry ); | ||||
| 	} | ||||
| 	while ( num--, num > 0 ); | ||||
| @@ -2121,23 +2017,17 @@ CodeBody def_union_body( s32 num, Code* codes ) | ||||
| 	CodeBody | ||||
| 	result       = (CodeBody) make_code(); | ||||
| 	result->Type = CT_Union_Body; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		Code entry = *codes; | ||||
|  | ||||
| 		if ( ! entry ) | ||||
| 		{ | ||||
| 		if ( ! entry ) { | ||||
| 			log_failure("gen::def_union_body: Provided a null entry"); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		if ( entry->Type != CT_Untyped && entry->Type != CT_Comment ) | ||||
| 		{ | ||||
| 		if ( entry->Type != CT_Untyped && entry->Type != CT_Comment ) { | ||||
| 			log_failure("gen::def_union_body: Entry type is not allowed: %s", code_debug_str(entry) ); | ||||
| 			return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| 		body_append(result, entry ); | ||||
| 	} | ||||
| 	while ( codes++, num--, num > 0 ); | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										125
									
								
								base/components/parser_types.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								base/components/parser_types.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,125 @@ | ||||
| #ifdef GEN_INTELLISENSE_DIRECTIVES | ||||
| #pragma once | ||||
| #include "types.hpp" | ||||
| #include "gen/ecode.hpp" | ||||
| #include "gen/eoperator.hpp" | ||||
| #include "gen/especifier.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_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_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); | ||||
|  | ||||
| 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; | ||||
| }; | ||||
| @@ -4,32 +4,16 @@ | ||||
| #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; | ||||
|  | ||||
| #pragma region Constants | ||||
| global u32 context_counter; | ||||
|  | ||||
| global Str enum_underlying_sig; | ||||
|  | ||||
| global Code Code_Global; | ||||
| global Code Code_Invalid; | ||||
|  | ||||
| global Code access_public; | ||||
| global Code access_protected; | ||||
| global Code access_private; | ||||
| @@ -84,8 +68,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 +89,5 @@ global CodeTypename t_f64; | ||||
| #endif | ||||
|  | ||||
| #pragma endregion Constants | ||||
|  | ||||
| #pragma endregion StaticData | ||||
|   | ||||
| @@ -48,13 +48,13 @@ Str access_spec_to_str( AccessSpec type ) | ||||
| { | ||||
| 	local_persist | ||||
| 	Str lookup[ (u32)AccessSpec_Num_AccessSpec ] = { | ||||
| 		{ sizeof("") - 1,          "" }, | ||||
| 		{ sizeof("prviate") - 1,   "private" }, | ||||
| 		{ sizeof("protected") - 1, "private" }, | ||||
| 		{ sizeof("public") - 1,    "public" }, | ||||
| 		{ "",        sizeof( "" )        - 1 }, | ||||
| 		{ "private", sizeof("prviate")   - 1 }, | ||||
| 		{ "private", sizeof("protected") - 1 }, | ||||
| 		{ "public",  sizeof("public")    - 1 }, | ||||
| 	}; | ||||
|  | ||||
| 	Str invalid = { sizeof("Invalid") - 1, "Invalid" }; | ||||
| 	Str invalid = { "Invalid", sizeof("Invalid") - 1 }; | ||||
| 	if ( type > AccessSpec_Public ) | ||||
| 		return invalid; | ||||
|  | ||||
| @@ -101,13 +101,13 @@ Str module_flag_to_str( ModuleFlag flag ) | ||||
| { | ||||
| 	local_persist | ||||
| 	Str lookup[ (u32)Num_ModuleFlags ] = { | ||||
| 		{ sizeof("__none__"), "__none__" }, | ||||
| 		{ sizeof("export"), "export" }, | ||||
| 		{ sizeof("import"), "import" }, | ||||
| 		{ "__none__", sizeof("__none__") - 1 }, | ||||
| 		{ "export",   sizeof("export")   - 1 }, | ||||
| 		{ "import",   sizeof("import")   - 1 }, | ||||
| 	}; | ||||
|  | ||||
| 	local_persist | ||||
| 	Str invalid_flag = { sizeof("invalid"), "invalid" }; | ||||
| 	Str invalid_flag = { "invalid", sizeof("invalid") }; | ||||
| 	if ( flag > ModuleFlag_Import ) | ||||
| 		return invalid_flag; | ||||
|  | ||||
|   | ||||
| @@ -102,16 +102,16 @@ struct Array | ||||
| #endif | ||||
|  | ||||
| #if GEN_COMPILER_CPP && 0 | ||||
| template<class Type> bool         append(Array<Type>& array, Array<Type> other)                         { return append( & array, other ); } | ||||
| template<class Type> bool         append(Array<Type>& array, Type value)                                { return append( & array, value ); } | ||||
| template<class Type> bool         append(Array<Type>& array, Type* items, usize item_num)               { return append( & array, items, item_num ); } | ||||
| template<class Type> bool         append_at(Array<Type>& array, Type item, usize idx)                   { return append_at( & array, item, idx ); } | ||||
| template<class Type> bool         append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return append_at( & array, items, item_num, idx ); } | ||||
| template<class Type> void         free(Array<Type>& array)                                              { return free( & array ); } | ||||
| template<class Type> bool         grow(Array<Type>& array, usize min_capacity)                          { return grow( & array, min_capacity); } | ||||
| template<class Type> bool         reserve(Array<Type>& array, usize new_capacity)                       { return reserve( & array, new_capacity); } | ||||
| template<class Type> bool         resize(Array<Type>& array, usize num)                                 { return resize( & array, num); } | ||||
| template<class Type> bool         set_capacity(Array<Type>& array, usize new_capacity)                  { return set_capacity( & array, new_capacity); } | ||||
| template<class Type> bool append(Array<Type>& array, Array<Type> other)                         { return append( & array, other ); } | ||||
| template<class Type> bool append(Array<Type>& array, Type value)                                { return append( & array, value ); } | ||||
| template<class Type> bool append(Array<Type>& array, Type* items, usize item_num)               { return append( & array, items, item_num ); } | ||||
| template<class Type> bool append_at(Array<Type>& array, Type item, usize idx)                   { return append_at( & array, item, idx ); } | ||||
| template<class Type> bool append_at(Array<Type>& array, Type* items, usize item_num, usize idx) { return append_at( & array, items, item_num, idx ); } | ||||
| template<class Type> void free(Array<Type>& array)                                              { return free( & array ); } | ||||
| template<class Type> bool grow(Array<Type>& array, usize min_capacity)                          { return grow( & array, min_capacity); } | ||||
| template<class Type> bool reserve(Array<Type>& array, usize new_capacity)                       { return reserve( & array, new_capacity); } | ||||
| template<class Type> bool resize(Array<Type>& array, usize num)                                 { return resize( & array, num); } | ||||
| template<class Type> bool set_capacity(Array<Type>& array, usize new_capacity)                  { return set_capacity( & array, new_capacity); } | ||||
|  | ||||
| template<class Type> forceinline Type* begin(Array<Type>& array)             { return array;      } | ||||
| template<class Type> forceinline Type* end(Array<Type>& array)               { return array + array_get_header(array)->Num; } | ||||
|   | ||||
| @@ -11,8 +11,10 @@ | ||||
| #if GEN_BUILD_DEBUG | ||||
| #	if defined( GEN_COMPILER_MSVC ) | ||||
| #		if _MSC_VER < 1300 | ||||
| #pragma message("GEN_BUILD_DEBUG: __asm int 3") | ||||
| #			define GEN_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */ | ||||
| #		else | ||||
| #pragma message("GEN_BUILD_DEBUG: __debugbreak()") | ||||
| #			define GEN_DEBUG_TRAP() __debugbreak() | ||||
| #		endif | ||||
| #	elif defined( GEN_COMPILER_TINYC ) | ||||
| @@ -21,6 +23,7 @@ | ||||
| #		define GEN_DEBUG_TRAP() __builtin_trap() | ||||
| #	endif | ||||
| #else | ||||
| #pragma message("GEN_BUILD_DEBUG: omitted") | ||||
| #	define GEN_DEBUG_TRAP() | ||||
| #endif | ||||
|  | ||||
| @@ -48,7 +51,7 @@ | ||||
| 		local_persist thread_local                         \ | ||||
| 		char buf[GEN_PRINTF_MAXLEN] = { 0 };               \ | ||||
| 		                                                   \ | ||||
| 		c_str_fmt(buf, GEN_PRINTF_MAXLEN, __VA_ARGS__);      \ | ||||
| 		c_str_fmt(buf, GEN_PRINTF_MAXLEN, __VA_ARGS__);    \ | ||||
| 		GEN_PANIC(buf);                                    \ | ||||
| 	}                                                      \ | ||||
| 	while (0) | ||||
| @@ -57,7 +60,8 @@ | ||||
| #	define GEN_FATAL( ... )                  \ | ||||
| 	do                                       \ | ||||
| 	{                                        \ | ||||
| 		c_str_fmt_out_err( __VA_ARGS__ );      \ | ||||
| 		c_str_fmt_out_err( __VA_ARGS__ );    \ | ||||
| 		GEN_DEBUG_TRAP();                    \ | ||||
| 		process_exit(1);                     \ | ||||
| 	}                                        \ | ||||
| 	while (0) | ||||
|   | ||||
| @@ -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 | ||||
| @@ -69,7 +87,13 @@ | ||||
| #endif | ||||
|  | ||||
| #ifndef do_once | ||||
| #define do_once( statement ) for ( local_persist b32 once = true; once; once = false, (statement) ) | ||||
| #define do_once()                                                               \ | ||||
|     static int __do_once_counter_##__LINE__ = 0;                                \ | ||||
|     for(; __do_once_counter_##__LINE__ != 1; __do_once_counter_##__LINE__ = 1 ) \ | ||||
|  | ||||
| #define do_once_defer( expression )                                                          \ | ||||
|     static int __do_once_counter_##__LINE__ = 0;                                             \ | ||||
|     for(; __do_once_counter_##__LINE__ != 1; __do_once_counter_##__LINE__ = 1, (expression)) \ | ||||
|  | ||||
| #define do_once_start      \ | ||||
| 	do                     \ | ||||
|   | ||||
| @@ -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          } | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| #	include "debug.cpp" | ||||
| #endif | ||||
|  | ||||
| #pragma region StrBuilder Ops | ||||
| #pragma region String Ops | ||||
|  | ||||
| internal | ||||
| ssize _scan_zpl_i64( const char* text, s32 base, s64* value ) | ||||
| @@ -211,4 +211,4 @@ f64 c_str_to_f64( const char* str, char** end_ptr ) | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| #pragma endregion StrBuilder Ops | ||||
| #pragma endregion String Ops | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| #	include "memory.hpp" | ||||
| #endif | ||||
|  | ||||
| #pragma region StrBuilder Ops | ||||
| #pragma region String Ops | ||||
|  | ||||
| const char* char_first_occurence( const char* str, char c ); | ||||
|  | ||||
| @@ -284,4 +284,4 @@ void c_str_to_upper( char* str ) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #pragma endregion StrBuilder Ops | ||||
| #pragma endregion String Ops | ||||
|   | ||||
| @@ -18,8 +18,8 @@ Str         str_visualize_whitespace(Str str, AllocatorInfo allocator); | ||||
| // Constant string with length. | ||||
| struct Str | ||||
| { | ||||
| 	ssize       Len; | ||||
| 	char const* Ptr; | ||||
| 	ssize       Len; | ||||
|  | ||||
| #if GEN_COMPILER_CPP | ||||
| 	forceinline operator char const* ()               const { return Ptr; } | ||||
| @@ -40,9 +40,9 @@ struct Str | ||||
|  | ||||
| #ifndef txt | ||||
| #	if GEN_COMPILER_CPP | ||||
| #		define txt( text )          Str { sizeof( text ) - 1, ( text ) } | ||||
| #		define txt( text )          Str { ( text ), sizeof( text ) - 1 } | ||||
| #	else | ||||
| #		define txt( text )         (Str){ sizeof( text ) - 1, ( text ) } | ||||
| #		define txt( text )         (Str){ ( text ), sizeof( text ) - 1 } | ||||
| #	endif | ||||
| #endif | ||||
|  | ||||
| @@ -103,7 +103,7 @@ b32 str_starts_with(Str str, Str substring) { | ||||
|  | ||||
| inline | ||||
| Str to_str_from_c_str( char const* bad_str ) { | ||||
| 	Str result = { c_str_len( bad_str ), bad_str }; | ||||
| 	Str result = { bad_str, c_str_len( bad_str ) }; | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -170,7 +170,7 @@ struct StrBuilder | ||||
|  | ||||
| 	forceinline operator char*()             { return Data; } | ||||
| 	forceinline operator char const*() const { return Data; } | ||||
| 	forceinline operator Str()         const { return { strbuilder_length(* this), Data }; } | ||||
| 	forceinline operator Str()         const { return { Data, strbuilder_length(* this) }; } | ||||
|  | ||||
| 	StrBuilder const& operator=(StrBuilder const& other) const { | ||||
| 		if (this == &other) | ||||
| @@ -222,31 +222,31 @@ struct StrBuilder | ||||
| 		return strbuilder_make_length(allocator, buf, res); | ||||
| 	} | ||||
|  | ||||
| 	forceinline bool          make_space_for(char const* str, ssize add_len) { return strbuilder_make_space_for(this, str, add_len); } | ||||
| 	forceinline bool          append(char c)                                 { return strbuilder_append_char(this, c); } | ||||
| 	forceinline bool          append(char const* str)                        { return strbuilder_append_c_str(this, str); } | ||||
| 	forceinline bool          append(char const* str, ssize length)          { return strbuilder_append_c_str_len(this, str, length); } | ||||
| 	forceinline bool          append(Str str)                                { return strbuilder_append_str(this, str); } | ||||
| 	forceinline bool          append(const StrBuilder other)                 { return strbuilder_append_string(this, other); } | ||||
| 	forceinline ssize         avail_space() const                            { return strbuilder_avail_space(* this); } | ||||
| 	forceinline char*         back()                                         { return strbuilder_back(* this); } | ||||
| 	forceinline bool          contains(Str substring) const                  { return strbuilder_contains_str(* this, substring); } | ||||
| 	forceinline bool          contains(StrBuilder const& substring) const    { return strbuilder_contains_string(* this, substring); } | ||||
| 	forceinline ssize         capacity() const                               { return strbuilder_capacity(* this); } | ||||
| 	forceinline void          clear()                                        {        strbuilder_clear(* this); } | ||||
| 	forceinline StrBuilder    duplicate(AllocatorInfo allocator) const       { return strbuilder_duplicate(* this, allocator); } | ||||
| 	forceinline void          free()                                         {        strbuilder_free(this); } | ||||
| 	forceinline bool          is_equal(StrBuilder const& other) const        { return strbuilder_are_equal(* this, other); } | ||||
| 	forceinline bool          is_equal(Str other) const                      { return strbuilder_are_equal_str(* this, other); } | ||||
| 	forceinline ssize         length() const                                 { return strbuilder_length(* this); } | ||||
| 	forceinline b32           starts_with(Str substring) const               { return strbuilder_starts_with_str(* this, substring); } | ||||
| 	forceinline b32           starts_with(StrBuilder substring) const        { return strbuilder_starts_with_string(* this, substring); } | ||||
| 	forceinline void          skip_line()                                    {        strbuilder_skip_line(* this); } | ||||
| 	forceinline void          strip_space()                                  {        strbuilder_strip_space(* this); } | ||||
| 	forceinline Str           to_str()                                       { return { strbuilder_length(*this), Data}; } | ||||
| 	forceinline void          trim(char const* cut_set)                      {        strbuilder_trim(* this, cut_set); } | ||||
| 	forceinline void          trim_space()                                   {        strbuilder_trim_space(* this); } | ||||
| 	forceinline StrBuilder    visualize_whitespace() const                   { return strbuilder_visualize_whitespace(* this); } | ||||
| 	forceinline bool              make_space_for(char const* str, ssize add_len) { return strbuilder_make_space_for(this, str, add_len); } | ||||
| 	forceinline bool              append(char c)                                 { return strbuilder_append_char(this, c); } | ||||
| 	forceinline bool              append(char const* str)                        { return strbuilder_append_c_str(this, str); } | ||||
| 	forceinline bool              append(char const* str, ssize length)          { return strbuilder_append_c_str_len(this, str, length); } | ||||
| 	forceinline bool              append(Str str)                                { return strbuilder_append_str(this, str); } | ||||
| 	forceinline bool              append(const StrBuilder other)                 { return strbuilder_append_string(this, other); } | ||||
| 	forceinline ssize             avail_space() const                            { return strbuilder_avail_space(* this); } | ||||
| 	forceinline char*             back()                                         { return strbuilder_back(* this); } | ||||
| 	forceinline bool              contains(Str substring) const                  { return strbuilder_contains_str(* this, substring); } | ||||
| 	forceinline bool              contains(StrBuilder const& substring) const    { return strbuilder_contains_string(* this, substring); } | ||||
| 	forceinline ssize             capacity() const                               { return strbuilder_capacity(* this); } | ||||
| 	forceinline void              clear()                                        {        strbuilder_clear(* this); } | ||||
| 	forceinline StrBuilder        duplicate(AllocatorInfo allocator) const       { return strbuilder_duplicate(* this, allocator); } | ||||
| 	forceinline void              free()                                         {        strbuilder_free(this); } | ||||
| 	forceinline bool              is_equal(StrBuilder const& other) const        { return strbuilder_are_equal(* this, other); } | ||||
| 	forceinline bool              is_equal(Str other) const                      { return strbuilder_are_equal_str(* this, other); } | ||||
| 	forceinline ssize             length() const                                 { return strbuilder_length(* this); } | ||||
| 	forceinline b32               starts_with(Str substring) const               { return strbuilder_starts_with_str(* this, substring); } | ||||
| 	forceinline b32               starts_with(StrBuilder substring) const        { return strbuilder_starts_with_string(* this, substring); } | ||||
| 	forceinline void              skip_line()                                    {        strbuilder_skip_line(* this); } | ||||
| 	forceinline void              strip_space()                                  {        strbuilder_strip_space(* this); } | ||||
| 	forceinline Str               to_str()                                       { return { Data, strbuilder_length(*this) }; } | ||||
| 	forceinline void              trim(char const* cut_set)                      {        strbuilder_trim(* this, cut_set); } | ||||
| 	forceinline void              trim_space()                                   {        strbuilder_trim_space(* this); } | ||||
| 	forceinline StrBuilder        visualize_whitespace() const                   { return strbuilder_visualize_whitespace(* this); } | ||||
| 	forceinline StrBuilderHeader& get_header()                                   { return * strbuilder_get_header(* this); } | ||||
|  | ||||
| 	bool append_fmt(char const* fmt, ...) { | ||||
| @@ -621,7 +621,7 @@ void strip_space(StrBuilder str) | ||||
|  | ||||
| forceinline | ||||
| Str strbuilder_to_str(StrBuilder str) { | ||||
| 	Str result = { strbuilder_length(str), (char const*)str }; | ||||
| 	Str result = { (char const*)str, strbuilder_length(str) }; | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -737,8 +737,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 | ||||
|   | ||||
| 
 | 
| @@ -31,7 +31,6 @@ GEN_NS_BEGIN | ||||
|  | ||||
| #include "components/interface.cpp" | ||||
| #include "components/interface.upfront.cpp" | ||||
| #include "components/gen/etoktype.cpp" | ||||
| #include "components/lexer.cpp" | ||||
| #include "components/parser.cpp" | ||||
| #include "components/interface.parsing.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" | ||||
|   | ||||
| @@ -13,17 +13,17 @@ CodeBody gen_ecode( char const* path, bool use_c_definition = false ) | ||||
| 	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) ); | ||||
| 	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; | ||||
| 		char const* keyword = csv_enum.Col_2[idx].string; | ||||
| 		// TODO(Ed): to_c_str_entries and the others in here didn't have proper sizing of the Str slice. | ||||
| 		strbuilder_append_fmt( & enum_entries,             "CT_%s,\n", code ); | ||||
| 		strbuilder_append_fmt( & to_c_str_entries,         "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); | ||||
| 		strbuilder_append_fmt( & to_keyword_c_str_entries, "{ sizeof(\"%s\") - 1, \"%s\" },\n", keyword, keyword ); | ||||
| 		strbuilder_append_fmt( & to_c_str_entries,         "{ \"%s\",  sizeof(\"%s\") - 1 },\n", code,    code ); | ||||
| 		strbuilder_append_fmt( & to_keyword_c_str_entries, "{  \"%s\", sizeof(\"%s\") - 1 },\n", keyword, keyword ); | ||||
| 	} | ||||
|  | ||||
| 	CodeEnum enum_code; | ||||
| @@ -40,7 +40,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) | ||||
| @@ -97,14 +97,14 @@ CodeBody gen_eoperator( char const* path, bool use_c_definition = false ) | ||||
| 	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 ); | ||||
| 	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; | ||||
| 		char const* entry_to_str = csv_enum.Col_2[idx].string; | ||||
| 		strbuilder_append_fmt( & enum_entries,     "Op_%s,\n", enum_str ); | ||||
| 		strbuilder_append_fmt( & to_c_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||
| 		strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str); | ||||
| 	} | ||||
|  | ||||
| 	CodeEnum  enum_code; | ||||
| @@ -136,7 +136,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 | ||||
| @@ -181,7 +181,7 @@ 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 ); | ||||
| 	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) ); | ||||
|  | ||||
| @@ -190,7 +190,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | ||||
| 		char const* enum_str     = csv_enum.Col_1[idx].string; | ||||
| 		char const* entry_to_str = csv_enum.Col_2[idx].string; | ||||
| 		strbuilder_append_fmt( & enum_entries,     "Spec_%s,\n", enum_str ); | ||||
| 		strbuilder_append_fmt( & to_c_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||
| 		strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str); | ||||
| 	} | ||||
|  | ||||
| 	CodeEnum enum_code; | ||||
| @@ -237,7 +237,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 | ||||
| @@ -267,7 +267,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | ||||
|  | ||||
| 					// We subtract 1 to remove the null terminator | ||||
| 					// This is because the tokens lexed are not null terminated. | ||||
| 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1); | ||||
| 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len  ); | ||||
| 				} | ||||
| 			do_once_end | ||||
|  | ||||
| @@ -317,7 +317,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false ) | ||||
|  | ||||
| CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_definition = false ) | ||||
| { | ||||
| 	FixedArena_64KB scratch; fixed_arena_init(& scratch); | ||||
| 	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 ); | ||||
| @@ -330,15 +330,15 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | ||||
| 	CSV_Object csv_attr_nodes; | ||||
| 	csv_parse( &csv_attr_nodes, rcast(char*, attrib_content.data), scratch_info, false ); | ||||
|  | ||||
| 	Array<ADT_Node> enum_strs          = csv_enum_nodes.nodes[0].nodes; | ||||
| 	Array<ADT_Node> enum_strs            = csv_enum_nodes.nodes[0].nodes; | ||||
| 	Array<ADT_Node> enum_c_str_strs      = csv_enum_nodes.nodes[1].nodes; | ||||
| 	Array<ADT_Node> attribute_strs     = csv_attr_nodes.nodes[0].nodes; | ||||
| 	Array<ADT_Node> attribute_strs       = csv_attr_nodes.nodes[0].nodes; | ||||
| 	Array<ADT_Node> attribute_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 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 to_c_str_attributes      = strbuilder_make_reserve( scratch_info, kilobytes(4) ); | ||||
| 	StrBuilder attribute_define_entries = strbuilder_make_reserve( scratch_info, kilobytes(4) ); | ||||
|  | ||||
| 	for (usize idx = 0; idx < array_num(enum_strs); idx++) | ||||
| @@ -346,8 +346,8 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | ||||
| 		char const* enum_str     = enum_strs[idx].string; | ||||
| 		char const* entry_to_str = enum_c_str_strs [idx].string; | ||||
|  | ||||
| 		strbuilder_append_fmt( & enum_entries, "Tok_%s,\n", enum_str ); | ||||
| 		strbuilder_append_fmt( & to_c_str_entries, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||
| 		strbuilder_append_fmt( & enum_entries,     "Tok_%s,\n",                         enum_str ); | ||||
| 		strbuilder_append_fmt( & to_c_str_entries, "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str); | ||||
| 	} | ||||
|  | ||||
| 	for ( usize idx = 0; idx < array_num(attribute_strs); idx++ ) | ||||
| @@ -355,8 +355,8 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | ||||
| 		char const* attribute_str = attribute_strs[idx].string; | ||||
| 		char const* entry_to_str  = attribute_c_str_strs [idx].string; | ||||
|  | ||||
| 		strbuilder_append_fmt( & attribute_entries, "Tok_Attribute_%s,\n", attribute_str ); | ||||
| 		strbuilder_append_fmt( & to_c_str_attributes, "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||
| 		strbuilder_append_fmt( & attribute_entries,        "Tok_Attribute_%s,\n",               attribute_str ); | ||||
| 		strbuilder_append_fmt( & to_c_str_attributes,      "{ \"%s\", sizeof(\"%s\") - 1 },\n", entry_to_str, entry_to_str); | ||||
| 		strbuilder_append_fmt( & attribute_define_entries, "Entry( Tok_Attribute_%s, \"%s\" )", attribute_str, entry_to_str ); | ||||
|  | ||||
| 		if ( idx < array_num(attribute_strs) - 1 ) | ||||
| @@ -429,7 +429,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path, bool use_c_ | ||||
|  | ||||
| 					// We subtract 1 to remove the null terminator | ||||
| 					// This is because the tokens lexed are not null terminated. | ||||
| 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1); | ||||
| 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len); | ||||
| 				} | ||||
| 			do_once_end | ||||
|  | ||||
| @@ -449,7 +449,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 +458,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; | ||||
| } | ||||
|  | ||||
| @@ -505,7 +503,7 @@ CodeBody gen_ast_inlines() | ||||
| 		{ | ||||
| 			if ( ast == nullptr ) | ||||
| 			{ | ||||
| 				log_failure( "Attempt to dereference a nullptr!" ); | ||||
| 				log_failure( "Attempt to dereference a nullptr!\n" ); | ||||
| 				return nullptr; | ||||
| 			} | ||||
| 			return ast; | ||||
|   | ||||
| @@ -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 ); | ||||
|   | ||||
| @@ -46,13 +46,13 @@ The C/C++ interface procedures are located with `ast.hpp` (for the Code type), a | ||||
| All code types can either serialize using a function of the pattern: | ||||
|  | ||||
| ```c | ||||
| StrBuilder <prefix>_to_string(Code code); | ||||
| StrBuilder <prefix>_to_strbuilder(Code code); | ||||
| // or | ||||
| <prefix>_to_string(Code code, StrBuilder& result); | ||||
| <prefix>_to_strbuilder(Code code, StrBuilder& result); | ||||
| ``` | ||||
|  | ||||
| Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator. | ||||
|  | ||||
| Serialization of for the AST is defined for `Code` in [`ast.chpp`](../base/components/ast.cpp) with `code_to_strbuilder_ptr` & `code_to_string`.   | ||||
| Serialization of for the AST is defined for `Code` in [`ast.chpp`](../base/components/ast.cpp) with `code_to_strbuilder_ptr` & `code_to_strbuilder`.   | ||||
| Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).   | ||||
| Gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after serializing. | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
| @@ -18,6 +18,6 @@ If using the library's provided build scripts: | ||||
| .\build.ps1 <compiler> <debug or omit> c_library | ||||
| ``` | ||||
|  | ||||
| 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. | ||||
| 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.** | ||||
|   | ||||
| @@ -62,20 +62,21 @@ 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")); | ||||
| 	ctx.PreprocessorDefines.append(txt("GEN_API_C_BEGIN")); | ||||
| 	ctx.PreprocessorDefines.append(txt("GEN_API_C_END")); | ||||
| 	ctx.PreprocessorDefines.append(txt("Array(")); | ||||
| 	ctx.PreprocessorDefines.append(txt("HashTable(")); | ||||
| 	ctx.PreprocessorDefines.append(txt("GEN_NS_PARSER")); | ||||
| 	ctx.PreprocessorDefines.append(txt("GEN_NS_PARSER_BEGIN")); | ||||
| 	ctx.PreprocessorDefines.append(txt("GEN_NS_PARSER_END")); | ||||
| 	ctx.PreprocessorDefines.append(txt("Using_Code(")); | ||||
| 	ctx.PreprocessorDefines.append(txt("Using_CodeOps(")); | ||||
| 	ctx.PreprocessorDefines.append(txt("GEN_OPTIMIZE_MAPPINGS_BEGIN")); | ||||
| 	ctx.PreprocessorDefines.append(txt("GEN_OPITMIZE_MAPPINGS_END")); | ||||
| 	ctx.PreprocessorDefines.append(txt("GEN_PARAM_DEFAULT")); | ||||
| 	//PreprocessorDefines.append(txt("GEN_EXECUTION_EXPRESSION_SUPPORT")); | ||||
|  | ||||
| 	Code push_ignores           = scan_file( path_base "helpers/push_ignores.inline.hpp" ); | ||||
| @@ -126,7 +127,7 @@ int gen_main() | ||||
| 			if (fn->Specs) { | ||||
| 				s32 constexpr_found = fn->Specs.remove( Spec_Constexpr ); | ||||
| 				if (constexpr_found > -1) { | ||||
| 					//log_fmt("Found constexpr: %SB\n", entry.to_string()); | ||||
| 					//log_fmt("Found constexpr: %SB\n", entry.to_strbuilder()); | ||||
| 					fn->Specs.append(Spec_Inline); | ||||
| 				} | ||||
| 			} | ||||
| @@ -253,7 +254,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); | ||||
| @@ -549,9 +550,9 @@ do                          \ | ||||
| 			{ | ||||
| 				CodeTypename type       = using_ver->UnderlyingType; | ||||
| 				CodeTypedef typedef_ver = parse_typedef(token_fmt( | ||||
| 					"ReturnType", to_string(type->ReturnType).to_str() | ||||
| 					"ReturnType", to_strbuilder(type->ReturnType).to_str() | ||||
| 				,	"Name"      , using_ver->Name | ||||
| 				,	"Parameters", to_string(type->Params).to_str() | ||||
| 				,	"Parameters", to_strbuilder(type->Params).to_str() | ||||
| 				,	stringize( | ||||
| 						typedef <ReturnType>( * <Name>)(<Parameters>); | ||||
| 				))); | ||||
| @@ -588,8 +589,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); | ||||
| @@ -646,10 +741,10 @@ do                          \ | ||||
| 					if (fn->Name.starts_with(txt("code_"))) | ||||
| 					{ | ||||
| 						Str   old_prefix  = txt("code_"); | ||||
| 						Str   actual_name = { fn->Name.Len  - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; | ||||
| 						StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name ); | ||||
| 						Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len }; | ||||
| 						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); | ||||
| @@ -694,7 +789,7 @@ do                          \ | ||||
|  | ||||
| 			s32 constexpr_found = var->Specs ? var->Specs.remove( Spec_Constexpr ) : - 1; | ||||
| 			if (constexpr_found > -1) { | ||||
| 				//log_fmt("Found constexpr: %SB\n", entry.to_string()); | ||||
| 				//log_fmt("Found constexpr: %SB\n", entry.to_strbuilder()); | ||||
| 				if (var->Name.contains(txt("AST_ArrSpecs_Cap"))) | ||||
| 				{ | ||||
| 					Code def = untyped_str(txt( | ||||
| @@ -702,7 +797,7 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| (                           \ | ||||
| 	AST_POD_Size              \ | ||||
| 	- sizeof(Code)            \ | ||||
| 	- sizeof(StringCached)    \ | ||||
| 	- sizeof(StrCached)    \ | ||||
| 	- sizeof(Code) * 2        \ | ||||
| 	- sizeof(Token*)          \ | ||||
| 	- sizeof(Code)            \ | ||||
| @@ -716,7 +811,7 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| 					ast.append(def); | ||||
| 					break; | ||||
| 				} | ||||
| 				CodeDefine def = def_define(var->Name, var->Value.to_string()); | ||||
| 				CodeDefine def = def_define(var->Name, var->Value.to_strbuilder()); | ||||
| 				ast.append(def); | ||||
| 				break; | ||||
| 			} | ||||
| @@ -791,17 +886,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.Len - private_prefix.Len, fn->Name.Ptr + private_prefix.Len }; | ||||
| 				StrBuilder interface_name  = StrBuilder::fmt_buf(GlobalAllocator, "code_%S", actual_name ); | ||||
| 				Str   actual_name     = { fn->Name.Ptr + private_prefix.Len, fn->Name.Len - private_prefix.Len }; | ||||
| 				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 +1005,9 @@ 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 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 ) | ||||
| @@ -931,8 +1029,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
|  | ||||
| 			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()); | ||||
| 				StrBuilder postfix_arr = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%S_arr", entry->Name); | ||||
| 				entry->Name = cache_str(postfix_arr.to_str()); | ||||
| 				postfix_arr.free(); | ||||
| 			} | ||||
|  | ||||
| @@ -941,12 +1039,12 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 			{ | ||||
| 				// Convert the definition to use a default struct: https://vxtwitter.com/vkrajacic/status/1749816169736073295 | ||||
| 				Str prefix      = txt("def_"); | ||||
| 				Str actual_name = { fn->Name.Len  - prefix.Len, fn->Name.Ptr + prefix.Len }; | ||||
| 				Str new_name    = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str(); | ||||
| 				Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len  - prefix.Len }; | ||||
| 				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 +1068,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) { | ||||
| @@ -1020,10 +1118,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 			if (fn->Name.starts_with(txt("code_"))) | ||||
| 			{ | ||||
| 				Str   old_prefix  = txt("code_"); | ||||
| 				Str   actual_name = { fn->Name.Len  - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; | ||||
| 				StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name ); | ||||
| 				Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len }; | ||||
| 				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); | ||||
| 		} | ||||
| @@ -1142,10 +1240,6 @@ 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" ); | ||||
| @@ -1175,10 +1269,10 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 			if (fn->Name.starts_with(txt("code_"))) | ||||
| 			{ | ||||
| 				Str   old_prefix  = txt("code_"); | ||||
| 				Str   actual_name = { fn->Name.Len  - old_prefix.Len, fn->Name.Ptr + old_prefix.Len }; | ||||
| 				StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name ); | ||||
| 				Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len }; | ||||
| 				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); | ||||
| 		} | ||||
| @@ -1219,18 +1313,18 @@ R"(#define <interface_name>( code ) _Generic( (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()); | ||||
| 					StrBuilder postfix_arr = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "%S_arr", fn->Name); | ||||
| 					fn->Name = cache_str(postfix_arr.to_str()); | ||||
| 					postfix_arr.free(); | ||||
| 				} | ||||
|  | ||||
| 			for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_"))) | ||||
| 			{ | ||||
| 				Str prefix      = txt("def_"); | ||||
| 				Str actual_name = { fn->Name.Len  - prefix.Len, fn->Name.Ptr + prefix.Len }; | ||||
| 				Str new_name    = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str(); | ||||
| 				Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len  - prefix.Len }; | ||||
| 				Str new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str(); | ||||
|  | ||||
| 				fn->Name = get_cached_string(new_name); | ||||
| 				fn->Name = cache_str(new_name); | ||||
| 			} | ||||
|  | ||||
| 			src_upfront.append(fn); | ||||
| @@ -1267,51 +1361,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); | ||||
| @@ -1319,7 +1368,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 				Code define_ver = untyped_str(token_fmt( | ||||
| 						"name",  var->Name | ||||
| 					,	"value", var->Value->Content | ||||
| 					,	"type",  var->ValueType.to_string().to_str() | ||||
| 					,	"type",  var->ValueType.to_strbuilder().to_str() | ||||
| 					,	"#define <name> (<type>) <value>\n" | ||||
| 				)); | ||||
| 				src_lexer.append(define_ver); | ||||
| @@ -1364,7 +1413,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 				Code define_ver = untyped_str(token_fmt( | ||||
| 						"name",  var->Name | ||||
| 					,	"value", var->Value->Content | ||||
| 					,	"type",  var->ValueType.to_string().to_str() | ||||
| 					,	"type",  var->ValueType.to_strbuilder().to_str() | ||||
| 					,	"#define <name> (<type>) <value>\n" | ||||
| 				)); | ||||
| 				src_parser.append(define_ver); | ||||
| @@ -1416,13 +1465,14 @@ 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); | ||||
| @@ -1481,9 +1531,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( r_header_macros ); | ||||
| 		header.print( header_generic_macros ); | ||||
|  | ||||
| 		header.print_fmt( "GEN_API_C_BEGIN\n" ); | ||||
|  | ||||
| 		header.print( r_header_basic_types ); | ||||
| 		header.print( r_header_debug ); | ||||
| 		header.print( rf_header_memory ); | ||||
| @@ -1497,7 +1549,8 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 		header.print( r_header_timing ); | ||||
| 		header.print(rf_header_parsing ); | ||||
|  | ||||
| 		header.print_fmt( "\nGEN_NS_END\n" ); | ||||
| 		header.print_fmt( "\nGEN_API_C_END\n" ); | ||||
| 		header.print_fmt( "GEN_NS_END\n" ); | ||||
| 		header.print_fmt( roll_own_dependencies_guard_end ); | ||||
| 	#pragma endregion Print Dependencies | ||||
|  | ||||
| @@ -1515,6 +1568,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"); | ||||
| @@ -1523,6 +1578,13 @@ 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( rf_interface ); | ||||
| 		header.print(fmt_newline); | ||||
|  | ||||
| @@ -1531,7 +1593,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 ); | ||||
| @@ -1548,7 +1609,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
|  | ||||
| 	#pragma region Print Dependencies | ||||
| 		header.print_fmt( roll_own_dependencies_guard_start ); | ||||
| 		header.print_fmt( "GEN_NS_BEGIN\n"); | ||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | ||||
| 		header.print_fmt( "GEN_API_C_BEGIN\n" ); | ||||
|  | ||||
| 		header.print( r_src_dep_start ); | ||||
| @@ -1562,17 +1623,14 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 		header.print( r_src_timing ); | ||||
| 		header.print( rf_src_parsing ); | ||||
|  | ||||
| 		header.print_fmt( "\nGEN_API_C_END\n" ); | ||||
| 		header.print_fmt( "GEN_NS_END\n"); | ||||
| 		header.print_fmt( roll_own_dependencies_guard_end ); | ||||
| 	#pragma endregion Print Dependencies | ||||
|  | ||||
| 	#pragma region Print Components | ||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | ||||
|  | ||||
| 		header.print( fmt_newline); | ||||
| 		header.print( rf_array_arena ); | ||||
| 		header.print( fmt_newline); | ||||
| 		header.print( rf_array_pool); | ||||
| 		header.print_fmt( "GEN_API_C_BEGIN\n" ); | ||||
|  | ||||
| 		header.print( r_src_static_data ); | ||||
| 		header.print( fmt_newline); | ||||
| @@ -1587,7 +1645,6 @@ 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 ); | ||||
| @@ -1596,12 +1653,13 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 		header.print( r_src_parsing ); | ||||
| 		header.print_fmt( "\n#pragma endregion Parsing\n" ); | ||||
| 		header.print( r_src_untyped ); | ||||
| 		header.print_fmt( "\n#pragma endregion Interface\n\n"); | ||||
| 		header.print_fmt( "\n#pragma endregion Interface\n"); | ||||
|  | ||||
| 		header.print( rf_src_builder ); | ||||
| 		header.print( rf_src_scanner ); | ||||
|  | ||||
| 		header.print_fmt( "GEN_API_C_END\n" ); | ||||
| 		header.print_fmt( "\nGEN_API_C_END\n" ); | ||||
| 		header.print_fmt( "GEN_NS_END\n"); | ||||
| 	#pragma endregion Print Components | ||||
|  | ||||
| 		header.print_fmt( implementation_guard_end ); | ||||
| @@ -1641,7 +1699,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" ); | ||||
| @@ -1679,6 +1736,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"); | ||||
| @@ -1732,7 +1791,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 ); | ||||
| @@ -1746,11 +1804,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; | ||||
| } | ||||
|   | ||||
| @@ -173,7 +173,7 @@ word PrintF_Buffer,     gen_PrintF_Buffer | ||||
| word Msg_Invalid_Value, gen_Msg_Invalid_Value | ||||
| word log_fmt,           gen_log_fmt | ||||
|  | ||||
| // StrBuilder Ops | ||||
| // String Ops | ||||
|  | ||||
| namespace char_, gen_char_ | ||||
|  | ||||
| @@ -224,7 +224,7 @@ word StrBuilder,       gen_StrBuilder | ||||
|  | ||||
| namespace strbuilder_, gen_strbuilder_ | ||||
|  | ||||
| word StringCached, gen_StringCached | ||||
| word StrCached, gen_StrCached | ||||
|  | ||||
| word StringTable, gen_StringTable | ||||
|  | ||||
| @@ -401,7 +401,7 @@ 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 +414,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,28 +432,17 @@ 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 | ||||
| namespace builder_, gen_builder_ | ||||
|  | ||||
| // Scanner | ||||
|  | ||||
| word scan_file, gen_scan_file | ||||
|  | ||||
| // Implementation (prviate) | ||||
|  | ||||
| word _format_info, gen__format_info | ||||
| @@ -514,7 +489,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 | ||||
|  | ||||
| @@ -523,7 +498,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_ | ||||
|   | ||||
| @@ -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" ) | ||||
| @@ -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 | ||||
| 	)); | ||||
| }; | ||||
|   | ||||
| @@ -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 | ||||
| 	)); | ||||
| } | ||||
|   | ||||
| @@ -84,7 +84,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 +104,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 +147,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 +211,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; | ||||
|   | ||||
							
								
								
									
										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" ); | ||||
| @@ -171,7 +178,7 @@ int gen_main() | ||||
| 		builder_print_fmt( header, "#pragma endregion Inlines\n" ); | ||||
|  | ||||
| 		builder_print( header, header_end ); | ||||
| 		builder_print_fmt( header, "GEN_NS_END\n\n" ); | ||||
| 		builder_print_fmt( header, "\nGEN_NS_END\n\n" ); | ||||
| 		builder_print( header, pop_ignores ); | ||||
| 		builder_write(header); | ||||
| 	} | ||||
| @@ -190,12 +197,6 @@ int gen_main() | ||||
| 		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,7 +216,6 @@ 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 ); | ||||
| 		builder_print( src, parsing_interface ); | ||||
| @@ -238,7 +238,7 @@ int gen_main() | ||||
| 		builder_print( & header, def_include( txt("gen.hpp") )); | ||||
| 		builder_print_fmt( & header, "\nGEN_NS_BEGIN\n" ); | ||||
| 		builder_print( & header, builder ); | ||||
| 		builder_print_fmt( & header, "GEN_NS_END\n" ); | ||||
| 		builder_print_fmt( & header, "\nGEN_NS_END\n" ); | ||||
| 		builder_write( & header); | ||||
| 	} | ||||
|  | ||||
| @@ -278,10 +278,10 @@ int gen_main() | ||||
| 		builder_print( & src, def_include( txt("gen.scanner.hpp") ) ); | ||||
| 		builder_print_fmt( & src, "\nGEN_NS_BEGIN\n" ); | ||||
| 		builder_print( & src, scanner ); | ||||
| 		builder_print_fmt( & src, "GEN_NS_END\n" ); | ||||
| 		builder_print_fmt( & src, "\nGEN_NS_END\n" ); | ||||
| 		builder_write( & src); | ||||
| 	} | ||||
|  | ||||
| 	gen::deinit(); | ||||
| 	gen::deinit( & ctx); | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
| @@ -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" ); | ||||
| @@ -105,22 +106,25 @@ int gen_main() | ||||
| 				header.print( scan_file( path_base "dependencies/parsing.hpp" ) ); | ||||
| 			} | ||||
|  | ||||
| 			header.print(fmt_newline); | ||||
| 			header.print_fmt( "GEN_NS_END\n" ); | ||||
| 			header.print_fmt( roll_own_dependencies_guard_end ); | ||||
| 			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" ); | ||||
| @@ -134,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"); | ||||
| @@ -155,7 +162,11 @@ int gen_main() | ||||
| 		if ( generate_builder ) { | ||||
| 			header.print( scan_file( path_base "auxillary/builder.hpp" ) ); | ||||
| 		} | ||||
| 		if ( generate_scanner ) { | ||||
| 			header.print( scan_file( path_base "auxillary/scanner.hpp" ) ); | ||||
| 		} | ||||
|  | ||||
| 		header.print(fmt_newline); | ||||
| 		header.print_fmt( "GEN_NS_END\n" ); | ||||
| 	} | ||||
|  | ||||
| @@ -176,9 +187,10 @@ int gen_main() | ||||
| 			Code timing     = scan_file( path_base "dependencies/timing.cpp" ); | ||||
|  | ||||
| 			header.print_fmt( roll_own_dependencies_guard_start ); | ||||
| 			header.print_fmt( "GEN_NS_BEGIN\n\n"); | ||||
|  | ||||
| 			header.print( impl_start ); | ||||
| 			header.print( fmt_newline ); | ||||
| 			header.print_fmt( "GEN_NS_BEGIN\n"); | ||||
|  | ||||
| 			header.print( debug ); | ||||
| 			header.print( string_ops ); | ||||
| 			header.print( printing ); | ||||
| @@ -209,11 +221,9 @@ int gen_main() | ||||
| 		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" ); | ||||
| 		CodeNS   parser_nspace = def_namespace( name(parser), def_namespace_body( args(etoktype)) ); | ||||
|  | ||||
| 		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 ); | ||||
| @@ -225,27 +235,24 @@ int gen_main() | ||||
| 		header.print( interface ); | ||||
| 		header.print( upfront ); | ||||
| 		header.print_fmt( "\n#pragma region Parsing\n\n" ); | ||||
| 		header.print( format(parser_nspace) ); | ||||
| 		header.print( lexer ); | ||||
| 		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 Interface\n\n"); | ||||
| 		header.print_fmt("\n#pragma endregion Untyped\n"); | ||||
| 		header.print_fmt( "\n#pragma endregion Interface\n"); | ||||
|  | ||||
| 		if ( generate_builder ) { | ||||
| 			header.print( scan_file( path_base "auxillary/builder.cpp"  ) ); | ||||
| 		} | ||||
|  | ||||
| 		// Scanner header depends on implementation | ||||
| 		if ( generate_scanner ) { | ||||
| 			header.print( scan_file( path_base "auxillary/scanner.hpp" ) ); | ||||
| 		} | ||||
|  | ||||
| 		if ( generate_scanner ) { | ||||
| 			header.print( scan_file( path_base "auxillary/scanner.cpp" ) ); | ||||
| 		} | ||||
|  | ||||
| 		header.print( fmt_newline); | ||||
| 		header.print_fmt( "GEN_NS_END\n"); | ||||
|  | ||||
| 		header.print_fmt( "%s\n", (char const*) implementation_guard_end ); | ||||
| @@ -254,6 +261,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.20-Alpha | | ||||
| 	! ============================================================================================ | | ||||
| 	! WARNING: THIS IS AN ALPHA VERSION OF THE LIBRARY, USE AT YOUR OWN DISCRETION                 | | ||||
| 	! NEVER DO CODE GENERATION WITHOUT AT LEAST HAVING CONTENT IN A CODEBASE UNDER VERSION CONTROL | | ||||
| 	! ============================================================================================ / | ||||
| */ | ||||
| #if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME) | ||||
| #	error Gen.hpp : GEN_TIME not defined | ||||
|   | ||||
| @@ -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" ); | ||||
| @@ -67,8 +68,8 @@ int gen_main() | ||||
| 	{ | ||||
| 		CodeBody macros = def_body( CT_Global_Body ); | ||||
| 		{ | ||||
| 			FileContents content    = file_read_contents( GlobalAllocator, true, path_base "dependencies/macros.hpp" ); | ||||
| 			CodeBody     ori_macros = parse_global_body( Str { content.size, (char const*)content.data }); | ||||
| 			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(); | ||||
| 						code != ori_macros.end(); | ||||
| @@ -175,6 +176,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" ); | ||||
| @@ -187,6 +189,11 @@ int gen_main() | ||||
| 		CodeBody especifier  = gen_especifier( path_base "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( path_base "enums/ETokType.csv", "enums/AttributeTokens.csv" ); | ||||
|  | ||||
| 		Builder | ||||
| 		header = Builder::open( "gen/gen.hpp" ); | ||||
| 		header.print_fmt( generation_notice ); | ||||
| @@ -205,6 +212,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" ); | ||||
| @@ -223,14 +232,14 @@ int gen_main() | ||||
| 		header.print_fmt( "#pragma endregion Inlines\n" ); | ||||
|  | ||||
| 		header.print( header_end ); | ||||
| 		header.print_fmt( "GEN_NS_END\n\n" ); | ||||
| 		header.print_fmt( "\nGEN_NS_END\n\n" ); | ||||
| 		header.print( pop_ignores ); | ||||
| 		header.write(); | ||||
| 	} | ||||
|  | ||||
| 	// 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" ); | ||||
| @@ -242,11 +251,6 @@ int gen_main() | ||||
| 		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 ); | ||||
| @@ -268,7 +272,6 @@ int gen_main() | ||||
| 		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 ); | ||||
| 		src.print( parsing_interface ); | ||||
| @@ -294,7 +297,7 @@ int gen_main() | ||||
| 		header.print( def_include( txt("gen.hpp") )); | ||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n" ); | ||||
| 		header.print( builder ); | ||||
| 		header.print_fmt( "GEN_NS_END\n" ); | ||||
| 		header.print_fmt( "\nGEN_NS_END\n" ); | ||||
| 		header.print( fmt_newline ); | ||||
| 		header.print( pop_ignores ); | ||||
| 		header.write(); | ||||
| @@ -333,7 +336,7 @@ int gen_main() | ||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n" ); | ||||
| 		header.print( parsing ); | ||||
| 		header.print( scanner ); | ||||
| 		header.print_fmt( "GEN_NS_END\n" ); | ||||
| 		header.print_fmt( "\nGEN_NS_END\n" ); | ||||
| 		header.print( fmt_newline ); | ||||
| 		header.print( pop_ignores ); | ||||
| 		header.write(); | ||||
| @@ -353,7 +356,7 @@ int gen_main() | ||||
| 		src.print_fmt( "\nGEN_NS_BEGIN\n" ); | ||||
| 		src.print( parsing ); | ||||
| 		// src.print( scanner ); | ||||
| 		src.print_fmt( "GEN_NS_END\n" ); | ||||
| 		src.print_fmt( "\nGEN_NS_END\n" ); | ||||
| 		src.print( fmt_newline ); | ||||
| 		src.print( pop_ignores ); | ||||
| 		src.write(); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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,47 +325,24 @@ if ( $unreal ) | ||||
| 	. $refactor_unreal | ||||
| } | ||||
|  | ||||
| # TODO(Ed): The unit testing needs a full rewrite | ||||
| if ( $test -and $false ) | ||||
| if ( $test ) | ||||
| { | ||||
| 	$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_lib = join-path $path_test       c_library | ||||
| 	$path_build      = join-path $path_test_c_lib build | ||||
|  | ||||
| 	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 | ||||
| 	} | ||||
| 	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 | ||||
| 	} | ||||
|  | ||||
| 	$path_bootstrap = join-path $path_project gen | ||||
|  | ||||
| 	$includes    = @( $path_bootstrap ) | ||||
| 	$unit       = join-path $path_test  "test.cpp" | ||||
| 	$executable = join-path $path_build "test.exe" | ||||
| 	$includes    = @( $path_c_library ) | ||||
| 	$unit       = join-path $path_test_c_lib "gen.c" | ||||
| 	$executable = join-path $path_build      "gen_c_library_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 | ||||
| @@ -363,16 +350,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_c_lib | ||||
| 		if ( Test-Path( $executable ) ) { | ||||
| 			write-host "`nRunning test generator" | ||||
| 			write-host "`nRunning c_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 | ||||
| } | ||||
|   | ||||
| @@ -21,7 +21,7 @@ | ||||
| 		<Action>NoStepInto</Action> | ||||
| 	</Function> | ||||
| 	<Function> | ||||
| 		<Name>gen::Code.*::to_string</Name> | ||||
| 		<Name>gen::Code.*::to_strbuilder</Name> | ||||
| 		<Action>NoStepInto</Action> | ||||
| 	</Function> | ||||
| 	<Function> | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| #define GEN_IMPLEMENTATION | ||||
| #include "gen/gen.c" | ||||
| #include "gen/gen_singleheader.h" | ||||
| 
 | ||||
| int main() | ||||
| int gen_main() | ||||
| { | ||||
| 	// init();
 | ||||
| 	__debugbreak(); | ||||
| 	return 0; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user