From 80cb3f4ecaa7387865af4ad1febcd6806d91e060 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 1 Dec 2024 18:50:37 -0500 Subject: [PATCH] Significant progress reducing c++ feature usage in the library. --- project/bootstrap.cpp | 5 +- project/components/ast.cpp | 491 +++++++++++----------- project/components/ast.hpp | 57 ++- project/components/code_serialization.cpp | 13 +- project/components/code_types.hpp | 37 +- project/components/gen/ast_inlines.hpp | 58 +-- project/components/inlines.hpp | 49 ++- project/components/interface.cpp | 14 +- project/components/interface.untyped.cpp | 4 +- project/components/interface.upfront.cpp | 4 +- project/components/lexer.cpp | 6 +- project/components/parser.cpp | 129 +++--- project/components/types.hpp | 8 +- project/dependencies/macros.hpp | 25 +- project/dependencies/memory.hpp | 142 ++++--- project/dependencies/platform.hpp | 6 +- project/dependencies/strings.hpp | 12 +- project/helpers/helper.hpp | 13 +- scripts/build.ci.ps1 | 24 ++ 19 files changed, 611 insertions(+), 486 deletions(-) diff --git a/project/bootstrap.cpp b/project/bootstrap.cpp index ffa783b..24dd2bb 100644 --- a/project/bootstrap.cpp +++ b/project/bootstrap.cpp @@ -1,7 +1,8 @@ #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_ENFORCE_STRONG_CODE_TYPES #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 "helpers/push_ignores.inline.hpp" @@ -63,6 +64,8 @@ int gen_main() { gen::init(); + // PreprocessorDefines.append("GEN_NS"); + Code push_ignores = scan_file( "helpers/push_ignores.inline.hpp" ); Code pop_ignores = scan_file( "helpers/pop_ignores.inline.hpp" ); diff --git a/project/components/ast.cpp b/project/components/ast.cpp index d56eebf..5f8fa43 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -7,20 +7,21 @@ Code Code::Global; Code Code::Invalid; // 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) ); - if ( Parent ) - append_fmt( result, "\n\tParent : %S %S", Parent->type_str(), Name ? Name : "" ); + if ( self->Parent ) + append_fmt( result, "\n\tParent : %S %S", self->Parent->type_str(), self->Name ? self->Name : "" ); else append_fmt( result, "\n\tParent : %S", "Null" ); - append_fmt( result, "\n\tName : %S", Name ? Name : "Null" ); - append_fmt( result, "\n\tType : %S", type_str() ); - append_fmt( result, "\n\tModule Flags : %S", to_str( ModuleFlags ) ); + append_fmt( result, "\n\tName : %S", self->Name ? self->Name : "Null" ); + append_fmt( result, "\n\tType : %S", type_str(self) ); + append_fmt( result, "\n\tModule Flags : %S", to_str( self->ModuleFlags ) ); - switch ( Type ) + switch ( self->Type ) { using namespace ECode; @@ -29,10 +30,10 @@ char const* AST::debug_str() case Access_Private: case Access_Protected: case Access_Public: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); break; case Untyped: @@ -47,75 +48,75 @@ char const* AST::debug_str() case Preprocess_Else: case Preprocess_IfDef: case Preprocess_IfNotDef: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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; case Class: case Struct: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" ); - append_fmt( result, "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" ); - append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" ); + append_fmt( result, "\n\tParentType : %s", self->ParentType ? type_str(self->ParentType) : "Null" ); + append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); break; case Class_Fwd: case Struct_Fwd: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" ); - append_fmt( result, "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tParentAccess: %s", self->ParentType ? to_str( self->ParentAccess ) : "No Parent" ); + append_fmt( result, "\n\tParentType : %s", self->ParentType ? type_str(self->ParentType) : "Null" ); break; case Constructor: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" ); - append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); - append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? to_string(self->InitializerList) : "Null" ); + append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); + append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); break; case Constructor_Fwd: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" ); - append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tInitializerList: %S", self->InitializerList ? to_string(self->InitializerList) : "Null" ); + append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); break; case Destructor: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); break; case Destructor_Fwd: @@ -123,248 +124,248 @@ char const* AST::debug_str() case Enum: case Enum_Class: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); - append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" ); + append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); break; case Enum_Fwd: case Enum_Class_Fwd: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tUnderlying Type : %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" ); break; case Extern_Linkage: case Namespace: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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; case Friend: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? to_string(self->Declaration) : "Null" ); break; case Function: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); - append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); - append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); + append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); + append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); break; case Function_Fwd: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); - append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); + append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); break; case Module: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + append_fmt( result, "\n\tNext: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); break; case Operator: case Operator_Member: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); - append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); - append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); - append_fmt( result, "\n\tOp : %S", to_str( Op ) ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); + append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); + append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); + append_fmt( result, "\n\tOp : %S", to_str( self->Op ) ); break; case Operator_Fwd: case Operator_Member_Fwd: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); - append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); - append_fmt( result, "\n\tOp : %S", to_str( Op ) ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tReturnType: %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); + append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); + append_fmt( result, "\n\tOp : %S", to_str( self->Op ) ); break; case Operator_Cast: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); - append_fmt( result, "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" ); + append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); break; case Operator_Cast_Fwd: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" ); break; case Parameters: - append_fmt( result, "\n\tNumEntries: %d", NumEntries ); - append_fmt( result, "\n\tLast : %S", Last->Name ); - append_fmt( result, "\n\tNext : %S", Next->Name ); - append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); - append_fmt( result, "\n\tValue : %S", Value ? Value->to_string() : "Null" ); + append_fmt( result, "\n\tNumEntries: %d", self->NumEntries ); + append_fmt( result, "\n\tLast : %S", self->Last->Name ); + append_fmt( result, "\n\tNext : %S", self->Next->Name ); + append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" ); + append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" ); break; case Specifiers: { - append_fmt( result, "\n\tNumEntries: %d", NumEntries ); + append_fmt( result, "\n\tNumEntries: %d", self->NumEntries ); GEN_NS append( result, "\n\tArrSpecs: " ); s32 idx = 0; - s32 left = NumEntries; + s32 left = self->NumEntries; 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 ); 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; case Template: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" ); + append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); + append_fmt( result, "\n\tDeclaration: %S", self->Declaration ? to_string(self->Declaration) : "Null" ); break; case Typedef: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" ); break; case Typename: - append_fmt( result, "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tReturnType : %S", ReturnType ? ReturnType->to_string() : "Null" ); - append_fmt( result, "\n\tParams : %S", Params ? Params->to_string() : "Null" ); - append_fmt( result, "\n\tArrExpr : %S", ArrExpr ? ArrExpr->to_string() : "Null" ); + append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tReturnType : %S", self->ReturnType ? to_string(self->ReturnType) : "Null" ); + append_fmt( result, "\n\tParams : %S", self->Params ? to_string(self->Params) : "Null" ); + append_fmt( result, "\n\tArrExpr : %S", self->ArrExpr ? to_string(self->ArrExpr) : "Null" ); break; case Union: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tBody : %S", Body ? Body->debug_str() : "Null" ); + append_fmt( result, "\n\tAttributes: %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tBody : %S", self->Body ? debug_str(self->Body) : "Null" ); break; case Using: - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tUnderlyingType: %S", self->UnderlyingType ? to_string(self->UnderlyingType) : "Null" ); break; case Variable: - if ( Parent && Parent->Type == Variable ) + if ( self->Parent && self->Parent->Type == Variable ) { // Its a NextVar - append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tValue : %S", Value ? Value->to_string() : "Null" ); - append_fmt( result, "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" ); - append_fmt( result, "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" ); + append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? to_string(self->BitfieldSize) : "Null" ); + append_fmt( result, "\n\tNextVar : %S", self->NextVar ? debug_str(self->NextVar) : "Null" ); break; } - if ( Prev ) - append_fmt( result, "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); - if ( Next ) - append_fmt( result, "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( self->Prev ) + append_fmt( result, "\n\tPrev: %S %S", type_str(self->Prev), self->Prev->Name ? self->Prev->Name : "Null" ); + if ( self->Next ) + 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\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); - append_fmt( result, "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); - append_fmt( result, "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); - append_fmt( result, "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" ); - append_fmt( result, "\n\tValue : %S", Value ? Value->to_string() : "Null" ); - append_fmt( result, "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" ); + append_fmt( result, "\n\tInlineCmt : %S", self->InlineCmt ? self->InlineCmt->Content : "Null" ); + append_fmt( result, "\n\tAttributes : %S", self->Attributes ? to_string(self->Attributes) : "Null" ); + append_fmt( result, "\n\tSpecs : %S", self->Specs ? to_string(self->Specs) : "Null" ); + append_fmt( result, "\n\tValueType : %S", self->ValueType ? to_string(self->ValueType) : "Null" ); + append_fmt( result, "\n\tBitfieldSize: %S", self->BitfieldSize ? to_string(self->BitfieldSize) : "Null" ); + append_fmt( result, "\n\tValue : %S", self->Value ? to_string(self->Value) : "Null" ); + append_fmt( result, "\n\tNextVar : %S", self->NextVar ? debug_str(self->NextVar) : "Null" ); break; } return result; } -AST* AST::duplicate() +AST* duplicate(AST* self) { using namespace ECode; AST* result = make_code().ast; - mem_copy( result, this, sizeof( AST ) ); + mem_copy( result, self, sizeof( AST ) ); result->Parent = nullptr; return result; @@ -412,169 +413,169 @@ void AST::to_string( String& result ) break; case Class: - cast().to_string_def( result ); + code_cast().to_string_def( result ); break; case Class_Fwd: - cast().to_string_fwd( result ); + code_cast().to_string_fwd( result ); break; case Constructor: - cast().to_string_def( result ); + code_cast().to_string_def( result ); break; case Constructor_Fwd: - cast().to_string_fwd( result ); + code_cast().to_string_fwd( result ); break; case Destructor: - cast().to_string_def( result ); + code_cast().to_string_def( result ); break; case Destructor_Fwd: - cast().to_string_fwd( result ); + code_cast().to_string_fwd( result ); break; case Enum: - cast().to_string_def( result ); + code_cast().to_string_def( result ); break; case Enum_Fwd: - cast().to_string_fwd( result ); + code_cast().to_string_fwd( result ); break; case Enum_Class: - cast().to_string_class_def( result ); + code_cast().to_string_class_def( result ); break; case Enum_Class_Fwd: - cast().to_string_class_fwd( result ); + code_cast().to_string_class_fwd( result ); break; case Export_Body: - cast().to_string_export( result ); + code_cast().to_string_export( result ); break; case Extern_Linkage: - cast().to_string( result ); + code_cast().to_string( result ); break; case Friend: - cast().to_string( result ); + code_cast().to_string( result ); break; case Function: - cast().to_string_def( result ); + code_cast().to_string_def( result ); break; case Function_Fwd: - cast().to_string_fwd( result ); + code_cast().to_string_fwd( result ); break; case Module: - cast().to_string( result ); + code_cast().to_string( result ); break; case Namespace: - cast().to_string( result ); + code_cast().to_string( result ); break; case Operator: case Operator_Member: - cast().to_string_def( result ); + code_cast().to_string_def( result ); break; case Operator_Fwd: case Operator_Member_Fwd: - cast().to_string_fwd( result ); + code_cast().to_string_fwd( result ); break; case Operator_Cast: - cast().to_string_def( result ); + code_cast().to_string_def( result ); break; case Operator_Cast_Fwd: - cast().to_string_fwd( result ); + code_cast().to_string_fwd( result ); break; case Parameters: - cast().to_string( result ); + code_cast().to_string( result ); break; case Preprocess_Define: - cast().to_string( result ); + code_cast().to_string( result ); break; case Preprocess_If: - cast().to_string_if( result ); + code_cast().to_string_if( result ); break; case Preprocess_IfDef: - cast().to_string_ifdef( result ); + code_cast().to_string_ifdef( result ); break; case Preprocess_IfNotDef: - cast().to_string_ifndef( result ); + code_cast().to_string_ifndef( result ); break; case Preprocess_Include: - cast().to_string( result ); + code_cast().to_string( result ); break; case Preprocess_ElIf: - cast().to_string_elif( result ); + code_cast().to_string_elif( result ); break; case Preprocess_Else: - cast().to_string_else( result ); + code_cast().to_string_else( result ); break; case Preprocess_EndIf: - cast().to_string_endif( result ); + code_cast().to_string_endif( result ); break; case Preprocess_Pragma: - cast().to_string( result ); + code_cast().to_string( result ); break; case Specifiers: - cast().to_string( result ); + code_cast().to_string( result ); break; case Struct: - cast().to_string_def( result ); + code_cast().to_string_def( result ); break; case Struct_Fwd: - cast().to_string_fwd( result ); + code_cast().to_string_fwd( result ); break; case Template: - cast().to_string( result ); + code_cast().to_string( result ); break; case Typedef: - cast().to_string( result ); + code_cast().to_string( result ); break; case Typename: - cast().to_string( result ); + code_cast().to_string( result ); break; case Union: - cast().to_string( result ); + code_cast().to_string( result ); break; case Using: - cast().to_string( result ); + code_cast().to_string( result ); break; case Using_Namespace: - cast().to_string_ns( result ); + code_cast().to_string_ns( result ); break; case Variable: - cast().to_string( result ); + code_cast().to_string( result ); break; case Enum_Body: @@ -585,7 +586,7 @@ void AST::to_string( String& result ) case Namespace_Body: case Struct_Body: case Union_Body: - cast().to_string( result ); + code_cast().to_string( result ); break; } } @@ -1157,7 +1158,7 @@ bool AST::validate_body() #define CheckEntries( Unallowed_Types ) \ do \ { \ - for ( Code entry : cast() ) \ + for ( Code entry : code_cast() ) \ { \ switch ( entry->Type ) \ { \ @@ -1175,7 +1176,7 @@ bool AST::validate_body() CheckEntries( GEN_AST_BODY_CLASS_UNALLOWED_TYPES ); break; case Enum_Body: - for ( Code entry : cast() ) + for ( Code entry : code_cast() ) { if ( entry->Type != Untyped ) { @@ -1194,7 +1195,7 @@ bool AST::validate_body() CheckEntries( GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES ); break; case Global_Body: - for (Code entry : cast()) + for (Code entry : code_cast()) { switch (entry->Type) { @@ -1227,7 +1228,7 @@ bool AST::validate_body() CheckEntries( GEN_AST_BODY_STRUCT_UNALLOWED_TYPES ); break; case Union_Body: - for ( Code entry : Body->cast() ) + for ( Code entry : Body->code_cast() ) { if ( entry->Type != Untyped ) { diff --git a/project/components/ast.hpp b/project/components/ast.hpp index a2a1fd8..533e705 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -146,6 +146,11 @@ namespace parser 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 - Not constantly have to append the '*' as this is written often.. @@ -178,7 +183,7 @@ struct Code Using_Code( Code ); template< class Type > - forceinline Type cast() + forceinline Type code_cast() { 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. 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. */ struct AST { +#if GEN_SUPPORT_CPP_MEMBER_FEATURES # pragma region Member Functions - void append ( AST* other ); - char const* debug_str (); - AST* duplicate (); - Code& entry ( u32 idx ); + void append ( AST* other ) { GEN_NS append(this, other); } + char const* debug_str () { return GEN_NS debug_str(this); } + AST* duplicate () { return GEN_NS duplicate(this); } + Code* entry ( u32 idx ) { return GEN_NS entry(this, idx); } bool has_entries(); bool is_equal ( AST* other ); - bool is_body(); - char const* type_str(); + bool is_body() { return GEN_NS is_body(this); } + char const* type_str() { return GEN_NS type_str(this); } bool validate_body(); - String to_string(); - - neverinline - void to_string( String& result ); + String to_string(); //{ return GEN_NS to_string(this); } template< class Type > - forceinline Type cast() + forceinline Type code_cast() { return * this; } + neverinline + void to_string( String& result ); +# pragma endregion Member Functions +#endif + operator Code(); operator CodeBody(); operator CodeAttributes(); @@ -305,7 +330,6 @@ struct AST operator CodeUnion(); operator CodeUsing(); operator CodeVar(); -# pragma endregion Member Functions constexpr static 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. // All extra functionality within the AST namespace should just be syntatic sugar. diff --git a/project/components/code_serialization.cpp b/project/components/code_serialization.cpp index 0a1df21..170feab 100644 --- a/project/components/code_serialization.cpp +++ b/project/components/code_serialization.cpp @@ -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() ); - CodeType interface = ast->ParentType->Next->cast< CodeType >(); + CodeType interface = ast->ParentType->Next->code_cast< CodeType >(); if ( interface ) append( result, "\n" ); while ( interface ) { 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 ) @@ -353,7 +353,10 @@ void CodeEnum::to_string_fwd( String& result ) if ( ast->Attributes ) 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 ) ) { @@ -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() ); - CodeType interface = ast->ParentType->Next->cast< CodeType >(); + CodeType interface = ast->ParentType->Next->code_cast< CodeType >(); if ( interface ) append( result, "\n" ); while ( interface ) { 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 ) diff --git a/project/components/code_types.hpp b/project/components/code_types.hpp index 8bab98e..6d211d0 100644 --- a/project/components/code_types.hpp +++ b/project/components/code_types.hpp @@ -11,37 +11,30 @@ struct CodeBody void append( Code other ) { - if (other.is_body()) - { - append( other.cast() ); + GEN_ASSERT(other.ast != nullptr); + + if (other.is_body()) { + append( cast(CodeBody, & other) ); } - raw()->append( other.ast ); + + GEN_NS append( raw(), other.ast ); } void append( CodeBody body ) { - for ( Code entry : body ) - { + for ( Code entry : body ) { append( entry ); } } - bool has_entries() - { - return rcast( AST*, ast )->has_entries(); - } + bool has_entries() { return GEN_NS has_entries(rcast( AST*, ast )); } + AST* raw() { return rcast( AST*, ast ); } + void to_string( String& result ); void to_string_export( String& result ); - AST* raw() - { - return rcast( AST*, ast ); - } - AST_Body* operator->() - { - return ast; - } - operator Code() - { - return * rcast( Code*, this ); - } + + AST_Body* operator->() { return ast; } + + operator Code() { return * rcast( Code*, this ); } + #pragma region Iterator Code begin() { diff --git a/project/components/gen/ast_inlines.hpp b/project/components/gen/ast_inlines.hpp index c449e0d..ec26f08 100644 --- a/project/components/gen/ast_inlines.hpp +++ b/project/components/gen/ast_inlines.hpp @@ -11,7 +11,7 @@ inline char const* Code::debug_str() { if ( ast == nullptr ) 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() @@ -87,7 +87,7 @@ inline char const* CodeBody::debug_str() { if ( ast == nullptr ) 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() @@ -163,7 +163,7 @@ inline char const* CodeAttributes::debug_str() { if ( ast == nullptr ) 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() @@ -259,7 +259,7 @@ inline char const* CodeComment::debug_str() { if ( ast == nullptr ) 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() @@ -355,7 +355,7 @@ inline char const* CodeConstructor::debug_str() { if ( ast == nullptr ) 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() @@ -451,7 +451,7 @@ inline char const* CodeClass::debug_str() { if ( ast == nullptr ) 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() @@ -527,7 +527,7 @@ inline char const* CodeDefine::debug_str() { if ( ast == nullptr ) 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() @@ -623,7 +623,7 @@ inline char const* CodeDestructor::debug_str() { if ( ast == nullptr ) 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() @@ -719,7 +719,7 @@ inline char const* CodeEnum::debug_str() { if ( ast == nullptr ) 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() @@ -815,7 +815,7 @@ inline char const* CodeExec::debug_str() { if ( ast == nullptr ) 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() @@ -911,7 +911,7 @@ inline char const* CodeExtern::debug_str() { if ( ast == nullptr ) 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() @@ -1007,7 +1007,7 @@ inline char const* CodeFriend::debug_str() { if ( ast == nullptr ) 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() @@ -1103,7 +1103,7 @@ inline char const* CodeFn::debug_str() { if ( ast == nullptr ) 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() @@ -1199,7 +1199,7 @@ inline char const* CodeInclude::debug_str() { if ( ast == nullptr ) 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() @@ -1295,7 +1295,7 @@ inline char const* CodeModule::debug_str() { if ( ast == nullptr ) 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() @@ -1391,7 +1391,7 @@ inline char const* CodeNS::debug_str() { if ( ast == nullptr ) 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() @@ -1487,7 +1487,7 @@ inline char const* CodeOperator::debug_str() { if ( ast == nullptr ) 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() @@ -1583,7 +1583,7 @@ inline char const* CodeOpCast::debug_str() { if ( ast == nullptr ) 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() @@ -1679,7 +1679,7 @@ inline char const* CodeParam::debug_str() { if ( ast == nullptr ) 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() @@ -1755,7 +1755,7 @@ inline char const* CodePragma::debug_str() { if ( ast == nullptr ) 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() @@ -1851,7 +1851,7 @@ inline char const* CodePreprocessCond::debug_str() { if ( ast == nullptr ) 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() @@ -1947,7 +1947,7 @@ inline char const* CodeSpecifiers::debug_str() { if ( ast == nullptr ) 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() @@ -2023,7 +2023,7 @@ inline char const* CodeStruct::debug_str() { if ( ast == nullptr ) 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() @@ -2099,7 +2099,7 @@ inline char const* CodeTemplate::debug_str() { if ( ast == nullptr ) 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() @@ -2195,7 +2195,7 @@ inline char const* CodeType::debug_str() { if ( ast == nullptr ) 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() @@ -2291,7 +2291,7 @@ inline char const* CodeTypedef::debug_str() { if ( ast == nullptr ) 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() @@ -2387,7 +2387,7 @@ inline char const* CodeUnion::debug_str() { if ( ast == nullptr ) 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() @@ -2483,7 +2483,7 @@ inline char const* CodeUsing::debug_str() { if ( ast == nullptr ) 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() @@ -2579,7 +2579,7 @@ inline char const* CodeVar::debug_str() { if ( ast == nullptr ) 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() diff --git a/project/components/inlines.hpp b/project/components/inlines.hpp index 34bdf5b..8178ab2 100644 --- a/project/components/inlines.hpp +++ b/project/components/inlines.hpp @@ -4,56 +4,62 @@ #endif inline -void AST::append( AST* other ) +void append( AST* self, AST* other ) { + GEN_ASSERT(self != nullptr); + GEN_ASSERT(other != nullptr); + if ( other->Parent ) - other = other->duplicate(); + other = duplicate(other); - other->Parent = this; + other->Parent = self; - if ( Front == nullptr ) + if ( self->Front == nullptr ) { - Front = other; - Back = other; + self->Front = other; + self->Back = other; - NumEntries++; + self->NumEntries++; return; } AST* - Current = Back; + Current = self->Back; Current->Next = other; other->Prev = Current; - Back = other; - NumEntries++; + self->Back = other; + self->NumEntries++; } 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 ) { if ( idx == 0 ) - return * rcast( Code*, current); + return rcast( Code*, current); current = & ( * current )->Next; idx--; } - return * rcast( Code*, current); + return rcast( Code*, current); } inline -bool AST::has_entries() +bool has_entries(AST* self) { - return NumEntries > 0; + GEN_ASSERT(self != nullptr); + return self->NumEntries > 0; } 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::Class_Body: @@ -70,9 +76,10 @@ bool AST::is_body() } 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 @@ -117,7 +124,7 @@ void CodeParam::append( CodeParam other ) AST* entry = (AST*) other.ast; if ( entry->Parent ) - entry = entry->duplicate(); + entry = GEN_NS duplicate( entry ); entry->Parent = self; diff --git a/project/components/interface.cpp b/project/components/interface.cpp index c64f937..b62d537 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -30,7 +30,7 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s last = & back(Global_AllocatorBuckets); } - return alloc_align( allocator_info(* last), size, alignment ); + return alloc_align( allocator_info(last), size, alignment ); } case EAllocation_FREE: { @@ -306,7 +306,7 @@ void deinit() do { Pool* code_pool = & CodePools[index]; - free(* code_pool); + free(code_pool); index++; } while ( left--, left ); @@ -316,7 +316,7 @@ void deinit() do { Arena* string_arena = & StringArenas[index]; - free(* string_arena); + free(string_arena); index++; } while ( left--, left ); @@ -326,7 +326,7 @@ void deinit() free(CodePools); free(StringArenas); - free(LexArena); + free(& LexArena); free(PreprocessorDefines); @@ -335,7 +335,7 @@ void deinit() do { Arena* bucket = & Global_AllocatorBuckets[ index ]; - free(* bucket); + free(bucket); index++; } while ( left--, left ); @@ -387,7 +387,7 @@ AllocatorInfo get_string_allocator( s32 str_length ) last = & back(StringArenas); } - return allocator_info(* last); + return allocator_info(last); } // Will either make or retrive a code string. @@ -425,7 +425,7 @@ Code make_code() 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) ); // result->Type = ECode::Invalid; diff --git a/project/components/interface.untyped.cpp b/project/components/interface.untyped.cpp index 217a5d2..bafc313 100644 --- a/project/components/interface.untyped.cpp +++ b/project/components/interface.untyped.cpp @@ -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 ]; tok_map_arena = arena_init_from_memory( tok_map_mem, sizeof(tok_map_mem) ); - tok_map = hashtable_init( allocator_info(tok_map_arena) ); + tok_map = hashtable_init( allocator_info(& tok_map_arena) ); 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); - free(tok_map_arena); + free(& tok_map_arena); ssize result = buf_size - remaining; diff --git a/project/components/interface.upfront.cpp b/project/components/interface.upfront.cpp index 1d0f559..c0e9c9b 100644 --- a/project/components/interface.upfront.cpp +++ b/project/components/interface.upfront.cpp @@ -1925,7 +1925,7 @@ CodeBody def_global_body( s32 num, ... ) switch (entry->Type) { case Global_Body: - result.append( entry.cast() ) ; + result.append( entry.code_cast() ) ; continue; GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES @@ -1966,7 +1966,7 @@ CodeBody def_global_body( s32 num, Code* codes ) switch (entry->Type) { case Global_Body: - result.append( entry.cast() ) ; + result.append( entry.code_cast() ) ; continue; GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES diff --git a/project/components/lexer.cpp b/project/components/lexer.cpp index f2fe4d3..61e4283 100644 --- a/project/components/lexer.cpp +++ b/project/components/lexer.cpp @@ -579,7 +579,7 @@ TokArray lex( StrC content ) if ( left <= 0 ) { log_failure( "gen::lex: no tokens found (only whitespace provided)" ); - return { { nullptr }, 0 }; + return { {}, 0 }; } foreach( StringCached, entry, PreprocessorDefines ) @@ -652,7 +652,7 @@ TokArray lex( StrC content ) continue; case Lex_ReturnNull: - return { { nullptr }, 0 }; + return { {}, 0 }; } } case '.': @@ -1256,7 +1256,7 @@ TokArray lex( StrC content ) if ( num(Tokens) == 0 ) { log_failure( "Failed to lex any tokens" ); - return { { nullptr }, 0 }; + return { {}, 0 }; } clear(defines); diff --git a/project/components/parser.cpp b/project/components/parser.cpp index 7801ab0..b04fd0a 100644 --- a/project/components/parser.cpp +++ b/project/components/parser.cpp @@ -132,12 +132,12 @@ bool TokArray::__eat( TokType type ) internal void init() { - Tokens = array_init_reserve( allocator_info(LexArena) + Tokens = array_init_reserve( allocator_info( & LexArena) , ( LexAllocator_Size - sizeof( ArrayHeader ) ) / sizeof(Token) ); - fixed_arena_init(defines_map_arena); - defines = hashtable_init_reserve( allocator_info(defines_map_arena), 256 ); + fixed_arena_init(& defines_map_arena); + defines = hashtable_init_reserve( allocator_info( & defines_map_arena), 256 ); } internal @@ -714,7 +714,7 @@ Code parse_class_struct( TokType which, bool inplace_def = false ) char interface_arr_mem[ kilobytes(4) ] {0}; Array interfaces; { Arena arena = arena_init_from_memory( interface_arr_mem, kilobytes(4) ); - interfaces = array_init_reserve( allocator_info(arena), 4 ); + interfaces = array_init_reserve( 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. @@ -4910,10 +4910,12 @@ CodeTypedef parse_typedef() || currtok.Type == TokType::Decl_Struct || currtok.Type == TokType::Decl_Union; + // This code is highly correlated with parse_complicated_definition if ( is_complicated ) { TokArray tokens = Context.Tokens; + TokType which = currtok.Type; s32 idx = tokens.Idx; s32 level = 0; @@ -4929,73 +4931,80 @@ CodeTypedef parse_typedef() 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 - type = parse_forward_or_definition( currtok.Type, from_typedef ); + type = parse_forward_or_definition( which, from_typedef ); // typedef } - - Token tok = tokens[ idx - 1 ]; - if ( tok.Type == TokType::Identifier ) + else { - tok = tokens[ idx - 2 ]; - - bool is_indirection = tok.Type == TokType::Ampersand - || tok.Type == TokType::Star; - - bool ok_to_parse = false; - - if ( tok.Type == TokType::BraceCurly_Close ) + Token tok = tokens.Arr[ idx - 1 ]; + if ( tok.Type == TokType::Identifier ) { - // Its an inplace definition - // typdef { ... } ; - 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. - // ; - ok_to_parse = true; - } - else if ( is_indirection ) - { - // Its a indirection type with type ID using struct namespace. - // * ; - ok_to_parse = true; - } + log_fmt("Found id\n"); + tok = tokens.Arr[ idx - 2 ]; - 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 { ... } ; + 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 ; + ok_to_parse = true; + } + else if ( is_indirection ) + { + // Its a indirection type with type ID using struct namespace. + // typedef * ; + 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 ); + // typedef + } + else if ( tok.Type == TokType::BraceCurly_Close ) + { + // Its a definition + // { ... }; + type = parse_forward_or_definition( currtok.Type, from_typedef ); + // typedef + } + else if ( tok.Type == TokType::BraceSquare_Close) + { + // Its an array definition + // [ ... ]; + type = parse_type(); + // typedef + } + else { 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( currtok.Type, from_typedef ); - // typedef - } - else if ( tok.Type == TokType::BraceCurly_Close ) - { - // Its a definition - // { ... }; - type = parse_forward_or_definition( currtok.Type, from_typedef ); - // typedef - } - else if ( tok.Type == TokType::BraceSquare_Close) - { - // Its an array definition - // [ ... ]; - type = parse_type(); - // typedef - } - else - { - log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() ); - Context.pop(); - return CodeInvalid; } } else @@ -5057,7 +5066,7 @@ CodeTypedef parse_typedef() // 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 ) - type.cast()->ArrExpr = array_expr; + type.code_cast()->ArrExpr = array_expr; if ( inline_cmt ) result->InlineCmt = inline_cmt; diff --git a/project/components/types.hpp b/project/components/types.hpp index 35975ed..e7a9e81 100644 --- a/project/components/types.hpp +++ b/project/components/types.hpp @@ -25,7 +25,7 @@ enum AccessSpec enum_underlying(u32) 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 char const* to_str( AccessSpec type ) @@ -54,7 +54,7 @@ enum CodeFlag enum_underlying(u32) 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. enum EnumDecl enum_underlying(u8) @@ -77,7 +77,7 @@ enum ModuleFlag enum_underlying(u32) 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 StrC to_str( ModuleFlag flag ) @@ -110,4 +110,4 @@ enum EPreprocessCond enum_underlying(u32) 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" ); diff --git a/project/dependencies/macros.hpp b/project/dependencies/macros.hpp index 791ad1e..91a1dd4 100644 --- a/project/dependencies/macros.hpp +++ b/project/dependencies/macros.hpp @@ -23,7 +23,11 @@ #define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) ) #endif + #if ! GEN_C_COMPILER +# ifndef cast +# define cast( type, value ) (tmpl_cast( value )) +# endif # ifndef ccast # define ccast( type, value ) ( const_cast< type >( (value) ) ) # endif @@ -37,11 +41,14 @@ # define scast( type, value ) static_cast< type >( value ) # endif #else +# ifndef cast +# define cast( type, value ) ( (type)(value) ) +# endif # ifndef ccast # define ccast( type, value ) ( (type)(value) ) # endif # ifndef pcast -# define pcast( type, value ) ( (type)(value) ) +# define pcast( type, value ) ( * (type*)(value) ) # endif # ifndef rcast # define rcast( type, value ) ( (type)(value) ) @@ -181,8 +188,14 @@ # endif #endif -#if !defined(GEN_SUPPORT_CPP_MEMBER_FEATURES) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L) -# define GEN_SUPPORT_CPP_MEMBER_FEATURES 0 +#if !defined(GEN_SUPPORT_CPP_REFERENCES) && (GEN_COMPILER_C || __STDC_VERSION__ < 202311L) +# 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 #if !defined(typeof) && (!GEN_COMPILER_C || __STDC_VERSION__ < 202311L) @@ -215,4 +228,10 @@ # define enum_underlying(type) : type #endif +#if GEN_COMPILER_C +# ifndef nullptr +# define nullptr NULL +# endif +#endif + #pragma endregion Macros diff --git a/project/dependencies/memory.hpp b/project/dependencies/memory.hpp index aeae598..0399248 100644 --- a/project/dependencies/memory.hpp +++ b/project/dependencies/memory.hpp @@ -62,21 +62,23 @@ void zero_size( void* ptr, ssize size ); //! Clears up an array. #define zero_array( a, count ) zero_size( ( a ), size_of( *( a ) ) * count ) -enum AllocType : u8 +enum AllocType_Def //enum_underlying(u8) { EAllocation_ALLOC, EAllocation_FREE, EAllocation_FREE_ALL, 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 ); -struct AllocatorInfo +struct AllocatorInfo_Def { AllocatorProc* Proc; void* Data; }; +typedef struct AllocatorInfo_Def AllocatorInfo; 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 ); //! 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. #define malloc( sz ) alloc( heap(), sz ) @@ -170,26 +172,26 @@ ssize gen_virtual_memory_page_size( ssize* alignment_out ); #pragma region Arena struct Arena; -AllocatorInfo allocator_info( Arena& arena ); +AllocatorInfo allocator_info( Arena* arena ); // 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); // Add these declarations after the Arena struct Arena arena_init_from_allocator(AllocatorInfo backing, 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 arena_init_from_memory ( void* start, ssize size ); + +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 #pragma push_macro("check") #undef check -void check(Arena& arena); +void check(Arena* arena); #pragma pop_macro("check") -void free(Arena& arena); -ssize size_remaining(Arena& arena, ssize alignment); - struct Arena { AllocatorInfo Backing; @@ -200,29 +202,45 @@ struct Arena #if GEN_SUPPORT_CPP_MEMBER_FEATURES #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 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_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 void free() { return GEN_NS free(* this); } - forceinline ssize size_remaining( ssize alignment ) { return GEN_NS size_remaining(* this, alignment); } + forceinline ssize alignment_of( ssize alignment ) { return GEN_NS alignment_of(this, alignment); } + forceinline void free() { return GEN_NS free(this); } + forceinline ssize size_remaining( ssize alignment ) { return GEN_NS size_remaining(this, alignment); } // This id is defined by Unreal for asserts #pragma push_macro("check") #undef check - forceinline void check() { GEN_NS check(* this); } + forceinline void check() { GEN_NS check(this); } #pragma pop_macro("check") #pragma endregion Member Mapping #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 -AllocatorInfo allocator_info( Arena& arena ) { - return { arena_allocator_proc, &arena }; +AllocatorInfo allocator_info( Arena* arena ) { + GEN_ASSERT(arena != nullptr); + return { arena_allocator_proc, arena }; } inline @@ -251,18 +269,20 @@ Arena arena_init_from_allocator(AllocatorInfo backing, ssize size) { } inline -Arena init_sub(Arena& parent, ssize size) { - return arena_init_from_allocator(parent.Backing, size); +Arena init_sub(Arena* parent, ssize size) { + GEN_ASSERT(parent != nullptr); + return arena_init_from_allocator(parent->Backing, size); } 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; GEN_ASSERT(is_power_of_two(alignment)); alignment_offset = 0; - result_pointer = (ssize)arena.PhysicalStart + arena.TotalUsed; + result_pointer = (ssize)arena->PhysicalStart + arena->TotalUsed; mask = alignment - 1; if (result_pointer & mask) @@ -274,26 +294,29 @@ ssize alignment_of(Arena& arena, ssize alignment) #pragma push_macro("check") #undef check 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") 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); - arena.PhysicalStart = nullptr; + GEN_NS free(arena->Backing, arena->PhysicalStart); + arena->PhysicalStart = nullptr; } } 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; } #pragma endregion Arena @@ -302,9 +325,14 @@ ssize size_remaining(Arena& arena, ssize alignment) template struct FixedArena; -template AllocatorInfo allocator_info( FixedArena& fixed_arena ); template FixedArena fixed_arena_init(); -template ssize size_remaining(FixedArena& fixed_arena, ssize alignment); +template AllocatorInfo allocator_info(FixedArena* fixed_arena ); +template ssize size_remaining(FixedArena* fixed_arena, ssize alignment); + +#if GEN_SUPPORT_CPP_REFERENCES +template AllocatorInfo allocator_info( FixedArena& fixed_arena ) { return allocator_info(& fixed_arena); } +template ssize size_remaining(FixedArena& 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. // Used for static segment or stack allocations. @@ -316,26 +344,29 @@ struct FixedArena #if GEN_SUPPORT_CPP_MEMBER_FEATURES #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(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 #endif }; template inline -AllocatorInfo allocator_info( FixedArena& fixed_arena ) { return { arena_allocator_proc, & fixed_arena.arena }; } - -template inline -void fixed_arena_init(FixedArena& result) { - zero_size(& result.memory[0], Size); - result.arena = arena_init_from_memory(& result.memory[0], Size); +AllocatorInfo allocator_info( FixedArena* fixed_arena ) { + GEN_ASSERT(fixed_arena); + return { arena_allocator_proc, & fixed_arena->arena }; } template inline -ssize size_remaining(FixedArena& fixed_arena, ssize alignment) { - return size_remaining(fixed_arena.arena, alignment); +void fixed_arena_init(FixedArena* result) { + zero_size(& result->memory[0], Size); + result->arena = arena_init_from_memory(& result->memory[0], Size); +} + +template inline +ssize size_remaining(FixedArena* fixed_arena, ssize alignment) { + return size_remaining(fixed_arena->arena, alignment); } using Arena_1KB = FixedArena< kilobytes( 1 ) >; @@ -355,12 +386,19 @@ using Arena_4MB = FixedArena< megabytes( 4 ) >; #pragma region 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_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 free(Pool& pool); +#endif struct Pool { @@ -374,20 +412,20 @@ struct Pool #if GEN_SUPPORT_CPP_MEMBER_FEATURES #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 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 void clear() { GEN_NS clear(* this); } - forceinline void free() { GEN_NS free(* this); } + forceinline void clear() { GEN_NS clear( this); } + forceinline void free() { GEN_NS free( this); } #pragma endregion #endif }; inline -AllocatorInfo allocator_info(Pool& pool) { - return { pool_allocator_proc, &pool }; +AllocatorInfo allocator_info(Pool* pool) { + return { pool_allocator_proc, pool }; } inline @@ -396,9 +434,9 @@ Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size) { } inline -void free(Pool& pool) { - if(pool.Backing.Proc) { - GEN_NS free(pool.Backing, pool.PhysicalStart); +void free(Pool* pool) { + if(pool->Backing.Proc) { + GEN_NS free(pool->Backing, pool->PhysicalStart); } } #pragma endregion Pool diff --git a/project/dependencies/platform.hpp b/project/dependencies/platform.hpp index 583b260..27a9a6b 100644 --- a/project/dependencies/platform.hpp +++ b/project/dependencies/platform.hpp @@ -125,9 +125,13 @@ # include # endif +#if GEN_COMPILER_C +#include +#endif + #pragma endregion Mandatory Includes -#if GEN_DONT_USE_NAMESPACE +#if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C # if GEN_COMPILER_C # define GEN_NS_ENUM_BEGIN # define GEN_NS_ENUM_END diff --git a/project/dependencies/strings.hpp b/project/dependencies/strings.hpp index 285e3e8..3058f87 100644 --- a/project/dependencies/strings.hpp +++ b/project/dependencies/strings.hpp @@ -305,7 +305,7 @@ bool are_equal(String const& lhs, StrC rhs) return false; for (ssize idx = 0; idx < length(lhs); ++idx) - if (lhs[idx] != rhs[idx]) + if (lhs[idx] != rhs.Ptr[idx]) return false; return true; @@ -319,7 +319,7 @@ ssize avail_space(String const& str) { inline char& back(String& str) { - return str.Data[length(str) - 1]; + return str[length(str) - 1]; } inline @@ -335,7 +335,7 @@ bool contains(String const& str, StrC substring) 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; } @@ -355,7 +355,7 @@ bool contains(String const& str, String const& substring) 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; } @@ -380,7 +380,7 @@ String duplicate(String const& str, AllocatorInfo allocator) { inline void free(String& str) { - if (!str.Data) + if (! str) return; StringHeader& header = get_header(str); @@ -389,7 +389,7 @@ void free(String& str) { inline StringHeader& get_header(String& str) { - return *(StringHeader*)(str.Data - sizeof(StringHeader)); + return *(StringHeader*)(scast(char*, str) - sizeof(StringHeader)); } inline diff --git a/project/helpers/helper.hpp b/project/helpers/helper.hpp index e648ab6..975d08d 100644 --- a/project/helpers/helper.hpp +++ b/project/helpers/helper.hpp @@ -13,7 +13,7 @@ CodeBody gen_ecode( char const* path ) char scratch_mem[kilobytes(1)]; 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_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); @@ -59,7 +59,7 @@ CodeBody gen_eoperator( char const* path ) char scratch_mem[kilobytes(4)]; 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_parse( &csv_nodes, scratch_mem, GlobalAllocator, false ); @@ -115,7 +115,7 @@ CodeBody gen_especifier( char const* path ) char scratch_mem[kilobytes(4)]; 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_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)]; 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 ); @@ -342,8 +342,10 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) CodeBody gen_ast_inlines() { +#pragma push_macro("GEN_NS") #pragma push_macro("rcast") #pragma push_macro("log_failure") +#undef GEN_NS #undef rcast #undef log_failure char const* code_impl_tmpl = stringize( @@ -354,7 +356,7 @@ CodeBody gen_ast_inlines() if ( ast == nullptr ) return "Code::debug_str: AST is null!"; - return rcast(AST*, ast)->debug_str(); + return GEN_NS debug_str( rcast(AST*, ast) ); } inline Code ::duplicate() @@ -455,6 +457,7 @@ CodeBody gen_ast_inlines() } \n ); +#pragma pop_macro("GEN_NS") 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 )); diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index 67b2697..2a4e63a 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -226,6 +226,30 @@ if ( $c_library ) write-host "`nc_library generator completed in $($time_taken.TotalMilliseconds) ms" } 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 )