mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 22:40:54 -07:00 
			
		
		
		
	Finished fleshing out incrementals, started to flesh out parsing
This commit is contained in:
		| @@ -63,15 +63,18 @@ using zpl::arena_init_from_memory; | ||||
| using zpl::arena_free; | ||||
| using zpl::bprintf; | ||||
| using zpl::char_is_alpha; | ||||
| using zpl::char_is_alphanumeric; | ||||
| using zpl::char_is_space; | ||||
| using zpl::crc32; | ||||
| using zpl::free_all; | ||||
| using zpl::memcopy; | ||||
| using zpl::memset; | ||||
| using zpl::pool_allocator; | ||||
| using zpl::pool_init; | ||||
| using zpl::pool_free; | ||||
| using zpl::printf_va; | ||||
| using zpl::printf_err_va; | ||||
| using zpl::str_compare; | ||||
| using zpl::snprintf_va; | ||||
| using zpl::string_appendc; | ||||
| using zpl::string_append_fmt; | ||||
|   | ||||
							
								
								
									
										526
									
								
								project/gen.cpp
									
									
									
									
									
								
							
							
						
						
									
										526
									
								
								project/gen.cpp
									
									
									
									
									
								
							| @@ -769,7 +769,7 @@ namespace gen | ||||
| 	}; | ||||
|  | ||||
| 	inline | ||||
| 	OpValidateResult operator_validate( OperatorT op, Code params_code, Code ret_type, Code specifier ) | ||||
| 	OpValidateResult operator__validate( OperatorT op, Code params_code, Code ret_type, Code specifier ) | ||||
| 	{ | ||||
| 		using namespace EOperator; | ||||
|  | ||||
| @@ -1119,25 +1119,25 @@ namespace gen | ||||
|  | ||||
| #	pragma region Helper Functions | ||||
| 	// This snippet is used in nearly all the functions. | ||||
| #	define name_check( Context_, Length_, Name_ )                                               \ | ||||
| 	{                                                                                           \ | ||||
| 		if ( Length_ <= 0 )                                                                     \ | ||||
| 		{                                                                                       \ | ||||
| 			log_failure( "gen::%s: Invalid name length provided - %d", txt(Context_), length ); \ | ||||
| 			return Code::Invalid;                                                               \ | ||||
| 		}                                                                                       \ | ||||
|                                                                                                 \ | ||||
| 		if ( Name_ == nullptr )                                                                 \ | ||||
| 		{                                                                                       \ | ||||
| 			log_failure( "gen::%s: name is null", txt(Context_) );                              \ | ||||
| 			return Code::Invalid;                                                               \ | ||||
| 		}                                                                                       \ | ||||
| #	define name_check( Context_, Length_, Name_ )                                                \ | ||||
| 	{                                                                                            \ | ||||
| 		if ( Length_ <= 0 )                                                                      \ | ||||
| 		{                                                                                        \ | ||||
| 			log_failure( "gen::" txt(Context_) ": Invalid name length provided - %d",  length ); \ | ||||
| 			return Code::Invalid;                                                                \ | ||||
| 		}                                                                                        \ | ||||
|                                                                                                  \ | ||||
| 		if ( Name_ == nullptr )                                                                  \ | ||||
| 		{                                                                                        \ | ||||
| 			log_failure( "gen::" txt(Context_) ": name is null" );                               \ | ||||
| 			return Code::Invalid;                                                                \ | ||||
| 		}                                                                                        \ | ||||
| 	} | ||||
|  | ||||
| #	define null_check( Context_, Code_ )                                          \ | ||||
| 	if ( ! Code_ )                                                                \ | ||||
| 	{                                                                             \ | ||||
| 		log_failure( "gen::%s: %s provided is null", txt(Context_), txt(Code_) ); \ | ||||
| 		log_failure( "gen::" txt(Context_) ": " txt(Code_) " provided is null" ); \ | ||||
| 		return Code::Invalid;                                                     \ | ||||
| 	} | ||||
|  | ||||
| @@ -1145,13 +1145,13 @@ namespace gen | ||||
| 	{                                                                                   \ | ||||
| 		if ( ! Code_ )                                                                  \ | ||||
| 		{                                                                               \ | ||||
| 			log_failure( "gen::%s: %s provided is null", txt(Context_) );               \ | ||||
| 			log_failure( "gen::" txt(Context_) ": " txt(Code_) " provided is null" );   \ | ||||
| 			return Code::Invalid;                                                       \ | ||||
| 		}                                                                               \ | ||||
|                                                                                         \ | ||||
| 		if ( Code_->is_invalid() )                                                      \ | ||||
| 		{                                                                               \ | ||||
| 			log_failure("gen::%s: %s provided is invalid", txt(Context_), txt(Code_) ); \ | ||||
| 			log_failure("gen::" txt(Context_) ": " txt(Code_) " provided is invalid" ); \ | ||||
| 			return Code::Invalid;                                                       \ | ||||
| 		}                                                                               \ | ||||
| 	} | ||||
| @@ -1435,7 +1435,7 @@ namespace gen | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
|  | ||||
| 		OpValidateResult check_result = operator_validate( op, params_code, ret_type, specifiers ); | ||||
| 		OpValidateResult check_result = operator__validate( op, params_code, ret_type, specifiers ); | ||||
|  | ||||
| 		if ( check_result == OpValidateResult::Fail ) | ||||
| 		{ | ||||
| @@ -2386,7 +2386,7 @@ namespace gen | ||||
| 	{ | ||||
| 		using namespace ECode; | ||||
|  | ||||
| 		OpValidateResult check_result = operator_validate( op, params_code, ret_type, specifiers ); | ||||
| 		OpValidateResult check_result = operator__validate( op, params_code, ret_type, specifiers ); | ||||
|  | ||||
| 		if ( check_result == OpValidateResult::Fail ) | ||||
| 		{ | ||||
| @@ -2468,6 +2468,73 @@ namespace gen | ||||
| #	pragma endregion Incremetnal Constructions | ||||
|  | ||||
| #	pragma region Parsing Constructors | ||||
| #	pragma region Helper Macros | ||||
| #	define check_parse_args( func, length, def )                         \ | ||||
| 	if ( length <= 0 )                                                   \ | ||||
| 	{                                                                    \ | ||||
| 		log_failure( "gen::" txt(func) ": length must greater than 0" ); \ | ||||
| 		return Code::Invalid;                                            \ | ||||
| 	}                                                                    \ | ||||
| 	if ( def == nullptr )                                                \ | ||||
| 	{                                                                    \ | ||||
| 		log_failure( "gen::" txt(func) ": def was null" );               \ | ||||
| 		return Code::Invalid;                                            \ | ||||
| 	} | ||||
|  | ||||
| /* | ||||
| 	These macros are used to make the parsing code more readable. | ||||
|  | ||||
| 	They expect the following variables to be defined withing the scope of parsing constructor: | ||||
| 		SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; | ||||
| 		s32        num_specifiers = 0; | ||||
|  | ||||
| 		char const* name        = nullptr; | ||||
| 		s32         name_length = 0; | ||||
|  | ||||
| 		s32 	    left    = length; | ||||
| 		char const* scanner = def; | ||||
|  | ||||
| 		Code array_expr = Code::Invalid; | ||||
| 		Code type       = Code::Invalid; | ||||
|  | ||||
| 		char const* word        = scanner; | ||||
| 		s32         word_length = 0; | ||||
| */ | ||||
|  | ||||
| #	define current ( * scanner ) | ||||
|  | ||||
| #	define move_forward() \ | ||||
| 	left--;               \ | ||||
| 	scanner++ | ||||
|  | ||||
| #	define SkipWhitespace() \ | ||||
| 	while ( left && char_is_space( current ) ) \ | ||||
| 	{                                          \ | ||||
| 		move_forward();                        \ | ||||
| 	} | ||||
|  | ||||
| #	define GetWord()                                                    \ | ||||
| 	while ( left && char_is_alphanumeric( current ) || current == '_' ) \ | ||||
| 	{                                                                   \ | ||||
| 		move_forward();                                                 \ | ||||
| 		word_length++;                                                  \ | ||||
| 	} | ||||
|  | ||||
| #	define CheckForSpecifiers()                                                     \ | ||||
| 	GetWord();                                                                      \ | ||||
| 	for ( s32 index = 0; index < ESpecifier::Num_Specifiers; index++ )              \ | ||||
| 	{                                                                               \ | ||||
| 		char const* specifier_str = ESpecifier::to_str( scast(SpecifierT, index) ); \ | ||||
| 																					\ | ||||
| 		if ( str_compare( word, specifier_str, word_length ) == 0 )                 \ | ||||
| 		{                                                                           \ | ||||
| 			specs_found[num_specifiers] = (SpecifierT) index;                       \ | ||||
| 			num_specifiers++;                                                       \ | ||||
| 			continue;                                                               \ | ||||
| 		}                                                                           \ | ||||
| 	} | ||||
| #	pragma endregion Helper Macros | ||||
|  | ||||
| 	Code parse_class( s32 length, char const* def ) | ||||
| 	{ | ||||
| 		not_implemented( parse_class ); | ||||
| @@ -2475,7 +2542,148 @@ namespace gen | ||||
|  | ||||
| 	Code parse_enum( s32 length, char const* def ) | ||||
| 	{ | ||||
| 		not_implemented( parse_enum ); | ||||
| 		check_parse_args( parse_enum, length, def ); | ||||
|  | ||||
| 		// Just in case someone gets a vulkan-level enum in here... | ||||
| 		char  entries_code[ kilobytes(128) ] { 0 }; | ||||
| 		s32   entries_length = 0; | ||||
|  | ||||
| 		char const* name        = nullptr; | ||||
| 		s32         name_length = 0; | ||||
|  | ||||
| 		s32 	    left    = length; | ||||
| 		char const* scanner = def; | ||||
|  | ||||
| 		char const* word        = scanner; | ||||
| 		s32         word_length = 0; | ||||
|  | ||||
| 		Code type = { nullptr }; | ||||
|  | ||||
| 		bool is_enum_class = false; | ||||
|  | ||||
| 		SkipWhitespace(); | ||||
| 		if ( left <= 0 ) | ||||
| 		{ | ||||
| 			log_failure( "gen::parse_enum: enum definition was empty" ); | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
|  | ||||
| 		GetWord(); | ||||
| 		if ( word_length != 4 || str_compare( word, "enum", word_length ) != 0 ) | ||||
| 		{ | ||||
| 			log_failure( "gen::parse_enum: enum definition did not start with `enum`" ); | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
|  | ||||
| 		SkipWhitespace(); | ||||
| 		if ( left <= 0 ) | ||||
| 		{ | ||||
| 			log_failure( "gen::parse_enum: enum definition did not have a name" ); | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
|  | ||||
| 		GetWord(); | ||||
| 		if ( word_length == 5 && str_compare( word, "class", word_length ) == 0 ) | ||||
| 		{ | ||||
| 			is_enum_class = true; | ||||
| 		} | ||||
|  | ||||
| 		SkipWhitespace(); | ||||
| 		if ( left <= 0 ) | ||||
| 		{ | ||||
| 			log_failure( "gen::parse_enum: enum definition did not have a name" ); | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
|  | ||||
| 		GetWord(); | ||||
| 		name        = word; | ||||
| 		name_length = word_length; | ||||
|  | ||||
| 		SkipWhitespace(); | ||||
|  | ||||
| 		if ( current == ':' ) | ||||
| 		{ | ||||
| 			move_forward(); | ||||
| 			SkipWhitespace(); | ||||
|  | ||||
| 			GetWord(); | ||||
| 			def_type( word_length, word, type ); | ||||
| 		} | ||||
|  | ||||
| 		SkipWhitespace(); | ||||
|  | ||||
| 		if ( current == ';' ) | ||||
| 		{ | ||||
| 			goto Finished; | ||||
| 		} | ||||
|  | ||||
| 		if ( current != '{' ) | ||||
| 		{ | ||||
| 			log_failure( "gen::parse_enum: enum definition did not have a body" ); | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
| 		move_forward(); | ||||
|  | ||||
| 		char const* body_start = scanner; | ||||
| 		do | ||||
| 		{ | ||||
| 			if ( current == '}' ) | ||||
| 			{ | ||||
| 				move_forward(); | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			SkipWhitespace(); | ||||
| 			if ( left <= 0 ) | ||||
| 			{ | ||||
| 				log_failure( "gen::parse_enum: enum definition did not have a body" ); | ||||
| 				return Code::Invalid; | ||||
| 			} | ||||
|  | ||||
| 			GetWord(); | ||||
| 			if ( word_length == 0 ) | ||||
| 			{ | ||||
| 				log_failure( "gen::parse_enum: enum definition did not have a body" ); | ||||
| 				return Code::Invalid; | ||||
| 			} | ||||
|  | ||||
| 			entries_length += word_length; | ||||
|  | ||||
| 			if ( entries_length	>= kilobytes(128) ) | ||||
| 			{ | ||||
| 				log_failure( "gen::parse_enum: enum definition had too many entries" ); | ||||
| 				return Code::Invalid; | ||||
| 			} | ||||
| 		} | ||||
| 		while(1); | ||||
|  | ||||
| 	Finished: | ||||
| 		using namespace ECode; | ||||
|  | ||||
| 		Code | ||||
| 		result = make_code(); | ||||
|  | ||||
| 		if ( entries_length ) | ||||
| 		{ | ||||
| 			memcopy( entries_code, body_start, entries_length ); | ||||
|  | ||||
| 			Code body = untyped_str( entries_length, entries_code ); | ||||
|  | ||||
| 			result->Type = is_enum_class ? Enum_Class : Enum; | ||||
| 			result->add_entry( body ); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			result->Type = is_enum_class ? Enum_Class_Fwd : Enum_Fwd; | ||||
| 		} | ||||
|  | ||||
| 		result->Name = get_cached_string( name, name_length ); | ||||
|  | ||||
| 		if ( type ) | ||||
| 			result->add_entry( type ); | ||||
|  | ||||
| 		result.lock(); | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	Code parse_execution( s32 length, char const* exec_def ) | ||||
| @@ -2495,11 +2703,7 @@ namespace gen | ||||
|  | ||||
| 	Code parse_function( s32 length, char const* def ) | ||||
| 	{ | ||||
| 		if ( def == nullptr ) | ||||
| 		{ | ||||
| 			log_failure("gen::parse_proc: def is null!"); | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
| 		check_parse_args( parse_function, length, def ); | ||||
|  | ||||
| 		Arena mem; | ||||
| 		do_once_start | ||||
| @@ -2523,9 +2727,6 @@ namespace gen | ||||
| 		static | ||||
| 		Param Params[ 64 ] { 0 }; | ||||
|  | ||||
| 		// Zero out params before a run of this func. | ||||
| 		memset( Params, 0, sizeof( Params )); | ||||
|  | ||||
| 		char const* name; | ||||
| 		s32         name_length = 0; | ||||
|  | ||||
| @@ -2540,15 +2741,6 @@ namespace gen | ||||
|  | ||||
| 		while ( left -- ) | ||||
| 		{ | ||||
| 			#define SkipWhitespace() \ | ||||
| 			while ( left && char_is_space( * scanner ) ) \ | ||||
| 			{                                            \ | ||||
| 				left--;                                  \ | ||||
| 				scanner++ ;                              \ | ||||
| 			} | ||||
|  | ||||
| 			#define Get | ||||
|  | ||||
| 			// Find all specifiers (if any) and the return type | ||||
| 			do | ||||
| 			{ | ||||
| @@ -2684,14 +2876,263 @@ namespace gen | ||||
| 		not_implemented( parse_variable ); | ||||
| 	} | ||||
|  | ||||
| 	Code parse_type( s32 length, char const* def ) | ||||
| 	inline | ||||
| 	bool parse__type_helper( char const* func_name | ||||
| 		, s32 length,        char const* def | ||||
| 		, s32 name_length,   char const* name | ||||
| 		, u8 num_specifiers, SpecifierT* specs_found | ||||
| 		, Code& array_expr) | ||||
| 	{ | ||||
| 		not_implemented( parse_type ); | ||||
| 		s32 	    left    = length; | ||||
| 		char const* scanner = def; | ||||
|  | ||||
| 		char const* word        = scanner; | ||||
| 		s32         word_length = 0; | ||||
|  | ||||
| 		// Find all left-hand specifiers and the typename. | ||||
| 		do | ||||
| 		{ | ||||
| 			// Clearing any whitespace | ||||
| 			SkipWhitespace(); | ||||
|  | ||||
| 			if ( left <= 0 ) | ||||
| 			{ | ||||
| 				log_failure( "gen::%s: Error, reached end of string before finding typename", func_name ); | ||||
| 				return false; | ||||
| 			} | ||||
|  | ||||
| 			CheckForSpecifiers(); | ||||
| 			break; | ||||
| 		} | ||||
| 		while (1); | ||||
|  | ||||
| 		name        = scanner; | ||||
| 		name_length = word_length; | ||||
|  | ||||
| 		// Find all right-hand specifiers. | ||||
| 		do | ||||
| 		{ | ||||
| 			SkipWhitespace(); | ||||
|  | ||||
| 			if ( left <= 0 ) | ||||
| 				break; | ||||
|  | ||||
| 			if ( current == '*') | ||||
| 			{ | ||||
| 				specs_found[num_specifiers] = ESpecifier::Ptr; | ||||
| 				num_specifiers++; | ||||
| 				move_forward(); | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if ( current == '&') | ||||
| 			{ | ||||
| 				move_forward(); | ||||
|  | ||||
| 				if ( current == '&') | ||||
| 				{ | ||||
| 					specs_found[num_specifiers] = ESpecifier::RValue; | ||||
| 					num_specifiers++; | ||||
| 					move_forward(); | ||||
| 					continue; | ||||
| 				} | ||||
|  | ||||
| 				specs_found[num_specifiers] = ESpecifier::Ref; | ||||
| 				num_specifiers++; | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			if ( current == '[') | ||||
| 			{ | ||||
| 				move_forward(); | ||||
|  | ||||
| 				SkipWhitespace(); | ||||
|  | ||||
| 				if ( left <= 0 ) | ||||
| 				{ | ||||
| 					log_failure( "gen::%s: Error, reached end of string before finding array expression", func_name ); | ||||
| 					return false; | ||||
| 				} | ||||
|  | ||||
| 				word        = scanner; | ||||
| 				word_length = 0; | ||||
| 				GetWord(); | ||||
|  | ||||
| 				array_expr = untyped_str( word_length, word ); | ||||
|  | ||||
| 				if ( left <= 0 ) | ||||
| 				{ | ||||
| 					log_failure( "gen::%s: Error, reached end of string before finding ']' for array expression", func_name ); | ||||
| 					return false; | ||||
| 				} | ||||
|  | ||||
| 				if ( current == ']') | ||||
| 				{ | ||||
| 					move_forward(); | ||||
| 				} | ||||
|  | ||||
| 				num_specifiers++; | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			word        = scanner; | ||||
| 			word_length = 0; | ||||
|  | ||||
| 			CheckForSpecifiers(); | ||||
| 			break; | ||||
| 		} | ||||
| 		while (1); | ||||
| 	} | ||||
|  | ||||
| 	Code parse_typdef( s32 length, char const* def ) | ||||
| 	Code parse_type( s32 length, char const* def ) | ||||
| 	{ | ||||
| 		not_implemented( parse_typedef ); | ||||
| 		check_parse_args( parse_type, length, def ); | ||||
|  | ||||
| 		SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; | ||||
| 		u8         num_specifiers = 0; | ||||
|  | ||||
| 		char const* name        = nullptr; | ||||
| 		s32         name_length = 0; | ||||
|  | ||||
| 		Code array_expr = { nullptr }; | ||||
|  | ||||
| 		bool helper_result = parse__type_helper( txt(parse_type) | ||||
| 			, length,         def | ||||
| 			, name_length,    name | ||||
| 			, num_specifiers, specs_found | ||||
| 			, array_expr | ||||
| 		); | ||||
|  | ||||
| 		if ( ! helper_result ) | ||||
| 			return Code::Invalid; | ||||
|  | ||||
| 		using namespace ECode; | ||||
|  | ||||
| 		Code | ||||
| 		result       = make_code(); | ||||
| 		result->Type = Typename; | ||||
| 		result->Name = get_cached_string( name, name_length ); | ||||
|  | ||||
| 		Code specifiers = def_specifiers( num_specifiers, specs_found ); | ||||
|  | ||||
| 		result->add_entry( specifiers ); | ||||
|  | ||||
| 		if ( array_expr ) | ||||
| 			result->add_entry( array_expr ); | ||||
|  | ||||
| 		result.lock(); | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	Code parse_typedef( s32 length, char const* def ) | ||||
| 	{ | ||||
| 		check_parse_args( parse_typedef, length, def ); | ||||
|  | ||||
| 		using namespace ECode; | ||||
|  | ||||
| 		SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; | ||||
| 		s32        num_specifiers = 0; | ||||
|  | ||||
| 		char const* name        = nullptr; | ||||
| 		s32         name_length = 0; | ||||
|  | ||||
| 		s32 	    left    = length; | ||||
| 		char const* scanner = def; | ||||
|  | ||||
| 		Code array_expr = { nullptr }; | ||||
| 		Code type       = { nullptr }; | ||||
|  | ||||
| 		char const* word        = scanner; | ||||
| 		s32         word_length = 0; | ||||
|  | ||||
| 		do | ||||
| 		{ | ||||
| 			SkipWhitespace(); | ||||
|  | ||||
| 			if ( left <= 0 ) | ||||
| 			{ | ||||
| 				log_failure( "gen::parse_typedef: Error, reached end of string before finding typename" ); | ||||
| 				return Code::Invalid; | ||||
| 			} | ||||
|  | ||||
| 			GetWord(); | ||||
| 			if ( str_compare( word, "typedef", word_length ) != 0 ) | ||||
| 			{ | ||||
| 				log_failure( "gen::parse_typedef: Error, expected 'typedef' but found '%.*s'", word_length, word ); | ||||
| 				return Code::Invalid; | ||||
| 			} | ||||
|  | ||||
| 			// Determining the typename inline | ||||
|  | ||||
| 			bool helper_result = parse__type_helper( txt(parse_typedef) | ||||
| 				, left,           scanner | ||||
| 				, name_length,    name | ||||
| 				, num_specifiers, specs_found | ||||
| 				, array_expr | ||||
| 			); | ||||
|  | ||||
| 			if ( ! helper_result ) | ||||
| 				return Code::Invalid; | ||||
|  | ||||
| 			type       = make_code(); | ||||
| 			type->Type = Typename; | ||||
| 			type->Name = get_cached_string( name, name_length ); | ||||
|  | ||||
| 			Code specifiers = def_specifiers( num_specifiers, specs_found ); | ||||
|  | ||||
| 			type->add_entry( specifiers ); | ||||
|  | ||||
| 			if ( array_expr ) | ||||
| 				type->add_entry( array_expr ); | ||||
|  | ||||
| 			type.lock(); | ||||
|  | ||||
| 			// End typename | ||||
|  | ||||
| 			SkipWhitespace(); | ||||
|  | ||||
| 			if ( left <= 0 ) | ||||
| 			{ | ||||
| 				log_failure( "gen::parse_typedef: Error, reached end of string before finding name" ); | ||||
| 				return Code::Invalid; | ||||
| 			} | ||||
| 			word        = scanner; | ||||
| 			word_length = 0; | ||||
| 			GetWord(); | ||||
|  | ||||
| 			name        = word; | ||||
| 			name_length = word_length; | ||||
|  | ||||
| 			SkipWhitespace(); | ||||
|  | ||||
| 			if ( left <= 0 ) | ||||
| 			{ | ||||
| 				log_failure( "gen::parse_typedef: Error, reached end of string before finding ';' for typedef" ); | ||||
| 				return Code::Invalid; | ||||
| 			} | ||||
|  | ||||
| 			if ( current == ';') | ||||
| 			{ | ||||
| 				move_forward(); | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			log_failure( "gen::parse_typedef: Error, expected ';' for typedef" ); | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
| 		while (1); | ||||
|  | ||||
| 		using namespace ECode; | ||||
|  | ||||
| 		Code | ||||
| 		result = make_code(); | ||||
| 		result->Type = Typedef; | ||||
| 		result->Name = get_cached_string( name, name_length ); | ||||
|  | ||||
| 		result->add_entry( type ); | ||||
|  | ||||
| 		result.lock(); | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	Code parse_using( s32 length, char const* def ) | ||||
| @@ -2742,9 +3183,6 @@ namespace gen | ||||
| 	s32 parse_typedefs( s32 length, char const* typedef_def, Code* out_typedef_codes ) | ||||
| 	{ | ||||
| 		not_implemented( parse_typedefs ); | ||||
|  | ||||
| 		Code | ||||
| 		result = make_code(); | ||||
| 	} | ||||
|  | ||||
| 	s32 parse_usings( s32 length, char const* usings_def, Code* out_using_codes ) | ||||
|   | ||||
| @@ -584,8 +584,9 @@ namespace gen | ||||
| #		define Define_Specifiers                     \ | ||||
| 		Entry( API_Import,       API_Export_Code )   \ | ||||
| 		Entry( API_Export,       API_Import_Code )   \ | ||||
| 		Entry( Attribute, "      You cannot stringize an attribute this way" ) \ | ||||
| 		Entry( Alignas,          alignas )           \ | ||||
| 		Entry( Attribute,        "You cannot stringize an attribute this way" )     \ | ||||
| 		Entry( Alignas,          alignas )                                          \ | ||||
| 		Entry( Array_Decl,       "You cannot stringize an array declare this way" ) \ | ||||
| 		Entry( Const,            const )             \ | ||||
| 		Entry( C_Linkage,        extern "C" )        \ | ||||
| 		Entry( Consteval,        consteval )         \ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user