Significant progress reducing c++ feature usage in the library.

This commit is contained in:
Edward R. Gonzalez 2024-12-01 18:50:37 -05:00
parent 9e88cb8724
commit 80cb3f4eca
19 changed files with 611 additions and 486 deletions

View File

@ -1,7 +1,8 @@
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES #define GEN_ENFORCE_STRONG_CODE_TYPES
#define GEN_EXPOSE_BACKEND #define GEN_EXPOSE_BACKEND
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 0 #define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
#define GEN_SUPPORT_CPP_REFERENCES 0
#include "gen.cpp" #include "gen.cpp"
#include "helpers/push_ignores.inline.hpp" #include "helpers/push_ignores.inline.hpp"
@ -63,6 +64,8 @@ int gen_main()
{ {
gen::init(); gen::init();
// PreprocessorDefines.append("GEN_NS");
Code push_ignores = scan_file( "helpers/push_ignores.inline.hpp" ); Code push_ignores = scan_file( "helpers/push_ignores.inline.hpp" );
Code pop_ignores = scan_file( "helpers/pop_ignores.inline.hpp" ); Code pop_ignores = scan_file( "helpers/pop_ignores.inline.hpp" );

View File

@ -7,20 +7,21 @@ Code Code::Global;
Code Code::Invalid; Code Code::Invalid;
// This serializes all the data-members in a "debug" format, where each member is printed with its associated value. // This serializes all the data-members in a "debug" format, where each member is printed with its associated value.
char const* AST::debug_str() char const* debug_str(AST* self)
{ {
GEN_ASSERT(self != nullptr);
String result = string_make_reserve( GlobalAllocator, kilobytes(1) ); String result = string_make_reserve( GlobalAllocator, kilobytes(1) );
if ( Parent ) if ( self->Parent )
append_fmt( result, "\n\tParent : %S %S", Parent->type_str(), Name ? Name : "" ); append_fmt( result, "\n\tParent : %S %S", self->Parent->type_str(), self->Name ? self->Name : "" );
else else
append_fmt( result, "\n\tParent : %S", "Null" ); append_fmt( result, "\n\tParent : %S", "Null" );
append_fmt( result, "\n\tName : %S", Name ? Name : "Null" ); append_fmt( result, "\n\tName : %S", self->Name ? self->Name : "Null" );
append_fmt( result, "\n\tType : %S", type_str() ); append_fmt( result, "\n\tType : %S", type_str(self) );
append_fmt( result, "\n\tModule Flags : %S", to_str( ModuleFlags ) ); append_fmt( result, "\n\tModule Flags : %S", to_str( self->ModuleFlags ) );
switch ( Type ) switch ( self->Type )
{ {
using namespace ECode; using namespace ECode;
@ -29,10 +30,10 @@ char const* AST::debug_str()
case Access_Private: case Access_Private:
case Access_Protected: case Access_Protected:
case Access_Public: case Access_Public:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
break; break;
case Untyped: case Untyped:
@ -47,75 +48,75 @@ char const* AST::debug_str()
case Preprocess_Else: case Preprocess_Else:
case Preprocess_IfDef: case Preprocess_IfDef:
case Preprocess_IfNotDef: case Preprocess_IfNotDef:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tContent: %S", Content ); append_fmt( result, "\n\tContent: %S", self->Content );
break; break;
case Class: case Class:
case Struct: case Struct:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" ); append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" );
append_fmt( result, "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" ); append_fmt( result, "\n\tParentType : %s", self->ParentType ? type_str(self->ParentType) : "Null" );
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case Class_Fwd: case Class_Fwd:
case Struct_Fwd: case Struct_Fwd:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" ); append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" );
append_fmt( result, "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" ); append_fmt( result, "\n\tParentType : %s", self->ParentType ? type_str(self->ParentType) : "Null" );
break; break;
case Constructor: case Constructor:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" ); append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? to_string(self->InitializerList) : "Null" );
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case Constructor_Fwd: case Constructor_Fwd:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" ); append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? to_string(self->InitializerList) : "Null" );
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
break; break;
case Destructor: case Destructor:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case Destructor_Fwd: case Destructor_Fwd:
@ -123,248 +124,248 @@ char const* AST::debug_str()
case Enum: case Enum:
case Enum_Class: case Enum_Class:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" );
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case Enum_Fwd: case Enum_Fwd:
case Enum_Class_Fwd: case Enum_Class_Fwd:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" );
break; break;
case Extern_Linkage: case Extern_Linkage:
case Namespace: case Namespace:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tBody: %S", Body ? Body->debug_str() : "Null" ); append_fmt( result, "\n\tBody: %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case Friend: case Friend:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" ); append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? to_string(self->Declaration) : "Null" );
break; break;
case Function: case Function:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case Function_Fwd: case Function_Fwd:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
break; break;
case Module: case Module:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
break; break;
case Operator: case Operator:
case Operator_Member: case Operator_Member:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
append_fmt( result, "\n\tOp : %S", to_str( Op ) ); append_fmt( result, "\n\tOp : %S", to_str( self->Op ) );
break; break;
case Operator_Fwd: case Operator_Fwd:
case Operator_Member_Fwd: case Operator_Member_Fwd:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tOp : %S", to_str( Op ) ); append_fmt( result, "\n\tOp : %S", to_str( self->Op ) );
break; break;
case Operator_Cast: case Operator_Cast:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" );
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case Operator_Cast_Fwd: case Operator_Cast_Fwd:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" );
break; break;
case Parameters: case Parameters:
append_fmt( result, "\n\tNumEntries: %d", NumEntries ); append_fmt( result, "\n\tNumEntries: %d", self->NumEntries );
append_fmt( result, "\n\tLast : %S", Last->Name ); append_fmt( result, "\n\tLast : %S", self->Last->Name );
append_fmt( result, "\n\tNext : %S", Next->Name ); append_fmt( result, "\n\tNext : %S", self->Next->Name );
append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" );
append_fmt( result, "\n\tValue : %S", Value ? Value->to_string() : "Null" ); append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" );
break; break;
case Specifiers: case Specifiers:
{ {
append_fmt( result, "\n\tNumEntries: %d", NumEntries ); append_fmt( result, "\n\tNumEntries: %d", self->NumEntries );
GEN_NS append( result, "\n\tArrSpecs: " ); GEN_NS append( result, "\n\tArrSpecs: " );
s32 idx = 0; s32 idx = 0;
s32 left = NumEntries; s32 left = self->NumEntries;
while ( left-- ) while ( left-- )
{ {
StrC spec = ESpecifier::to_str( ArrSpecs[idx] ); StrC spec = ESpecifier::to_str( self->ArrSpecs[idx] );
append_fmt( result, "%.*s, ", spec.Len, spec.Ptr ); append_fmt( result, "%.*s, ", spec.Len, spec.Ptr );
idx++; idx++;
} }
append_fmt( result, "\n\tNextSpecs: %S", NextSpecs ? NextSpecs->debug_str() : "Null" ); append_fmt( result, "\n\tNextSpecs: %S", self->NextSpecs ? debug_str(self->NextSpecs) : "Null" );
} }
break; break;
case Template: case Template:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" ); append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? to_string(self->Declaration) : "Null" );
break; break;
case Typedef: case Typedef:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" );
break; break;
case Typename: case Typename:
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tReturnType : %S", ReturnType ? ReturnType->to_string() : "Null" ); append_fmt( result, "\n\tReturnType : %S", self->ReturnType ? to_string(self->ReturnType) : "Null" );
append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" );
append_fmt( result, "\n\tArrExpr : %S", ArrExpr ? ArrExpr->to_string() : "Null" ); append_fmt( result, "\n\tArrExpr : %S", self->ArrExpr ? to_string(self->ArrExpr) : "Null" );
break; break;
case Union: case Union:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" );
break; break;
case Using: case Using:
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" );
break; break;
case Variable: case Variable:
if ( Parent && Parent->Type == Variable ) if ( self->Parent && self->Parent->Type == Variable )
{ {
// Its a NextVar // Its a NextVar
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tValue : %S", Value ? Value->to_string() : "Null" ); append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" );
append_fmt( result, "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" ); append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? to_string(self->BitfieldSize) : "Null" );
append_fmt( result, "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" ); append_fmt( result, "\n\tNextVar : %S", self->NextVar ? debug_str(self->NextVar) : "Null" );
break; break;
} }
if ( Prev ) if ( self->Prev )
append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
if ( Next ) if ( self->Next )
append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" );
append_fmt( result, "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" );
append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" );
append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" );
append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" );
append_fmt( result, "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" ); append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? to_string(self->BitfieldSize) : "Null" );
append_fmt( result, "\n\tValue : %S", Value ? Value->to_string() : "Null" ); append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" );
append_fmt( result, "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" ); append_fmt( result, "\n\tNextVar : %S", self->NextVar ? debug_str(self->NextVar) : "Null" );
break; break;
} }
return result; return result;
} }
AST* AST::duplicate() AST* duplicate(AST* self)
{ {
using namespace ECode; using namespace ECode;
AST* result = make_code().ast; AST* result = make_code().ast;
mem_copy( result, this, sizeof( AST ) ); mem_copy( result, self, sizeof( AST ) );
result->Parent = nullptr; result->Parent = nullptr;
return result; return result;
@ -412,169 +413,169 @@ void AST::to_string( String& result )
break; break;
case Class: case Class:
cast<CodeClass>().to_string_def( result ); code_cast<CodeClass>().to_string_def( result );
break; break;
case Class_Fwd: case Class_Fwd:
cast<CodeClass>().to_string_fwd( result ); code_cast<CodeClass>().to_string_fwd( result );
break; break;
case Constructor: case Constructor:
cast<CodeConstructor>().to_string_def( result ); code_cast<CodeConstructor>().to_string_def( result );
break; break;
case Constructor_Fwd: case Constructor_Fwd:
cast<CodeConstructor>().to_string_fwd( result ); code_cast<CodeConstructor>().to_string_fwd( result );
break; break;
case Destructor: case Destructor:
cast<CodeDestructor>().to_string_def( result ); code_cast<CodeDestructor>().to_string_def( result );
break; break;
case Destructor_Fwd: case Destructor_Fwd:
cast<CodeDestructor>().to_string_fwd( result ); code_cast<CodeDestructor>().to_string_fwd( result );
break; break;
case Enum: case Enum:
cast<CodeEnum>().to_string_def( result ); code_cast<CodeEnum>().to_string_def( result );
break; break;
case Enum_Fwd: case Enum_Fwd:
cast<CodeEnum>().to_string_fwd( result ); code_cast<CodeEnum>().to_string_fwd( result );
break; break;
case Enum_Class: case Enum_Class:
cast<CodeEnum>().to_string_class_def( result ); code_cast<CodeEnum>().to_string_class_def( result );
break; break;
case Enum_Class_Fwd: case Enum_Class_Fwd:
cast<CodeEnum>().to_string_class_fwd( result ); code_cast<CodeEnum>().to_string_class_fwd( result );
break; break;
case Export_Body: case Export_Body:
cast<CodeBody>().to_string_export( result ); code_cast<CodeBody>().to_string_export( result );
break; break;
case Extern_Linkage: case Extern_Linkage:
cast<CodeExtern>().to_string( result ); code_cast<CodeExtern>().to_string( result );
break; break;
case Friend: case Friend:
cast<CodeFriend>().to_string( result ); code_cast<CodeFriend>().to_string( result );
break; break;
case Function: case Function:
cast<CodeFn>().to_string_def( result ); code_cast<CodeFn>().to_string_def( result );
break; break;
case Function_Fwd: case Function_Fwd:
cast<CodeFn>().to_string_fwd( result ); code_cast<CodeFn>().to_string_fwd( result );
break; break;
case Module: case Module:
cast<CodeModule>().to_string( result ); code_cast<CodeModule>().to_string( result );
break; break;
case Namespace: case Namespace:
cast<CodeNS>().to_string( result ); code_cast<CodeNS>().to_string( result );
break; break;
case Operator: case Operator:
case Operator_Member: case Operator_Member:
cast<CodeOperator>().to_string_def( result ); code_cast<CodeOperator>().to_string_def( result );
break; break;
case Operator_Fwd: case Operator_Fwd:
case Operator_Member_Fwd: case Operator_Member_Fwd:
cast<CodeOperator>().to_string_fwd( result ); code_cast<CodeOperator>().to_string_fwd( result );
break; break;
case Operator_Cast: case Operator_Cast:
cast<CodeOpCast>().to_string_def( result ); code_cast<CodeOpCast>().to_string_def( result );
break; break;
case Operator_Cast_Fwd: case Operator_Cast_Fwd:
cast<CodeOpCast>().to_string_fwd( result ); code_cast<CodeOpCast>().to_string_fwd( result );
break; break;
case Parameters: case Parameters:
cast<CodeParam>().to_string( result ); code_cast<CodeParam>().to_string( result );
break; break;
case Preprocess_Define: case Preprocess_Define:
cast<CodeDefine>().to_string( result ); code_cast<CodeDefine>().to_string( result );
break; break;
case Preprocess_If: case Preprocess_If:
cast<CodePreprocessCond>().to_string_if( result ); code_cast<CodePreprocessCond>().to_string_if( result );
break; break;
case Preprocess_IfDef: case Preprocess_IfDef:
cast<CodePreprocessCond>().to_string_ifdef( result ); code_cast<CodePreprocessCond>().to_string_ifdef( result );
break; break;
case Preprocess_IfNotDef: case Preprocess_IfNotDef:
cast<CodePreprocessCond>().to_string_ifndef( result ); code_cast<CodePreprocessCond>().to_string_ifndef( result );
break; break;
case Preprocess_Include: case Preprocess_Include:
cast<CodeInclude>().to_string( result ); code_cast<CodeInclude>().to_string( result );
break; break;
case Preprocess_ElIf: case Preprocess_ElIf:
cast<CodePreprocessCond>().to_string_elif( result ); code_cast<CodePreprocessCond>().to_string_elif( result );
break; break;
case Preprocess_Else: case Preprocess_Else:
cast<CodePreprocessCond>().to_string_else( result ); code_cast<CodePreprocessCond>().to_string_else( result );
break; break;
case Preprocess_EndIf: case Preprocess_EndIf:
cast<CodePreprocessCond>().to_string_endif( result ); code_cast<CodePreprocessCond>().to_string_endif( result );
break; break;
case Preprocess_Pragma: case Preprocess_Pragma:
cast<CodePragma>().to_string( result ); code_cast<CodePragma>().to_string( result );
break; break;
case Specifiers: case Specifiers:
cast<CodeSpecifiers>().to_string( result ); code_cast<CodeSpecifiers>().to_string( result );
break; break;
case Struct: case Struct:
cast<CodeStruct>().to_string_def( result ); code_cast<CodeStruct>().to_string_def( result );
break; break;
case Struct_Fwd: case Struct_Fwd:
cast<CodeStruct>().to_string_fwd( result ); code_cast<CodeStruct>().to_string_fwd( result );
break; break;
case Template: case Template:
cast<CodeTemplate>().to_string( result ); code_cast<CodeTemplate>().to_string( result );
break; break;
case Typedef: case Typedef:
cast<CodeTypedef>().to_string( result ); code_cast<CodeTypedef>().to_string( result );
break; break;
case Typename: case Typename:
cast<CodeType>().to_string( result ); code_cast<CodeType>().to_string( result );
break; break;
case Union: case Union:
cast<CodeUnion>().to_string( result ); code_cast<CodeUnion>().to_string( result );
break; break;
case Using: case Using:
cast<CodeUsing>().to_string( result ); code_cast<CodeUsing>().to_string( result );
break; break;
case Using_Namespace: case Using_Namespace:
cast<CodeUsing>().to_string_ns( result ); code_cast<CodeUsing>().to_string_ns( result );
break; break;
case Variable: case Variable:
cast<CodeVar>().to_string( result ); code_cast<CodeVar>().to_string( result );
break; break;
case Enum_Body: case Enum_Body:
@ -585,7 +586,7 @@ void AST::to_string( String& result )
case Namespace_Body: case Namespace_Body:
case Struct_Body: case Struct_Body:
case Union_Body: case Union_Body:
cast<CodeBody>().to_string( result ); code_cast<CodeBody>().to_string( result );
break; break;
} }
} }
@ -1157,7 +1158,7 @@ bool AST::validate_body()
#define CheckEntries( Unallowed_Types ) \ #define CheckEntries( Unallowed_Types ) \
do \ do \
{ \ { \
for ( Code entry : cast<CodeBody>() ) \ for ( Code entry : code_cast<CodeBody>() ) \
{ \ { \
switch ( entry->Type ) \ switch ( entry->Type ) \
{ \ { \
@ -1175,7 +1176,7 @@ bool AST::validate_body()
CheckEntries( GEN_AST_BODY_CLASS_UNALLOWED_TYPES ); CheckEntries( GEN_AST_BODY_CLASS_UNALLOWED_TYPES );
break; break;
case Enum_Body: case Enum_Body:
for ( Code entry : cast<CodeBody>() ) for ( Code entry : code_cast<CodeBody>() )
{ {
if ( entry->Type != Untyped ) if ( entry->Type != Untyped )
{ {
@ -1194,7 +1195,7 @@ bool AST::validate_body()
CheckEntries( GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES ); CheckEntries( GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES );
break; break;
case Global_Body: case Global_Body:
for (Code entry : cast<CodeBody>()) for (Code entry : code_cast<CodeBody>())
{ {
switch (entry->Type) switch (entry->Type)
{ {
@ -1227,7 +1228,7 @@ bool AST::validate_body()
CheckEntries( GEN_AST_BODY_STRUCT_UNALLOWED_TYPES ); CheckEntries( GEN_AST_BODY_STRUCT_UNALLOWED_TYPES );
break; break;
case Union_Body: case Union_Body:
for ( Code entry : Body->cast<CodeBody>() ) for ( Code entry : Body->code_cast<CodeBody>() )
{ {
if ( entry->Type != Untyped ) if ( entry->Type != Untyped )
{ {

View File

@ -146,6 +146,11 @@ namespace parser
struct Token; struct Token;
} }
template< class Type> forceinline Type tmpl_cast( Code* self ) { return * rcast( Type*, self ); }
#if ! GEN_COMPILER_C && 0
template< class Type> forceinline Type tmpl_cast( Code& self ) { return * rcast( Type*, & self ); }
#endif
/* /*
AST* wrapper AST* wrapper
- Not constantly have to append the '*' as this is written often.. - Not constantly have to append the '*' as this is written often..
@ -178,7 +183,7 @@ struct Code
Using_Code( Code ); Using_Code( Code );
template< class Type > template< class Type >
forceinline Type cast() forceinline Type code_cast()
{ {
return * rcast( Type*, this ); return * rcast( Type*, this );
} }
@ -248,33 +253,53 @@ static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" );
// Desired width of the AST data structure. // Desired width of the AST data structure.
constexpr int const AST_POD_Size = 128; constexpr int const AST_POD_Size = 128;
void append ( AST* self, AST* other );
char const* debug_str ( AST* self );
AST* duplicate ( AST* self );
Code* entry ( AST* self, u32 idx );
bool has_entries( AST* self );
bool is_body ( AST* self );
String to_string ( AST* self );
char const* type_str ( AST* self );
#if GEN_CPP_SUPPORT_REFERENCES
void append ( AST& self, AST& other ) { return append(& self, & other); }
bool is_body ( AST& self ) { return is_body(& self); }
char const* debug_str( AST& self ) { return debug_str( & self ); }
String to_string( AST& self ) { return to_string( & self ); }
char const* type_str ( AST& self ) { return type_str( & self ); }
#endif
/* /*
Simple AST POD with functionality to seralize into C++ syntax. Simple AST POD with functionality to seralize into C++ syntax.
*/ */
struct AST struct AST
{ {
#if GEN_SUPPORT_CPP_MEMBER_FEATURES
# pragma region Member Functions # pragma region Member Functions
void append ( AST* other ); void append ( AST* other ) { GEN_NS append(this, other); }
char const* debug_str (); char const* debug_str () { return GEN_NS debug_str(this); }
AST* duplicate (); AST* duplicate () { return GEN_NS duplicate(this); }
Code& entry ( u32 idx ); Code* entry ( u32 idx ) { return GEN_NS entry(this, idx); }
bool has_entries(); bool has_entries();
bool is_equal ( AST* other ); bool is_equal ( AST* other );
bool is_body(); bool is_body() { return GEN_NS is_body(this); }
char const* type_str(); char const* type_str() { return GEN_NS type_str(this); }
bool validate_body(); bool validate_body();
String to_string(); String to_string(); //{ return GEN_NS to_string(this); }
neverinline
void to_string( String& result );
template< class Type > template< class Type >
forceinline Type cast() forceinline Type code_cast()
{ {
return * this; return * this;
} }
neverinline
void to_string( String& result );
# pragma endregion Member Functions
#endif
operator Code(); operator Code();
operator CodeBody(); operator CodeBody();
operator CodeAttributes(); operator CodeAttributes();
@ -305,7 +330,6 @@ struct AST
operator CodeUnion(); operator CodeUnion();
operator CodeUsing(); operator CodeUsing();
operator CodeVar(); operator CodeVar();
# pragma endregion Member Functions
constexpr static constexpr static
int ArrSpecs_Cap = int ArrSpecs_Cap =
@ -446,12 +470,9 @@ struct AST_POD
}; };
}; };
struct test {
SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers
AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
};
constexpr int pls = sizeof(test); // TODO(Ed): Convert
String to_string ( AST* self ) { return self->to_string(); }
// Its intended for the AST to have equivalent size to its POD. // Its intended for the AST to have equivalent size to its POD.
// All extra functionality within the AST namespace should just be syntatic sugar. // All extra functionality within the AST namespace should just be syntatic sugar.

View File

@ -176,14 +176,14 @@ void CodeClass::to_string_def( String& result )
append_fmt( result, "%S : %s %S", ast->Name, access_level, ast->ParentType.to_string() ); append_fmt( result, "%S : %s %S", ast->Name, access_level, ast->ParentType.to_string() );
CodeType interface = ast->ParentType->Next->cast< CodeType >(); CodeType interface = ast->ParentType->Next->code_cast< CodeType >();
if ( interface ) if ( interface )
append( result, "\n" ); append( result, "\n" );
while ( interface ) while ( interface )
{ {
append_fmt( result, ", %S", interface.to_string() ); append_fmt( result, ", %S", interface.to_string() );
interface = interface->Next ? interface->Next->cast< CodeType >() : CodeType { nullptr }; interface = interface->Next ? interface->Next->code_cast< CodeType >() : CodeType { nullptr };
} }
} }
else if ( ast->Name ) else if ( ast->Name )
@ -353,7 +353,10 @@ void CodeEnum::to_string_fwd( String& result )
if ( ast->Attributes ) if ( ast->Attributes )
append_fmt( result, "%S ", ast->Attributes.to_string() ); append_fmt( result, "%S ", ast->Attributes.to_string() );
append_fmt( result, "enum %S : %S", ast->Name, ast->UnderlyingType.to_string() ); if ( ast->UnderlyingType )
append_fmt( result, "enum %S : %S", ast->Name, ast->UnderlyingType.to_string() );
else
append_fmt( result, "enum %S", ast->Name );
if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) if ( ast->Parent.ast == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) )
{ {
@ -1007,14 +1010,14 @@ void CodeStruct::to_string_def( String& result )
append_fmt( result, "%S : %s %S", ast->Name, access_level, ast->ParentType.to_string() ); append_fmt( result, "%S : %s %S", ast->Name, access_level, ast->ParentType.to_string() );
CodeType interface = ast->ParentType->Next->cast< CodeType >(); CodeType interface = ast->ParentType->Next->code_cast< CodeType >();
if ( interface ) if ( interface )
append( result, "\n" ); append( result, "\n" );
while ( interface ) while ( interface )
{ {
append_fmt( result, ", %S", interface.to_string() ); append_fmt( result, ", %S", interface.to_string() );
interface = interface->Next ? interface->Next->cast< CodeType >() : CodeType { nullptr }; interface = interface->Next ? interface->Next->code_cast< CodeType >() : CodeType { nullptr };
} }
} }
else if ( ast->Name ) else if ( ast->Name )

View File

@ -11,37 +11,30 @@ struct CodeBody
void append( Code other ) void append( Code other )
{ {
if (other.is_body()) GEN_ASSERT(other.ast != nullptr);
{
append( other.cast<CodeBody>() ); if (other.is_body()) {
append( cast(CodeBody, & other) );
} }
raw()->append( other.ast );
GEN_NS append( raw(), other.ast );
} }
void append( CodeBody body ) void append( CodeBody body )
{ {
for ( Code entry : body ) for ( Code entry : body ) {
{
append( entry ); append( entry );
} }
} }
bool has_entries() bool has_entries() { return GEN_NS has_entries(rcast( AST*, ast )); }
{ AST* raw() { return rcast( AST*, ast ); }
return rcast( AST*, ast )->has_entries();
}
void to_string( String& result ); void to_string( String& result );
void to_string_export( String& result ); void to_string_export( String& result );
AST* raw()
{ AST_Body* operator->() { return ast; }
return rcast( AST*, ast );
} operator Code() { return * rcast( Code*, this ); }
AST_Body* operator->()
{
return ast;
}
operator Code()
{
return * rcast( Code*, this );
}
#pragma region Iterator #pragma region Iterator
Code begin() Code begin()
{ {

View File

@ -11,7 +11,7 @@ inline char const* Code::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code Code::duplicate() inline Code Code::duplicate()
@ -87,7 +87,7 @@ inline char const* CodeBody::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeBody::duplicate() inline Code CodeBody::duplicate()
@ -163,7 +163,7 @@ inline char const* CodeAttributes::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeAttributes::duplicate() inline Code CodeAttributes::duplicate()
@ -259,7 +259,7 @@ inline char const* CodeComment::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeComment::duplicate() inline Code CodeComment::duplicate()
@ -355,7 +355,7 @@ inline char const* CodeConstructor::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeConstructor::duplicate() inline Code CodeConstructor::duplicate()
@ -451,7 +451,7 @@ inline char const* CodeClass::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeClass::duplicate() inline Code CodeClass::duplicate()
@ -527,7 +527,7 @@ inline char const* CodeDefine::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeDefine::duplicate() inline Code CodeDefine::duplicate()
@ -623,7 +623,7 @@ inline char const* CodeDestructor::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeDestructor::duplicate() inline Code CodeDestructor::duplicate()
@ -719,7 +719,7 @@ inline char const* CodeEnum::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeEnum::duplicate() inline Code CodeEnum::duplicate()
@ -815,7 +815,7 @@ inline char const* CodeExec::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeExec::duplicate() inline Code CodeExec::duplicate()
@ -911,7 +911,7 @@ inline char const* CodeExtern::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeExtern::duplicate() inline Code CodeExtern::duplicate()
@ -1007,7 +1007,7 @@ inline char const* CodeFriend::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeFriend::duplicate() inline Code CodeFriend::duplicate()
@ -1103,7 +1103,7 @@ inline char const* CodeFn::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeFn::duplicate() inline Code CodeFn::duplicate()
@ -1199,7 +1199,7 @@ inline char const* CodeInclude::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeInclude::duplicate() inline Code CodeInclude::duplicate()
@ -1295,7 +1295,7 @@ inline char const* CodeModule::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeModule::duplicate() inline Code CodeModule::duplicate()
@ -1391,7 +1391,7 @@ inline char const* CodeNS::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeNS::duplicate() inline Code CodeNS::duplicate()
@ -1487,7 +1487,7 @@ inline char const* CodeOperator::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeOperator::duplicate() inline Code CodeOperator::duplicate()
@ -1583,7 +1583,7 @@ inline char const* CodeOpCast::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeOpCast::duplicate() inline Code CodeOpCast::duplicate()
@ -1679,7 +1679,7 @@ inline char const* CodeParam::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeParam::duplicate() inline Code CodeParam::duplicate()
@ -1755,7 +1755,7 @@ inline char const* CodePragma::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodePragma::duplicate() inline Code CodePragma::duplicate()
@ -1851,7 +1851,7 @@ inline char const* CodePreprocessCond::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodePreprocessCond::duplicate() inline Code CodePreprocessCond::duplicate()
@ -1947,7 +1947,7 @@ inline char const* CodeSpecifiers::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeSpecifiers::duplicate() inline Code CodeSpecifiers::duplicate()
@ -2023,7 +2023,7 @@ inline char const* CodeStruct::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeStruct::duplicate() inline Code CodeStruct::duplicate()
@ -2099,7 +2099,7 @@ inline char const* CodeTemplate::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeTemplate::duplicate() inline Code CodeTemplate::duplicate()
@ -2195,7 +2195,7 @@ inline char const* CodeType::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeType::duplicate() inline Code CodeType::duplicate()
@ -2291,7 +2291,7 @@ inline char const* CodeTypedef::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeTypedef::duplicate() inline Code CodeTypedef::duplicate()
@ -2387,7 +2387,7 @@ inline char const* CodeUnion::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeUnion::duplicate() inline Code CodeUnion::duplicate()
@ -2483,7 +2483,7 @@ inline char const* CodeUsing::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeUsing::duplicate() inline Code CodeUsing::duplicate()
@ -2579,7 +2579,7 @@ inline char const* CodeVar::debug_str()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast( AST*, ast )->debug_str(); return GEN_NS debug_str( rcast( AST*, ast ) );
} }
inline Code CodeVar::duplicate() inline Code CodeVar::duplicate()

View File

@ -4,56 +4,62 @@
#endif #endif
inline inline
void AST::append( AST* other ) void append( AST* self, AST* other )
{ {
GEN_ASSERT(self != nullptr);
GEN_ASSERT(other != nullptr);
if ( other->Parent ) if ( other->Parent )
other = other->duplicate(); other = duplicate(other);
other->Parent = this; other->Parent = self;
if ( Front == nullptr ) if ( self->Front == nullptr )
{ {
Front = other; self->Front = other;
Back = other; self->Back = other;
NumEntries++; self->NumEntries++;
return; return;
} }
AST* AST*
Current = Back; Current = self->Back;
Current->Next = other; Current->Next = other;
other->Prev = Current; other->Prev = Current;
Back = other; self->Back = other;
NumEntries++; self->NumEntries++;
} }
inline inline
Code& AST::entry( u32 idx ) Code* entry( AST* self, u32 idx )
{ {
AST** current = & Front; GEN_ASSERT(self != nullptr);
AST** current = & self->Front;
while ( idx >= 0 && current != nullptr ) while ( idx >= 0 && current != nullptr )
{ {
if ( idx == 0 ) if ( idx == 0 )
return * rcast( Code*, current); return rcast( Code*, current);
current = & ( * current )->Next; current = & ( * current )->Next;
idx--; idx--;
} }
return * rcast( Code*, current); return rcast( Code*, current);
} }
inline inline
bool AST::has_entries() bool has_entries(AST* self)
{ {
return NumEntries > 0; GEN_ASSERT(self != nullptr);
return self->NumEntries > 0;
} }
inline inline
bool AST::is_body() bool is_body(AST* self)
{ {
switch (Type) GEN_ASSERT(self != nullptr);
switch (self->Type)
{ {
case ECode::Enum_Body: case ECode::Enum_Body:
case ECode::Class_Body: case ECode::Class_Body:
@ -70,9 +76,10 @@ bool AST::is_body()
} }
inline inline
char const* AST::type_str() char const* type_str(AST* self)
{ {
return ECode::to_str( Type ); GEN_ASSERT(self != nullptr);
return ECode::to_str( self->Type );
} }
inline inline
@ -117,7 +124,7 @@ void CodeParam::append( CodeParam other )
AST* entry = (AST*) other.ast; AST* entry = (AST*) other.ast;
if ( entry->Parent ) if ( entry->Parent )
entry = entry->duplicate(); entry = GEN_NS duplicate( entry );
entry->Parent = self; entry->Parent = self;

View File

@ -30,7 +30,7 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
last = & back(Global_AllocatorBuckets); last = & back(Global_AllocatorBuckets);
} }
return alloc_align( allocator_info(* last), size, alignment ); return alloc_align( allocator_info(last), size, alignment );
} }
case EAllocation_FREE: case EAllocation_FREE:
{ {
@ -306,7 +306,7 @@ void deinit()
do do
{ {
Pool* code_pool = & CodePools[index]; Pool* code_pool = & CodePools[index];
free(* code_pool); free(code_pool);
index++; index++;
} }
while ( left--, left ); while ( left--, left );
@ -316,7 +316,7 @@ void deinit()
do do
{ {
Arena* string_arena = & StringArenas[index]; Arena* string_arena = & StringArenas[index];
free(* string_arena); free(string_arena);
index++; index++;
} }
while ( left--, left ); while ( left--, left );
@ -326,7 +326,7 @@ void deinit()
free(CodePools); free(CodePools);
free(StringArenas); free(StringArenas);
free(LexArena); free(& LexArena);
free(PreprocessorDefines); free(PreprocessorDefines);
@ -335,7 +335,7 @@ void deinit()
do do
{ {
Arena* bucket = & Global_AllocatorBuckets[ index ]; Arena* bucket = & Global_AllocatorBuckets[ index ];
free(* bucket); free(bucket);
index++; index++;
} }
while ( left--, left ); while ( left--, left );
@ -387,7 +387,7 @@ AllocatorInfo get_string_allocator( s32 str_length )
last = & back(StringArenas); last = & back(StringArenas);
} }
return allocator_info(* last); return allocator_info(last);
} }
// Will either make or retrive a code string. // Will either make or retrive a code string.
@ -425,7 +425,7 @@ Code make_code()
allocator = & back(CodePools); allocator = & back(CodePools);
} }
Code result { rcast( AST*, alloc( allocator_info(* allocator), sizeof(AST) )) }; Code result { rcast( AST*, alloc( allocator_info(allocator), sizeof(AST) )) };
mem_set( result.ast, 0, sizeof(AST) ); mem_set( result.ast, 0, sizeof(AST) );
// result->Type = ECode::Invalid; // result->Type = ECode::Invalid;

View File

@ -17,7 +17,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
char tok_map_mem[ TokenFmt_TokenMap_MemSize ]; char tok_map_mem[ TokenFmt_TokenMap_MemSize ];
tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) ); tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) );
tok_map = hashtable_init<StrC>( allocator_info(tok_map_arena) ); tok_map = hashtable_init<StrC>( allocator_info(& tok_map_arena) );
s32 left = num_tokens - 1; s32 left = num_tokens - 1;
@ -95,7 +95,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
} }
clear(tok_map); clear(tok_map);
free(tok_map_arena); free(& tok_map_arena);
ssize result = buf_size - remaining; ssize result = buf_size - remaining;

View File

@ -1925,7 +1925,7 @@ CodeBody def_global_body( s32 num, ... )
switch (entry->Type) switch (entry->Type)
{ {
case Global_Body: case Global_Body:
result.append( entry.cast<CodeBody>() ) ; result.append( entry.code_cast<CodeBody>() ) ;
continue; continue;
GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES
@ -1966,7 +1966,7 @@ CodeBody def_global_body( s32 num, Code* codes )
switch (entry->Type) switch (entry->Type)
{ {
case Global_Body: case Global_Body:
result.append( entry.cast<CodeBody>() ) ; result.append( entry.code_cast<CodeBody>() ) ;
continue; continue;
GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES

View File

@ -579,7 +579,7 @@ TokArray lex( StrC content )
if ( left <= 0 ) if ( left <= 0 )
{ {
log_failure( "gen::lex: no tokens found (only whitespace provided)" ); log_failure( "gen::lex: no tokens found (only whitespace provided)" );
return { { nullptr }, 0 }; return { {}, 0 };
} }
foreach( StringCached, entry, PreprocessorDefines ) foreach( StringCached, entry, PreprocessorDefines )
@ -652,7 +652,7 @@ TokArray lex( StrC content )
continue; continue;
case Lex_ReturnNull: case Lex_ReturnNull:
return { { nullptr }, 0 }; return { {}, 0 };
} }
} }
case '.': case '.':
@ -1256,7 +1256,7 @@ TokArray lex( StrC content )
if ( num(Tokens) == 0 ) if ( num(Tokens) == 0 )
{ {
log_failure( "Failed to lex any tokens" ); log_failure( "Failed to lex any tokens" );
return { { nullptr }, 0 }; return { {}, 0 };
} }
clear(defines); clear(defines);

View File

@ -132,12 +132,12 @@ bool TokArray::__eat( TokType type )
internal internal
void init() void init()
{ {
Tokens = array_init_reserve<Token>( allocator_info(LexArena) Tokens = array_init_reserve<Token>( allocator_info( & LexArena)
, ( LexAllocator_Size - sizeof( ArrayHeader ) ) / sizeof(Token) , ( LexAllocator_Size - sizeof( ArrayHeader ) ) / sizeof(Token)
); );
fixed_arena_init(defines_map_arena); fixed_arena_init(& defines_map_arena);
defines = hashtable_init_reserve<StrC>( allocator_info(defines_map_arena), 256 ); defines = hashtable_init_reserve<StrC>( allocator_info( & defines_map_arena), 256 );
} }
internal internal
@ -714,7 +714,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false )
char interface_arr_mem[ kilobytes(4) ] {0}; char interface_arr_mem[ kilobytes(4) ] {0};
Array<CodeType> interfaces; { Array<CodeType> interfaces; {
Arena arena = arena_init_from_memory( interface_arr_mem, kilobytes(4) ); Arena arena = arena_init_from_memory( interface_arr_mem, kilobytes(4) );
interfaces = array_init_reserve<CodeType>( allocator_info(arena), 4 ); interfaces = array_init_reserve<CodeType>( allocator_info(& arena), 4 );
} }
// TODO(Ed) : Make an AST_DerivedType, we'll store any arbitary derived type into there as a linear linked list of them. // TODO(Ed) : Make an AST_DerivedType, we'll store any arbitary derived type into there as a linear linked list of them.
@ -4910,10 +4910,12 @@ CodeTypedef parse_typedef()
|| currtok.Type == TokType::Decl_Struct || currtok.Type == TokType::Decl_Struct
|| currtok.Type == TokType::Decl_Union; || currtok.Type == TokType::Decl_Union;
// This code is highly correlated with parse_complicated_definition // This code is highly correlated with parse_complicated_definition
if ( is_complicated ) if ( is_complicated )
{ {
TokArray tokens = Context.Tokens; TokArray tokens = Context.Tokens;
TokType which = currtok.Type;
s32 idx = tokens.Idx; s32 idx = tokens.Idx;
s32 level = 0; s32 level = 0;
@ -4929,73 +4931,80 @@ CodeTypedef parse_typedef()
break; break;
} }
if ( (idx - 2 ) == tokens.Idx ) Token pre_foward_tok = currtok;
if ( (idx - 3 ) == tokens.Idx )
{ {
log_fmt("Identified forward typedef\n");
// Its a forward declaration only // Its a forward declaration only
type = parse_forward_or_definition( currtok.Type, from_typedef ); type = parse_forward_or_definition( which, from_typedef );
// <ModuleFalgs> typedef <UnderlyingType: Forward Decl> // <ModuleFalgs> typedef <UnderlyingType: Forward Decl>
} }
else
Token tok = tokens[ idx - 1 ];
if ( tok.Type == TokType::Identifier )
{ {
tok = tokens[ idx - 2 ]; Token tok = tokens.Arr[ idx - 1 ];
if ( tok.Type == TokType::Identifier )
bool is_indirection = tok.Type == TokType::Ampersand
|| tok.Type == TokType::Star;
bool ok_to_parse = false;
if ( tok.Type == TokType::BraceCurly_Close )
{ {
// Its an inplace definition log_fmt("Found id\n");
// typdef <which> <type_identifier> { ... } <identifier>; tok = tokens.Arr[ idx - 2 ];
ok_to_parse = true;
}
else if ( tok.Type == TokType::Identifier && tokens[ idx - 3 ].Type == TokType::Decl_Struct )
{
// Its a variable with type ID using struct namespace.
// <which> <type_identifier> <identifier>;
ok_to_parse = true;
}
else if ( is_indirection )
{
// Its a indirection type with type ID using struct namespace.
// <which> <type_identifier>* <identifier>;
ok_to_parse = true;
}
if ( ! ok_to_parse ) bool is_indirection = tok.Type == TokType::Ampersand
|| tok.Type == TokType::Star;
bool ok_to_parse = false;
Token temp_3 = tokens.Arr[ idx - 3 ];
if ( tok.Type == TokType::BraceCurly_Close )
{
// Its an inplace definition
// typedef <which> <type_identifier> { ... } <identifier>;
ok_to_parse = true;
}
else if ( tok.Type == TokType::Identifier && tokens.Arr[ idx - 3 ].Type == which )
{
// Its a variable with type ID using which namespace.
// typedef <which> <type_identifier> <identifier>;
ok_to_parse = true;
}
else if ( is_indirection )
{
// Its a indirection type with type ID using struct namespace.
// typedef <which> <type_identifier>* <identifier>;
ok_to_parse = true;
}
if ( ! ok_to_parse )
{
log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() );
Context.pop();
return CodeInvalid;
}
// TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type.
// type = parse_type();
type = parse_forward_or_definition( which, from_typedef );
// <ModuleFalgs> typedef <UnderlyingType>
}
else if ( tok.Type == TokType::BraceCurly_Close )
{
// Its a definition
// <which> { ... };
type = parse_forward_or_definition( currtok.Type, from_typedef );
// <ModuleFalgs> typedef <UnderlyingType>
}
else if ( tok.Type == TokType::BraceSquare_Close)
{
// Its an array definition
// <which> <type_identifier> <identifier> [ ... ];
type = parse_type();
// <ModuleFalgs> typedef <UnderlyingType>
}
else
{ {
log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() ); log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() );
Context.pop(); Context.pop();
return CodeInvalid; return CodeInvalid;
} }
// TODO(Ed) : I'm not sure if I have to use parse_type here, I'd rather not as that would complicate parse_type.
// type = parse_type();
type = parse_forward_or_definition( currtok.Type, from_typedef );
// <ModuleFalgs> typedef <UnderlyingType>
}
else if ( tok.Type == TokType::BraceCurly_Close )
{
// Its a definition
// <which> { ... };
type = parse_forward_or_definition( currtok.Type, from_typedef );
// <ModuleFalgs> typedef <UnderlyingType>
}
else if ( tok.Type == TokType::BraceSquare_Close)
{
// Its an array definition
// <which> <type_identifier> <identifier> [ ... ];
type = parse_type();
// <ModuleFalgs> typedef <UnderlyingType>
}
else
{
log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() );
Context.pop();
return CodeInvalid;
} }
} }
else else
@ -5057,7 +5066,7 @@ CodeTypedef parse_typedef()
// Type needs to be aware of its parent so that it can be serialized properly. // Type needs to be aware of its parent so that it can be serialized properly.
if ( type->Type == Typename && array_expr && array_expr->Type != Invalid ) if ( type->Type == Typename && array_expr && array_expr->Type != Invalid )
type.cast<CodeType>()->ArrExpr = array_expr; type.code_cast<CodeType>()->ArrExpr = array_expr;
if ( inline_cmt ) if ( inline_cmt )
result->InlineCmt = inline_cmt; result->InlineCmt = inline_cmt;

View File

@ -25,7 +25,7 @@ enum AccessSpec enum_underlying(u32)
AccessSpec_SizeDef = GEN_U32_MAX, AccessSpec_SizeDef = GEN_U32_MAX,
}; };
static_assert( size_of(AccessSpec) == size_of(u32)); static_assert( size_of(AccessSpec) == size_of(u32), "AccessSpec not u32 size" );
inline inline
char const* to_str( AccessSpec type ) char const* to_str( AccessSpec type )
@ -54,7 +54,7 @@ enum CodeFlag enum_underlying(u32)
CodeFlag_SizeDef = GEN_U32_MAX, CodeFlag_SizeDef = GEN_U32_MAX,
}; };
static_assert( size_of(CodeFlag) == size_of(u32)); static_assert( size_of(CodeFlag) == size_of(u32), "CodeFlag not u32 size" );
// Used to indicate if enum definitoin is an enum class or regular enum. // Used to indicate if enum definitoin is an enum class or regular enum.
enum EnumDecl enum_underlying(u8) enum EnumDecl enum_underlying(u8)
@ -77,7 +77,7 @@ enum ModuleFlag enum_underlying(u32)
ModuleFlag_SizeDef = GEN_U32_MAX, ModuleFlag_SizeDef = GEN_U32_MAX,
}; };
static_assert( size_of(ModuleFlag) == size_of(u32)); static_assert( size_of(ModuleFlag) == size_of(u32), "ModuleFlag not u32 size" );
inline inline
StrC to_str( ModuleFlag flag ) StrC to_str( ModuleFlag flag )
@ -110,4 +110,4 @@ enum EPreprocessCond enum_underlying(u32)
EPreprocessCond_SizeDef = GEN_U32_MAX, EPreprocessCond_SizeDef = GEN_U32_MAX,
}; };
static_assert( size_of(EPreprocessCond) == size_of(u32)); static_assert( size_of(EPreprocessCond) == size_of(u32), "EPreprocessCond not u32 size" );

View File

@ -23,7 +23,11 @@
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) ) #define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
#endif #endif
#if ! GEN_C_COMPILER #if ! GEN_C_COMPILER
# ifndef cast
# define cast( type, value ) (tmpl_cast<type>( value ))
# endif
# ifndef ccast # ifndef ccast
# define ccast( type, value ) ( const_cast< type >( (value) ) ) # define ccast( type, value ) ( const_cast< type >( (value) ) )
# endif # endif
@ -37,11 +41,14 @@
# define scast( type, value ) static_cast< type >( value ) # define scast( type, value ) static_cast< type >( value )
# endif # endif
#else #else
# ifndef cast
# define cast( type, value ) ( (type)(value) )
# endif
# ifndef ccast # ifndef ccast
# define ccast( type, value ) ( (type)(value) ) # define ccast( type, value ) ( (type)(value) )
# endif # endif
# ifndef pcast # ifndef pcast
# define pcast( type, value ) ( (type)(value) ) # define pcast( type, value ) ( * (type*)(value) )
# endif # endif
# ifndef rcast # ifndef rcast
# define rcast( type, value ) ( (type)(value) ) # define rcast( type, value ) ( (type)(value) )
@ -181,8 +188,14 @@
# endif # endif
#endif #endif
#if !defined(GEN_SUPPORT_CPP_MEMBER_FEATURES) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L) #if !defined(GEN_SUPPORT_CPP_REFERENCES) && (GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
# define GEN_SUPPORT_CPP_MEMBER_FEATURES 0 # undef GEN_SUPPORT_CPP_REFERENCES
# define GEN_SUPPORT_CPP_REFERENCES 0
#endif
#if !defined(GEN_SUPPORT_CPP_MEMBER_FEATURES) && (GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
# undef GEN_SUPPORT_CPP_MEMBER_FEATURES
# define GEN_SUPPORT_CPP_MEMBER_FEATURES 0
#endif #endif
#if !defined(typeof) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L) #if !defined(typeof) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L)
@ -215,4 +228,10 @@
# define enum_underlying(type) : type # define enum_underlying(type) : type
#endif #endif
#if GEN_COMPILER_C
# ifndef nullptr
# define nullptr NULL
# endif
#endif
#pragma endregion Macros #pragma endregion Macros

View File

@ -62,21 +62,23 @@ void zero_size( void* ptr, ssize size );
//! Clears up an array. //! Clears up an array.
#define zero_array( a, count ) zero_size( ( a ), size_of( *( a ) ) * count ) #define zero_array( a, count ) zero_size( ( a ), size_of( *( a ) ) * count )
enum AllocType : u8 enum AllocType_Def //enum_underlying(u8)
{ {
EAllocation_ALLOC, EAllocation_ALLOC,
EAllocation_FREE, EAllocation_FREE,
EAllocation_FREE_ALL, EAllocation_FREE_ALL,
EAllocation_RESIZE, EAllocation_RESIZE,
}; };
typedef enum AllocType_Def AllocType;
typedef void*(AllocatorProc)( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); typedef void*(AllocatorProc)( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
struct AllocatorInfo struct AllocatorInfo_Def
{ {
AllocatorProc* Proc; AllocatorProc* Proc;
void* Data; void* Data;
}; };
typedef struct AllocatorInfo_Def AllocatorInfo;
enum AllocFlag enum AllocFlag
{ {
@ -132,7 +134,7 @@ void* default_resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize ne
void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
//! The heap allocator backed by operating system's memory manager. //! The heap allocator backed by operating system's memory manager.
constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr }; } constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
//! Helper to allocate memory using heap allocator. //! Helper to allocate memory using heap allocator.
#define malloc( sz ) alloc( heap(), sz ) #define malloc( sz ) alloc( heap(), sz )
@ -170,26 +172,26 @@ ssize gen_virtual_memory_page_size( ssize* alignment_out );
#pragma region Arena #pragma region Arena
struct Arena; struct Arena;
AllocatorInfo allocator_info( Arena& arena ); AllocatorInfo allocator_info( Arena* arena );
// Remove static keyword and rename allocator_proc // Remove static keyword and rename allocator_proc
void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
// Add these declarations after the Arena struct // Add these declarations after the Arena struct
Arena arena_init_from_allocator(AllocatorInfo backing, ssize size); Arena arena_init_from_allocator(AllocatorInfo backing, ssize size);
Arena arena_init_from_memory( void* start, ssize size ); Arena arena_init_from_memory ( void* start, ssize size );
Arena init_sub(Arena& parent, ssize size);
ssize alignment_of(Arena& arena, ssize alignment); Arena init_sub (Arena* parent, ssize size);
ssize alignment_of (Arena* arena, ssize alignment);
void free (Arena* arena);
ssize size_remaining(Arena* arena, ssize alignment);
// This id is defined by Unreal for asserts // This id is defined by Unreal for asserts
#pragma push_macro("check") #pragma push_macro("check")
#undef check #undef check
void check(Arena& arena); void check(Arena* arena);
#pragma pop_macro("check") #pragma pop_macro("check")
void free(Arena& arena);
ssize size_remaining(Arena& arena, ssize alignment);
struct Arena struct Arena
{ {
AllocatorInfo Backing; AllocatorInfo Backing;
@ -200,29 +202,45 @@ struct Arena
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_SUPPORT_CPP_MEMBER_FEATURES
#pragma region Member Mapping #pragma region Member Mapping
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(* this); } forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); }
forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return GEN_NS arena_allocator_proc( allocator_data, type, size, alignment, old_memory, old_size, flags ); } forceinline static void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) { return GEN_NS arena_allocator_proc( allocator_data, type, size, alignment, old_memory, old_size, flags ); }
forceinline static Arena init_from_memory( void* start, ssize size ) { return GEN_NS arena_init_from_memory( start, size ); } forceinline static Arena init_from_memory( void* start, ssize size ) { return GEN_NS arena_init_from_memory( start, size ); }
forceinline static Arena init_from_allocator( AllocatorInfo backing, ssize size ) { return GEN_NS arena_init_from_allocator( backing, size ); } forceinline static Arena init_from_allocator( AllocatorInfo backing, ssize size ) { return GEN_NS arena_init_from_allocator( backing, size ); }
forceinline static Arena init_sub( Arena& parent, ssize size ) { return GEN_NS arena_init_from_allocator( parent.Backing, size ); } forceinline static Arena init_sub( Arena& parent, ssize size ) { return GEN_NS arena_init_from_allocator( parent.Backing, size ); }
forceinline ssize alignment_of( ssize alignment ) { return GEN_NS alignment_of(* this, alignment); } forceinline ssize alignment_of( ssize alignment ) { return GEN_NS alignment_of(this, alignment); }
forceinline void free() { return GEN_NS free(* this); } forceinline void free() { return GEN_NS free(this); }
forceinline ssize size_remaining( ssize alignment ) { return GEN_NS size_remaining(* this, alignment); } forceinline ssize size_remaining( ssize alignment ) { return GEN_NS size_remaining(this, alignment); }
// This id is defined by Unreal for asserts // This id is defined by Unreal for asserts
#pragma push_macro("check") #pragma push_macro("check")
#undef check #undef check
forceinline void check() { GEN_NS check(* this); } forceinline void check() { GEN_NS check(this); }
#pragma pop_macro("check") #pragma pop_macro("check")
#pragma endregion Member Mapping #pragma endregion Member Mapping
#endif #endif
}; };
#if GEN_SUPPORT_CPP_REFERENCES
forceinline AllocatorInfo allocator_info(Arena& arena ) { return allocator_info(& arena); }
forceinline Arena init_sub (Arena& parent, ssize size) { return init_sub( & parent, size); }
forceinline ssize alignment_of (Arena& arena, ssize alignment) { return alignment_of( & arena, alignment); }
forceinline void free (Arena& arena) { return free(& arena); }
forceinline ssize size_remaining(Arena& arena, ssize alignment) { return size_remaining(& arena, alignment); }
// This id is defined by Unreal for asserts
#pragma push_macro("check")
#undef check
forceinline void check(Arena& arena) { return check(& arena); };
#pragma pop_macro("check")
#endif
inline inline
AllocatorInfo allocator_info( Arena& arena ) { AllocatorInfo allocator_info( Arena* arena ) {
return { arena_allocator_proc, &arena }; GEN_ASSERT(arena != nullptr);
return { arena_allocator_proc, arena };
} }
inline inline
@ -251,18 +269,20 @@ Arena arena_init_from_allocator(AllocatorInfo backing, ssize size) {
} }
inline inline
Arena init_sub(Arena& parent, ssize size) { Arena init_sub(Arena* parent, ssize size) {
return arena_init_from_allocator(parent.Backing, size); GEN_ASSERT(parent != nullptr);
return arena_init_from_allocator(parent->Backing, size);
} }
inline inline
ssize alignment_of(Arena& arena, ssize alignment) ssize alignment_of(Arena* arena, ssize alignment)
{ {
GEN_ASSERT(arena != nullptr);
ssize alignment_offset, result_pointer, mask; ssize alignment_offset, result_pointer, mask;
GEN_ASSERT(is_power_of_two(alignment)); GEN_ASSERT(is_power_of_two(alignment));
alignment_offset = 0; alignment_offset = 0;
result_pointer = (ssize)arena.PhysicalStart + arena.TotalUsed; result_pointer = (ssize)arena->PhysicalStart + arena->TotalUsed;
mask = alignment - 1; mask = alignment - 1;
if (result_pointer & mask) if (result_pointer & mask)
@ -274,26 +294,29 @@ ssize alignment_of(Arena& arena, ssize alignment)
#pragma push_macro("check") #pragma push_macro("check")
#undef check #undef check
inline inline
void check(Arena& arena) void check(Arena* arena)
{ {
GEN_ASSERT(arena.TempCount == 0); GEN_ASSERT(arena != nullptr );
GEN_ASSERT(arena->TempCount == 0);
} }
#pragma pop_macro("check") #pragma pop_macro("check")
inline inline
void free(Arena& arena) void free(Arena* arena)
{ {
if (arena.Backing.Proc) GEN_ASSERT(arena != nullptr);
if (arena->Backing.Proc)
{ {
GEN_NS free(arena.Backing, arena.PhysicalStart); GEN_NS free(arena->Backing, arena->PhysicalStart);
arena.PhysicalStart = nullptr; arena->PhysicalStart = nullptr;
} }
} }
inline inline
ssize size_remaining(Arena& arena, ssize alignment) ssize size_remaining(Arena* arena, ssize alignment)
{ {
ssize result = arena.TotalSize - (arena.TotalUsed + alignment_of(arena, alignment)); GEN_ASSERT(arena != nullptr);
ssize result = arena->TotalSize - (arena->TotalUsed + alignment_of(arena, alignment));
return result; return result;
} }
#pragma endregion Arena #pragma endregion Arena
@ -302,9 +325,14 @@ ssize size_remaining(Arena& arena, ssize alignment)
template<s32 Size> template<s32 Size>
struct FixedArena; struct FixedArena;
template<s32 Size> AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena );
template<s32 Size> FixedArena<Size> fixed_arena_init(); template<s32 Size> FixedArena<Size> fixed_arena_init();
template<s32 Size> ssize size_remaining(FixedArena<Size>& fixed_arena, ssize alignment); template<s32 Size> AllocatorInfo allocator_info(FixedArena<Size>* fixed_arena );
template<s32 Size> ssize size_remaining(FixedArena<Size>* fixed_arena, ssize alignment);
#if GEN_SUPPORT_CPP_REFERENCES
template<s32 Size> AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena ) { return allocator_info(& fixed_arena); }
template<s32 Size> ssize size_remaining(FixedArena<Size>& fixed_arena, ssize alignment) { return size_remaining( & fixed_arena, alignment); }
#endif
// Just a wrapper around using an arena with memory associated with its scope instead of from an allocator. // Just a wrapper around using an arena with memory associated with its scope instead of from an allocator.
// Used for static segment or stack allocations. // Used for static segment or stack allocations.
@ -316,26 +344,29 @@ struct FixedArena
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_SUPPORT_CPP_MEMBER_FEATURES
#pragma region Member Mapping #pragma region Member Mapping
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(* this); } forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); }
forceinline static FixedArena init() { FixedArena result; GEN_NS fixed_arena_init<Size>(result); return result; } forceinline static FixedArena init() { FixedArena result; GEN_NS fixed_arena_init<Size>(result); return result; }
forceinline ssize size_remaining(ssize alignment) { GEN_NS size_remaining(*this, alignment); } forceinline ssize size_remaining(ssize alignment) { GEN_NS size_remaining(this, alignment); }
#pragma endregion Member Mapping #pragma endregion Member Mapping
#endif #endif
}; };
template<s32 Size> inline template<s32 Size> inline
AllocatorInfo allocator_info( FixedArena<Size>& fixed_arena ) { return { arena_allocator_proc, & fixed_arena.arena }; } AllocatorInfo allocator_info( FixedArena<Size>* fixed_arena ) {
GEN_ASSERT(fixed_arena);
template<s32 Size> inline return { arena_allocator_proc, & fixed_arena->arena };
void fixed_arena_init(FixedArena<Size>& result) {
zero_size(& result.memory[0], Size);
result.arena = arena_init_from_memory(& result.memory[0], Size);
} }
template<s32 Size> inline template<s32 Size> inline
ssize size_remaining(FixedArena<Size>& fixed_arena, ssize alignment) { void fixed_arena_init(FixedArena<Size>* result) {
return size_remaining(fixed_arena.arena, alignment); zero_size(& result->memory[0], Size);
result->arena = arena_init_from_memory(& result->memory[0], Size);
}
template<s32 Size> inline
ssize size_remaining(FixedArena<Size>* fixed_arena, ssize alignment) {
return size_remaining(fixed_arena->arena, alignment);
} }
using Arena_1KB = FixedArena< kilobytes( 1 ) >; using Arena_1KB = FixedArena< kilobytes( 1 ) >;
@ -355,12 +386,19 @@ using Arena_4MB = FixedArena< megabytes( 4 ) >;
#pragma region Pool #pragma region Pool
struct Pool; struct Pool;
AllocatorInfo allocator_info(Pool& pool); void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size); Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size);
Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align); Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align);
AllocatorInfo allocator_info(Pool* pool);
void clear(Pool* pool);
void free(Pool* pool);
#if GEN_SUPPORT_CPP_REFERENCES
AllocatorInfo allocator_info(Pool& pool);
void clear(Pool& pool); void clear(Pool& pool);
void free(Pool& pool); void free(Pool& pool);
#endif
struct Pool struct Pool
{ {
@ -374,20 +412,20 @@ struct Pool
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_SUPPORT_CPP_MEMBER_FEATURES
#pragma region Member Mapping #pragma region Member Mapping
forceinline operator AllocatorInfo() { return GEN_NS allocator_info(* this); } forceinline operator AllocatorInfo() { return GEN_NS allocator_info(this); }
forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return GEN_NS pool_allocator_proc(allocator_data, type, size, alignment, old_memory, old_size, flags); } forceinline static void* allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags) { return GEN_NS pool_allocator_proc(allocator_data, type, size, alignment, old_memory, old_size, flags); }
forceinline static Pool init(AllocatorInfo backing, ssize num_blocks, ssize block_size) { return GEN_NS pool_init(backing, num_blocks, block_size); } forceinline static Pool init(AllocatorInfo backing, ssize num_blocks, ssize block_size) { return GEN_NS pool_init(backing, num_blocks, block_size); }
forceinline static Pool init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align) { return GEN_NS pool_init_align(backing, num_blocks, block_size, block_align); } forceinline static Pool init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align) { return GEN_NS pool_init_align(backing, num_blocks, block_size, block_align); }
forceinline void clear() { GEN_NS clear(* this); } forceinline void clear() { GEN_NS clear( this); }
forceinline void free() { GEN_NS free(* this); } forceinline void free() { GEN_NS free( this); }
#pragma endregion #pragma endregion
#endif #endif
}; };
inline inline
AllocatorInfo allocator_info(Pool& pool) { AllocatorInfo allocator_info(Pool* pool) {
return { pool_allocator_proc, &pool }; return { pool_allocator_proc, pool };
} }
inline inline
@ -396,9 +434,9 @@ Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size) {
} }
inline inline
void free(Pool& pool) { void free(Pool* pool) {
if(pool.Backing.Proc) { if(pool->Backing.Proc) {
GEN_NS free(pool.Backing, pool.PhysicalStart); GEN_NS free(pool->Backing, pool->PhysicalStart);
} }
} }
#pragma endregion Pool #pragma endregion Pool

View File

@ -125,9 +125,13 @@
# include <intrin.h> # include <intrin.h>
# endif # endif
#if GEN_COMPILER_C
#include <assert.h>
#endif
#pragma endregion Mandatory Includes #pragma endregion Mandatory Includes
#if GEN_DONT_USE_NAMESPACE #if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C
# if GEN_COMPILER_C # if GEN_COMPILER_C
# define GEN_NS_ENUM_BEGIN # define GEN_NS_ENUM_BEGIN
# define GEN_NS_ENUM_END # define GEN_NS_ENUM_END

View File

@ -305,7 +305,7 @@ bool are_equal(String const& lhs, StrC rhs)
return false; return false;
for (ssize idx = 0; idx < length(lhs); ++idx) for (ssize idx = 0; idx < length(lhs); ++idx)
if (lhs[idx] != rhs[idx]) if (lhs[idx] != rhs.Ptr[idx])
return false; return false;
return true; return true;
@ -319,7 +319,7 @@ ssize avail_space(String const& str) {
inline inline
char& back(String& str) { char& back(String& str) {
return str.Data[length(str) - 1]; return str[length(str) - 1];
} }
inline inline
@ -335,7 +335,7 @@ bool contains(String const& str, StrC substring)
for (ssize idx = 0; idx <= main_len - sub_len; ++idx) for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
{ {
if (str_compare(str.Data + idx, substring.Ptr, sub_len) == 0) if (str_compare(str + idx, substring.Ptr, sub_len) == 0)
return true; return true;
} }
@ -355,7 +355,7 @@ bool contains(String const& str, String const& substring)
for (ssize idx = 0; idx <= main_len - sub_len; ++idx) for (ssize idx = 0; idx <= main_len - sub_len; ++idx)
{ {
if (str_compare(str.Data + idx, substring.Data, sub_len) == 0) if (str_compare(str + idx, substring, sub_len) == 0)
return true; return true;
} }
@ -380,7 +380,7 @@ String duplicate(String const& str, AllocatorInfo allocator) {
inline inline
void free(String& str) { void free(String& str) {
if (!str.Data) if (! str)
return; return;
StringHeader& header = get_header(str); StringHeader& header = get_header(str);
@ -389,7 +389,7 @@ void free(String& str) {
inline inline
StringHeader& get_header(String& str) { StringHeader& get_header(String& str) {
return *(StringHeader*)(str.Data - sizeof(StringHeader)); return *(StringHeader*)(scast(char*, str) - sizeof(StringHeader));
} }
inline inline

View File

@ -13,7 +13,7 @@ CodeBody gen_ecode( char const* path )
char scratch_mem[kilobytes(1)]; char scratch_mem[kilobytes(1)];
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( allocator_info(scratch), zero_terminate, path ); file_read_contents( allocator_info( & scratch), zero_terminate, path );
CSV_Object csv_nodes; CSV_Object csv_nodes;
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
@ -59,7 +59,7 @@ CodeBody gen_eoperator( char const* path )
char scratch_mem[kilobytes(4)]; char scratch_mem[kilobytes(4)];
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( allocator_info(scratch), zero_terminate, path ); file_read_contents( allocator_info(& scratch), zero_terminate, path );
CSV_Object csv_nodes; CSV_Object csv_nodes;
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
@ -115,7 +115,7 @@ CodeBody gen_especifier( char const* path )
char scratch_mem[kilobytes(4)]; char scratch_mem[kilobytes(4)];
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
file_read_contents( allocator_info(scratch), zero_terminate, path ); file_read_contents( allocator_info(& scratch), zero_terminate, path );
CSV_Object csv_nodes; CSV_Object csv_nodes;
csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); csv_parse( &csv_nodes, scratch_mem, GlobalAllocator, false );
@ -220,7 +220,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
char scratch_mem[kilobytes(16)]; char scratch_mem[kilobytes(16)];
Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) ); Arena scratch = arena_init_from_memory( scratch_mem, sizeof(scratch_mem) );
AllocatorInfo scratch_info = allocator_info(scratch); AllocatorInfo scratch_info = allocator_info(& scratch);
FileContents enum_content = file_read_contents( scratch_info, zero_terminate, etok_path ); FileContents enum_content = file_read_contents( scratch_info, zero_terminate, etok_path );
@ -342,8 +342,10 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
CodeBody gen_ast_inlines() CodeBody gen_ast_inlines()
{ {
#pragma push_macro("GEN_NS")
#pragma push_macro("rcast") #pragma push_macro("rcast")
#pragma push_macro("log_failure") #pragma push_macro("log_failure")
#undef GEN_NS
#undef rcast #undef rcast
#undef log_failure #undef log_failure
char const* code_impl_tmpl = stringize( char const* code_impl_tmpl = stringize(
@ -354,7 +356,7 @@ CodeBody gen_ast_inlines()
if ( ast == nullptr ) if ( ast == nullptr )
return "Code::debug_str: AST is null!"; return "Code::debug_str: AST is null!";
return rcast(AST*, ast)->debug_str(); return GEN_NS debug_str( rcast(AST*, ast) );
} }
inline inline
Code <typename>::duplicate() Code <typename>::duplicate()
@ -455,6 +457,7 @@ CodeBody gen_ast_inlines()
} }
\n \n
); );
#pragma pop_macro("GEN_NS")
CodeBody impl_code = parse_global_body( token_fmt( "typename", StrC name(Code), code_impl_tmpl )); CodeBody impl_code = parse_global_body( token_fmt( "typename", StrC name(Code), code_impl_tmpl ));
CodeBody impl_code_body = parse_global_body( token_fmt( "typename", StrC name(CodeBody), code_impl_tmpl )); CodeBody impl_code_body = parse_global_body( token_fmt( "typename", StrC name(CodeBody), code_impl_tmpl ));

View File

@ -226,6 +226,30 @@ if ( $c_library )
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms" write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
} }
Pop-Location Pop-Location
$unit = join-path $path_c_library "gen.c"
$executable = join-path $path_build "gen_c_library_test.exe"
if ($vendor -eq "clang") {
$compiler_args += "-x"
$compiler_args += "c"
} elseif ($vendor -eq "msvc") {
$compiler_args += "/TC"
}
build-simple $path_build $includes $compiler_args $linker_args $unit $executable
Push-Location $path_c_library
if ( Test-Path( $executable ) ) {
write-host "`nRunning c_library test"
$time_taken = Measure-Command { & $executable
| ForEach-Object {
write-host `t $_ -ForegroundColor Green
}
}
write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms"
}
Pop-Location
} }
if ( $unreal ) if ( $unreal )