mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 07:44:45 -08:00
Updated AST::to_string to latest api changes with modules and attributes.
This commit is contained in:
parent
0edc3c57b6
commit
e8264c560f
@ -89,7 +89,6 @@ using zpl::string_length;
|
||||
using zpl::string_make;
|
||||
using zpl::str_len;
|
||||
|
||||
|
||||
#if __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
@ -146,17 +145,17 @@ using zpl::str_len;
|
||||
|
||||
#define macro_expand( Expanded_ ) Expanded_
|
||||
|
||||
#define bit( Value_ ) ( 1 << Value_ )
|
||||
#define bitfield_is_equal( Field_, Mask_ ) ( ( (Mask_) & (Field_) ) == (Mask_) )
|
||||
#define forceinline ZPL_ALWAYS_INLINE
|
||||
#define print_nl( _) zpl_printf("\n")
|
||||
#define ccast( Type_, Value_ ) * const_cast< Type_* >( & (Value_) )
|
||||
#define scast( Type_, Value_ ) static_cast< Type_ >( Value_ )
|
||||
#define rcast( Type_, Value_ ) reinterpret_cast< Type_ >( Value_ )
|
||||
#define pcast( Type_, Value_ ) ( * (Type_*)( & (Value_) ) )
|
||||
#define txt_impl( Value_ ) #Value_
|
||||
#define txt( Value_ ) txt_impl( Value_ )
|
||||
#define txt_n_len( Value_ ) sizeof( txt_impl( Value_ ) ), txt_impl( Value_ )
|
||||
#define bit( Value_ ) ( 1 << Value_ )
|
||||
#define bitfield_is_equal( Type_, Field_, Mask_ ) ( (Type_(Mask_) & Type_(Field_)) == Type_(Mask_) )
|
||||
#define forceinline ZPL_ALWAYS_INLINE
|
||||
#define print_nl( _) zpl_printf("\n")
|
||||
#define ccast( Type_, Value_ ) * const_cast< Type_* >( & (Value_) )
|
||||
#define scast( Type_, Value_ ) static_cast< Type_ >( Value_ )
|
||||
#define rcast( Type_, Value_ ) reinterpret_cast< Type_ >( Value_ )
|
||||
#define pcast( Type_, Value_ ) ( * (Type_*)( & (Value_) ) )
|
||||
#define txt_impl( Value_ ) #Value_
|
||||
#define txt( Value_ ) txt_impl( Value_ )
|
||||
#define txt_n_len( Value_ ) sizeof( txt_impl( Value_ ) ), txt_impl( Value_ )
|
||||
#define do_once() \
|
||||
do \
|
||||
{ \
|
||||
@ -184,6 +183,94 @@ while(0);
|
||||
constexpr
|
||||
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
|
||||
{
|
||||
constexpr uw Initial_Reserve = megabytes(10);
|
||||
|
434
project/gen.cpp
434
project/gen.cpp
@ -126,7 +126,7 @@ namespace gen
|
||||
# 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_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 region AST
|
||||
@ -488,8 +488,31 @@ namespace gen
|
||||
|
||||
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, "" );
|
||||
|
||||
// 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 )
|
||||
{
|
||||
using namespace ECode;
|
||||
@ -504,6 +527,8 @@ namespace gen
|
||||
|
||||
case Comment:
|
||||
{
|
||||
result = string_append_length( result, indent_str, tab_count );
|
||||
|
||||
static char line[MaxCommentLineLength];
|
||||
|
||||
s32 left = string_length( ccast(String, Content) );
|
||||
@ -526,141 +551,219 @@ namespace gen
|
||||
case Access_Private:
|
||||
case Access_Protected:
|
||||
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;
|
||||
|
||||
case Attributes:
|
||||
result = string_append_fmt( result, "%s", Content );
|
||||
result = string_append_length( result, Content, string_length( ccast(String, Content)) );
|
||||
|
||||
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;
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
result = string_append_fmt( result, " %s", Name );
|
||||
result = string_append_length( result, Name, string_length( ccast(String, Name)) );
|
||||
|
||||
if ( parent() )
|
||||
result = string_append_fmt( result, " : %s", parent()->to_string() );
|
||||
AST* parent = Entries[idx];
|
||||
|
||||
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;
|
||||
|
||||
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, " %s", Entries[idx]->to_string() );
|
||||
idx++;
|
||||
}
|
||||
|
||||
result = string_append_fmt( result, " %s;", Name );
|
||||
result = string_append_fmt( result, "class %s;", Name );
|
||||
}
|
||||
break;
|
||||
|
||||
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
|
||||
, underlying_type()->to_string()
|
||||
, body()->to_string()
|
||||
, Entries[idx]->to_string()
|
||||
, indent_str
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = string_append_fmt( result, "enum %s\n{\n%s\n};\n"
|
||||
result = string_append_fmt( result, "%s\n%s{\n"
|
||||
, Name
|
||||
, body()->to_string()
|
||||
, indent_str
|
||||
);
|
||||
}
|
||||
|
||||
result = string_append_fmt( result, "%s\n%s};"
|
||||
, body()->to_string()
|
||||
, indent_str
|
||||
);
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
, underlying_type()->to_string()
|
||||
, body()->to_string()
|
||||
, Entries[idx]->to_string()
|
||||
, indent_str
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = string_append_fmt( result, "enum class %s\n{\n%s\n};\n"
|
||||
result = string_append_fmt( result, "%s\n%s{\n"
|
||||
, Name
|
||||
, body()->to_string()
|
||||
, indent_str
|
||||
);
|
||||
}
|
||||
|
||||
result = string_append_fmt( result, "%s\n%s};"
|
||||
, body()->to_string()
|
||||
, indent_str
|
||||
);
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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 left = num_entries();
|
||||
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++;
|
||||
}
|
||||
|
||||
result = string_append_fmt( result, "};\n" );
|
||||
result = string_append_fmt( result, "%s};\n", indent_str );
|
||||
}
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
case Function:
|
||||
{
|
||||
result = string_append_length( result, indent_str, tab_count );
|
||||
|
||||
ProcessModuleFlags();
|
||||
|
||||
u32 idx = 1;
|
||||
u32 left = num_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 == Attributes )
|
||||
{
|
||||
result = string_append_fmt( result, "%s", Entries[idx]->to_string() );
|
||||
result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
|
||||
idx++;
|
||||
left--;
|
||||
}
|
||||
|
||||
if ( left <= 0 )
|
||||
log_failure( "Code::to_string - Name: %s Type: %s, expected return type", Name, Type );
|
||||
if ( Entries[idx]->Type == Specifiers )
|
||||
{
|
||||
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++;
|
||||
left--;
|
||||
|
||||
@ -675,18 +778,21 @@ namespace gen
|
||||
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;
|
||||
|
||||
case Function_Fwd:
|
||||
{
|
||||
result = string_append_length( result, indent_str, tab_count );
|
||||
|
||||
u32 idx = 0;
|
||||
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 )
|
||||
{
|
||||
result = string_append_fmt( result, "%s\n", Entries[idx]->to_string() );
|
||||
@ -694,9 +800,6 @@ namespace gen
|
||||
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 );
|
||||
idx++;
|
||||
left--;
|
||||
@ -717,28 +820,48 @@ namespace gen
|
||||
break;
|
||||
|
||||
case Module:
|
||||
// TODO: Add export condition
|
||||
// if ( )
|
||||
result = string_append_length( result, indent_str, tab_count );
|
||||
|
||||
ProcessModuleFlags();
|
||||
|
||||
result = string_append_fmt( result, "module %s", Content );
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case Operator:
|
||||
case Operator_Member:
|
||||
{
|
||||
result = string_append_length( result, indent_str, tab_count );
|
||||
|
||||
ProcessModuleFlags();
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
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++;
|
||||
|
||||
if ( Entries[idx]->Type == Parameters )
|
||||
@ -751,13 +874,21 @@ namespace gen
|
||||
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;
|
||||
|
||||
case Operator_Fwd:
|
||||
case Operator_Member_Fwd:
|
||||
{
|
||||
result = string_append_length( result, indent_str, tab_count );
|
||||
|
||||
ProcessModuleFlags();
|
||||
|
||||
s32 idx;
|
||||
|
||||
if ( Entries[idx]->Type == Specifiers )
|
||||
@ -811,20 +942,28 @@ namespace gen
|
||||
|
||||
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;
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
result = string_append_fmt( result, " %s", Name );
|
||||
result = string_append_fmt( result, "%s ", Name );
|
||||
|
||||
if ( parent() )
|
||||
result = string_append_fmt( result, " : %s", parent()->to_string() );
|
||||
if ( Entries[idx] )
|
||||
{
|
||||
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() );
|
||||
}
|
||||
@ -832,22 +971,30 @@ namespace gen
|
||||
|
||||
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;
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
result = string_append_fmt( result, " %s;", Name );
|
||||
result = string_append_fmt( result, "%s;", Name );
|
||||
}
|
||||
break;
|
||||
|
||||
case Variable:
|
||||
{
|
||||
result = string_append_length( result, indent_str, tab_count );
|
||||
|
||||
ProcessModuleFlags();
|
||||
|
||||
s32 idx = 1;
|
||||
|
||||
if ( Entries[idx]->Type == Specifiers )
|
||||
@ -864,27 +1011,87 @@ namespace gen
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
case Using:
|
||||
// TODO: Check for array expression
|
||||
result = string_append_length( result, indent_str, tab_count );
|
||||
|
||||
if ( Entries[0] )
|
||||
result = string_append_fmt( result, "using %s = %s", Name, Entries[0] );
|
||||
ProcessModuleFlags();
|
||||
|
||||
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
|
||||
result = string_append_fmt( result, "using %s", Name );
|
||||
|
||||
result = string_append_fmt( result, ";" );
|
||||
break;
|
||||
|
||||
case Using_Namespace:
|
||||
@ -904,7 +1111,7 @@ namespace gen
|
||||
s32 left = num_entries();
|
||||
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++;
|
||||
}
|
||||
}
|
||||
@ -912,6 +1119,8 @@ namespace gen
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
#undef ProcessModuleFlags
|
||||
}
|
||||
#pragma endregion AST
|
||||
|
||||
@ -1128,12 +1337,13 @@ namespace gen
|
||||
result->Content = nullptr;
|
||||
result->Parent = nullptr;
|
||||
result->Name = nullptr;
|
||||
result->Comment = nullptr;
|
||||
result->Type = ECode::Invalid;
|
||||
result->Op = EOperator::Invalid;
|
||||
result->ModuleFlags = ModuleFlag::Invalid;
|
||||
result->ParentAccess = AccessSpec::Invalid;
|
||||
result->StaticIndex = 0;
|
||||
result->Readonly = false;
|
||||
result->DynamicEntries = false;
|
||||
result->StaticIndex = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1621,7 +1831,7 @@ namespace gen
|
||||
Code def_class( s32 length, char const* name
|
||||
, Code body
|
||||
, Code parent, AccessSpec parent_access
|
||||
, Code specifiers, Code attributes
|
||||
, Code attributes
|
||||
, ModuleFlag mflags )
|
||||
{
|
||||
using namespace ECode;
|
||||
@ -1634,15 +1844,9 @@ namespace gen
|
||||
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() );
|
||||
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() );
|
||||
log_failure( "gen::def_class: parent provided is not type 'Class', 'Struct', 'Typeanme', or 'Untyped': %s", parent->debug_str() );
|
||||
return Code::Invalid;
|
||||
}
|
||||
|
||||
@ -1675,11 +1879,11 @@ namespace gen
|
||||
if ( attributes )
|
||||
result->add_entry( attributes );
|
||||
|
||||
if ( specifiers )
|
||||
result->add_entry( specifiers );
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
result->ParentAccess = parent_access;
|
||||
result->add_entry( parent );
|
||||
}
|
||||
|
||||
result.lock();
|
||||
return result;
|
||||
@ -1742,7 +1946,7 @@ namespace gen
|
||||
{
|
||||
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" );
|
||||
return Code::Invalid;
|
||||
@ -2068,8 +2272,8 @@ namespace gen
|
||||
|
||||
Code def_struct( u32 length, char const* name
|
||||
, Code body
|
||||
, Code parent, Code parent_access
|
||||
, Code specifiers, Code attributes
|
||||
, Code parent, AccessSpec parent_access
|
||||
, Code attributes
|
||||
, ModuleFlag mflags )
|
||||
{
|
||||
using namespace ECode;
|
||||
@ -2082,12 +2286,6 @@ namespace gen
|
||||
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 )
|
||||
{
|
||||
log_failure( "gen::def_struct: parent was not a `Struct` type" );
|
||||
@ -2118,11 +2316,11 @@ namespace gen
|
||||
if ( attributes )
|
||||
result->add_entry( attributes );
|
||||
|
||||
if ( specifiers )
|
||||
result->add_entry( specifiers );
|
||||
|
||||
if ( parent )
|
||||
{
|
||||
result->ParentAccess = parent_access;
|
||||
result->add_entry( parent );
|
||||
}
|
||||
|
||||
result.lock();
|
||||
return result;
|
||||
@ -2237,8 +2435,9 @@ namespace gen
|
||||
}
|
||||
|
||||
Code
|
||||
result = make_code();
|
||||
result->Name = get_cached_string( name, length );
|
||||
result = make_code();
|
||||
result->Name = get_cached_string( name, length );
|
||||
result->ModuleFlags = mflags;
|
||||
|
||||
switch ( specifier )
|
||||
{
|
||||
@ -2254,6 +2453,9 @@ namespace gen
|
||||
break;
|
||||
}
|
||||
|
||||
if ( attributes )
|
||||
result->add_entry( attributes );
|
||||
|
||||
result.lock();
|
||||
return result;
|
||||
}
|
||||
@ -3218,14 +3420,6 @@ namespace gen
|
||||
#ifdef GEN_FEATURE_PARSING
|
||||
/*
|
||||
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
|
||||
@ -4151,9 +4345,7 @@ namespace gen
|
||||
{
|
||||
case ESpecifier::Constexpr:
|
||||
case ESpecifier::Constinit:
|
||||
case ESpecifier::Export:
|
||||
case ESpecifier::External_Linkage:
|
||||
case ESpecifier::Import:
|
||||
case ESpecifier::Local_Persist:
|
||||
case ESpecifier::Mutable:
|
||||
case ESpecifier::Static_Member:
|
||||
@ -4340,10 +4532,6 @@ namespace gen
|
||||
member = parse_variable( toks, context );
|
||||
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:
|
||||
Token untyped_tok = currtok;
|
||||
|
||||
@ -4395,9 +4583,6 @@ namespace gen
|
||||
|
||||
switch ( spec )
|
||||
{
|
||||
case ESpecifier::API_Macro:
|
||||
case ESpecifier::API_Export:
|
||||
case ESpecifier::API_Import:
|
||||
case ESpecifier::External_Linkage:
|
||||
case ESpecifier::Local_Persist:
|
||||
case ESpecifier::Mutable:
|
||||
@ -4685,9 +4870,6 @@ namespace gen
|
||||
|
||||
switch ( spec )
|
||||
{
|
||||
case ESpecifier::API_Macro:
|
||||
case ESpecifier::API_Export:
|
||||
case ESpecifier::API_Import:
|
||||
case ESpecifier::Constexpr:
|
||||
case ESpecifier::External_Linkage:
|
||||
case ESpecifier::Local_Persist:
|
||||
|
@ -291,6 +291,7 @@ namespace gen
|
||||
|
||||
enum class AccessSpec : u32
|
||||
{
|
||||
Default,
|
||||
Public,
|
||||
Protected,
|
||||
Private,
|
||||
@ -304,6 +305,7 @@ namespace gen
|
||||
{
|
||||
local_persist
|
||||
char const* lookup[ (u32)AccessSpec::Num_AccessSpec ] = {
|
||||
"",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
@ -420,22 +422,6 @@ namespace gen
|
||||
return DynamicEntries ? array_count(Entries) : StaticIndex;
|
||||
}
|
||||
|
||||
// Class/Struct
|
||||
|
||||
inline
|
||||
AST* parent()
|
||||
{
|
||||
return Entries[1];
|
||||
}
|
||||
|
||||
// Enum
|
||||
|
||||
inline
|
||||
AST* underlying_type()
|
||||
{
|
||||
return Entries[1];
|
||||
}
|
||||
|
||||
// Parameter
|
||||
|
||||
bool add_param( AST* type, s32 length, char const* name );
|
||||
@ -533,7 +519,6 @@ namespace gen
|
||||
, Readonly ? "true" : "false"
|
||||
, Parent ? Parent->Name : ""
|
||||
, Name ? Name : ""
|
||||
, Comment ? Comment : ""
|
||||
);
|
||||
}
|
||||
|
||||
@ -554,9 +539,10 @@ namespace gen
|
||||
- sizeof(CodeT) // Type
|
||||
- sizeof(OperatorT) // Op
|
||||
- sizeof(ModuleFlag) // ModuleFlags
|
||||
- sizeof(AccessSpec) // ParentAccess
|
||||
- sizeof(u32) // StaticIndex
|
||||
- sizeof(bool) * 2 // Readonly, DynamicEntries
|
||||
- sizeof(u8) * 6 ) // _Align_Pad
|
||||
- sizeof(u8) * 2 ) // _Align_Pad
|
||||
/ sizeof(AST*);
|
||||
|
||||
constexpr static
|
||||
@ -574,10 +560,11 @@ namespace gen
|
||||
CodeT Type; \
|
||||
OperatorT Op; \
|
||||
ModuleFlag ModuleFlags; \
|
||||
AccessSpec ParentAccess; \
|
||||
u32 StaticIndex; \
|
||||
bool Readonly; \
|
||||
bool DynamicEntries; \
|
||||
u8 _Align_Pad[6];
|
||||
u8 _Align_Pad[2];
|
||||
|
||||
Using_Code_POD
|
||||
};
|
||||
@ -785,8 +772,8 @@ namespace gen
|
||||
|
||||
Code def_class( s32 length, char const* name
|
||||
, Code body = NoCode
|
||||
, Code parent = NoCode, AccessSpec access = AccessSpec::Public
|
||||
, Code specifiers = NoCode, Code attributes = NoCode
|
||||
, Code parent = NoCode, AccessSpec access = AccessSpec::Public
|
||||
, Code attributes = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None );
|
||||
|
||||
Code def_enum( s32 length, char const* name
|
||||
@ -816,10 +803,10 @@ namespace gen
|
||||
Code def_specifier( SpecifierT specifier );
|
||||
|
||||
Code def_struct( s32 length, char const* name
|
||||
, Code body
|
||||
, Code parent = NoCode, AccessSpec access
|
||||
, Code specifiers = NoCode, Code attributes = NoCode
|
||||
, ModuleFlag mflags = ModuleFlag::None );
|
||||
, 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 );
|
||||
|
Loading…
Reference in New Issue
Block a user