mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 06:20:52 -07:00 
			
		
		
		
	Support for interfaces in class/struct.
Interfaces are assumed to have the public access specifier for their content (if its a class definition) Started to prepare to segement library code into more files (Less scrolling, need for bootstrapping a tailored version + single header support anyway).
This commit is contained in:
		| @@ -3,16 +3,20 @@ | ||||
| The core library is contained within `gen.hpp` and `gen.cpp`. | ||||
| Things related to the editor and scanner are in their own respective files. (Ex: `gen.scanner.<hpp/cpp>` ) | ||||
|  | ||||
| Dependencies are within `gen.dep.<hpp/cpp>` | ||||
|  | ||||
|  | ||||
| ## gen.hpp | ||||
|  | ||||
| Feature Macros: | ||||
|  | ||||
| * `GEN_DONT_USE_NAMESPACE` : By default, the library is wrapped in a `gen` namespace, this will disable that expose it to the global scope. | ||||
| * `GEN_DONT_ENFORCE_GEN_TIME_GUARD` : By default, the library ( gen.hpp/ gen.cpp ) expects the macro `GEN_TIME` to be defined, this disables that. | ||||
| * `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves. | ||||
| * `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage | ||||
| * `GEN_ENFORCE_STRONG_CODE_TYPES` : Enforces casts to filtered code types. | ||||
| * `GEN_EXPOSE_BACKEND` : Will expose symbols meant for internal use only. | ||||
| * `GEN_Define_Attribute_Tokens` : Allows user to define their own attribute macros for use in parsing. | ||||
|  | ||||
| `GEN_USE_RECURSIVE_AST_DUPLICATION` is available but its not well tested and should not need to be used.   | ||||
| If constructing ASTs properly. There should be no modification of ASTs, and thus this would never become an issue.   | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| // This file is intended to be included within gen.hpp (There is pragma diagnostic ignores)
 | ||||
| // This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)
 | ||||
| #pragma once | ||||
| 
 | ||||
| #pragma region Platform Detection | ||||
| @@ -4,12 +4,12 @@ | ||||
| #error Gen.hpp : GEN_TIME not defined | ||||
| #endif | ||||
|  | ||||
| #include "gen.push_ignores.inline.hpp" | ||||
| #include "helpers/gen.push_ignores.inline.hpp" | ||||
|  | ||||
| //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. | ||||
| //! Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl | ||||
| #ifndef GEN_ROLL_OWN_DEPENDENCIES | ||||
| #	include "gen.dep.cpp" | ||||
| #	include "dependencies/gen.dep.cpp" | ||||
| #endif | ||||
|  | ||||
| #include "gen.hpp" | ||||
| @@ -478,6 +478,17 @@ String AST::to_string() | ||||
| 						, ParentType->to_string() | ||||
| 						, Body->to_string() | ||||
| 					); | ||||
|  | ||||
| 					CodeType interface = Next->cast<CodeType>(); | ||||
| 					if ( interface ) | ||||
| 						result.append("\n"); | ||||
|  | ||||
| 					while ( interface ) | ||||
| 					{ | ||||
| 						result.append_fmt( ", %s", interface.to_string() ); | ||||
|  | ||||
| 						interface = interface->Next->cast<CodeType>(); | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| @@ -902,6 +913,17 @@ String AST::to_string() | ||||
| 						, ParentType->to_string() | ||||
| 						, Body->to_string() | ||||
| 					); | ||||
|  | ||||
| 					CodeType interface = Next->cast<CodeType>(); | ||||
| 					if ( interface ) | ||||
| 						result.append("\n"); | ||||
|  | ||||
| 					while ( interface ) | ||||
| 					{ | ||||
| 						result.append_fmt( ", public %s", interface.to_string() ); | ||||
|  | ||||
| 						interface = interface->Next->cast<CodeType>(); | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| @@ -1182,7 +1204,8 @@ bool AST::validate_body() | ||||
| #pragma endregion AST | ||||
|  | ||||
| #pragma region Gen Interface | ||||
| internal void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ) | ||||
| internal | ||||
| void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ) | ||||
| { | ||||
| 	Arena* last = & Global_AllocatorBuckets.back(); | ||||
|  | ||||
| @@ -1244,7 +1267,8 @@ internal void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw s | ||||
| 	return nullptr; | ||||
| } | ||||
|  | ||||
| internal void define_constants() | ||||
| internal | ||||
| void define_constants() | ||||
| { | ||||
| 	Code::Global          = make_code(); | ||||
| 	Code::Global->Name    = get_cached_string( txt_StrC("Global Code") ); | ||||
| @@ -2032,7 +2056,8 @@ CodeClass def_class( StrC name | ||||
| 	, Code           body | ||||
| 	, CodeType       parent, AccessSpec parent_access | ||||
| 	, CodeAttributes attributes | ||||
| 	, ModuleFlag     mflags ) | ||||
| 	, ModuleFlag     mflags | ||||
| 	, CodeType*      interfaces, s32 num_interfaces	) | ||||
| { | ||||
| 	using namespace ECode; | ||||
|  | ||||
| @@ -2085,6 +2110,14 @@ CodeClass def_class( StrC name | ||||
| 		result->ParentType   = parent; | ||||
| 	} | ||||
|  | ||||
| 	if ( interfaces ) | ||||
| 	{ | ||||
| 		for (s32 idx = 0; idx < num_interfaces; idx++ ) | ||||
| 		{ | ||||
| 			result.add_interface( interfaces[idx] ); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -2523,7 +2556,8 @@ CodeStruct def_struct( StrC name | ||||
| 	, Code           body | ||||
| 	, CodeType       parent, AccessSpec parent_access | ||||
| 	, CodeAttributes attributes | ||||
| 	, ModuleFlag     mflags ) | ||||
| 	, ModuleFlag     mflags | ||||
| 	, CodeType*      interfaces, s32 num_interfaces ) | ||||
| { | ||||
| 	using namespace ECode; | ||||
|  | ||||
| @@ -2571,6 +2605,14 @@ CodeStruct def_struct( StrC name | ||||
| 		result->ParentType   = parent; | ||||
| 	} | ||||
|  | ||||
| 	if ( interfaces ) | ||||
| 	{ | ||||
| 		for (s32 idx = 0; idx < num_interfaces; idx++ ) | ||||
| 		{ | ||||
| 			result.add_interface( interfaces[idx] ); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -5162,6 +5204,7 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con | ||||
|  | ||||
| 	Token name { nullptr, 0, TokType::Invalid }; | ||||
|  | ||||
| 	AccessSpec     access     = AccessSpec::Default; | ||||
| 	CodeType       parent     = { nullptr }; | ||||
| 	CodeBody       body       = { nullptr }; | ||||
| 	CodeAttributes attributes = { nullptr }; | ||||
| @@ -5182,8 +5225,9 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con | ||||
| 	if ( check( TokType::Identifier ) ) | ||||
| 		name = parse_identifier( toks, context ); | ||||
|  | ||||
| 	AccessSpec access     = AccessSpec::Default; | ||||
| 	Token      parent_tok = { nullptr, 0, TokType::Invalid }; | ||||
| 	local_persist | ||||
| 	char interface_arr_mem[ kilobytes(4) ] {0}; | ||||
| 	Array<CodeType> interfaces = Array<CodeType>::init_reserve( Arena::init_from_memory(interface_arr_mem, kilobytes(4) ), 4 ); | ||||
|  | ||||
| 	if ( check( TokType::Assign_Classifer ) ) | ||||
| 	{ | ||||
| @@ -5194,7 +5238,22 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con | ||||
| 			access = tok_to_access_specifier( currtok ); | ||||
| 		} | ||||
|  | ||||
| 		parent_tok = parse_identifier( toks, context ); | ||||
| 		Token parent_tok = parse_identifier( toks, context ); | ||||
| 		parent = def_type( parent_tok ); | ||||
|  | ||||
| 		while ( check(TokType::Comma) ) | ||||
| 		{ | ||||
| 			eat(TokType::Access_Public); | ||||
|  | ||||
| 			if ( tok_is_access_specifier( currtok ) ) | ||||
| 			{ | ||||
| 				eat(currtok.Type); | ||||
| 			} | ||||
|  | ||||
| 			Token interface_tok = parse_identifier( toks, context ); | ||||
|  | ||||
| 			interfaces.append( def_type( interface_tok ) ); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if ( check( TokType::BraceCurly_Open ) ) | ||||
| @@ -5204,9 +5263,6 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con | ||||
|  | ||||
| 	eat( TokType::Statement_End ); | ||||
|  | ||||
| 	if ( parent_tok ) | ||||
| 		parent = def_type( parent_tok ); | ||||
|  | ||||
| 	if ( which == TokType::Decl_Class ) | ||||
| 		result = def_class( name, body, parent, access | ||||
| 			, attributes | ||||
| @@ -5219,6 +5275,7 @@ Code parse_class_struct( Parser::TokType which, Parser::TokArray& toks, char con | ||||
| 			, mflags | ||||
| 		); | ||||
|  | ||||
| 	interfaces.free(); | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| @@ -6812,4 +6869,4 @@ void Builder::write() | ||||
|  | ||||
| GEN_NS_END | ||||
|  | ||||
| #include "gen.pop_ignores.inline.hpp" | ||||
| #include "helpers/gen.pop_ignores.inline.hpp" | ||||
|   | ||||
							
								
								
									
										103
									
								
								project/gen.hpp
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								project/gen.hpp
									
									
									
									
									
								
							| @@ -12,12 +12,12 @@ | ||||
| #error Gen.hpp : GEN_TIME not defined | ||||
| #endif | ||||
|  | ||||
| #include "gen.push_ignores.inline.hpp" | ||||
| #include "helpers/gen.push_ignores.inline.hpp" | ||||
|  | ||||
| //! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. | ||||
| // Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl | ||||
| #ifndef GEN_ROLL_OWN_DEPENDENCIES | ||||
| #	include "gen.dep.hpp" | ||||
| #	include "dependencies/gen.dep.hpp" | ||||
| #endif | ||||
|  | ||||
| #if defined(GEN_DONT_USE_NAMESPACE) && ! defined(GEN_NS_BEGIN) | ||||
| @@ -778,7 +778,6 @@ struct CodeBody | ||||
|  | ||||
| Define_CodeType( Attributes ); | ||||
| Define_CodeType( Comment ); | ||||
| Define_CodeType( Class ); | ||||
| Define_CodeType( Enum ); | ||||
| Define_CodeType( Exec ); | ||||
| Define_CodeType( Extern ); | ||||
| @@ -789,14 +788,39 @@ Define_CodeType( Module ); | ||||
| Define_CodeType( Namespace ); | ||||
| Define_CodeType( Operator ); | ||||
| Define_CodeType( OpCast ); | ||||
| Define_CodeType( Struct ); | ||||
| Define_CodeType( Template ); | ||||
| Define_CodeType( Type ); | ||||
| Define_CodeType(Typedef); | ||||
| Define_CodeType( Typedef ); | ||||
| Define_CodeType( Union ); | ||||
| Define_CodeType( Using ); | ||||
| Define_CodeType( Var ); | ||||
|  | ||||
| struct CodeClass | ||||
| { | ||||
| 	Using_Code( CodeClass ); | ||||
|  | ||||
| 	void add_interface( CodeType interface ); | ||||
|  | ||||
| 	AST* raw() | ||||
| 	{ | ||||
| 		return rcast( AST*, ast ); | ||||
| 	} | ||||
| 	operator Code() | ||||
| 	{ | ||||
| 		return * rcast( Code*, this ); | ||||
| 	} | ||||
| 	AST_Class* operator->() | ||||
| 	{ | ||||
| 		if ( ast == nullptr ) | ||||
| 		{ | ||||
| 			log_failure("Attempt to dereference a nullptr"); | ||||
| 			return nullptr; | ||||
| 		} | ||||
| 		return ast; | ||||
| 	} | ||||
| 	AST_Class* ast; | ||||
| }; | ||||
|  | ||||
| struct CodeParam | ||||
| { | ||||
| 	Using_Code( CodeParam ); | ||||
| @@ -904,6 +928,32 @@ struct CodeSpecifiers | ||||
| 	AST_Specifiers* ast; | ||||
| }; | ||||
|  | ||||
| struct CodeStruct | ||||
| { | ||||
| 	Using_Code( CodeStruct ); | ||||
|  | ||||
| 	void add_interface( CodeType interface ); | ||||
|  | ||||
| 	AST* raw() | ||||
| 	{ | ||||
| 		return rcast( AST*, ast ); | ||||
| 	} | ||||
| 	operator Code() | ||||
| 	{ | ||||
| 		return * rcast( Code*, this ); | ||||
| 	} | ||||
| 	AST_Struct* operator->() | ||||
| 	{ | ||||
| 		if ( ast == nullptr ) | ||||
| 		{ | ||||
| 			log_failure("Attempt to dereference a nullptr"); | ||||
| 			return nullptr; | ||||
| 		} | ||||
| 		return ast; | ||||
| 	} | ||||
| 	AST_Struct* ast; | ||||
| }; | ||||
|  | ||||
| #undef Define_CodeType | ||||
| #undef Using_Code | ||||
| #pragma endregion Code Types | ||||
| @@ -971,8 +1021,8 @@ struct AST_Class | ||||
| 			CodeBody        Body; | ||||
| 		}; | ||||
| 	}; | ||||
| 	Code                    Prev; | ||||
| 	Code                    Next; | ||||
| 	CodeType                Last; | ||||
| 	CodeType                Next; | ||||
| 	Code                    Parent; | ||||
| 	StringCached            Name; | ||||
| 	CodeT                   Type; | ||||
| @@ -1223,8 +1273,8 @@ struct AST_Struct | ||||
| 			CodeBody       Body; | ||||
| 		}; | ||||
| 	}; | ||||
| 	Code                   Prev; | ||||
| 	Code                   Next; | ||||
| 	CodeType               Last; | ||||
| 	CodeType               Next; | ||||
| 	Code                   Parent; | ||||
| 	StringCached           Name; | ||||
| 	CodeT                  Type; | ||||
| @@ -1407,7 +1457,8 @@ CodeClass def_class( StrC name | ||||
| 	, Code           body         = NoCode | ||||
| 	, CodeType       parent       = NoCode, AccessSpec access = AccessSpec::Default | ||||
| 	, CodeAttributes attributes   = NoCode | ||||
| 	, ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	, ModuleFlag     mflags       = ModuleFlag::None | ||||
| 	, CodeType*      interfaces   = nullptr, s32 num_interfaces = 0 ); | ||||
|  | ||||
| CodeEnum def_enum( StrC name | ||||
| 	, Code         body      = NoCode,      CodeType       type       = NoCode | ||||
| @@ -1441,7 +1492,8 @@ CodeStruct def_struct( StrC name | ||||
| 	, Code           body       = NoCode | ||||
| 	, CodeType       parent     = NoCode, AccessSpec access = AccessSpec::Default | ||||
| 	, CodeAttributes attributes = NoCode | ||||
| 	, ModuleFlag     mflags     = ModuleFlag::None ); | ||||
| 	, ModuleFlag     mflags     = ModuleFlag::None | ||||
| 	, CodeType*      interfaces = nullptr, s32 num_interfaces = 0 ); | ||||
|  | ||||
| CodeTemplate def_template( CodeParam params, Code definition, ModuleFlag mflags = ModuleFlag::None ); | ||||
|  | ||||
| @@ -1737,8 +1789,8 @@ Define_AST_Cast( Namespace ); | ||||
| Define_AST_Cast( Operator ); | ||||
| Define_AST_Cast( OpCast ); | ||||
| Define_AST_Cast( Param ); | ||||
| Define_AST_Cast( Specifiers ); | ||||
| Define_AST_Cast( Struct ); | ||||
| Define_AST_Cast( Specifiers ); | ||||
| Define_AST_Cast( Template ); | ||||
| Define_AST_Cast( Type ); | ||||
| Define_AST_Cast( Typedef ); | ||||
| @@ -1779,6 +1831,19 @@ Define_CodeCast( Body); | ||||
| #undef Define_CodeCast | ||||
| #pragma endregion AST & Code Gen Common | ||||
|  | ||||
| void CodeClass::add_interface( CodeType type ) | ||||
| { | ||||
| 	if ( ! ast->Next ) | ||||
| 	{ | ||||
| 		ast->Next = type; | ||||
| 		ast->Last = ast->Next; | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	ast->Next->Next = type; | ||||
| 	ast->Last       = ast->Next->Next; | ||||
| } | ||||
|  | ||||
| void CodeParam::append( CodeParam other ) | ||||
| { | ||||
| 	AST* self  = (AST*) ast; | ||||
| @@ -1828,6 +1893,18 @@ CodeParam& CodeParam::operator ++() | ||||
| 	return * this; | ||||
| } | ||||
|  | ||||
| void CodeStruct::add_interface( CodeType type ) | ||||
| { | ||||
| 	if ( ! ast->Next ) | ||||
| 	{ | ||||
| 		ast->Next = type; | ||||
| 		ast->Last = ast->Next; | ||||
| 	} | ||||
|  | ||||
| 	ast->Next->Next = type; | ||||
| 	ast->Last       = ast->Next->Next; | ||||
| } | ||||
|  | ||||
| CodeBody def_body( CodeT type ) | ||||
| { | ||||
| 	switch ( type ) | ||||
| @@ -2030,4 +2107,4 @@ StrC token_fmt_impl( sw num, ... ) | ||||
|  | ||||
| GEN_NS_END | ||||
|  | ||||
| #include "gen.pop_ignores.inline.hpp" | ||||
| #include "helpers/gen.pop_ignores.inline.hpp" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user