mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 15:54: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::string_make;
|
||||||
using zpl::str_len;
|
using zpl::str_len;
|
||||||
|
|
||||||
|
|
||||||
#if __clang__
|
#if __clang__
|
||||||
# pragma clang diagnostic pop
|
# pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
@ -147,7 +146,7 @@ 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_) )
|
||||||
@ -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);
|
||||||
|
398
project/gen.cpp
398
project/gen.cpp
@ -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, indent_str, tab_count );
|
||||||
result = string_append_length( result, Name, string_length( ccast(String, Name)) );
|
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 );
|
||||||
|
|
||||||
|
ProcessModuleFlags();
|
||||||
|
|
||||||
result = string_append_fmt( result, "class ");
|
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 );
|
||||||
|
|
||||||
|
ProcessModuleFlags();
|
||||||
|
|
||||||
|
result = string_append_fmt( result, "class %s;", Name );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Enum:
|
||||||
|
result = string_append_length( result, indent_str, tab_count );
|
||||||
|
|
||||||
|
ProcessModuleFlags();
|
||||||
|
|
||||||
|
string_append_length( result, "enum ", 5);
|
||||||
|
|
||||||
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 );
|
if ( Entries[idx]->Type == Typename)
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Enum:
|
|
||||||
if ( underlying_type() )
|
|
||||||
{
|
{
|
||||||
result = string_append_fmt( result, "enum %s : %s\n{\n%s\n};\n"
|
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,24 +820,44 @@ 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 == Attributes )
|
||||||
|
{
|
||||||
|
result = string_append_fmt( result, "%s ", Entries[idx]->to_string() );
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
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\n", Entries[idx]->to_string() );
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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,11 +942,15 @@ namespace gen
|
|||||||
|
|
||||||
case Struct:
|
case Struct:
|
||||||
{
|
{
|
||||||
|
result = string_append_length( result, indent_str, tab_count );
|
||||||
|
|
||||||
|
ProcessModuleFlags();
|
||||||
|
|
||||||
result = string_append_fmt( result, "struct ");
|
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++;
|
||||||
@ -823,8 +958,12 @@ namespace gen
|
|||||||
|
|
||||||
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,6 +971,10 @@ namespace gen
|
|||||||
|
|
||||||
case Struct_Fwd:
|
case Struct_Fwd:
|
||||||
{
|
{
|
||||||
|
result = string_append_length( result, indent_str, tab_count );
|
||||||
|
|
||||||
|
ProcessModuleFlags();
|
||||||
|
|
||||||
result = string_append_fmt( result, "struct ");
|
result = string_append_fmt( result, "struct ");
|
||||||
|
|
||||||
s32 idx = 1;
|
s32 idx = 1;
|
||||||
@ -848,6 +991,10 @@ namespace gen
|
|||||||
|
|
||||||
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:
|
||||||
|
if ( Entries[0] )
|
||||||
|
{
|
||||||
result = string_append_fmt( result, "%s %s", Name, Entries[0]->to_string() );
|
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;
|
||||||
@ -2239,6 +2437,7 @@ 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:
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
@ -786,7 +773,7 @@ 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
|
||||||
@ -817,8 +804,8 @@ namespace gen
|
|||||||
|
|
||||||
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 );
|
||||||
|
Loading…
Reference in New Issue
Block a user