mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 14:30:53 -07:00 
			
		
		
		
	Started to implement context stack for parser.
This commit is contained in:
		
							
								
								
									
										30
									
								
								Readme.md
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								Readme.md
									
									
									
									
									
								
							| @@ -5,11 +5,6 @@ An attempt at simple staged metaprogramming for c/c++. | |||||||
| The library API is a composition of code element constructors.   | The library API is a composition of code element constructors.   | ||||||
| These build up a code AST to then serialize with a file builder. | These build up a code AST to then serialize with a file builder. | ||||||
|  |  | ||||||
| General goal is to have a less than 15k sloc library that takes at most a couple of hours to learn and make use of. |  | ||||||
|  |  | ||||||
| *Why 15k ?* Assuming a seasoned coder of C++ can read and understand around 1000-2000 lines of code per hour, 15,000 could be understood in under 16-18 hours |  | ||||||
| and have confidence in modifying for their use case. |  | ||||||
|  |  | ||||||
| This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto),   | This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto),   | ||||||
| its not meant to be a black box metaprogramming utility, its meant for the user to extend for their project domain. | its not meant to be a black box metaprogramming utility, its meant for the user to extend for their project domain. | ||||||
|  |  | ||||||
| @@ -30,17 +25,17 @@ The project has reached an *alpha* state, all the current functionality works fo | |||||||
|  |  | ||||||
| The project has no external dependencies beyond: | The project has no external dependencies beyond: | ||||||
|  |  | ||||||
| * `errno.h`    (gen.dep.cpp) | * `errno.h` | ||||||
| * `stat.h`     (gen.dep.cpp) | * `stat.h` | ||||||
| * `stdarg.h`   (gen.dep.hpp) | * `stdarg.h` | ||||||
| * `stddef.h`   (gen.dep.hpp | * `stddef.h` | ||||||
| * `stdio.h`    (gen.dep.cpp) | * `stdio.h` | ||||||
| * `copyfile.h` (Mac, gen.dep.cpp) | * `copyfile.h` (Mac) | ||||||
| * `types.h`    (Linux, gen.dep.cpp) | * `types.h`    (Linux) | ||||||
| * `unistd.h`   (Linux/Mac, gen.dep.cpp) | * `unistd.h`   (Linux/Mac) | ||||||
| * `intrin.h`   (Windows, gen.dep.hpp) | * `intrin.h`   (Windows) | ||||||
| * `io.h`       (Windows with gcc, gen.dep.cpp) | * `io.h`       (Windows with gcc) | ||||||
| * `windows.h`  (Windows, gen.dep.cpp) | * `windows.h`  (Windows) | ||||||
|  |  | ||||||
| Dependencies for the project are wrapped within `GENCPP_ROLL_OWN_DEPENDENCIES` (Defining it will disable them).   | Dependencies for the project are wrapped within `GENCPP_ROLL_OWN_DEPENDENCIES` (Defining it will disable them).   | ||||||
| The majority of the dependency's implementation was derived from the [c-zpl library](https://github.com/zpl-c/zpl). | The majority of the dependency's implementation was derived from the [c-zpl library](https://github.com/zpl-c/zpl). | ||||||
| @@ -561,6 +556,7 @@ The following are provided predefined by the library as they are commonly used: | |||||||
| * `access_private` | * `access_private` | ||||||
| * `module_global_fragment` | * `module_global_fragment` | ||||||
| * `module_private_fragment` | * `module_private_fragment` | ||||||
|  | * `param_varaidc` (Used for varadic definitions) | ||||||
| * `pragma_once` | * `pragma_once` | ||||||
| * `spec_const` | * `spec_const` | ||||||
| * `spec_consteval` | * `spec_consteval` | ||||||
| @@ -586,7 +582,7 @@ The following are provided predefined by the library as they are commonly used: | |||||||
| * `spec_type_unsigned` | * `spec_type_unsigned` | ||||||
| * `spec_type_short` | * `spec_type_short` | ||||||
| * `spec_type_long` | * `spec_type_long` | ||||||
| * `t_empty` | * `t_empty` (Used for varaidc macros) | ||||||
| * `t_auto` | * `t_auto` | ||||||
| * `t_void` | * `t_void` | ||||||
| * `t_int` | * `t_int` | ||||||
|   | |||||||
| @@ -37,8 +37,12 @@ Module_Import,          "import" | |||||||
| Module_Export,          "export" | Module_Export,          "export" | ||||||
| Number,                 "number" | Number,                 "number" | ||||||
| Operator,               "operator" | Operator,               "operator" | ||||||
| Preprocessor_Directive, "#" | Preprocess_Define,      "#define" | ||||||
| Preprocessor_Include,   "include" | Preprocess_Include,     "#include" | ||||||
|  | Preprocess_If,          "#if" | ||||||
|  | Preprocess_ElIF,		"#elif" | ||||||
|  | Preprocess_Else,        "#else" | ||||||
|  | Preprocess_EndIf,       "#endif" | ||||||
| Spec_Alignas,           "alignas" | Spec_Alignas,           "alignas" | ||||||
| Spec_Const,             "const" | Spec_Const,             "const" | ||||||
| Spec_Consteval,         "consteval" | Spec_Consteval,         "consteval" | ||||||
|   | |||||||
| 
 | 
| @@ -778,7 +778,7 @@ bool AST::validate_body() | |||||||
| 	switch ( Type ) | 	switch ( Type ) | ||||||
| 	{ | 	{ | ||||||
| 		case Class_Body: | 		case Class_Body: | ||||||
| 			CheckEntries( AST_BODY_CLASS_UNALLOWED_TYPES ); | 			CheckEntries( GEN_AST_BODY_CLASS_UNALLOWED_TYPES ); | ||||||
| 		break; | 		break; | ||||||
| 		case Enum_Body: | 		case Enum_Body: | ||||||
| 			for ( Code entry : cast<CodeBody>() ) | 			for ( Code entry : cast<CodeBody>() ) | ||||||
| @@ -791,22 +791,22 @@ bool AST::validate_body() | |||||||
| 			} | 			} | ||||||
| 		break; | 		break; | ||||||
| 		case Export_Body: | 		case Export_Body: | ||||||
| 			CheckEntries( AST_BODY_CLASS_UNALLOWED_TYPES ); | 			CheckEntries( GEN_AST_BODY_CLASS_UNALLOWED_TYPES ); | ||||||
| 		break; | 		break; | ||||||
| 		case Extern_Linkage: | 		case Extern_Linkage: | ||||||
| 			CheckEntries( AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES ); | 			CheckEntries( GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES ); | ||||||
| 		break; | 		break; | ||||||
| 		case Function_Body: | 		case Function_Body: | ||||||
| 			CheckEntries( AST_BODY_FUNCTION_UNALLOWED_TYPES ); | 			CheckEntries( GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES ); | ||||||
| 		break; | 		break; | ||||||
| 		case Global_Body: | 		case Global_Body: | ||||||
| 			CheckEntries( AST_BODY_GLOBAL_UNALLOWED_TYPES ); | 			CheckEntries( GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES ); | ||||||
| 		break; | 		break; | ||||||
| 		case Namespace_Body: | 		case Namespace_Body: | ||||||
| 			CheckEntries( AST_BODY_NAMESPACE_UNALLOWED_TYPES ); | 			CheckEntries( GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES ); | ||||||
| 		break; | 		break; | ||||||
| 		case Struct_Body: | 		case Struct_Body: | ||||||
| 			CheckEntries( AST_BODY_STRUCT_UNALLOWED_TYPES ); | 			CheckEntries( GEN_AST_BODY_STRUCT_UNALLOWED_TYPES ); | ||||||
| 		break; | 		break; | ||||||
| 		case Union_Body: | 		case Union_Body: | ||||||
| 			for ( Code entry : Body->cast<CodeBody>() ) | 			for ( Code entry : Body->cast<CodeBody>() ) | ||||||
|   | |||||||
| @@ -1,81 +1,79 @@ | |||||||
| #	define AST_BODY_CLASS_UNALLOWED_TYPES \ | #	define GEN_AST_BODY_CLASS_UNALLOWED_TYPES \ | ||||||
| 	case PlatformAttributes:              \ |  | ||||||
| 	case Class_Body:                      \ |  | ||||||
| 	case Enum_Body:                       \ |  | ||||||
| 	case Extern_Linkage:                  \ |  | ||||||
| 	case Function_Body:                   \ |  | ||||||
| 	case Function_Fwd:                    \ |  | ||||||
| 	case Global_Body:                     \ |  | ||||||
| 	case Namespace:                       \ |  | ||||||
| 	case Namespace_Body:                  \ |  | ||||||
| 	case Operator:                        \ |  | ||||||
| 	case Operator_Fwd:                    \ |  | ||||||
| 	case Parameters:                      \ |  | ||||||
| 	case Specifiers:                      \ |  | ||||||
| 	case Struct_Body:                     \ |  | ||||||
| 	case Typename: |  | ||||||
|  |  | ||||||
| #	define AST_BODY_FUNCTION_UNALLOWED_TYPES \ |  | ||||||
| 	case Access_Public:                      \ |  | ||||||
| 	case Access_Protected:                   \ |  | ||||||
| 	case Access_Private:                     \ |  | ||||||
| 	case PlatformAttributes:                 \ |  | ||||||
| 	case Class_Body:                         \ |  | ||||||
| 	case Enum_Body:                          \ |  | ||||||
| 	case Extern_Linkage:                     \ |  | ||||||
| 	case Friend:                             \ |  | ||||||
| 	case Function_Body:                      \ |  | ||||||
| 	case Function_Fwd:                       \ |  | ||||||
| 	case Global_Body:                        \ |  | ||||||
| 	case Namespace:                          \ |  | ||||||
| 	case Namespace_Body:                     \ |  | ||||||
| 	case Operator:                           \ |  | ||||||
| 	case Operator_Fwd:                       \ |  | ||||||
| 	case Operator_Member:                    \ |  | ||||||
| 	case Operator_Member_Fwd:                \ |  | ||||||
| 	case Parameters:                         \ |  | ||||||
| 	case Specifiers:                         \ |  | ||||||
| 	case Struct_Body:                        \ |  | ||||||
| 	case Typename: |  | ||||||
|  |  | ||||||
| #	define AST_BODY_GLOBAL_UNALLOWED_TYPES \ |  | ||||||
| 	case Access_Public: 				   \ |  | ||||||
| 	case Access_Protected: 				   \ |  | ||||||
| 	case Access_Private: 				   \ |  | ||||||
| 	case PlatformAttributes:               \ |  | ||||||
| 	case Class_Body: 					   \ |  | ||||||
| 	case Enum_Body: 					   \ |  | ||||||
| 	case Execution: 					   \ |  | ||||||
| 	case Friend: 						   \ |  | ||||||
| 	case Function_Body: 				   \ |  | ||||||
| 	case Global_Body: 					   \ |  | ||||||
| 	case Namespace_Body: 				   \ |  | ||||||
| 	case Operator_Member: 				   \ |  | ||||||
| 	case Operator_Member_Fwd: 			   \ |  | ||||||
| 	case Parameters: 					   \ |  | ||||||
| 	case Specifiers: 					   \ |  | ||||||
| 	case Struct_Body: 					   \ |  | ||||||
| 	case Typename: |  | ||||||
|  |  | ||||||
| #	define AST_BODY_EXPORT_UNALLOWED_TYPES         AST_BODY_GLOBAL_UNALLOWED_TYPES |  | ||||||
| #	define AST_BODY_NAMESPACE_UNALLOWED_TYPES \ |  | ||||||
| 	case Access_Public: 				      \ |  | ||||||
| 	case Access_Protected: 				      \ |  | ||||||
| 	case Access_Private: 				      \ |  | ||||||
| 	case PlatformAttributes:                  \ | 	case PlatformAttributes:                  \ | ||||||
| 	case Class_Body: 					      \ | 	case Class_Body:                          \ | ||||||
| 	case Enum_Body: 					      \ | 	case Enum_Body:                           \ | ||||||
| 	case Execution: 					      \ | 	case Extern_Linkage:                      \ | ||||||
| 	case Friend: 						      \ | 	case Function_Body:                       \ | ||||||
| 	case Function_Body: 				      \ | 	case Function_Fwd:                        \ | ||||||
| 	case Namespace_Body: 				      \ | 	case Global_Body:                         \ | ||||||
| 	case Operator_Member: 				      \ | 	case Namespace:                           \ | ||||||
| 	case Operator_Member_Fwd: 			      \ | 	case Namespace_Body:                      \ | ||||||
| 	case Parameters: 					      \ | 	case Operator:                            \ | ||||||
| 	case Specifiers: 					      \ | 	case Operator_Fwd:                        \ | ||||||
| 	case Struct_Body: 					      \ | 	case Parameters:                          \ | ||||||
|  | 	case Specifiers:                          \ | ||||||
|  | 	case Struct_Body:                         \ | ||||||
|  | 	case Typename: | ||||||
|  | #	define GEN_AST_BODY_STRUCT_UNALLOWED_TYPES GEN_AST_BODY_CLASS_UNALLOWED_TYPES | ||||||
|  |  | ||||||
|  | #	define GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES \ | ||||||
|  | 	case Access_Public:                          \ | ||||||
|  | 	case Access_Protected:                       \ | ||||||
|  | 	case Access_Private:                         \ | ||||||
|  | 	case PlatformAttributes:                     \ | ||||||
|  | 	case Class_Body:                             \ | ||||||
|  | 	case Enum_Body:                              \ | ||||||
|  | 	case Extern_Linkage:                         \ | ||||||
|  | 	case Friend:                                 \ | ||||||
|  | 	case Function_Body:                          \ | ||||||
|  | 	case Function_Fwd:                           \ | ||||||
|  | 	case Global_Body:                            \ | ||||||
|  | 	case Namespace:                              \ | ||||||
|  | 	case Namespace_Body:                         \ | ||||||
|  | 	case Operator:                               \ | ||||||
|  | 	case Operator_Fwd:                           \ | ||||||
|  | 	case Operator_Member:                        \ | ||||||
|  | 	case Operator_Member_Fwd:                    \ | ||||||
|  | 	case Parameters:                             \ | ||||||
|  | 	case Specifiers:                             \ | ||||||
|  | 	case Struct_Body:                            \ | ||||||
| 	case Typename: | 	case Typename: | ||||||
|  |  | ||||||
| #	define AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES AST_BODY_GLOBAL_UNALLOWED_TYPES | #	define GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES \ | ||||||
|  | 	case Access_Public: 				       \ | ||||||
|  | 	case Access_Protected: 				       \ | ||||||
|  | 	case Access_Private: 				       \ | ||||||
|  | 	case PlatformAttributes:                   \ | ||||||
|  | 	case Class_Body: 					       \ | ||||||
|  | 	case Enum_Body: 					       \ | ||||||
|  | 	case Execution: 					       \ | ||||||
|  | 	case Friend: 						       \ | ||||||
|  | 	case Function_Body: 				       \ | ||||||
|  | 	case Global_Body: 					       \ | ||||||
|  | 	case Namespace_Body: 				       \ | ||||||
|  | 	case Operator_Member: 				       \ | ||||||
|  | 	case Operator_Member_Fwd: 			       \ | ||||||
|  | 	case Parameters: 					       \ | ||||||
|  | 	case Specifiers: 					       \ | ||||||
|  | 	case Struct_Body: 					       \ | ||||||
|  | 	case Typename: | ||||||
|  | #	define GEN_AST_BODY_EXPORT_UNALLOWED_TYPES         GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||||
|  | #	define GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||||
|  |  | ||||||
| #	define AST_BODY_STRUCT_UNALLOWED_TYPES         AST_BODY_CLASS_UNALLOWED_TYPES | #	define GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES \ | ||||||
|  | 	case Access_Public: 				          \ | ||||||
|  | 	case Access_Protected: 				          \ | ||||||
|  | 	case Access_Private: 				          \ | ||||||
|  | 	case PlatformAttributes:                      \ | ||||||
|  | 	case Class_Body: 					          \ | ||||||
|  | 	case Enum_Body: 					          \ | ||||||
|  | 	case Execution: 					          \ | ||||||
|  | 	case Friend: 						          \ | ||||||
|  | 	case Function_Body: 				          \ | ||||||
|  | 	case Namespace_Body: 				          \ | ||||||
|  | 	case Operator_Member: 				          \ | ||||||
|  | 	case Operator_Member_Fwd: 			          \ | ||||||
|  | 	case Parameters: 					          \ | ||||||
|  | 	case Specifiers: 					          \ | ||||||
|  | 	case Struct_Body: 					          \ | ||||||
|  | 	case Typename: | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| #pragma region StaticData | #pragma region StaticData | ||||||
|  |  | ||||||
| // TODO : Convert global allocation strategy to use a slab allocation strategy. | // TODO : Convert global allocation strategy to use a slab allocation strategy. | ||||||
| global AllocatorInfo  GlobalAllocator; | global AllocatorInfo  GlobalAllocator; | ||||||
| global Array<Arena>   Global_AllocatorBuckets; | global Array<Arena>   Global_AllocatorBuckets; | ||||||
| @@ -16,9 +17,11 @@ global AllocatorInfo Allocator_Lexer       = heap(); | |||||||
| global AllocatorInfo Allocator_StringArena = heap(); | global AllocatorInfo Allocator_StringArena = heap(); | ||||||
| global AllocatorInfo Allocator_StringTable = heap(); | global AllocatorInfo Allocator_StringTable = heap(); | ||||||
| global AllocatorInfo Allocator_TypeTable   = heap(); | global AllocatorInfo Allocator_TypeTable   = heap(); | ||||||
|  |  | ||||||
| #pragma endregion StaticData | #pragma endregion StaticData | ||||||
|  |  | ||||||
| #pragma region Constants | #pragma region Constants | ||||||
|  |  | ||||||
| global CodeType t_empty; | global CodeType t_empty; | ||||||
| global CodeType t_auto; | global CodeType t_auto; | ||||||
| global CodeType t_void; | global CodeType t_void; | ||||||
| @@ -83,4 +86,5 @@ global CodeSpecifiers spec_static_member; | |||||||
| global CodeSpecifiers spec_thread_local; | global CodeSpecifiers spec_thread_local; | ||||||
| global CodeSpecifiers spec_virtual; | global CodeSpecifiers spec_virtual; | ||||||
| global CodeSpecifiers spec_volatile; | global CodeSpecifiers spec_volatile; | ||||||
|  |  | ||||||
| #pragma endregion Constants | #pragma endregion Constants | ||||||
|   | |||||||
| @@ -9,6 +9,12 @@ namespace Parser | |||||||
| 	Attributes_Start is only used to indicate the start of the user_defined attribute list. | 	Attributes_Start is only used to indicate the start of the user_defined attribute list. | ||||||
| */ | */ | ||||||
|  |  | ||||||
|  | #ifndef GEN_Define_Attribute_Tokens | ||||||
|  | #	define GEN_Define_Attribute_Tokens         \ | ||||||
|  | 	Entry( API_Export, "GEN_API_Export_Code" ) \ | ||||||
|  | 	Entry( API_Import, "GEN_API_Import_Code" ) | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #	define Define_TokType \ | #	define Define_TokType \ | ||||||
| 	Entry( Invalid,                "INVALID" )          \ | 	Entry( Invalid,                "INVALID" )          \ | ||||||
| 	Entry( Access_Private,         "private" )          \ | 	Entry( Access_Private,         "private" )          \ | ||||||
| @@ -49,8 +55,12 @@ namespace Parser | |||||||
| 	Entry( Module_Export,          "export" )           \ | 	Entry( Module_Export,          "export" )           \ | ||||||
| 	Entry( Number,                 "number" )           \ | 	Entry( Number,                 "number" )           \ | ||||||
| 	Entry( Operator,               "operator" )         \ | 	Entry( Operator,               "operator" )         \ | ||||||
| 	Entry( Preprocessor_Directive, "#")                 \ | 	Entry( Preprocess_Define,      "#define")           \ | ||||||
| 	Entry( Preprocessor_Include,   "include" )          \ | 	Entry( Preproces_Include,      "include" )          \ | ||||||
|  | 	Entry( Preprocess_If,          "#if")               \ | ||||||
|  | 	Entry( Preprocess_Elif,        "#elif")             \ | ||||||
|  | 	Entry( Preprocess_Else,        "#else")             \ | ||||||
|  | 	Entry( Preprocess_EndIf,       "#endif")            \ | ||||||
| 	Entry( Spec_Alignas,           "alignas" )          \ | 	Entry( Spec_Alignas,           "alignas" )          \ | ||||||
| 	Entry( Spec_Const,             "const" )            \ | 	Entry( Spec_Const,             "const" )            \ | ||||||
| 	Entry( Spec_Consteval,         "consteval" )        \ | 	Entry( Spec_Consteval,         "consteval" )        \ | ||||||
|   | |||||||
| @@ -84,6 +84,7 @@ Code& Code::operator ++() | |||||||
| } | } | ||||||
|  |  | ||||||
| #pragma region AST & Code Gen Common | #pragma region AST & Code Gen Common | ||||||
|  |  | ||||||
| #define Define_CodeImpl( Typename )                                                  \ | #define Define_CodeImpl( Typename )                                                  \ | ||||||
| char const* Typename::debug_str()                                                    \ | char const* Typename::debug_str()                                                    \ | ||||||
| {                                                                                    \ | {                                                                                    \ | ||||||
| @@ -243,6 +244,7 @@ Define_CodeCast( Using ); | |||||||
| Define_CodeCast( Var ); | Define_CodeCast( Var ); | ||||||
| Define_CodeCast( Body); | Define_CodeCast( Body); | ||||||
| #undef Define_CodeCast | #undef Define_CodeCast | ||||||
|  |  | ||||||
| #pragma endregion AST & Code Gen Common | #pragma endregion AST & Code Gen Common | ||||||
|  |  | ||||||
| void CodeClass::add_interface( CodeType type ) | void CodeClass::add_interface( CodeType type ) | ||||||
| @@ -361,9 +363,11 @@ StrC token_fmt_impl( sw num, ... ) | |||||||
|  |  | ||||||
| 	return { result, buf }; | 	return { result, buf }; | ||||||
| } | } | ||||||
|  |  | ||||||
| #pragma endregion Inlines | #pragma endregion Inlines | ||||||
|  |  | ||||||
| #pragma region Constants | #pragma region Constants | ||||||
|  |  | ||||||
| #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS | #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS | ||||||
| 	// Predefined typename codes. Are set to readonly and are setup during gen::init() | 	// Predefined typename codes. Are set to readonly and are setup during gen::init() | ||||||
|  |  | ||||||
| @@ -477,9 +481,11 @@ extern CodeSpecifiers spec_static_member; | |||||||
| extern CodeSpecifiers spec_thread_local; | extern CodeSpecifiers spec_thread_local; | ||||||
| extern CodeSpecifiers spec_virtual; | extern CodeSpecifiers spec_virtual; | ||||||
| extern CodeSpecifiers spec_volatile; | extern CodeSpecifiers spec_volatile; | ||||||
|  |  | ||||||
| #pragma endregion Constants | #pragma endregion Constants | ||||||
|  |  | ||||||
| #pragma region Macros | #pragma region Macros | ||||||
|  |  | ||||||
| #	define gen_main main | #	define gen_main main | ||||||
|  |  | ||||||
| #	define __ NoCode | #	define __ NoCode | ||||||
| @@ -498,9 +504,11 @@ extern CodeSpecifiers spec_volatile; | |||||||
|  |  | ||||||
| 	// Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string. | 	// Takes a format string (char const*) and a list of tokens (StrC) and returns a StrC of the formatted string. | ||||||
| #	define token_fmt( ... ) gen::token_fmt_impl( (num_args( __VA_ARGS__ ) + 1) / 2, __VA_ARGS__ ) | #	define token_fmt( ... ) gen::token_fmt_impl( (num_args( __VA_ARGS__ ) + 1) / 2, __VA_ARGS__ ) | ||||||
|  |  | ||||||
| #pragma endregion Macros | #pragma endregion Macros | ||||||
|  |  | ||||||
| #ifdef GEN_EXPOSE_BACKEND | #ifdef GEN_EXPOSE_BACKEND | ||||||
|  |  | ||||||
| 	// Global allocator used for data with process lifetime. | 	// Global allocator used for data with process lifetime. | ||||||
| 	extern AllocatorInfo  GlobalAllocator; | 	extern AllocatorInfo  GlobalAllocator; | ||||||
| 	extern Array< Arena > Global_AllocatorBuckets; | 	extern Array< Arena > Global_AllocatorBuckets; | ||||||
| @@ -517,4 +525,5 @@ extern CodeSpecifiers spec_volatile; | |||||||
| 	extern AllocatorInfo Allocator_StringArena; | 	extern AllocatorInfo Allocator_StringArena; | ||||||
| 	extern AllocatorInfo Allocator_StringTable; | 	extern AllocatorInfo Allocator_StringTable; | ||||||
| 	extern AllocatorInfo Allocator_TypeTable; | 	extern AllocatorInfo Allocator_TypeTable; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -4,13 +4,21 @@ These constructors are the most implementation intensive other than the editor o | |||||||
|  |  | ||||||
| namespace Parser | namespace Parser | ||||||
| { | { | ||||||
|  |  | ||||||
| 	struct Token | 	struct Token | ||||||
| 	{ | 	{ | ||||||
|  | 		// TokType  Type; | ||||||
|  | 		// s32      Start; | ||||||
|  | 		// s32      End; | ||||||
|  | 		// s32      Line; | ||||||
|  | 		// s32      Column; | ||||||
|  | 		// TokFlags Flags; | ||||||
|  |  | ||||||
| 		char const* Text; | 		char const* Text; | ||||||
| 		sptr        Length; | 		sptr        Length; | ||||||
| 		TokType     Type; | 		TokType     Type; | ||||||
| 		bool 	    IsAssign; | 		bool 	    IsAssign; | ||||||
|  | 		s32         Line; | ||||||
|  | 		s32         Column; | ||||||
|  |  | ||||||
| 		operator bool() | 		operator bool() | ||||||
| 		{ | 		{ | ||||||
| @@ -21,60 +29,42 @@ namespace Parser | |||||||
| 		{ | 		{ | ||||||
| 			return { Length, Text }; | 			return { Length, Text }; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		bool is_access_specifier() | ||||||
|  | 		{ | ||||||
|  | 			return Type >= TokType::Access_Private && Type <= TokType::Access_Public; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		bool is_attribute() | ||||||
|  | 		{ | ||||||
|  | 			return Type > TokType::Attributes_Start; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		bool is_preprocessor() | ||||||
|  | 		{ | ||||||
|  | 			return Type >= TokType::Preprocess_Define && Type <= TokType::Preprocess_EndIf; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		bool is_specifier() | ||||||
|  | 		{ | ||||||
|  | 			return (Type <= TokType::Star && Type >= TokType::Spec_Alignas) | ||||||
|  | 				|| Type == TokType::Ampersand | ||||||
|  | 				|| Type == TokType::Ampersand_DBL | ||||||
|  | 			; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		AccessSpec to_access_specifier() | ||||||
|  | 		{ | ||||||
|  | 			return scast(AccessSpec, Type); | ||||||
|  | 		} | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	internal inline |  | ||||||
| 	bool tok_is_specifier( Token const& tok ) |  | ||||||
| 	{ |  | ||||||
| 		return (tok.Type <= TokType::Star && tok.Type >= TokType::Spec_Alignas) |  | ||||||
| 			|| tok.Type == TokType::Ampersand |  | ||||||
| 			|| tok.Type == TokType::Ampersand_DBL |  | ||||||
| 		; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	internal inline |  | ||||||
| 	bool tok_is_access_specifier( Token const& tok ) |  | ||||||
| 	{ |  | ||||||
| 		return tok.Type >= TokType::Access_Private && tok.Type <= TokType::Access_Public; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	internal inline |  | ||||||
| 	AccessSpec tok_to_access_specifier( Token const& tok ) |  | ||||||
| 	{ |  | ||||||
| 		return scast(AccessSpec, tok.Type); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	internal inline |  | ||||||
| 	bool tok_is_attribute( Token const& tok ) |  | ||||||
| 	{ |  | ||||||
| 		return tok.Type > TokType::Attributes_Start; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	struct TokArray | 	struct TokArray | ||||||
| 	{ | 	{ | ||||||
| 		Array<Token> Arr; | 		Array<Token> Arr; | ||||||
| 		s32          Idx; | 		s32          Idx; | ||||||
|  |  | ||||||
| 		bool __eat( TokType type, char const* context ) | 		bool __eat( TokType type ); | ||||||
| 		{ |  | ||||||
| 			if ( Arr.num() - Idx <= 0 ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "gen::%s: No tokens left", context ); |  | ||||||
| 				return false; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if ( Arr[Idx].Type != type ) |  | ||||||
| 			{ |  | ||||||
| 				String token_str = String::make( GlobalAllocator, { Arr[Idx].Length, Arr[Idx].Text } ); |  | ||||||
|  |  | ||||||
| 				log_failure( "gen::%s: expected %s, got %s", context, ETokType::to_str(type), ETokType::to_str(Arr[Idx].Type) ); |  | ||||||
|  |  | ||||||
| 				return false; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			Idx++; |  | ||||||
| 			return true; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		Token& current() | 		Token& current() | ||||||
| 		{ | 		{ | ||||||
| @@ -92,13 +82,87 @@ namespace Parser | |||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	TokArray lex( StrC content, bool keep_preprocess_directives = false ) | 	struct StackNode | ||||||
|  | 	{ | ||||||
|  | 		StackNode* Prev; | ||||||
|  |  | ||||||
|  | 		Token Name;        // The name of the AST node (if parsed) | ||||||
|  | 		StrC  ProcName;    // The name of the procedure | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct ParseContext | ||||||
|  | 	{ | ||||||
|  | 		TokArray   Tokens; | ||||||
|  | 		StackNode* Scope; | ||||||
|  |  | ||||||
|  | 		String to_string() | ||||||
|  | 		{ | ||||||
|  | 			String result = String::make_reserve( GlobalAllocator, kilobytes(4) ); | ||||||
|  |  | ||||||
|  | 			result.append_fmt("\tContext:\n"); | ||||||
|  |  | ||||||
|  | 			StackNode* current = Scope; | ||||||
|  | 			do | ||||||
|  | 			{ | ||||||
|  | 				String name = String::make( GlobalAllocator, current->Name ? (StrC)current->Name : txt_StrC("Unresolved") ); | ||||||
|  |  | ||||||
|  | 				result.append_fmt("\tProcedure: %s, AST Name: %s\n\t(%d, %d):", current->ProcName, name ); | ||||||
|  | 				current = current->Prev; | ||||||
|  |  | ||||||
|  | 				name.free(); | ||||||
|  | 			} | ||||||
|  | 			while ( current ); | ||||||
|  |  | ||||||
|  | 			return result; | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	global ParseContext Context; | ||||||
|  |  | ||||||
|  | 	bool TokArray::__eat( TokType type ) | ||||||
|  | 	{ | ||||||
|  | 		if ( Arr.num() - Idx <= 0 ) | ||||||
|  | 		{ | ||||||
|  | 			log_failure( "No tokens left\n", Context.Scope->ProcName ); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if ( Arr[Idx].Type != type ) | ||||||
|  | 		{ | ||||||
|  | 			String token_str = String::make( GlobalAllocator, { Arr[Idx].Length, Arr[Idx].Text } ); | ||||||
|  |  | ||||||
|  | 			log_failure( "gen::%s: expected %s, got %s",  Context.Scope->ProcName, ETokType::to_str(type), ETokType::to_str(Arr[Idx].Type) ); | ||||||
|  |  | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Idx++; | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	enum TokFlags : u32 | ||||||
|  | 	{ | ||||||
|  | 		IsAssign = bit(0), | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	TokArray lex( StrC content, bool keep_preprocess_directives = true ) | ||||||
| 	{ | 	{ | ||||||
| 	#	define current ( * scanner ) | 	#	define current ( * scanner ) | ||||||
|  |  | ||||||
| 	#	define move_forward() \ | 	#	define move_forward()       \ | ||||||
| 		left--;               \ | 		{                           \ | ||||||
| 		scanner++ | 			if ( current == '\n' )  \ | ||||||
|  | 			{                       \ | ||||||
|  | 				line++;             \ | ||||||
|  | 				column = 0;         \ | ||||||
|  | 			}                       \ | ||||||
|  | 			else                    \ | ||||||
|  | 			{                       \ | ||||||
|  | 				column++;           \ | ||||||
|  | 			}                       \ | ||||||
|  | 			left--;                 \ | ||||||
|  | 			scanner++;              \ | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 	#	define SkipWhitespace()                     \ | 	#	define SkipWhitespace()                     \ | ||||||
| 		while ( left && char_is_space( current ) )  \ | 		while ( left && char_is_space( current ) )  \ | ||||||
| @@ -126,6 +190,9 @@ namespace Parser | |||||||
| 		char const* word        = scanner; | 		char const* word        = scanner; | ||||||
| 		s32         word_length = 0; | 		s32         word_length = 0; | ||||||
|  |  | ||||||
|  | 		s32 line   = 0; | ||||||
|  | 		s32 column = 0; | ||||||
|  |  | ||||||
| 		SkipWhitespace(); | 		SkipWhitespace(); | ||||||
| 		if ( left <= 0 ) | 		if ( left <= 0 ) | ||||||
| 		{ | 		{ | ||||||
| @@ -142,7 +209,7 @@ namespace Parser | |||||||
|  |  | ||||||
| 		while (left ) | 		while (left ) | ||||||
| 		{ | 		{ | ||||||
| 			Token token = { nullptr, 0, TokType::Invalid, false }; | 			Token token = { nullptr, 0, TokType::Invalid, false, line, column }; | ||||||
|  |  | ||||||
| 			SkipWhitespace(); | 			SkipWhitespace(); | ||||||
| 			if ( left <= 0 ) | 			if ( left <= 0 ) | ||||||
| @@ -153,11 +220,15 @@ namespace Parser | |||||||
| 				case '#': | 				case '#': | ||||||
| 					token.Text   = scanner; | 					token.Text   = scanner; | ||||||
| 					token.Length = 1; | 					token.Length = 1; | ||||||
| 					token.Type   = TokType::Preprocessor_Directive; |  | ||||||
| 					move_forward(); | 					move_forward(); | ||||||
|  |  | ||||||
| 					while (left && current != '\n' ) | 					while (left && current != '\n' ) | ||||||
| 					{ | 					{ | ||||||
|  | 						if ( token.Type == ETokType::Invalid && current == ' ' ) | ||||||
|  | 						{ | ||||||
|  | 							token.Type = ETokType::to_type( token ); | ||||||
|  | 						} | ||||||
|  |  | ||||||
| 						if ( current == '\\'  ) | 						if ( current == '\\'  ) | ||||||
| 						{ | 						{ | ||||||
| 							move_forward(); | 							move_forward(); | ||||||
| @@ -178,8 +249,9 @@ namespace Parser | |||||||
| 					token.Length = 1; | 					token.Length = 1; | ||||||
| 					token.Type   = TokType::Access_MemberSymbol; | 					token.Type   = TokType::Access_MemberSymbol; | ||||||
|  |  | ||||||
| 					if (left) | 					if (left) { | ||||||
| 						move_forward(); | 						move_forward(); | ||||||
|  | 					} | ||||||
|  |  | ||||||
| 					if ( current == '.' ) | 					if ( current == '.' ) | ||||||
| 					{ | 					{ | ||||||
| @@ -577,7 +649,7 @@ namespace Parser | |||||||
|  |  | ||||||
| 			if ( token.Type != TokType::Invalid ) | 			if ( token.Type != TokType::Invalid ) | ||||||
| 			{ | 			{ | ||||||
| 				if ( token.Type == TokType::Preprocessor_Directive && keep_preprocess_directives == false ) | 				if ( token.is_preprocessor() && keep_preprocess_directives == false ) | ||||||
| 					continue; | 					continue; | ||||||
|  |  | ||||||
| 				Tokens.append( token ); | 				Tokens.append( token ); | ||||||
| @@ -608,6 +680,7 @@ namespace Parser | |||||||
| } | } | ||||||
|  |  | ||||||
| #pragma region Helper Macros | #pragma region Helper Macros | ||||||
|  |  | ||||||
| #	define check_parse_args( func, def )                                   \ | #	define check_parse_args( func, def )                                   \ | ||||||
| if ( def.Len <= 0 )                                                        \ | if ( def.Len <= 0 )                                                        \ | ||||||
| {                                                                          \ | {                                                                          \ | ||||||
| @@ -620,13 +693,16 @@ if ( def.Ptr == nullptr )                                                  \ | |||||||
| 	return CodeInvalid;                                                    \ | 	return CodeInvalid;                                                    \ | ||||||
| } | } | ||||||
|  |  | ||||||
| #	define nexttok 	    toks.next() | #	define nexttok 	    Context.Tokens.next() | ||||||
| #	define currtok      toks.current() | #	define currtok      Context.Tokens.current() | ||||||
| #	define prevtok      toks.previous() | #	define prevtok      Context.Tokens.previous() | ||||||
| #	define eat( Type_ ) toks.__eat( Type_, context ) | #	define eat( Type_ ) Context.Tokens.__eat( Type_ ) | ||||||
| #	define left         ( toks.Arr.num() - toks.Idx ) | #	define left         ( Context.Tokens.Arr.num() - Context.Tokens.Idx ) | ||||||
|  |  | ||||||
| #	define check( Type_ ) ( left && currtok.Type == Type_ ) | #	define check( Type_ ) ( left && currtok.Type == Type_ ) | ||||||
|  |  | ||||||
|  | // #	define  | ||||||
|  |  | ||||||
| #pragma endregion Helper Macros | #pragma endregion Helper Macros | ||||||
|  |  | ||||||
| struct ParseContext | struct ParseContext | ||||||
| @@ -635,28 +711,28 @@ struct ParseContext | |||||||
| 	char const*   Fn; | 	char const*   Fn; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| internal Code parse_function_body( Parser::TokArray& toks, char const* context ); | internal Code parse_function_body(); | ||||||
| internal Code parse_global_nspace( Parser::TokArray& toks, char const* context ); | internal Code parse_global_nspace(); | ||||||
|  |  | ||||||
| internal CodeClass     parse_class           ( Parser::TokArray& toks, char const* context ); | internal CodeClass     parse_class           (); | ||||||
| internal CodeEnum      parse_enum            ( Parser::TokArray& toks, char const* context ); | internal CodeEnum      parse_enum            (); | ||||||
| internal CodeBody      parse_export_body     ( Parser::TokArray& toks, char const* context ); | internal CodeBody      parse_export_body     (); | ||||||
| internal CodeBody      parse_extern_link_body( Parser::TokArray& toks, char const* context ); | internal CodeBody      parse_extern_link_body(); | ||||||
| internal CodeExtern    parse_exten_link      ( Parser::TokArray& toks, char const* context ); | internal CodeExtern    parse_exten_link      (); | ||||||
| internal CodeFriend    parse_friend          ( Parser::TokArray& toks, char const* context ); | internal CodeFriend    parse_friend          (); | ||||||
| internal CodeFn        parse_function        ( Parser::TokArray& toks, char const* context ); | internal CodeFn        parse_function        (); | ||||||
| internal CodeNamespace parse_namespace       ( Parser::TokArray& toks, char const* context ); | internal CodeNamespace parse_namespace       (); | ||||||
| internal CodeOpCast    parse_operator_cast   ( Parser::TokArray& toks, char const* context ); | internal CodeOpCast    parse_operator_cast   (); | ||||||
| internal CodeStruct    parse_struct          ( Parser::TokArray& toks, char const* context ); | internal CodeStruct    parse_struct          (); | ||||||
| internal CodeVar       parse_variable        ( Parser::TokArray& toks, char const* context ); | internal CodeVar       parse_variable        (); | ||||||
| internal CodeTemplate  parse_template        ( Parser::TokArray& toks, char const* context ); | internal CodeTemplate  parse_template        (); | ||||||
| internal CodeType      parse_type            ( Parser::TokArray& toks, char const* context ); | internal CodeType      parse_type            (); | ||||||
| internal CodeTypedef   parse_typedef         ( Parser::TokArray& toks, char const* context ); | internal CodeTypedef   parse_typedef         (); | ||||||
| internal CodeUnion     parse_union           ( Parser::TokArray& toks, char const* context ); | internal CodeUnion     parse_union           (); | ||||||
| internal CodeUsing     parse_using           ( Parser::TokArray& toks, char const* context ); | internal CodeUsing     parse_using           (); | ||||||
|  |  | ||||||
| internal inline | internal inline | ||||||
| Code parse_array_decl( Parser::TokArray& toks, char const* context ) | Code parse_array_decl() | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
|  |  | ||||||
| @@ -707,7 +783,7 @@ Code parse_array_decl( Parser::TokArray& toks, char const* context ) | |||||||
| } | } | ||||||
|  |  | ||||||
| internal inline | internal inline | ||||||
| CodeAttributes parse_attributes( Parser::TokArray& toks, char const* context ) | CodeAttributes parse_attributes() | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
|  |  | ||||||
| @@ -759,7 +835,7 @@ CodeAttributes parse_attributes( Parser::TokArray& toks, char const* context ) | |||||||
| 		s32 len = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)start.Text; | 		s32 len = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)start.Text; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	else if ( tok_is_attribute( currtok ) ) | 	else if ( currtok.is_attribute() ) | ||||||
| 	{ | 	{ | ||||||
| 		eat(currtok.Type); | 		eat(currtok.Type); | ||||||
| 		s32 len = start.Length; | 		s32 len = start.Length; | ||||||
| @@ -775,7 +851,7 @@ CodeAttributes parse_attributes( Parser::TokArray& toks, char const* context ) | |||||||
| } | } | ||||||
|  |  | ||||||
| internal inline | internal inline | ||||||
| Parser::Token parse_identifier( Parser::TokArray& toks, char const* context ) | Parser::Token parse_identifier() | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
| 	Token name = currtok; | 	Token name = currtok; | ||||||
| @@ -788,7 +864,7 @@ Parser::Token parse_identifier( Parser::TokArray& toks, char const* context ) | |||||||
|  |  | ||||||
| 		if ( left == 0 ) | 		if ( left == 0 ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure( "%s: Error, unexpected end of type definition, expected identifier", context ); | 			log_failure( "%s: Error, unexpected end of type definition, expected identifier", Context.to_string() ); | ||||||
| 			return { nullptr, 0, TokType::Invalid }; | 			return { nullptr, 0, TokType::Invalid }; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -806,7 +882,7 @@ Parser::Token parse_identifier( Parser::TokArray& toks, char const* context ) | |||||||
| } | } | ||||||
|  |  | ||||||
| internal | internal | ||||||
| CodeParam parse_params( Parser::TokArray& toks, char const* context, bool use_template_capture = false ) | CodeParam parse_params( bool use_template_capture = false ) | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
| 	using namespace ECode; | 	using namespace ECode; | ||||||
| @@ -973,15 +1049,13 @@ CodeFn parse_function_after_name( | |||||||
| 	, CodeSpecifiers    specifiers | 	, CodeSpecifiers    specifiers | ||||||
| 	, CodeType          ret_type | 	, CodeType          ret_type | ||||||
| 	, StrC              name | 	, StrC              name | ||||||
| 	, Parser::TokArray& toks |  | ||||||
| 	, char const*        context |  | ||||||
| ) | ) | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
|  |  | ||||||
| 	CodeParam params = parse_params( toks, stringize(parse_function) ); | 	CodeParam params = parse_params( toks, stringize(parse_function) ); | ||||||
|  |  | ||||||
| 	while ( left && tok_is_specifier( currtok ) ) | 	while ( left && currtok.is_specifier() ) | ||||||
| 	{ | 	{ | ||||||
| 		specifiers.append( ESpecifier::to_type(currtok) ); | 		specifiers.append( ESpecifier::to_type(currtok) ); | ||||||
| 		eat( currtok.Type ); | 		eat( currtok.Type ); | ||||||
| @@ -1041,12 +1115,12 @@ CodeFn parse_function_after_name( | |||||||
| } | } | ||||||
|  |  | ||||||
| internal inline | internal inline | ||||||
| CodeOperator parse_operator_after_ret_type( ModuleFlag mflags | CodeOperator parse_operator_after_ret_type(  | ||||||
|  | 	  ModuleFlag mflags | ||||||
| 	, CodeAttributes attributes | 	, CodeAttributes attributes | ||||||
| 	, CodeSpecifiers  specifiers | 	, CodeSpecifiers  specifiers | ||||||
| 	, CodeType       ret_type | 	, CodeType       ret_type | ||||||
| 	, Parser::TokArray& toks | ) | ||||||
| 	, char const* context ) |  | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
| 	using namespace EOperator; | 	using namespace EOperator; | ||||||
| @@ -1251,7 +1325,7 @@ CodeOperator parse_operator_after_ret_type( ModuleFlag mflags | |||||||
| 	// Parse Params | 	// Parse Params | ||||||
| 	CodeParam params = parse_params( toks, stringize(parse_operator) ); | 	CodeParam params = parse_params( toks, stringize(parse_operator) ); | ||||||
|  |  | ||||||
| 	while ( left && tok_is_specifier( currtok ) ) | 	while ( left && currtok.is_specifier() ) | ||||||
| 	{ | 	{ | ||||||
| 		specifiers.append( ESpecifier::to_type(currtok) ); | 		specifiers.append( ESpecifier::to_type(currtok) ); | ||||||
| 		eat( currtok.Type ); | 		eat( currtok.Type ); | ||||||
| @@ -1341,7 +1415,7 @@ CodeVar parse_variable_after_name( | |||||||
| } | } | ||||||
|  |  | ||||||
| internal inline | internal inline | ||||||
| Code parse_variable_assignment( Parser::TokArray& toks, char const* context ) | Code parse_variable_assignment() | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
|  |  | ||||||
| @@ -1372,7 +1446,7 @@ Code parse_variable_assignment( Parser::TokArray& toks, char const* context ) | |||||||
| } | } | ||||||
|  |  | ||||||
| internal inline | internal inline | ||||||
| Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers, Parser::TokArray& toks, char const* context ) | Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers ) | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
|  |  | ||||||
| @@ -1416,7 +1490,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes | |||||||
| } | } | ||||||
|  |  | ||||||
| internal | internal | ||||||
| CodeBody parse_class_struct_body( Parser::TokType which, Parser::TokArray& toks, char const* context ) | CodeBody parse_class_struct_body( Parser::TokType which ) | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
| 	using namespace ECode; | 	using namespace ECode; | ||||||
| @@ -1508,7 +1582,7 @@ CodeBody parse_class_struct_body( Parser::TokType which, Parser::TokArray& toks, | |||||||
| 			GEN_Define_Attribute_Tokens | 			GEN_Define_Attribute_Tokens | ||||||
| 		#undef Entry | 		#undef Entry | ||||||
| 			{ | 			{ | ||||||
| 				attributes = parse_attributes( toks, context ); | 				attributes = parse_attributes(); | ||||||
| 			} | 			} | ||||||
| 			//! Fallthrough intended | 			//! Fallthrough intended | ||||||
| 			case TokType::Spec_Consteval: | 			case TokType::Spec_Consteval: | ||||||
| @@ -1522,7 +1596,7 @@ CodeBody parse_class_struct_body( Parser::TokType which, Parser::TokArray& toks, | |||||||
| 				SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; | 				SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; | ||||||
| 				s32        NumSpecifiers = 0; | 				s32        NumSpecifiers = 0; | ||||||
|  |  | ||||||
| 				while ( left && tok_is_specifier( currtok ) ) | 				while ( left && currtok.is_specifier() ) | ||||||
| 				{ | 				{ | ||||||
| 					SpecifierT spec = ESpecifier::to_type( currtok ); | 					SpecifierT spec = ESpecifier::to_type( currtok ); | ||||||
|  |  | ||||||
| @@ -1597,7 +1671,7 @@ CodeBody parse_class_struct_body( Parser::TokType which, Parser::TokArray& toks, | |||||||
| } | } | ||||||
|  |  | ||||||
| internal | internal | ||||||
| Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char const* context ) | Code parse_class_struct( Parser::TokType which ) | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
|  |  | ||||||
| @@ -1625,7 +1699,7 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con | |||||||
|  |  | ||||||
| 	eat( which ); | 	eat( which ); | ||||||
|  |  | ||||||
| 	attributes = parse_attributes( toks, context ); | 	attributes = parse_attributes(); | ||||||
|  |  | ||||||
| 	if ( check( TokType::Identifier ) ) | 	if ( check( TokType::Identifier ) ) | ||||||
| 		name = parse_identifier( toks, context ); | 		name = parse_identifier( toks, context ); | ||||||
| @@ -1638,9 +1712,9 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con | |||||||
| 	{ | 	{ | ||||||
| 		eat( TokType::Assign_Classifer ); | 		eat( TokType::Assign_Classifer ); | ||||||
|  |  | ||||||
| 		if ( tok_is_access_specifier( currtok ) ) | 		if ( currtok.is_access_specifier() ) | ||||||
| 		{ | 		{ | ||||||
| 			access = tok_to_access_specifier( currtok ); | 			access = currtok.to_access_specifier(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		Token parent_tok = parse_identifier( toks, context ); | 		Token parent_tok = parse_identifier( toks, context ); | ||||||
| @@ -1650,7 +1724,7 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con | |||||||
| 		{ | 		{ | ||||||
| 			eat(TokType::Access_Public); | 			eat(TokType::Access_Public); | ||||||
|  |  | ||||||
| 			if ( tok_is_access_specifier( currtok ) ) | 			if ( currtok.is_access_specifier() ) | ||||||
| 			{ | 			{ | ||||||
| 				eat(currtok.Type); | 				eat(currtok.Type); | ||||||
| 			} | 			} | ||||||
| @@ -1685,7 +1759,7 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con | |||||||
| } | } | ||||||
|  |  | ||||||
| internal | internal | ||||||
| Code parse_function_body( Parser::TokArray& toks, char const* context ) | Code parse_function_body() | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
| 	using namespace ECode; | 	using namespace ECode; | ||||||
| @@ -1724,7 +1798,7 @@ Code parse_function_body( Parser::TokArray& toks, char const* context ) | |||||||
| } | } | ||||||
|  |  | ||||||
| internal | internal | ||||||
| CodeBody parse_global_nspace( CodeT which, Parser::TokArray& toks, char const* context ) | CodeBody parse_global_nspace( CodeT which ) | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
| 	using namespace ECode; | 	using namespace ECode; | ||||||
| @@ -1811,7 +1885,7 @@ CodeBody parse_global_nspace( CodeT which, Parser::TokArray& toks, char const* c | |||||||
| 			GEN_Define_Attribute_Tokens | 			GEN_Define_Attribute_Tokens | ||||||
| 		#undef Entry | 		#undef Entry | ||||||
| 			{ | 			{ | ||||||
| 				attributes = parse_attributes( toks, context ); | 				attributes = parse_attributes(); | ||||||
| 			} | 			} | ||||||
| 			//! Fallthrough intentional | 			//! Fallthrough intentional | ||||||
| 			case TokType::Spec_Consteval: | 			case TokType::Spec_Consteval: | ||||||
| @@ -1826,7 +1900,7 @@ CodeBody parse_global_nspace( CodeT which, Parser::TokArray& toks, char const* c | |||||||
| 				SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; | 				SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; | ||||||
| 				s32        NumSpecifiers = 0; | 				s32        NumSpecifiers = 0; | ||||||
|  |  | ||||||
| 				while ( left && tok_is_specifier( currtok ) ) | 				while ( left && currtok.is_specifier() ) | ||||||
| 				{ | 				{ | ||||||
| 					SpecifierT spec = ESpecifier::to_type( currtok ); | 					SpecifierT spec = ESpecifier::to_type( currtok ); | ||||||
|  |  | ||||||
| @@ -1890,7 +1964,7 @@ CodeBody parse_global_nspace( CodeT which, Parser::TokArray& toks, char const* c | |||||||
| } | } | ||||||
|  |  | ||||||
| internal | internal | ||||||
| CodeClass parse_class( Parser::TokArray& toks, char const* context ) | CodeClass parse_class() | ||||||
| { | { | ||||||
| 	return (CodeClass) parse_class_struct( Parser::TokType::Decl_Class, toks, context ); | 	return (CodeClass) parse_class_struct( Parser::TokType::Decl_Class, toks, context ); | ||||||
| } | } | ||||||
| @@ -1908,7 +1982,7 @@ CodeClass parse_class( StrC def ) | |||||||
| } | } | ||||||
|  |  | ||||||
| internal | internal | ||||||
| CodeEnum parse_enum( Parser::TokArray& toks, char const* context ) | CodeEnum parse_enum() | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
| 	using namespace ECode; | 	using namespace ECode; | ||||||
| @@ -2027,7 +2101,7 @@ CodeEnum parse_enum( StrC def ) | |||||||
| } | } | ||||||
|  |  | ||||||
| internal inline | internal inline | ||||||
| CodeBody parse_export_body( Parser::TokArray& toks, char const* context ) | CodeBody parse_export_body() | ||||||
| { | { | ||||||
| 	return parse_global_nspace( ECode::Export_Body, toks, context ); | 	return parse_global_nspace( ECode::Export_Body, toks, context ); | ||||||
| } | } | ||||||
| @@ -2170,9 +2244,9 @@ CodeFn parse_functon( Parser::TokArray& toks, char const* context ) | |||||||
| 		eat( TokType::Module_Export ); | 		eat( TokType::Module_Export ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	attributes = parse_attributes( toks, context ); | 	attributes = parse_attributes(); | ||||||
|  |  | ||||||
| 	while ( left && tok_is_specifier( currtok ) ) | 	while ( left && currtok.is_specifier() ) | ||||||
| 	{ | 	{ | ||||||
| 		SpecifierT spec = ESpecifier::to_type( currtok ); | 		SpecifierT spec = ESpecifier::to_type( currtok ); | ||||||
|  |  | ||||||
| @@ -2294,9 +2368,9 @@ CodeOperator parse_operator( Parser::TokArray& toks, char const* context ) | |||||||
| 		eat( TokType::Module_Export ); | 		eat( TokType::Module_Export ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	attributes = parse_attributes( toks, context ); | 	attributes = parse_attributes(); | ||||||
|  |  | ||||||
| 	while ( left && tok_is_specifier( currtok ) ) | 	while ( left && currtok.is_specifier() ) | ||||||
| 	{ | 	{ | ||||||
| 		SpecifierT spec = ESpecifier::to_type( currtok ); | 		SpecifierT spec = ESpecifier::to_type( currtok ); | ||||||
|  |  | ||||||
| @@ -2492,9 +2566,9 @@ CodeTemplate parse_template( Parser::TokArray& toks, char const* context ) | |||||||
| 		SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; | 		SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; | ||||||
| 		s32        NumSpecifiers = 0; | 		s32        NumSpecifiers = 0; | ||||||
|  |  | ||||||
| 		attributes = parse_attributes( toks, stringize(parse_template) ); | 		attributes = parse_attributes(); | ||||||
|  |  | ||||||
| 		while ( left && tok_is_specifier( currtok ) ) | 		while ( left && currtok.is_specifier() ) | ||||||
| 		{ | 		{ | ||||||
| 			SpecifierT spec = ESpecifier::to_type( currtok ); | 			SpecifierT spec = ESpecifier::to_type( currtok ); | ||||||
|  |  | ||||||
| @@ -2576,9 +2650,9 @@ CodeType parse_type( Parser::TokArray& toks, char const* context ) | |||||||
| 	Token name      = { nullptr, 0, TokType::Invalid }; | 	Token name      = { nullptr, 0, TokType::Invalid }; | ||||||
| 	Token brute_sig = { currtok.Text, 0, TokType::Invalid }; | 	Token brute_sig = { currtok.Text, 0, TokType::Invalid }; | ||||||
|  |  | ||||||
| 	CodeAttributes attributes = parse_attributes( toks, context ); | 	CodeAttributes attributes = parse_attributes(); | ||||||
|  |  | ||||||
| 	while ( left && tok_is_specifier( currtok ) ) | 	while ( left && currtok.is_specifier() ) | ||||||
| 	{ | 	{ | ||||||
| 		SpecifierT spec = ESpecifier::to_type( currtok ); | 		SpecifierT spec = ESpecifier::to_type( currtok ); | ||||||
|  |  | ||||||
| @@ -2651,7 +2725,7 @@ CodeType parse_type( Parser::TokArray& toks, char const* context ) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	while ( left && tok_is_specifier( currtok ) ) | 	while ( left && currtok.is_specifier() ) | ||||||
| 	{ | 	{ | ||||||
| 		SpecifierT spec = ESpecifier::to_type( currtok ); | 		SpecifierT spec = ESpecifier::to_type( currtok ); | ||||||
|  |  | ||||||
| @@ -2842,7 +2916,7 @@ CodeUnion parse_union( Parser::TokArray& toks, char const* context ) | |||||||
|  |  | ||||||
| 	eat( TokType::Decl_Union ); | 	eat( TokType::Decl_Union ); | ||||||
|  |  | ||||||
| 	CodeAttributes attributes = parse_attributes( toks, context ); | 	CodeAttributes attributes = parse_attributes(); | ||||||
|  |  | ||||||
| 	StrC name = { 0, nullptr }; | 	StrC name = { 0, nullptr }; | ||||||
|  |  | ||||||
| @@ -2986,12 +3060,10 @@ CodeUsing parse_using( StrC def ) | |||||||
| } | } | ||||||
|  |  | ||||||
| internal | internal | ||||||
| CodeVar parse_variable( Parser::TokArray& toks, char const* context ) | CodeVar parse_variable() | ||||||
| { | { | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
|  |  | ||||||
| 	Token name = { nullptr, 0, TokType::Invalid }; |  | ||||||
|  |  | ||||||
| 	SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; | 	SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; | ||||||
| 	s32        NumSpecifiers = 0; | 	s32        NumSpecifiers = 0; | ||||||
|  |  | ||||||
| @@ -3005,7 +3077,7 @@ CodeVar parse_variable( Parser::TokArray& toks, char const* context ) | |||||||
| 		eat( TokType::Module_Export ); | 		eat( TokType::Module_Export ); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	attributes = parse_attributes( toks, context ); | 	attributes = parse_attributes(); | ||||||
|  |  | ||||||
| 	while ( left && tok_is_specifier( currtok ) ) | 	while ( left && tok_is_specifier( currtok ) ) | ||||||
| 	{ | 	{ | ||||||
| @@ -3050,24 +3122,32 @@ CodeVar parse_variable( Parser::TokArray& toks, char const* context ) | |||||||
| 	if ( type == Code::Invalid ) | 	if ( type == Code::Invalid ) | ||||||
| 		return CodeInvalid; | 		return CodeInvalid; | ||||||
|  |  | ||||||
| 	name = currtok; | 	Context.Scope->Name = current; | ||||||
| 	eat( TokType::Identifier ); | 	eat( TokType::Identifier ); | ||||||
|  |  | ||||||
| 	CodeVar result = parse_variable_after_name( mflags, attributes, specifiers, type, name, toks, context ); | 	CodeVar result = parse_variable_after_name( mflags, attributes, specifiers, type, Context.Scope->Name, Context.Tokens, Context.Scope->ProcName ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| CodeVar parse_variable( StrC def ) | CodeVar parse_variable( StrC def ) | ||||||
| { | { | ||||||
| 	check_parse_args( parse_variable, def ); |  | ||||||
| 	using namespace Parser; | 	using namespace Parser; | ||||||
|  | 	check_parse_args( parse_variable, def ); | ||||||
|  |  | ||||||
| 	TokArray toks = lex( def ); | 	TokArray toks = lex( def ); | ||||||
| 	if ( toks.Arr == nullptr ) | 	if ( toks.Arr == nullptr ) | ||||||
| 		return CodeInvalid; | 		return CodeInvalid; | ||||||
|  |  | ||||||
| 	return parse_variable( toks, stringize(parse_variable) ); | 	Context.Tokens = toks; | ||||||
|  | 	Parser::StackNode root | ||||||
|  | 	{ | ||||||
|  | 		toks.current(), | ||||||
|  | 		{ nullptr, 0, TokType::Invalid }, | ||||||
|  | 		name(parse_variable) | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	return parse_variable(); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Undef helper macros | // Undef helper macros | ||||||
| @@ -3075,4 +3155,3 @@ CodeVar parse_variable( StrC def ) | |||||||
| #	undef curr_tok | #	undef curr_tok | ||||||
| #	undef eat | #	undef eat | ||||||
| #	undef left | #	undef left | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1338,7 +1338,7 @@ CodeBody def_class_body( s32 num, ... ) | |||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, num); | 	va_start(va, num); | ||||||
| 	def_body_code_validation_start( def_class_body ); | 	def_body_code_validation_start( def_class_body ); | ||||||
| 		AST_BODY_CLASS_UNALLOWED_TYPES | 		GEN_AST_BODY_CLASS_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_class_body ); | 	def_body_code_validation_end( def_class_body ); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| @@ -1354,7 +1354,7 @@ CodeBody def_class_body( s32 num, Code* codes ) | |||||||
| 	result->Type = Function_Body; | 	result->Type = Function_Body; | ||||||
|  |  | ||||||
| 	def_body_code_array_validation_start( def_class_body ); | 	def_body_code_array_validation_start( def_class_body ); | ||||||
| 		AST_BODY_CLASS_UNALLOWED_TYPES | 		GEN_AST_BODY_CLASS_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_class_body ); | 	def_body_code_validation_end( def_class_body ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -1437,7 +1437,7 @@ CodeBody def_export_body( s32 num, ... ) | |||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, num); | 	va_start(va, num); | ||||||
| 	def_body_code_validation_start( def_export_body ); | 	def_body_code_validation_start( def_export_body ); | ||||||
| 		AST_BODY_EXPORT_UNALLOWED_TYPES | 		GEN_AST_BODY_EXPORT_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_export_body ); | 	def_body_code_validation_end( def_export_body ); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| @@ -1453,7 +1453,7 @@ CodeBody def_export_body( s32 num, Code* codes ) | |||||||
| 	result->Type = Export_Body; | 	result->Type = Export_Body; | ||||||
|  |  | ||||||
| 	def_body_code_array_validation_start( def_export_body ); | 	def_body_code_array_validation_start( def_export_body ); | ||||||
| 		AST_BODY_EXPORT_UNALLOWED_TYPES | 		GEN_AST_BODY_EXPORT_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_export_body ); | 	def_body_code_validation_end( def_export_body ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -1470,7 +1470,7 @@ CodeBody def_extern_link_body( s32 num, ... ) | |||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, num); | 	va_start(va, num); | ||||||
| 	def_body_code_validation_start( def_extern_linkage_body ); | 	def_body_code_validation_start( def_extern_linkage_body ); | ||||||
| 		AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | 		GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_extern_linkage_body ); | 	def_body_code_validation_end( def_extern_linkage_body ); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| @@ -1486,7 +1486,7 @@ CodeBody def_extern_link_body( s32 num, Code* codes ) | |||||||
| 	result->Type = Extern_Linkage_Body; | 	result->Type = Extern_Linkage_Body; | ||||||
|  |  | ||||||
| 	def_body_code_array_validation_start( def_extern_linkage_body ); | 	def_body_code_array_validation_start( def_extern_linkage_body ); | ||||||
| 		AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | 		GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_extern_linkage_body ); | 	def_body_code_validation_end( def_extern_linkage_body ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -1503,7 +1503,7 @@ CodeBody def_function_body( s32 num, ... ) | |||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, num); | 	va_start(va, num); | ||||||
| 	def_body_code_validation_start( def_function_body ); | 	def_body_code_validation_start( def_function_body ); | ||||||
| 		AST_BODY_FUNCTION_UNALLOWED_TYPES | 		GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_function_body ); | 	def_body_code_validation_end( def_function_body ); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| @@ -1519,7 +1519,7 @@ CodeBody def_function_body( s32 num, Code* codes ) | |||||||
| 	result->Type = Function_Body; | 	result->Type = Function_Body; | ||||||
|  |  | ||||||
| 	def_body_code_array_validation_start( def_function_body ); | 	def_body_code_array_validation_start( def_function_body ); | ||||||
| 		AST_BODY_FUNCTION_UNALLOWED_TYPES | 		GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_function_body ); | 	def_body_code_validation_end( def_function_body ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -1536,7 +1536,7 @@ CodeBody def_global_body( s32 num, ... ) | |||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, num); | 	va_start(va, num); | ||||||
| 	def_body_code_validation_start( def_global_body ); | 	def_body_code_validation_start( def_global_body ); | ||||||
| 		AST_BODY_GLOBAL_UNALLOWED_TYPES | 		GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_global_body ); | 	def_body_code_validation_end( def_global_body ); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| @@ -1552,7 +1552,7 @@ CodeBody def_global_body( s32 num, Code* codes ) | |||||||
| 	result->Type = Global_Body; | 	result->Type = Global_Body; | ||||||
|  |  | ||||||
| 	def_body_code_array_validation_start( def_global_body ); | 	def_body_code_array_validation_start( def_global_body ); | ||||||
| 		AST_BODY_GLOBAL_UNALLOWED_TYPES | 		GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_global_body ); | 	def_body_code_validation_end( def_global_body ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -1569,7 +1569,7 @@ CodeBody def_namespace_body( s32 num, ... ) | |||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, num); | 	va_start(va, num); | ||||||
| 	def_body_code_validation_start( def_namespace_body ); | 	def_body_code_validation_start( def_namespace_body ); | ||||||
| 		AST_BODY_NAMESPACE_UNALLOWED_TYPES | 		GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_namespace_body ); | 	def_body_code_validation_end( def_namespace_body ); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| @@ -1585,7 +1585,7 @@ CodeBody def_namespace_body( s32 num, Code* codes ) | |||||||
| 	result->Type = Global_Body; | 	result->Type = Global_Body; | ||||||
|  |  | ||||||
| 	def_body_code_array_validation_start( def_namespace_body ); | 	def_body_code_array_validation_start( def_namespace_body ); | ||||||
| 		AST_BODY_NAMESPACE_UNALLOWED_TYPES | 		GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_namespace_body ); | 	def_body_code_validation_end( def_namespace_body ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
| @@ -1737,7 +1737,7 @@ CodeBody def_struct_body( s32 num, ... ) | |||||||
| 	va_list va; | 	va_list va; | ||||||
| 	va_start(va, num); | 	va_start(va, num); | ||||||
| 	def_body_code_validation_start( def_struct_body ); | 	def_body_code_validation_start( def_struct_body ); | ||||||
| 		AST_BODY_STRUCT_UNALLOWED_TYPES | 		GEN_AST_BODY_STRUCT_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_struct_body ); | 	def_body_code_validation_end( def_struct_body ); | ||||||
| 	va_end(va); | 	va_end(va); | ||||||
|  |  | ||||||
| @@ -1753,7 +1753,7 @@ CodeBody def_struct_body( s32 num, Code* codes ) | |||||||
| 	result->Type = Struct_Body; | 	result->Type = Struct_Body; | ||||||
|  |  | ||||||
| 	def_body_code_array_validation_start( def_struct_body ); | 	def_body_code_array_validation_start( def_struct_body ); | ||||||
| 		AST_BODY_STRUCT_UNALLOWED_TYPES | 		GEN_AST_BODY_STRUCT_UNALLOWED_TYPES | ||||||
| 	def_body_code_validation_end( def_struct_body ); | 	def_body_code_validation_end( def_struct_body ); | ||||||
|  |  | ||||||
| 	return result; | 	return result; | ||||||
|   | |||||||
| @@ -100,10 +100,3 @@ constexpr char const* Attribute_Keyword = stringize( GEN_Attribute_Keyword ); | |||||||
|  |  | ||||||
| constexpr char const* Attribute_Keyword = ""; | constexpr char const* Attribute_Keyword = ""; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #ifndef GEN_Define_Attribute_Tokens |  | ||||||
| #	define GEN_Define_Attribute_Tokens         \ |  | ||||||
| 	Entry( API_Export, "GEN_API_Export_Code" ) \ |  | ||||||
| 	Entry( API_Import, "GEN_API_Import_Code" ) |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ using namespace gen; | |||||||
|  |  | ||||||
| CodeBody gen_ecode( char const* path ) | CodeBody gen_ecode( char const* path ) | ||||||
| { | { | ||||||
| 	char scratch_mem[kilobytes(1)]; | 	char  scratch_mem[kilobytes(1)]; | ||||||
| 	Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) ); | 	Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) ); | ||||||
|  |  | ||||||
| 	file_read_contents( scratch, zero_terminate, path ); | 	file_read_contents( scratch, zero_terminate, path ); | ||||||
| @@ -50,8 +50,7 @@ CodeBody gen_ecode( char const* path ) | |||||||
| #pragma pop_macro( "local_persist" ) | #pragma pop_macro( "local_persist" ) | ||||||
|  |  | ||||||
| 	CodeNamespace nspace = def_namespace( name(ECode), def_namespace_body( args( enum_code, to_str ) ) ); | 	CodeNamespace nspace = def_namespace( name(ECode), def_namespace_body( args( enum_code, to_str ) ) ); | ||||||
|  | 	CodeUsing    code_t  = def_using( name(CodeT), def_type( name(ECode::Type) ) ); | ||||||
| 	CodeUsing code_t = def_using( name(CodeT), def_type( name(ECode::Type) ) ); |  | ||||||
|  |  | ||||||
| 	return def_global_body( args( nspace, code_t ) ); | 	return def_global_body( args( nspace, code_t ) ); | ||||||
| } | } | ||||||
| @@ -209,7 +208,7 @@ CodeBody gen_especifier( char const* path ) | |||||||
|  |  | ||||||
| CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) | CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) | ||||||
| { | { | ||||||
| 	char scratch_mem[kilobytes(64)]; | 	char  scratch_mem[kilobytes(64)]; | ||||||
| 	Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) ); | 	Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) ); | ||||||
|  |  | ||||||
| 	FileContents enum_content = file_read_contents( scratch, zero_terminate, etok_path ); | 	FileContents enum_content = file_read_contents( scratch, zero_terminate, etok_path ); | ||||||
| @@ -217,8 +216,6 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) | |||||||
| 	CSV_Object csv_enum_nodes; | 	CSV_Object csv_enum_nodes; | ||||||
| 	csv_parse( &csv_enum_nodes, rcast(char*, enum_content.data), GlobalAllocator, false ); | 	csv_parse( &csv_enum_nodes, rcast(char*, enum_content.data), GlobalAllocator, false ); | ||||||
|  |  | ||||||
| 	// memset( scratch_mem, 0, sizeof(scratch_mem) ); |  | ||||||
| 	// scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) ); |  | ||||||
| 	FileContents attrib_content = file_read_contents( scratch, zero_terminate, attr_path ); | 	FileContents attrib_content = file_read_contents( scratch, zero_terminate, attr_path ); | ||||||
|  |  | ||||||
| 	CSV_Object csv_attr_nodes; | 	CSV_Object csv_attr_nodes; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user