mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-29 14:00:52 -07:00 
			
		
		
		
	Compare commits
	
		
			7 Commits
		
	
	
		
			string_dis
			...
			v0.22-Alph
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 967a044637 | |||
| b5cf633e98 | |||
| 16d0e0834f | |||
| 76ac3a0f93 | |||
| 78bcc21130 | |||
| a125653448 | |||
| aa2170ba80 | 
							
								
								
									
										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, | ||||
|   | ||||
| @@ -150,7 +150,7 @@ The convention you'll see used throughout the upfront interface of the library i | ||||
| 3. Populate immediate fields (Name, Type, ModuleFlags, etc) | ||||
| 4. Populate sub-entires using `add_entry`. If using the default serialization function `to_strbuilder`, follow the order at which entires are expected to appear (there is a strong ordering expected). | ||||
|  | ||||
| Names or Content fields are interned strings and thus showed be cached using `get_cached_string` if its desired to preserve that behavior. | ||||
| Names or Content fields are interned strings and thus showed be cached using `cache_str` if its desired to preserve that behavior. | ||||
|  | ||||
| `def_operator` is the most sophisticated upfront constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid. | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,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; | ||||
|   | ||||
| @@ -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,7 +117,7 @@ Code scan_file( char const* path ) | ||||
| } | ||||
|  | ||||
| CodeBody parse_file( const char* path ) { | ||||
| 	FileContents file    = file_read_contents( GlobalAllocator, true, path ); | ||||
| 	FileContents file    = file_read_contents( _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); | ||||
|   | ||||
| @@ -27,7 +27,8 @@ constexpr char const* generation_notice = | ||||
|  | ||||
| int gen_main() | ||||
| { | ||||
| 	gen::init(); | ||||
| 	gen::Context ctx {}; | ||||
| 	gen::init( & ctx); | ||||
|  | ||||
| 	CodeBody gen_component_header = def_global_body( args( | ||||
| 		def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ), | ||||
| @@ -59,7 +60,7 @@ int gen_main() | ||||
| 	builder_print( & header_especifier, format(especifier) ); | ||||
| 	builder_write( & header_especifier); | ||||
| 	 | ||||
| 	Builder header_etoktype = builder_open( "components/gen/etoktype.cpp" ); | ||||
| 	Builder header_etoktype = builder_open( "components/gen/etoktype.hpp" ); | ||||
| 	builder_print( & header_etoktype, gen_component_header ); | ||||
| 	builder_print( & header_etoktype, format(etoktype) ); | ||||
| 	builder_write( & header_etoktype); | ||||
| @@ -69,6 +70,6 @@ int gen_main() | ||||
| 	builder_print( & header_ast_inlines, format(ast_inlines) ); | ||||
| 	builder_write( & header_ast_inlines); | ||||
|  | ||||
| 	gen::deinit(); | ||||
| 	gen::deinit(& ctx); | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
| @@ -3,14 +3,11 @@ | ||||
| #include "static_data.cpp" | ||||
| #endif | ||||
|  | ||||
| global Code Code_Global; | ||||
| global Code Code_Invalid; | ||||
|  | ||||
| // This serializes all the data-members in a "debug" format, where each member is printed with its associated value. | ||||
| Str code_debug_str(Code self) | ||||
| { | ||||
| 	GEN_ASSERT(self != nullptr); | ||||
| 	StrBuilder  result_stack = strbuilder_make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
| 	StrBuilder  result_stack = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(1) ); | ||||
| 	StrBuilder* result       = & result_stack; | ||||
|  | ||||
| 	if ( self->Parent ) | ||||
| @@ -372,7 +369,7 @@ Code code_duplicate(Code self) | ||||
|  | ||||
| StrBuilder code_to_strbuilder(Code self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_str( GlobalAllocator, txt("") ); | ||||
| 	StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") ); | ||||
| 	code_to_strbuilder_ptr( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -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; | ||||
| @@ -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 )                                                                \ | ||||
| @@ -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_strbuilder    (Code self ); | ||||
| void       code_to_strbuilder_ptr(Code self, StrBuilder* result ); | ||||
| Str        code_type_str         (Code self ); | ||||
| bool       code_validate_body    (Code self ); | ||||
| GEN_API void       code_append           (Code code, Code other ); | ||||
| GEN_API Str        code_debug_str        (Code code); | ||||
| GEN_API Code       code_duplicate        (Code code); | ||||
| GEN_API Code*      code_entry            (Code code, u32 idx ); | ||||
| GEN_API bool       code_has_entries      (Code code); | ||||
| GEN_API bool       code_is_body          (Code code); | ||||
| GEN_API bool       code_is_equal         (Code code, Code other); | ||||
| GEN_API bool       code_is_valid         (Code code); | ||||
| GEN_API void       code_set_global       (Code code); | ||||
| GEN_API StrBuilder code_to_strbuilder    (Code self ); | ||||
| GEN_API void       code_to_strbuilder_ptr(Code self, StrBuilder* result ); | ||||
| GEN_API Str        code_type_str         (Code self ); | ||||
| GEN_API bool       code_validate_body    (Code self ); | ||||
|  | ||||
| #pragma endregion Code C-Interface | ||||
|  | ||||
| @@ -368,7 +353,7 @@ int AST_ArrSpecs_Cap = | ||||
| ( | ||||
| 	AST_POD_Size | ||||
| 	- sizeof(Code) | ||||
| 	- sizeof(StringCached) | ||||
| 	- sizeof(StrCached) | ||||
| 	- sizeof(Code) * 2 | ||||
| 	- sizeof(Token*) | ||||
| 	- sizeof(Code) | ||||
| @@ -414,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; | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
| inline | ||||
| StrBuilder attributes_to_strbuilder(CodeAttributes attributes) { | ||||
| 	GEN_ASSERT(attributes); | ||||
| 	char* raw = ccast(char*, str_duplicate( attributes->Content, GlobalAllocator ).Ptr); | ||||
| 	char* raw = ccast(char*, str_duplicate( attributes->Content, _ctx->Allocator_Temp ).Ptr); | ||||
| 	StrBuilder result = { raw }; | ||||
| 	return result; | ||||
| } | ||||
| @@ -21,7 +21,7 @@ void attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result) | ||||
| StrBuilder body_to_strbuilder(CodeBody body) | ||||
| { | ||||
| 	GEN_ASSERT(body); | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | ||||
| 	switch ( body->Type ) | ||||
| 	{ | ||||
| 		case CT_Untyped: | ||||
| @@ -82,7 +82,7 @@ void body_to_strbuilder_export( CodeBody body, StrBuilder* result ) | ||||
| inline | ||||
| StrBuilder comment_to_strbuilder(CodeComment comment) { | ||||
| 	GEN_ASSERT(comment); | ||||
| 	char* raw = ccast(char*, str_duplicate( comment->Content, GlobalAllocator ).Ptr); | ||||
| 	char* raw = ccast(char*, str_duplicate( comment->Content, _ctx->Allocator_Temp ).Ptr); | ||||
| 	StrBuilder result = { raw }; | ||||
| 	return result; | ||||
| } | ||||
| @@ -96,7 +96,7 @@ void comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result) { | ||||
|  | ||||
| StrBuilder constructor_to_strbuilder(CodeConstructor self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | ||||
| 	switch (self->Type) | ||||
| 	{ | ||||
| 		case CT_Constructor: | ||||
| @@ -159,7 +159,7 @@ void constructor_to_strbuilder_fwd(CodeConstructor self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder class_to_strbuilder( CodeClass self ) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Class: | ||||
| @@ -241,7 +241,7 @@ void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder define_to_strbuilder(CodeDefine define) | ||||
| { | ||||
| 	return strbuilder_fmt_buf( GlobalAllocator, "#define %S %S", define->Name, define->Content ); | ||||
| 	return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#define %S %S", define->Name, define->Content ); | ||||
| } | ||||
|  | ||||
| void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result ) | ||||
| @@ -251,7 +251,7 @@ void define_to_strbuilder_ref(CodeDefine define, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder destructor_to_strbuilder(CodeDestructor self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Destructor: | ||||
| @@ -308,7 +308,7 @@ void destructor_to_strbuilder_fwd(CodeDestructor self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder enum_to_strbuilder(CodeEnum self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Enum: | ||||
| @@ -443,7 +443,7 @@ void enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result ) | ||||
| StrBuilder exec_to_strbuilder(CodeExec exec) | ||||
| { | ||||
| 	GEN_ASSERT(exec); | ||||
| 	char* raw = ccast(char*, str_duplicate( exec->Content, GlobalAllocator ).Ptr); | ||||
| 	char* raw = ccast(char*, str_duplicate( exec->Content, _ctx->Allocator_Temp ).Ptr); | ||||
| 	StrBuilder result = { raw }; | ||||
| 	return result; | ||||
| } | ||||
| @@ -458,7 +458,7 @@ void extern_to_strbuilder(CodeExtern self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder include_to_strbuilder(CodeInclude include) | ||||
| { | ||||
| 	return strbuilder_fmt_buf( GlobalAllocator, "#include %S\n", include->Content ); | ||||
| 	return strbuilder_fmt_buf( _ctx->Allocator_Temp, "#include %S\n", include->Content ); | ||||
| } | ||||
|  | ||||
| void include_to_strbuilder_ref( CodeInclude include, StrBuilder* result ) | ||||
| @@ -468,7 +468,7 @@ void include_to_strbuilder_ref( CodeInclude include, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder friend_to_strbuilder(CodeFriend self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 256 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 ); | ||||
| 	friend_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -490,7 +490,7 @@ void friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder fn_to_strbuilder(CodeFn self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Function: | ||||
| @@ -621,7 +621,7 @@ void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder module_to_strbuilder(CodeModule self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 64 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 ); | ||||
| 	module_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -639,7 +639,7 @@ void module_to_strbuilder_ref(CodeModule self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder namespace_to_strbuilder(CodeNS self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 ); | ||||
| 	namespace_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -654,7 +654,7 @@ void namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder code_op_to_strbuilder(CodeOperator self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Operator: | ||||
| @@ -776,7 +776,7 @@ void code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder opcast_to_strbuilder(CodeOpCast self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Operator_Cast: | ||||
| @@ -867,7 +867,7 @@ StrBuilder params_to_strbuilder(CodeParams self) | ||||
| { | ||||
| 	GEN_ASSERT(self); | ||||
| 	GEN_ASSERT(self); | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | ||||
| 	params_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -914,7 +914,7 @@ void params_to_strbuilder_ref( CodeParams self, StrBuilder* result ) | ||||
| StrBuilder preprocess_to_strbuilder(CodePreprocessCond self) | ||||
| { | ||||
| 	GEN_ASSERT(self); | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 256 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Preprocess_If: | ||||
| @@ -978,7 +978,7 @@ void preprocess_to_strbuilder_endif(CodePreprocessCond cond, StrBuilder* result | ||||
| StrBuilder pragma_to_strbuilder(CodePragma self) | ||||
| { | ||||
| 	GEN_ASSERT(self); | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 256 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 ); | ||||
| 	pragma_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -990,7 +990,7 @@ void pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder specifiers_to_strbuilder(CodeSpecifiers self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 64 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 64 ); | ||||
| 	specifiers_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -1013,7 +1013,7 @@ StrBuilder struct_to_strbuilder(CodeStruct self) | ||||
| { | ||||
| 	GEN_ASSERT(self); | ||||
| 	GEN_ASSERT(self); | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Struct: | ||||
| @@ -1096,7 +1096,7 @@ void struct_to_strbuilder_fwd( CodeStruct self, StrBuilder* result ) | ||||
| StrBuilder template_to_strbuilder(CodeTemplate self) | ||||
| { | ||||
| 	GEN_ASSERT(self); | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 1024 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 1024 ); | ||||
| 	template_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -1116,7 +1116,7 @@ void template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder typedef_to_strbuilder(CodeTypedef self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | ||||
| 	typedef_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -1158,7 +1158,7 @@ void typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder typename_to_strbuilder(CodeTypename self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_str( GlobalAllocator, txt("") ); | ||||
| 	StrBuilder result = strbuilder_make_str( _ctx->Allocator_Temp, txt("") ); | ||||
| 	typename_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -1221,7 +1221,7 @@ void typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result ) | ||||
|  | ||||
| StrBuilder union_to_strbuilder(CodeUnion self) | ||||
| { | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 512 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 512 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Union: | ||||
| @@ -1287,7 +1287,7 @@ void union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result ) | ||||
| StrBuilder using_to_strbuilder(CodeUsing self) | ||||
| { | ||||
| 	GEN_ASSERT(self); | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 128 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 128 ); | ||||
| 	switch ( self->Type ) | ||||
| 	{ | ||||
| 		case CT_Using: | ||||
| @@ -1352,7 +1352,7 @@ inline | ||||
| StrBuilder var_to_strbuilder(CodeVar self) | ||||
| { | ||||
| 	GEN_ASSERT(self); | ||||
| 	StrBuilder result = strbuilder_make_reserve( GlobalAllocator, 256 ); | ||||
| 	StrBuilder result = strbuilder_make_reserve( _ctx->Allocator_Temp, 256 ); | ||||
| 	var_to_strbuilder_ref( self, & result ); | ||||
| 	return result; | ||||
| } | ||||
| @@ -1407,7 +1407,7 @@ void var_to_strbuilder_ref(CodeVar self, StrBuilder* result ) | ||||
| 	if ( self->Attributes || self->Specs ) | ||||
| 	{ | ||||
| 		if ( self->Attributes ) | ||||
| 			strbuilder_append_fmt( result, "%SB ", specifiers_to_strbuilder(self->Specs) ); | ||||
| 			strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) ); | ||||
|  | ||||
| 		if ( self->Specs ) | ||||
| 			strbuilder_append_fmt( result, "%SB\n", specifiers_to_strbuilder(self->Specs) ); | ||||
|   | ||||
| @@ -17,128 +17,128 @@ | ||||
|  | ||||
| #pragma region Code Type C-Interface | ||||
|  | ||||
| void       body_append              ( CodeBody body, Code     other ); | ||||
| void       body_append_body         ( CodeBody body, CodeBody other ); | ||||
| StrBuilder body_to_strbuilder       ( CodeBody body ); | ||||
| void       body_to_strbuilder_ref   ( CodeBody body, StrBuilder* result ); | ||||
| void       body_to_strbuilder_export( CodeBody body, StrBuilder* result ); | ||||
| GEN_API void       body_append              ( CodeBody body, Code     other ); | ||||
| GEN_API void       body_append_body         ( CodeBody body, CodeBody other ); | ||||
| GEN_API StrBuilder body_to_strbuilder       ( CodeBody body ); | ||||
| GEN_API void       body_to_strbuilder_ref   ( CodeBody body, StrBuilder* result ); | ||||
| GEN_API void       body_to_strbuilder_export( CodeBody body, StrBuilder* result ); | ||||
|  | ||||
| Code begin_CodeBody( CodeBody body); | ||||
| Code end_CodeBody  ( CodeBody body ); | ||||
| Code next_CodeBody ( CodeBody body, Code entry_iter ); | ||||
| GEN_API Code begin_CodeBody( CodeBody body); | ||||
| GEN_API Code end_CodeBody  ( CodeBody body ); | ||||
| GEN_API Code next_CodeBody ( CodeBody body, Code entry_iter ); | ||||
|  | ||||
| void       class_add_interface    ( CodeClass self, CodeTypename interface ); | ||||
| StrBuilder class_to_strbuilder    ( CodeClass self ); | ||||
| void       class_to_strbuilder_def( CodeClass self, StrBuilder* result ); | ||||
| void       class_to_strbuilder_fwd( CodeClass self, StrBuilder* result ); | ||||
| GEN_API void       class_add_interface    ( CodeClass self, CodeTypename interface ); | ||||
| GEN_API StrBuilder class_to_strbuilder    ( CodeClass self ); | ||||
| GEN_API void       class_to_strbuilder_def( CodeClass self, StrBuilder* result ); | ||||
| GEN_API void       class_to_strbuilder_fwd( CodeClass self, StrBuilder* result ); | ||||
|  | ||||
| void       params_append           (CodeParams params, CodeParams param ); | ||||
| CodeParams params_get              (CodeParams params, s32 idx); | ||||
| bool       params_has_entries      (CodeParams params ); | ||||
| StrBuilder params_to_strbuilder    (CodeParams params ); | ||||
| void       params_to_strbuilder_ref(CodeParams params, StrBuilder* result ); | ||||
| GEN_API void       params_append           (CodeParams params, CodeParams param ); | ||||
| GEN_API CodeParams params_get              (CodeParams params, s32 idx); | ||||
| GEN_API bool       params_has_entries      (CodeParams params ); | ||||
| GEN_API StrBuilder params_to_strbuilder    (CodeParams params ); | ||||
| GEN_API void       params_to_strbuilder_ref(CodeParams params, StrBuilder* result ); | ||||
|  | ||||
| CodeParams begin_CodeParams(CodeParams params); | ||||
| CodeParams end_CodeParams  (CodeParams params); | ||||
| CodeParams next_CodeParams (CodeParams params, CodeParams entry_iter); | ||||
| GEN_API CodeParams begin_CodeParams(CodeParams params); | ||||
| GEN_API CodeParams end_CodeParams  (CodeParams params); | ||||
| GEN_API CodeParams next_CodeParams (CodeParams params, CodeParams entry_iter); | ||||
|  | ||||
| bool       specifiers_append           (CodeSpecifiers specifiers, Specifier spec); | ||||
| s32        specifiers_has              (CodeSpecifiers specifiers, Specifier spec); | ||||
| s32        specifiers_remove           (CodeSpecifiers specifiers, Specifier to_remove ); | ||||
| StrBuilder specifiers_to_strbuilder    (CodeSpecifiers specifiers); | ||||
| void       specifiers_to_strbuilder_ref(CodeSpecifiers specifiers, StrBuilder* result); | ||||
| GEN_API bool       specifiers_append           (CodeSpecifiers specifiers, Specifier spec); | ||||
| GEN_API s32        specifiers_has              (CodeSpecifiers specifiers, Specifier spec); | ||||
| GEN_API s32        specifiers_remove           (CodeSpecifiers specifiers, Specifier to_remove ); | ||||
| GEN_API StrBuilder specifiers_to_strbuilder    (CodeSpecifiers specifiers); | ||||
| GEN_API void       specifiers_to_strbuilder_ref(CodeSpecifiers specifiers, StrBuilder* result); | ||||
|  | ||||
| Specifier* begin_CodeSpecifiers(CodeSpecifiers specifiers); | ||||
| Specifier* end_CodeSpecifiers  (CodeSpecifiers specifiers); | ||||
| Specifier* next_CodeSpecifiers (CodeSpecifiers specifiers, Specifier* spec_iter); | ||||
| GEN_API Specifier* begin_CodeSpecifiers(CodeSpecifiers specifiers); | ||||
| GEN_API Specifier* end_CodeSpecifiers  (CodeSpecifiers specifiers); | ||||
| GEN_API Specifier* next_CodeSpecifiers (CodeSpecifiers specifiers, Specifier* spec_iter); | ||||
|  | ||||
| void       struct_add_interface    (CodeStruct self, CodeTypename interface); | ||||
| StrBuilder struct_to_strbuilder    (CodeStruct self); | ||||
| void       struct_to_strbuilder_fwd(CodeStruct self, StrBuilder* result); | ||||
| void       struct_to_strbuilder_def(CodeStruct self, StrBuilder* result); | ||||
| GEN_API void       struct_add_interface    (CodeStruct self, CodeTypename interface); | ||||
| GEN_API StrBuilder struct_to_strbuilder    (CodeStruct self); | ||||
| GEN_API void       struct_to_strbuilder_fwd(CodeStruct self, StrBuilder* result); | ||||
| GEN_API void       struct_to_strbuilder_def(CodeStruct self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder attributes_to_strbuilder    (CodeAttributes attributes); | ||||
| void       attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result); | ||||
| GEN_API StrBuilder attributes_to_strbuilder    (CodeAttributes attributes); | ||||
| GEN_API void       attributes_to_strbuilder_ref(CodeAttributes attributes, StrBuilder* result); | ||||
|  | ||||
| StrBuilder comment_to_strbuilder    (CodeComment comment ); | ||||
| void       comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result ); | ||||
| GEN_API StrBuilder comment_to_strbuilder    (CodeComment comment ); | ||||
| GEN_API void       comment_to_strbuilder_ref(CodeComment comment, StrBuilder* result ); | ||||
|  | ||||
| StrBuilder constructor_to_strbuilder    (CodeConstructor constructor); | ||||
| void       constructor_to_strbuilder_def(CodeConstructor constructor, StrBuilder* result ); | ||||
| void       constructor_to_strbuilder_fwd(CodeConstructor constructor, StrBuilder* result ); | ||||
| GEN_API StrBuilder constructor_to_strbuilder    (CodeConstructor constructor); | ||||
| GEN_API void       constructor_to_strbuilder_def(CodeConstructor constructor, StrBuilder* result ); | ||||
| GEN_API void       constructor_to_strbuilder_fwd(CodeConstructor constructor, StrBuilder* result ); | ||||
|  | ||||
| StrBuilder define_to_strbuilder    (CodeDefine self); | ||||
| void       define_to_strbuilder_ref(CodeDefine self, StrBuilder* result); | ||||
| GEN_API StrBuilder define_to_strbuilder    (CodeDefine self); | ||||
| GEN_API void       define_to_strbuilder_ref(CodeDefine self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder destructor_to_strbuilder    (CodeDestructor destructor); | ||||
| void       destructor_to_strbuilder_fwd(CodeDestructor destructor, StrBuilder* result ); | ||||
| void       destructor_to_strbuilder_def(CodeDestructor destructor, StrBuilder* result ); | ||||
| GEN_API StrBuilder destructor_to_strbuilder    (CodeDestructor destructor); | ||||
| GEN_API void       destructor_to_strbuilder_fwd(CodeDestructor destructor, StrBuilder* result ); | ||||
| GEN_API void       destructor_to_strbuilder_def(CodeDestructor destructor, StrBuilder* result ); | ||||
|  | ||||
| StrBuilder enum_to_strbuilder          (CodeEnum self); | ||||
| void       enum_to_strbuilder_def      (CodeEnum self, StrBuilder* result ); | ||||
| void       enum_to_strbuilder_fwd      (CodeEnum self, StrBuilder* result ); | ||||
| void       enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result ); | ||||
| void       enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result ); | ||||
| GEN_API StrBuilder enum_to_strbuilder          (CodeEnum self); | ||||
| GEN_API void       enum_to_strbuilder_def      (CodeEnum self, StrBuilder* result ); | ||||
| GEN_API void       enum_to_strbuilder_fwd      (CodeEnum self, StrBuilder* result ); | ||||
| GEN_API void       enum_to_strbuilder_class_def(CodeEnum self, StrBuilder* result ); | ||||
| GEN_API void       enum_to_strbuilder_class_fwd(CodeEnum self, StrBuilder* result ); | ||||
|  | ||||
| StrBuilder exec_to_strbuilder    (CodeExec exec); | ||||
| void       exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result); | ||||
| GEN_API StrBuilder exec_to_strbuilder    (CodeExec exec); | ||||
| GEN_API void       exec_to_strbuilder_ref(CodeExec exec, StrBuilder* result); | ||||
|  | ||||
| void extern_to_strbuilder(CodeExtern self, StrBuilder* result); | ||||
| GEN_API void extern_to_strbuilder(CodeExtern self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder include_to_strbuilder    (CodeInclude self); | ||||
| void       include_to_strbuilder_ref(CodeInclude self, StrBuilder* result); | ||||
| GEN_API StrBuilder include_to_strbuilder    (CodeInclude self); | ||||
| GEN_API void       include_to_strbuilder_ref(CodeInclude self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder friend_to_strbuilder     (CodeFriend self); | ||||
| void       friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result); | ||||
| GEN_API StrBuilder friend_to_strbuilder     (CodeFriend self); | ||||
| GEN_API void       friend_to_strbuilder_ref(CodeFriend self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder fn_to_strbuilder    (CodeFn self); | ||||
| void       fn_to_strbuilder_def(CodeFn self, StrBuilder* result); | ||||
| void       fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result); | ||||
| GEN_API StrBuilder fn_to_strbuilder    (CodeFn self); | ||||
| GEN_API void       fn_to_strbuilder_def(CodeFn self, StrBuilder* result); | ||||
| GEN_API void       fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder module_to_strbuilder    (CodeModule self); | ||||
| void       module_to_strbuilder_ref(CodeModule self, StrBuilder* result); | ||||
| GEN_API StrBuilder module_to_strbuilder    (CodeModule self); | ||||
| GEN_API void       module_to_strbuilder_ref(CodeModule self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder namespace_to_strbuilder    (CodeNS self); | ||||
| void       namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result); | ||||
| GEN_API StrBuilder namespace_to_strbuilder    (CodeNS self); | ||||
| GEN_API void       namespace_to_strbuilder_ref(CodeNS self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder code_op_to_strbuilder    (CodeOperator self); | ||||
| void       code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result ); | ||||
| void       code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result ); | ||||
| GEN_API StrBuilder code_op_to_strbuilder    (CodeOperator self); | ||||
| GEN_API void       code_op_to_strbuilder_fwd(CodeOperator self, StrBuilder* result ); | ||||
| GEN_API void       code_op_to_strbuilder_def(CodeOperator self, StrBuilder* result ); | ||||
|  | ||||
| StrBuilder opcast_to_strbuilder     (CodeOpCast op_cast ); | ||||
| void       opcast_to_strbuilder_def(CodeOpCast op_cast, StrBuilder* result ); | ||||
| void       opcast_to_strbuilder_fwd(CodeOpCast op_cast, StrBuilder* result ); | ||||
| GEN_API StrBuilder opcast_to_strbuilder     (CodeOpCast op_cast ); | ||||
| GEN_API void       opcast_to_strbuilder_def(CodeOpCast op_cast, StrBuilder* result ); | ||||
| GEN_API void       opcast_to_strbuilder_fwd(CodeOpCast op_cast, StrBuilder* result ); | ||||
|  | ||||
| StrBuilder pragma_to_strbuilder    (CodePragma self); | ||||
| void       pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result); | ||||
| GEN_API StrBuilder pragma_to_strbuilder    (CodePragma self); | ||||
| GEN_API void       pragma_to_strbuilder_ref(CodePragma self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder preprocess_to_strbuilder       (CodePreprocessCond cond); | ||||
| void       preprocess_to_strbuilder_if    (CodePreprocessCond cond, StrBuilder* result ); | ||||
| void       preprocess_to_strbuilder_ifdef (CodePreprocessCond cond, StrBuilder* result ); | ||||
| void       preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result ); | ||||
| void       preprocess_to_strbuilder_elif  (CodePreprocessCond cond, StrBuilder* result ); | ||||
| void       preprocess_to_strbuilder_else  (CodePreprocessCond cond, StrBuilder* result ); | ||||
| void       preprocess_to_strbuilder_endif (CodePreprocessCond cond, StrBuilder* result ); | ||||
| GEN_API StrBuilder preprocess_to_strbuilder       (CodePreprocessCond cond); | ||||
| GEN_API void       preprocess_to_strbuilder_if    (CodePreprocessCond cond, StrBuilder* result ); | ||||
| GEN_API void       preprocess_to_strbuilder_ifdef (CodePreprocessCond cond, StrBuilder* result ); | ||||
| GEN_API void       preprocess_to_strbuilder_ifndef(CodePreprocessCond cond, StrBuilder* result ); | ||||
| GEN_API void       preprocess_to_strbuilder_elif  (CodePreprocessCond cond, StrBuilder* result ); | ||||
| GEN_API void       preprocess_to_strbuilder_else  (CodePreprocessCond cond, StrBuilder* result ); | ||||
| GEN_API void       preprocess_to_strbuilder_endif (CodePreprocessCond cond, StrBuilder* result ); | ||||
|  | ||||
| StrBuilder template_to_strbuilder    (CodeTemplate self); | ||||
| void       template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result); | ||||
| GEN_API StrBuilder template_to_strbuilder    (CodeTemplate self); | ||||
| GEN_API void       template_to_strbuilder_ref(CodeTemplate self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder typename_to_strbuilder    (CodeTypename self); | ||||
| void       typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result); | ||||
| GEN_API StrBuilder typename_to_strbuilder    (CodeTypename self); | ||||
| GEN_API void       typename_to_strbuilder_ref(CodeTypename self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder typedef_to_strbuilder    (CodeTypedef self); | ||||
| void       typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result ); | ||||
| GEN_API StrBuilder typedef_to_strbuilder    (CodeTypedef self); | ||||
| GEN_API void       typedef_to_strbuilder_ref(CodeTypedef self, StrBuilder* result ); | ||||
|  | ||||
| StrBuilder union_to_strbuilder    (CodeUnion self); | ||||
| void       union_to_strbuilder_def(CodeUnion self, StrBuilder* result); | ||||
| void       union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result); | ||||
| GEN_API StrBuilder union_to_strbuilder    (CodeUnion self); | ||||
| GEN_API void       union_to_strbuilder_def(CodeUnion self, StrBuilder* result); | ||||
| GEN_API void       union_to_strbuilder_fwd(CodeUnion self, StrBuilder* result); | ||||
|  | ||||
| StrBuilder using_to_strbuilder    (CodeUsing op_cast ); | ||||
| void       using_to_strbuilder_ref(CodeUsing op_cast, StrBuilder* result ); | ||||
| void       using_to_strbuilder_ns (CodeUsing op_cast, StrBuilder* result ); | ||||
| GEN_API StrBuilder using_to_strbuilder    (CodeUsing op_cast ); | ||||
| GEN_API void       using_to_strbuilder_ref(CodeUsing op_cast, StrBuilder* result ); | ||||
| GEN_API void       using_to_strbuilder_ns (CodeUsing op_cast, StrBuilder* result ); | ||||
|  | ||||
| StrBuilder var_to_strbuilder    (CodeVar self); | ||||
| void       var_to_strbuilder_ref(CodeVar self, StrBuilder* result); | ||||
| GEN_API StrBuilder var_to_strbuilder    (CodeVar self); | ||||
| GEN_API void       var_to_strbuilder_ref(CodeVar self, StrBuilder* result); | ||||
|  | ||||
| #pragma endregion Code Type C-Interface | ||||
|  | ||||
|   | ||||
| @@ -1,235 +0,0 @@ | ||||
| #ifdef GEN_INTELLISENSE_DIRECTIVES | ||||
| #pragma once | ||||
| #include "components/types.hpp" | ||||
| #endif | ||||
|  | ||||
| // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) | ||||
|  | ||||
| GEN_NS_PARSER_BEGIN | ||||
|  | ||||
| #define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Tok_Attribute_API_Import, "GEN_API_Import_Code" ) | ||||
|  | ||||
| enum TokType : u32 | ||||
| { | ||||
| 	Tok_Invalid, | ||||
| 	Tok_Access_Private, | ||||
| 	Tok_Access_Protected, | ||||
| 	Tok_Access_Public, | ||||
| 	Tok_Access_MemberSymbol, | ||||
| 	Tok_Access_StaticSymbol, | ||||
| 	Tok_Ampersand, | ||||
| 	Tok_Ampersand_DBL, | ||||
| 	Tok_Assign_Classifer, | ||||
| 	Tok_Attribute_Open, | ||||
| 	Tok_Attribute_Close, | ||||
| 	Tok_BraceCurly_Open, | ||||
| 	Tok_BraceCurly_Close, | ||||
| 	Tok_BraceSquare_Open, | ||||
| 	Tok_BraceSquare_Close, | ||||
| 	Tok_Capture_Start, | ||||
| 	Tok_Capture_End, | ||||
| 	Tok_Comment, | ||||
| 	Tok_Comment_End, | ||||
| 	Tok_Comment_Start, | ||||
| 	Tok_Char, | ||||
| 	Tok_Comma, | ||||
| 	Tok_Decl_Class, | ||||
| 	Tok_Decl_GNU_Attribute, | ||||
| 	Tok_Decl_MSVC_Attribute, | ||||
| 	Tok_Decl_Enum, | ||||
| 	Tok_Decl_Extern_Linkage, | ||||
| 	Tok_Decl_Friend, | ||||
| 	Tok_Decl_Module, | ||||
| 	Tok_Decl_Namespace, | ||||
| 	Tok_Decl_Operator, | ||||
| 	Tok_Decl_Struct, | ||||
| 	Tok_Decl_Template, | ||||
| 	Tok_Decl_Typedef, | ||||
| 	Tok_Decl_Using, | ||||
| 	Tok_Decl_Union, | ||||
| 	Tok_Identifier, | ||||
| 	Tok_Module_Import, | ||||
| 	Tok_Module_Export, | ||||
| 	Tok_NewLine, | ||||
| 	Tok_Number, | ||||
| 	Tok_Operator, | ||||
| 	Tok_Preprocess_Hash, | ||||
| 	Tok_Preprocess_Define, | ||||
| 	Tok_Preprocess_If, | ||||
| 	Tok_Preprocess_IfDef, | ||||
| 	Tok_Preprocess_IfNotDef, | ||||
| 	Tok_Preprocess_ElIf, | ||||
| 	Tok_Preprocess_Else, | ||||
| 	Tok_Preprocess_EndIf, | ||||
| 	Tok_Preprocess_Include, | ||||
| 	Tok_Preprocess_Pragma, | ||||
| 	Tok_Preprocess_Content, | ||||
| 	Tok_Preprocess_Macro, | ||||
| 	Tok_Preprocess_Unsupported, | ||||
| 	Tok_Spec_Alignas, | ||||
| 	Tok_Spec_Const, | ||||
| 	Tok_Spec_Consteval, | ||||
| 	Tok_Spec_Constexpr, | ||||
| 	Tok_Spec_Constinit, | ||||
| 	Tok_Spec_Explicit, | ||||
| 	Tok_Spec_Extern, | ||||
| 	Tok_Spec_Final, | ||||
| 	Tok_Spec_ForceInline, | ||||
| 	Tok_Spec_Global, | ||||
| 	Tok_Spec_Inline, | ||||
| 	Tok_Spec_Internal_Linkage, | ||||
| 	Tok_Spec_LocalPersist, | ||||
| 	Tok_Spec_Mutable, | ||||
| 	Tok_Spec_NeverInline, | ||||
| 	Tok_Spec_Override, | ||||
| 	Tok_Spec_Static, | ||||
| 	Tok_Spec_ThreadLocal, | ||||
| 	Tok_Spec_Volatile, | ||||
| 	Tok_Spec_Virtual, | ||||
| 	Tok_Star, | ||||
| 	Tok_Statement_End, | ||||
| 	Tok_StaticAssert, | ||||
| 	Tok_String, | ||||
| 	Tok_Type_Typename, | ||||
| 	Tok_Type_Unsigned, | ||||
| 	Tok_Type_Signed, | ||||
| 	Tok_Type_Short, | ||||
| 	Tok_Type_Long, | ||||
| 	Tok_Type_bool, | ||||
| 	Tok_Type_char, | ||||
| 	Tok_Type_int, | ||||
| 	Tok_Type_double, | ||||
| 	Tok_Type_MS_int8, | ||||
| 	Tok_Type_MS_int16, | ||||
| 	Tok_Type_MS_int32, | ||||
| 	Tok_Type_MS_int64, | ||||
| 	Tok_Type_MS_W64, | ||||
| 	Tok_Varadic_Argument, | ||||
| 	Tok___Attributes_Start, | ||||
| 	Tok_Attribute_API_Export, | ||||
| 	Tok_Attribute_API_Import, | ||||
| 	Tok_NumTokens | ||||
| }; | ||||
|  | ||||
| inline Str toktype_to_str( TokType type ) | ||||
| { | ||||
| 	local_persist Str lookup[] = { | ||||
| 		{ "__invalid__",         sizeof( "__invalid__" ) - 1         }, | ||||
| 		{ "private",             sizeof( "private" ) - 1             }, | ||||
| 		{ "protected",           sizeof( "protected" ) - 1           }, | ||||
| 		{ "public",              sizeof( "public" ) - 1              }, | ||||
| 		{ ".",		           sizeof( "." ) - 1                   }, | ||||
| 		{ "::",		          sizeof( "::" ) - 1                  }, | ||||
| 		{ "&",		           sizeof( "&" ) - 1                   }, | ||||
| 		{ "&&",		          sizeof( "&&" ) - 1                  }, | ||||
| 		{ ":",		           sizeof( ":" ) - 1                   }, | ||||
| 		{ "[[",		          sizeof( "[[" ) - 1                  }, | ||||
| 		{ "]]",		          sizeof( "]]" ) - 1                  }, | ||||
| 		{ "{",		           sizeof( "{" ) - 1                   }, | ||||
| 		{ "}",		           sizeof( "}" ) - 1                   }, | ||||
| 		{ "[",		           sizeof( "[" ) - 1                   }, | ||||
| 		{ "]",		           sizeof( "]" ) - 1                   }, | ||||
| 		{ "(",		           sizeof( "(" ) - 1                   }, | ||||
| 		{ ")",		           sizeof( ")" ) - 1                   }, | ||||
| 		{ "__comment__",         sizeof( "__comment__" ) - 1         }, | ||||
| 		{ "__comment_end__",     sizeof( "__comment_end__" ) - 1     }, | ||||
| 		{ "__comment_start__",   sizeof( "__comment_start__" ) - 1   }, | ||||
| 		{ "__character__",       sizeof( "__character__" ) - 1       }, | ||||
| 		{ ",",		           sizeof( "," ) - 1                   }, | ||||
| 		{ "class",               sizeof( "class" ) - 1               }, | ||||
| 		{ "__attribute__",       sizeof( "__attribute__" ) - 1       }, | ||||
| 		{ "__declspec",          sizeof( "__declspec" ) - 1          }, | ||||
| 		{ "enum",                sizeof( "enum" ) - 1                }, | ||||
| 		{ "extern",              sizeof( "extern" ) - 1              }, | ||||
| 		{ "friend",              sizeof( "friend" ) - 1              }, | ||||
| 		{ "module",              sizeof( "module" ) - 1              }, | ||||
| 		{ "namespace",           sizeof( "namespace" ) - 1           }, | ||||
| 		{ "operator",            sizeof( "operator" ) - 1            }, | ||||
| 		{ "struct",              sizeof( "struct" ) - 1              }, | ||||
| 		{ "template",            sizeof( "template" ) - 1            }, | ||||
| 		{ "typedef",             sizeof( "typedef" ) - 1             }, | ||||
| 		{ "using",               sizeof( "using" ) - 1               }, | ||||
| 		{ "union",               sizeof( "union" ) - 1               }, | ||||
| 		{ "__identifier__",      sizeof( "__identifier__" ) - 1      }, | ||||
| 		{ "import",              sizeof( "import" ) - 1              }, | ||||
| 		{ "export",              sizeof( "export" ) - 1              }, | ||||
| 		{ "__new_line__",        sizeof( "__new_line__" ) - 1        }, | ||||
| 		{ "__number__",          sizeof( "__number__" ) - 1          }, | ||||
| 		{ "__operator__",        sizeof( "__operator__" ) - 1        }, | ||||
| 		{ "#",		           sizeof( "#" ) - 1                   }, | ||||
| 		{ "define",              sizeof( "define" ) - 1              }, | ||||
| 		{ "if",		          sizeof( "if" ) - 1                  }, | ||||
| 		{ "ifdef",               sizeof( "ifdef" ) - 1               }, | ||||
| 		{ "ifndef",              sizeof( "ifndef" ) - 1              }, | ||||
| 		{ "elif",                sizeof( "elif" ) - 1                }, | ||||
| 		{ "else",                sizeof( "else" ) - 1                }, | ||||
| 		{ "endif",               sizeof( "endif" ) - 1               }, | ||||
| 		{ "include",             sizeof( "include" ) - 1             }, | ||||
| 		{ "pragma",              sizeof( "pragma" ) - 1              }, | ||||
| 		{ "__macro_content__",   sizeof( "__macro_content__" ) - 1   }, | ||||
| 		{ "__macro__",           sizeof( "__macro__" ) - 1           }, | ||||
| 		{ "__unsupported__",     sizeof( "__unsupported__" ) - 1     }, | ||||
| 		{ "alignas",             sizeof( "alignas" ) - 1             }, | ||||
| 		{ "const",               sizeof( "const" ) - 1               }, | ||||
| 		{ "consteval",           sizeof( "consteval" ) - 1           }, | ||||
| 		{ "constexpr",           sizeof( "constexpr" ) - 1           }, | ||||
| 		{ "constinit",           sizeof( "constinit" ) - 1           }, | ||||
| 		{ "explicit",            sizeof( "explicit" ) - 1            }, | ||||
| 		{ "extern",              sizeof( "extern" ) - 1              }, | ||||
| 		{ "final",               sizeof( "final" ) - 1               }, | ||||
| 		{ "forceinline",         sizeof( "forceinline" ) - 1         }, | ||||
| 		{ "global",              sizeof( "global" ) - 1              }, | ||||
| 		{ "inline",              sizeof( "inline" ) - 1              }, | ||||
| 		{ "internal",            sizeof( "internal" ) - 1            }, | ||||
| 		{ "local_persist",       sizeof( "local_persist" ) - 1       }, | ||||
| 		{ "mutable",             sizeof( "mutable" ) - 1             }, | ||||
| 		{ "neverinline",         sizeof( "neverinline" ) - 1         }, | ||||
| 		{ "override",            sizeof( "override" ) - 1            }, | ||||
| 		{ "static",              sizeof( "static" ) - 1              }, | ||||
| 		{ "thread_local",        sizeof( "thread_local" ) - 1        }, | ||||
| 		{ "volatile",            sizeof( "volatile" ) - 1            }, | ||||
| 		{ "virtual",             sizeof( "virtual" ) - 1             }, | ||||
| 		{ "*",		           sizeof( "*" ) - 1                   }, | ||||
| 		{ ";",		           sizeof( ";" ) - 1                   }, | ||||
| 		{ "static_assert",       sizeof( "static_assert" ) - 1       }, | ||||
| 		{ "__string__",          sizeof( "__string__" ) - 1          }, | ||||
| 		{ "typename",            sizeof( "typename" ) - 1            }, | ||||
| 		{ "unsigned",            sizeof( "unsigned" ) - 1            }, | ||||
| 		{ "signed",              sizeof( "signed" ) - 1              }, | ||||
| 		{ "short",               sizeof( "short" ) - 1               }, | ||||
| 		{ "long",                sizeof( "long" ) - 1                }, | ||||
| 		{ "bool",                sizeof( "bool" ) - 1                }, | ||||
| 		{ "char",                sizeof( "char" ) - 1                }, | ||||
| 		{ "int",		         sizeof( "int" ) - 1                 }, | ||||
| 		{ "double",              sizeof( "double" ) - 1              }, | ||||
| 		{ "__int8",              sizeof( "__int8" ) - 1              }, | ||||
| 		{ "__int16",             sizeof( "__int16" ) - 1             }, | ||||
| 		{ "__int32",             sizeof( "__int32" ) - 1             }, | ||||
| 		{ "__int64",             sizeof( "__int64" ) - 1             }, | ||||
| 		{ "_W64",                sizeof( "_W64" ) - 1                }, | ||||
| 		{ "...",		         sizeof( "..." ) - 1                 }, | ||||
| 		{ "__attrib_start__",    sizeof( "__attrib_start__" ) - 1    }, | ||||
| 		{ "GEN_API_Export_Code", sizeof( "GEN_API_Export_Code" ) - 1 }, | ||||
| 		{ "GEN_API_Import_Code", sizeof( "GEN_API_Import_Code" ) - 1 }, | ||||
| 	}; | ||||
| 	return lookup[type]; | ||||
| } | ||||
|  | ||||
| inline TokType str_to_toktype( Str str ) | ||||
| { | ||||
| 	local_persist u32 keymap[Tok_NumTokens]; | ||||
| 	do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ ) | ||||
| 	{ | ||||
| 		Str enum_str  = toktype_to_str( (TokType)index ); | ||||
| 		keymap[index] = crc32( enum_str.Ptr, enum_str.Len ); | ||||
| 	} | ||||
| 	do_once_end u32 hash = crc32( str.Ptr, str.Len ); | ||||
| 	for ( u32 index = 0; index < Tok_NumTokens; index++ ) | ||||
| 	{ | ||||
| 		if ( keymap[index] == hash ) | ||||
| 			return (TokType)index; | ||||
| 	} | ||||
| 	return Tok_Invalid; | ||||
| } | ||||
|  | ||||
| GEN_NS_PARSER_END | ||||
							
								
								
									
										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 | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -10,23 +10,21 @@ | ||||
|  | ||||
| CodeClass parse_class( Str def ) | ||||
| { | ||||
| 	GEN_USING_NS_PARSER; | ||||
| 	check_parse_args( def ); | ||||
|  | ||||
| 	TokArray toks = lex( def ); | ||||
| 	if ( toks.Arr == nullptr ) | ||||
| 		return InvalidCode; | ||||
|  | ||||
| 	Context.Tokens = toks; | ||||
| 	_ctx->parser.Tokens = toks; | ||||
| 	push_scope(); | ||||
| 	CodeClass result = (CodeClass) parse_class_struct( Tok_Decl_Class, parser_not_inplace_def ); | ||||
| 	parser_pop(& Context); | ||||
| 	parser_pop(& _ctx->parser); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| CodeConstructor parse_constructor( Str def ) | ||||
| { | ||||
| 	GEN_USING_NS_PARSER; | ||||
| 	check_parse_args( def ); | ||||
|  | ||||
| 	TokArray toks = lex( def ); | ||||
| @@ -59,8 +57,8 @@ CodeConstructor parse_constructor( Str def ) | ||||
| 				break; | ||||
|  | ||||
| 			default : | ||||
| 				log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(Context) ); | ||||
| 				parser_pop(& Context); | ||||
| 				log_failure( "Invalid specifier %s for variable\n%S", spec_to_str( spec ), parser_to_strbuilder(_ctx->parser) ); | ||||
| 				parser_pop(& _ctx->parser); | ||||
| 				return InvalidCode; | ||||
| 		} | ||||
|  | ||||
| @@ -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      = { fmt, c_str_len_capped(fmt, MaxNameLength) }; | ||||
|     Str uncapped_str = { buf, length }; | ||||
|     Str content = { buf, length }; | ||||
|  | ||||
| 	Code | ||||
| 	result          = make_code(); | ||||
| 	result->Name    = get_cached_string( buf_str ); | ||||
| 	result->Type    = CT_Untyped; | ||||
| 	result->Content = get_cached_string( uncapped_str ); | ||||
| 	result->Content = cache_str( content ); | ||||
|  | ||||
| 	if ( result->Name.Len == 0 ) | ||||
| 	{ | ||||
| @@ -176,9 +166,8 @@ Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ) | ||||
|  | ||||
| 	Code | ||||
| 	result          = make_code(); | ||||
| 	result->Name    = get_cached_string( buf_str ); | ||||
| 	result->Type    = CT_Untyped; | ||||
| 	result->Content = result->Name; | ||||
| 	result->Content = cache_str( buf_str ); | ||||
|  | ||||
| 	if ( result->Name.Len == 0 ) | ||||
| 	{ | ||||
|   | ||||
| @@ -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 ); | ||||
| @@ -466,7 +461,7 @@ CodeComment def_comment( Str content ) | ||||
| 	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 ) { | ||||
| @@ -590,7 +585,7 @@ CodeDefine def_define( Str name, Str content, Opts_def_define p ) | ||||
| 				break; | ||||
| 		} | ||||
| 		Str lex_id = { result->Name.Ptr,  lex_id_len }; | ||||
| 		array_append(PreprocessorDefines, lex_id ); | ||||
| 		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; | ||||
| @@ -899,7 +894,7 @@ CodeOperator def_operator( Operator op, Str nspace, Opts_def_operator p ) | ||||
|  | ||||
| 	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 ); | ||||
|   | ||||
| @@ -4,95 +4,9 @@ | ||||
| #include "gen/etoktype.cpp" | ||||
| #endif | ||||
|  | ||||
| GEN_NS_PARSER_BEGIN | ||||
|  | ||||
| enum TokFlags : u32 | ||||
| { | ||||
| 	TF_Operator		   = bit(0), | ||||
| 	TF_Assign          = bit(1), | ||||
| 	TF_Preprocess      = bit(2), | ||||
| 	TF_Preprocess_Cond = bit(3), | ||||
| 	TF_Attribute       = bit(6), | ||||
| 	TF_AccessOperator  = bit( 7 ), | ||||
| 	TF_AccessSpecifier = bit( 8 ), | ||||
| 	TF_Specifier       = bit( 9 ), | ||||
| 	TF_EndDefinition   = bit( 10 ),    // Either ; or } | ||||
| 	TF_Formatting      = bit( 11 ), | ||||
| 	TF_Literal         = bit( 12 ), | ||||
|  | ||||
| 	TF_Null = 0, | ||||
| 	TF_UnderlyingType = GEN_U32_MAX, | ||||
| }; | ||||
|  | ||||
| struct Token | ||||
| { | ||||
| 	Str     Text; | ||||
| 	TokType Type; | ||||
| 	s32     Line; | ||||
| 	s32     Column; | ||||
| 	u32     Flags; | ||||
| }; | ||||
|  | ||||
| constexpr Token NullToken { nullptr, 0, Tok_Invalid, false, 0, TF_Null }; | ||||
|  | ||||
| forceinline | ||||
| AccessSpec tok_to_access_specifier(Token tok) { | ||||
| 	return scast(AccessSpec, tok.Type); | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| Str tok_to_str(Token tok) { | ||||
| 	return tok.Text; | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| bool tok_is_valid( Token tok ) { | ||||
| 	return tok.Text.Ptr && tok.Text.Len && tok.Type != Tok_Invalid; | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| bool tok_is_access_operator(Token tok) { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_AccessOperator ); | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| bool tok_is_access_specifier(Token tok) { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_AccessSpecifier ); | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| bool tok_is_attribute(Token tok) { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Attribute ); | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| bool tok_is_operator(Token tok) { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Operator ); | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| bool tok_is_preprocessor(Token tok) { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Preprocess ); | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| bool tok_is_preprocess_cond(Token tok) { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Preprocess_Cond ); | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| bool tok_is_specifier(Token tok) { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_Specifier ); | ||||
| } | ||||
|  | ||||
| forceinline | ||||
| bool tok_is_end_definition(Token tok) { | ||||
| 	return bitfield_is_equal( u32, tok.Flags, TF_EndDefinition ); | ||||
| } | ||||
|  | ||||
| StrBuilder tok_to_strbuilder(Token tok) | ||||
| { | ||||
| 	StrBuilder result   = strbuilder_make_reserve( GlobalAllocator, kilobytes(4) ); | ||||
| 	StrBuilder result   = strbuilder_make_reserve( _ctx->Allocator_Temp, kilobytes(4) ); | ||||
| 	Str        type_str = toktype_to_str( tok.Type ); | ||||
|  | ||||
| 	strbuilder_append_fmt( & result, "Line: %d Column: %d, Type: %.*s Content: %.*s" | ||||
| @@ -103,12 +17,6 @@ StrBuilder tok_to_strbuilder(Token tok) | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| struct TokArray  | ||||
| { | ||||
| 	Array(Token) Arr; | ||||
| 	s32          Idx; | ||||
| }; | ||||
|  | ||||
| bool lex__eat( TokArray* self, TokType type ); | ||||
|  | ||||
| Token* lex_current(TokArray* self, bool skip_formatting ) | ||||
| @@ -160,27 +68,12 @@ Token* lex_next(TokArray self, bool skip_formatting) | ||||
| 	return & self.Arr[idx + 1]; | ||||
| } | ||||
|  | ||||
| global FixedArena_256KB Lexer_defines_map_arena; | ||||
| global StringTable      Lexer_defines; | ||||
| global Array(Token)     Lexer_Tokens; | ||||
|  | ||||
| enum | ||||
| { | ||||
| 	Lex_Continue, | ||||
| 	Lex_ReturnNull, | ||||
| }; | ||||
|  | ||||
| struct LexContext | ||||
| { | ||||
| 	Str             content; | ||||
| 	s32             left; | ||||
| 	char const*     scanner; | ||||
| 	s32             line; | ||||
| 	s32             column; | ||||
| 	StringTable     defines; | ||||
| 	Token           token; | ||||
| }; | ||||
|  | ||||
| forceinline | ||||
| void lexer_move_forward( LexContext* ctx ) | ||||
| { | ||||
| @@ -224,7 +117,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| { | ||||
| 	char const* hash = ctx->scanner; | ||||
| 	Token hash_tok = { { hash, 1 }, Tok_Preprocess_Hash, ctx->line, ctx->column, TF_Preprocess }; | ||||
| 	array_append( Lexer_Tokens, hash_tok  ); | ||||
| 	array_append( _ctx->Lexer_Tokens, hash_tok  ); | ||||
|  | ||||
| 	move_forward(); | ||||
| 	skip_whitespace(); | ||||
| @@ -300,14 +193,14 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
|  | ||||
| 		ctx->token.Text.Len = ctx->token.Text.Len + ctx->token.Text.Ptr - hash; | ||||
| 		ctx->token.Text.Ptr = hash; | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		array_append( _ctx->Lexer_Tokens, ctx->token ); | ||||
| 		return Lex_Continue; // Skip found token, its all handled here. | ||||
| 	} | ||||
|  | ||||
| 	if ( ctx->token.Type == Tok_Preprocess_Else || ctx->token.Type == Tok_Preprocess_EndIf ) | ||||
| 	{ | ||||
| 		ctx->token.Flags |= TF_Preprocess_Cond; | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		array_append( _ctx->Lexer_Tokens, ctx->token ); | ||||
| 		end_line(); | ||||
| 		return Lex_Continue; | ||||
| 	} | ||||
| @@ -316,7 +209,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 		ctx->token.Flags |= TF_Preprocess_Cond; | ||||
| 	} | ||||
|  | ||||
| 	array_append( Lexer_Tokens, ctx->token ); | ||||
| 	array_append( _ctx->Lexer_Tokens, ctx->token ); | ||||
|  | ||||
| 	skip_whitespace(); | ||||
|  | ||||
| @@ -340,7 +233,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 			name.Text.Len++; | ||||
| 		} | ||||
|  | ||||
| 		array_append( Lexer_Tokens, name ); | ||||
| 		array_append( _ctx->Lexer_Tokens, name ); | ||||
|  | ||||
| 		u64 key = crc32( name.Text.Ptr, name.Text.Len ); | ||||
| 		hashtable_set(ctx->defines, key, tok_to_str(name) ); | ||||
| @@ -354,7 +247,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
|  | ||||
| 		if ( (* ctx->scanner) != '"' && (* ctx->scanner) != '<' ) | ||||
| 		{ | ||||
| 			StrBuilder directive_str = strbuilder_fmt_buf( GlobalAllocator, "%.*s", min( 80, ctx->left + preprocess_content.Text.Len ), ctx->token.Text.Ptr ); | ||||
| 			StrBuilder directive_str = strbuilder_fmt_buf( _ctx->Allocator_Temp, "%.*s", min( 80, ctx->left + preprocess_content.Text.Len ), ctx->token.Text.Ptr ); | ||||
|  | ||||
| 			log_failure( "gen::Parser::lex: Expected '\"' or '<' after #include, not '%c' (%d, %d)\n%s" | ||||
| 				, (* ctx->scanner) | ||||
| @@ -386,7 +279,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 			move_forward(); | ||||
| 		} | ||||
|  | ||||
| 		array_append( Lexer_Tokens, preprocess_content ); | ||||
| 		array_append( _ctx->Lexer_Tokens, preprocess_content ); | ||||
| 		return Lex_Continue; // Skip found token, its all handled here. | ||||
| 	} | ||||
|  | ||||
| @@ -421,8 +314,8 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				StrBuilder directive_str = strbuilder_make_length( GlobalAllocator, ctx->token.Text.Ptr, ctx->token.Text.Len ); | ||||
| 				StrBuilder content_str   = strbuilder_fmt_buf( GlobalAllocator, "%.*s", min( 400, ctx->left + preprocess_content.Text.Len ), preprocess_content.Text.Ptr ); | ||||
| 				StrBuilder directive_str = strbuilder_make_length( _ctx->Allocator_Temp, ctx->token.Text.Ptr, ctx->token.Text.Len ); | ||||
| 				StrBuilder content_str   = strbuilder_fmt_buf( _ctx->Allocator_Temp, "%.*s", min( 400, ctx->left + preprocess_content.Text.Len ), preprocess_content.Text.Ptr ); | ||||
|  | ||||
| 				log_failure( "gen::Parser::lex: Invalid escape sequence '\\%c' (%d, %d)" | ||||
| 							" in preprocessor directive '%s' (%d, %d)\n%s" | ||||
| @@ -449,7 +342,7 @@ s32 lex_preprocessor_directive( LexContext* ctx ) | ||||
| 		preprocess_content.Text.Len++; | ||||
| 	} | ||||
|  | ||||
| 	array_append( Lexer_Tokens, preprocess_content ); | ||||
| 	array_append( _ctx->Lexer_Tokens, preprocess_content ); | ||||
| 	return Lex_Continue; // Skip found token, its all handled here. | ||||
| } | ||||
|  | ||||
| @@ -458,7 +351,7 @@ void lex_found_token( LexContext* ctx ) | ||||
| { | ||||
| 	if ( ctx->token.Type != Tok_Invalid ) | ||||
| 	{ | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		array_append( _ctx->Lexer_Tokens, ctx->token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -485,7 +378,7 @@ void lex_found_token( LexContext* ctx ) | ||||
| 		} | ||||
|  | ||||
| 		ctx->token.Type = type; | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		array_append( _ctx->Lexer_Tokens, ctx->token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -495,7 +388,7 @@ void lex_found_token( LexContext* ctx ) | ||||
| 	{ | ||||
| 		ctx->token.Type   = type; | ||||
| 		ctx->token.Flags |= TF_Specifier; | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		array_append( _ctx->Lexer_Tokens, ctx->token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -503,7 +396,7 @@ void lex_found_token( LexContext* ctx ) | ||||
| 	if ( type != Tok_Invalid ) | ||||
| 	{ | ||||
| 		ctx->token.Type = type; | ||||
| 		array_append( Lexer_Tokens, ctx->token ); | ||||
| 		array_append( _ctx->Lexer_Tokens, ctx->token ); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -557,7 +450,7 @@ void lex_found_token( LexContext* ctx ) | ||||
| 		ctx->token.Type = Tok_Identifier; | ||||
| 	} | ||||
|  | ||||
| 	array_append( Lexer_Tokens, ctx->token ); | ||||
| 	array_append( _ctx->Lexer_Tokens, ctx->token ); | ||||
| } | ||||
|  | ||||
| neverinline | ||||
| @@ -568,7 +461,7 @@ TokArray lex( Str content ) | ||||
| 	c.content = content; | ||||
| 	c.left    = content.Len; | ||||
| 	c.scanner = content.Ptr; | ||||
| 	c.defines = Lexer_defines; | ||||
| 	c.defines = _ctx->Lexer_defines; | ||||
|  | ||||
| 	char const* word        = c.scanner; | ||||
| 	s32         word_length = 0; | ||||
| @@ -584,7 +477,7 @@ TokArray lex( Str content ) | ||||
| 		return null_array; | ||||
| 	} | ||||
|  | ||||
| 	for ( StringCached* entry = array_begin(PreprocessorDefines); entry != array_end(PreprocessorDefines); entry = array_next(PreprocessorDefines, entry)) | ||||
| 	for ( StrCached* entry = array_begin(_ctx->PreprocessorDefines); entry != array_end(_ctx->PreprocessorDefines); entry = array_next(_ctx->PreprocessorDefines, entry)) | ||||
| 	{ | ||||
| 		s32         length  = 0; | ||||
| 		char const* entry_scanner = (*entry).Ptr; | ||||
| @@ -602,7 +495,7 @@ TokArray lex( Str content ) | ||||
| 		hashtable_set(c.defines, key, * entry ); | ||||
| 	} | ||||
|  | ||||
| 	array_clear(Lexer_Tokens); | ||||
| 	array_clear(_ctx->Lexer_Tokens); | ||||
|  | ||||
| 	while (c.left ) | ||||
| 	{ | ||||
| @@ -635,7 +528,7 @@ TokArray lex( Str content ) | ||||
| 				c.token.Type = Tok_NewLine; | ||||
| 				c.token.Text.Len++; | ||||
|  | ||||
| 				array_append( Lexer_Tokens, c.token ); | ||||
| 				array_append( _ctx->Lexer_Tokens, c.token ); | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| @@ -674,7 +567,7 @@ TokArray lex( Str content ) | ||||
| 								c.token.Text.Len++; | ||||
| 								move_forward(); | ||||
|  | ||||
| 								array_append( Lexer_Tokens, c.token ); | ||||
| 								array_append( _ctx->Lexer_Tokens, c.token ); | ||||
| 							} | ||||
| 						} | ||||
| 						continue; | ||||
| @@ -710,7 +603,7 @@ TokArray lex( Str content ) | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						StrBuilder context_str = strbuilder_fmt_buf( GlobalAllocator, "%s", c.scanner, min( 100, c.left ) ); | ||||
| 						StrBuilder context_str = strbuilder_fmt_buf( _ctx->Allocator_Temp, "%s", c.scanner, min( 100, c.left ) ); | ||||
|  | ||||
| 						log_failure( "gen::lex: invalid varadic argument, expected '...' got '..%c' (%d, %d)\n%s", (* ctx->scanner), c.line, c.column, context_str ); | ||||
| 					} | ||||
| @@ -1131,7 +1024,7 @@ TokArray lex( Str content ) | ||||
| 							move_forward(); | ||||
| 							c.token.Text.Len++; | ||||
| 						} | ||||
| 						array_append( Lexer_Tokens, c.token ); | ||||
| 						array_append( _ctx->Lexer_Tokens, c.token ); | ||||
| 						continue; | ||||
| 					} | ||||
| 					else if ( (* ctx->scanner) == '*' ) | ||||
| @@ -1167,7 +1060,7 @@ TokArray lex( Str content ) | ||||
| 							move_forward(); | ||||
| 							c.token.Text.Len++; | ||||
| 						} | ||||
| 						array_append( Lexer_Tokens, c.token ); | ||||
| 						array_append( _ctx->Lexer_Tokens, c.token ); | ||||
| 						// end_line(); | ||||
| 						continue; | ||||
| 					} | ||||
| @@ -1260,18 +1153,18 @@ TokArray lex( Str content ) | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			s32 start = max( 0, array_num(Lexer_Tokens) - 100 ); | ||||
| 			s32 start = max( 0, array_num(_ctx->Lexer_Tokens) - 100 ); | ||||
| 			log_fmt("\n%d\n", start); | ||||
| 			for ( s32 idx = start; idx < array_num(Lexer_Tokens); idx++ ) | ||||
| 			for ( s32 idx = start; idx < array_num(_ctx->Lexer_Tokens); idx++ ) | ||||
| 			{ | ||||
| 				log_fmt( "Token %d Type: %s : %.*s\n" | ||||
| 					, idx | ||||
| 					, toktype_to_str( Lexer_Tokens[ idx ].Type ).Ptr | ||||
| 					, Lexer_Tokens[ idx ].Text.Len, Lexer_Tokens[ idx ].Text.Ptr | ||||
| 					, toktype_to_str( _ctx->Lexer_Tokens[ idx ].Type ).Ptr | ||||
| 					, _ctx->Lexer_Tokens[ idx ].Text.Len, _ctx->Lexer_Tokens[ idx ].Text.Ptr | ||||
| 				); | ||||
| 			} | ||||
|  | ||||
| 			StrBuilder context_str = strbuilder_fmt_buf( GlobalAllocator, "%.*s", min( 100, c.left ), c.scanner ); | ||||
| 			StrBuilder context_str = strbuilder_fmt_buf( _ctx->Allocator_Temp, "%.*s", min( 100, c.left ), c.scanner ); | ||||
| 			log_failure( "Failed to lex token '%c' (%d, %d)\n%s", (* ctx->scanner), c.line, c.column, context_str ); | ||||
|  | ||||
| 			// Skip to next whitespace since we can't know if anything else is valid until then. | ||||
| @@ -1284,7 +1177,7 @@ TokArray lex( Str content ) | ||||
| 		FoundToken: | ||||
| 		{ | ||||
| 			lex_found_token( ctx ); | ||||
| 			TokType last_type = array_back(Lexer_Tokens)->Type; | ||||
| 			TokType last_type = array_back(_ctx->Lexer_Tokens)->Type; | ||||
| 			if ( last_type == Tok_Preprocess_Macro ) | ||||
| 			{ | ||||
| 				Token thanks_c = { { c.scanner, 0 }, Tok_Invalid, c.line, c.column, TF_Null }; | ||||
| @@ -1301,14 +1194,14 @@ TokArray lex( Str content ) | ||||
| 					c.token.Text.Len++; | ||||
| 					move_forward(); | ||||
|  | ||||
| 					array_append( Lexer_Tokens, c.token ); | ||||
| 					array_append( _ctx->Lexer_Tokens, c.token ); | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if ( array_num(Lexer_Tokens) == 0 ) | ||||
| 	if ( array_num(_ctx->Lexer_Tokens) == 0 ) | ||||
| 	{ | ||||
| 		log_failure( "Failed to lex any tokens" ); | ||||
| 		{ | ||||
| @@ -1317,13 +1210,11 @@ TokArray lex( Str content ) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	hashtable_clear(Lexer_defines); | ||||
| 	hashtable_clear(_ctx->Lexer_defines); | ||||
| 	// defines_map_arena.free(); | ||||
| 	TokArray result = { Lexer_Tokens, 0 }; | ||||
| 	TokArray result = { _ctx->Lexer_Tokens, 0 }; | ||||
| 	return result; | ||||
| } | ||||
| #undef move_forward | ||||
| #undef skip_whitespace | ||||
| #undef end_line | ||||
|  | ||||
| GEN_NS_PARSER_END | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										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 | ||||
|   | ||||
| @@ -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          } | ||||
|   | ||||
| @@ -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,9 +13,9 @@ 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; | ||||
| @@ -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,8 +97,8 @@ 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; | ||||
| @@ -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 | ||||
| @@ -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 | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 ); | ||||
|   | ||||
| @@ -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" ); | ||||
| @@ -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); | ||||
| @@ -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); | ||||
| @@ -647,9 +742,9 @@ do                          \ | ||||
| 					{ | ||||
| 						Str   old_prefix  = txt("code_"); | ||||
| 						Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len }; | ||||
| 						StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name ); | ||||
| 						StrBuilder new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "code__%S", actual_name ); | ||||
|  | ||||
| 						fn->Name = get_cached_string(new_name); | ||||
| 						fn->Name = cache_str(new_name); | ||||
| 						code_c_interface.append(fn); | ||||
| 					} | ||||
| 					ast.append(entry); | ||||
| @@ -702,7 +797,7 @@ R"(#define AST_ArrSpecs_Cap \ | ||||
| (                           \ | ||||
| 	AST_POD_Size              \ | ||||
| 	- sizeof(Code)            \ | ||||
| 	- sizeof(StringCached)    \ | ||||
| 	- sizeof(StrCached)    \ | ||||
| 	- sizeof(Code) * 2        \ | ||||
| 	- sizeof(Token*)          \ | ||||
| 	- sizeof(Code)            \ | ||||
| @@ -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.Ptr + private_prefix.Len, fn->Name.Len - private_prefix.Len }; | ||||
| 				StrBuilder interface_name  = StrBuilder::fmt_buf(GlobalAllocator, "code_%S", actual_name ); | ||||
| 				StrBuilder interface_name  = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "code_%S", actual_name ); | ||||
|  | ||||
| 				// Resolve generic's arguments | ||||
| 				b32    has_args   = fn->Params->NumEntries > 1; | ||||
| 				StrBuilder params_str = StrBuilder::make_reserve(GlobalAllocator, 32); | ||||
| 				StrBuilder params_str = StrBuilder::make_reserve(_ctx->Allocator_Temp, 32); | ||||
| 				for (CodeParams param = fn->Params->Next; param != fn->Params.end(); ++ param) { | ||||
| 					// We skip the first parameter as its always going to be the code for selection | ||||
| 					if (param->Next == nullptr) { | ||||
| @@ -910,6 +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(); | ||||
| 			} | ||||
|  | ||||
| @@ -942,11 +1040,11 @@ 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.Ptr + prefix.Len, fn->Name.Len  - prefix.Len }; | ||||
| 				Str new_name    = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str(); | ||||
| 				Str new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str(); | ||||
|  | ||||
| 				// Resolve define's arguments | ||||
| 				b32    has_args   = fn->Params->NumEntries > 1; | ||||
| 				StrBuilder params_str = StrBuilder::make_reserve(GlobalAllocator, 32); | ||||
| 				StrBuilder params_str = StrBuilder::make_reserve(_ctx->Allocator_Temp, 32); | ||||
| 				for (CodeParams other_param = fn->Params; other_param != opt_param; ++ other_param) { | ||||
| 					if ( other_param == opt_param ) { | ||||
| 						params_str.append_fmt( "%S", other_param->Name ); | ||||
| @@ -970,7 +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) { | ||||
| @@ -1021,9 +1119,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 			{ | ||||
| 				Str   old_prefix  = txt("code_"); | ||||
| 				Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len }; | ||||
| 				StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name ); | ||||
| 				StrBuilder new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "code__%S", actual_name ); | ||||
|  | ||||
| 				fn->Name = get_cached_string(new_name); | ||||
| 				fn->Name = cache_str(new_name); | ||||
| 			} | ||||
| 			inlines.append(entry); | ||||
| 		} | ||||
| @@ -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" ); | ||||
| @@ -1176,9 +1270,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 			{ | ||||
| 				Str   old_prefix  = txt("code_"); | ||||
| 				Str   actual_name = { fn->Name.Ptr + old_prefix.Len, fn->Name.Len  - old_prefix.Len }; | ||||
| 				StrBuilder new_name    = StrBuilder::fmt_buf(GlobalAllocator, "code__%S", actual_name ); | ||||
| 				StrBuilder new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "code__%S", actual_name ); | ||||
|  | ||||
| 				fn->Name = get_cached_string(new_name); | ||||
| 				fn->Name = cache_str(new_name); | ||||
| 			} | ||||
| 			src_ast.append(entry); | ||||
| 		} | ||||
| @@ -1219,8 +1313,8 @@ 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(); | ||||
| 				} | ||||
|  | ||||
| @@ -1228,9 +1322,9 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 			{ | ||||
| 				Str prefix      = txt("def_"); | ||||
| 				Str actual_name = { fn->Name.Ptr + prefix.Len, fn->Name.Len  - prefix.Len }; | ||||
| 				Str new_name    = StrBuilder::fmt_buf(GlobalAllocator, "def__%S", actual_name ).to_str(); | ||||
| 				Str new_name    = StrBuilder::fmt_buf(_ctx->Allocator_Temp, "def__%S", actual_name ).to_str(); | ||||
|  | ||||
| 				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); | ||||
| @@ -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,10 +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_fmt( "GEN_API_C_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 ); | ||||
| @@ -1517,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"); | ||||
| @@ -1525,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); | ||||
|  | ||||
| @@ -1533,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 ); | ||||
| @@ -1573,11 +1632,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \ | ||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | ||||
| 		header.print_fmt( "GEN_API_C_BEGIN\n" ); | ||||
|  | ||||
| 		header.print( fmt_newline); | ||||
| 		header.print( rf_array_arena ); | ||||
| 		header.print( fmt_newline); | ||||
| 		header.print( rf_array_pool); | ||||
|  | ||||
| 		header.print( r_src_static_data ); | ||||
| 		header.print( fmt_newline); | ||||
|  | ||||
| @@ -1591,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 ); | ||||
| @@ -1646,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" ); | ||||
| @@ -1684,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"); | ||||
| @@ -1737,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 ); | ||||
| @@ -1751,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; | ||||
| } | ||||
|   | ||||
| @@ -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,23 +432,8 @@ word preprocess_else, gen_preprocess_else | ||||
| namespace spec_, gen_spec_ | ||||
| namespace t_,    gen_t_ | ||||
|  | ||||
| word PreprocessorDefines, gen_PreprocessorDefines | ||||
|  | ||||
| // Backend | ||||
|  | ||||
| word GlobalAllocator,         gen_GlobalAllocator | ||||
| word Global_AllocatorBuckets, gen_Global_AllocatorBuckets | ||||
| word CodePools,               gen_CodePools | ||||
| word StringArenas,            gen_StringArenas | ||||
| word StringCache,             gen_StringCache | ||||
| word LexArena,                gen_LexArena | ||||
| word Allocator_DataArrays,    gen_Allocator_DataArrays | ||||
| word Allocator_CodePool,      gen_Allocator_CodePool | ||||
| word Allocator_Lexer,         gen_Allocator_Lexer | ||||
| word Allocator_StringArena,   gen_Allocator_StringArena | ||||
| word Allocator_StringTable,   gen_Allocator_StringTable | ||||
| word Allocator_TypeTable,     gen_Allocator_TypeTable | ||||
|  | ||||
| // Builder | ||||
|  | ||||
| word      Builder,  gen_Builder | ||||
| @@ -518,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 | ||||
|  | ||||
| @@ -527,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" ); | ||||
| @@ -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 ); | ||||
| @@ -282,6 +282,6 @@ int gen_main() | ||||
| 		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" ); | ||||
| @@ -111,17 +112,19 @@ int gen_main() | ||||
| 			header.print( fmt_newline ); | ||||
| 		} | ||||
|  | ||||
| 		Code types      = scan_file( path_base "components/types.hpp" ); | ||||
| 		Code ast        = scan_file( path_base "components/ast.hpp" ); | ||||
| 		Code ast_types  = scan_file( path_base "components/ast_types.hpp" ); | ||||
| 		Code code_types = scan_file( path_base "components/code_types.hpp" ); | ||||
| 		Code interface  = scan_file( path_base "components/interface.hpp" ); | ||||
| 		Code inlines 	= scan_file( path_base "components/inlines.hpp" ); | ||||
| 		Code header_end = scan_file( path_base "components/header_end.hpp" ); | ||||
| 		Code types        = scan_file( path_base "components/types.hpp" ); | ||||
| 		Code parser_types = scan_file( path_base "components/parser_types.hpp"); | ||||
| 		Code ast          = scan_file( path_base "components/ast.hpp" ); | ||||
| 		Code ast_types    = scan_file( path_base "components/ast_types.hpp" ); | ||||
| 		Code code_types   = scan_file( path_base "components/code_types.hpp" ); | ||||
| 		Code interface    = scan_file( path_base "components/interface.hpp" ); | ||||
| 		Code inlines 	  = scan_file( path_base "components/inlines.hpp" ); | ||||
| 		Code header_end   = scan_file( path_base "components/header_end.hpp" ); | ||||
|  | ||||
| 		CodeBody ecode       = gen_ecode     ( path_base "enums/ECodeTypes.csv" ); | ||||
| 		CodeBody eoperator   = gen_eoperator ( path_base "enums/EOperator.csv" ); | ||||
| 		CodeBody especifier  = gen_especifier( path_base "enums/ESpecifier.csv" ); | ||||
| 		CodeBody etoktype    = gen_etoktype  ( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv" ); | ||||
| 		CodeBody ast_inlines = gen_ast_inlines(); | ||||
|  | ||||
| 		header.print_fmt( "GEN_NS_BEGIN\n\n" ); | ||||
| @@ -135,6 +138,9 @@ int gen_main() | ||||
| 		header.print( fmt_newline ); | ||||
| 		header.print( format( especifier )); | ||||
| 		header.print( fmt_newline ); | ||||
| 		header.print( format( etoktype )); | ||||
| 		header.print( parser_types ); | ||||
| 		header.print( fmt_newline ); | ||||
| 		header.print_fmt("#pragma endregion Types\n\n"); | ||||
|  | ||||
| 		header.print_fmt("#pragma region AST\n"); | ||||
| @@ -215,10 +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" ); | ||||
|  | ||||
| 		header.print_fmt( "\nGEN_NS_BEGIN\n"); | ||||
| 		header.print( static_data ); | ||||
| 		header.print( fmt_newline); | ||||
|  | ||||
| 		header.print_fmt( "#pragma region AST\n\n" ); | ||||
| 		header.print( ast_case_macros ); | ||||
| @@ -230,12 +235,13 @@ int gen_main() | ||||
| 		header.print( interface ); | ||||
| 		header.print( upfront ); | ||||
| 		header.print_fmt( "\n#pragma region Parsing\n\n" ); | ||||
| 		header.print( format(etoktype) ); | ||||
| 		header.print( lexer ); | ||||
| 		header.print( parser ); | ||||
| 		header.print( parsing_interface ); | ||||
| 		header.print_fmt( "\n#pragma endregion Parsing\n" ); | ||||
| 		header.print_fmt("\n#pragma region Untyped\n"); | ||||
| 		header.print( untyped ); | ||||
| 		header.print_fmt("\n#pragma endregion Untyped\n"); | ||||
| 		header.print_fmt( "\n#pragma endregion Interface\n"); | ||||
|  | ||||
| 		if ( generate_builder ) { | ||||
| @@ -255,6 +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,7 +68,7 @@ int gen_main() | ||||
| 	{ | ||||
| 		CodeBody macros = def_body( CT_Global_Body ); | ||||
| 		{ | ||||
| 			FileContents content    = file_read_contents( GlobalAllocator, true, path_base "dependencies/macros.hpp" ); | ||||
| 			FileContents content    = file_read_contents( ctx.Allocator_Temp, file_zero_terminate, path_base "dependencies/macros.hpp" ); | ||||
| 			CodeBody     ori_macros = parse_global_body( Str { (char const*)content.data, content.size }); | ||||
|  | ||||
| 			for (Code	code =  ori_macros.begin(); | ||||
| @@ -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" ); | ||||
| @@ -230,7 +239,7 @@ int gen_main() | ||||
|  | ||||
| 	// gen.cpp | ||||
| 	{ | ||||
| 		Code        src_start          = scan_file(             "components/src_start.cpp" ); | ||||
| 		Code        src_start          = scan_file(           "components/src_start.cpp" ); | ||||
| 		Code        static_data 	   = scan_file( path_base "components/static_data.cpp" ); | ||||
| 		Code        ast_case_macros    = scan_file( path_base "components/ast_case_macros.cpp" ); | ||||
| 		Code        ast			       = scan_file( path_base "components/ast.cpp" ); | ||||
| @@ -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 ); | ||||
|   | ||||
| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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