2023-11-20 12:09:01 -08:00
|
|
|
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
2023-11-19 17:34:46 -08:00
|
|
|
#pragma once
|
|
|
|
#include "ast.cpp"
|
|
|
|
#endif
|
|
|
|
|
2024-12-01 22:56:49 -08:00
|
|
|
String to_string(Code self)
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-01 22:56:49 -08:00
|
|
|
if ( self.ast == nullptr )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
log_failure( "Code::to_string: Cannot convert code to string, AST is null!" );
|
|
|
|
return { nullptr };
|
|
|
|
}
|
2024-12-02 00:18:52 -08:00
|
|
|
return to_string( self.ast );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeAttributes::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
return GEN_NS duplicate( ast->Content, GlobalAllocator );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
String to_string(CodeBody body)
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
GEN_ASSERT(body.ast != nullptr);
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2024-12-02 01:12:09 -08:00
|
|
|
switch ( body.ast->Type )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
using namespace ECode;
|
2023-11-20 12:09:01 -08:00
|
|
|
case Untyped:
|
|
|
|
case Execution:
|
2024-12-02 01:12:09 -08:00
|
|
|
append( & result, rcast(AST*, body.ast)->Content );
|
2023-11-20 12:09:01 -08:00
|
|
|
break;
|
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
case Enum_Body:
|
|
|
|
case Class_Body:
|
|
|
|
case Extern_Linkage_Body:
|
|
|
|
case Function_Body:
|
|
|
|
case Global_Body:
|
|
|
|
case Namespace_Body:
|
|
|
|
case Struct_Body:
|
|
|
|
case Union_Body:
|
2024-12-02 01:12:09 -08:00
|
|
|
to_string( body, & result );
|
2023-11-19 17:34:46 -08:00
|
|
|
break;
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
case Export_Body:
|
2024-12-02 01:12:09 -08:00
|
|
|
to_string_export( body, & result );
|
2023-11-19 17:34:46 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
void to_string( CodeBody body, String* result )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
GEN_ASSERT(body.ast != nullptr);
|
|
|
|
GEN_ASSERT(result != nullptr);
|
|
|
|
Code curr = body.ast->Front;
|
|
|
|
s32 left = body.ast->NumEntries;
|
2023-11-19 17:34:46 -08:00
|
|
|
while ( left -- )
|
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, "%S", GEN_NS to_string(curr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
++curr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
void to_string_export( CodeBody body, String* result )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
GEN_ASSERT(body.ast != nullptr);
|
|
|
|
GEN_ASSERT(result != nullptr);
|
|
|
|
append_fmt( result, "export\n{\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
Code curr = body;
|
|
|
|
s32 left = body.ast->NumEntries;
|
2023-11-19 17:34:46 -08:00
|
|
|
while ( left-- )
|
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, "%S", to_string(curr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
++curr;
|
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, "};\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeComment::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
return GEN_NS duplicate( ast->Content, GlobalAllocator );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeConstructor::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
switch (ast->Type)
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Constructor:
|
|
|
|
to_string_def( result );
|
|
|
|
break;
|
|
|
|
case Constructor_Fwd:
|
|
|
|
to_string_fwd( result );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeConstructor::to_string_def( String& result )
|
|
|
|
{
|
2024-04-17 14:40:32 -07:00
|
|
|
AST* ClassStructParent = ast->Parent->Parent;
|
|
|
|
if (ClassStructParent) {
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ClassStructParent->Name );
|
2024-04-17 14:40:32 -07:00
|
|
|
}
|
|
|
|
else {
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ast->Name );
|
2024-04-17 14:40:32 -07:00
|
|
|
}
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->Params )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "( %S )", ast->Params.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "()" );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->InitializerList )
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, " : %S", GEN_NS to_string(ast->InitializerList) );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " // %S", ast->InlineCmt->Content );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "\n{\n%S\n}\n", GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeConstructor::to_string_fwd( String& result )
|
|
|
|
{
|
2024-04-17 14:40:32 -07:00
|
|
|
AST* ClassStructParent = ast->Parent->Parent;
|
|
|
|
if (ClassStructParent) {
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ClassStructParent->Name );
|
2024-04-17 14:40:32 -07:00
|
|
|
}
|
|
|
|
else {
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ast->Name );
|
2024-04-17 14:40:32 -07:00
|
|
|
}
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->Params )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "( %S )", ast->Params.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "()");
|
2024-04-17 14:40:32 -07:00
|
|
|
|
|
|
|
if (ast->Body)
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, " = %S", GEN_NS to_string(ast->Body) );
|
2024-04-17 14:40:32 -07:00
|
|
|
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "; // %S\n", ast->InlineCmt->Content );
|
2024-04-17 14:40:32 -07:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
String to_string( CodeClass self )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2024-12-02 01:12:09 -08:00
|
|
|
switch ( self->Type )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Class:
|
2024-12-02 01:12:09 -08:00
|
|
|
to_string_def(self, & result );
|
2023-11-19 17:34:46 -08:00
|
|
|
break;
|
|
|
|
case Class_Fwd:
|
2024-12-02 01:12:09 -08:00
|
|
|
to_string_fwd(self, & result );
|
2023-11-19 17:34:46 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
void to_string_def( CodeClass self, String* result )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
GEN_ASSERT(self.ast != nullptr);
|
|
|
|
AST_Class* ast = self.ast;
|
|
|
|
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-02 01:12:09 -08:00
|
|
|
append( result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
append( result, "class " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->ParentType )
|
|
|
|
{
|
|
|
|
char const* access_level = to_str( ast->ParentAccess );
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, "%S : %s %S", ast->Name, access_level, ast->ParentType.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-02 00:18:52 -08:00
|
|
|
CodeType interface = cast(CodeType, ast->ParentType->Next);
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( interface )
|
2024-12-02 01:12:09 -08:00
|
|
|
append( result, "\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
while ( interface )
|
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, ", %S", interface.to_string() );
|
2024-12-02 00:18:52 -08:00
|
|
|
interface = interface->Next ? cast(CodeType, interface->Next) : CodeType { nullptr };
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( ast->Name )
|
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
append( result, ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->InlineCmt )
|
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, " // %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, "\n{\n%S\n}", GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
|
2024-12-02 01:12:09 -08:00
|
|
|
append( result, ";\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
void to_string_fwd( CodeClass self, String* result )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
GEN_ASSERT(self.ast != nullptr);
|
|
|
|
AST_Class* ast = self.ast;
|
|
|
|
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-02 01:12:09 -08:00
|
|
|
append( result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, "class %S %S", ast->Attributes.to_string(), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
else append_fmt( result, "class %S", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
// Check if it can have an end-statement
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( result, "; // %S\n", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-02 01:12:09 -08:00
|
|
|
append( result,";\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String CodeDefine::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
return string_fmt_buf( GlobalAllocator, "#define %S %S\n", ast->Name, ast->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeDefine::to_string( String& result )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "#define %S %S\n", ast->Name, ast->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeDestructor::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
switch ( ast->Type )
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Destructor:
|
|
|
|
to_string_def( result );
|
|
|
|
break;
|
|
|
|
case Destructor_Fwd:
|
|
|
|
to_string_fwd( result );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeDestructor::to_string_def( String& result )
|
|
|
|
{
|
2024-04-17 14:40:32 -07:00
|
|
|
if ( ast->Name )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S()", ast->Name );
|
2024-04-17 14:40:32 -07:00
|
|
|
}
|
|
|
|
else if ( ast->Specs )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ast->Specs.has( ESpecifier::Virtual ) )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "virtual ~%S()", ast->Parent->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "~%S()", ast->Parent->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "~%S()", ast->Parent->Name );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "\n{\n%S\n}\n", GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeDestructor::to_string_fwd( String& result )
|
|
|
|
{
|
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
|
|
|
if ( ast->Specs.has( ESpecifier::Virtual ) )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "virtual ~%S();\n", ast->Parent->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "~%S()", ast->Parent->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Specs.has( ESpecifier::Pure ) )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, " = 0;" );
|
2024-04-17 14:40:32 -07:00
|
|
|
else if (ast->Body)
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, " = %S;", GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "~%S();", ast->Parent->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeEnum::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
switch ( ast->Type )
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Enum:
|
|
|
|
to_string_def( result );
|
|
|
|
break;
|
|
|
|
case Enum_Fwd:
|
|
|
|
to_string_fwd( result );
|
|
|
|
break;
|
|
|
|
case Enum_Class:
|
|
|
|
to_string_class_def( result );
|
|
|
|
break;
|
|
|
|
case Enum_Class_Fwd:
|
|
|
|
to_string_class_fwd( result );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeEnum::to_string_def( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->Attributes || ast->UnderlyingType )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "enum " );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
|
|
|
if ( ast->UnderlyingType )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S : %S\n{\n%S\n}"
|
2023-11-19 17:34:46 -08:00
|
|
|
, ast->Name
|
|
|
|
, ast->UnderlyingType.to_string()
|
2024-12-02 01:12:09 -08:00
|
|
|
, GEN_NS to_string(ast->Body)
|
2023-11-19 17:34:46 -08:00
|
|
|
);
|
2024-12-01 02:30:37 -08:00
|
|
|
else if ( ast->UnderlyingTypeMacro )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S : %S\n{\n%S\n}"
|
2024-12-01 02:30:37 -08:00
|
|
|
, ast->Name
|
2024-12-01 23:38:55 -08:00
|
|
|
, GEN_NS to_string(ast->UnderlyingTypeMacro)
|
2024-12-02 01:12:09 -08:00
|
|
|
, GEN_NS to_string(ast->Body)
|
2024-12-01 02:30:37 -08:00
|
|
|
);
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
else append_fmt( & result, "%S\n{\n%S\n}", ast->Name, GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
2024-12-02 01:12:09 -08:00
|
|
|
else append_fmt( & result, "enum %S\n{\n%S\n}", ast->Name, GEN_NS to_string(ast->Body) );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
|
|
|
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeEnum::to_string_fwd( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 15:50:37 -08:00
|
|
|
if ( ast->UnderlyingType )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "enum %S : %S", ast->Name, ast->UnderlyingType.to_string() );
|
2024-12-01 15:50:37 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "enum %S", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "; %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeEnum::to_string_class_def( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->Attributes || ast->UnderlyingType )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "enum class " );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->Attributes )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->UnderlyingType )
|
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "%S : %S\n{\n%S\n}", ast->Name, ast->UnderlyingType.to_string(), GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "%S\n{\n%S\n}", ast->Name, GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "enum class %S\n{\n%S\n}", GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
2023-11-20 12:09:01 -08:00
|
|
|
|
|
|
|
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeEnum::to_string_class_fwd( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "enum class " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S : %S", ast->Name, ast->UnderlyingType.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "; %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String CodeExec::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
return GEN_NS duplicate( ast->Content, GlobalAllocator );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeExtern::to_string( String& result )
|
|
|
|
{
|
|
|
|
if ( ast->Body )
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "extern \"%S\"\n{\n%S\n}\n", ast->Name, GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "extern \"%S\"\n{}\n", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeInclude::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
return string_fmt_buf( GlobalAllocator, "#include %S\n", ast->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeInclude::to_string( String& result )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "#include %S\n", ast->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
String CodeFriend::to_string()
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeFriend::to_string( String& result )
|
|
|
|
{
|
2024-12-02 00:18:52 -08:00
|
|
|
append_fmt( & result, "friend %S", GEN_NS to_string(ast->Declaration) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 00:06:30 -08:00
|
|
|
if ( ast->Declaration->Type != ECode::Function && result[ length(result) - 1 ] != ';' )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
String CodeFn::to_string()
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
switch ( ast->Type )
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Function:
|
|
|
|
to_string_def( result );
|
|
|
|
break;
|
|
|
|
case Function_Fwd:
|
|
|
|
to_string_fwd( result );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeFn::to_string_def( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-10-24 22:04:17 -07:00
|
|
|
bool prefix_specs = false;
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
|
|
|
for ( SpecifierT spec : ast->Specs )
|
|
|
|
{
|
|
|
|
if ( ! ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %.*s", spec_str.Len, spec_str.Ptr );
|
2024-05-05 18:53:22 -07:00
|
|
|
|
|
|
|
prefix_specs = true;
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-05 18:53:22 -07:00
|
|
|
if ( ast->Attributes || prefix_specs )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->ReturnType )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S %S(", ast->ReturnType.to_string(), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S(", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Params )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S)", ast->Params.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ")" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
|
|
|
for ( SpecifierT spec : ast->Specs )
|
|
|
|
{
|
|
|
|
if ( ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %.*s", spec_str.Len, spec_str.Ptr );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "\n{\n%S\n}\n", GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeFn::to_string_fwd( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-05-05 18:53:22 -07:00
|
|
|
b32 prefix_specs = false;
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Specs )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
for ( SpecifierT spec : ast->Specs )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-05-05 18:53:22 -07:00
|
|
|
if ( ! ESpecifier::is_trailing( spec ) || ! (spec != ESpecifier::Pure) )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %.*s", spec_str.Len, spec_str.Ptr );
|
2024-05-05 18:53:22 -07:00
|
|
|
|
|
|
|
prefix_specs = true;
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-05 18:53:22 -07:00
|
|
|
if ( ast->Attributes || prefix_specs )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->ReturnType )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S %S(", ast->ReturnType.to_string(), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S(", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Params )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S)", ast->Params.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ")" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
for ( SpecifierT spec : ast->Specs )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %.*s", spec_str.Len, spec_str.Ptr );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-05 18:53:22 -07:00
|
|
|
if ( ast->Specs && ast->Specs.has( ESpecifier::Pure ) >= 0 )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, " = 0;" );
|
2024-04-17 14:40:32 -07:00
|
|
|
else if (ast->Body)
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, " = %S;", GEN_NS to_string(ast->Body) );
|
2024-04-17 14:40:32 -07:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "; %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeModule::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeModule::to_string( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if (((u32(ModuleFlag_Export) & u32(ast->ModuleFlags)) == u32(ModuleFlag_Export)))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export ");
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 02:30:37 -08:00
|
|
|
if (((u32(ModuleFlag_Import) & u32(ast->ModuleFlags)) == u32(ModuleFlag_Import)))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "import ");
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S;\n", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeNS::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeNS::to_string( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "namespace %S\n{\n%S\n}\n", ast->Name , GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeOperator::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
switch ( ast->Type )
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Operator:
|
|
|
|
case Operator_Member:
|
|
|
|
to_string_def( result );
|
|
|
|
break;
|
|
|
|
case Operator_Fwd:
|
|
|
|
case Operator_Member_Fwd:
|
|
|
|
to_string_fwd( result );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeOperator::to_string_def( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
|
|
|
for ( SpecifierT spec : ast->Specs )
|
|
|
|
{
|
|
|
|
if ( ! ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %.*s", spec_str.Len, spec_str.Ptr );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->Attributes || ast->Specs )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->ReturnType )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S %S (", ast->ReturnType.to_string(), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Params )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S)", ast->Params.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ")" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
|
|
|
for ( SpecifierT spec : ast->Specs )
|
|
|
|
{
|
|
|
|
if ( ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %.*s", spec_str.Len, spec_str.Ptr );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "\n{\n%S\n}\n"
|
2024-12-02 01:12:09 -08:00
|
|
|
, GEN_NS to_string(ast->Body)
|
2023-11-19 17:34:46 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeOperator::to_string_fwd( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S\n", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
for ( SpecifierT spec : ast->Specs )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ! ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %.*s", spec_str.Len, spec_str.Ptr );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->Attributes || ast->Specs )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S %S (", ast->ReturnType.to_string(), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Params )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S)", ast->Params.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, ")" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
for ( SpecifierT spec : ast->Specs )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %.*s", spec_str.Len, spec_str.Ptr );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "; %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeOpCast::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
switch ( ast->Type )
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Operator_Cast:
|
|
|
|
to_string_def( result );
|
|
|
|
break;
|
|
|
|
case Operator_Cast_Fwd:
|
|
|
|
to_string_fwd( result );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeOpCast::to_string_def( String& result )
|
|
|
|
{
|
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
2024-10-25 01:08:20 -07:00
|
|
|
for ( SpecifierT spec : ast->Specs )
|
|
|
|
{
|
|
|
|
if ( ! ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%*s ", spec_str.Len, spec_str.Ptr );
|
2024-10-25 01:08:20 -07:00
|
|
|
}
|
|
|
|
}
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 00:06:30 -08:00
|
|
|
if ( ast->Name && length(ast->Name) )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%Soperator %S()", ast->Name, ast->ValueType.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "operator %S()", ast->ValueType.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
for ( SpecifierT spec : ast->Specs )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %.*s", spec_str.Len, spec_str.Ptr );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "\n{\n%S\n}\n", GEN_NS to_string(ast->Body) );
|
2023-11-20 12:09:01 -08:00
|
|
|
return;
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2024-12-01 00:06:30 -08:00
|
|
|
if ( ast->Name && length(ast->Name) )
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "%Soperator %S()\n{\n%S\n}\n", ast->Name, ast->ValueType.to_string(), GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "operator %S()\n{\n%S\n}\n", ast->ValueType.to_string(), GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeOpCast::to_string_fwd( String& result )
|
|
|
|
{
|
|
|
|
if ( ast->Specs )
|
|
|
|
{
|
2024-10-25 01:08:20 -07:00
|
|
|
for ( SpecifierT spec : ast->Specs )
|
|
|
|
{
|
|
|
|
if ( ! ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%*s ", spec_str.Len, spec_str.Ptr );
|
2024-10-25 01:08:20 -07:00
|
|
|
}
|
|
|
|
}
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "operator %S()", ast->ValueType.to_string() );
|
2023-11-20 12:09:01 -08:00
|
|
|
|
|
|
|
for ( SpecifierT spec : ast->Specs )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ESpecifier::is_trailing( spec ) )
|
|
|
|
{
|
|
|
|
StrC spec_str = ESpecifier::to_str( spec );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %*s", spec_str.Len, spec_str.Ptr );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "; %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n" );
|
2023-11-20 12:09:01 -08:00
|
|
|
return;
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
2023-11-20 12:09:01 -08:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "operator %S(); %S", ast->ValueType.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "operator %S();\n", ast->ValueType.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeParam::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeParam::to_string( String& result )
|
|
|
|
{
|
2024-04-17 14:40:32 -07:00
|
|
|
if ( ast->Macro )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-04-17 14:40:32 -07:00
|
|
|
// Related to parsing: ( <macro>, ... )
|
2024-12-01 20:35:58 -08:00
|
|
|
GEN_NS append( & result, ast->Macro.ast->Content );
|
2024-04-17 14:40:32 -07:00
|
|
|
// Could also be: ( <macro> <type <name>, ... )
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->Name )
|
2024-04-17 14:40:32 -07:00
|
|
|
{
|
|
|
|
if ( ast->ValueType.ast == nullptr )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %S", ast->Name );
|
2024-04-17 14:40:32 -07:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %S %S", ast->ValueType.to_string(), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-04-17 14:40:32 -07:00
|
|
|
}
|
|
|
|
else if ( ast->ValueType )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %S", ast->ValueType.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-10-24 22:04:17 -07:00
|
|
|
if ( ast->PostNameMacro )
|
|
|
|
{
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, " %S", GEN_NS to_string(ast->PostNameMacro) );
|
2024-10-24 22:04:17 -07:00
|
|
|
}
|
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->Value )
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, " = %S", GEN_NS to_string(ast->Value) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-04-17 14:40:32 -07:00
|
|
|
if ( ast->NumEntries - 1 > 0 )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-04-17 14:40:32 -07:00
|
|
|
for ( CodeParam param : ast->Next )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, ", %S", param.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String CodePreprocessCond::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
switch ( ast->Type )
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Preprocess_If:
|
|
|
|
to_string_if( result );
|
|
|
|
break;
|
|
|
|
case Preprocess_IfDef:
|
|
|
|
to_string_ifdef( result );
|
|
|
|
break;
|
2023-11-20 12:09:01 -08:00
|
|
|
case Preprocess_IfNotDef:
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string_ifndef( result );
|
|
|
|
break;
|
|
|
|
case Preprocess_ElIf:
|
|
|
|
to_string_elif( result );
|
|
|
|
break;
|
|
|
|
case Preprocess_Else:
|
|
|
|
to_string_else( result );
|
|
|
|
break;
|
|
|
|
case Preprocess_EndIf:
|
|
|
|
to_string_endif( result );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodePreprocessCond::to_string_if( String& result )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "#if %S\n", ast->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodePreprocessCond::to_string_ifdef( String& result )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "#ifdef %S\n", ast->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodePreprocessCond::to_string_ifndef( String& result )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "#ifndef %S\n", ast->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodePreprocessCond::to_string_elif( String& result )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "#elif %S\n", ast->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodePreprocessCond::to_string_else( String& result )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "#else\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodePreprocessCond::to_string_endif( String& result )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "#endif\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodePragma::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodePragma::to_string( String& result )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "#pragma %S\n", ast->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeSpecifiers::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeSpecifiers::to_string( String& result )
|
|
|
|
{
|
|
|
|
s32 idx = 0;
|
|
|
|
s32 left = ast->NumEntries;
|
|
|
|
while ( left-- )
|
|
|
|
{
|
|
|
|
StrC spec = ESpecifier::to_str( ast->ArrSpecs[idx] );
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%.*s ", spec.Len, spec.Ptr );
|
2023-11-19 17:34:46 -08:00
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String CodeStruct::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
switch ( ast->Type )
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Struct:
|
|
|
|
to_string_def( result );
|
|
|
|
break;
|
|
|
|
case Struct_Fwd:
|
|
|
|
to_string_fwd( result );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeStruct::to_string_def( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "struct " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->ParentType )
|
|
|
|
{
|
|
|
|
char const* access_level = to_str( ast->ParentAccess );
|
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S : %s %S", ast->Name, access_level, ast->ParentType.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-02 00:18:52 -08:00
|
|
|
CodeType interface = cast(CodeType, ast->ParentType->Next);
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( interface )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
while ( interface )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, ", %S", interface.to_string() );
|
2024-12-02 00:18:52 -08:00
|
|
|
interface = interface->Next ? cast( CodeType, interface->Next) : CodeType { nullptr };
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( ast->Name )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->InlineCmt )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " // %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2024-12-02 01:12:09 -08:00
|
|
|
append_fmt( & result, "\n{\n%S\n}", GEN_NS to_string(ast->Body) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeStruct::to_string_fwd( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "struct %S %S", ast->Attributes.to_string(), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
else append_fmt( & result, "struct %S", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "; %S", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String CodeTemplate::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeTemplate::to_string( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Params )
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "template< %S >\n%S", GEN_NS to_string(ast->Params), GEN_NS to_string(ast->Declaration) );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "template<>\n%S", GEN_NS to_string(ast->Declaration) );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeTypedef::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeTypedef::to_string( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "typedef ");
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
// Determines if the typedef is a function typename
|
|
|
|
if ( ast->UnderlyingType->ReturnType )
|
2024-12-01 23:38:55 -08:00
|
|
|
append( & result, GEN_NS to_string(ast->UnderlyingType) );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "%S %S", GEN_NS to_string(ast->UnderlyingType), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->UnderlyingType->Type == ECode::Typename && ast->UnderlyingType->ArrExpr )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-02 00:18:52 -08:00
|
|
|
append_fmt( & result, "[ %S ];", GEN_NS to_string(ast->UnderlyingType->ArrExpr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
AST* next_arr_expr = ast->UnderlyingType->ArrExpr->Next;
|
|
|
|
while ( next_arr_expr )
|
|
|
|
{
|
2024-12-02 00:18:52 -08:00
|
|
|
append_fmt( & result, "[ %S ];", GEN_NS to_string(next_arr_expr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
next_arr_expr = next_arr_expr->Next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %S", ast->InlineCmt->Content);
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeType::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeType::to_string( String& result )
|
|
|
|
{
|
2024-10-24 22:04:17 -07:00
|
|
|
#if defined(GEN_USE_NEW_TYPENAME_PARSING)
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->ReturnType && ast->Params )
|
|
|
|
{
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 00:06:30 -08:00
|
|
|
append_fmt( result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( ast->Specs )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ( %S ) ( %S ) %S", ast->ReturnType.to_string(), ast->Name, ast->Params.to_string(), ast->Specs.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ( %S ) ( %S )", ast->ReturnType.to_string(), ast->Name, ast->Params.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if ( ast->ReturnType && ast->Params )
|
|
|
|
{
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
|
|
|
{
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Specs )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S %S ( %S ) %S", ast->ReturnType.to_string(), ast->Name, ast->Params.to_string(), ast->Specs.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S %S ( %S )", ast->ReturnType.to_string(), ast->Name, ast->Params.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
return;
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Specs )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S %S", ast->Name, ast->Specs.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->IsParamPack )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "...");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeUnion::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeUnion::to_string( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "union " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Name )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S\n{\n%S\n}"
|
2023-11-19 17:34:46 -08:00
|
|
|
, ast->Name
|
2024-12-02 01:12:09 -08:00
|
|
|
, GEN_NS to_string(ast->Body)
|
2023-11-19 17:34:46 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Anonymous union
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "\n{\n%S\n}"
|
2024-12-02 01:12:09 -08:00
|
|
|
, GEN_NS to_string(ast->Body)
|
2023-11-19 17:34:46 -08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeUsing::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
switch ( ast->Type )
|
|
|
|
{
|
|
|
|
using namespace ECode;
|
|
|
|
case Using:
|
|
|
|
to_string( result );
|
|
|
|
break;
|
|
|
|
case Using_Namespace:
|
|
|
|
to_string_ns( result );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeUsing::to_string( String& result )
|
|
|
|
{
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Attributes.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->UnderlyingType )
|
|
|
|
{
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "using %S = %S", ast->Name, ast->UnderlyingType.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->UnderlyingType->ArrExpr )
|
|
|
|
{
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "[ %S ]", GEN_NS to_string(ast->UnderlyingType->ArrExpr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
AST* next_arr_expr = ast->UnderlyingType->ArrExpr->Next;
|
|
|
|
while ( next_arr_expr )
|
|
|
|
{
|
2024-12-02 00:18:52 -08:00
|
|
|
append_fmt( & result, "[ %S ]", GEN_NS to_string(next_arr_expr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
next_arr_expr = next_arr_expr->Next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";" );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "using %S;", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %S\n", ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeUsing::to_string_ns( String& result )
|
|
|
|
{
|
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "using namespace $S; %S", ast->Name, ast->InlineCmt->Content );
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "using namespace %s;\n", ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
String CodeVar::to_string()
|
|
|
|
{
|
2024-12-01 00:06:30 -08:00
|
|
|
String result = string_make( GlobalAllocator, "" );
|
2023-11-19 17:34:46 -08:00
|
|
|
to_string( result );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeVar::to_string( String& result )
|
|
|
|
{
|
|
|
|
if ( ast->Parent && ast->Parent->Type == ECode::Variable )
|
|
|
|
{
|
|
|
|
// Its a comma-separated variable ( a NextVar )
|
|
|
|
|
|
|
|
if ( ast->Specs )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Specs.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-10-24 22:04:17 -07:00
|
|
|
if ( ast->ValueType->ArrExpr )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "[ %S ]", GEN_NS to_string(ast->ValueType->ArrExpr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
AST* next_arr_expr = ast->ValueType->ArrExpr->Next;
|
|
|
|
while ( next_arr_expr )
|
|
|
|
{
|
2024-12-02 00:18:52 -08:00
|
|
|
append_fmt( & result, "[ %S ]", GEN_NS to_string(next_arr_expr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
next_arr_expr = next_arr_expr->Next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->Value )
|
2024-10-24 22:04:17 -07:00
|
|
|
{
|
|
|
|
if ( ast->VarConstructorInit )
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "( %S ", GEN_NS to_string(ast->Value) );
|
2024-10-24 22:04:17 -07:00
|
|
|
else
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, " = %S", GEN_NS to_string(ast->Value) );
|
2024-10-24 22:04:17 -07:00
|
|
|
}
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
// Keep the chain going...
|
|
|
|
if ( ast->NextVar )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, ", %S", ast->NextVar.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-10-24 22:04:17 -07:00
|
|
|
if ( ast->VarConstructorInit )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, " )");
|
2024-10-24 22:04:17 -07:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
return;
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
2024-12-01 02:30:37 -08:00
|
|
|
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "export " );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Attributes || ast->Specs )
|
|
|
|
{
|
|
|
|
if ( ast->Attributes )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S ", ast->Specs.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Specs )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S\n", ast->Specs.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S %S", ast->ValueType.to_string(), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->ValueType->ArrExpr )
|
|
|
|
{
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "[ %S ]", GEN_NS to_string(ast->ValueType->ArrExpr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
AST* next_arr_expr = ast->ValueType->ArrExpr->Next;
|
|
|
|
while ( next_arr_expr )
|
|
|
|
{
|
2024-12-02 00:18:52 -08:00
|
|
|
append_fmt( & result, "[ %S ]", GEN_NS to_string(next_arr_expr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
next_arr_expr = next_arr_expr->Next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->BitfieldSize )
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, " : %S", GEN_NS to_string(ast->BitfieldSize) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->Value )
|
2024-10-24 22:04:17 -07:00
|
|
|
{
|
|
|
|
if ( ast->VarConstructorInit )
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "( %S ", GEN_NS to_string(ast->Value) );
|
2024-10-24 22:04:17 -07:00
|
|
|
else
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, " = %S", GEN_NS to_string(ast->Value) );
|
2024-10-24 22:04:17 -07:00
|
|
|
}
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
if ( ast->NextVar )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, ", %S", ast->NextVar.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-10-24 22:04:17 -07:00
|
|
|
if ( ast->VarConstructorInit )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, " )");
|
2024-10-24 22:04:17 -07:00
|
|
|
|
2023-11-19 17:34:46 -08:00
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "; %S", ast->InlineCmt->Content);
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";\n" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
return;
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( ast->BitfieldSize )
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "%S %S : %S", ast->ValueType.to_string(), ast->Name, GEN_NS to_string(ast->BitfieldSize) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
else if ( ast->ValueType->ArrExpr )
|
2023-11-19 17:34:46 -08:00
|
|
|
{
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "%S %S[ %S ]", ast->ValueType.to_string(), ast->Name, GEN_NS to_string(ast->ValueType->ArrExpr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
|
|
|
AST* next_arr_expr = ast->ValueType->ArrExpr->Next;
|
|
|
|
while ( next_arr_expr )
|
|
|
|
{
|
2024-12-02 00:18:52 -08:00
|
|
|
append_fmt( & result, "[ %S ]", GEN_NS to_string(next_arr_expr) );
|
2023-11-19 17:34:46 -08:00
|
|
|
next_arr_expr = next_arr_expr->Next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, "%S %S", ast->ValueType.to_string(), ast->Name );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->Value )
|
2024-10-24 22:04:17 -07:00
|
|
|
{
|
|
|
|
if ( ast->VarConstructorInit )
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, "( %S ", GEN_NS to_string(ast->Value) );
|
2024-10-24 22:04:17 -07:00
|
|
|
else
|
2024-12-01 23:38:55 -08:00
|
|
|
append_fmt( & result, " = %S", GEN_NS to_string(ast->Value) );
|
2024-10-24 22:04:17 -07:00
|
|
|
}
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->NextVar )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, ", %S", ast->NextVar.to_string() );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2024-10-24 22:04:17 -07:00
|
|
|
if ( ast->VarConstructorInit )
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, " )");
|
2024-10-24 22:04:17 -07:00
|
|
|
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, ";" );
|
2023-11-19 17:34:46 -08:00
|
|
|
|
2023-11-20 12:09:01 -08:00
|
|
|
if ( ast->InlineCmt )
|
2024-12-01 20:35:58 -08:00
|
|
|
append_fmt( & result, " %S", ast->InlineCmt->Content);
|
2023-11-19 17:34:46 -08:00
|
|
|
else
|
2024-12-01 20:35:58 -08:00
|
|
|
append( & result, "\n");
|
2023-11-19 17:34:46 -08:00
|
|
|
}
|