mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 14:30:53 -07:00 
			
		
		
		
	Started to generate the enums from csv (ECode, EOperator, ESpecifier).
- Changed the zpl csv parser to only accept hex values with 0x perfix. it was messing with the add term. - Small changes to the clang format config.
This commit is contained in:
		| @@ -0,0 +1,2 @@ | ||||
| API_Export, GEN_API_Export_Code | ||||
| API_Import, GEN_API_Import_Code | ||||
|   | ||||
| 
 | 
| @@ -0,0 +1,46 @@ | ||||
| Untyped | ||||
| Comment | ||||
| Access_Private | ||||
| Access_Protected | ||||
| Access_Public | ||||
| PlatformAttributes | ||||
| Class | ||||
| Class_Fwd | ||||
| Class_Body | ||||
| Enum | ||||
| Enum_Fwd | ||||
| Enum_Body | ||||
| Enum_Class | ||||
| Enum_Class_Fwd | ||||
| Execution | ||||
| Export_Body | ||||
| Extern_Linkage | ||||
| Extern_Linkage_Body | ||||
| Friend | ||||
| Function | ||||
| Function_Fwd | ||||
| Function_Body | ||||
| Global_Body | ||||
| Module | ||||
| Namespace | ||||
| Namespace_Body | ||||
| Operator | ||||
| Operator_Fwd | ||||
| Operator_Member | ||||
| Operator_Member_Fwd | ||||
| Operator_Cast | ||||
| Operator_Cast_Fwd | ||||
| Parameters | ||||
| Preprocessor_Include | ||||
| Specifiers | ||||
| Struct | ||||
| Struct_Fwd | ||||
| Struct_Body | ||||
| Template | ||||
| Typedef | ||||
| Typename | ||||
| Union | ||||
| Union_Body | ||||
| Using | ||||
| Using_Namespace | ||||
| Variable | ||||
|   | ||||
| 
 | 
| @@ -0,0 +1,42 @@ | ||||
| Assign,          "=" | ||||
| Assign_Add,      "+=" | ||||
| Assign_Subtract, "-=" | ||||
| Assign_Multiply, "*=" | ||||
| Assign_Divide,   "/=" | ||||
| Assign_Modulo,   "%=" | ||||
| Assign_BAnd,     "&=" | ||||
| Assign_BOr,      "|=" | ||||
| Assign_BXOr,     "^=" | ||||
| Assign_LShift,   "<<=" | ||||
| Assign_RShift,   ">>=" | ||||
| Increment,       "++" | ||||
| Decrement,       "--" | ||||
| Unary_Plus,      "+" | ||||
| Unary_Minus,     "-" | ||||
| UnaryNot,        "!" | ||||
| Add,             "+" | ||||
| Subtract,        "-" | ||||
| Multiply,        "*" | ||||
| Divide,          "/" | ||||
| Modulo,          "%" | ||||
| BNot,            "~" | ||||
| BAnd,            "&" | ||||
| BOr,             "|" | ||||
| BXOr,            "^" | ||||
| LShift,          "<<" | ||||
| RShift,          ">>" | ||||
| LAnd,            "&&" | ||||
| LOr,             "||" | ||||
| LEqual,          "==" | ||||
| LNot,            "!=" | ||||
| Lesser,          "<" | ||||
| Greater,         ">" | ||||
| LesserEqual,     "<=" | ||||
| GreaterEqual,    ">=" | ||||
| Subscript,       "[]" | ||||
| Indirection,     "*" | ||||
| AddressOf,       "&" | ||||
| MemberOfPointer, "->" | ||||
| PtrToMemOfPtr,   "->*" | ||||
| FunctionCall,    "()" | ||||
| Comma,           "," | ||||
|   | ||||
| 
 | 
| @@ -0,0 +1,22 @@ | ||||
| Invalid,          INVALID | ||||
| Consteval,        consteval | ||||
| Constexpr,        constexpr | ||||
| Constinit,        constinit | ||||
| Explicit,         explicit | ||||
| External_Linkage, extern | ||||
| Global,           global | ||||
| Inline,           inline | ||||
| Internal_Linkage, internal | ||||
| Local_Persist,    local_persist | ||||
| Mutable,          mutable | ||||
| Ptr,              * | ||||
| Ref,              & | ||||
| Register,         register | ||||
| RValue,           && | ||||
| Static,           static | ||||
| Thread_Local,     thread_local | ||||
| Volatile,         volatile | ||||
| Virtual,          virtual | ||||
| Const,            const | ||||
| Final,            final | ||||
| Override,         override | ||||
|   | ||||
| 
 | 
| @@ -0,0 +1,69 @@ | ||||
| 	Access_Private,         "private" | ||||
| 	Access_Protected,       "protected" | ||||
| 	Access_Public,          "public" | ||||
| 	Access_MemberSymbol,    "." | ||||
| 	Access_StaticSymbol,    "::" | ||||
| 	Ampersand,              "&" | ||||
| 	Ampersand_DBL,          "&&" | ||||
| 	Assign_Classifer,       ":" | ||||
| 	Attribute_Open, 	    "[[" | ||||
| 	Attribute_Close, 	    "]]" | ||||
| 	BraceCurly_Open,        "{" | ||||
| 	BraceCurly_Close,       "}" | ||||
| 	BraceSquare_Open,       "[" | ||||
| 	BraceSquare_Close,      "]" | ||||
| 	Capture_Start,          "(" | ||||
| 	Capture_End,            ")" | ||||
| 	Comment,                "__comment__" | ||||
| 	Char,                   "__char__" | ||||
| 	Comma,                  "," | ||||
| 	Decl_Class,             "class" | ||||
| 	Decl_GNU_Attribute,     "__attribute__" | ||||
| 	Decl_MSVC_Attribute,    "__declspec" | ||||
| 	Decl_Enum,              "enum" | ||||
| 	Decl_Extern_Linkage,    "extern" | ||||
| 	Decl_Friend,            "friend" | ||||
| 	Decl_Module,            "module" | ||||
| 	Decl_Namespace,         "namespace" | ||||
| 	Decl_Operator,          "operator" | ||||
| 	Decl_Struct,            "struct" | ||||
| 	Decl_Template,          "template" | ||||
| 	Decl_Typedef,           "typedef" | ||||
| 	Decl_Using,             "using" | ||||
| 	Decl_Union,             "union" | ||||
| 	Identifier,             "__identifier__" | ||||
| 	Module_Import,          "import" | ||||
| 	Module_Export,          "export" | ||||
| 	Number,                 "number" | ||||
| 	Operator,               "operator" | ||||
| 	Preprocessor_Directive, "#" | ||||
| 	Preprocessor_Include,   "include" | ||||
| 	Spec_Alignas,           "alignas" | ||||
| 	Spec_Const,             "const" | ||||
| 	Spec_Consteval,         "consteval" | ||||
| 	Spec_Constexpr,         "constexpr" | ||||
| 	Spec_Constinit,         "constinit" | ||||
| 	Spec_Explicit, 		    "explicit" | ||||
| 	Spec_Extern,            "extern" | ||||
| 	Spec_Final, 		    "final" | ||||
| 	Spec_Global, 		    "global" | ||||
| 	Spec_Inline,            "inline" | ||||
| 	Spec_Internal_Linkage,  "internal" | ||||
| 	Spec_LocalPersist,      "local_persist" | ||||
| 	Spec_Mutable,           "mutable" | ||||
| 	Spec_Override,          "override" | ||||
| 	Spec_Static,            "static" | ||||
| 	Spec_ThreadLocal,       "thread_local" | ||||
| 	Spec_Volatile,          "volatile" | ||||
| 	Star,                   "*" | ||||
| 	Statement_End,          ";" | ||||
| 	String,                 "__string__" | ||||
| 	Type_Unsigned, 	        "unsigned" | ||||
| 	Type_Signed,            "signed" | ||||
| 	Type_Short,             "short" | ||||
| 	Type_Long,              "long" | ||||
| 	Type_char, 			    "char" | ||||
| 	Type_int, 			    "int" | ||||
| 	Type_double, 		    "double" | ||||
| 	Varadic_Argument,       "..." | ||||
| 	Attributes_Start,       "__attrib_start__" | ||||
|   | ||||
| 
 | 
| @@ -1,3 +1,5 @@ | ||||
| #pragma region AST | ||||
|  | ||||
| Code Code::Global; | ||||
| Code Code::Invalid; | ||||
|  | ||||
| @@ -5,215 +7,11 @@ AST* AST::duplicate() | ||||
| { | ||||
| 	using namespace ECode; | ||||
|  | ||||
| 	AST* | ||||
| 	result = make_code().ast; | ||||
| #ifndef GEN_USE_RECURSIVE_AST_DUPLICATION | ||||
| 	AST* result = make_code().ast; | ||||
|  | ||||
| 	mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 	result->Parent = nullptr; | ||||
| #else | ||||
| 	// TODO : Stress test this... | ||||
| 	switch ( Type ) | ||||
| 	{ | ||||
| 		case Invalid: | ||||
| 			log_failure("Attempted to duplicate invalid code! - \n%s", Parent ? Parent->debug_str() : Name ); | ||||
| 			return nullptr | ||||
| 		case Untyped: | ||||
| 		case Comment: | ||||
| 		case Execution: | ||||
| 		case Access_Private: | ||||
| 		case Access_Protected: | ||||
| 		case Access_Public: | ||||
| 		case PlatformAttributes: | ||||
| 		case Preprocessor_Include: | ||||
| 		case Module: | ||||
| 		case Specifiers: | ||||
| 		case Using_Namespace: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
| 		break; | ||||
|  | ||||
| 		case Extern_Linkage: | ||||
| 		case Friend: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			if (Value) | ||||
| 				result->Value = Value->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Class: | ||||
| 		case Struct: | ||||
| 		case Enum: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			if ( Attributes) | ||||
| 				result->Attributes = Attributes->duplicate(); | ||||
|  | ||||
| 			if ( ParentType ) | ||||
| 				result->ParentType = ParentType->duplicate(); | ||||
|  | ||||
| 			result->Body = Body->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Enum_Fwd: | ||||
| 		case Class_Fwd: | ||||
| 		case Struct_Fwd: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			if ( Attributes) | ||||
| 				result->Attributes = Attributes->duplicate(); | ||||
|  | ||||
| 			if ( ParentType ) | ||||
| 				result->ParentType = ParentType->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Function: | ||||
| 		case Operator: | ||||
| 		case Operator_Member: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			if ( Attributes) | ||||
| 				result->Attributes = Attributes->duplicate(); | ||||
|  | ||||
| 			if ( Specs ) | ||||
| 				result->ParentType = ParentType->duplicate(); | ||||
|  | ||||
| 			if ( ReturnType ) | ||||
| 				result->ReturnType = ReturnType->duplicate(); | ||||
|  | ||||
| 			if ( Params ) | ||||
| 				result->Params = Params->duplicate(); | ||||
|  | ||||
| 			result->Body = Body->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Function_Fwd: | ||||
| 		case Operator_Fwd: | ||||
| 		case Operator_Member_Fwd: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			if ( Attributes) | ||||
| 				result->Attributes = Attributes->duplicate(); | ||||
|  | ||||
| 			if ( Specs ) | ||||
| 				result->ParentType = ParentType->duplicate(); | ||||
|  | ||||
| 			if ( ReturnType ) | ||||
| 				result->ReturnType = ReturnType->duplicate(); | ||||
|  | ||||
| 			if ( Params ) | ||||
| 				result->Params = Params->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Namespace: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			result->Body = Body->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Operator_Cast: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			result->ValueType = ValueType->duplicate(); | ||||
| 			result->Body      = Body->duplicate(); | ||||
| 		break; | ||||
| 		case Operator_Cast_Fwd: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			result->ValueType = ValueType->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Parameters: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			result->NumEntries = 0; | ||||
| 			result->Last = nullptr; | ||||
| 			result->Next = nullptr; | ||||
|  | ||||
| 			if ( NumEntries - 1 > 0 ) | ||||
| 			{ | ||||
| 				CodeParam parent = result->cast<CodeParam>(); | ||||
| 				for ( CodeParam param : Next->cast<CodeParam>() ) | ||||
| 				{ | ||||
| 					parent.append( param ); | ||||
| 				} | ||||
| 			} | ||||
| 		break; | ||||
|  | ||||
| 		case Template: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			result->Params      = Params->duplicate(); | ||||
| 			result->Declaration = Declaration->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Typename: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			if (Attributes) | ||||
| 				result->Attributes = Attributes->duplicate(); | ||||
|  | ||||
| 			if ( Specs ) | ||||
| 				result->Specs = Specs->duplicate(); | ||||
|  | ||||
| 			if ( ArrExpr ) | ||||
| 				result->ArrExpr = ArrExpr->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Typedef: | ||||
| 		case Using: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			if (Attributes) | ||||
| 				result->Attributes = Attributes->duplicate(); | ||||
|  | ||||
| 			if ( UnderlyingType ) | ||||
| 				result->UnderlyingType = UnderlyingType->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Union: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			if ( Attributes) | ||||
| 				result->Attributes = Attributes->duplicate(); | ||||
|  | ||||
| 			result->Body = Body->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Variable: | ||||
| 			mem_copy( result, this, sizeof( AST ) ); | ||||
|  | ||||
| 			if (Attributes) | ||||
| 				result->Attributes = Attributes->duplicate(); | ||||
|  | ||||
| 			if ( Specs ) | ||||
| 				result->Specs = Specs->duplicate(); | ||||
|  | ||||
| 			result->ValueType = UnderlyingType->duplicate(); | ||||
|  | ||||
| 			if ( Value ) | ||||
| 				result->Value = Value->duplicate(); | ||||
| 		break; | ||||
|  | ||||
| 		case Class_Body: | ||||
| 		case Enum_Body: | ||||
| 		case Export_Body: | ||||
| 		case Extern_Linkage_Body: | ||||
| 		case Function_Body: | ||||
| 		case Global_Body: | ||||
| 		case Namespace_Body: | ||||
| 		case Struct_Body: | ||||
| 		case Union_Body: | ||||
| 			CodeBody | ||||
| 			body         = cast<CodeBody>(); | ||||
| 			body->Name   = Name; | ||||
| 			body->Type   = Type; | ||||
| 			for ( Code entry : cast<CodeBody>() ) | ||||
| 			{ | ||||
| 				result->append( entry.ast ); | ||||
| 			} | ||||
| 		break; | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -1028,3 +826,5 @@ bool AST::validate_body() | ||||
|  | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| #pragma endregion AST | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| #pragma region Data Structures | ||||
|  | ||||
| // Implements basic string interning. Data structure is based off the ZPL Hashtable. | ||||
| using StringTable = HashTable<String const>; | ||||
|  | ||||
| @@ -1011,3 +1013,4 @@ struct AST_Var | ||||
| static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST"); | ||||
| #pragma endregion Filtered ASTs | ||||
|  | ||||
| #pragma endregion Data Structures | ||||
|   | ||||
							
								
								
									
										78
									
								
								project/components/gen.ecode.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								project/components/gen.ecode.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| // This is the non-bootstraped version of the ECode. This will be obsolete once bootstrap is stress tested. | ||||
|  | ||||
| namespace ECode | ||||
| { | ||||
| #	define Define_Types           \ | ||||
| 	Entry( Untyped )              \ | ||||
| 	Entry( Comment )              \ | ||||
| 	Entry( Access_Private )       \ | ||||
| 	Entry( Access_Protected )     \ | ||||
| 	Entry( Access_Public )        \ | ||||
| 	Entry( PlatformAttributes )   \ | ||||
| 	Entry( Class )                \ | ||||
| 	Entry( Class_Fwd )            \ | ||||
| 	Entry( Class_Body )           \ | ||||
| 	Entry( Enum )                 \ | ||||
| 	Entry( Enum_Fwd )             \ | ||||
| 	Entry( Enum_Body )            \ | ||||
| 	Entry( Enum_Class )           \ | ||||
| 	Entry( Enum_Class_Fwd )       \ | ||||
| 	Entry( Execution )            \ | ||||
| 	Entry( Export_Body )          \ | ||||
| 	Entry( Extern_Linkage )       \ | ||||
| 	Entry( Extern_Linkage_Body )  \ | ||||
| 	Entry( Friend )               \ | ||||
| 	Entry( Function )             \ | ||||
| 	Entry( Function_Fwd )         \ | ||||
| 	Entry( Function_Body )        \ | ||||
| 	Entry( Global_Body )          \ | ||||
| 	Entry( Module )               \ | ||||
| 	Entry( Namespace )            \ | ||||
| 	Entry( Namespace_Body )       \ | ||||
| 	Entry( Operator )             \ | ||||
| 	Entry( Operator_Fwd )         \ | ||||
| 	Entry( Operator_Member )      \ | ||||
| 	Entry( Operator_Member_Fwd )  \ | ||||
| 	Entry( Operator_Cast )		  \ | ||||
| 	Entry( Operator_Cast_Fwd )    \ | ||||
| 	Entry( Parameters )           \ | ||||
| 	Entry( Preprocessor_Include ) \ | ||||
| 	Entry( Specifiers )           \ | ||||
| 	Entry( Struct )               \ | ||||
| 	Entry( Struct_Fwd )           \ | ||||
| 	Entry( Struct_Body )          \ | ||||
| 	Entry( Template )             \ | ||||
| 	Entry( Typedef )              \ | ||||
| 	Entry( Typename )             \ | ||||
| 	Entry( Union )			      \ | ||||
| 	Entry( Union_Body) 		      \ | ||||
| 	Entry( Using )                \ | ||||
| 	Entry( Using_Namespace )      \ | ||||
| 	Entry( Variable ) | ||||
|  | ||||
| 	enum Type : u32 | ||||
| 	{ | ||||
| 	#	define Entry( Type ) Type, | ||||
| 		Define_Types | ||||
| 	#	undef Entry | ||||
|  | ||||
| 		Num_Types, | ||||
| 		Invalid | ||||
| 	}; | ||||
|  | ||||
| 	inline | ||||
| 	StrC to_str( Type type ) | ||||
| 	{ | ||||
| 		static | ||||
| 		StrC lookup[Num_Types] = { | ||||
| 		#	define Entry( Type ) { sizeof(stringize(Type)), stringize(Type) }, | ||||
| 			Define_Types | ||||
| 		#	undef Entry | ||||
| 		}; | ||||
|  | ||||
| 		return lookup[ type ]; | ||||
| 	} | ||||
|  | ||||
| #	undef Define_Types | ||||
| } | ||||
| using CodeT = ECode::Type; | ||||
							
								
								
									
										75
									
								
								project/components/gen.eoperator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								project/components/gen.eoperator.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| // This is the non-bootstraped version of the EOperator. This will be obsolete once bootstrap is stress tested. | ||||
|  | ||||
| namespace EOperator | ||||
| { | ||||
| #	define Define_Operators       \ | ||||
| 	Entry( Assign,          =  )  \ | ||||
| 	Entry( Assign_Add,      += )  \ | ||||
| 	Entry( Assign_Subtract, -= )  \ | ||||
| 	Entry( Assign_Multiply, *= )  \ | ||||
| 	Entry( Assign_Divide,   /= )  \ | ||||
| 	Entry( Assign_Modulo,   %= )  \ | ||||
| 	Entry( Assign_BAnd,     &= )  \ | ||||
| 	Entry( Assign_BOr,      |= )  \ | ||||
| 	Entry( Assign_BXOr,     ^= )  \ | ||||
| 	Entry( Assign_LShift,   <<= ) \ | ||||
| 	Entry( Assign_RShift,   >>= ) \ | ||||
| 	Entry( Increment,       ++ )  \ | ||||
| 	Entry( Decrement,       -- )  \ | ||||
| 	Entry( Unary_Plus,      + )   \ | ||||
| 	Entry( Unary_Minus,     - )   \ | ||||
| 	Entry( UnaryNot,        ! )   \ | ||||
| 	Entry( Add,             + )   \ | ||||
| 	Entry( Subtract,        - )   \ | ||||
| 	Entry( Multiply,        * )   \ | ||||
| 	Entry( Divide,          / )   \ | ||||
| 	Entry( Modulo,          % )   \ | ||||
| 	Entry( BNot,            ~ )   \ | ||||
| 	Entry( BAnd,            & )   \ | ||||
| 	Entry( BOr,             | )   \ | ||||
| 	Entry( BXOr,            ^ )   \ | ||||
| 	Entry( LShift,          << )  \ | ||||
| 	Entry( RShift,          >> )  \ | ||||
| 	Entry( LAnd,            && )  \ | ||||
| 	Entry( LOr,             || )  \ | ||||
| 	Entry( LEqual,          == )  \ | ||||
| 	Entry( LNot,            != )  \ | ||||
| 	Entry( Lesser,          < )   \ | ||||
| 	Entry( Greater,         > )   \ | ||||
| 	Entry( LesserEqual,     <= )  \ | ||||
| 	Entry( GreaterEqual,    >= )  \ | ||||
| 	Entry( Subscript,       [] )  \ | ||||
| 	Entry( Indirection,     * )   \ | ||||
| 	Entry( AddressOf,       & )   \ | ||||
| 	Entry( MemberOfPointer, -> )  \ | ||||
| 	Entry( PtrToMemOfPtr,   ->* ) \ | ||||
| 	Entry( FunctionCall,    () ) | ||||
|  | ||||
| 	enum Type : u32 | ||||
| 	{ | ||||
| 	#	define Entry( Type_, Token_ ) Type_, | ||||
| 		Define_Operators | ||||
| 	#	undef Entry | ||||
| 		Comma, | ||||
|  | ||||
| 		Num_Ops, | ||||
| 		Invalid | ||||
| 	}; | ||||
|  | ||||
| 	inline | ||||
| 	char const* to_str( Type op ) | ||||
| 	{ | ||||
| 		local_persist | ||||
| 		char const* lookup[ Num_Ops ] = { | ||||
| 		#	define Entry( Type_, Token_ ) stringize(Token_), | ||||
| 			Define_Operators | ||||
| 		#	undef Entry | ||||
| 			"," | ||||
| 		}; | ||||
|  | ||||
| 		return lookup[ op ]; | ||||
| 	} | ||||
|  | ||||
| #	undef Define_Operators | ||||
| } | ||||
| using OperatorT = EOperator::Type; | ||||
							
								
								
									
										104
									
								
								project/components/gen.especifier.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								project/components/gen.especifier.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| // This is the non-bootstraped version of the ESpecifier. This will be obsolete once bootstrap is stress tested. | ||||
|  | ||||
| namespace ESpecifier | ||||
| { | ||||
| /* | ||||
| 	Note: The following are handled separately: | ||||
| 	attributes | ||||
| 	alignas | ||||
| */ | ||||
|  | ||||
| #	define Define_Specifiers                     \ | ||||
| 	Entry( Invalid,          INVALID )           \ | ||||
| 	Entry( Consteval,        consteval )         \ | ||||
| 	Entry( Constexpr,        constexpr )         \ | ||||
| 	Entry( Constinit,        constinit )         \ | ||||
| 	Entry( Explicit,         explicit )          \ | ||||
| 	Entry( External_Linkage, extern )            \ | ||||
| 	Entry( Global,           global )            \ | ||||
| 	Entry( Inline,           inline )            \ | ||||
| 	Entry( Internal_Linkage, internal )          \ | ||||
| 	Entry( Local_Persist,    local_persist )     \ | ||||
| 	Entry( Mutable,          mutable )           \ | ||||
| 	Entry( Ptr,              * )                 \ | ||||
| 	Entry( Ref,              & )                 \ | ||||
| 	Entry( Register,         register )          \ | ||||
| 	Entry( RValue,           && )                \ | ||||
| 	Entry( Static,           static  )           \ | ||||
| 	Entry( Thread_Local,     thread_local )      \ | ||||
| 	Entry( Volatile,         volatile )          \ | ||||
| 	Entry( Virtual,          virtual )           \ | ||||
| 	Entry( Const,            const )             \ | ||||
| 	Entry( Final,            final )             \ | ||||
| 	Entry( Override,         override ) | ||||
|  | ||||
| 	enum Type : u32 | ||||
| 	{ | ||||
| 	#	define Entry( Specifier, Code ) Specifier, | ||||
| 		Define_Specifiers | ||||
| 	#	undef Entry | ||||
|  | ||||
| 		Num_Specifiers, | ||||
| 	}; | ||||
|  | ||||
| 	inline | ||||
| 	bool is_trailing( Type specifier ) | ||||
| 	{ | ||||
| 		return specifier > Virtual; | ||||
| 	} | ||||
|  | ||||
| 	// Specifier to string | ||||
| 	inline | ||||
| 	StrC to_str( Type specifier ) | ||||
| 	{ | ||||
| 		local_persist | ||||
| 		StrC lookup[ Num_Specifiers ] = { | ||||
| 		#	pragma push_macro( "global" ) | ||||
| 		#	pragma push_macro( "internal" ) | ||||
| 		#	pragma push_macro( "local_persist" ) | ||||
| 		#	undef global | ||||
| 		#	undef internal | ||||
| 		#	undef local_persist | ||||
|  | ||||
| 		#	define Entry( Spec_, Code_ ) { sizeof(stringize(Code_)), stringize(Code_) }, | ||||
| 			Define_Specifiers | ||||
| 		#	undef Entry | ||||
|  | ||||
| 		#	pragma pop_macro( "global" ) | ||||
| 		#	pragma pop_macro( "internal" ) | ||||
| 		#	pragma pop_macro( "local_persist" ) | ||||
| 		}; | ||||
|  | ||||
| 		return lookup[ specifier ]; | ||||
| 	} | ||||
|  | ||||
| 	inline | ||||
| 	Type to_type( StrC str ) | ||||
| 	{ | ||||
| 		local_persist | ||||
| 		u32 keymap[ Num_Specifiers ]; | ||||
| 		do_once_start | ||||
| 			for ( u32 index = 0; index < Num_Specifiers; index++ ) | ||||
| 			{ | ||||
| 				StrC enum_str = to_str( (Type)index ); | ||||
|  | ||||
| 				// We subtract 1 to remove the null terminator | ||||
| 				// This is because the tokens lexed are not null terminated. | ||||
| 				keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1); | ||||
| 			} | ||||
| 		do_once_end | ||||
|  | ||||
| 		u32 hash = crc32( str.Ptr, str.Len ); | ||||
|  | ||||
| 		for ( u32 index = 0; index < Num_Specifiers; index++ ) | ||||
| 		{ | ||||
| 			if ( keymap[index] == hash ) | ||||
| 				return (Type)index; | ||||
| 		} | ||||
|  | ||||
| 		return Invalid; | ||||
| 	} | ||||
|  | ||||
| #	undef Define_Specifiers | ||||
| } | ||||
| using SpecifierT = ESpecifier::Type; | ||||
| @@ -1,3 +1,5 @@ | ||||
| #pragma region Gen Interface | ||||
|  | ||||
| // Initialize the library. | ||||
| // This currently just initializes the CodePool. | ||||
| void init(); | ||||
| @@ -32,6 +34,7 @@ void set_allocator_string_table( AllocatorInfo string_allocator ); | ||||
| void set_allocator_type_table  ( AllocatorInfo type_reg_allocator ); | ||||
|  | ||||
| #pragma region Upfront | ||||
|  | ||||
| CodeAttributes def_attributes( StrC content ); | ||||
| CodeComment    def_comment   ( StrC content ); | ||||
|  | ||||
| @@ -122,9 +125,11 @@ 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 ); | ||||
|  | ||||
| #pragma endregion Upfront | ||||
|  | ||||
| #pragma region Parsing | ||||
|  | ||||
| CodeClass     parse_class        ( StrC class_def     ); | ||||
| CodeEnum      parse_enum         ( StrC enum_def      ); | ||||
| CodeBody      parse_export_body  ( StrC export_def    ); | ||||
| @@ -142,13 +147,18 @@ CodeTypedef   parse_typedef      ( StrC typedef_def   ); | ||||
| CodeUnion     parse_union        ( StrC union_def     ); | ||||
| CodeUsing     parse_using        ( StrC using_def     ); | ||||
| CodeVar       parse_variable     ( StrC var_def       ); | ||||
|  | ||||
| #pragma endregion Parsing | ||||
|  | ||||
| #pragma region Untyped text | ||||
|  | ||||
| sw   token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va ); | ||||
| StrC token_fmt_impl( sw, ... ); | ||||
|  | ||||
| Code untyped_str      ( StrC content); | ||||
| Code untyped_fmt      ( char const* fmt, ... ); | ||||
| Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... ); | ||||
|  | ||||
| #pragma endregion Untyped text | ||||
|  | ||||
| #pragma endregion Gen Interface | ||||
|   | ||||
| @@ -8,83 +8,6 @@ using LogFailType = sw(*)(char const*, ...); | ||||
| 	constexpr LogFailType log_failure = fatal; | ||||
| #endif | ||||
|  | ||||
| namespace ECode | ||||
| { | ||||
| #	define Define_Types           \ | ||||
| 	Entry( Untyped )              \ | ||||
| 	Entry( Comment )              \ | ||||
| 	Entry( Access_Private )       \ | ||||
| 	Entry( Access_Protected )     \ | ||||
| 	Entry( Access_Public )        \ | ||||
| 	Entry( PlatformAttributes )   \ | ||||
| 	Entry( Class )                \ | ||||
| 	Entry( Class_Fwd )            \ | ||||
| 	Entry( Class_Body )           \ | ||||
| 	Entry( Enum )                 \ | ||||
| 	Entry( Enum_Fwd )             \ | ||||
| 	Entry( Enum_Body )            \ | ||||
| 	Entry( Enum_Class )           \ | ||||
| 	Entry( Enum_Class_Fwd )       \ | ||||
| 	Entry( Execution )            \ | ||||
| 	Entry( Export_Body )          \ | ||||
| 	Entry( Extern_Linkage )       \ | ||||
| 	Entry( Extern_Linkage_Body )  \ | ||||
| 	Entry( Friend )               \ | ||||
| 	Entry( Function )             \ | ||||
| 	Entry( Function_Fwd )         \ | ||||
| 	Entry( Function_Body )        \ | ||||
| 	Entry( Global_Body )          \ | ||||
| 	Entry( Module )               \ | ||||
| 	Entry( Namespace )            \ | ||||
| 	Entry( Namespace_Body )       \ | ||||
| 	Entry( Operator )             \ | ||||
| 	Entry( Operator_Fwd )         \ | ||||
| 	Entry( Operator_Member )      \ | ||||
| 	Entry( Operator_Member_Fwd )  \ | ||||
| 	Entry( Operator_Cast )		  \ | ||||
| 	Entry( Operator_Cast_Fwd )    \ | ||||
| 	Entry( Parameters )           \ | ||||
| 	Entry( Preprocessor_Include ) \ | ||||
| 	Entry( Specifiers )           \ | ||||
| 	Entry( Struct )               \ | ||||
| 	Entry( Struct_Fwd )           \ | ||||
| 	Entry( Struct_Body )          \ | ||||
| 	Entry( Template )             \ | ||||
| 	Entry( Typedef )              \ | ||||
| 	Entry( Typename )             \ | ||||
| 	Entry( Union )			      \ | ||||
| 	Entry( Union_Body) 		      \ | ||||
| 	Entry( Using )                \ | ||||
| 	Entry( Using_Namespace )      \ | ||||
| 	Entry( Variable ) | ||||
|  | ||||
| 	enum Type : u32 | ||||
| 	{ | ||||
| 	#	define Entry( Type ) Type, | ||||
| 		Define_Types | ||||
| 	#	undef Entry | ||||
|  | ||||
| 		Num_Types, | ||||
| 		Invalid | ||||
| 	}; | ||||
|  | ||||
| 	inline | ||||
| 	StrC to_str( Type type ) | ||||
| 	{ | ||||
| 		static | ||||
| 		StrC lookup[Num_Types] = { | ||||
| 		#	define Entry( Type ) { sizeof(stringize(Type)), stringize(Type) }, | ||||
| 			Define_Types | ||||
| 		#	undef Entry | ||||
| 		}; | ||||
|  | ||||
| 		return lookup[ type ]; | ||||
| 	} | ||||
|  | ||||
| #	undef Define_Types | ||||
| } | ||||
| using CodeT = ECode::Type; | ||||
|  | ||||
| // Used to indicate if enum definitoin is an enum class or regular enum. | ||||
| enum class EnumT : u8 | ||||
| { | ||||
| @@ -95,183 +18,6 @@ enum class EnumT : u8 | ||||
| constexpr EnumT EnumClass   = EnumT::Class; | ||||
| constexpr EnumT EnumRegular = EnumT::Regular; | ||||
|  | ||||
| namespace EOperator | ||||
| { | ||||
| #	define Define_Operators       \ | ||||
| 	Entry( Assign,          =  )  \ | ||||
| 	Entry( Assign_Add,      += )  \ | ||||
| 	Entry( Assign_Subtract, -= )  \ | ||||
| 	Entry( Assign_Multiply, *= )  \ | ||||
| 	Entry( Assign_Divide,   /= )  \ | ||||
| 	Entry( Assign_Modulo,   %= )  \ | ||||
| 	Entry( Assign_BAnd,     &= )  \ | ||||
| 	Entry( Assign_BOr,      |= )  \ | ||||
| 	Entry( Assign_BXOr,     ^= )  \ | ||||
| 	Entry( Assign_LShift,   <<= ) \ | ||||
| 	Entry( Assign_RShift,   >>= ) \ | ||||
| 	Entry( Increment,       ++ )  \ | ||||
| 	Entry( Decrement,       -- )  \ | ||||
| 	Entry( Unary_Plus,      + )   \ | ||||
| 	Entry( Unary_Minus,     - )   \ | ||||
| 	Entry( UnaryNot,        ! )   \ | ||||
| 	Entry( Add,             + )   \ | ||||
| 	Entry( Subtract,        - )   \ | ||||
| 	Entry( Multiply,        * )   \ | ||||
| 	Entry( Divide,          / )   \ | ||||
| 	Entry( Modulo,          % )   \ | ||||
| 	Entry( BNot,            ~ )   \ | ||||
| 	Entry( BAnd,            & )   \ | ||||
| 	Entry( BOr,             | )   \ | ||||
| 	Entry( BXOr,            ^ )   \ | ||||
| 	Entry( LShift,          << )  \ | ||||
| 	Entry( RShift,          >> )  \ | ||||
| 	Entry( LAnd,            && )  \ | ||||
| 	Entry( LOr,             || )  \ | ||||
| 	Entry( LEqual,          == )  \ | ||||
| 	Entry( LNot,            != )  \ | ||||
| 	Entry( Lesser,          < )   \ | ||||
| 	Entry( Greater,         > )   \ | ||||
| 	Entry( LesserEqual,     <= )  \ | ||||
| 	Entry( GreaterEqual,    >= )  \ | ||||
| 	Entry( Subscript,       [] )  \ | ||||
| 	Entry( Indirection,     * )   \ | ||||
| 	Entry( AddressOf,       & )   \ | ||||
| 	Entry( MemberOfPointer, -> )  \ | ||||
| 	Entry( PtrToMemOfPtr,   ->* ) \ | ||||
| 	Entry( FunctionCall,    () ) | ||||
|  | ||||
| 	enum Type : u32 | ||||
| 	{ | ||||
| 	#	define Entry( Type_, Token_ ) Type_, | ||||
| 		Define_Operators | ||||
| 	#	undef Entry | ||||
| 		Comma, | ||||
|  | ||||
| 		Num_Ops, | ||||
| 		Invalid | ||||
| 	}; | ||||
|  | ||||
| 	inline | ||||
| 	char const* to_str( Type op ) | ||||
| 	{ | ||||
| 		local_persist | ||||
| 		char const* lookup[ Num_Ops ] = { | ||||
| 		#	define Entry( Type_, Token_ ) stringize(Token_), | ||||
| 			Define_Operators | ||||
| 		#	undef Entry | ||||
| 			"," | ||||
| 		}; | ||||
|  | ||||
| 		return lookup[ op ]; | ||||
| 	} | ||||
|  | ||||
| #	undef Define_Operators | ||||
| } | ||||
| using OperatorT = EOperator::Type; | ||||
|  | ||||
| namespace ESpecifier | ||||
| { | ||||
| /* | ||||
| 	Note: The following are handled separately: | ||||
| 	attributes | ||||
| 	alignas | ||||
| */ | ||||
|  | ||||
| #	define Define_Specifiers                     \ | ||||
| 	Entry( Invalid,          INVALID )           \ | ||||
| 	Entry( Consteval,        consteval )         \ | ||||
| 	Entry( Constexpr,        constexpr )         \ | ||||
| 	Entry( Constinit,        constinit )         \ | ||||
| 	Entry( Explicit,         explicit )          \ | ||||
| 	Entry( External_Linkage, extern )            \ | ||||
| 	Entry( Global,           global )            \ | ||||
| 	Entry( Inline,           inline )            \ | ||||
| 	Entry( Internal_Linkage, internal )          \ | ||||
| 	Entry( Local_Persist,    local_persist )     \ | ||||
| 	Entry( Mutable,          mutable )           \ | ||||
| 	Entry( Ptr,              * )                 \ | ||||
| 	Entry( Ref,              & )                 \ | ||||
| 	Entry( Register,         register )          \ | ||||
| 	Entry( RValue,           && )                \ | ||||
| 	Entry( Static,           static  )           \ | ||||
| 	Entry( Thread_Local,     thread_local )      \ | ||||
| 	Entry( Volatile,         volatile )          \ | ||||
| 	Entry( Virtual,          virtual )           \ | ||||
| 	Entry( Const,            const )             \ | ||||
| 	Entry( Final,            final )             \ | ||||
| 	Entry( Override,         override ) | ||||
|  | ||||
| 	enum Type : u32 | ||||
| 	{ | ||||
| 	#	define Entry( Specifier, Code ) Specifier, | ||||
| 		Define_Specifiers | ||||
| 	#	undef Entry | ||||
|  | ||||
| 		Num_Specifiers, | ||||
| 	}; | ||||
|  | ||||
| 	inline | ||||
| 	bool is_trailing( Type specifier ) | ||||
| 	{ | ||||
| 		return specifier > Virtual; | ||||
| 	} | ||||
|  | ||||
| 	// Specifier to string | ||||
| 	inline | ||||
| 	StrC to_str( Type specifier ) | ||||
| 	{ | ||||
| 		local_persist | ||||
| 		StrC lookup[ Num_Specifiers ] = { | ||||
| 		#	pragma push_macro( "global" ) | ||||
| 		#	pragma push_macro( "internal" ) | ||||
| 		#	pragma push_macro( "local_persist" ) | ||||
| 		#	undef global | ||||
| 		#	undef internal | ||||
| 		#	undef local_persist | ||||
|  | ||||
| 		#	define Entry( Spec_, Code_ ) { sizeof(stringize(Code_)), stringize(Code_) }, | ||||
| 			Define_Specifiers | ||||
| 		#	undef Entry | ||||
|  | ||||
| 		#	pragma pop_macro( "global" ) | ||||
| 		#	pragma pop_macro( "internal" ) | ||||
| 		#	pragma pop_macro( "local_persist" ) | ||||
| 		}; | ||||
|  | ||||
| 		return lookup[ specifier ]; | ||||
| 	} | ||||
|  | ||||
| 	inline | ||||
| 	Type to_type( StrC str ) | ||||
| 	{ | ||||
| 		local_persist | ||||
| 		u32 keymap[ Num_Specifiers ]; | ||||
| 		do_once_start | ||||
| 			for ( u32 index = 0; index < Num_Specifiers; index++ ) | ||||
| 			{ | ||||
| 				StrC enum_str = to_str( (Type)index ); | ||||
|  | ||||
| 				// We subtract 1 to remove the null terminator | ||||
| 				// This is because the tokens lexed are not null terminated. | ||||
| 				keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1); | ||||
| 			} | ||||
| 		do_once_end | ||||
|  | ||||
| 		u32 hash = crc32( str.Ptr, str.Len ); | ||||
|  | ||||
| 		for ( u32 index = 0; index < Num_Specifiers; index++ ) | ||||
| 		{ | ||||
| 			if ( keymap[index] == hash ) | ||||
| 				return (Type)index; | ||||
| 		} | ||||
|  | ||||
| 		return Invalid; | ||||
| 	} | ||||
|  | ||||
| #	undef Define_Specifiers | ||||
| } | ||||
| using SpecifierT = ESpecifier::Type; | ||||
|  | ||||
| enum class AccessSpec : u32 | ||||
| { | ||||
| 	Default, | ||||
|   | ||||
| @@ -507,6 +507,13 @@ char* adt_parse_number( ADT_Node* node, char* base_str ) | ||||
| 		{ | ||||
| 			node_props = EADT_PROPS_IS_HEX; | ||||
| 		} | ||||
|  | ||||
| 		/* bail if ZPL_ADT_PROPS_IS_HEX is unset but we get 'x' on input */ | ||||
| 		if ( char_to_lower( *e ) == 'x' && ( node_props != EADT_PROPS_IS_HEX ) ) | ||||
| 		{ | ||||
| 			return ++base_str; | ||||
| 		} | ||||
|  | ||||
| 		while ( char_is_hex_digit( *e ) || char_to_lower( *e ) == 'x' ) | ||||
| 		{ | ||||
| 			buf[ ib++ ] = *e++; | ||||
| @@ -795,155 +802,185 @@ ADT_Error adt_str_to_number_strict( ADT_Node* node ) | ||||
|  | ||||
| u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim ) | ||||
| { | ||||
| 	CSV_Error err = ECSV_Error__NONE; | ||||
| 	CSV_Error error = ECSV_Error__NONE; | ||||
| 	GEN_ASSERT_NOT_NULL( root ); | ||||
| 	GEN_ASSERT_NOT_NULL( text ); | ||||
| 	zero_item( root ); | ||||
|  | ||||
| 	adt_make_branch( root, allocator, NULL, has_header ? false : true ); | ||||
|  | ||||
| 	char* p = text; | ||||
| 	char* b = p; | ||||
| 	char* e = p; | ||||
| 	char* currentChar = text; | ||||
| 	char* beginChar; | ||||
| 	char* endChar; | ||||
|  | ||||
| 	sw colc       = 0; | ||||
| 	sw total_colc = 0; | ||||
| 	sw columnIndex       = 0; | ||||
| 	sw totalColumnIndex = 0; | ||||
|  | ||||
| 	do | ||||
| 	{ | ||||
| 		char d = 0; | ||||
| 		p      = zpl_cast( char* ) str_trim( p, false ); | ||||
| 		if ( *p == 0 ) | ||||
| 		char delimiter = 0; | ||||
| 		currentChar = zpl_cast( char* ) str_trim( currentChar, false ); | ||||
|  | ||||
| 		if ( *currentChar == 0 ) | ||||
| 			break; | ||||
| 		ADT_Node row_item = { 0 }; | ||||
| 		row_item.type     = EADT_TYPE_STRING; | ||||
| #ifndef GEN_PARSER_DISABLE_ANALYSIS | ||||
| 		row_item.name_style = EADT_NAME_STYLE_NO_QUOTES; | ||||
| #endif | ||||
|  | ||||
| 		ADT_Node rowItem = { 0 }; | ||||
| 		rowItem.type     = EADT_TYPE_STRING; | ||||
|  | ||||
| 	#ifndef GEN_PARSER_DISABLE_ANALYSIS | ||||
| 		rowItem.name_style = EADT_NAME_STYLE_NO_QUOTES; | ||||
| 	#endif | ||||
|  | ||||
| 		/* handle string literals */ | ||||
| 		if ( *p == '"' ) | ||||
| 		if ( *currentChar == '"' ) | ||||
| 		{ | ||||
| 			p = b = e       = p + 1; | ||||
| 			row_item.string = b; | ||||
| #ifndef GEN_PARSER_DISABLE_ANALYSIS | ||||
| 			row_item.name_style = EADT_NAME_STYLE_DOUBLE_QUOTE; | ||||
| #endif | ||||
| 			currentChar   += 1; | ||||
| 			beginChar      = currentChar; | ||||
| 			endChar        = currentChar; | ||||
| 			rowItem.string = beginChar; | ||||
| 		#ifndef GEN_PARSER_DISABLE_ANALYSIS | ||||
| 			rowItem.name_style = EADT_NAME_STYLE_DOUBLE_QUOTE; | ||||
| 		#endif | ||||
| 			do | ||||
| 			{ | ||||
| 				e = zpl_cast( char* ) str_skip( e, '"' ); | ||||
| 				if ( *e && *( e + 1 ) == '"' ) | ||||
| 				endChar = zpl_cast( char* ) str_skip( endChar, '"' ); | ||||
|  | ||||
| 				if ( *endChar && *( endChar + 1 ) == '"' ) | ||||
| 				{ | ||||
| 					e += 2; | ||||
| 					endChar += 2; | ||||
| 				} | ||||
| 				else | ||||
| 					break; | ||||
| 			} while ( *e ); | ||||
| 			if ( *e == 0 ) | ||||
| 			} | ||||
| 			while ( *endChar ); | ||||
|  | ||||
| 			if ( *endChar == 0 ) | ||||
| 			{ | ||||
| 				GEN_CSV_ASSERT( "unmatched quoted string" ); | ||||
| 				err = ECSV_Error__UNEXPECTED_END_OF_INPUT; | ||||
| 				return err; | ||||
| 				error = ECSV_Error__UNEXPECTED_END_OF_INPUT; | ||||
| 				return error; | ||||
| 			} | ||||
| 			*e = 0; | ||||
| 			p  = zpl_cast( char* ) str_trim( e + 1, true ); | ||||
| 			d  = *p; | ||||
|  | ||||
| 			*endChar    = 0; | ||||
| 			currentChar = zpl_cast( char* ) str_trim( endChar + 1, true ); | ||||
| 			delimiter   = * currentChar; | ||||
|  | ||||
| 			/* unescape escaped quotes (so that unescaped text escapes :) */ | ||||
| 			{ | ||||
| 				char* ep = b; | ||||
| 				char* escapedChar = beginChar; | ||||
| 				do | ||||
| 				{ | ||||
| 					if ( *ep == '"' && *( ep + 1 ) == '"' ) | ||||
| 					if ( *escapedChar == '"' && *( escapedChar + 1 ) == '"' ) | ||||
| 					{ | ||||
| 						mem_move( ep, ep + 1, str_len( ep ) ); | ||||
| 						mem_move( escapedChar, escapedChar + 1, str_len( escapedChar ) ); | ||||
| 					} | ||||
| 					ep++; | ||||
| 				} while ( *ep ); | ||||
| 					escapedChar++; | ||||
| 				} | ||||
| 				while ( *escapedChar ); | ||||
| 			} | ||||
| 		} | ||||
| 		else if ( *p == delim ) | ||||
| 		else if ( *currentChar == delim ) | ||||
| 		{ | ||||
| 			d               = *p; | ||||
| 			row_item.string = ""; | ||||
| 			delimiter      = * currentChar; | ||||
| 			rowItem.string = ""; | ||||
| 		} | ||||
| 		else if ( *p ) | ||||
| 		else if ( *currentChar ) | ||||
| 		{ | ||||
| 			/* regular data */ | ||||
| 			b = e           = p; | ||||
| 			row_item.string = b; | ||||
| 			beginChar      = currentChar; | ||||
| 			endChar        = currentChar; | ||||
| 			rowItem.string = beginChar; | ||||
|  | ||||
| 			do | ||||
| 			{ | ||||
| 				e++; | ||||
| 			} while ( *e && *e != delim && *e != '\n' ); | ||||
| 			if ( *e ) | ||||
| 				endChar++; | ||||
| 			} | ||||
| 			while ( * endChar && * endChar != delim && * endChar != '\n' ); | ||||
|  | ||||
| 			if ( * endChar ) | ||||
| 			{ | ||||
| 				p = zpl_cast( char* ) str_trim( e, true ); | ||||
| 				while ( char_is_space( *( e - 1 ) ) ) | ||||
| 				currentChar = zpl_cast( char* ) str_trim( endChar, true ); | ||||
|  | ||||
| 				while ( char_is_space( *( endChar - 1 ) ) ) | ||||
| 				{ | ||||
| 					e--; | ||||
| 					endChar--; | ||||
| 				} | ||||
| 				d  = *p; | ||||
| 				*e = 0; | ||||
|  | ||||
| 				delimiter = * currentChar; | ||||
| 				* endChar = 0; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				d = 0; | ||||
| 				p = e; | ||||
| 				delimiter   = 0; | ||||
| 				currentChar = endChar; | ||||
| 			} | ||||
|  | ||||
| 			/* check if number and process if so */ | ||||
| 			b32   skip_number = false; | ||||
| 			char* num_p       = b; | ||||
| 			do | ||||
| 			{ | ||||
| 				if ( ! char_is_hex_digit( *num_p ) && ( ! str_find( "+-.eExX", *num_p ) ) ) | ||||
| 				{ | ||||
| 					skip_number = true; | ||||
| 					break; | ||||
| 				} | ||||
| 			} while ( *num_p++ ); | ||||
| 			char* num_p       = beginChar; | ||||
|  | ||||
| 			if ( ! skip_number ) | ||||
| 			// We only consider hexadecimal values if they start with 0x | ||||
| 			if ( str_len(num_p) > 2 && num_p[0] == '0' && (num_p[1] == 'x' || num_p[1] == 'X') ) | ||||
| 			{ | ||||
| 				adt_str_to_number( &row_item ); | ||||
| 				num_p += 2; // skip '0x' prefix | ||||
| 				do | ||||
| 				{ | ||||
| 					if (!char_is_hex_digit(*num_p)) | ||||
| 					{ | ||||
| 						skip_number = true; | ||||
| 						break; | ||||
| 					} | ||||
| 				} while (*num_p++); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				skip_number = true; | ||||
| 			} | ||||
|  | ||||
| 			if (!skip_number) | ||||
| 			{ | ||||
| 				adt_str_to_number(&rowItem); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if ( colc >= root->nodes.num() ) | ||||
| 		if ( columnIndex >= root->nodes.num() ) | ||||
| 		{ | ||||
| 			adt_append_arr( root, NULL ); | ||||
| 		} | ||||
|  | ||||
| 		root->nodes[ colc ].nodes.append( row_item ); | ||||
| 		root->nodes[ columnIndex ].nodes.append( rowItem ); | ||||
|  | ||||
| 		if ( d == delim ) | ||||
| 		if ( delimiter == delim ) | ||||
| 		{ | ||||
| 			colc++; | ||||
| 			p++; | ||||
| 			columnIndex++; | ||||
| 			currentChar++; | ||||
| 		} | ||||
| 		else if ( d == '\n' || d == 0 ) | ||||
| 		else if ( delimiter == '\n' || delimiter == 0 ) | ||||
| 		{ | ||||
| 			/* check if number of rows is not mismatched */ | ||||
| 			if ( total_colc < colc ) | ||||
| 				total_colc = colc; | ||||
| 			else if ( total_colc != colc ) | ||||
| 			if ( totalColumnIndex < columnIndex ) | ||||
| 				totalColumnIndex = columnIndex; | ||||
|  | ||||
| 			else if ( totalColumnIndex != columnIndex ) | ||||
| 			{ | ||||
| 				GEN_CSV_ASSERT( "mismatched rows" ); | ||||
| 				err = ECSV_Error__MISMATCHED_ROWS; | ||||
| 				return err; | ||||
| 				error = ECSV_Error__MISMATCHED_ROWS; | ||||
| 				return error; | ||||
| 			} | ||||
| 			colc = 0; | ||||
| 			if ( d != 0 ) | ||||
| 				p++; | ||||
|  | ||||
| 			columnIndex = 0; | ||||
|  | ||||
| 			if ( delimiter != 0 ) | ||||
| 				currentChar++; | ||||
| 		} | ||||
| 	} while ( *p ); | ||||
| 	} | ||||
| 	while ( *currentChar ); | ||||
|  | ||||
| 	if ( root->nodes.num() == 0 ) | ||||
| 	{ | ||||
| 		GEN_CSV_ASSERT( "unexpected end of input. stream is empty." ); | ||||
| 		err = ECSV_Error__UNEXPECTED_END_OF_INPUT; | ||||
| 		return err; | ||||
| 		error = ECSV_Error__UNEXPECTED_END_OF_INPUT; | ||||
| 		return error; | ||||
| 	} | ||||
|  | ||||
| 	/* consider first row as a header. */ | ||||
| @@ -958,7 +995,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return err; | ||||
| 	return error; | ||||
| } | ||||
|  | ||||
| void csv_free( CSV_Object* obj ) | ||||
|   | ||||
| @@ -372,4 +372,4 @@ struct String_POD | ||||
| }; | ||||
| static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" ); | ||||
|  | ||||
| #pragma endregion String | ||||
| #pragma endregion String | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #define GEN_EXPOSE_BACKEND | ||||
| #include "gen.cpp" | ||||
| #include "filesystem/gen.scanner.hpp" | ||||
| #include "helpers/gen.helper.hpp" | ||||
|  | ||||
| using namespace gen; | ||||
|  | ||||
| @@ -46,7 +47,7 @@ int gen_main() | ||||
| 		Code string_ops    = scan_file( "dependencies/gen.string_ops.hpp" ); | ||||
| 		Code printing      = scan_file( "dependencies/gen.printing.hpp" ); | ||||
| 		Code containers    = scan_file( "dependencies/gen.containers.hpp" ); | ||||
| 		Core hashing 	   = scan_file( "dependencies/gen.hashing.hpp" ); | ||||
| 		Code hashing 	   = scan_file( "dependencies/gen.hashing.hpp" ); | ||||
| 		Code string        = scan_file( "dependencies/gen.string.hpp" ); | ||||
| 		Code file_handling = scan_file( "dependencies/gen.file_handling.hpp" ); | ||||
| 		Code parsing       = scan_file( "dependencies/gen.parsing.hpp" ); | ||||
| @@ -60,18 +61,20 @@ int gen_main() | ||||
| 			deps_header.print( header_start ); | ||||
| 			deps_header.print( nspace_macro ); | ||||
| 			deps_header.print_fmt( "GEN_NS_BEGIN\n\n"); | ||||
| 				deps_header.print( macros ); | ||||
| 				deps_header.print( basic_types ); | ||||
| 				deps_header.print( debug ); | ||||
| 				deps_header.print( memory ); | ||||
| 				deps_header.print( string_ops ); | ||||
| 				deps_header.print( printing ); | ||||
| 				deps_header.print( containers ); | ||||
| 				deps_header.print( hashing ); | ||||
| 				deps_header.print( string ); | ||||
| 				deps_header.print( file_handling ); | ||||
| 				deps_header.print( parsing ); | ||||
| 				deps_header.print( timing ); | ||||
|  | ||||
| 			deps_header.print( macros ); | ||||
| 			deps_header.print( basic_types ); | ||||
| 			deps_header.print( debug ); | ||||
| 			deps_header.print( memory ); | ||||
| 			deps_header.print( string_ops ); | ||||
| 			deps_header.print( printing ); | ||||
| 			deps_header.print( containers ); | ||||
| 			deps_header.print( hashing ); | ||||
| 			deps_header.print( string ); | ||||
| 			deps_header.print( file_handling ); | ||||
| 			deps_header.print( parsing ); | ||||
| 			deps_header.print( timing ); | ||||
|  | ||||
| 			deps_header.print_fmt( "GEN_NS_END\n\n"); | ||||
| 		deps_header.write(); | ||||
| 	} | ||||
| @@ -96,13 +99,16 @@ int gen_main() | ||||
| 			deps_impl.print( impl_start ); | ||||
| 			deps_impl.print( header ); | ||||
| 			deps_impl.print_fmt( "\nGEN_NS_BEGIN\n"); | ||||
| 				deps_impl.print( debug ); | ||||
| 				deps_impl.print( string_ops ); | ||||
| 				deps_impl.print( printing ); | ||||
| 				deps_impl.print( memory ); | ||||
| 				deps_impl.print( parsing ); | ||||
| 				deps_impl.print( string ); | ||||
| 				deps_impl.print( timing ); | ||||
|  | ||||
| 			deps_impl.print( debug ); | ||||
| 			deps_impl.print( string_ops ); | ||||
| 			deps_impl.print( printing ); | ||||
| 			deps_impl.print( hashing ); | ||||
| 			deps_impl.print( memory ); | ||||
| 			deps_impl.print( parsing ); | ||||
| 			deps_impl.print( string ); | ||||
| 			deps_impl.print( timing ); | ||||
|  | ||||
| 			deps_impl.print_fmt( "GEN_NS_END\n\n"); | ||||
| 		deps_impl.write(); | ||||
| 	} | ||||
| @@ -116,6 +122,10 @@ int gen_main() | ||||
| 		Code interface    = scan_file( "components/gen.interface.hpp" ); | ||||
| 		Code header_end   = scan_file( "components/gen.header_end.hpp" ); | ||||
|  | ||||
| 		CodeBody ecode      = gen_ecode( "./components/ECode.csv" ); | ||||
| 		CodeBody eoperator  = gen_eoperator( "./components/EOperator.csv" ); | ||||
| 		CodeBody especifier = gen_especifier( "./components/ESpecifier.csv" ); | ||||
|  | ||||
| 		Code builder = scan_file( "filesystem/gen.builder.hpp" ); | ||||
|  | ||||
| 		Builder | ||||
| @@ -126,11 +136,20 @@ int gen_main() | ||||
| 			header.print( header_start ); | ||||
| 			header.print( nspace_macro ); | ||||
| 			header.print_fmt( "GEN_NS_BEGIN\n\n"); | ||||
| 				header.print( types ); | ||||
| 				header.print( data_structs ); | ||||
| 				header.print( interface ); | ||||
| 				header.print( header_end ); | ||||
| 					header.print( builder ); | ||||
|  | ||||
| 			header.print_fmt("#pragma region Types"); | ||||
| 			header.print( types ); | ||||
| 			header.print( ecode ); | ||||
| 			header.print( eoperator ); | ||||
| 			header.print( especifier ); | ||||
| 			header.print_fmt("#pragma endregion Types"); | ||||
|  | ||||
| 			header.print( data_structs ); | ||||
| 			header.print( interface ); | ||||
| 			header.print( header_end ); | ||||
|  | ||||
| 			header.print( builder ); | ||||
|  | ||||
| 			header.print_fmt( "GEN_NS_END\n\n"); | ||||
| 			header.print( pop_ignores ); | ||||
| 		header.write(); | ||||
| @@ -157,14 +176,16 @@ int gen_main() | ||||
| 			impl.print( impl_start ); | ||||
| 			impl.print( header ); | ||||
| 			impl.print_fmt( "\nGEN_NS_BEGIN\n\n"); | ||||
| 				impl.print( data ); | ||||
| 				impl.print( ast_case_macros ); | ||||
| 				impl.print( ast ); | ||||
| 				impl.print( interface ); | ||||
| 				impl.print( upfront ); | ||||
| 				impl.print( parsing ); | ||||
| 				impl.print( untyped ); | ||||
| 					impl.print( builder ); | ||||
|  | ||||
| 			impl.print( data ); | ||||
| 			impl.print( ast_case_macros ); | ||||
| 			impl.print( ast ); | ||||
| 			impl.print( interface ); | ||||
| 			impl.print( upfront ); | ||||
| 			impl.print( parsing ); | ||||
| 			impl.print( untyped ); | ||||
|  | ||||
| 			impl.print( builder ); | ||||
| 			impl.print_fmt( "GEN_NS_END\n\n"); | ||||
| 			impl.print( pop_ignores ); | ||||
| 		impl.write(); | ||||
|   | ||||
| @@ -22,6 +22,9 @@ | ||||
| GEN_NS_BEGIN | ||||
|  | ||||
| #include "components/gen.types.hpp" | ||||
| #include "components/gen.ecode.hpp" | ||||
| #include "components/gen.eoperator.hpp" | ||||
| #include "components/gen.especifier.hpp" | ||||
| #include "components/gen.data_structures.hpp" | ||||
| #include "components/gen.interface.hpp" | ||||
| #include "components/gen.header_end.hpp" | ||||
|   | ||||
							
								
								
									
										215
									
								
								project/helpers/gen.helper.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								project/helpers/gen.helper.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,215 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "gen.hpp" | ||||
|  | ||||
| using namespace gen; | ||||
|  | ||||
| CodeBody gen_ecode( char const* path ) | ||||
| { | ||||
| 	char scratch_mem[kilobytes(1)]; | ||||
| 	Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) ); | ||||
|  | ||||
| 	file_read_contents( scratch, zero_terminate, path ); | ||||
|  | ||||
| 	CSV_Object csv_nodes; | ||||
| 	csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); | ||||
|  | ||||
| 	Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes; | ||||
|  | ||||
| 	String enum_entries   = String::make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
| 	String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
|  | ||||
| 	for ( ADT_Node node : enum_strs ) | ||||
| 	{ | ||||
| 		char const* code = node.string; | ||||
| 		enum_entries.append_fmt( "%s,\n", code ); | ||||
| 		to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", code, code ); | ||||
| 	} | ||||
|  | ||||
| 	CodeEnum enum_code = parse_enum( token_fmt( "entries", (StrC)enum_entries, stringize( | ||||
| 		enum Type : u32 | ||||
| 		{ | ||||
| 			<entries> | ||||
| 			NumTypes | ||||
| 		}; | ||||
| 	))); | ||||
|  | ||||
| #pragma push_macro( "local_persist" ) | ||||
| #undef local_persist | ||||
| 	CodeFn to_str = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize( | ||||
| 		StrC to_str( Type type ) | ||||
| 		{ | ||||
| 			local_persist | ||||
| 			StrC lookup[] { | ||||
| 				<entries> | ||||
| 			}; | ||||
|  | ||||
| 			return lookup[ type ]; | ||||
| 		} | ||||
| 	))); | ||||
| #pragma pop_macro( "local_persist" ) | ||||
|  | ||||
| 	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) ) ); | ||||
|  | ||||
| 	return def_global_body( args( nspace, code_t ) ); | ||||
| } | ||||
|  | ||||
| CodeBody gen_eoperator( char const* path ) | ||||
| { | ||||
| 	char scratch_mem[kilobytes(1)]; | ||||
| 	Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) ); | ||||
|  | ||||
| 	file_read_contents( scratch, zero_terminate, path ); | ||||
|  | ||||
| 	CSV_Object csv_nodes; | ||||
| 	csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); | ||||
|  | ||||
| 	Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes; | ||||
| 	Array<ADT_Node> str_strs  = csv_nodes.nodes[1].nodes; | ||||
|  | ||||
| 	String enum_entries   = String::make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
| 	String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
|  | ||||
| 	for (uw idx = 0; idx < enum_strs.num(); idx++) | ||||
| 	{ | ||||
| 		char const* enum_str     = enum_strs[idx].string; | ||||
| 		char const* entry_to_str = str_strs [idx].string; | ||||
|  | ||||
| 		enum_entries.append_fmt( "%s,\n", enum_str ); | ||||
| 		to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||
| 	} | ||||
|  | ||||
| 	CodeEnum  enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize( | ||||
| 		enum Type : u32 | ||||
| 		{ | ||||
| 			<entries> | ||||
| 			NumOps | ||||
| 		}; | ||||
| 	))); | ||||
|  | ||||
| #pragma push_macro( "local_persist" ) | ||||
| #undef local_persist | ||||
| 	CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize( | ||||
| 		StrC to_str( Type op ) | ||||
| 		{ | ||||
| 			local_persist | ||||
| 			StrC lookup[] { | ||||
| 				<entries> | ||||
| 			}; | ||||
|  | ||||
| 			return lookup[ op ]; | ||||
| 		} | ||||
| 	))); | ||||
| #pragma pop_macro( "local_persist" ) | ||||
|  | ||||
| 	CodeNamespace nspace = def_namespace( name(EOperator), def_namespace_body( args( enum_code, to_str ) ) ); | ||||
|  | ||||
| 	CodeUsing operator_t = def_using( name(OperatorT), def_type( name(EOperator::Type) ) ); | ||||
|  | ||||
| 	return def_global_body( args( nspace, operator_t ) ); | ||||
| } | ||||
|  | ||||
| CodeBody gen_especifier( char const* path ) | ||||
| { | ||||
| 	char scratch_mem[kilobytes(1)]; | ||||
| 	Arena scratch = Arena::init_from_memory( scratch_mem, sizeof(scratch_mem) ); | ||||
|  | ||||
| 	file_read_contents( scratch, zero_terminate, path ); | ||||
|  | ||||
| 	CSV_Object csv_nodes; | ||||
| 	csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); | ||||
|  | ||||
| 	Array<ADT_Node> enum_strs = csv_nodes.nodes[0].nodes; | ||||
| 	Array<ADT_Node> str_strs  = csv_nodes.nodes[1].nodes; | ||||
|  | ||||
| 	String enum_entries   = String::make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
| 	String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) ); | ||||
|  | ||||
| 	for (uw idx = 0; idx < enum_strs.num(); idx++) | ||||
| 	{ | ||||
| 		char const* enum_str     = enum_strs[idx].string; | ||||
| 		char const* entry_to_str = str_strs [idx].string; | ||||
|  | ||||
| 		enum_entries.append_fmt( "%s,\n", enum_str ); | ||||
| 		to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str); | ||||
| 	} | ||||
|  | ||||
| 	CodeEnum  enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, stringize( | ||||
| 		enum Type : u32 | ||||
| 		{ | ||||
| 			<entries> | ||||
| 			NumSpecifiers | ||||
| 		}; | ||||
| 	))); | ||||
|  | ||||
| 	CodeFn is_trailing = parse_function(token_fmt("specifier", (StrC)to_str_entries, stringize( | ||||
| 		bool is_trailing( Type specifier ) | ||||
| 		{ | ||||
| 			return specifier > Virtual; | ||||
| 		} | ||||
| 	))); | ||||
|  | ||||
| #pragma push_macro( "local_persist" ) | ||||
| #pragma push_macro( "do_once_start" ) | ||||
| #pragma push_macro( "do_once_end" ) | ||||
| #undef local_persist | ||||
| #undef do_once_start | ||||
| #undef do_once_end | ||||
|  | ||||
| 	CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize( | ||||
| 		StrC to_str( Type type ) | ||||
| 		{ | ||||
| 			local_persist | ||||
| 			StrC lookup[] { | ||||
| 				<entries> | ||||
| 			}; | ||||
|  | ||||
| 			return lookup[ type ]; | ||||
| 		} | ||||
| 	))); | ||||
|  | ||||
| 	CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize( | ||||
| 		Type to_type( StrC str ) | ||||
| 		{ | ||||
| 			local_persist | ||||
| 			u32 keymap[ NumSpecifiers ]; | ||||
| 			do_once_start | ||||
| 				for ( u32 index = 0; index < NumSpecifiers; index++ ) | ||||
| 				{ | ||||
| 					StrC enum_str = to_str( (Type)index ); | ||||
|  | ||||
| 					// We subtract 1 to remove the null terminator | ||||
| 					// This is because the tokens lexed are not null terminated. | ||||
| 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1); | ||||
| 				} | ||||
| 			do_once_end | ||||
|  | ||||
| 			u32 hash = crc32( str.Ptr, str.Len ); | ||||
|  | ||||
| 			for ( u32 index = 0; index < NumSpecifiers; index++ ) | ||||
| 			{ | ||||
| 				if ( keymap[index] == hash ) | ||||
| 					return (Type)index; | ||||
| 			} | ||||
|  | ||||
| 			return Invalid; | ||||
| 		} | ||||
| 	))); | ||||
|  | ||||
| #pragma pop_macro( "local_persist" ) | ||||
| #pragma pop_macro( "do_once_start" ) | ||||
| #pragma pop_macro( "do_once_end" ) | ||||
|  | ||||
| 	CodeNamespace nspace = def_namespace( name(ESpecifier), def_namespace_body( args( enum_code, is_trailing, to_str, to_type ) ) ); | ||||
|  | ||||
| 	CodeUsing specifier_t = def_using( name(SpecifierT), def_type( name(ESpecifier::Type) ) ); | ||||
|  | ||||
| 	return def_global_body( args( nspace, specifier_t ) ); | ||||
| } | ||||
|  | ||||
| CodeBody gen_etoktype() | ||||
| { | ||||
| 	return CodeInvalid; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user