WIP doing the massive refactor... also started setup an experimental new layout for the AST..

This commit is contained in:
Edward R. Gonzalez 2023-07-14 01:37:22 -04:00
parent 7a2e20bcdb
commit 7133dc0a95
5 changed files with 526 additions and 559 deletions

File diff suppressed because it is too large Load Diff

View File

@ -2420,7 +2420,7 @@ namespace gen
alignas alignas
*/ */
# define Define_Specifiers \ # define Define_Specifiers \
Entry( Invalid, INVALID ) \ Entry( Invalid, INVALID ) \
Entry( Const, const ) \ Entry( Const, const ) \
Entry( Consteval, consteval ) \ Entry( Consteval, consteval ) \
@ -2597,7 +2597,7 @@ namespace gen
struct AST; struct AST;
struct Code; struct Code;
// These are to offer strong type safety for the AST. // These are to offer ease of use and optionally strong type safety for the AST.
struct CodeAttributes; struct CodeAttributes;
struct CodeComment; struct CodeComment;
struct CodeClass; struct CodeClass;
@ -2621,6 +2621,7 @@ namespace gen
struct CodeUsing; struct CodeUsing;
struct CodeUsingNamespace; struct CodeUsingNamespace;
struct CodeVar; struct CodeVar;
struct CodeBody;
struct CodeClassBody; struct CodeClassBody;
struct CodeEnumBody; struct CodeEnumBody;
struct CodeExportBody; struct CodeExportBody;
@ -2634,27 +2635,30 @@ namespace gen
// Desired width of the AST data structure. // Desired width of the AST data structure.
constexpr u32 AST_POD_Size = 256; constexpr u32 AST_POD_Size = 256;
/* namespace EEntry
Simple AST POD with functionality to seralize into C++ syntax.
*/
struct AST
{ {
enum Entry : u32 enum Type : u32
{ {
Entry_Array_Expression, Entry_Array_Expression,
Entry_Attributes, Entry_Attributes,
Entry_Body, Entry_Body,
Entry_Parameters, Entry_Parameters,
Entry_Parameter_Type, Entry_Parameter_Type,
Entry_Parent_Type, Entry_Parent,
Entry_Return_Type, Entry_Return_Type,
Entry_Specifiers, Entry_Specifiers,
Entry_Value, Entry_Value,
}; };
}
using EntryT = EEntry::Type;
/*
Simple AST POD with functionality to seralize into C++ syntax.
*/
struct AST
{
# pragma region Member Functions # pragma region Member Functions
void add_entry( AST* other ); void add_entry( AST* other );
// AST* body();
AST* duplicate(); AST* duplicate();
AST*& entry( u32 idx ); AST*& entry( u32 idx );
bool has_entries(); bool has_entries();
@ -2691,9 +2695,17 @@ namespace gen
return ECode::to_str( Type ); return ECode::to_str( Type );
} }
// Validation
bool validate_body(); bool validate_body();
operator Code(); operator Code();
template< class Type >
Type cast()
{
return (Type) { this };
}
# pragma endregion Member Functions # pragma endregion Member Functions
constexpr static constexpr static
@ -2733,6 +2745,53 @@ namespace gen
Using_AST_POD Using_AST_POD
}; };
struct AST_Experimental
{
using AST = AST_Experimental;
static constexpr uw ArrSpecs_Cap = sizeof( AST* ) * 9;
// Should only be used for body types.
void add( AST* other )
{
Back->Right = other;
Back = other;
}
union {
struct
{
AST* ArrExpr;
AST* Attributes;
AST* Parameters;
AST* ParameterType;
AST* ParentType;
AST* ReturnType;
AST* Specifiers;
AST* Value;
};
struct
{
AST* Left;
AST* Right;
};
struct
{
AST* Front;
AST* Back;
};
StringCached Content;
SpecifierT ArrSpecs[ArrSpecs_Cap];
};
AST* Parent;
StringCached Name;
CodeT Type;
OperatorT Op;
ModuleFlag ModuleFlags;
AccessSpec ParentAccess;
u32 NumEntries;
};
struct AST_POD struct AST_POD
{ {
Using_AST_POD Using_AST_POD
@ -2798,6 +2857,11 @@ namespace gen
Using_Code; Using_Code;
#define GEN_ENFORCE_STRONG_CODE_TYPES
#ifdef GEN_ENFORCE_STRONG_CODE_TYPES
#define operator explicit operator
#endif
operator CodeAttributes() const; operator CodeAttributes() const;
operator CodeComment() const; operator CodeComment() const;
operator CodeClass() const; operator CodeClass() const;
@ -2831,6 +2895,8 @@ namespace gen
operator CodeNamespaceBody() const; operator CodeNamespaceBody() const;
operator CodeStructBody() const; operator CodeStructBody() const;
operator CodeUnionBody() const; operator CodeUnionBody() const;
#undef operator
}; };
struct Code_POD struct Code_POD
@ -2840,23 +2906,22 @@ namespace gen
static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" ); static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" );
// Used when the its desired when omission is allowed in a definition. #ifdef GEN_ENFORCE_STRONG_CODE_TYPES
constexpr Code NoCode = { nullptr }; // Used when the its desired when omission is allowed in a definition.
#define NoCode { nullptr }
#define CodeInvalid { Code::Invalid.ast }
#else
// Used when the its desired when omission is allowed in a definition.
constexpr Code NoCode = { nullptr };
constexpr Code CodeInvalid = Code::Invalid;
#endif
#pragma region Code Types #pragma region Code Types
#ifndef GEN_ENFORCE_STRONG_CODE_TYPES
#define Define_ParentCast \ #define Define_ParentCast \
operator Code() \ operator Code() \
{ \ { \
return * rcast( Code*, this ); \ return * rcast( Code*, this ); \
} }
#else
#define Define_ParentCast \
explicit operator Code() \
{ \
return * rcast( Code*, this ); \
}
#endif
#define Define_CodeBodyType( Name ) \ #define Define_CodeBodyType( Name ) \
struct Code##Name \ struct Code##Name \
@ -2942,7 +3007,7 @@ namespace gen
Using_Code; Using_Code;
Define_ParentCast; Define_ParentCast;
Code definition(); Code symbol();
}; };
struct CodeFn struct CodeFn
@ -3086,6 +3151,7 @@ namespace gen
CodeAttributes attributes(); CodeAttributes attributes();
CodeSpecifiers specifiers(); CodeSpecifiers specifiers();
CodeType type(); CodeType type();
Code value();
}; };
#undef Define_CodeBodyType #undef Define_CodeBodyType
@ -3134,23 +3200,23 @@ namespace gen
CodeComment def_comment ( StrC content ); CodeComment def_comment ( StrC content );
CodeClass def_class( StrC name CodeClass def_class( StrC name
, CodeClassBody body = NoCode , Code body = NoCode
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default , CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
, CodeAttributes attributes = NoCode , CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
CodeEnum def_enum( StrC CodeEnum def_enum( StrC
, Code body = NoCode, Code type = NoCode , Code body = NoCode, CodeType type = NoCode
, EnumT specifier = EnumRegular, Code attributes = NoCode , EnumT specifier = EnumRegular, CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
CodeExec def_execution ( StrC content ); CodeExec def_execution ( StrC content );
CodeExtern def_extern_link( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None ); CodeExtern def_extern_link( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None );
CodeFriend def_friend ( Code symbol ); CodeFriend def_friend ( Code symbol );
CodeFn def_function( StrC name CodeFn def_function( StrC name
, Code params = NoCode, Code ret_type = NoCode, Code body = NoCode , CodeParams params = NoCode, CodeType ret_type = NoCode, CodeFnBody body = NoCode
, Code specifiers = NoCode, Code attributes = NoCode , CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
CodeInclude def_include ( StrC content ); CodeInclude def_include ( StrC content );
@ -3158,9 +3224,9 @@ namespace gen
CodeNamespace def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None ); CodeNamespace def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None );
CodeOperator def_operator( OperatorT op CodeOperator def_operator( OperatorT op
, Code params = NoCode, Code ret_type = NoCode, Code body = NoCode , CodeParams params = NoCode, CodeType ret_type = NoCode, Code body = NoCode
, Code specifiers = NoCode, Code attributes = NoCode , CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
CodeOpCast def_operator_cast( Code type, Code body = NoCode ); CodeOpCast def_operator_cast( Code type, Code body = NoCode );
@ -3168,27 +3234,27 @@ namespace gen
CodeSpecifiers def_specifier( SpecifierT specifier ); CodeSpecifiers def_specifier( SpecifierT specifier );
CodeStruct def_struct( StrC name CodeStruct def_struct( StrC name
, Code body , Code body
, Code parent = NoCode, AccessSpec access = AccessSpec::Default , CodeType parent = NoCode, AccessSpec access = AccessSpec::Default
, Code attributes = NoCode , CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
CodeTemplate def_template( Code params, Code body, ModuleFlag mflags = ModuleFlag::None ); CodeTemplate def_template( CodeParams params, Code definition, ModuleFlag mflags = ModuleFlag::None );
CodeType def_type ( StrC name, Code arrayexpr = NoCode, Code specifiers = NoCode, Code attributes = NoCode ); CodeType def_type ( StrC name, Code arrayexpr = NoCode, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode );
CodeTypedef def_typedef( StrC name, Code type, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); CodeTypedef def_typedef( StrC name, CodeType type, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
CodeUnion def_union( StrC name, Code body, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); CodeUnion def_union( StrC name, Code body, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
CodeUsing def_using( StrC name, Code type = NoCode CodeUsing def_using( StrC name, CodeType type = NoCode
, Code attributess = NoCode , CodeAttributes attributess = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
CodeUsingNamespace def_using_namespace( StrC name ); CodeUsingNamespace def_using_namespace( StrC name );
CodeVar def_variable( Code type, StrC name, Code value = NoCode CodeVar def_variable( CodeType type, StrC name, Code value = NoCode
, Code specifiers = NoCode, Code attributes = NoCode , CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries. // Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
CodeBody def_body( CodeT type ); CodeBody def_body( CodeT type );
@ -3211,7 +3277,7 @@ namespace gen
CodeNamespace def_namespace_body ( s32 num, ... ); CodeNamespace def_namespace_body ( s32 num, ... );
CodeNamespace def_namespace_body ( s32 num, Code* codes ); CodeNamespace def_namespace_body ( s32 num, Code* codes );
CodeParams def_params ( s32 num, ... ); CodeParams def_params ( s32 num, ... );
CodeParams def_params ( s32 num, Code* params ); CodeParams def_params ( s32 num, CodeParams* params );
CodeSpecifiers def_specifiers ( s32 num, ... ); CodeSpecifiers def_specifiers ( s32 num, ... );
CodeSpecifiers def_specifiers ( s32 num, SpecifierT* specs ); CodeSpecifiers def_specifiers ( s32 num, SpecifierT* specs );
CodeStructBody def_struct_body ( s32 num, ... ); CodeStructBody def_struct_body ( s32 num, ... );
@ -3439,8 +3505,6 @@ namespace gen
constexpr s32 MaxUntypedStrLength = kilobytes(640); constexpr s32 MaxUntypedStrLength = kilobytes(640);
constexpr s32 StringTable_MaxHashLength = kilobytes(1); constexpr s32 StringTable_MaxHashLength = kilobytes(1);
// Predefined Codes. Are set to readonly and are setup during gen::init()
extern CodeType t_auto; extern CodeType t_auto;
extern CodeType t_void; extern CodeType t_void;
extern CodeType t_int; extern CodeType t_int;
@ -3482,7 +3546,6 @@ namespace gen
#pragma region Inlines #pragma region Inlines
namespace gen namespace gen
{ {
inline
void AST::add_entry( AST* other ) void AST::add_entry( AST* other )
{ {
AST* to_add = other->Parent ? AST* to_add = other->Parent ?
@ -3546,7 +3609,7 @@ namespace gen
if ( index <= 0 ) if ( index <= 0 )
return * this; return * this;
return (Code){ ast->entry( index + 1 ) }; return (CodeParams){ ast->entry( index + 1 ) };
} }
inline inline
@ -3612,7 +3675,7 @@ namespace gen
Define_CodeCast( CodeUsing ); Define_CodeCast( CodeUsing );
Define_CodeCast( CodeUsingNamespace ); Define_CodeCast( CodeUsingNamespace );
Define_CodeCast( CodeVar ); Define_CodeCast( CodeVar );
Define_CodeCast( CodeBody ); Define_CodeCast( CodeBody);
Define_CodeCast( CodeClassBody ); Define_CodeCast( CodeClassBody );
Define_CodeCast( CodeEnumBody ); Define_CodeCast( CodeEnumBody );
Define_CodeCast( CodeExportBody ); Define_CodeCast( CodeExportBody );
@ -3622,7 +3685,6 @@ namespace gen
Define_CodeCast( CodeNamespaceBody ); Define_CodeCast( CodeNamespaceBody );
Define_CodeCast( CodeStructBody ); Define_CodeCast( CodeStructBody );
Define_CodeCast( CodeUnionBody ); Define_CodeCast( CodeUnionBody );
#undef Define_CodeCast #undef Define_CodeCast
#pragma endregion Operater Cast Impl #pragma endregion Operater Cast Impl
@ -3644,13 +3706,13 @@ namespace gen
default: default:
log_failure( "def_body: Invalid type %s", (char const*)ECode::to_str(type) ); log_failure( "def_body: Invalid type %s", (char const*)ECode::to_str(type) );
return Code::Invalid; return (CodeBody)Code::Invalid;
} }
Code Code
result = make_code(); result = make_code();
result->Type = type; result->Type = type;
return result; return (CodeBody)result;
} }
//! Do not use directly. Use the token_fmt macro instead. //! Do not use directly. Use the token_fmt macro instead.

View File

@ -9,14 +9,14 @@ Code gen__array_base()
{ {
Code t_allocator_info = def_type( name(AllocatorInfo) ); Code t_allocator_info = def_type( name(AllocatorInfo) );
Code header = def_struct( name(ArrayHeader), CodeStruct header = def_struct( name(ArrayHeader),
def_struct_body( args( def_struct_body( args(
def_variable( t_allocator_info, name(Allocator) ) def_variable( t_allocator_info, name(Allocator) )
, def_variable( t_uw, name(Capacity) ) , def_variable( t_uw, name(Capacity) )
, def_variable( t_uw, name(Num) ) , def_variable( t_uw, name(Num) )
))); )));
Code grow_formula = def_function( name(array_grow_formula), def_param( t_uw, name(value)), t_uw CodeFn grow_formula = def_function( name(array_grow_formula), def_param( t_uw, name(value)), t_uw
, def_execution( code( return 2 * value * 8; ) ) , def_execution( code( return 2 * value * 8; ) )
, def_specifiers( args( ESpecifier::Static_Member, ESpecifier::Inline ) ) , def_specifiers( args( ESpecifier::Static_Member, ESpecifier::Inline ) )
); );
@ -26,15 +26,15 @@ Code gen__array_base()
Code gen__array( StrC type ) Code gen__array( StrC type )
{ {
static Code t_allocator_info = def_type( name(AllocatorInfo) ); static CodeType t_allocator_info = def_type( name(AllocatorInfo) );
static Code v_nullptr = code_str( code(nullptr)); static Code v_nullptr = code_str(nullptr);
static Code spec_ct_member = def_specifiers( 2, ESpecifier::Constexpr, ESpecifier::Static_Member ); static CodeSpecifiers spec_ct_member = def_specifiers( 2, ESpecifier::Constexpr, ESpecifier::Static_Member );
static Code spec_static_inline = def_specifiers( 2, ESpecifier::Static_Member, ESpecifier::Inline ); static CodeSpecifiers spec_static_inline = def_specifiers( 2, ESpecifier::Static_Member, ESpecifier::Inline );
static Code spec_static = def_specifier( ESpecifier::Static_Member ); static CodeSpecifiers spec_static = def_specifier( ESpecifier::Static_Member );
static Code using_header = def_using( name(Header), def_type( name(ArrayHeader) ) ); static CodeUsing using_header = def_using( name(Header), def_type( name(ArrayHeader) ) );
static Code ct_grow_formula = def_variable( t_auto, name(grow_formula), code_str( code( & array_grow_formula )), spec_ct_member ); static CodeVar ct_grow_formula = def_variable( t_auto, name(grow_formula), untyped_str( code( & array_grow_formula )), spec_ct_member );
StrC name; StrC name;
{ {
@ -134,7 +134,7 @@ Code gen__array( StrC type )
, def_param( t_alias, name(value) ) , def_param( t_alias, name(value) )
); );
Code body = code_str( code( Code body = untyped_str( code(
Header& header = * get_header(); Header& header = * get_header();
if ( begin < 0 || end >= header.Num ) if ( begin < 0 || end >= header.Num )

View File

@ -140,7 +140,7 @@ Code gen__hashtable( StrC type )
char const* tmpl = stringize( char const* tmpl = stringize(
void (*) ( u64 key, <type> value ) void (*) ( u64 key, <type> value )
); );
Code value = code_str( token_fmt( "type", (StrC)t_type->to_string(), tmpl ) ); Code value = untyped_str( token_fmt( "type", (StrC)t_type->to_string(), tmpl ) );
using_map_proc = def_using ( name(MapProc), value); using_map_proc = def_using ( name(MapProc), value);
} }
@ -166,7 +166,7 @@ Code gen__hashtable( StrC type )
char const* tmpl = stringize( char const* tmpl = stringize(
void (*) ( u64 key, <type> value ) void (*) ( u64 key, <type> value )
); );
Code value = code_str( token_fmt( "type", (StrC)t_type_ptr->to_string(), tmpl ) ); Code value = untyped_str( token_fmt( "type", (StrC)t_type_ptr->to_string(), tmpl ) );
using_map_mut_proc = def_using ( name(MapMutProc), value); using_map_mut_proc = def_using ( name(MapMutProc), value);
} }

View File

@ -23,12 +23,11 @@ u32 gen_sanity_upfront()
// Class // Class
{ {
Code fwd = def_class( name(TestEmptyClass) ); CodeClass fwd = def_class( name(TestEmptyClass) );
Code empty_body; CodeClass empty_body;
{ {
Code cmt = def_comment( txt_StrC("Empty class body") ); CodeComment cmt = def_comment( txt_StrC("Empty class body") );
CodeClassBody body = def_class_body( args( cmt ) );
Code body = def_class_body( args( cmt ) );
empty_body = def_class( name(TestEmptyClass), body ); empty_body = def_class( name(TestEmptyClass), body );
} }
@ -41,8 +40,8 @@ u32 gen_sanity_upfront()
// Typedef // Typedef
{ {
Code t_unsigned_char = def_type( name(unsigned char) ); CodeType t_unsigned_char = def_type( name(unsigned char) );
Code u8_typedef = def_typedef( name(u8), t_unsigned_char ); CodeTypedef u8_typedef = def_typedef( name(u8), t_unsigned_char );
gen_sanity_file.print(u8_typedef); gen_sanity_file.print(u8_typedef);
} }
@ -52,9 +51,9 @@ u32 gen_sanity_upfront()
// Enum // Enum
{ {
Code fwd = def_enum( name(ETestEnum), NoCode, t_u8 ); Code fwd = def_enum( name(ETestEnum), NoCode, t_u8 );
Code def; CodeEnum def;
{ {
Code body = code_str( code( Code body = untyped_str( code(
A, A,
B, B,
C C
@ -87,8 +86,8 @@ u32 gen_sanity_upfront()
// Friend // Friend
{ {
Code fwd = def_class( name(TestFriendFwd)); CodeClass fwd = def_class( name(TestFriendFwd));
Code body = def_class_body( args( def_friend( fwd ) ) ); CodeClassBody body = def_class_body( args( def_friend( fwd ) ) );
gen_sanity_file.print( def_class( name(TestFriend), body ) ); gen_sanity_file.print( def_class( name(TestFriend), body ) );
} }
@ -97,10 +96,10 @@ u32 gen_sanity_upfront()
// Function // Function
{ {
Code fwd = def_function( name(test_function) ); CodeFn fwd = def_function( name(test_function) );
Code def; CodeFn def;
{ {
Code body = def_function_body( 1 CodeFnBody body = def_function_body( 1
, def_comment( txt_StrC("Empty function body") ) , def_comment( txt_StrC("Empty function body") )
); );
@ -160,7 +159,7 @@ u32 gen_sanity_upfront()
Code bitflagtest; Code bitflagtest;
{ {
Code body = def_enum_body( 1, code_str( code( Code body = def_enum_body( 1, untyped_str( code(
A = 1 << 0, A = 1 << 0,
B = 1 << 1, B = 1 << 1,
C = 1 << 2 C = 1 << 2
@ -169,15 +168,15 @@ u32 gen_sanity_upfront()
} }
Code t_bitflag = def_type( name(EBitFlagtest) ); Code t_bitflag = def_type( name(EBitFlagtest) );
Code op_fwd, op_or; CodeOperator op_fwd, op_or;
{ {
Code params = def_params( 2, CodeParams params = def_params( 2,
def_param( t_bitflag, name(a) ), def_param( t_bitflag, name(a) ),
def_param( t_bitflag, name(b) ) def_param( t_bitflag, name(b) )
); );
op_fwd = def_operator( EOperator::BOr, params, t_bitflag ); op_fwd = def_operator( EOperator::BOr, params, t_bitflag );
op_or = def_operator( EOperator::BOr, params, t_bitflag, code_str( code( op_or = def_operator( EOperator::BOr, params, t_bitflag, untyped_str( code(
return EBitFlagtest( (u8)a | (u8)b ); return EBitFlagtest( (u8)a | (u8)b );
))); )));
} }
@ -299,7 +298,7 @@ u32 gen_sanity_upfront()
// Variable // Variable
{ {
Code bss = def_variable( t_u8, name(test_variable) ); Code bss = def_variable( t_u8, name(test_variable) );
Code data = def_variable( t_u8, name(test_variable2), code_str( code( 0x12 )) ); Code data = def_variable( t_u8, name(test_variable2), untyped_str( code( 0x12 )) );
gen_sanity_file.print(bss); gen_sanity_file.print(bss);
gen_sanity_file.print(data); gen_sanity_file.print(data);