mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-10-30 22:40:54 -07:00 
			
		
		
		
	WIP: Converting api to use custom String types
This commit is contained in:
		| @@ -54,7 +54,7 @@ using zpl::ArrayHeader; | ||||
| using zpl::FileInfo; | ||||
| using zpl::FileError; | ||||
| using zpl::Pool; | ||||
| using zpl::String; | ||||
| // using zpl::String; | ||||
|  | ||||
| using zpl::EFileMode_WRITE; | ||||
| using zpl::EFileError_NONE; | ||||
| @@ -77,6 +77,7 @@ using zpl::pool_allocator; | ||||
| using zpl::pool_init; | ||||
| using zpl::pool_free; | ||||
| using zpl::process_exit; | ||||
| using zpl::str_copy; | ||||
| using zpl::str_fmt_out_va; | ||||
| using zpl::str_fmt_out_err_va; | ||||
| using zpl::str_compare; | ||||
| @@ -188,7 +189,25 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; | ||||
| #pragma endregion Memory | ||||
|  | ||||
| #pragma region String | ||||
| #if 0 | ||||
| #if 1 | ||||
| 	// Constant string with length. | ||||
| 	struct StrC | ||||
| 	{ | ||||
| 		sw          Len; | ||||
| 		char const* Ptr; | ||||
|  | ||||
| 		static StrC from( char const* str ) | ||||
| 		{ | ||||
| 			return { str_len( str ), str }; | ||||
| 		} | ||||
|  | ||||
| 		operator char const* () const | ||||
| 		{ | ||||
| 			return Ptr; | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	// Dynamic String | ||||
| 	struct String | ||||
| 	{ | ||||
| 		struct Header | ||||
| @@ -238,10 +257,12 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; | ||||
| 		void append( char c ); | ||||
| 		void append( char const* str ); | ||||
| 		void append( char const* str, sw length ); | ||||
| 		void append( StrC str); | ||||
| 		void append( const String other ); | ||||
| 		void append( char const* fmt, ... ); | ||||
| 		void append( const String other ); | ||||
|  | ||||
| 		void append_fmt( char const* fmt, ... ); | ||||
|  | ||||
| 		sw avail_space(); | ||||
| 		sw capacity(); | ||||
|  | ||||
| @@ -251,13 +272,67 @@ char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; | ||||
|  | ||||
| 		void free(); | ||||
|  | ||||
| 		Header& header(); | ||||
| 		Header& get_headder() | ||||
| 		{ | ||||
| 			return pcast( Header, Data[ - sizeof( Header ) ] ); | ||||
| 		} | ||||
|  | ||||
| 		sw length(); | ||||
| 		sw length() const; | ||||
|  | ||||
| 		void trim( char const* cut_set ); | ||||
| 		void trim_space(); | ||||
|  | ||||
| 		operator bool() | ||||
| 		{ | ||||
| 			return Data; | ||||
| 		} | ||||
|  | ||||
| 		operator char* () | ||||
| 		{ | ||||
| 			return Data; | ||||
| 		} | ||||
|  | ||||
| 		operator char const* () const | ||||
| 		{ | ||||
| 			return Data; | ||||
| 		} | ||||
|  | ||||
| 		operator StrC() | ||||
| 		{ | ||||
| 			return | ||||
| 			{ | ||||
| 				length(), | ||||
| 				Data | ||||
| 			}; | ||||
| 		} | ||||
|  | ||||
| 		String const& operator = ( String const& other ) const | ||||
| 		{ | ||||
| 			if ( this == & other ) | ||||
| 				return *this; | ||||
|  | ||||
| 			String& this_ = ccast( String, *this ); | ||||
|  | ||||
| 			this_.Data = other.Data; | ||||
|  | ||||
| 			return this_; | ||||
| 		} | ||||
|  | ||||
| 		String& operator += ( String const& other ) | ||||
| 		{ | ||||
| 			append( other ); | ||||
| 			return *this; | ||||
| 		} | ||||
|  | ||||
| 		char& operator [] ( sw index ) | ||||
| 		{ | ||||
| 			return Data[ index ]; | ||||
| 		} | ||||
|  | ||||
| 		char const& operator [] ( sw index ) const | ||||
| 		{ | ||||
| 			return Data[ index ]; | ||||
| 		} | ||||
|  | ||||
| 		char* Data = nullptr; | ||||
| 	}; | ||||
| @@ -287,7 +362,7 @@ namespace Memory | ||||
| } | ||||
|  | ||||
| inline | ||||
| sw log_fmt(char const *fmt, ...) | ||||
| sw log_fmt(char const* fmt, ...) | ||||
| { | ||||
| 	sw res; | ||||
| 	va_list va; | ||||
| @@ -300,7 +375,7 @@ sw log_fmt(char const *fmt, ...) | ||||
| } | ||||
|  | ||||
| inline | ||||
| sw fatal(char const *fmt, ...) | ||||
| sw fatal(char const* fmt, ...) | ||||
| { | ||||
| 	local_persist thread_local | ||||
| 	char buf[ZPL_PRINTF_MAXLEN] = { 0 }; | ||||
|   | ||||
							
								
								
									
										527
									
								
								project/gen.cpp
									
									
									
									
									
								
							
							
						
						
									
										527
									
								
								project/gen.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										126
									
								
								project/gen.hpp
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								project/gen.hpp
									
									
									
									
									
								
							| @@ -11,7 +11,7 @@ | ||||
| #include "Bloat.hpp" | ||||
|  | ||||
| // Temporarily here for debugging purposes. | ||||
| #define GEN_DEFINE_DSL | ||||
| // #define GEN_DEFINE_DSL | ||||
| #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS | ||||
| // #define GEN_DONT_USE_FATAL | ||||
| #define GEN_ENFORCE_READONLY_AST | ||||
| @@ -94,11 +94,11 @@ namespace gen | ||||
| 		}; | ||||
|  | ||||
| 		inline | ||||
| 		char const* to_str( Type type ) | ||||
| 		StrC to_str( Type type ) | ||||
| 		{ | ||||
| 			static | ||||
| 			char const* lookup[Num_Types] = { | ||||
| 			#	define Entry( Type ) txt( Type ), | ||||
| 			StrC lookup[Num_Types] = { | ||||
| 			#	define Entry( Type ) { txt_n_len( Type ) }, | ||||
| 				Define_Types | ||||
| 			#	undef Entry | ||||
| 			}; | ||||
| @@ -248,11 +248,11 @@ namespace gen | ||||
|  | ||||
| 		// Specifier to string | ||||
| 		inline | ||||
| 		char const* to_str( Type specifier ) | ||||
| 		StrC to_str( Type specifier ) | ||||
| 		{ | ||||
| 			local_persist | ||||
| 			char const* lookup[ Num_Specifiers ] = { | ||||
| 			#	define Entry( Spec_, Code_ ) txt(Code_), | ||||
| 			StrC lookup[ Num_Specifiers ] = { | ||||
| 			#	define Entry( Spec_, Code_ ) { txt_n_len(Code_) }, | ||||
| 				Define_Specifiers | ||||
| 			#	undef Entry | ||||
| 			}; | ||||
| @@ -261,20 +261,20 @@ namespace gen | ||||
| 		} | ||||
|  | ||||
| 		inline | ||||
| 		Type to_type( char const* str, s32 length ) | ||||
| 		Type to_type( StrC str ) | ||||
| 		{ | ||||
| 			local_persist | ||||
| 			u32 keymap[ Num_Specifiers ]; | ||||
| 			do_once_start | ||||
| 				for ( u32 index = 0; index < Num_Specifiers; index++ ) | ||||
| 				{ | ||||
| 					char const* enum_str = to_str( (Type)index ); | ||||
| 					StrC enum_str = to_str( (Type)index ); | ||||
|  | ||||
| 					keymap[index] = crc32( enum_str, str_len(enum_str, 42) ); | ||||
| 					keymap[index] = crc32( enum_str.Ptr, enum_str.Len); | ||||
| 				} | ||||
| 			do_once_end | ||||
|  | ||||
| 			u32 hash = crc32(str, length ); | ||||
| 			u32 hash = crc32( str.Ptr, str.Len ); | ||||
|  | ||||
| 			for ( u32 index = 0; index < Num_Specifiers; index++ ) | ||||
| 			{ | ||||
| @@ -371,7 +371,7 @@ namespace gen | ||||
|  | ||||
| 	// Represents strings cached with the string table. | ||||
| 	// Should never be modified, if changed string is desired, cache_string( str ) another. | ||||
| 	using StringCached = char const*; | ||||
| 	using StringCached = String const; | ||||
|  | ||||
| 	// Desired width of the AST data structure. | ||||
| 	constexpr u32 AST_POD_Size = 256; | ||||
| @@ -424,7 +424,7 @@ namespace gen | ||||
|  | ||||
| 		// Parameter | ||||
|  | ||||
| 		bool add_param( AST* type, s32 length, char const* name ); | ||||
| 		bool add_param( AST* type, StrC name ); | ||||
|  | ||||
| 		inline | ||||
| 		AST* get_param( s32 index ) | ||||
| @@ -638,7 +638,7 @@ namespace gen | ||||
| 		} | ||||
|  | ||||
| 		inline | ||||
| 		char const* to_string() | ||||
| 		String to_string() | ||||
| 		{ | ||||
| 			return ast->to_string(); | ||||
| 		} | ||||
| @@ -743,7 +743,7 @@ namespace gen | ||||
|  | ||||
| 	// Used internally to retrive or make string allocations. | ||||
| 	// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena) | ||||
| 	StringCached get_cached_string( char const* cstr, s32 length ); | ||||
| 	StringCached get_cached_string( StrC str ); | ||||
|  | ||||
| 	/* | ||||
| 		This provides a fresh Code AST. | ||||
| @@ -767,58 +767,58 @@ namespace gen | ||||
| 	void set_allocator_type_table       ( AllocatorInfo type_reg_allocator ); | ||||
|  | ||||
| #	pragma region Upfront | ||||
| 	Code def_comment   ( s32 length, char const* content ); | ||||
| 	Code def_attributes( s32 length, char const* content ); | ||||
| 	Code def_comment   ( StrC content ); | ||||
| 	Code def_attributes( StrC content ); | ||||
|  | ||||
| 	Code def_class( s32 length, char const* name | ||||
| 	Code def_class( StrC name | ||||
| 		, Code body         = NoCode | ||||
| 		, Code parent       = NoCode, AccessSpec access = AccessSpec::Public | ||||
| 		, Code attributes   = NoCode | ||||
| 		, ModuleFlag mflags = ModuleFlag::None ); | ||||
|  | ||||
| 	Code def_enum( s32 length, char const* name | ||||
| 	Code def_enum( StrC | ||||
| 		, Code       body      = NoCode,      Code type       = NoCode | ||||
| 		, EnumT      specifier = EnumRegular, Code attributes = NoCode | ||||
| 		, ModuleFlag mflags    = ModuleFlag::None ); | ||||
|  | ||||
| 	Code def_execution  ( s32 length, char const* content ); | ||||
| 	Code def_extern_link( s32 length, char const* name, Code body, ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	Code def_execution  ( StrC content ); | ||||
| 	Code def_extern_link( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	Code def_friend     ( Code symbol ); | ||||
|  | ||||
| 	Code def_function( s32 length, char const* name | ||||
| 	Code def_function( StrC name | ||||
| 		, Code       params     = NoCode, Code ret_type   = NoCode, Code body = NoCode | ||||
| 		, Code       specifiers = NoCode, Code attributes = NoCode | ||||
| 		, ModuleFlag mflags     = ModuleFlag::None ); | ||||
|  | ||||
| 	Code def_include  ( s32 length, char const* path ); | ||||
| 	Code def_module   ( s32 length, char const* name,            ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	Code def_namespace( s32 length, char const* name, Code body, ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	Code def_include  ( StrC content ); | ||||
| 	Code def_module   ( StrC name,            ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	Code def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None ); | ||||
|  | ||||
| 	Code def_operator( OperatorT op | ||||
| 		, Code       params     = NoCode, Code ret_type   = NoCode, Code body = NoCode | ||||
| 		, Code       specifiers = NoCode, Code attributes = NoCode | ||||
| 		, ModuleFlag mflags     = ModuleFlag::None ); | ||||
|  | ||||
| 	Code def_param     ( Code type, s32 length, char const* name, Code value = NoCode ); | ||||
| 	Code def_param     ( Code type, StrC name, Code value = NoCode ); | ||||
| 	Code def_specifier( SpecifierT specifier ); | ||||
|  | ||||
| 	Code def_struct( s32 length, char const* name | ||||
| 	Code def_struct( StrC name | ||||
| 		, Code       body | ||||
| 		, Code       parent     = NoCode, AccessSpec access = AccessSpec::Public | ||||
| 		, Code       attributes = NoCode | ||||
| 		, ModuleFlag mflags     = ModuleFlag::None ); | ||||
|  | ||||
| 	Code def_typedef( s32 length, char const* name, Code type, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	Code def_type   ( s32 length, char const* name, Code arrayexpr = NoCode, Code specifiers = NoCode ); | ||||
| 	Code def_typedef( StrC name, Code type, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	Code def_type   ( StrC name, Code arrayexpr = NoCode, Code specifiers = NoCode ); | ||||
|  | ||||
| 	Code def_union( s32 length, char const* name, Code body = NoCode, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	Code def_union( StrC name, Code body = NoCode, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | ||||
|  | ||||
| 	Code def_using( s32 length, char const* name, UsingT specifier = UsingRegular | ||||
| 	Code def_using( StrC name, UsingT specifier = UsingRegular | ||||
| 		, Code       type        = NoCode | ||||
| 		, Code       attributess = NoCode | ||||
| 		, ModuleFlag mflags      = ModuleFlag::None ); | ||||
|  | ||||
| 	Code def_variable( Code type, s32 length, char const* name, Code value = NoCode | ||||
| 	Code def_variable( Code type, StrC name, Code value = NoCode | ||||
| 		, Code       specifiers = NoCode, Code attributes = NoCode | ||||
| 		, ModuleFlag mflags     = ModuleFlag::None ); | ||||
|  | ||||
| @@ -847,24 +847,24 @@ namespace gen | ||||
|  | ||||
| #	pragma region Incremental | ||||
| #	ifdef GEN_FEATURE_INCREMENTAL | ||||
| 	Code make_class( s32 length, char const* name | ||||
| 	Code make_class( StrC name | ||||
| 		, Code       parent     = NoCode, AccessSpec access     = AccessSpec::Public | ||||
| 		, Code       specifiers = NoCode, Code       attributes = NoCode | ||||
| 		, ModuleFlag mflags     = ModuleFlag::None ); | ||||
|  | ||||
| 	Code make_enum( s32 length, char const* name | ||||
| 	Code make_enum( StrC name | ||||
| 		, Code type       = NoCode, EnumT      specifier = EnumRegular | ||||
| 		, Code attributes = NoCode, ModuleFlag mflags    = ModuleFlag::None ); | ||||
|  | ||||
| 	Code make_export_body   ( s32 length = 1, char const* name = "" ); | ||||
| 	Code make_export_body   ( StrC name = { 1, "" } ); | ||||
| 	Code make_extern_linkage( s32 length,     char const* name, ModuleFlag mflags = ModuleFlag::None ); | ||||
|  | ||||
| 	Code make_function( s32 length, char const* name | ||||
| 	Code make_function( StrC name | ||||
| 		, Code       params     = NoCode, Code ret_type   = NoCode | ||||
| 		, Code       specifiers = NoCode, Code attributes = NoCode | ||||
| 		, ModuleFlag mflags     = ModuleFlag::None ); | ||||
|  | ||||
| 	Code make_global_body( s32 length = 1, char const* name = "" ); | ||||
| 	Code make_global_body( StrC name = { 1, "" } ); | ||||
| 	Code make_namespace  ( s32 length,     char const* name, ModuleFlag mflags = ModuleFlag::None ); | ||||
|  | ||||
| 	Code make_operator( OperatorT op | ||||
| @@ -875,32 +875,32 @@ namespace gen | ||||
| 	Code make_params    (); | ||||
| 	Code make_specifiers(); | ||||
|  | ||||
| 	Code make_struct( s32 length, char const* name | ||||
| 	Code make_struct( StrC name | ||||
| 		, Code       parent     = NoCode, AccessSpec access | ||||
| 		, Code       specifiers = NoCode, Code       attributes = NoCode | ||||
| 		, ModuleFlag mflags     = ModuleFlag::None ); | ||||
|  | ||||
| 	Code make_union( s32 length, char const* name, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | ||||
| 	Code make_union( StrC name, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); | ||||
| #	endif | ||||
| #	pragma endregion Incremental | ||||
|  | ||||
| 	#pragma region Parsing | ||||
| 	#ifdef GEN_FEATURE_PARSING | ||||
| 	Code parse_class      ( s32 length, char const* class_def     ); | ||||
| 	Code parse_enum       ( s32 length, char const* enum_def      ); | ||||
| 	Code parse_export_body( s32 length, char const* export_def    ); | ||||
| 	Code parse_exten_link ( s32 length, char const* exten_link_def); | ||||
| 	Code parse_friend     ( s32 length, char const* friend_def    ); | ||||
| 	Code parse_function   ( s32 length, char const* fn_def        ); | ||||
| 	Code parse_global_body( s32 length, char const* body_def      ); | ||||
| 	Code parse_namespace  ( s32 length, char const* namespace_def ); | ||||
| 	Code parse_operator   ( s32 length, char const* operator_def  ); | ||||
| 	Code parse_struct     ( s32 length, char const* struct_def    ); | ||||
| 	Code parse_type       ( s32 length, char const* type_def      ); | ||||
| 	Code parse_typedef    ( s32 length, char const* typedef_def   ); | ||||
| 	Code parse_union      ( s32 length, char const* union_def     ); | ||||
| 	Code parse_using      ( s32 length, char const* using_def     ); | ||||
| 	Code parse_variable   ( s32 length, char const* var_def       ); | ||||
| 	Code parse_class      ( StrC class_def     ); | ||||
| 	Code parse_enum       ( StrC enum_def      ); | ||||
| 	Code parse_export_body( StrC export_def    ); | ||||
| 	Code parse_exten_link ( StrC exten_link_def); | ||||
| 	Code parse_friend     ( StrC friend_def    ); | ||||
| 	Code parse_function   ( StrC fn_def        ); | ||||
| 	Code parse_global_body( StrC body_def      ); | ||||
| 	Code parse_namespace  ( StrC namespace_def ); | ||||
| 	Code parse_operator   ( StrC operator_def  ); | ||||
| 	Code parse_struct     ( StrC struct_def    ); | ||||
| 	Code parse_type       ( StrC type_def      ); | ||||
| 	Code parse_typedef    ( StrC typedef_def   ); | ||||
| 	Code parse_union      ( StrC union_def     ); | ||||
| 	Code parse_using      ( StrC using_def     ); | ||||
| 	Code parse_variable   ( StrC var_def       ); | ||||
| 	#endif | ||||
| 	#pragma endregion Parsing | ||||
|  | ||||
| @@ -921,9 +921,9 @@ namespace gen | ||||
| 		return buf; | ||||
| 	} | ||||
|  | ||||
| 	Code untyped_str      ( s32 length, char const* str); | ||||
| 	Code untyped_fmt      (             char const* fmt, ... ); | ||||
| 	Code untyped_token_fmt(             char const* fmt, s32 num_tokens, ... ); | ||||
| 	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 | ||||
|  | ||||
| 	struct Builder | ||||
| @@ -1058,10 +1058,10 @@ namespace gen | ||||
|  | ||||
| //	Convienence for defining any name used with the gen interface. | ||||
| //  Lets you provide the length and string literal to the functions without the need for the DSL. | ||||
| #	define name( Id_ )   txt_n_len( Id_ ) | ||||
| #	define name( Id_ )   { txt_n_len( Id_ ) } | ||||
|  | ||||
| //  Same as name just used to indicate intention of literal for code instead of names. | ||||
| #	define code( Code_ ) txt_n_len( Code_ ) | ||||
| #	define code( Code_ ) { txt_n_len( Code_ ) } | ||||
|  | ||||
| /* | ||||
| 	gen's Domain Specific Langauge. | ||||
| @@ -1285,7 +1285,7 @@ namespace gen | ||||
| 	} | ||||
|  | ||||
| 	inline | ||||
| 	bool AST::add_param( AST* type, s32 length, char const* name ) | ||||
| 	bool AST::add_param( AST* type, StrC name ) | ||||
| 	{ | ||||
| 		if ( Type != ECode::Function ) | ||||
| 		{ | ||||
| @@ -1293,9 +1293,9 @@ namespace gen | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
|  | ||||
| 		if ( length <= 0 ) | ||||
| 		if ( name.Len <= 0 ) | ||||
| 		{ | ||||
| 			log_failure( "gen::AST::add_param: Invalid name length provided - %d", length ); | ||||
| 			log_failure( "gen::AST::add_param: Invalid name length provided - %d", name.Len ); | ||||
| 			return Code::Invalid; | ||||
| 		} | ||||
|  | ||||
| @@ -1317,7 +1317,7 @@ namespace gen | ||||
| 		} | ||||
| 		else if ( score == 2) | ||||
| 		{ | ||||
| 			Name       = name; | ||||
| 			Name       = get_cached_string( name ); | ||||
| 			Entries[0] = type; | ||||
| 			return true; | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										231
									
								
								test/NonParsed/Array.NonParsed.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								test/NonParsed/Array.NonParsed.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,231 @@ | ||||
| #pragma once | ||||
|  | ||||
| #if gen_time | ||||
| #include "gen.hpp" | ||||
|  | ||||
| using namespace gen; | ||||
|  | ||||
| Code gen__array_base() | ||||
| { | ||||
| 	Code t_allocator_info = def_type( name(AllocatorInfo) ); | ||||
| 	Code header; | ||||
| 	{ | ||||
| 		Code allocator = def_variable( t_allocator_info, name(Allocator) ); | ||||
| 		Code capacity  = def_variable( t_uw,             name(Capacity) ); | ||||
| 		Code num       = def_variable( t_uw,             name(Num) ); | ||||
|  | ||||
| 		Code body   = def_struct_body( 3, allocator, capacity, num ); | ||||
| 		     header = def_struct( name(Header), body ); | ||||
| 	} | ||||
|  | ||||
| 	Code grow_formula; | ||||
| 	{ | ||||
| 		Code params = def_param( t_uw, name(value)); | ||||
| 		Code body   = untyped_str( code( return 2 * value * 8; )); | ||||
|  | ||||
| 		Code spec = def_specifiers( ESpecifier::Static_Member, ESpecifier::Inline ); | ||||
|  | ||||
| 		grow_formula = def_function( name(grow_formula), params, t_uw, body, spec ); | ||||
| 	} | ||||
|  | ||||
| 	Code body       = def_struct_body( 2, header, grow_formula ); | ||||
| 	Code array_base = def_struct( name(ArrayBase), body ); | ||||
|  | ||||
| 	return array_base; | ||||
| } | ||||
|  | ||||
| Code gen__array( StrC type, sw type_size ) | ||||
| { | ||||
| 	Code t_allocator_info = def_type( name(AllocatorInfo) ); | ||||
| 	Code v_nullptr        = untyped_str( code(nullptr)); | ||||
|  | ||||
| 	static Code ArrayBase = gen__array_base(); | ||||
|  | ||||
| 	StrC name; | ||||
| 	{ | ||||
| 		char const* name_str = str_fmt_buf( "Array_%s", type.Ptr ); | ||||
| 		s32         name_len = str_len( name ); | ||||
|  | ||||
| 		name = { name_len, name_str }; | ||||
| 	}; | ||||
|  | ||||
| 	Code t_array_type = def_type( name ); | ||||
|  | ||||
| 	Code t_type     = def_type( type ); | ||||
| 	Code t_type_ptr = def_type( type, __, spec_ptr ); | ||||
| 	Code t_type_ref = def_type( type, __, spec_ref ); | ||||
|  | ||||
| 	Code t_header     = def_type( name(Header) ); | ||||
| 	Code t_header_ptr = def_type( name(Header), __, spec_ptr ); | ||||
| 	Code t_header_ref = def_type( name(Header), __, spec_ref ); | ||||
|  | ||||
| 	Code spec_static_inline = def_specifiers( ESpecifier::Static_Member, ESpecifier::Inline ); | ||||
| 	Code spec_static        = def_specifiers( ESpecifier::Static_Member ); | ||||
|  | ||||
| 	Code array; | ||||
| 	{ | ||||
| 		Code using_type = def_using( name(Type), UsingRegular, t_type ); | ||||
| 		Code data       = def_variable( t_type_ptr, name(Data) ); | ||||
|  | ||||
| 		Code init; | ||||
| 		{ | ||||
| 			Code params = def_param( t_allocator_info, name(allocator) ); | ||||
| 			Code body   = untyped_str( code( | ||||
| 				return init_reserve( allocator, grow_formula(0) ); | ||||
| 			)); | ||||
|  | ||||
| 			init = def_function( name(init), params, t_array_type, body, spec_static ); | ||||
| 		} | ||||
|  | ||||
| 		Code init_reserve; | ||||
| 		{ | ||||
| 			Code params = def_params( 2, t_allocator_info, name(allocator), t_sw, name(capacity) ); | ||||
| 			Code body = untyped_str( code( | ||||
| 				Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) )); | ||||
|  | ||||
| 				if ( header == nullptr ) | ||||
| 					return false; | ||||
|  | ||||
| 				header->Allocator = allocator; | ||||
| 				header->Capacity  = capacity; | ||||
| 				header->Num       = 0; | ||||
|  | ||||
| 				Data = rcast( Type*, header + 1 ); | ||||
|  | ||||
| 				return true; | ||||
| 			)); | ||||
|  | ||||
| 			init_reserve = def_function( name(init_reserve), params, t_array_type, body, spec_static ); | ||||
| 		} | ||||
|  | ||||
| 		Code append; | ||||
| 		{ | ||||
| 			Code params = def_param( t_type, name(value)); | ||||
|  | ||||
| 			Code body = untyped_str( code( | ||||
| 				Header& header = get_header(); | ||||
|  | ||||
| 				if ( header.Num == header.Capacity ) | ||||
| 				{ | ||||
| 					if ( ! grow( header.Allocator )) | ||||
| 						return false; | ||||
| 				} | ||||
|  | ||||
| 				data[ header.Num ] = value; | ||||
| 				header.Num++; | ||||
|  | ||||
| 				return true; | ||||
| 			)); | ||||
|  | ||||
| 			append = def_function( name(append), params, t_bool, body ); | ||||
| 		} | ||||
|  | ||||
| 		Code back; | ||||
| 		{ | ||||
| 			Code body = untyped_str( code( | ||||
| 				Header& header = get_header(); | ||||
| 				return Data[ header.Num - 1 ]; | ||||
| 			)); | ||||
|  | ||||
| 			back = def_function( name(back), __, t_type_ref, body ); | ||||
| 		} | ||||
|  | ||||
| 		Code clear; | ||||
| 		Code fill; | ||||
|  | ||||
| 		Code free; | ||||
| 		{ | ||||
| 			Code body = untyped_str( code( | ||||
| 				Header& header = get_header(); | ||||
| 				::free( header.Allocator, & header ); | ||||
| 			)); | ||||
|  | ||||
| 			free = def_function( name(free), __, t_void, body, spec_inline ); | ||||
| 		} | ||||
|  | ||||
| 		Code get_header; | ||||
| 		Code grow; | ||||
| 		Code pop; | ||||
| 		Code reserve; | ||||
| 		Code resize; | ||||
| 		Code set_capacity; | ||||
|  | ||||
| 		Code body = def_struct_body( 17 | ||||
| 			, using_type | ||||
|  | ||||
| 			, init | ||||
| 			, init_reserve | ||||
|  | ||||
| 			, append | ||||
| 			, back | ||||
| 			, clear | ||||
| 			, fill | ||||
| 			, free | ||||
| 			, get_header | ||||
| 			, grow | ||||
| 			, pop | ||||
| 			, reserve | ||||
| 			, resize | ||||
| 			, set_capacity | ||||
|  | ||||
| 			, data | ||||
| 		); | ||||
|  | ||||
| 		array = def_struct( name, body ); | ||||
| 	} | ||||
|  | ||||
| 	return array; | ||||
| } | ||||
|  | ||||
|  | ||||
| struct GenArrayRequest | ||||
| { | ||||
| 	StrC Type; | ||||
| 	StrC Dependency; | ||||
| 	sw   Size; | ||||
| }; | ||||
| Array(GenArrayRequest) GenArrayRequests; | ||||
|  | ||||
| void gen__array_request( StrC type, StrC dep, sw size ) | ||||
| { | ||||
| 	GenArrayRequest request = { type, dep, size }; | ||||
| 	array_append( GenArrayRequests, request ); | ||||
| } | ||||
| #define Gen_Array( type ) gen__array_request( txt_n_len( type ), sizeof(type) ) | ||||
|  | ||||
| u32 gen_array_file() | ||||
| { | ||||
| 	Builder | ||||
| 	gen_array_file; | ||||
| 	gen_array_file.open( "array.gen.hpp" ); | ||||
|  | ||||
|  | ||||
| 	GenArrayRequest* current = GenArrayRequests; | ||||
| 	s32 left = array_count( GenArrayRequests ); | ||||
| 	while (left--) | ||||
| 	{ | ||||
| 		GenArrayRequest const& request = * current; | ||||
|  | ||||
| 		Code generated_array = gen__array( request.Type, request.Size ); | ||||
|  | ||||
| 		if ( request.Dependency ) | ||||
| 		{ | ||||
| 			char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); | ||||
| 			s32         cmt_len = str_len( cmt_str ); | ||||
|  | ||||
| 			Code cmt     = def_comment( { cmt_len, cmt_str } ); | ||||
| 			Code include = def_include( request.Dependency ); | ||||
|  | ||||
| 			gen_array_file.print( cmt ); | ||||
| 			gen_array_file.print( include ); | ||||
| 		} | ||||
|  | ||||
| 		gen_array_file.print( generated_array ); | ||||
| 		current++; | ||||
| 	} | ||||
|  | ||||
| 	gen_array_file.write(); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										170
									
								
								test/Parsed/Array.Parsed.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								test/Parsed/Array.Parsed.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,170 @@ | ||||
| #pragma once | ||||
|  | ||||
| #if gen_time | ||||
| #include "gen.hpp" | ||||
|  | ||||
| using namespace gen; | ||||
|  | ||||
| Code gen__array_base() | ||||
| { | ||||
| 	Code array_base = parse_struct( code( | ||||
| 		struct ArrayBase | ||||
| 		{ | ||||
| 			struct Header | ||||
| 			{ | ||||
| 				AllocatorInfo Allocator; | ||||
| 				uw            Capacity; | ||||
| 				uw            Num; | ||||
| 			}; | ||||
|  | ||||
| 			static inline | ||||
| 			sw grow_formula( sw value ) | ||||
| 			{ | ||||
| 				return 2 * value * 8; | ||||
| 			} | ||||
| 		}; | ||||
| 	)); | ||||
|  | ||||
| 	return array_base; | ||||
| } | ||||
|  | ||||
| Code gen__array( s32 length, char const* type_str, sw type_size ) | ||||
| { | ||||
| 	StrC tmpl = code( | ||||
| 		struct Array_{type} : ArrayBase | ||||
| 		{ | ||||
| 			using Type = {type}; | ||||
|  | ||||
| 			Type* Data; | ||||
|  | ||||
| 			static Array_{type} init( AllocatorInfo allocator ) | ||||
| 			{ | ||||
| 				return init_reserve( allocator, grow_formula(0) ); | ||||
| 			} | ||||
|  | ||||
| 			static Array_{type} init_reserve( AllocatorInfo allocator, uw capacity ) | ||||
| 			{ | ||||
| 				Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) )); | ||||
|  | ||||
| 				if ( header == nullptr ) | ||||
| 					return false; | ||||
|  | ||||
| 				header->Allocator = allocator; | ||||
| 				header->Capacity  = capacity; | ||||
| 				header->Num       = 0; | ||||
|  | ||||
| 				Array_{type} array; | ||||
| 				array.Data = rcast( Type*, header + 1 ); | ||||
|  | ||||
| 				return array; | ||||
| 			} | ||||
|  | ||||
| 			bool append( Type const& value ) | ||||
| 			{ | ||||
| 				Header& header = get_header(); | ||||
|  | ||||
| 				if ( header.Num == header.Capacity ) | ||||
| 				{ | ||||
| 					if ( ! grow( header.Allocator )) | ||||
| 						return false; | ||||
| 				} | ||||
|  | ||||
| 				data[ header.Num ] = value; | ||||
| 				header.Num++; | ||||
|  | ||||
| 				return true; | ||||
| 			} | ||||
|  | ||||
| 			Type& back() | ||||
| 			{ | ||||
| 				Header& header = get_header(); | ||||
| 				return data[ header.Num - 1 ]; | ||||
| 			} | ||||
|  | ||||
| 			void clear(); | ||||
|  | ||||
| 			bool fill(); | ||||
|  | ||||
| 			void free() | ||||
| 			{ | ||||
| 				Header& header = get_header(); | ||||
| 				::free( header.Allocator, & header ); | ||||
| 			} | ||||
|  | ||||
| 			Header& get_header() | ||||
| 			{ | ||||
| 				return rcast( Header*, Data ) - 1; | ||||
| 			} | ||||
|  | ||||
| 			bool grow(); | ||||
|  | ||||
| 			void pop(); | ||||
|  | ||||
| 			bool reserve( uw num ); | ||||
|  | ||||
| 			bool resize( uw num ); | ||||
|  | ||||
| 			bool set_capacity( uw capacity ); | ||||
| 		} | ||||
| 	); | ||||
|  | ||||
| 	char const* gen_from_tmpl     = token_fmt( tmpl.Ptr, 1, "type", type_str ); | ||||
| 	s32         gen_from_tmpl_len = str_len( gen_from_tmpl ); | ||||
|  | ||||
| 	Code array = parse_struct( { gen_from_tmpl_len, gen_from_tmpl } ); | ||||
| } | ||||
|  | ||||
|  | ||||
| struct GenArrayRequest | ||||
| { | ||||
| 	s32         TypeLength; | ||||
| 	char const* Type; | ||||
| 	sw          Size; | ||||
| 	s32         DependencyLength; | ||||
| 	char const* Dependency; | ||||
| }; | ||||
| Array(GenArrayRequest) GenArrayRequests; | ||||
|  | ||||
| void gen__array_request( s32 type_len, char const* type_str, sw type_size, s32 dep_len, char const* dep ) | ||||
| { | ||||
| 	GenArrayRequest request = { type_len, type_str, type_size, dep_len, dep }; | ||||
| 	array_append( GenArrayRequests, request ); | ||||
| } | ||||
| #define Gen_Array( type ) gen__array_request( txt_n_len( type ), sizeof(type) ) | ||||
|  | ||||
| u32 gen_array_file() | ||||
| { | ||||
| 	Builder | ||||
| 	gen_array_file; | ||||
| 	gen_array_file.open( "array.gen.hpp" ); | ||||
|  | ||||
|  | ||||
| 	GenArrayRequest* current = GenArrayRequests; | ||||
| 	s32 left = array_count( GenArrayRequests ); | ||||
| 	while (left--) | ||||
| 	{ | ||||
| 		GenArrayRequest const& request = * current; | ||||
|  | ||||
| 		Code generated_array = gen__array( request.TypeLength, request.Type, request.Size ); | ||||
|  | ||||
| 		if ( request.Dependency ) | ||||
| 		{ | ||||
| 			char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type ); | ||||
| 			s32         cmt_len = str_len( cmt_str ); | ||||
|  | ||||
| 			Code cmt     = def_comment( { cmt_len, cmt_str } ); | ||||
| 			Code include = def_include( { request.DependencyLength, request.Dependency } ); | ||||
|  | ||||
| 			gen_array_file.print( cmt ); | ||||
| 			gen_array_file.print( include ); | ||||
| 		} | ||||
|  | ||||
| 		gen_array_file.print( generated_array ); | ||||
| 		current++; | ||||
| 	} | ||||
|  | ||||
| 	gen_array_file.write(); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user