mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 22:40:54 -07:00 
			
		
		
		
	Added extern linkage bodies to upfront constructors, more work on parsing constructors
- Made some more parsing helper functions - Got initial prototype of parse_friend done - getting ready to complete prototype of parse_function
This commit is contained in:
		
							
								
								
									
										537
									
								
								project/gen.cpp
									
									
									
									
									
								
							
							
						
						
									
										537
									
								
								project/gen.cpp
									
									
									
									
									
								
							| @@ -65,6 +65,7 @@ namespace gen | |||||||
| #	define AST_BODY_CLASS_UNALLOWED_TYPES \ | #	define AST_BODY_CLASS_UNALLOWED_TYPES \ | ||||||
| 	case Class_Body:                      \ | 	case Class_Body:                      \ | ||||||
| 	case Enum_Body:                       \ | 	case Enum_Body:                       \ | ||||||
|  | 	case Extern_Linkage:                  \ | ||||||
| 	case Friend:                          \ | 	case Friend:                          \ | ||||||
| 	case Function_Body:                   \ | 	case Function_Body:                   \ | ||||||
| 	case Function_Fwd:                    \ | 	case Function_Fwd:                    \ | ||||||
| @@ -84,6 +85,7 @@ namespace gen | |||||||
| 	case Access_Private:                     \ | 	case Access_Private:                     \ | ||||||
| 	case Class_Body:                         \ | 	case Class_Body:                         \ | ||||||
| 	case Enum_Body:                          \ | 	case Enum_Body:                          \ | ||||||
|  | 	case Extern_Linkage:                     \ | ||||||
| 	case Friend:                             \ | 	case Friend:                             \ | ||||||
| 	case Function_Body:                      \ | 	case Function_Body:                      \ | ||||||
| 	case Function_Fwd:                       \ | 	case Function_Fwd:                       \ | ||||||
| @@ -135,8 +137,27 @@ namespace gen | |||||||
| 	case Struct_Body: 						  \ | 	case Struct_Body: 						  \ | ||||||
| 	case Typename: | 	case Typename: | ||||||
|  |  | ||||||
|  | #	define AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES \ | ||||||
|  | 	case Access_Public: 					       \ | ||||||
|  | 	case Access_Protected: 					       \ | ||||||
|  | 	case Access_Private: 					       \ | ||||||
|  | 	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_STRUCT_UNALLOWED_TYPES \ | #	define AST_BODY_STRUCT_UNALLOWED_TYPES \ | ||||||
| 	case Enum_Body: 					   \ | 	case Enum_Body: 					   \ | ||||||
|  | 	case Extern_Linkage:                   \ | ||||||
| 	case Execution: 					   \ | 	case Execution: 					   \ | ||||||
| 	case Function_Body: 				   \ | 	case Function_Body: 				   \ | ||||||
| 	case Global_Body: 					   \ | 	case Global_Body: 					   \ | ||||||
| @@ -206,7 +227,7 @@ namespace gen | |||||||
| 				{ | 				{ | ||||||
| 					AST_BODY_CLASS_UNALLOWED_TYPES | 					AST_BODY_CLASS_UNALLOWED_TYPES | ||||||
| 					{ | 					{ | ||||||
| 						log_failure( "AST::add: Cannot add an AST to a class body." ); | 						log_failure( "AST::add: Cannot add %s to a class body.", other->type_str() ); | ||||||
| 						return false; | 						return false; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -223,6 +244,23 @@ namespace gen | |||||||
| 				log_failure( "AST::add: Cannot add an AST to an enum forward declaration." ); | 				log_failure( "AST::add: Cannot add an AST to an enum forward declaration." ); | ||||||
| 				return false; | 				return false; | ||||||
|  |  | ||||||
|  | 			case Extern_Linkage: | ||||||
|  | 				log_failure( "AST::add: Cannot add an AST to an extern linkage, only to its body." ); | ||||||
|  | 				return false; | ||||||
|  |  | ||||||
|  | 			case Extern_Linkage_Body: | ||||||
|  | 				switch ( other->Type ) | ||||||
|  | 				{ | ||||||
|  | 					AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | ||||||
|  | 					{ | ||||||
|  | 						log_failure( "AST::add: Cannot add %s to an extern linkage body.", other->type_str() ); | ||||||
|  | 						return false; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					default: | ||||||
|  | 						break; | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 			case Enum_Body: | 			case Enum_Body: | ||||||
| 				if ( other->Type != Untyped ) | 				if ( other->Type != Untyped ) | ||||||
| 				{ | 				{ | ||||||
| @@ -252,7 +290,7 @@ namespace gen | |||||||
| 				{ | 				{ | ||||||
| 					AST_BODY_FUNCTION_UNALLOWED_TYPES | 					AST_BODY_FUNCTION_UNALLOWED_TYPES | ||||||
| 					{ | 					{ | ||||||
| 						log_failure( "AST::add: Cannot add an AST to a function body." ); | 						log_failure( "AST::add: Cannot add %s to a function body.", other->type_str() ); | ||||||
| 						return false; | 						return false; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -270,7 +308,7 @@ namespace gen | |||||||
| 				{ | 				{ | ||||||
| 					AST_BODY_GLOBAL_UNALLOWED_TYPES | 					AST_BODY_GLOBAL_UNALLOWED_TYPES | ||||||
| 					{ | 					{ | ||||||
| 						log_failure( "AST::add: Cannot add an AST to a global body." ); | 						log_failure( "AST::add: Cannot add %s to a global body.", other->type_str() ); | ||||||
| 						return false; | 						return false; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -279,7 +317,6 @@ namespace gen | |||||||
| 				} | 				} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
|  |  | ||||||
| 			case Namespace: | 			case Namespace: | ||||||
| 				if ( Type != Global_Body ) | 				if ( Type != Global_Body ) | ||||||
| 				{ | 				{ | ||||||
| @@ -292,7 +329,7 @@ namespace gen | |||||||
| 				{ | 				{ | ||||||
| 					AST_BODY_NAMESPACE_UNALLOWED_TYPES | 					AST_BODY_NAMESPACE_UNALLOWED_TYPES | ||||||
| 					{ | 					{ | ||||||
| 						log_failure( "AST::add: Cannot add an AST to a namespace body." ); | 						log_failure( "AST::add: Cannot add %s to a namespace body.", other->type_str() ); | ||||||
| 						return false; | 						return false; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -326,7 +363,7 @@ namespace gen | |||||||
| 				{ | 				{ | ||||||
| 					AST_BODY_STRUCT_UNALLOWED_TYPES | 					AST_BODY_STRUCT_UNALLOWED_TYPES | ||||||
| 					{ | 					{ | ||||||
| 						log_failure( "AST::add: Cannot add to a struct body." ); | 						log_failure( "AST::add: Cannot add %s to a struct body.", other->type_str() ); | ||||||
| 						return false; | 						return false; | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -384,10 +421,6 @@ namespace gen | |||||||
| 			case Access_Public: | 			case Access_Public: | ||||||
| 			case Access_Protected: | 			case Access_Protected: | ||||||
| 			case Access_Private: | 			case Access_Private: | ||||||
| 			case Class_Fwd: |  | ||||||
| 			case Enum_Fwd: |  | ||||||
| 			case Function_Fwd: |  | ||||||
| 			case Specifiers: |  | ||||||
| 				// Can just be the same, as its a cached string. | 				// Can just be the same, as its a cached string. | ||||||
| 				result->Content = Content; | 				result->Content = Content; | ||||||
| 				return result; | 				return result; | ||||||
| @@ -395,16 +428,28 @@ namespace gen | |||||||
| 			// The main purpose of this is to make sure entires in the AST are unique, | 			// The main purpose of this is to make sure entires in the AST are unique, | ||||||
| 			// So that we can assign the new parent without corrupting the existing AST. | 			// So that we can assign the new parent without corrupting the existing AST. | ||||||
| 			case Class: | 			case Class: | ||||||
|  | 			case Class_Fwd: | ||||||
| 			case Class_Body: | 			case Class_Body: | ||||||
| 			case Enum: | 			case Enum: | ||||||
|  | 			case Enum_Fwd: | ||||||
| 			case Enum_Body: | 			case Enum_Body: | ||||||
|  | 			case Enum_Class: | ||||||
|  | 			case Enum_Class_Fwd: | ||||||
|  | 			case Extern_Linkage: | ||||||
|  | 			case Extern_Linkage_Body: | ||||||
| 			case Friend: | 			case Friend: | ||||||
|  | 			case Function: | ||||||
|  | 			case Function_Fwd: | ||||||
|  | 			case Function_Body: | ||||||
| 			case Global_Body: | 			case Global_Body: | ||||||
| 			case Namespace: | 			case Namespace: | ||||||
| 			case Namespace_Body: | 			case Namespace_Body: | ||||||
|  | 			case Operator: | ||||||
|  | 			case Operator_Fwd: | ||||||
|  | 			case Operator_Member: | ||||||
|  | 			case Operator_Member_Fwd: | ||||||
| 			case Parameters: | 			case Parameters: | ||||||
| 			case Function: | 			case Specifiers: | ||||||
| 			case Function_Body: |  | ||||||
| 			case Struct: | 			case Struct: | ||||||
| 			case Struct_Fwd: | 			case Struct_Fwd: | ||||||
| 			case Struct_Body: | 			case Struct_Body: | ||||||
| @@ -412,6 +457,7 @@ namespace gen | |||||||
| 			case Typedef: | 			case Typedef: | ||||||
| 			case Typename: | 			case Typename: | ||||||
| 			case Using: | 			case Using: | ||||||
|  | 			case Using_Namespace: | ||||||
| 				s32 index = 0; | 				s32 index = 0; | ||||||
| 				s32 left  = num_entries(); | 				s32 left  = num_entries(); | ||||||
| 				while ( left -- ) | 				while ( left -- ) | ||||||
| @@ -532,6 +578,10 @@ namespace gen | |||||||
| 				result = string_append_fmt( result, "enum class %s : %s;\n", Name, underlying_type()->to_string() ); | 				result = string_append_fmt( result, "enum class %s : %s;\n", Name, underlying_type()->to_string() ); | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
|  | 			case Extern_Linkage: | ||||||
|  | 				result = string_append_fmt( result, "extern %s\n{\n%s\n};\n", Name, body()->to_string() ); | ||||||
|  | 			break; | ||||||
|  |  | ||||||
| 			case Friend: | 			case Friend: | ||||||
| 				result = string_append_fmt( result, "friend %s;\n", Entries[0]->to_string() ); | 				result = string_append_fmt( result, "friend %s;\n", Entries[0]->to_string() ); | ||||||
| 			break; | 			break; | ||||||
| @@ -773,6 +823,7 @@ namespace gen | |||||||
|  |  | ||||||
| 			case Class_Body: | 			case Class_Body: | ||||||
| 			case Enum_Body: | 			case Enum_Body: | ||||||
|  | 			case Extern_Linkage_Body: | ||||||
| 			case Function_Body: | 			case Function_Body: | ||||||
| 			case Global_Body: | 			case Global_Body: | ||||||
| 			case Namespace_Body: | 			case Namespace_Body: | ||||||
| @@ -1581,6 +1632,32 @@ namespace gen | |||||||
| 		result       = make_code(); | 		result       = make_code(); | ||||||
| 		result->Type = ECode::Execution; | 		result->Type = ECode::Execution; | ||||||
|  |  | ||||||
|  | 		result->add_entry( untyped_code ); | ||||||
|  |  | ||||||
|  | 		result.lock(); | ||||||
|  | 		return result; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Code def_extern_linkage( s32 length, char const* name, Code body ) | ||||||
|  | 	{ | ||||||
|  | 		using namespace ECode; | ||||||
|  |  | ||||||
|  | 		name_check( def_extern_linkage, length, name ); | ||||||
|  | 		null_check( def_extern_linkage, body ); | ||||||
|  |  | ||||||
|  | 		if ( body->Type != Extern_Linkage_Body || body->Type != Untyped ) | ||||||
|  | 		{ | ||||||
|  | 			log_failure("gen::def_extern_linkage: body is not of extern_linkage or untyped type %s", body->debug_str()); | ||||||
|  | 			return Code::Invalid; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Code | ||||||
|  | 		result = make_code(); | ||||||
|  | 		result->Type = Extern_Linkage; | ||||||
|  | 		result->Name = get_cached_string( name, length ); | ||||||
|  |  | ||||||
|  | 		result->add_entry( body ); | ||||||
|  |  | ||||||
| 		result.lock(); | 		result.lock(); | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
| @@ -1697,18 +1774,18 @@ namespace gen | |||||||
| 		name_check( def_namespace, length, name ); | 		name_check( def_namespace, length, name ); | ||||||
| 		null_check( def_namespace, body ); | 		null_check( def_namespace, body ); | ||||||
|  |  | ||||||
| 		Code |  | ||||||
| 		result          = make_code(); |  | ||||||
| 		result->Type    = Namespace; |  | ||||||
| 		result->Name    = get_cached_string( name, length ); |  | ||||||
| 		result->Entries = make_code_entries(); |  | ||||||
|  |  | ||||||
| 		if ( body->Type != Namespace_Body || body->Type != Untyped ) | 		if ( body->Type != Namespace_Body || body->Type != Untyped ) | ||||||
| 		{ | 		{ | ||||||
| 			log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body->debug_str()); | 			log_failure("gen::def_namespace: body is not of namespace or untyped type %s", body->debug_str()); | ||||||
| 			return Code::Invalid; | 			return Code::Invalid; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		Code | ||||||
|  | 		result          = make_code(); | ||||||
|  | 		result->Type    = Namespace; | ||||||
|  | 		result->Name    = get_cached_string( name, length ); | ||||||
|  | 		result->Entries = make_code_entries(); | ||||||
|  |  | ||||||
| 		result->add_entry( body ); | 		result->add_entry( body ); | ||||||
|  |  | ||||||
| 		result.lock(); | 		result.lock(); | ||||||
| @@ -1763,7 +1840,7 @@ namespace gen | |||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Code def_param( Code type, s32 length, char const* name ) | 	Code def_param( Code type, s32 length, char const* name, Code value ) | ||||||
| 	{ | 	{ | ||||||
| 		using namespace ECode; | 		using namespace ECode; | ||||||
|  |  | ||||||
| @@ -1776,6 +1853,12 @@ namespace gen | |||||||
| 			return Code::Invalid; | 			return Code::Invalid; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		if ( value && value->Type != Untyped ) | ||||||
|  | 		{ | ||||||
|  | 			log_failure( "gen::def_param: value is not untyped - %s", value->debug_str() ); | ||||||
|  | 			return Code::Invalid; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		Code | 		Code | ||||||
| 		result       = make_code(); | 		result       = make_code(); | ||||||
| 		result->Type = Parameters; | 		result->Type = Parameters; | ||||||
| @@ -1783,6 +1866,9 @@ namespace gen | |||||||
|  |  | ||||||
| 		result->add_entry( type ); | 		result->add_entry( type ); | ||||||
|  |  | ||||||
|  | 		if ( value ) | ||||||
|  | 			result->add_entry( value ); | ||||||
|  |  | ||||||
| 		result.lock(); | 		result.lock(); | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
| @@ -2141,6 +2227,41 @@ namespace gen | |||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	Code def_extern_linkage_body( s32 num, ... ) | ||||||
|  | 	{ | ||||||
|  | 		def_body_start( def_extern_linkage_body ); | ||||||
|  |  | ||||||
|  | 		Code | ||||||
|  | 		result       = make_code(); | ||||||
|  | 		result->Type = Extern_Linkage_Body; | ||||||
|  |  | ||||||
|  | 		va_list va; | ||||||
|  | 		va_start(va, num); | ||||||
|  | 		def_body_code_validation_start( def_extern_linkage_body, va_arg(va, Code) ); | ||||||
|  | 			AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | ||||||
|  | 		def_body_code_validation_end( def_extern_linkage_body ); | ||||||
|  | 		va_end(va); | ||||||
|  |  | ||||||
|  | 		result.lock(); | ||||||
|  | 		return result; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Code def_extern_linkage_body( s32 num, Code* codes ) | ||||||
|  | 	{ | ||||||
|  | 		def_body_code_array_start( def_extern_linkage_body ); | ||||||
|  |  | ||||||
|  | 		Code | ||||||
|  | 		result       = make_code(); | ||||||
|  | 		result->Type = Extern_Linkage_Body; | ||||||
|  |  | ||||||
|  | 		def_body_code_validation_start( def_extern_linkage_body, *codes; codes++ ); | ||||||
|  | 			AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES | ||||||
|  | 		def_body_code_validation_end( def_extern_linkage_body ); | ||||||
|  |  | ||||||
|  | 		result.lock(); | ||||||
|  | 		return result; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	Code def_function_body( s32 num, ... ) | 	Code def_function_body( s32 num, ... ) | ||||||
| 	{ | 	{ | ||||||
| 		def_body_start( def_function_body ); | 		def_body_start( def_function_body ); | ||||||
| @@ -2268,7 +2389,6 @@ namespace gen | |||||||
| 		char const* name        = va_arg(va, char const*); | 		char const* name        = va_arg(va, char const*); | ||||||
|  |  | ||||||
| 		result->Name = get_cached_string( name, name_length ); | 		result->Name = get_cached_string( name, name_length ); | ||||||
| 		result->Entries = make_code_entries(); |  | ||||||
|  |  | ||||||
| 		if ( type->Type != Typename ) | 		if ( type->Type != Typename ) | ||||||
| 		{ | 		{ | ||||||
| @@ -2531,15 +2651,19 @@ namespace gen | |||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Code make_global_body( s32 length, char const* name, s32 num, ... ) | 	Code make_global_body( s32 length, char const* name ) | ||||||
| 	{ | 	{ | ||||||
| 		name_check( make_global_body, length, name ); | 		name_check( make_global_body, length, name ); | ||||||
|  |  | ||||||
| 		Code | 		Code | ||||||
| 		result       = make_code(); | 		result       = make_code(); | ||||||
| 		result->Type = ECode::Global_Body; | 		result->Type = ECode::Global_Body; | ||||||
|  |  | ||||||
|  | 		if ( length > 0 ) | ||||||
| 			result->Name = get_cached_string( name, length ); | 			result->Name = get_cached_string( name, length ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -2744,6 +2868,11 @@ namespace gen | |||||||
| 			sptr        Length; | 			sptr        Length; | ||||||
| 			TokType     Type; | 			TokType     Type; | ||||||
| 			bool 	    IsAssign; | 			bool 	    IsAssign; | ||||||
|  |  | ||||||
|  | 			operator bool() | ||||||
|  | 			{ | ||||||
|  | 				return Text && Length && Type != TokType::Invalid; | ||||||
|  | 			} | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		TokType get_tok_type( char const* word, s32 length ) | 		TokType get_tok_type( char const* word, s32 length ) | ||||||
| @@ -3266,6 +3395,160 @@ namespace gen | |||||||
| #	define check( Type_ ) left && currtok.Type == Type_ | #	define check( Type_ ) left && currtok.Type == Type_ | ||||||
| #pragma endregion Helper Macros | #pragma endregion Helper Macros | ||||||
|  |  | ||||||
|  | 	Code parse_type( Parser::TokArray& toks, char const* func_name ); | ||||||
|  |  | ||||||
|  | 	inline | ||||||
|  | 	Code parse_array_decl( Parser::TokArray& toks, char const* func_name ) | ||||||
|  | 	{ | ||||||
|  | 		using namespace Parser; | ||||||
|  |  | ||||||
|  | 		if ( check( TokType::BraceSquare_Open ) ) | ||||||
|  | 		{ | ||||||
|  | 			eat( TokType::BraceSquare_Open ); | ||||||
|  |  | ||||||
|  | 			if ( left == 0 ) | ||||||
|  | 			{ | ||||||
|  | 				log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", txt(parse_typedef) ); | ||||||
|  | 				return Code::Invalid; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if ( currtok.Type == TokType::BraceSquare_Close ) | ||||||
|  | 			{ | ||||||
|  | 				log_failure( "%s: Error, empty array expression in typedef definition", txt(parse_typedef) ); | ||||||
|  | 				return Code::Invalid; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			Token untyped_tok = currtok; | ||||||
|  |  | ||||||
|  | 			while ( left && currtok.Type != TokType::BraceSquare_Close ) | ||||||
|  | 			{ | ||||||
|  | 				untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			Code array_expr = untyped_str( untyped_tok.Length, untyped_tok.Text ); | ||||||
|  |  | ||||||
|  | 			if ( left == 0 ) | ||||||
|  | 			{ | ||||||
|  | 				log_failure( "%s: Error, unexpected end of type definition, expected ]", txt(parse_typedef) ); | ||||||
|  | 				return Code::Invalid; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if ( currtok.Type != TokType::BraceSquare_Close ) | ||||||
|  | 			{ | ||||||
|  | 				log_failure( "%s: Error, expected ] in type definition, not %s", txt(parse_typedef), str_tok_type( currtok.Type ) ); | ||||||
|  | 				return Code::Invalid; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			eat( TokType::BraceSquare_Close ); | ||||||
|  | 			return array_expr; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return Code::Invalid; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	inline | ||||||
|  | 	Parser::Token parse_identifier( Parser::TokArray& toks, char const* func_name ) | ||||||
|  | 	{ | ||||||
|  | 		using namespace Parser; | ||||||
|  | 		Token name = currtok; | ||||||
|  |  | ||||||
|  | 		eat( TokType::Identifier ); | ||||||
|  |  | ||||||
|  | 		while ( left && currtok.Type == TokType::Access_StaticSymbol ) | ||||||
|  | 		{ | ||||||
|  | 			eat( TokType::Access_StaticSymbol ); | ||||||
|  |  | ||||||
|  | 			if ( left == 0 ) | ||||||
|  | 			{ | ||||||
|  | 				log_failure( "%s: Error, unexpected end of type definition, expected identifier", func_name ); | ||||||
|  | 				return { nullptr, 0, TokType::Invalid }; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if ( currtok.Type != TokType::Identifier ) | ||||||
|  | 			{ | ||||||
|  | 				log_failure( "%s: Error, expected identifier in type definition, not %s", func_name, str_tok_type( currtok.Type ) ); | ||||||
|  | 				return { nullptr, 0, TokType::Invalid }; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			name.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)name.Text; | ||||||
|  | 			eat( TokType::Identifier ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return name; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Code parse_params( Parser::TokArray& toks, char const* context ) | ||||||
|  | 	{ | ||||||
|  | 		using namespace Parser; | ||||||
|  | 		using namespace ECode; | ||||||
|  |  | ||||||
|  | 		eat( TokType::Capture_Start ); | ||||||
|  |  | ||||||
|  | 		if ( check(TokType::Capture_End) ) | ||||||
|  | 		{ | ||||||
|  | 			eat( TokType::Capture_End ); | ||||||
|  | 			return { nullptr }; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Code | ||||||
|  | 		result = make_code(); | ||||||
|  | 		result->Type = Parameters; | ||||||
|  |  | ||||||
|  | 		while ( left && currtok.Type != TokType::Capture_End) | ||||||
|  | 		{ | ||||||
|  | 			Code type  = { nullptr }; | ||||||
|  | 			Code value = { nullptr }; | ||||||
|  |  | ||||||
|  | 			type = parse_type( toks, context ); | ||||||
|  | 			if ( type == Code::Invalid ) | ||||||
|  | 				return Code::Invalid; | ||||||
|  |  | ||||||
|  | 			Token name = currtok; | ||||||
|  | 			eat( TokType::Identifier ); | ||||||
|  |  | ||||||
|  | 			if ( currtok.IsAssign ) | ||||||
|  | 			{ | ||||||
|  | 				eat( TokType::Operator ); | ||||||
|  |  | ||||||
|  | 				Token value_tok = currtok; | ||||||
|  |  | ||||||
|  | 				if ( currtok.Type == TokType::Statement_End ) | ||||||
|  | 				{ | ||||||
|  | 					log_failure( "gen::%s: Expected value after assignment operator", context ); | ||||||
|  | 					return Code::Invalid; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				while ( left && currtok.Type != TokType::Statement_End ) | ||||||
|  | 				{ | ||||||
|  | 					value_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)value_tok.Text; | ||||||
|  | 					eat( currtok.Type ); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				value = parse_type( toks, context ); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			Code | ||||||
|  | 			param = make_code(); | ||||||
|  | 			param->Type = Parameters; | ||||||
|  | 			param->Name = get_cached_string( name.Text, name.Length ); | ||||||
|  |  | ||||||
|  | 			param->add_entry( type ); | ||||||
|  |  | ||||||
|  | 			if ( value ) | ||||||
|  | 				param->add_entry( value ); | ||||||
|  |  | ||||||
|  | 			param.lock(); | ||||||
|  |  | ||||||
|  | 			result->add_entry( param ); | ||||||
|  | 			eat( TokType::Comma ); | ||||||
|  | 		} | ||||||
|  | 		eat( TokType::Capture_End ); | ||||||
|  |  | ||||||
|  | 		result.lock(); | ||||||
|  | 		return result; | ||||||
|  | 	#	undef context | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	Code parse_class( s32 length, char const* def ) | 	Code parse_class( s32 length, char const* def ) | ||||||
| 	{ | 	{ | ||||||
| 		using namespace Parser; | 		using namespace Parser; | ||||||
| @@ -3391,14 +3674,10 @@ namespace gen | |||||||
| 	#	undef context | 	#	undef context | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	Code parse_execution( s32 length, char const* exec_def ) |  | ||||||
| 	{ |  | ||||||
| 		not_implemented( parse_execution ); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	Code parse_friend( s32 length, char const* def ) | 	Code parse_friend( s32 length, char const* def ) | ||||||
| 	{ | 	{ | ||||||
| 		using namespace Parser; | 		using namespace Parser; | ||||||
|  | 		using namespace ECode; | ||||||
|  |  | ||||||
| #		define context parse_friend | #		define context parse_friend | ||||||
| 		check_parse_args( parse_friend, length, def ); | 		check_parse_args( parse_friend, length, def ); | ||||||
| @@ -3409,19 +3688,46 @@ namespace gen | |||||||
|  |  | ||||||
| 		eat( TokType::Decl_Friend ); | 		eat( TokType::Decl_Friend ); | ||||||
|  |  | ||||||
| 		// This can either be a simple type, or a function declaration. | 		Code function = { nullptr }; | ||||||
| 		// If its a function declaration, it will have a return type, followed by a name, followed by a parameter list. |  | ||||||
| 		// If its a simple type, it will have a type, followed by a name. |  | ||||||
|  |  | ||||||
|  | 		// Type declaration or return type | ||||||
|  | 		Code type = parse_type( toks, txt(parse_friend) ); | ||||||
|  | 		if ( type == Code::Invalid ) | ||||||
|  | 			return Code::Invalid; | ||||||
|  |  | ||||||
|  | 		// Funciton declaration | ||||||
|  | 		if ( currtok.Type == TokType::Identifier ) | ||||||
|  | 		{ | ||||||
|  | 			// Name | ||||||
|  | 			Token name = parse_identifier( toks, txt(parse_friend) ); | ||||||
|  |  | ||||||
|  | 			// Parameter list | ||||||
|  | 			Code params = parse_params( toks, txt(parse_friend) ); | ||||||
|  |  | ||||||
| 		using namespace ECode; | 			function       = make_code(); | ||||||
|  | 			function->Type = Function_Fwd; | ||||||
|  | 			function->Name = get_cached_string( name.Text, name.Length ); | ||||||
|  | 			function->add_entry( type ); | ||||||
|  |  | ||||||
| 		Code result = make_code(); | 			if ( params ) | ||||||
|  | 				function->add_entry( params ); | ||||||
|  |  | ||||||
|  | 			function.lock(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		eat( TokType::Statement_End ); | ||||||
|  |  | ||||||
|  | 		Code | ||||||
|  | 		result       = make_code(); | ||||||
|  | 		result->Type = Friend; | ||||||
|  |  | ||||||
|  | 		if ( function ) | ||||||
|  | 			result->add_entry( function ); | ||||||
|  |  | ||||||
|  | 		else | ||||||
|  | 			result->add_entry( type ); | ||||||
|  |  | ||||||
|  | 		result.lock(); | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -3441,48 +3747,12 @@ namespace gen | |||||||
| 			arena_init_from_allocator( & mem, heap(), kilobytes( 10 ) ); | 			arena_init_from_allocator( & mem, heap(), kilobytes( 10 ) ); | ||||||
| 		do_once_end | 		do_once_end | ||||||
|  |  | ||||||
| 		// Pretty sure its impossible to have more than this. |  | ||||||
| 		SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; |  | ||||||
|  |  | ||||||
| 		u8 num_specifiers; |  | ||||||
|  |  | ||||||
| 		// Making all significant tokens have a max length of 128 for this parser. |  | ||||||
| 		constexpr sw LengthID = 128; |  | ||||||
|  |  | ||||||
| 		struct Param |  | ||||||
| 		{ |  | ||||||
| 			char const Type[LengthID]; |  | ||||||
| 			char const Name[LengthID]; |  | ||||||
| 		}; |  | ||||||
|  |  | ||||||
| 		static |  | ||||||
| 		Param Params[ 64 ] { 0 }; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 		using namespace ECode; |  | ||||||
|  |  | ||||||
| 		Code specifiers = def_specifiers( num_specifiers, specs_found ); |  | ||||||
|  |  | ||||||
| 		Code params   = make_code(); |  | ||||||
| 		// Code ret_type = def_type( ret_length, ret_type_str ); |  | ||||||
| 		// Code body     = untyped_str( body_length, body_str ); |  | ||||||
|  |  | ||||||
| 		Code | 		Code | ||||||
| 		result = make_code(); | 		result = make_code(); | ||||||
| 		// result->Name = get_cached_string( name, name_length ); |  | ||||||
| 		result->Type = Function; |  | ||||||
|  |  | ||||||
| 		// result->add_entry( body ); |  | ||||||
|  |  | ||||||
| 		if ( specifiers ) |  | ||||||
| 			result->add_entry( specifiers ); |  | ||||||
|  |  | ||||||
| 		// result->add_entry( ret_type ); |  | ||||||
|  |  | ||||||
| 		if ( params ) |  | ||||||
| 			result->add_entry( params ); |  | ||||||
|  |  | ||||||
| 		result.lock(); | 		result.lock(); | ||||||
| 		return result; | 		return result; | ||||||
| @@ -3530,7 +3800,7 @@ namespace gen | |||||||
| 		if ( toks.Arr == nullptr ) | 		if ( toks.Arr == nullptr ) | ||||||
| 			return Code::Invalid; | 			return Code::Invalid; | ||||||
|  |  | ||||||
| 		Token* name = nullptr; | 		Token name = { nullptr, 0, TokType::Invalid }; | ||||||
|  |  | ||||||
| 		SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; | 		SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; | ||||||
| 		s32        num_specifiers = 0; | 		s32        num_specifiers = 0; | ||||||
| @@ -3613,7 +3883,7 @@ namespace gen | |||||||
| 			return Code::Invalid; | 			return Code::Invalid; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		name = & currtok; | 		name = currtok; | ||||||
| 		eat( TokType::Identifier ); | 		eat( TokType::Identifier ); | ||||||
|  |  | ||||||
| 		Code expr = { nullptr }; | 		Code expr = { nullptr }; | ||||||
| @@ -3639,46 +3909,7 @@ namespace gen | |||||||
| 			expr = untyped_str( expr_tok.Length, expr_tok.Text ); | 			expr = untyped_str( expr_tok.Length, expr_tok.Text ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( check( TokType::BraceSquare_Open ) ) | 		array_expr = parse_array_decl( toks, txt(parse_variable) ); | ||||||
| 		{ |  | ||||||
| 			eat( TokType::BraceSquare_Open ); |  | ||||||
|  |  | ||||||
| 			if ( left == 0 ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", txt(parse_typedef) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if ( currtok.Type == TokType::BraceSquare_Close ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, empty array expression in typedef definition", txt(parse_typedef) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			Token |  | ||||||
| 			untyped_tok = currtok; |  | ||||||
|  |  | ||||||
| 			while ( left && currtok.Type != TokType::BraceSquare_Close ) |  | ||||||
| 			{ |  | ||||||
| 				untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			array_expr = untyped_str( untyped_tok.Length, untyped_tok.Text ); |  | ||||||
|  |  | ||||||
| 			if ( left == 0 ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, unexpected end of type definition, expected ]", txt(parse_typedef) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if ( currtok.Type != TokType::BraceSquare_Close ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, expected ] in type definition, not %s", txt(parse_typedef), str_tok_type( currtok.Type ) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			eat( TokType::BraceSquare_Close ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		eat( TokType::Statement_End ); | 		eat( TokType::Statement_End ); | ||||||
|  |  | ||||||
| @@ -3686,7 +3917,7 @@ namespace gen | |||||||
|  |  | ||||||
| 		Code result  = make_code(); | 		Code result  = make_code(); | ||||||
| 		result->Type = Variable; | 		result->Type = Variable; | ||||||
| 		result->Name = get_cached_string( name->Text, name->Length ); | 		result->Name = get_cached_string( name.Text, name.Length ); | ||||||
|  |  | ||||||
| 		result->add_entry( type ); | 		result->add_entry( type ); | ||||||
|  |  | ||||||
| @@ -3747,8 +3978,9 @@ namespace gen | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			name = currtok; | 			name = parse_identifier( toks, func_name ); | ||||||
| 			eat( TokType::Identifier ); | 			if ( ! name ) | ||||||
|  | 				return Code::Invalid; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		while ( left && tok_is_specifier( currtok ) ) | 		while ( left && tok_is_specifier( currtok ) ) | ||||||
| @@ -3836,45 +4068,7 @@ namespace gen | |||||||
| 		name = currtok; | 		name = currtok; | ||||||
| 		eat( TokType::Identifier ); | 		eat( TokType::Identifier ); | ||||||
|  |  | ||||||
| 		if ( check( TokType::BraceSquare_Open ) ) | 		array_expr = parse_array_decl( toks, txt(parse_typedef) ); | ||||||
| 		{ |  | ||||||
| 			eat( TokType::BraceSquare_Open ); |  | ||||||
|  |  | ||||||
| 			if ( left == 0 ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", txt(parse_typedef) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if ( currtok.Type == TokType::BraceSquare_Close ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, empty array expression in typedef definition", txt(parse_typedef) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			Token untyped_tok = currtok; |  | ||||||
|  |  | ||||||
| 			while ( left && currtok.Type != TokType::BraceSquare_Close ) |  | ||||||
| 			{ |  | ||||||
| 				untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			array_expr = untyped_str( untyped_tok.Length, untyped_tok.Text ); |  | ||||||
|  |  | ||||||
| 			if ( left == 0 ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, unexpected end of type definition, expected ]", txt(parse_typedef) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if ( currtok.Type != TokType::BraceSquare_Close ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, expected ] in type definition, not %s", txt(parse_typedef), str_tok_type( currtok.Type ) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			eat( TokType::BraceSquare_Close ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		eat( TokType::Statement_End ); | 		eat( TokType::Statement_End ); | ||||||
|  |  | ||||||
| @@ -3932,46 +4126,7 @@ namespace gen | |||||||
| 			type = parse_type( toks, txt(parse_typedef) ); | 			type = parse_type( toks, txt(parse_typedef) ); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if ( ! is_namespace && check( TokType::BraceSquare_Open ) ) | 		array_expr = parse_array_decl( toks, txt(parse_typedef) ); | ||||||
| 		{ |  | ||||||
| 			eat( TokType::BraceSquare_Open ); |  | ||||||
|  |  | ||||||
| 			if ( left == 0 ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, unexpected end of typedef definition ( '[]' scope started )", txt(parse_typedef) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if ( currtok.Type == TokType::BraceSquare_Close ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, empty array expression in typedef definition", txt(parse_typedef) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			Token |  | ||||||
| 			untyped_tok = currtok; |  | ||||||
|  |  | ||||||
| 			while ( left && currtok.Type != TokType::BraceSquare_Close ) |  | ||||||
| 			{ |  | ||||||
| 				untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			array_expr = untyped_str( untyped_tok.Length, untyped_tok.Text ); |  | ||||||
|  |  | ||||||
| 			if ( left == 0 ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, unexpected end of type definition, expected ]", txt(parse_typedef) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if ( currtok.Type != TokType::BraceSquare_Close ) |  | ||||||
| 			{ |  | ||||||
| 				log_failure( "%s: Error, expected ] in type definition, not %s", txt(parse_typedef), str_tok_type( currtok.Type ) ); |  | ||||||
| 				return Code::Invalid; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			eat( TokType::BraceSquare_Close ); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		eat( TokType::Statement_End ); | 		eat( TokType::Statement_End ); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -51,6 +51,8 @@ namespace gen | |||||||
| 		Entry( Enum_Class )          \ | 		Entry( Enum_Class )          \ | ||||||
| 		Entry( Enum_Class_Fwd )      \ | 		Entry( Enum_Class_Fwd )      \ | ||||||
| 		Entry( Execution )           \ | 		Entry( Execution )           \ | ||||||
|  | 		Entry( Extern_Linkage )      \ | ||||||
|  | 		Entry( Extern_Linkage_Body ) \ | ||||||
| 		Entry( Friend )              \ | 		Entry( Friend )              \ | ||||||
| 		Entry( Function )            \ | 		Entry( Function )            \ | ||||||
| 		Entry( Function_Fwd )        \ | 		Entry( Function_Fwd )        \ | ||||||
| @@ -214,7 +216,6 @@ namespace gen | |||||||
| 		Entry( API_Export,       API_Import_Code )   \ | 		Entry( API_Export,       API_Import_Code )   \ | ||||||
| 		Entry( Alignas,          alignas )                                          \ | 		Entry( Alignas,          alignas )                                          \ | ||||||
| 		Entry( Array_Decl,       "You cannot stringize an array declare this way" ) \ | 		Entry( Array_Decl,       "You cannot stringize an array declare this way" ) \ | ||||||
| 		Entry( C_Linkage,        extern "C" )        \ |  | ||||||
| 		Entry( Const,            const )             \ | 		Entry( Const,            const )             \ | ||||||
| 		Entry( Consteval,        consteval )         \ | 		Entry( Consteval,        consteval )         \ | ||||||
| 		Entry( Constexpr,        constexpr )         \ | 		Entry( Constexpr,        constexpr )         \ | ||||||
| @@ -714,10 +715,11 @@ namespace gen | |||||||
|  |  | ||||||
| 	Code def_friend         ( Code symbol ); | 	Code def_friend         ( Code symbol ); | ||||||
| 	Code def_function       ( s32 length, char const* name, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode ); | 	Code def_function       ( s32 length, char const* name, Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode ); | ||||||
|  | 	Code def_extern_linkage ( s32 length, char const* name,                                                                         Code body ); | ||||||
| 	Code def_namespace      ( s32 length, char const* name,                                                                         Code body ); | 	Code def_namespace      ( s32 length, char const* name,                                                                         Code body ); | ||||||
| 	Code def_operator       (             OperatorT   op,   Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode ); | 	Code def_operator       (             OperatorT   op,   Code params = NoCode, Code ret_type = NoCode, Code specifiers = NoCode, Code body = NoCode ); | ||||||
|  |  | ||||||
| 	Code def_param          ( Code type, s32 length, char const* name ); | 	Code def_param          ( Code type, s32 length, char const* name, Code value = NoCode ); | ||||||
|  |  | ||||||
| 	Code def_specifier      ( SpecifierT specifier ); | 	Code def_specifier      ( SpecifierT specifier ); | ||||||
|  |  | ||||||
| @@ -729,8 +731,10 @@ namespace gen | |||||||
| 	Code def_variable       ( Code type, s32 length, char const* name, Code value = NoCode, Code specifiers = NoCode ); | 	Code def_variable       ( Code type, s32 length, char const* name, Code value = NoCode, Code specifiers = NoCode ); | ||||||
|  |  | ||||||
| 	Code def_class_body         ( s32 num, ... ); | 	Code def_class_body         ( s32 num, ... ); | ||||||
| 	Code def_enum_body      ( u32 num, ... ); | 	Code def_enum_body          ( s32 num, ... ); | ||||||
| 	Code def_enum_body      ( u32 num, Code* codes ); | 	Code def_enum_body          ( s32 num, Code* codes ); | ||||||
|  | 	Code def_extern_linkage_body( s32 num, ... ); | ||||||
|  | 	Code def_extern_linkage_body( s32 num, Code* codes ); | ||||||
| 	Code def_global_body        ( s32 num, ... ); | 	Code def_global_body        ( s32 num, ... ); | ||||||
| 	Code def_global_body        ( s32 num, Code* codes ); | 	Code def_global_body        ( s32 num, Code* codes ); | ||||||
| 	Code def_function_body      ( s32 num, ... ); | 	Code def_function_body      ( s32 num, ... ); | ||||||
| @@ -749,8 +753,9 @@ namespace gen | |||||||
| #	ifdef GEN_FEATURE_INCREMENTAL | #	ifdef GEN_FEATURE_INCREMENTAL | ||||||
| 	Code make_class         ( s32 length,     char const* name, Code parent = NoCode,                                Code specifiers = NoCode ); | 	Code make_class         ( s32 length,     char const* name, Code parent = NoCode,                                Code specifiers = NoCode ); | ||||||
| 	Code make_enum          ( s32 length,     char const* name, Code type   = NoCode, EnumT specifier = EnumRegular ); | 	Code make_enum          ( s32 length,     char const* name, Code type   = NoCode, EnumT specifier = EnumRegular ); | ||||||
|  | 	Code make_extern_linkage( s32 length,     char const* name ); | ||||||
| 	Code make_function      ( s32 length,     char const* name, Code params = NoCode, Code  ret_type  = NoCode,      Code specifiers = NoCode ); | 	Code make_function      ( s32 length,     char const* name, Code params = NoCode, Code  ret_type  = NoCode,      Code specifiers = NoCode ); | ||||||
| 	Code make_global_body ( s32 length = 1, char const* name = "", s32 num = 0, ... ); | 	Code make_global_body   ( s32 length = 1, char const* name = "" ); | ||||||
| 	Code make_namespace     ( s32 length,     char const* name ); | 	Code make_namespace     ( s32 length,     char const* name ); | ||||||
| 	Code make_operator      (                 OperatorT   op,   Code params = NoCode, Code  ret_type  = NoCode,      Code specifiers = NoCode ); | 	Code make_operator      (                 OperatorT   op,   Code params = NoCode, Code  ret_type  = NoCode,      Code specifiers = NoCode ); | ||||||
| 	Code make_params        (); | 	Code make_params        (); | ||||||
| @@ -763,7 +768,6 @@ namespace gen | |||||||
| 	#ifdef GEN_FEATURE_PARSING | 	#ifdef GEN_FEATURE_PARSING | ||||||
| 	Code parse_class      ( s32 length, char const* class_def     ); | 	Code parse_class      ( s32 length, char const* class_def     ); | ||||||
| 	Code parse_enum       ( s32 length, char const* enum_def      ); | 	Code parse_enum       ( s32 length, char const* enum_def      ); | ||||||
| 	Code parse_execution  ( s32 length, char const* exec_def      ); |  | ||||||
| 	Code parse_friend     ( s32 length, char const* friend_def    ); | 	Code parse_friend     ( s32 length, char const* friend_def    ); | ||||||
| 	Code parse_function   ( s32 length, char const* fn_def        ); | 	Code parse_function   ( s32 length, char const* fn_def        ); | ||||||
| 	Code parse_global_body( s32 length, char const* body_def      ); | 	Code parse_global_body( s32 length, char const* body_def      ); | ||||||
| @@ -1010,6 +1014,7 @@ namespace gen | |||||||
| #	define class( Name_, ... )            gen::def_class( txt_n_len(Name_), __VA_ARGS__ ) | #	define class( Name_, ... )            gen::def_class( txt_n_len(Name_), __VA_ARGS__ ) | ||||||
| #	define enum( Name_, Type_, Body_ )    gen::def_enum ( txt_n_len(Name_), type_ns(Type_), Body_ ) | #	define enum( Name_, Type_, Body_ )    gen::def_enum ( txt_n_len(Name_), type_ns(Type_), Body_ ) | ||||||
|  |  | ||||||
|  | #	define extern_linkage( Name_, Body_ ) gen::def_extern_linkage( txt_n_len(Name_), Body_ ) | ||||||
| #	define function( ... )                macrofn_polymorphic( function, __VA_ARGS__ ) | #	define function( ... )                macrofn_polymorphic( function, __VA_ARGS__ ) | ||||||
| #	define namespace( Name_, Body_ )      gen::def_namespace      ( txt_n_len(Name_),  Body_ ) | #	define namespace( Name_, Body_ )      gen::def_namespace      ( txt_n_len(Name_),  Body_ ) | ||||||
| #	define operator( Op_, ... )           macrofn_polymorphic( operator, __VA_ARGS__ ) | #	define operator( Op_, ... )           macrofn_polymorphic( operator, __VA_ARGS__ ) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user