diff --git a/docs/AST_Design.md b/docs/AST_Design.md new file mode 100644 index 0000000..284e0ac --- /dev/null +++ b/docs/AST_Design.md @@ -0,0 +1,37 @@ +# Forward + +Was never satisfied with how I did the wrap of the management of the AST. +For C++, the current design may be as good as it gets for the limitations of the langauge. + +I'll at least try in this issue to brainstorm something simpiler without losing ergonomics. +This will also be a good place to document the current design. + +## Current Design + +`AST` is the actual managed node object for the library. +Its raw and really not meant to be used directly. + +All user interaction must be with its pointer so the type they deal with is `AST*`. +For user-facing code, they should never be giveen a nullptr. Instead, they should be given a designated `Invalid` AST node. + +In order to abstract away constant use of `AST*`, I wanted to provide a wrapper for it. + +The simpliest being just a type alias. + +```cpp +using Code = AST*; +``` + +This is what the genc library would have to use due to its constraints of a langauge. +Anything else and it would either be an unergonomic mess of struct wrapping with a mess of macros & procedures to interface with it. + +Further, to provide intuitive filters on the AST, there are AST types (covered in [AST_Types.md](AST_Types.md)). + +These are pure PODS that just have the lay members relevant to the type of AST node they represent. +Each of them has a Code type alias specific to it. + +Again, the simpliest case for these would be a type alias. + +```cpp +using struct AST_Typedef CodeTypedef; +``` diff --git a/docs/ASTs.md b/docs/AST_Types.md similarity index 96% rename from docs/ASTs.md rename to docs/AST_Types.md index ea065df..5b3acf7 100644 --- a/docs/ASTs.md +++ b/docs/AST_Types.md @@ -1,4 +1,4 @@ -# ASTs Documentation +# AST Types Documentation While the Readme for docs covers the data layout per AST, this will focus on the AST types avaialble, and their nuances. @@ -95,12 +95,12 @@ The upfront constructor: `def_comment` expects to recieve a comment without the Fields: ```cpp -CodeComment InlineCmt; // Only supported by forward declarations +CodeComment InlineCmt; // Only supported by forward declarations CodeAttributes Attributes; CodeType ParentType; CodeBody Body; -CodeType Last; // Used to store references to interfaces -CodeType Next; // Used to store references to interfaces +CodeType Prev; // Used to store references to interfaces +CodeType Next; // Used to store references to interfaces Code Parent; StringCached Name; CodeT Type; @@ -115,7 +115,7 @@ Serialization: ; // Class - : , public , ... + : , public Next>, ... { }; @@ -145,7 +145,8 @@ Serialization: Name>( ); // Constructor - Name>( ): + Name>( ) + : { } diff --git a/docs/Parsing.md b/docs/Parsing.md index 39010dd..91deb93 100644 --- a/docs/Parsing.md +++ b/docs/Parsing.md @@ -67,7 +67,6 @@ Adding your own exceptions is possible by simply modifying the parser to allow f *Note: You could interpret this strictness as a feature. This would allow the user to see if their codebase or a third-party's codebase some some egregious preprocessor abuse.* - The lexing and parsing takes shortcuts from whats expected in the standard. * Numeric literals are not checked for validity. @@ -80,4 +79,3 @@ The lexing and parsing takes shortcuts from whats expected in the standard. * Parsing attributes can be extended to support user defined macros by defining `GEN_DEFINE_ATTRIBUTE_TOKENS` (see `gen.hpp` for the formatting) Empty lines used throughout the file are preserved for formatting purposes during ast serialization. - diff --git a/docs/Readme.md b/docs/Readme.md index bb9ef04..9300a1d 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -42,6 +42,7 @@ Otherwise the library is free of any templates. **There is no support for validating expressions.** Its difficult to parse without enough benefits (At the metaprogramming level). +I plan to add this only at the tail of the project parsing milestone. **Only trivial template support is provided.** The intention is for only simple, non-recursive substitution. diff --git a/gencpp.10x b/gencpp.10x index 29874bd..3619e7e 100644 --- a/gencpp.10x +++ b/gencpp.10x @@ -19,7 +19,7 @@ pwsh ./scripts/build.ps1 ./test/gen/build/gencpp.exe - false + true Debug Release diff --git a/project/Readme.md b/project/Readme.md index 0b5e35d..04ec394 100644 --- a/project/Readme.md +++ b/project/Readme.md @@ -53,3 +53,8 @@ Names or Content fields are interned strings and thus showed be cached using `ge The library has its code segmented into component files, use it to help create a derived version without needing to have to rewrite a generated file directly or build on top of the header via composition or inheritance. The parser is documented under `docs/Parsing.md` and `docs/Parser_Algo.md`. + +## A note on compilation and runtime generation speed + +The library is designed to be fast to compile and generate code at runtime as fast as resonable possible on a debug build. +Its recommended that your metaprogam be compiled using a single translation unit (unity build). diff --git a/project/bootstrap.cpp b/project/bootstrap.cpp index facf3c9..6e05e92 100644 --- a/project/bootstrap.cpp +++ b/project/bootstrap.cpp @@ -148,7 +148,7 @@ int gen_main() CodeBody gen_component_header = def_global_body( args( def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ), pragma_once, - def_include(txt("types.hpp")), + def_include(txt("components/types.hpp")), preprocess_endif, fmt_newline, untyped_str( to_str(generation_notice) ) diff --git a/project/components/ast.cpp b/project/components/ast.cpp index 11f8fc9..9f9d49d 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -11,7 +11,6 @@ char const* AST::debug_str() { String result = String::make_reserve( GlobalAllocator, kilobytes(1) ); -#if 1 if ( Parent ) result.append_fmt( "\n\tParent : %S %S", Parent->type_str(), Name ? Name : "" ); else @@ -20,7 +19,6 @@ char const* AST::debug_str() result.append_fmt( "\n\tName : %S", Name ? Name : "Null" ); result.append_fmt( "\n\tType : %S", type_str() ); result.append_fmt( "\n\tModule Flags : %S", to_str( ModuleFlags ) ); - result.append_fmt( "\n\tToken : %d", Token ); switch ( Type ) { @@ -71,6 +69,19 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Class_Fwd: + case Struct_Fwd: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" ); + result.append_fmt( "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" ); + break; + case Constructor: if ( Prev ) result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); @@ -84,6 +95,18 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Constructor_Fwd: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" ); + result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + break; + case Destructor: if ( Prev ) result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); @@ -95,7 +118,11 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Destructor_Fwd: + break; + case Enum: + case Enum_Class: if ( Prev ) result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); if ( Next ) @@ -107,6 +134,10 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Enum_Class_Fwd: + + break; + case Extern_Linkage: case Namespace: if ( Prev ) @@ -275,7 +306,6 @@ char const* AST::debug_str() result.append_fmt( "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" ); break; } -#endif return result; } @@ -334,43 +364,37 @@ String AST::to_string() if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) result.append( "export " ); - if ( Attributes || ParentType ) + result.append( "class " ); + + if ( Attributes ) { - result.append( "class " ); + result.append_fmt( "%S ", Attributes->to_string() ); + } - if ( Attributes ) + if ( ParentType ) + { + char const* access_level = to_str( ParentAccess ); + + result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); + + CodeType interface = ParentType->Next->cast< CodeType >(); + if ( interface ) + result.append( "\n" ); + + while ( interface ) { - result.append_fmt( "%S ", Attributes->to_string() ); - } - - if ( ParentType ) - { - char const* access_level = to_str( ParentAccess ); - - result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); - - CodeType interface = ParentType->Next->cast< CodeType >(); - if ( interface ) - result.append( "\n" ); - - while ( interface ) - { - result.append_fmt( ", %S", interface.to_string() ); - interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; - } - - result.append_fmt( "\n{\n%S\n}", Body->to_string() ); - } - else - { - result.append_fmt( "%S \n{\n%S\n}", Name, Body->to_string() ); + result.append_fmt( ", %S", interface.to_string() ); + interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; } } - else + + if ( InlineCmt ) { - result.append_fmt( "class %S\n{\n%S\n}", Name, Body->to_string() ); + result.append_fmt( " // %S", InlineCmt->Content ); } + result.append_fmt( "\n{\n%S\n}", Body->to_string() ); + if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) result.append(";\n"); } @@ -409,6 +433,9 @@ String AST::to_string() if ( InitializerList ) result.append_fmt( " : %S", InitializerList->to_string() ); + if ( InlineCmt ) + result.append_fmt( " // %S", InlineCmt->Content ); + result.append_fmt( "\n{\n%S\n}\n", Body->to_string() ); } break; @@ -930,56 +957,39 @@ String AST::to_string() if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) result.append( "export " ); - if ( Name == nullptr) + result.append( "struct " ); + + if ( Attributes ) { - result.append_fmt( "struct\n{\n%S\n};\n", Body->to_string() ); - break; + result.append_fmt( "%S ", Attributes->to_string() ); } - if ( Attributes || ParentType ) + if ( ParentType ) { - result.append( "struct " ); + char const* access_level = to_str( ParentAccess ); - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); + result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); - if ( ParentType ) + CodeType interface = ParentType->Next->cast< CodeType >(); + if ( interface ) + result.append( "\n" ); + + while ( interface ) { - char const* access_level = to_str( ParentAccess ); - - result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); - - CodeType interface = ParentType->Next->cast< CodeType >(); - if ( interface ) - result.append( "\n" ); - - while ( interface ) - { - result.append_fmt( ", %S", interface.to_string() ); - - interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; - } - - result.append_fmt( "\n{\n%S\n}", Body->to_string() ); - } - else - { - if ( Name ) - result.append_fmt( "%S \n{\n%S\n}", Name, Body->to_string() ); + result.append_fmt( ", %S", interface.to_string() ); + interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; } } - else + + if ( InlineCmt ) { - result.append_fmt( "struct %S\n{\n%S\n}", Name, Body->to_string() ); + result.append_fmt( " // %S", InlineCmt->Content ); } + result.append_fmt( "\n{\n%S\n}", Body->to_string() ); + if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - { - if ( InlineCmt ) - result.append_fmt("; %S", InlineCmt->Content ); - else - result.append(";\n"); - } + result.append(";\n"); } break; diff --git a/project/components/ast.hpp b/project/components/ast.hpp index 9169404..a986b88 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -67,6 +67,11 @@ struct CodeUnion; struct CodeUsing; struct CodeVar; +// namespace Parser +// { +// struct Token; +// } + /* AST* wrapper - Not constantly have to append the '*' as this is written often.. @@ -82,7 +87,7 @@ struct Code static Code Invalid; # pragma endregion Statics -# define Using_Code( Typename ) \ +# define Using_Code( Typename ) \ char const* debug_str(); \ Code duplicate(); \ bool is_equal( Code other ); \ @@ -108,7 +113,7 @@ struct Code return ast; } Code& operator ++(); - Code& operator*() + auto& operator*() { return *this; } @@ -157,7 +162,7 @@ struct Code_POD static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" ); // Desired width of the AST data structure. -constexpr u32 AST_POD_Size = 128; +constexpr int AST_POD_Size = 128; /* Simple AST POD with functionality to seralize into C++ syntax. @@ -214,17 +219,20 @@ struct AST # pragma endregion Member Functions constexpr static - uw ArrSpecs_Cap = + int ArrSpecs_Cap = + #if 1 ( AST_POD_Size - - sizeof(AST*) * 4 - - sizeof(StringCached) - - sizeof(CodeT) + - sizeof(void*) * 4 + // - sizeof(Parser::Token*) + // - sizeof(AST*) + - sizeof(void*) + - sizeof(int) - sizeof(ModuleFlag) - - sizeof(u32) - - sizeof(s32) + - sizeof(int) ) / sizeof(SpecifierT); // -1 for 4 extra bytes + #endif union { struct @@ -251,13 +259,13 @@ struct AST }; union { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) - AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. + AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) }; }; StringCached Content; // Attributes, Comment, Execution, Include struct { SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers - AST* NextSpecs; // Specifiers + AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. }; }; union { @@ -269,6 +277,7 @@ struct AST AST* Next; AST* Back; }; + // Parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing. AST* Parent; StringCached Name; CodeT Type; @@ -280,7 +289,6 @@ struct AST AccessSpec ParentAccess; s32 NumEntries; }; - s32 Token; // Handle to the token, stored in the CodeFile (Otherwise unretrivable) }; struct AST_POD @@ -310,13 +318,13 @@ struct AST_POD }; union { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) - AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. + AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) }; }; StringCached Content; // Attributes, Comment, Execution, Include struct { SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers - AST* NextSpecs; // Specifiers + AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. }; }; union { @@ -328,6 +336,7 @@ struct AST_POD AST* Next; AST* Back; }; + // Parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing. AST* Parent; StringCached Name; CodeT Type; @@ -339,9 +348,11 @@ struct AST_POD AccessSpec ParentAccess; s32 NumEntries; }; - s32 Token; // Handle to the token, stored in the CodeFile (Otherwise unretrivable) }; +constexpr int specifierT_size = sizeof(SpecifierT); +constexpr int AST_SIZE = sizeof(AST); + // Its intended for the AST to have equivalent size to its POD. // All extra functionality within the AST namespace should just be syntatic sugar. static_assert( sizeof(AST) == sizeof(AST_POD), "ERROR: AST IS NOT POD" ); diff --git a/project/components/ast_types.hpp b/project/components/ast_types.hpp index 228e429..0690faa 100644 --- a/project/components/ast_types.hpp +++ b/project/components/ast_types.hpp @@ -15,14 +15,14 @@ struct AST_Body char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; Code Front; Code Back; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; s32 NumEntries; - s32 Token; }; -static_assert( sizeof(AST_Body) == sizeof(AST), "ERROR: AST_Filtered is not the same size as AST"); +static_assert( sizeof(AST_Body) == sizeof(AST), "ERROR: AST_Body is not the same size as AST"); struct AST_Attributes { @@ -32,11 +32,11 @@ struct AST_Attributes }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Attributes) == sizeof(AST), "ERROR: AST_Attributes is not the same size as AST"); @@ -48,11 +48,11 @@ struct AST_Comment }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Comment) == sizeof(AST), "ERROR: AST_Comment is not the same size as AST"); @@ -73,12 +73,12 @@ struct AST_Class }; CodeType Prev; CodeType Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; AccessSpec ParentAccess; - s32 Token; }; static_assert( sizeof(AST_Class) == sizeof(AST), "ERROR: AST_Class is not the same size as AST"); @@ -99,11 +99,11 @@ struct AST_Constructor }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; char _PAD_NAME_[ sizeof(StringCached) ]; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Constructor) == sizeof(AST), "ERROR: AST_Constructor is not the same size as AST"); @@ -115,11 +115,11 @@ struct AST_Define }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the same size as AST"); @@ -139,11 +139,11 @@ struct AST_Destructor }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; char _PAD_NAME_[ sizeof(StringCached) ]; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Destructor) == sizeof(AST), "ERROR: AST_Destructor is not the same size as AST"); @@ -164,12 +164,12 @@ struct AST_Enum }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST"); @@ -181,11 +181,11 @@ struct AST_Exec }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Exec) == sizeof(AST), "ERROR: AST_Exec is not the same size as AST"); @@ -202,11 +202,11 @@ struct AST_Extern }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Extern) == sizeof(AST), "ERROR: AST_Extern is not the same size as AST"); @@ -218,11 +218,11 @@ struct AST_Include }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Include) == sizeof(AST), "ERROR: AST_Include is not the same size as AST"); @@ -240,11 +240,11 @@ struct AST_Friend }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Friend) == sizeof(AST), "ERROR: AST_Friend is not the same size as AST"); @@ -264,13 +264,13 @@ struct AST_Fn }; }; Code Prev; - Code Parent; Code Next; + Parser::Token* Token; + Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Fn) == sizeof(AST), "ERROR: AST_Fn is not the same size as AST"); @@ -279,12 +279,12 @@ struct AST_Module char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Module) == sizeof(AST), "ERROR: AST_Module is not the same size as AST"); @@ -300,12 +300,12 @@ struct AST_NS }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_NS) == sizeof(AST), "ERROR: AST_NS is not the same size as AST"); @@ -324,14 +324,14 @@ struct AST_Operator char _PAD_PROPERTIES_ [ sizeof(AST*) ]; }; }; - Code Prev; - Code Next; - Code Parent; - StringCached Name; - CodeT Type; - ModuleFlag ModuleFlags; - OperatorT Op; - s32 Token; + Code Prev; + Code Next; + Parser::Token* Token; + Code Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + OperatorT Op; }; static_assert( sizeof(AST_Operator) == sizeof(AST), "ERROR: AST_Operator is not the same size as AST"); @@ -352,11 +352,11 @@ struct AST_OpCast }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the same size as AST"); @@ -375,12 +375,12 @@ struct AST_Param }; CodeParam Last; CodeParam Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; s32 NumEntries; - s32 Token; }; static_assert( sizeof(AST_Param) == sizeof(AST), "ERROR: AST_Param is not the same size as AST"); @@ -392,11 +392,11 @@ struct AST_Pragma }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Pragma) == sizeof(AST), "ERROR: AST_Pragma is not the same size as AST"); @@ -408,11 +408,11 @@ struct AST_PreprocessCond }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_PreprocessCond is not the same size as AST"); @@ -422,12 +422,12 @@ struct AST_Specifiers CodeSpecifiers NextSpecs; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; s32 NumEntries; - s32 Token; }; static_assert( sizeof(AST_Specifiers) == sizeof(AST), "ERROR: AST_Specifier is not the same size as AST"); @@ -448,12 +448,12 @@ struct AST_Struct }; CodeType Prev; CodeType Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; AccessSpec ParentAccess; - s32 Token; }; static_assert( sizeof(AST_Struct) == sizeof(AST), "ERROR: AST_Struct is not the same size as AST"); @@ -471,12 +471,12 @@ struct AST_Template }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Template) == sizeof(AST), "ERROR: AST_Template is not the same size as AST"); @@ -497,12 +497,12 @@ struct AST_Type }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; b32 IsParamPack; - s32 Token; }; static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST"); @@ -520,12 +520,12 @@ struct AST_Typedef }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; b32 IsFunction; - s32 Token; }; static_assert( sizeof(AST_Typedef) == sizeof(AST), "ERROR: AST_Typedef is not the same size as AST"); @@ -544,12 +544,12 @@ struct AST_Union }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Union) == sizeof(AST), "ERROR: AST_Union is not the same size as AST"); @@ -568,12 +568,12 @@ struct AST_Using }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Using) == sizeof(AST), "ERROR: AST_Using is not the same size as AST"); @@ -594,12 +594,12 @@ struct AST_Var }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST"); diff --git a/project/components/gen/ecode.hpp b/project/components/gen/ecode.hpp index 678c476..68877f7 100644 --- a/project/components/gen/ecode.hpp +++ b/project/components/gen/ecode.hpp @@ -1,6 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once -#include "types.hpp" +#include "components/Types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/gen/eoperator.hpp b/project/components/gen/eoperator.hpp index b1ab7c9..a26e8ce 100644 --- a/project/components/gen/eoperator.hpp +++ b/project/components/gen/eoperator.hpp @@ -1,6 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once -#include "types.hpp" +#include "components/types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/gen/especifier.hpp b/project/components/gen/especifier.hpp index 7e53adc..0a0e1cf 100644 --- a/project/components/gen/especifier.hpp +++ b/project/components/gen/especifier.hpp @@ -1,6 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once -#include "types.hpp" +#include "components/types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/interface.cpp b/project/components/interface.cpp index 44d41cd..917aa96 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -419,15 +419,15 @@ Code make_code() // mem_set( result.ast, 0, sizeof(AST) ); result->Type = ECode::Invalid; - result->Content = { nullptr }; - result->Prev = { nullptr }; - result->Next = { nullptr }; - result->Parent = { nullptr }; - result->Name = { nullptr }; - result->Type = ECode::Invalid; - result->ModuleFlags = ModuleFlag::Invalid; - result->NumEntries = 0; - result->Token = -1; + result->Content = { nullptr }; + result->Prev = { nullptr }; + result->Next = { nullptr }; + result->Token = nullptr; + result->Parent = { nullptr }; + result->Name = { nullptr }; + result->Type = ECode::Invalid; + result->ModuleFlags = ModuleFlag::Invalid; + result->NumEntries = 0; return result; } diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index b0f6b46..c929f6b 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -6,6 +6,18 @@ namespace Parser { + enum TokFlags : u32 + { + TF_Operator = bit(0), + TF_Assign = bit(0), + TF_Preprocess = bit(1), + TF_Comment = bit(2), + TF_Attribute = bit(3), + TF_AccessSpecifier = bit(4), + TF_Specifier = bit(5), + TF_EndDefinition = bit(6), // Either ; or } + }; + struct Token { char const* Text; @@ -251,11 +263,6 @@ namespace Parser return true; } - enum TokFlags : u32 - { - IsAssign = bit(0), - }; - global Array Tokens; neverinline @@ -1638,6 +1645,7 @@ CodeAttributes parse_attributes() { eat( TokType::Attribute_Open); + start = currtok; while ( left && currtok.Type != TokType::Attribute_Close ) { eat( currtok.Type ); @@ -1653,6 +1661,7 @@ CodeAttributes parse_attributes() eat(TokType::Capture_Start); eat(TokType::Capture_Start); + start = currtok; while ( left && currtok.Type != TokType::Capture_End ) { eat(currtok.Type); @@ -1669,6 +1678,7 @@ CodeAttributes parse_attributes() eat( TokType::Decl_MSVC_Attribute ); eat( TokType::Capture_Start); + start = currtok; while ( left && currtok.Type != TokType::Capture_End ) { eat(currtok.Type); @@ -1697,6 +1707,7 @@ CodeAttributes parse_attributes() result->Type = ECode::PlatformAttributes; result->Name = get_cached_string( name_stripped ); result->Content = result->Name; + // result->Token = return (CodeAttributes) result; } @@ -1717,6 +1728,7 @@ CodeComment parse_comment() result->Type = ECode::Comment; result->Content = get_cached_string( currtok_noskip ); result->Name = result->Content; + // result->Token = currtok_noskip; eat( TokType::Comment ); Context.pop(); @@ -5052,7 +5064,7 @@ CodeType parse_type( bool* typedef_is_function ) CodeType result = (CodeType) make_code(); result->Type = Typename; - result->Token = Context.Scope->Start; + // result->Token = Context.Scope->Start; // Need to wait until were using the new parsing method to do this. String name_stripped = strip_formatting( name, strip_formatting_dont_preserve_newlines ); diff --git a/project/components/types.hpp b/project/components/types.hpp index 460145e..b9d5437 100644 --- a/project/components/types.hpp +++ b/project/components/types.hpp @@ -41,6 +41,15 @@ char const* to_str( AccessSpec type ) return lookup[ (u32)type ]; } + +enum CodeFlag : u32 +{ + FunctionType = bit(0), + ParamPack = bit(1), + Module_Export = bit(2), + Module_Import = bit(3), +}; + // Used to indicate if enum definitoin is an enum class or regular enum. enum class EnumT : u8 { diff --git a/project/dependencies/debug.hpp b/project/dependencies/debug.hpp index 43d50cb..40e7747 100644 --- a/project/dependencies/debug.hpp +++ b/project/dependencies/debug.hpp @@ -1,4 +1,4 @@ -#ifdef GEN_INTELLISENSE_DIRECTIVESj +#ifdef GEN_INTELLISENSE_DIRECTIVES # pragma once # include "basic_types.hpp" #endif diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index e1a4db6..4f3d812 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -113,6 +113,39 @@ function run-linker } } +function run-compile-and-link +{ + param( $vendor, $unit, $compiler_args, $linker_args ) + + write-host "`Compiling & Linking $unit" + write-host "Compiler config:" + $compiler_args | ForEach-Object { + write-host $_ -ForegroundColor Cyan + } + write-host "Linker config:" + $linker_args | ForEach-Object { + write-host $_ -ForegroundColor Cyan + } + + $time_taken = Measure-Command { + & $vendor $compiler_args $linker_args 2>&1 | ForEach-Object { + $color = 'White' + switch ($_){ + { $_ -match "error" } { $color = 'Red' ; break } + { $_ -match "warning" } { $color = 'Yellow'; break } + } + write-host `t $_ -ForegroundColor $color + } + } + + # if ( Test-Path($binary) ) { + # write-host "$binary compile & link finished in $($time_taken.TotalMilliseconds) ms" + # } + # else { + # write-host "Compile & Link failed for $binary" -ForegroundColor Red + # } +} + if ( $vendor -match "clang" ) { # https://clang.llvm.org/docs/ClangCommandLineReference.html @@ -173,7 +206,8 @@ if ( $vendor -match "clang" ) $flag_wall, $flag_preprocess_non_intergrated, ( $flag_define + 'GEN_TIME' ), - ( $flag_path_output + $object ), + # ( $flag_path_output + $object ), + ( $flag_path_output + $executable ) ( $flag_include + $includes ) ) if ( $release -eq $false ) { @@ -188,8 +222,8 @@ if ( $vendor -match "clang" ) # $compiler_args += $flag_preprocess - $compiler_args += $flag_compile, $unit - run-compiler $compiler $unit $compiler_args + # $compiler_args += $flag_compile, $unit + # run-compiler $compiler $unit $compiler_args $linker_args = @( $flag_link_win_subsystem_console, @@ -207,8 +241,12 @@ if ( $vendor -match "clang" ) $linker_args += $_ + '.lib' } - $linker_args += $object - run-linker $linker $executable $linker_args + # $linker_args += $object + # run-linker $linker $executable $linker_args + + $compiler_args += $unit + # $linker_args += $object + run-compile-and-link $compiler $unit $compiler_args } $compiler = 'clang++'