Updated AST::to_string to latest api changes with modules and attributes.

This commit is contained in:
Edward R. Gonzalez 2023-05-06 00:18:44 -04:00
parent 0edc3c57b6
commit e8264c560f
3 changed files with 419 additions and 163 deletions

View File

@ -89,7 +89,6 @@ using zpl::string_length;
using zpl::string_make; using zpl::string_make;
using zpl::str_len; using zpl::str_len;
#if __clang__ #if __clang__
# pragma clang diagnostic pop # pragma clang diagnostic pop
#endif #endif
@ -146,17 +145,17 @@ using zpl::str_len;
#define macro_expand( Expanded_ ) Expanded_ #define macro_expand( Expanded_ ) Expanded_
#define bit( Value_ ) ( 1 << Value_ ) #define bit( Value_ ) ( 1 << Value_ )
#define bitfield_is_equal( Field_, Mask_ ) ( ( (Mask_) & (Field_) ) == (Mask_) ) #define bitfield_is_equal( Type_, Field_, Mask_ ) ( (Type_(Mask_) & Type_(Field_)) == Type_(Mask_) )
#define forceinline ZPL_ALWAYS_INLINE #define forceinline ZPL_ALWAYS_INLINE
#define print_nl( _) zpl_printf("\n") #define print_nl( _) zpl_printf("\n")
#define ccast( Type_, Value_ ) * const_cast< Type_* >( & (Value_) ) #define ccast( Type_, Value_ ) * const_cast< Type_* >( & (Value_) )
#define scast( Type_, Value_ ) static_cast< Type_ >( Value_ ) #define scast( Type_, Value_ ) static_cast< Type_ >( Value_ )
#define rcast( Type_, Value_ ) reinterpret_cast< Type_ >( Value_ ) #define rcast( Type_, Value_ ) reinterpret_cast< Type_ >( Value_ )
#define pcast( Type_, Value_ ) ( * (Type_*)( & (Value_) ) ) #define pcast( Type_, Value_ ) ( * (Type_*)( & (Value_) ) )
#define txt_impl( Value_ ) #Value_ #define txt_impl( Value_ ) #Value_
#define txt( Value_ ) txt_impl( Value_ ) #define txt( Value_ ) txt_impl( Value_ )
#define txt_n_len( Value_ ) sizeof( txt_impl( Value_ ) ), txt_impl( Value_ ) #define txt_n_len( Value_ ) sizeof( txt_impl( Value_ ) ), txt_impl( Value_ )
#define do_once() \ #define do_once() \
do \ do \
{ \ { \
@ -184,6 +183,94 @@ while(0);
constexpr constexpr
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
#pragma region Memory
#pragma endregion Memory
#pragma region String
#if 0
struct String
{
struct Header
{
AllocatorInfo Allocator;
sw Length;
sw Capacity;
};
static String make ( AllocatorInfo allocator, char const* str )
{
sw length = str ? str_len( str ) : 0;
return make_length( allocator, str, length );
}
static String make_reserve( AllocatorInfo allocator, sw capacity )
{
constexpr sw header_size = sizeof( Header );
s32 alloc_size = header_size + capacity + 1;
void* allocation = alloc( allocator, alloc_size );
if ( allocation == nullptr )
return { nullptr };
mem_set( allocation, 0, alloc_size );
Header*
header = rcast(Header*, allocation);
header->Allocator = allocator;
header->Capacity = capacity;
header->Length = 0;
String result = { (char*)allocation + header_size };
return result;
}
static String make_length( AllocatorInfo allocator, char const* str, sw length );
static String fmt ( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... );
static String fmt_buf( AllocatorInfo allocator, char const* fmt, ... );
static String join( AllocatorInfo allocator, char const** parts, sw num_parts, char const* glue );
static bool are_equal( String lhs, String rhs );
void append( char c );
void append( char const* str );
void append( char const* str, sw length );
void append( const String other );
void append( char const* fmt, ... );
void append( const String other );
sw avail_space();
sw capacity();
void clear();
String duplicate( AllocatorInfo allocator );
void free();
Header& header();
sw length();
void trim( char const* cut_set );
void trim_space();
char* Data = nullptr;
};
struct String_POD
{
char* Data;
};
static_assert( sizeof( String_POD ) == sizeof( String ), "String is not a POD" );
#endif
#pragma endregion String
namespace Memory namespace Memory
{ {
constexpr uw Initial_Reserve = megabytes(10); constexpr uw Initial_Reserve = megabytes(10);

View File

@ -126,7 +126,7 @@ namespace gen
# define AST_BODY_NAMESPACE_UNALLOWED_TYPES AST_BODY_GLOBAL_UNALLOWED_TYPES # define AST_BODY_NAMESPACE_UNALLOWED_TYPES AST_BODY_GLOBAL_UNALLOWED_TYPES
# define AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES AST_BODY_GLOBAL_UNALLOWED_TYPES # define AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES AST_BODY_GLOBAL_UNALLOWED_TYPES
# define AST_BODY_STRUCT_UNALLOWED_TYPES AST_BODY_CLASS_UNALLOWED_TYPES # define AST_BODY_STRUCT_UNALLOWED_TYPES AST_BODY_CLASS_UNALLOWED_TYPES
#pragma endregion AST Body Case Macros #pragma endregion AST Body Case Macros
#pragma region AST #pragma region AST
@ -488,8 +488,31 @@ namespace gen
String AST::to_string() String AST::to_string()
{ {
# define ProcessModuleFlags() \
if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) \
result = string_append_fmt( result, "export " ); \
\
if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Import )) \
result = string_append_fmt( result, "import " ); \
\
if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Private )) \
result = string_append_fmt( result, "private " );
String result = string_make( g_allocator, "" ); String result = string_make( g_allocator, "" );
// Scope indentation.
char indent_str[128] = {0}; // Should be more than enough...
s32 tab_count = 0;
{
AST* curr_parent = Parent;
while ( Parent )
{
indent_str[tab_count] = '\t';
tab_count++;
}
}
switch ( Type ) switch ( Type )
{ {
using namespace ECode; using namespace ECode;
@ -504,6 +527,8 @@ namespace gen
case Comment: case Comment:
{ {
result = string_append_length( result, indent_str, tab_count );
static char line[MaxCommentLineLength]; static char line[MaxCommentLineLength];
s32 left = string_length( ccast(String, Content) ); s32 left = string_length( ccast(String, Content) );
@ -526,141 +551,219 @@ namespace gen
case Access_Private: case Access_Private:
case Access_Protected: case Access_Protected:
case Access_Public: case Access_Public:
result = string_append_length( result, Name, string_length( ccast(String, Name)) ) ; result = string_append_length( result, indent_str, tab_count );
result = string_append_length( result, Name, string_length( ccast(String, Name)) );
break; break;
case Attributes: case Attributes:
result = string_append_fmt( result, "%s", Content ); result = string_append_length( result, Content, string_length( ccast(String, Content)) );
case Class: case Class:
{ {
result = string_append_length( result, indent_str, tab_count );
result = string_append_fmt( result, "class"); ProcessModuleFlags();
result = string_append_fmt( result, "class ");
s32 idx = 1; s32 idx = 1;
if ( Entries[idx]->Type == Specifiers ) if ( Entries[idx]->Type == Attributes )
{ {
result = string_append_fmt( result, " %s", Entries[idx]->to_string() ); result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
idx++; idx++;
} }
result = string_append_fmt( result, " %s", Name ); result = string_append_length( result, Name, string_length( ccast(String, Name)) );
if ( parent() ) AST* parent = Entries[idx];
result = string_append_fmt( result, " : %s", parent()->to_string() );
result = string_append_fmt( result, "\n{\n%s\n};\n", body()->to_string() ); if ( parent )
{
char const* access_level = to_str( ParentAccess );
result = string_append_fmt( result, ": %s %s\n%s{\n"
, access_level
, parent
, indent_str
);
}
result = string_append_fmt( result, "%s\n%s};\n", body()->to_string(), indent_str );
} }
break; break;
case Class_Fwd: case Class_Fwd:
{ {
result = string_append_fmt( result, "class"); result = string_append_length( result, indent_str, tab_count );
s32 idx = 1; ProcessModuleFlags();
if ( Entries[idx]->Type == Specifiers ) result = string_append_fmt( result, "class %s;", Name );
{
result = string_append_fmt( result, " %s", Entries[idx]->to_string() );
idx++;
}
result = string_append_fmt( result, " %s;", Name );
} }
break; break;
case Enum: case Enum:
if ( underlying_type() ) result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
string_append_length( result, "enum ", 5);
s32 idx = 1;
if ( Entries[idx]->Type == Attributes )
{ {
result = string_append_fmt( result, "enum %s : %s\n{\n%s\n};\n" result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
idx++;
}
if ( Entries[idx]->Type == Typename)
{
result = string_append_fmt( result, "%s : %s\n%s{\n"
, Name , Name
, underlying_type()->to_string() , Entries[idx]->to_string()
, body()->to_string() , indent_str
); );
} }
else else
{ {
result = string_append_fmt( result, "enum %s\n{\n%s\n};\n" result = string_append_fmt( result, "%s\n%s{\n"
, Name , Name
, body()->to_string() , indent_str
); );
} }
result = string_append_fmt( result, "%s\n%s};"
, body()->to_string()
, indent_str
);
break; break;
case Enum_Fwd: case Enum_Fwd:
result = string_append_fmt( result, "enum %s : %s;\n", Name, underlying_type()->to_string() ); result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
result = string_append_fmt( result, "enum %s : %s;\n", Name, Entries[1]->to_string() );
break; break;
case Enum_Class: case Enum_Class:
if ( underlying_type() ) result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
result = string_append_fmt( result, "enum class " );
s32 idx = 0;
if ( Entries[idx]->Type == Attributes )
{ {
result = string_append_fmt( result, "enum class %s : %s\n{\n%s\n};\n" result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
idx++;
}
if ( Entries[idx]->Type == Typename )
{
result = string_append_fmt( result, ": %s\n%s{\n"
, Name , Name
, underlying_type()->to_string() , Entries[idx]->to_string()
, body()->to_string() , indent_str
); );
} }
else else
{ {
result = string_append_fmt( result, "enum class %s\n{\n%s\n};\n" result = string_append_fmt( result, "%s\n%s{\n"
, Name , Name
, body()->to_string() , indent_str
); );
} }
result = string_append_fmt( result, "%s\n%s};"
, body()->to_string()
, indent_str
);
break; break;
case Enum_Class_Fwd: case Enum_Class_Fwd:
result = string_append_fmt( result, "enum class %s : %s;\n", Name, underlying_type()->to_string() ); result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
result = string_append_fmt( result, "enum class " );
s32 idx = 0;
if ( Entries[idx]->Type == Attributes )
{
result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
idx++;
}
result = string_append_fmt( result, ": %s;\n", Name, Entries[idx]->to_string() );
break; break;
case Execution: case Execution:
result = string_append_fmt( result, "%s\n", Entries[0]->to_string() ); result = string_append_length( result, Content, string_length( ccast(String, Content)) );
break; break;
case Export_Body: case Export_Body:
{ {
result = string_append_fmt( result, "export\n{\n" ); result = string_append_fmt( result, "%sexport\n%s{\n", indent_str, indent_str );
s32 index = 0; s32 index = 0;
s32 left = num_entries(); s32 left = num_entries();
while ( left -- ) while ( left -- )
{ {
result = string_append_fmt( result, "%s\n", Entries[index]->to_string() ); result = string_append_fmt( result, "%s\t%s\n", indent_str, Entries[index]->to_string() );
index++; index++;
} }
result = string_append_fmt( result, "};\n" ); result = string_append_fmt( result, "%s};\n", indent_str );
} }
break; break;
case Extern_Linkage: case Extern_Linkage:
result = string_append_fmt( result, "extern %s\n{\n%s\n};\n", Name, body()->to_string() ); result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
result = string_append_fmt( result, "extern %s\n%s{\n%s\n%s};\n"
, Name
, indent_str
, body()->to_string()
, indent_str
);
break; break;
case Friend: case Friend:
result = string_append_fmt( result, "friend %s;\n", Entries[0]->to_string() ); result = string_append_fmt( result, "%sfriend %s;\n", indent_str, Entries[0]->to_string() );
break; break;
case Function: case Function:
{ {
result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
u32 idx = 1; u32 idx = 1;
u32 left = num_entries(); u32 left = num_entries();
if ( left <= 0 ) if ( Entries[idx]->Type == Attributes )
log_failure( "Code::to_string - Name: %s Type: %s, expected definition", Name, Type );
if ( Entries[idx]->Type == Specifiers )
{ {
result = string_append_fmt( result, "%s", Entries[idx]->to_string() ); result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
idx++; idx++;
left--; left--;
} }
if ( left <= 0 ) if ( Entries[idx]->Type == Specifiers )
log_failure( "Code::to_string - Name: %s Type: %s, expected return type", Name, Type ); {
result = string_append_fmt( result, "%s\n", Entries[idx]->to_string() );
idx++;
left--;
}
result = string_append_fmt( result, "\n%s %s(", Entries[idx]->to_string(), Name ); result = string_append_fmt( result, "%s %s(", Entries[idx]->to_string(), Name );
idx++; idx++;
left--; left--;
@ -675,18 +778,21 @@ namespace gen
result = string_append_fmt( result, "void" ); result = string_append_fmt( result, "void" );
} }
result = string_append_fmt( result, ")\n{\n%s\n}", body()->to_string() ); result = string_append_fmt( result, ")\n%s{\n%s\n%s}"
, indent_str
, body()->to_string()
, indent_str
);
} }
break; break;
case Function_Fwd: case Function_Fwd:
{ {
result = string_append_length( result, indent_str, tab_count );
u32 idx = 0; u32 idx = 0;
u32 left = array_count( Entries ); u32 left = array_count( Entries );
if ( left <= 0 )
log_failure( "Code::to_string - Name: %s Type: %s, expected definition", Name, Type );
if ( Entries[idx]->Type == Specifiers ) if ( Entries[idx]->Type == Specifiers )
{ {
result = string_append_fmt( result, "%s\n", Entries[idx]->to_string() ); result = string_append_fmt( result, "%s\n", Entries[idx]->to_string() );
@ -694,9 +800,6 @@ namespace gen
left--; left--;
} }
if ( left <= 0 )
log_failure( "Code::to_string - Name: %s Type: %s, expected return type", Name, Type );
result = string_append_fmt( result, "\n%s %s(", Entries[idx]->to_string(), Name ); result = string_append_fmt( result, "\n%s %s(", Entries[idx]->to_string(), Name );
idx++; idx++;
left--; left--;
@ -717,28 +820,48 @@ namespace gen
break; break;
case Module: case Module:
// TODO: Add export condition result = string_append_length( result, indent_str, tab_count );
// if ( )
ProcessModuleFlags();
result = string_append_fmt( result, "module %s", Content ); result = string_append_fmt( result, "module %s", Content );
break; break;
case Namespace: case Namespace:
result = string_append_fmt( result, "namespace %s\n{\n%s\n};\n", Name, body()->to_string() ); result = string_append_length( result, indent_str, tab_count);
ProcessModuleFlags();
result = string_append_fmt( result, "namespace %s\n%s{\n%s\n%s};\n"
, Name
, indent_str
, body()->to_string()
, indent_str
);
break; break;
case Operator: case Operator:
case Operator_Member: case Operator_Member:
{ {
result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
s32 idx = 1; s32 idx = 1;
if ( Entries[idx]->Type == Specifiers ) if ( Entries[idx]->Type == Attributes )
{ {
result = string_append_fmt( result, "%s", Entries[idx]->to_string() ); result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
idx++; idx++;
} }
result = string_append_fmt( result, "%s operator%s(", Entries[idx]->to_string(), Name ); if ( Entries[idx]->Type == Specifiers )
{
result = string_append_fmt( result, "%s\n", Entries[idx]->to_string() );
idx++;
}
result = string_append_fmt( result, "%s operator %s (", Entries[idx]->to_string(), Name );
idx++; idx++;
if ( Entries[idx]->Type == Parameters ) if ( Entries[idx]->Type == Parameters )
@ -751,13 +874,21 @@ namespace gen
result = string_append_fmt( result, "void" ); result = string_append_fmt( result, "void" );
} }
result = string_append_fmt( result, ")\n{\n%s\n}", body()->to_string() ); result = string_append_fmt( result, ")\n%s{\n%s\n%s}"
, indent_str
, body()->to_string()
, indent_str
);
} }
break; break;
case Operator_Fwd: case Operator_Fwd:
case Operator_Member_Fwd: case Operator_Member_Fwd:
{ {
result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
s32 idx; s32 idx;
if ( Entries[idx]->Type == Specifiers ) if ( Entries[idx]->Type == Specifiers )
@ -811,20 +942,28 @@ namespace gen
case Struct: case Struct:
{ {
result = string_append_fmt( result, "struct"); result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
result = string_append_fmt( result, "struct ");
s32 idx = 1; s32 idx = 1;
if ( Entries[idx]->Type == Specifiers ) if ( Entries[idx]->Type == Attributes )
{ {
result = string_append_fmt( result, " %s", Entries[idx]->to_string() ); result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
idx++; idx++;
} }
result = string_append_fmt( result, " %s", Name ); result = string_append_fmt( result, "%s ", Name );
if ( parent() ) if ( Entries[idx] )
result = string_append_fmt( result, " : %s", parent()->to_string() ); {
char const* access_str = to_str( ParentAccess );
result = string_append_fmt( result, ": %s %s", access_str, Entries[idx]->to_string() );
}
result = string_append_fmt( result, "\n{\n%s\n};\n", body()->to_string() ); result = string_append_fmt( result, "\n{\n%s\n};\n", body()->to_string() );
} }
@ -832,22 +971,30 @@ namespace gen
case Struct_Fwd: case Struct_Fwd:
{ {
result = string_append_fmt( result, "struct"); result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
result = string_append_fmt( result, "struct ");
s32 idx = 1; s32 idx = 1;
if ( Entries[idx]->Type == Specifiers ) if ( Entries[idx]->Type == Specifiers )
{ {
result = string_append_fmt( result, " %s", Entries[idx]->to_string() ); result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
idx++; idx++;
} }
result = string_append_fmt( result, " %s;", Name ); result = string_append_fmt( result, "%s;", Name );
} }
break; break;
case Variable: case Variable:
{ {
result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
s32 idx = 1; s32 idx = 1;
if ( Entries[idx]->Type == Specifiers ) if ( Entries[idx]->Type == Specifiers )
@ -864,27 +1011,87 @@ namespace gen
break; break;
case Typedef: case Typedef:
// TODO: Check for array expression result = string_append_length( result, indent_str, tab_count );
result = string_append_fmt( result, "typedef %s %s", Entries[0]->to_string(), Name ); ProcessModuleFlags();
AST* type = Entries[0];
if ( Entries[1] && Entries[1]->Type == Attributes )
{
result = string_append_fmt( result, "%s ", Entries[1]->to_string() );
}
result = string_append_fmt( result, "typedef %s %s", type->to_string(), Name );
if ( type->Entries[1] )
{
result = string_append_fmt( result, "[%s];", type->Entries[1]->to_string() );
}
else
{
result = string_append_length( result, ";", 1);
}
break; break;
case Typename: case Typename:
result = string_append_fmt( result, "%s %s", Name, Entries[0]->to_string() ); if ( Entries[0] )
{
result = string_append_fmt( result, "%s %s", Name, Entries[0]->to_string() );
}
else
{
result = string_append_fmt( result, "%s", Name );
}
break; break;
case Union: case Union:
result = string_append_fmt( result, "union %s\n{\n%s\n};\n", Name, body()->to_string() ); result = string_append_length( result, indent_str, tab_count );
ProcessModuleFlags();
s32 idx = 0;
result = string_append_length( result, "union ", 6 );
if ( Entries[idx]->Type == Attributes )
{
result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
idx++;
}
result = string_append_fmt( result, "%s\n%s{\n%s\n%s};\n"
, Name
, indent_str
, body()->to_string()
, indent_str
);
break; break;
case Using: case Using:
// TODO: Check for array expression result = string_append_length( result, indent_str, tab_count );
if ( Entries[0] ) ProcessModuleFlags();
result = string_append_fmt( result, "using %s = %s", Name, Entries[0] );
AST* type = Entries[0];
if ( Entries[1] && Entries[1]->Type == Attributes )
{
result = string_append_fmt( result, "%s ", Entries[1]->to_string() );
}
if ( type )
{
result = string_append_fmt( result, "using %s = %s", Name, type->to_string() );
if ( type->Entries[1] )
result = string_append_fmt( result, "[%s]", type->Entries[1]->to_string() );
}
else else
result = string_append_fmt( result, "using %s", Name ); result = string_append_fmt( result, "using %s", Name );
result = string_append_fmt( result, ";" );
break; break;
case Using_Namespace: case Using_Namespace:
@ -904,7 +1111,7 @@ namespace gen
s32 left = num_entries(); s32 left = num_entries();
while ( left -- ) while ( left -- )
{ {
result = string_append_fmt( result, "%s\n", Entries[index]->to_string() ); result = string_append_fmt( result, "%s%s\n", indent_str, Entries[index]->to_string() );
index++; index++;
} }
} }
@ -912,6 +1119,8 @@ namespace gen
} }
return result; return result;
#undef ProcessModuleFlags
} }
#pragma endregion AST #pragma endregion AST
@ -1128,12 +1337,13 @@ namespace gen
result->Content = nullptr; result->Content = nullptr;
result->Parent = nullptr; result->Parent = nullptr;
result->Name = nullptr; result->Name = nullptr;
result->Comment = nullptr;
result->Type = ECode::Invalid; result->Type = ECode::Invalid;
result->Op = EOperator::Invalid; result->Op = EOperator::Invalid;
result->ModuleFlags = ModuleFlag::Invalid;
result->ParentAccess = AccessSpec::Invalid;
result->StaticIndex = 0;
result->Readonly = false; result->Readonly = false;
result->DynamicEntries = false; result->DynamicEntries = false;
result->StaticIndex = 0;
return result; return result;
} }
@ -1621,7 +1831,7 @@ namespace gen
Code def_class( s32 length, char const* name Code def_class( s32 length, char const* name
, Code body , Code body
, Code parent, AccessSpec parent_access , Code parent, AccessSpec parent_access
, Code specifiers, Code attributes , Code attributes
, ModuleFlag mflags ) , ModuleFlag mflags )
{ {
using namespace ECode; using namespace ECode;
@ -1634,15 +1844,9 @@ namespace gen
return Code::Invalid; return Code::Invalid;
} }
if ( specifiers && specifiers->Type != Specifiers ) if ( parent && parent->Type != Class || parent->Type != Struct || parent->Type != Typename || parent->Type != Untyped )
{ {
log_failure( "gen::def_class: specifiers was not a 'Specifiers' type: %s", specifiers->debug_str() ); log_failure( "gen::def_class: parent provided is not type 'Class', 'Struct', 'Typeanme', or 'Untyped': %s", parent->debug_str() );
return Code::Invalid;
}
if ( parent && parent->Type != Class || parent->Type != Struct )
{
log_failure( "gen::def_class: parent provided is not type 'Class' or 'Struct': %s", parent->debug_str() );
return Code::Invalid; return Code::Invalid;
} }
@ -1675,11 +1879,11 @@ namespace gen
if ( attributes ) if ( attributes )
result->add_entry( attributes ); result->add_entry( attributes );
if ( specifiers )
result->add_entry( specifiers );
if ( parent ) if ( parent )
{
result->ParentAccess = parent_access;
result->add_entry( parent ); result->add_entry( parent );
}
result.lock(); result.lock();
return result; return result;
@ -1742,7 +1946,7 @@ namespace gen
{ {
result->add_entry( type ); result->add_entry( type );
} }
else if ( result->Type == Enum_Class_Fwd || result->Type == Enum_Fwd ) else if ( result->Type != Enum_Class_Fwd && result->Type != Enum_Fwd )
{ {
log_failure( "gen::def_enum: enum forward declaration must have an underlying type" ); log_failure( "gen::def_enum: enum forward declaration must have an underlying type" );
return Code::Invalid; return Code::Invalid;
@ -2068,8 +2272,8 @@ namespace gen
Code def_struct( u32 length, char const* name Code def_struct( u32 length, char const* name
, Code body , Code body
, Code parent, Code parent_access , Code parent, AccessSpec parent_access
, Code specifiers, Code attributes , Code attributes
, ModuleFlag mflags ) , ModuleFlag mflags )
{ {
using namespace ECode; using namespace ECode;
@ -2082,12 +2286,6 @@ namespace gen
return Code::Invalid; return Code::Invalid;
} }
if ( specifiers && specifiers->Type != Specifiers )
{
log_failure( "gen::def_struct: specifiers was not a `Specifiers` type" );
return Code::Invalid;
}
if ( parent && parent->Type != Struct ) if ( parent && parent->Type != Struct )
{ {
log_failure( "gen::def_struct: parent was not a `Struct` type" ); log_failure( "gen::def_struct: parent was not a `Struct` type" );
@ -2118,11 +2316,11 @@ namespace gen
if ( attributes ) if ( attributes )
result->add_entry( attributes ); result->add_entry( attributes );
if ( specifiers )
result->add_entry( specifiers );
if ( parent ) if ( parent )
{
result->ParentAccess = parent_access;
result->add_entry( parent ); result->add_entry( parent );
}
result.lock(); result.lock();
return result; return result;
@ -2237,8 +2435,9 @@ namespace gen
} }
Code Code
result = make_code(); result = make_code();
result->Name = get_cached_string( name, length ); result->Name = get_cached_string( name, length );
result->ModuleFlags = mflags;
switch ( specifier ) switch ( specifier )
{ {
@ -2254,6 +2453,9 @@ namespace gen
break; break;
} }
if ( attributes )
result->add_entry( attributes );
result.lock(); result.lock();
return result; return result;
} }
@ -3218,14 +3420,6 @@ namespace gen
#ifdef GEN_FEATURE_PARSING #ifdef GEN_FEATURE_PARSING
/* /*
These constructors are the most implementation intensive other than the edtior or scanner. These constructors are the most implementation intensive other than the edtior or scanner.
The current implementation is very convervative and does not use a lexer to process the input first.
Instead, it just sifts through the content directly looking for the syntax pattern for the code type
and then constructs the AST after.
Eventually I will problably end up using a dedicated lexer for parser constructors to lower the sloc.
It uses the upfront constructors to help keep code from getitng to large since the target is to keep the sloc low
*/ */
namespace Parser namespace Parser
@ -4151,9 +4345,7 @@ namespace gen
{ {
case ESpecifier::Constexpr: case ESpecifier::Constexpr:
case ESpecifier::Constinit: case ESpecifier::Constinit:
case ESpecifier::Export:
case ESpecifier::External_Linkage: case ESpecifier::External_Linkage:
case ESpecifier::Import:
case ESpecifier::Local_Persist: case ESpecifier::Local_Persist:
case ESpecifier::Mutable: case ESpecifier::Mutable:
case ESpecifier::Static_Member: case ESpecifier::Static_Member:
@ -4340,10 +4532,6 @@ namespace gen
member = parse_variable( toks, context ); member = parse_variable( toks, context );
break; break;
case TokType::Spec_API:
log_failure( "gen::%s: %s not allowed in function body", context, str_tok_type( currtok.Type ) );
return Code::Invalid;
default: default:
Token untyped_tok = currtok; Token untyped_tok = currtok;
@ -4395,9 +4583,6 @@ namespace gen
switch ( spec ) switch ( spec )
{ {
case ESpecifier::API_Macro:
case ESpecifier::API_Export:
case ESpecifier::API_Import:
case ESpecifier::External_Linkage: case ESpecifier::External_Linkage:
case ESpecifier::Local_Persist: case ESpecifier::Local_Persist:
case ESpecifier::Mutable: case ESpecifier::Mutable:
@ -4685,9 +4870,6 @@ namespace gen
switch ( spec ) switch ( spec )
{ {
case ESpecifier::API_Macro:
case ESpecifier::API_Export:
case ESpecifier::API_Import:
case ESpecifier::Constexpr: case ESpecifier::Constexpr:
case ESpecifier::External_Linkage: case ESpecifier::External_Linkage:
case ESpecifier::Local_Persist: case ESpecifier::Local_Persist:

View File

@ -291,6 +291,7 @@ namespace gen
enum class AccessSpec : u32 enum class AccessSpec : u32
{ {
Default,
Public, Public,
Protected, Protected,
Private, Private,
@ -304,6 +305,7 @@ namespace gen
{ {
local_persist local_persist
char const* lookup[ (u32)AccessSpec::Num_AccessSpec ] = { char const* lookup[ (u32)AccessSpec::Num_AccessSpec ] = {
"",
"private", "private",
"protected", "protected",
"public", "public",
@ -420,22 +422,6 @@ namespace gen
return DynamicEntries ? array_count(Entries) : StaticIndex; return DynamicEntries ? array_count(Entries) : StaticIndex;
} }
// Class/Struct
inline
AST* parent()
{
return Entries[1];
}
// Enum
inline
AST* underlying_type()
{
return Entries[1];
}
// Parameter // Parameter
bool add_param( AST* type, s32 length, char const* name ); bool add_param( AST* type, s32 length, char const* name );
@ -533,7 +519,6 @@ namespace gen
, Readonly ? "true" : "false" , Readonly ? "true" : "false"
, Parent ? Parent->Name : "" , Parent ? Parent->Name : ""
, Name ? Name : "" , Name ? Name : ""
, Comment ? Comment : ""
); );
} }
@ -554,9 +539,10 @@ namespace gen
- sizeof(CodeT) // Type - sizeof(CodeT) // Type
- sizeof(OperatorT) // Op - sizeof(OperatorT) // Op
- sizeof(ModuleFlag) // ModuleFlags - sizeof(ModuleFlag) // ModuleFlags
- sizeof(AccessSpec) // ParentAccess
- sizeof(u32) // StaticIndex - sizeof(u32) // StaticIndex
- sizeof(bool) * 2 // Readonly, DynamicEntries - sizeof(bool) * 2 // Readonly, DynamicEntries
- sizeof(u8) * 6 ) // _Align_Pad - sizeof(u8) * 2 ) // _Align_Pad
/ sizeof(AST*); / sizeof(AST*);
constexpr static constexpr static
@ -574,10 +560,11 @@ namespace gen
CodeT Type; \ CodeT Type; \
OperatorT Op; \ OperatorT Op; \
ModuleFlag ModuleFlags; \ ModuleFlag ModuleFlags; \
AccessSpec ParentAccess; \
u32 StaticIndex; \ u32 StaticIndex; \
bool Readonly; \ bool Readonly; \
bool DynamicEntries; \ bool DynamicEntries; \
u8 _Align_Pad[6]; u8 _Align_Pad[2];
Using_Code_POD Using_Code_POD
}; };
@ -785,8 +772,8 @@ namespace gen
Code def_class( s32 length, char const* name Code def_class( s32 length, char const* name
, Code body = NoCode , Code body = NoCode
, Code parent = NoCode, AccessSpec access = AccessSpec::Public , Code parent = NoCode, AccessSpec access = AccessSpec::Public
, Code specifiers = NoCode, Code attributes = NoCode , Code attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
Code def_enum( s32 length, char const* name Code def_enum( s32 length, char const* name
@ -816,10 +803,10 @@ namespace gen
Code def_specifier( SpecifierT specifier ); Code def_specifier( SpecifierT specifier );
Code def_struct( s32 length, char const* name Code def_struct( s32 length, char const* name
, Code body , Code body
, Code parent = NoCode, AccessSpec access , Code parent = NoCode, AccessSpec access = AccessSpec::Public
, Code specifiers = NoCode, Code attributes = NoCode , Code attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
Code def_typedef( s32 length, char const* name, Code type, 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_type ( s32 length, char const* name, Code arrayexpr = NoCode, Code specifiers = NoCode );