From 208cc67a7fa37c48f9e5b2dccc82ab9f64814e6c Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 25 Oct 2024 05:04:11 -0400 Subject: [PATCH] Updates to gasagen gencpp library after backporting changes from this project to the gencpp repo. --- .../GasaEditor/GasaGen/ChangeBPActionMenu.cpp | 1 + .../GasaEditor/GasaGen/gencpp/AST_Design.md | 44 + .../GasaEditor/GasaGen/gencpp/AST_Types.md | 737 +++++++++ .../Source/GasaEditor/GasaGen/gencpp/LICENSE | 28 + .../GasaEditor/GasaGen/gencpp/Parser_Algo.md | 702 +++++++++ .../GasaEditor/GasaGen/gencpp/Parsing.md | 81 + .../GasaEditor/GasaGen/gencpp/Readme.md | 137 ++ .../GasaEditor/GasaGen/gencpp/Readme_Docs.md | 489 ++++++ .../GasaEditor/GasaGen/gencpp/gen.builder.cpp | 8 +- .../GasaEditor/GasaGen/gencpp/gen.builder.hpp | 11 +- .../Source/GasaEditor/GasaGen/gencpp/gen.cpp | 189 ++- .../GasaEditor/GasaGen/gencpp/gen.dep.cpp | 9 +- .../GasaEditor/GasaGen/gencpp/gen.dep.hpp | 117 +- .../Source/GasaEditor/GasaGen/gencpp/gen.hpp | 1355 ++++++----------- .../GasaEditor/GasaGen/gencpp/gen.scanner.cpp | 27 +- .../GasaEditor/GasaGen/gencpp/gen.scanner.hpp | 9 +- Project/Source/GasaGen/GasaGen.cpp | 13 +- Project/Source/GasaGen/gen.builder.cpp | 32 +- Project/Source/GasaGen/gen.builder.hpp | 29 +- Project/Source/GasaGen/gen.cpp | 213 ++- Project/Source/GasaGen/gen.dep.cpp | 34 +- Project/Source/GasaGen/gen.dep.hpp | 143 +- Project/Source/GasaGen/gen.hpp | 940 ++++++------ Project/Source/GasaGen/gen.scanner.cpp | 49 +- Project/Source/GasaGen/gen.scanner.hpp | 31 +- 25 files changed, 3769 insertions(+), 1659 deletions(-) create mode 100644 Project/Source/GasaEditor/GasaGen/gencpp/AST_Design.md create mode 100644 Project/Source/GasaEditor/GasaGen/gencpp/AST_Types.md create mode 100644 Project/Source/GasaEditor/GasaGen/gencpp/LICENSE create mode 100644 Project/Source/GasaEditor/GasaGen/gencpp/Parser_Algo.md create mode 100644 Project/Source/GasaEditor/GasaGen/gencpp/Parsing.md create mode 100644 Project/Source/GasaEditor/GasaGen/gencpp/Readme.md create mode 100644 Project/Source/GasaEditor/GasaGen/gencpp/Readme_Docs.md diff --git a/Project/Source/GasaEditor/GasaGen/ChangeBPActionMenu.cpp b/Project/Source/GasaEditor/GasaGen/ChangeBPActionMenu.cpp index abbda96..0dad5c9 100644 --- a/Project/Source/GasaEditor/GasaGen/ChangeBPActionMenu.cpp +++ b/Project/Source/GasaEditor/GasaGen/ChangeBPActionMenu.cpp @@ -1,4 +1,5 @@ // Used in the GasaGen.cpp translation unit +#include "ChangeBPActionMenu.h" #include "GasaGen_Common.h" constexpr StrC SBlueprintActionMenu_Construct_Replacement = txt(R"( diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/AST_Design.md b/Project/Source/GasaEditor/GasaGen/gencpp/AST_Design.md new file mode 100644 index 0000000..8b123e9 --- /dev/null +++ b/Project/Source/GasaEditor/GasaGen/gencpp/AST_Design.md @@ -0,0 +1,44 @@ +## 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. +The actual content per type of AST is covered within [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; +``` + +As of November 21st, 2023, the AST has had a strict layout for how its content is laid out. +This will be abandoned during its redesign that will occur starting with support for statments & expressions for either execution and type declarations. +Having a strict layout is too resctrictive vs allowing each AST type to have maximum control over the layout. + +The redesign will occur after the following todos are addressed: + +* [Improvements Lexer & Token struct#27](https://github.com/Ed94/gencpp/issues/27) +* [Generalize AST Flags to a single 4-byte flag#42](https://github.com/Ed94/gencpp/issues/42) +* [AST-Code Object Redesign.#38](https://github.com/Ed94/gencpp/issues/38) +* [Code-AST Documentation#40](https://github.com/Ed94/gencpp/issues/40) +* [AST::debug_str() improvements#33](https://github.com/Ed94/gencpp/issues/33) +* [AST::is_equal implemented and works with singleheader-test#31](https://github.com/Ed94/gencpp/issues/31) +* [Parser : Add ability to have a parse failure and continue with errors recorded.#35](https://github.com/Ed94/gencpp/issues/35) +* [Scanner : Add CodeFile#29](https://github.com/Ed94/gencpp/issues/29) +* [Auxiliary : AST visual debugger#36](https://github.com/Ed94/gencpp/issues/36) + diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/AST_Types.md b/Project/Source/GasaEditor/GasaGen/gencpp/AST_Types.md new file mode 100644 index 0000000..3f96ceb --- /dev/null +++ b/Project/Source/GasaEditor/GasaGen/gencpp/AST_Types.md @@ -0,0 +1,737 @@ +# 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. + +## Body + +These are containers representing a scope body of a definition that can be of the following `ECode` type: + +* Class_Body +* Enum_Body +* Export_Body +* Extern_Linkage_Body +* Function_Body +* Global_Body +* Namespace_Body +* Struct_Body +* Union_Body + +Fields: + +```cpp +Code Front; +Code Back; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +s32 NumEntries; +``` + +The `Front` member represents the start of the link list and `Back` the end. +NumEntries is the number of entries in the body. + +Parent should have a compatible ECode type for the type of defintion used. + +Serialization: + +Will output only the entries, the braces are handled by the parent. + +```cpp +... + +``` + +## Attributes + +Represent standard or vendor specific C/C++ attributes. + +Fields: + +```cpp +StringCached Content; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp + +``` + +While the parser supports the `__declspec` and `__attribute__` syntax, the upfront constructor ( def_attributes ) must have the user specify the entire attribute, including the `[[]]`, `__declspec` or `__attribute__` parts. + +## Comment + +Stores a comment. + +Fields: + +```cpp +StringCached Content; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp + +``` + +The parser will perserve comments found if residing with a body or in accepted inline-to-definition locations. +Otherwise they will be skipped by the TokArray::__eat and TokArray::current( skip foramtting enabled ) functions. + +The upfront constructor: `def_comment` expects to recieve a comment without the `//` or `/* */` parts. It will add them during construction. + +## Class & Struct + +Fields: + +```cpp +CodeComment InlineCmt; // Only supported by forward declarations +CodeAttributes Attributes; +CodeType ParentType; +CodeBody Body; +CodeType Prev; // Used to store references to interfaces +CodeType Next; // Used to store references to interfaces +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +AccessSpec ParentAccess; +``` + +Serialization: + +```cpp +// Class_Fwd + ; + +// Class + : , public Next>, ... +{ + +}; +``` + +You'll notice that only one parent type is supported only with parent access. This library only supports single inheritance, the rest must be done through interfaces. + +## Constructor + +Fields: + +```cpp +CodeComment InlineCmt; // Only supported by forward declarations +Code InitializerList; +CodeParam Params; +Code Body; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp +// Constructor_Fwd + Name>( ); + +// Constructor + Name>( ) + : +{ + +} + +// Constructor Source Implementation + ::~Name>( ) +{ + +} +``` + +## Define + +Represents a preprocessor define + +Fields: + +```cpp +StringCached Content; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp +#define +``` + +## Destructor + +Fields: + +```cpp +CodeComment InlineCmt; +CodeSpecifiers Specs; +Code Body; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp +// Destructor_Fwd + ~Name>( ) ; + +// Destructor + ~Name>( ) +{ + +} + +// Destructor Source Implementation + ::~Name>( ) +{ + +} +``` + +## Enum + +Fields: + +```cpp +CodeComment InlineCmt; +CodeAttributes Attributes; +CodeType UnderlyingType; +CodeBody Body; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +``` + +Serialization: + +```cpp +// Enum_Fwd + enum class : ; + +// Enum + : +{ + +}; +``` + +## Execution + +Just represents an execution body. Equivalent to an untyped body. +Will be obsolute when function body parsing is implemented. + +Fields: + +```cpp +StringCached Content; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp + +``` + +## External Linkage + +Fields: + +```cpp +CodeBody Body; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp +extern "" +{ + +} +``` + +## Include + +Fields: + +```cpp +StringCached Content; +Code Prev; +Code Next; +Code Parent; +parser::Token* Tok; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp +#include +``` + +## Friend + +This library (until its necessary become some third-party library to do otherwise) does not support friend declarations with in-statment function definitions. + +Fields: + +```cpp +CodeComment InlineCmt; +Code Declaration; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp +friend ; +``` + +## Function + +Fields: + +```cpp +CodeComment InlineCmt; +CodeAttributes Attributes; +CodeSpecifiers Specs; +CodeType ReturnType; +CodeParam Params; +CodeBody Body; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +``` + +Serialization: + +```cpp +// Function_Fwd + ( ) ; + +// Function + ( ) +{ + +} +``` + +## Module + +Fields: + +```cpp +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +``` + +Serialization: + +```cpp + module ; +``` + +## Namespace + +Fields: + +```cpp +CodeBody Body; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +``` + +Serialization: + +```cpp + namespace +{ + +} +``` + +## Operator Overload + +Fields: + +```cpp +CodeComment InlineCmt; +CodeAttributes Attributes; +CodeSpecifiers Specs; +CodeType ReturnType; +CodeParam Params; +CodeBody Body; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +OperatorT Op; +``` + +Serialization: + +```cpp +// Operator_Fwd + operator ( ) ; + +// Operator + operator ( ) +{ + +} +``` + +## Operator Cast Overload ( User-Defined Type Conversion ) + +Fields: + +```cpp +CodeComment InlineCmt; +CodeSpecifiers Specs; +CodeType ValueType; +CodeBody Body; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp +// Operator_Cast_Fwd + operator () ; + +// Operator_Cast + operator () +{ + +} +``` + +## Parameters (AST_Param) + +Fields: + +```cpp +CodeType ValueType; +Code Macro; +Code Value; +CodeParam Last; +CodeParam Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +s32 NumEntries; +``` + +Serialization: + +```cpp +, ... + + , ... +``` + +## Pragma + +Fields: + +```cpp +StringCached Content; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp +#pragma +``` + +## Preprocessor Conditional + +Fields: + +```cpp +StringCached Content; +Code Prev; +Code Next; +paser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +``` + +Serialization: + +```cpp +# +``` + +## Specifiers + +Fields: + +```cpp +SpecifierT ArrSpecs[ AST::ArrSpecs_Cap ]; +CodeSpecifiers NextSpecs; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +s32 NumEntries; +``` + +Serialization: + +```cpp +, ... +``` + +## Template + +Fields: + +```cpp +CodeParam Params; +Code Declaration; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +``` + +Serialization: + +```cpp + +template< > + +``` + +## Typename + +Typenames represent the type "symbol". + +Fields: + +```cpp +CodeAttributes Attributes; +CodeSpecifiers Specs; +CodeReturnType ReturnType; +CodeParam Params; +Code ArrExpr; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +b32 IsParamPack; +``` + +Serialization: + +```cpp + +``` + +## Typedef + +Behave as usual except function or macro typedefs. +Those (macros) don't use the underlying type field as everything was serialized under the Name field. + +Fields: + +```cpp +CodeComment InlineCmt; +Code UnderlyingType; +Code Prev; +Code Next; +parse::Token* Tok +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +b32 IsFunction; +``` + +Serialization: + +```cpp +// Regular + typedef ; + +// Functions + typedef ( ); + typedef ( )( ); +``` + +## Union + +Fields: + +```cpp +CodeAttributes Attributes; +CodeBody Body; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +``` + +Serialization: + +```cpp + union +{ + +} +``` + +## Using + +Fields: + +```cpp +CodeComment InlineCmt; +CodeAttributes Attributes; +CodeType UnderlyingType; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +``` + +Serialization: + +```cpp +// Regular + using = ; + +// Namespace + using namespace ; +``` + +## Variable + +[Algo](./Parser_Algo.md:) + +Fields: + +```cpp +CodeComment InlineCmt; +CodeAttributes Attributes; +CodeSpecifiers Specs; +CodeType ValueType; +Code BitfieldSize; +Code Value; +CodeVar NextVar; +Code Prev; +Code Next; +parser::Token* Tok; +Code Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +``` + +Serialization: + +```cpp +// Regular + = , NextVar ...; + +// Bitfield + : = , NextVar ...; +``` diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/LICENSE b/Project/Source/GasaEditor/GasaGen/gencpp/LICENSE new file mode 100644 index 0000000..90e47fc --- /dev/null +++ b/Project/Source/GasaEditor/GasaGen/gencpp/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2023, Edward R. Gonzalez + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/Parser_Algo.md b/Project/Source/GasaEditor/GasaGen/gencpp/Parser_Algo.md new file mode 100644 index 0000000..d085f3b --- /dev/null +++ b/Project/Source/GasaEditor/GasaGen/gencpp/Parser_Algo.md @@ -0,0 +1,702 @@ +# Parser's Algorithim + +gencpp uses a hand-written recursive descent parser. Both the lexer and parser currently handle a full C/C++ file in a single pass. + +## Notable implementation background + +### Lexer + +The lex procedure does the lexical pass of content provided as a `StrC` type. +The tokens are stored (for now) in `gen::parser::Tokens`. + +Fields: + +```cpp +Array Arr; +s32 Idx; +``` + +What token types are supported can be found in [ETokType.csv](../project/enums/ETokType.csv) you can also find the token types in [ETokType.h](../project/components/gen/etoktype.cpp) , which is the generated enum from the csv file. + +Tokens are defined with the struct `gen::parser::Token`: + +Fields: + +```cpp +char const* Text; +sptr Length; +TokType Type; +s32 Line; +s32 Column; +u32 Flags; +``` + +Flags is a bitfield made up of TokFlags (Token Flags): + +* `TF_Operator` : Any operator token used in expressions +* `TF_Assign` + * Using statment assignment + * Parameter argument default value assignment + * Variable declaration initialization assignment +* `TF_Preprocess` : Related to a preprocessing directive +* `TF_Preprocess_Cond` : A preprocess conditional +* `TF_Attribute` : An attribute token +* `TF_AccessSpecifier` : An accesor operation token +* `TF_Specifier` : One of the specifier tokens +* `TF_EndDefinition` : Can be interpreted as an end definition for a scope. +* `TF_Formatting` : Considered a part of the formatting +* `TF_Literal` : Anything considered a literal by C++. + +I plan to replace IsAssign with a general flags field and properly keep track of all operator types instead of abstracting it away to `ETokType::Operator`. + +Traversing the tokens is done with the following interface macros: + +| Macro | Description | +| --- | --- | +| `currtok_noskip` | Get the current token without skipping whitespace | +| `currtok` | Get the current token, skip any whitespace tokens | +| `prevtok` | Get the previous token (does not skip whitespace) | +| `nexttok` | Get the next token (does not skip whitespace) | +| `eat( Token Type )` | Check to see if the current token is of the given type, if so, advance Token's index to the next token | +| `left` | Get the number of tokens left in the token array | +| `check_noskip` | Check to see if the current token is of the given type, without skipping whitespace | +| `check` | Check to see if the current token is of the given type, skip any whitespace tokens | + +### Parser + +The parser has a limited user interface, only specific types of definitions or statements are expected to be provided by the user directly when using to construct an AST dynamically (See SOA for example). It however does attempt to provide capability to parse a full C/C++ from production codebases. + +Each public user interface procedure has the following format: + +```cpp + parse_( StrC def ) +{ + check_parse_args( def ); + using namespace Parser; + + TokArray toks = lex( def ); + if ( toks.Arr == nullptr ) + return CodeInvalid; + + // Parse the tokens and return a constructed AST using internal procedures + ... +} +``` + +The most top-level parsing procedure used for C/C++ file parsing is `parse_global_body`: + +It uses a helper procedure called `parse_global_nspace`. + +Each internal procedure will have the following format: + +```cpp +internal + parse_( ) +{ + push_scope(); + + ... + + result = () make_code(); + ... + + Context.pop(); + return result; +} +``` + +Below is an outline of the general alogirithim used for these internal procedures. The intention is to provide a basic briefing to aid the user in traversing the actual code definitions. These appear in the same order as they are in the `parser.cpp` file + +***NOTE: This is still heavily in an alpha state. A large swaph of this can change, make sure these docs are up to date before considering them 1:1 with the repo commit your considering.*** + +## `parse_array_decl` + +1. Check if its an array declaration with no expression. + 1. Consume and return empty array declaration +2. Opening square bracket +3. Consume expression +4. Closing square bracket +5. If adjacent opening bracket + 1. Repeat array declaration parse until no brackets remain + +## `parse_assignment_expression` + +1. Eat the assignment operator +2. Make sure there is content or at least an end statement after. +3. Flatten the assignment expression to an untyped Code string. + +## `parse_attributes` + +1. Check for standard attribute +2. Check for GNU attribute +3. Check for MSVC attribute +4. Check for a token registered as an attribute + a. Check and grab the arguments of a token registered of an attribute if it has any. +5. Repeat for chained attributes. Flatten them to a single attribute AST node. + +## `parse_class_struct` + +1. Check for export module specifier +2. class or struct keyword +3. `parse_attributes` +4. If identifier : `parse_identifier` +5. Parse inherited parent or interfaces +6. If opening curly brace : `parse_class_struct_body` +7. If not an inplace definition + 1. End statement + 2. Check for inline comment + +## `parse_class_struct_body` + +1. Opening curly brace +2. Parse the body (Possible options): + 1. Ignore dangling end statements + 2. Newline : ast constant + 3. Comment : `parse_comment` + 4. Access_Public : ast constant + 5. Access_Protected : ast constant + 6. Access_Private : ast constant + 7. Decl_Class : `parse_complicated_definition` + 8. Decl_Enum : `parse_complicated_definition` + 9. Decl_Friend : `parse_friend` + 10. Decl_Operator : `parse_operator_cast` + 11. Decl_Struct : `parse_complicated_definition` + 12. Decl_Template : `parse_template` + 13. Decl_Typedef : `parse_typedef` + 14. Decl_Union : `parse_complicated_definition` + 15. Decl_Using : `parse_using` + 16. Operator == '~' + 1. `parse_destructor` + 17. Preprocess_Define : `parse_define` + 18. Preprocess_Include : `parse_include` + 19. Preprocess_Conditional (if, ifdef, ifndef, elif, else, endif) : `parse_preprocess_cond` or else/endif ast constant + 20. Preprocess_Macro : `parse_simple_preprocess` + 21. Preprocess_Pragma : `parse_pragma` + 22. Preprocess_Unsupported : `parse_simple_preprocess` + 23. StaticAssert : `parse_static_assert` + 24. The following compound into a resolved definition or declaration: + 1. Attributes (Standard, GNU, MSVC) : `parse_attributes` + 2. Specifiers (consteval, constexpr, constinit, explicit, forceinline, inline, mutable, neverinline, static, volatile, virtual) + 3. Possible Destructor : `parse_destructor` + 4. Possible User defined operator cast : `parse_operator_cast` + 5. Possible Constructor : `parse_constructor` + 6. Something that has the following: (identifier, const, unsigned, signed, short, long, bool, char, int, double) + 1. Possible Constructor `parse_constructor` + 2. Possible Operator, Function, or varaible : `parse_operator_function_or_variable` + 25. Something completely unknown (will just make untyped...) : `parse_untyped` + +## `parse_comment` + +1. Just wrap the token into a cached string ( the lexer did the processing ) + +## `parse_compilcated_definition` + +This is a helper function used by the following functions to help resolve a declaration or definition: + +* `parse_class_struct_body` +* `parse_global_nspace` +* `parse_union` + +A portion of the code in `parse_typedef` is very similar to this as both have to resolve a similar issue. + +1. Look ahead to the termination token (End statement) +2. Check to see if it fits the pattern for a forward declare +3. If the previous token was an identifier ( `token[-1]` ): + 1. Look back one more token : `[-2]` + 2. If the token has a closing brace its an inplace definition + 3. If the `token[-2]` is an identifier & `token[-3]` is the declaration type, its a variable using a namespaced type. + 4. If the `token[-2]` is an indirection, then its a variable using a namespaced/forwarded type. + 5. If the `token[-2]` is an assign classifier, and the starting tokens were the which type with possible `class` token after, its an enum forward declaration. + 6. If any of the above is the case, `parse_operator_function_or_variable` +4. If the `token[2]` is a vendor fundamental type (builtin) then it is an enum forward declaration. +5. If the previous token was a closing curly brace, its a definition : `parse_forward_or_definition` +6. If the previous token was a closing square brace, its an array definition : `parse_operator_function_or_variable` + +## `parse_define` + +1. Define directive +2. Get identifier +3. Get Content (Optional) + +## `parse_forward_or_definition` + +* Parse any of the following for either a forward declaration or definition: + 1. Decl_Class : `parse_class` + 2. Decl_Enum : `parse_enum` + 3. Decl_Struct : `parse_struct` + 4. Decl_Union : `parse_union` + +## `parse_function_after_name` + +This is needed as a function defintion is not easily resolvable early on, as such this function handles resolving a function +after its been made ceratin that the type of declaration or definition is indeed for a function signature. + +By the point this function is called the following are known : export module flag, attributes, specifiers, return type, & name + +1. `parse_parameters` +2. parse postfix specifiers (we do not check if the specifier here is correct or not to be here... yet) +3. If there is a body : `parse_body` +4. Otherwise : + 1. Statment end + 2. Check for inline comment + +## `parse_function_body` + +Currently there is no actual parsing of the function body. Any content with the braces is shoved into an execution AST node. +In the future statements and expressions will be parsed. + +1. Open curly brace +2. Grab all tokens between the brace and the closing brace, shove them in a execution AST node. +3. Closing curly brace + +## `parse_global_nspace` + +1. Make sure this is being called for a valid type (namespace, global body, export body, linkage body) +2. If its not a global body, consume the opening curly brace +3. Parse the body (Possible options): + 1. Ignore dangling end statements + 2. NewLine : ast constant + 3. Comment : `parse_comment` + 4. Decl_Cass : `parse_complicated_definition` + 5. Decl_Enum : `parse_complicated_definition` + 6. Decl_Extern_Linkage : `parse_extern_link` + 7. Decl_Namespace : `parse_namespace` + 8. Decl_Struct : `parse_complicated_definition` + 9. Decl_Template : `parse_template` + 10. Decl_Typedef : `parse_typedef` + 11. Decl_Union : `parse_complicated_definition` + 12. Decl_Using : `parse_using` + 13. Preprocess_Define : `parse_define` + 14. Preprocess_Include : `parse_include` + 15. Preprocess_If, IfDef, IfNotDef, Elif : `parse_preprocess_cond` + 16. Preprocess_Else : ast constant + 17. Preprocess_Endif : ast constant + 18. Preprocess_Macro : `parse_simple_preprocess` + 19. Preprocess_Pragma : `parse_pragma` + 20. Preprocess_Unsupported : `parse_simple_preprocess` + 21. StaticAssert : `parse_static_assert` + 22. Module_Export : `parse_export_body` + 23. Module_Import : NOT_IMPLEMENTED + 24. The following compound into a resolved definition or declaration: + 1. Attributes ( Standard, GNU, MSVC, Macro ) : `parse_attributes` + 2. Specifiers ( consteval, constexpr, constinit, extern, forceinline, global, inline, internal_linkage, neverinline, static ) + 3. Is either ( identifier, const specifier, long, short, signed, unsigned, bool, char, double, int) + 1. Attempt to parse as constrcutor or destructor : `parse_global_nspace_constructor_destructor` + 2. If its an operator cast (definition outside class) : `parse_operator_cast` + 3. Its an operator, function, or varaible : `parse_operator_function_or_varaible` +4. If its not a global body, consume the closing curly brace + +## `parse_global_nspace_constructor_destructor` + +1. Look ahead for the start of the arguments for a possible constructor/destructor +2. Go back past the identifier +3. Check to see if its a destructor by checking for the `~` +4. Continue the next token should be a `::` +5. Determine if the next valid identifier (ignoring possible template parameters) is the same as the first identifier of the function. +6. If it is we have either a constructor or destructor so parse using their respective functions (`parse_constructor`, `parse_destructor`). + +## `parse_identifier` + +This is going to get heavily changed down the line to have a more broken down "identifier expression" so that the qualifier, template args, etc, can be distinguished between the targeted identifier. +The function can parse all of them, however the AST node compresses them all into a string. + +1. Consume first identifier +2. `parse_template_args` +3. While there is a static symbol accessor ( `::` ) + 1. Consume `::` + 2. Consume member identifier + 3. `parse_template args` (for member identifier) + 4. If a `~` is encounted and the scope is for a destructor's identifier, do not consume it and return with what parsed. + +## `parse_include` + +1. Consume include directive +2. Consume the path + +## `parse_operator_after_ret_type` + +This is needed as a operator defintion is not easily resolvable early on, as such this function handles resolving a operator after its been made ceratin that the type of declaration or definition is indeed for a operator signature. + +By the point this function is called the following are known : export module flag, attributes, specifiers, return type + +1. If there is any qualifiers for the operator, parse them +2. Consume operator keyword +3. Determine the operator type (This will be offloaded to the lexer moreso than how it is now) & consume +4. `parse_params` +5. If there is no parameters this is operator is a member of pointer if its symbols is a *. +6. Parse postfix specifiers +7. If there is a opening curly brace, `parse function_body` +8. Otherwise: consume end statement, check for inline comment. + +## `parse_operator_function_or_variable` + +When this function is called, attribute and specifiers may have been resolved, however what comes next can still be either an operator, function, or varaible. + +1. Check for preprocessor macro, if there is one : `parse_simple_preprocess` +2. `parse_type` (Does the bulk of the work) +3. Begin lookahead to see if we get qualifiers or we eventually find the operator declaration +4. If we find an operator keyword : `parse_operator_after_ret_type` +5. otherwise : + 1. `parse_identifier` + 2. If we se a opening parenthesis (capture start), its a function : `parse_function_after_name` + 3. Its a variable : `parse_variable_after_name` + +## `parse_pragma` + +1. Consume pragma directive +2. Process the token content into cached string + +## `parse_params` + +1. Consume either a `(` or `<` based on `use_template_capture` arg +2. If the we immdiately find a closing token, consume it and finish. +3. If we encounter a varadic argument, consume it and return a `param_varadic` ast constant +4. `parse_type` +5. If we have a macro, parse it (Unreal has macros as tags to parameters and or as entire arguments). +6. So long as next token isn't a comma + a. If we have an identifier + 1. Consume it + 2. Check for assignment: + a. Consume assign operator + b. Parse the expression +7. While we continue to encounter commas + a. Consume them + b. Repeat steps 3 to 6.2.b +8. Consume the closing token + +## `parse_preprocess_cond` + +1. Parse conditional directive +2. Process directive's content expression + +## `parse_simple_preprocess` + +There is still decent room for improvement in this setup. Right now the entire macro's relevant tokens are shoved into an untyped AST. It would be better to store it instead in an `AST_Macro` node instead down the line. + +1. Consume the macro token +2. Check for an opening curly brace + 1. Consume opening curly brace + 2. Until the closing curly is encountered consume all tokens. + 3. If the parent context is a typedef + 1. Check for end stement + 1. Consume it + 2. Consume potential inline comment +3. Otherwise do steps 3 to 3.1.2 +4. Shove it all in an untyped string + +## `parse_static_assert` + +1. Consume static assert and opening curly brace +2. Consume all tokens until the the closing brace is reached. +3. Consume curly brace and end statement +4. Place all tokens within braces into a content for the assert. + +## `parse_template_args` + +This will get changed heavily once we have better support for typename expressions + +1. Consume opening angle bracket +2. Consume all tokens until closing angle bracket +3. Consme closing angle bracket +4. Return the currtok with the ammended length. + +## `parse_variable_after_name` + +This is needed as a variable defintion is not easily resolvable early on, it takes a long evaluation period before its known that the declaration or definition is a variable. As such this function handles resolving a variable. + +By the point this function is called the following are known : export module flag, attributes, specifiers, value type, name + +1. If its an assignment, parse the assignment expression (currently to an untyped string) +2. If its an opening curly brace, parse the expression within (currnelty to an untyped stirng). + 1. Consume the closing curly brace +3. If its a `:`, we're dealing with bitfield definition: + 1. Consume the assign classifier + 2. Consume the expression (currently to an untyped string) +4. If a comma is encountered : `parse_variable declaration_list` +5. Consume statement end +6. Check for inline comment + +## `parse_variable_declaration_list` + +1. Consume the comma +2. Parse specifiers +3. `parse_variable_after_name` + +## `parse_class` + +1. `parse_class_struct` + +## `parse_constructor` + +This currently doesn't support postfix specifiers (planning to in the future) + +1. `parse_identifier` +2. `parse_parameters` +3. If currtok is a `:` + 1. Consume `:` + 2. Parse the initializer list + 3. `parse_function_body` +4. If currtok is an opening curly brace + 1. `parse_function_body` +5. Otherwise: + 1. Consume statement end + 2. Check for inline comment + +## `parse_destructor` + +1. Check for and consume virtual specifier +2. Check for the `~` operator +3. `parse_identifier` +4. Consume opening and closing parenthesis +5. Check for assignment operator: + 1. Consume assignment op + 2. Consume pure specifier `0` +6. If not pure virtual & currtok is opening curly brace: + 1. `parse_function_body` +7. Otherwise: + 1. Consume end statement + 2. If currtok is comment : `parse_comment` + +## `parse_enum` + +1. Consume enum token +2. Check for and consume class token +3. `parse_attributes` +4. If there is an identifier consume it +5. Check for a `:` + 1. Consume `:` + 2. `parse_type` +6. If there is a body parse it (Consume `{`): + 1. Newline : ast constant + 2. Comment : `parse_comment` + 3. Preprocess_Define : `parse_define` + 4. Preprocess_Conditional (if, ifdef, ifndef, elif ) : `parse_preprocess_cond` + 5. Preprocess_Else : ast constant + 6. Preprocess_Endif : ast constant + 7. Preprocess_Macro : `parse_simple_preprocess` + 8. Preprocess_Pragma : `parse_pragma` + 9. Preprocess_Unsupported : `parse_smple_preprocess` + 10. An actual enum entry + 1. Consume identifier + 2. If there is an assignment operator: + 1. Consume operator + 2. Consume the expression (assigned to untyped string for now) + 3. If a macro is encountered consume it (Unreal UMETA macro support) + 3. If there is a comma, consume it + +## `parse_export_body` + +1. `parse_global_nspace` + +## `parse_extern_link_body` + +1. `parse_global_nspace` + +## `parse_extern_link` + +1. Consume Decl_Extern_Linkage +2. Consume the linkage identifier +3. `parse_extern_link_body` + +## `parse_friend` + +1. Consume `friend` +2. `parse_type` +3. If the currok is an identifier its a function declaration or definition + 1. `parse_function_after_name` +4. Consume end statement so long as its not a function definion +5. Check for inline comment, `parse_comment` if exists + +## `parse_function` + +1. Check and parse for `export` +2. `parse_attributes` +3. Parse specifiers +4. `parse_type` +5. `parse_identifier` +6. `parse_function_after_name` + +## `parse_namespace` + +1. Consume namespace declaration +2. Parse identifier +3. `parse_global_namespace` + +## `parse_operator` + +1. Check for and parse export declaration +2. `parse_attributes` +3. Parse specifiers +4. `parse_type` +5. `parse_operator_after_ret_type` + +## `parse_operator_cast` + +1. Look for and parse a qualifier namespace for the cast (in-case this is defined outside the class's scope) +2. Consume operator declaration +3. `parse_type` +4. Consume opening and closing parethesis +5. Check for a const qualifiying specifier +6. Check to see if this is a definition (`{`) + 1. Consume `{` + 2. Parse body to untyped string (parsing statement and expressions not supported yet) + 3. Consume `}` +7. Otherwise: + 1. Consume end statement + 2. Check for and consume comment : `parse_comment` + + +## `parse_struct` + +1. `parse_class_struct` + +## `parse_template` + +Note: This currently doesn't support templated operator casts (going to need to add support for it) + +1. Check for and parse export declaration +2. Consume template declaration +3. `parse_params` +4. Parse for any of the following: + 1. Decl_Class : `parse_class` + 2. Decl_Struct : `parse_struct` + 3. Decl_Union : `parse_union` + 4. Decl_Using : `parse_using` + 5. The following compound into a resolved definition or declaration: + 1. `parse_attributes` + 2. Parse specifiers + 3. Attempt to parse as constructor or destructor: `parse_global_nspace_constructor_destructor` + 4. Otherwise: `parse_operator_function_or_variable` + +## `parse_type` + +This function's implementation is awful and not done correctly. It will most likely be overhauled in the future as I plan to segement the AST_Type into several AST varaints along with sub-types to help produce robust type expressions. +Hopefully I won't need to make authentic type expressions as I was hopeing to avoid that... + +### Current Algorithim + +Anything that is in the qualifier capture of the function typename is treated as an expression abstracted as an untyped string + +1. `parse_attributes` +2. Parse specifiers +3. If the `parse_type` was called from a template parse, check to see if class was used instead of typname and consume as name. +4. This is where things get ugly for each of these depend on what the next token is. + 1. If its an in-place definition of a class, enum, struct, or union: + 2. If its a decltype (Not supported yet but draft impl there) + 3. If its a compound native type expression (unsigned, char, short, long, int, float, dobule, etc ) + 4. Ends up being a regular type alias of an identifier +5. Parse specifiers (postfix) +6. We need to now look ahead to see If we're dealing with a function typename +7. If wer're dealing with a function typename: + 1. Shove the specifiers, and identifier code we have so far into a return type typename's Name (untyped string) + 1. Reset the specifiers code for the top-level typeanme + 2. Check to see if the next token is an identifier: + 1. `parse_identifier` + 3. Check to see if the next token is capture start and is not the last capture ("qualifier capture"): + 1. Consume `(` + 2. Consume expresssion between capture + 3. Consume `)` + 4. `parse_params` + 5. Parse postfix specifiers +8. Check for varaidic argument (param pack) token: + 1. Consume varadic argument token + +### WIP - Alternative Algorithim + +Currently wrapped up via macro: `GEN_USE_NEW_TYPENAME_PARSING` +Anything that is in the qualifier capture of the function typename is treated as an expression abstracted as an untyped string + +1. `parse_attributes` +2. Parse specifiers (prefix) +3. This is where things get ugly for each of these depend on what the next token is. + 1. If its an in-place definition of a class, enum, struct, or union: + 2. If its a decltype (Not supported yet but draft impl there) + 3. If its a compound native type expression (unsigned, char, short, long, int, float, dobule, etc ) + 4. Ends up being a regular type alias of an identifier +4. Parse specifiers (postfix) + 1. If any specifiers are found populate specifiers code with them. +5. We need to now look ahead to see If we're dealing with a function typename +6. If wer're dealing with a function typename: + 1. Shove the specifiers, and identifier code we have so far into a return type typename's Name (untyped string) + 1. Reset the specifiers code for the top-level typename + 2. Check to see if the next token is an identifier: + 1. `parse_identifier` + 3. Check to see if the next token is capture start and is not the last capture ("qualifier capture"): + 1. Consume `(` + 2. Parse binding specifiers + 3. `parse_identifier` + 4. `parse_parameters` -> params_nested + 5. Consume `)` + 6. Construct a nested function typename definition for the qualifier `Name` + 4. `parse_params` - > params + 5. Parse postfix specifiers +7. Check for varaidic argument (param pack) token: + 1. Consume varadic argument token + +### **Later: Algorithim based on typename expressions** + +## `parse_typedef` + +1. Check for export module specifier +2. typedef keyword +3. If its a preprocess macro: Get the macro name +4. Else: + 1. Check to see if its a complicated definition (in-place enum, class, struct, union) + 2. If its a complicated definition: + 1. Perform the look ahead similar to `parse_complicated_definition`'s implementation + 2. Check to see if its a forward declaration : `parse_forward_declaration` + 3. If end[-1] is an identifier: + 1. Its either an in-place, varaible type qualified identifier, or indirection type: + 1. `parse_foward_or_definition` + 4. else if end[-1] is a closing curly brace + 1. Its a definition: `parse_forward_or_definition` + 5. else if end[-1] is a closing square brace + 2. Its an array definition: `parse_type` + 3. Else : `parse-type` + 4. Check for identifier : Consume the token + 5. `parse_array_decl` +5. Consume end statement +6. Check for inline comment : `parse_comment` + +## `parse_union` + +1. Check for export module specifier +2. union keyword +3. `parse_attributes` +4. Check for identifier +5. Parse the body (Possible options): + 1. Newline + 2. Comment + 3. Decl_Class + 4. Decl_Enum + 5. Decl_Struct + 6. Decl_Union + 7. Preprocess_Define + 8. Preprocess_Conditional (if, ifdef, ifndef, elif, else, endif) + 9. Preprocess_Macro + 10. Preprocess_Pragma + 11. Unsupported preprocess directive + 12. Variable +6. If its not an inplace definiton: End Statement + +## `parse_using` + +1. Check for export module specifier +2. using keyword +3. Check to see if its a using namespace +4. Get the identifier +5. If its a regular using declaration: + 1. `parse_attributes` + 2. `parse_type` + 3. `parse_array_decl` +6. End statement +7. Check for inline comment + +## `parse_variable` + +1. Check for export module specifier +2. `parse_attributes` +3. `parse specifiers` +4. `parse_type` +5. `parse_identifier` +6. `parse_variable_after_name` diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/Parsing.md b/Project/Source/GasaEditor/GasaGen/gencpp/Parsing.md new file mode 100644 index 0000000..3c2348a --- /dev/null +++ b/Project/Source/GasaEditor/GasaGen/gencpp/Parsing.md @@ -0,0 +1,81 @@ +# Parsing + +The library features a naive parser tailored for only what the library needs to construct the supported syntax of C++ into its AST. + +This parser does not, and should not do the compiler's job. By only supporting this minimal set of features, the parser is kept (so far) around ~5600 loc. I hope to keep it under 10k loc worst case. + +You can think of this parser of a frontend parser vs a semantic parser. Its intuitively similar to WYSIWYG. What you precerive as the syntax from the user-side before the compiler gets a hold of it, is what you get. + +User exposed interface: + +```cpp +CodeClass parse_class ( StrC class_def ); +CodeConstructor parse_constructor ( StrC constructor_def ); +CodeDestructor parse_destructor ( StrC destructor_def ); +CodeEnum parse_enum ( StrC enum_def ); +CodeBody parse_export_body ( StrC export_def ); +CodeExtern parse_extern_link ( StrC exten_link_def ); +CodeFriend parse_friend ( StrC friend_def ); +CodeFn parse_function ( StrC fn_def ); +CodeBody parse_global_body ( StrC body_def ); +CodeNS parse_namespace ( StrC namespace_def ); +CodeOperator parse_operator ( StrC operator_def ); +CodeOpCast parse_operator_cast( StrC operator_def ); +CodeStruct parse_struct ( StrC struct_def ); +CodeTemplate parse_template ( StrC template_def ); +CodeType parse_type ( StrC type_def ); +CodeTypedef parse_typedef ( StrC typedef_def ); +CodeUnion parse_union ( StrC union_def ); +CodeUsing parse_using ( StrC using_def ); +CodeVar parse_variable ( StrC var_def ); +``` + +To parse file buffers, use the `parse_global_body` function. + +***Parsing will aggregate any tokens within a function body or expression statement to an untyped Code AST.*** + +Everything is done in one pass for both the preprocessor directives and the rest of the language. +The parser performs no macro expansion as the scope of gencpp feature-set is to only support the preprocessor for the goal of having rudimentary awareness of preprocessor ***conditionals***, ***defines***, ***includes***, and ***pragmas***. + +The keywords supported for the preprocessor are: + +* include +* define +* if +* ifdef +* elif +* endif +* pragma + +Each directive `#` line is considered one preproecessor unit, and will be treated as one Preprocessor AST. *These ASTs will be considered members or entries of braced scope they reside within*. +If a directive is used with an unsupported keyword its will be processed as an untyped AST. + +The preprocessor lines are stored as members of their associated scope they are parsed within. ( Global, Namespace, Class/Struct ) + +Any preprocessor definition abuse that changes the syntax of the core language is unsupported and will fail to parse if not kept within an execution scope (function body, or expression assignment). +Exceptions: + +* function signatures are allowed for a preprocessed macro: `neverinline MACRO() { ... }` + * Disable with: `#define GEN_PARSER_DISABLE_MACRO_FUNCTION_SIGNATURES` +* typedefs allow for a preprocessed macro: `typedef MACRO();` + * Disable with: `#define GEN_PARSER_DISABLE_MACRO_TYPEDEF` + +*(Exceptions are added on an on-demand basis)* +*(See functions `parse_operator_function_or_variable` and `parse_typedef` )* + +Adding your own exceptions is possible by simply modifying the parser to allow for the syntax you need. + +*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. +* The parse API treats any execution scope definitions with no validation and are turned into untyped Code ASTs. + * *This includes the assignment of variables.* +* Attributes ( `[[]]` (standard), `__declspec` (Microsoft), or `__attribute__` (GNU) ) + * Assumed to *come before specifiers* (`const`, `constexpr`, `extern`, `static`, etc) for a function or right afterthe return type. + * Or in the usual spot for class, structs, (*right after the declaration keyword*) + * typedefs have attributes with the type (`parse_type`) +* 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/Project/Source/GasaEditor/GasaGen/gencpp/Readme.md b/Project/Source/GasaEditor/GasaGen/gencpp/Readme.md new file mode 100644 index 0000000..a8cde93 --- /dev/null +++ b/Project/Source/GasaEditor/GasaGen/gencpp/Readme.md @@ -0,0 +1,137 @@ +# gencpp + +An attempt at simple staged metaprogramming for c/c++. + +The library API is a composition of code element constructors. +These build up a code AST to then serialize with a file builder. + +This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto). +Its not meant to be a black box metaprogramming utility, it should be easy to intergrate into a user's project domain. + +## Notes + +**On Partial Hiatus: Life has got me tackling other issues..** +I will be passively updating the library with bug fixes and minor improvements as I use it for my personal projects. +There won't be any major reworks or features to this thing for a while. + +This project is still in development (very much an alpha state), so expect bugs and missing features. +See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos. + +The library can already be used to generate code just fine, but the parser is where the most work is needed. If your C++ isn't "down to earth" expect issues. + +A `natvis` and `natstepfilter` are provided in the scripts directory (its outdated, I'll update this readme when its not). + +***The editor and scanner have not been implemented yet. The scanner will come first, then the editor.*** + +A C variant is hosted [here](https://github.com/Ed94/genc); I will complete it when this library is feature complete, it should be easier to make than this... + +## Usage + +A metaprogram is built to generate files before the main program is built. We'll term runtime for this program as `GEN_TIME`. The metaprogram's core implementation are within `gen.hpp` and `gen.cpp` in the project directory. + +`gen.cpp` \`s `main()` is defined as `gen_main()` which the user will have to define once for their program. There they will dictate everything that should be generated. + +In order to keep the locality of this code within the same files the following pattern may be used (although this pattern isn't required at all): + +Within `program.cpp` : + +```cpp +#ifdef GEN_TIME +#include "gen.hpp" + +... + +u32 gen_main() +{ + ... +} +#endif + +// "Stage" agnostic code. + +#ifndef GEN_TIME +#include "program.gen.cpp" + + // Regular runtime dependent on the generated code here. +#endif + +``` + +The design uses a constructive builder API for the code to generate. +The user is provided `Code` objects that are used to build up the AST. + +Example using each construction interface: + +### Upfront + +Validation and construction through a functional interface. + +```cpp +Code t_uw = def_type( name(uw) ); +Code t_allocator = def_type( name(allocator) ); +Code t_string_const = def_type( name(char), def_specifiers( args( ESpecifier::Const, ESpecifier::Ptr ) )); + +Code header; +{ + Code num = def_variable( t_uw, name(Num) ); + Code cap = def_variable( t_uw, name(Capacity) ); + Code mem_alloc = def_variable( t_allocator, name(Allocator) ); + Code body = def_struct_body( args( num, cap, mem_alloc ) ); + + header = def_struct( name(ArrayHeader), __, __, body ); +} +``` + +### Parse + +Validation through ast construction. + +```cpp +Code header = parse_struct( code( + struct ArrayHeader + { + uw Num; + uw Capacity; + allocator Allocator; + }; +)); + +``` + +### Untyped + +No validation, just glorified text injection. + +```cpp +Code header = code_str( + struct ArrayHeader + { + uw Num; + uw Capacity; + allocator Allocator; + }; +); +``` + +`name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions. +`code` is a helper macro for providing a string literal with its size, but intended for code string parameters. +`args` is a helper macro for providing the number of arguments to varadic constructors. +`code_str` is a helper macro for writting `untyped_str( code( ))` + +All three constrcuton interfaces will generate the following C code: + +```cpp +struct ArrayHeader +{ + uw Num; + uw Capacity; + allocator Allocator; +}; +``` + +**Note: The formatting shown here is not how it will look. For your desired formatting its recommended to run a pass through the files with an auto-formatter.** +*(The library currently uses clang-format for formatting, beware its pretty slow...)* + +## Building + +See the [scripts directory](scripts/). diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/Readme_Docs.md b/Project/Source/GasaEditor/GasaGen/gencpp/Readme_Docs.md new file mode 100644 index 0000000..9c0f6a9 --- /dev/null +++ b/Project/Source/GasaEditor/GasaGen/gencpp/Readme_Docs.md @@ -0,0 +1,489 @@ +## Documentation + +The project has no external dependencies beyond: + +* `errno.h` +* `stat.h` +* `stdarg.h` +* `stddef.h` +* `stdio.h` +* `copyfile.h` (Mac) +* `types.h` (Linux) +* `unistd.h` (Linux/Mac) +* `intrin.h` (Windows) +* `io.h` (Windows with gcc) +* `windows.h` (Windows) + +Dependencies for the project are wrapped within `GENCPP_ROLL_OWN_DEPENDENCIES` (Defining it will disable them). +The majority of the dependency's implementation was derived from the [c-zpl library](https://github.com/zpl-c/zpl). + +This library was written in a subset of C++ where the following are not used at all: + +* RAII (Constructors/Destructors), lifetimes are managed using named static or regular functions. +* Language provide dynamic dispatch, RTTI +* Object-Oriented Inheritance +* Exceptions + +Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads. +There are only 4 template definitions in the entire library. (`Array`, `Hashtable`, `swap`, and `AST/Code::cast`) + +Two generic templated containers are used throughout the library: + +* `template< class Type> struct Array` +* `template< class Type> struct HashTable` + +Both Code and AST definitions have a `template< class Type> Code/AST :: cast()`. Its just an alternative way to explicitly cast to each other. + +`template< class Type> swap( Type& a, Type& b)` is used over a macro. + +Otherwise the library is free of any templates. + +### *WHAT IS NOT PROVIDED* + +**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. +The parameters of the template are treated like regular parameter AST entries. +This means that the typename entry for the parameter AST would be either: + +* `class` +* `typename` +* A fundamental type, function, or pointer type. + +Anything beyond this usage is not supported by parse_template for arguments (at least not intentionally). +Use at your own mental peril. + +*Concepts and Constraints are not supported, its usage is non-trivial substitution.* + +### The Data & Interface + +As mentioned in root readme, the user is provided Code objects by calling the constructor's functions to generate them or find existing matches. + +The AST is managed by the library and provided to the user via its interface. +However, the user may specifiy memory configuration. + +Data layout of AST struct (Subject to heavily change with upcoming redesign): + +```cpp +union { + struct + { + AST* InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable + AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable + AST* Specs; // Destructor, Function, Operator, Typename, Variable + union { + AST* InitializerList; // Constructor + AST* ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces. + AST* ReturnType; // Function, Operator, Typename + AST* UnderlyingType; // Enum, Typedef + AST* ValueType; // Parameter, Variable + }; + union { + AST* Macro; // Parameters + AST* BitfieldSize; // Variable (Class/Struct Data Member) + AST* Params; // Constructor, Function, Operator, Template, Typename + }; + union { + AST* ArrExpr; // Typename + AST* Body; // Class, Constructr, Destructor, Enum, Function, Namespace, Struct, Union + AST* Declaration; // Friend, Template + AST* Value; // Parameter, Variable + }; + 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. + }; + }; + StringCached Content; // Attributes, Comment, Execution, Include + struct { + SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + AST* NextSpecs; // Specifiers + }; +}; +union { + AST* Prev; + AST* Front; + AST* Last; +}; +union { + AST* Next; + AST* Back; +}; +AST* Parent; +StringCached Name; +CodeT Type; +ModuleFlag ModuleFlags; +union { + b32 IsFunction; // Used by typedef to not serialize the name field. + b32 IsParamPack; // Used by typename to know if type should be considered a parameter pack. + OperatorT Op; + AccessSpec ParentAccess; + s32 NumEntries; +}; +s32 Token; // Handle to the token, stored in the CodeFile (Otherwise unretrivable) +``` + +*`CodeT` is a typedef for `ECode::Type` which has an underlying type of `u32`* +*`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`* +*`StringCahced` is a typedef for `String const`, to denote it is an interned string* +*`String` is the dynamically allocated string type for the library* + +AST widths are setup to be AST_POD_Size. +The width dictates how much the static array can hold before it must give way to using an allocated array: + +```cpp +constexpr static +uw ArrSpecs_Cap = +( + AST_POD_Size + - sizeof(AST*) * 3 + - sizeof(StringCached) + - sizeof(CodeT) + - sizeof(ModuleFlag) + - sizeof(u32) +) +/ sizeof(SpecifierT) -1; // -1 for 4 extra bytes (Odd num of AST*) +``` + +*Ex: If the AST_POD_Size is 128 the capacity of the static array is 20.* + +Data Notes: + +* The allocator definitions used are exposed to the user incase they want to dictate memory usage + * You'll find the memory handling in `init`, `deinit`, `reset`, `gen_string_allocator`, `get_cached_string`, `make_code`. + * Allocators are defined with the `AllocatorInfo` structure found in `dependencies\memory.hpp` + * Most of the work is just defining the allocation procedure: + +```cpp + void* ( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags ); +``` + +* ASTs are wrapped for the user in a Code struct which is a wrapper for a AST* type. +* Both AST and Code have member symbols but their data layout is enforced to be POD types. +* This library treats memory failures as fatal. +* Cached Strings are stored in their own set of arenas. AST constructors use cached strings for names, and content. + * `StringArenas`, `StringCache`, `Allocator_StringArena`, and `Allocator_StringTable` are the associated containers or allocators. +* Strings used for serialization and file buffers are not contained by those used for cached strings. + * They are currently using `GlobalAllocator`, which are tracked array of arenas that grows as needed (adds buckets when one runs out). + * Memory within the buckets is not reused, so its inherently wasteful. + * I will be augmenting the single arena with a simple slag allocator. +* Linked lists used children nodes on bodies, and parameters. +* Its intended to generate the AST in one go and serialize after. The constructors and serializer are designed to be a "one pass, front to back" setup. +* Allocations can be tuned by defining the folloiwng macros: + * `GEN_GLOBAL_BUCKET_SIZE` : Size of each bucket area for the global allocator + * `GEN_CODEPOOL_NUM_BLOCKS` : Number of blocks per code pool in the code allocator + * `GEN_SIZE_PER_STRING_ARENA` : Size per arena used with string caching. + * `GEN_MAX_COMMENT_LINE_LENGTH` : Longest length a comment can have per line. + * `GEN_MAX_NAME_LENGTH` : Max length of any identifier. + * `GEN_MAX_UNTYPED_STR_LENGTH` : Max content length for any untyped code. + * `GEN_TOKEN_FMT_TOKEN_MAP_MEM_SIZE` : token_fmt_va uses local_persit memory of this size for the hashtable. + * `GEN_LEX_ALLOCATOR_SIZE` + * `GEN_BUILDER_STR_BUFFER_RESERVE` + +The following CodeTypes are used which the user may optionally use strong typing with if they enable: `GEN_ENFORCE_STRONG_CODE_TYPES` + +* CodeBody : Has support for `for-range` iterating across Code objects. +* CodeAttributes +* CodeComment +* CodeClass +* CodeConstructor +* CodeDefine +* CodeDestructor +* CodeEnum +* CodeExec +* CodeExtern +* CodeInclude +* CodeFriend +* CodeFn +* CodeModule +* CodeNS +* CodeOperator +* CodeOpCast +* CodeParam : Has support for `for-range` iterating across parameters. +* CodePreprocessCond +* CodePragma +* CodeSpecifiers : Has support for `for-range` iterating across specifiers. +* CodeStruct +* CodeTemplate +* CodeType +* CodeTypedef +* CodeUnion +* CodeUsing +* CodeVar + +Each Code boy has an associated "filtered AST" with the naming convention: `AST_` +Unrelated fields of the AST for that node type are omitted and only necessary padding members are defined otherwise. +Retrieving a raw version of the ast can be done using the `raw()` function defined in each AST. + +## There are three sets of interfaces for Code AST generation the library provides + +* Upfront +* Parsing +* Untyped + +### Upfront Construction + +All component ASTs must be previously constructed, and provided on creation of the code AST. +The construction will fail and return CodeInvalid otherwise. + +Interface :`` + +* def_attributes + * *This is pre-appended right before the function symbol, or placed after the class or struct keyword for any flavor of attributes used.* + * *Its up to the user to use the desired attribute formatting: `[[]]` (standard), `__declspec` (Microsoft), or `__attribute__` (GNU).* +* def_comment +* def_class +* def_constructor +* def_define +* def_destructor +* def_enum +* def_execution + * *This is equivalent to untyped_str, except that its intended for use only in execution scopes.* +* def_extern_link +* def_friend +* def_function +* def_include +* def_module +* def_namespace +* def_operator +* def_operator_cast +* def_param +* def_params +* def_pragma +* def_preprocess_cond +* def_specifier +* def_specifiers +* def_struct +* def_template +* def_type +* def_typedef +* def_union +* def_using +* def_using_namespace +* def_variable + +Bodies: + +* def_body +* def_class_body +* def_enum_body +* def_export_body +* def_extern_link_body +* def_function_body + * *Use this for operator bodies as well* +* def_global_body +* def_namespace_body +* def_struct_body +* def_union_body + +Usage: + +```cpp + = def_( ... ); + +Code +{ + ... + = def_( ... ); +} + +``` + +When using the body functions, its recommended to use the args macro to auto determine the number of arguments for the varadic: +```cpp +def_global_body( args( ht_entry, array_ht_entry, hashtable )); + +// instead of: +def_global_body( 3, ht_entry, array_ht_entry, hashtable ); +``` + +If a more incremental approach is desired for the body ASTs, `Code def_body( CodeT type )` can be used to create an empty body. +When the members have been populated use: `AST::validate_body` to verify that the members are valid entires for that type. + +### Parse construction + +A string provided to the API is parsed for the intended language construct. + +Interface : + +* parse_class +* parse_constructor +* parse_destructor +* parse_enum +* parse_export_body +* parse_extern_link +* parse_friend + * Purposefully are only support forward declares with this constructor. +* parse_function +* parse_global_body +* parse_namespace +* parse_operator +* parse_operator_cast +* parse_struct +* parse_template +* parse_type +* parse_typedef +* parse_union +* parse_using +* parse_variable + +Usage: + +```cpp +Code = parse_( string with code ); + +Code = def_( ..., parse_( + +)); +``` + +### Untyped constructions + +Code ASTs are constructed using unvalidated strings. + +Interface : + +* token_fmt_va +* token_fmt +* untyped_str +* untyped_fmt +* untyped_token_fmt + +During serialization any untyped Code AST has its string value directly injected inline of whatever context the content existed as an entry within. +Even though these are not validated from somewhat correct c/c++ syntax or components, it doesn't mean that Untyped code can be added as any component of a Code AST: + +* Untyped code cannot have children, thus there cannot be recursive injection this way. +* Untyped code can only be a child of a parent of body AST, or for values of an assignment (ex: variable assignment). + +These restrictions help prevent abuse of untyped code to some extent. + +Usage Conventions: + +```cpp +Code = def_variable( , , untyped_( + +)); + +Code = untyped_str( code( + +)); +``` + +Optionally, `code_str`, and `code_fmt` macros can be used so that the code macro doesn't have to be used: +```cpp +Code = code_str( ) +``` + +Template metaprogramming in the traditional sense becomes possible with the use of `token_fmt` and parse constructors: + +```cpp +StrC value = txt("Something"); + +char const* template_str = txt( + Code with to replace with token_values + ... +); +char const* gen_code_str = token_fmt( "key", value, template_str ); +Code = parse_( gen_code_str ); +``` + +## Predefined Codes + +The following are provided predefined by the library as they are commonly used: + +* `access_public` +* `access_protected` +* `access_private` +* `attrib_api_export` +* `attrib_api_import` +* `module_global_fragment` +* `module_private_fragment` +* `fmt_newline` +* `param_varaidc` (Used for varadic definitions) +* `pragma_once` +* `preprocess_else` +* `preprocess_endif` +* `spec_const` +* `spec_consteval` +* `spec_constexpr` +* `spec_constinit` +* `spec_extern_linkage` (extern) +* `spec_final` +* `spec_forceinline` +* `spec_global` (global macro) +* `spec_inline` +* `spec_internal_linkage` (internal macro) +* `spec_local_persist` (local_persist macro) +* `spec_mutable` +* `spec_neverinline` +* `spec_override` +* `spec_ptr` +* `spec_pure` +* `spec_ref` +* `spec_register` +* `spec_rvalue` +* `spec_static_member` (static) +* `spec_thread_local` +* `spec_virtual` +* `spec_volatile` +* `t_empty` (Used for varaidc macros) +* `t_auto` +* `t_void` +* `t_int` +* `t_bool` +* `t_char` +* `t_wchar_t` +* `t_class` +* `t_typename` + +Optionally the following may be defined if `GEN_DEFINE_LIBRARY_CODE_CONSTANTS` is defined + +* `t_b32` +* `t_s8` +* `t_s16` +* `t_s32` +* `t_s64` +* `t_u8` +* `t_u16` +* `t_u32` +* `t_u64` +* `t_sw` (ssize_t) +* `t_uw` (size_t) +* `t_f32` +* `t_f64` + +## Extent of operator overload validation + +The AST and constructors will be able to validate that the arguments provided for the operator type match the expected form: + +* If return type must match a parameter +* If number of parameters is correct +* If added as a member symbol to a class or struct, that operator matches the requirements for the class (types match up) +* There is no support for validating new & delete operations (yet) + +The user is responsible for making sure the code types provided are correct +and have the desired specifiers assigned to them beforehand. + +## Code generation and modification + +There are three provided auxillary interfaces: + +* Builder +* Editor +* Scanner + +Editor and Scanner are disabled by default, use `GEN_FEATURE_EDITOR` and `GEN_FEATURE_SCANNER` to enable them. + +### Builder is a similar object to the jai language's string_builder + +* The purpose of it is to generate a file. +* A file is specified and opened for writing using the open( file_path) function. +* The code is provided via print( code ) function will be serialized to its buffer. +* When all serialization is finished, use the write() command to write the buffer to the file. + +### Scanner Auxillary Interface + +Provides *(eventually)* `scan_file` to automatically populate a CodeFile which contains a parsed AST (`Code`) of the file, with any contextual failures that are reported from the parser. diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.builder.cpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.builder.cpp index 8fbbe89..16257a7 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.builder.cpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.builder.cpp @@ -1,10 +1,9 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) - -#include "gen.builder.hpp" +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -20,6 +19,8 @@ #pragma GCC diagnostic ignored "-Wunused-variable" #endif +#include "gen.builder.hpp" + GEN_NS_BEGIN Builder Builder::open( char const* path ) @@ -32,6 +33,7 @@ Builder Builder::open( char const* path ) log_failure( "gen::File::open - Could not open file: %s", path ); return result; } + result.Buffer = String::make_reserve( GlobalAllocator, Builder_StrBufferReserve ); // log_fmt("$Builder - Opened file: %s\n", result.File.filename ); diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.builder.hpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.builder.hpp index 330647e..ef56f6d 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.builder.hpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.builder.hpp @@ -1,12 +1,9 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) - -#pragma once - -#include "gen.hpp" +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -22,6 +19,10 @@ #pragma GCC diagnostic ignored "-Wunused-variable" #endif +#pragma once + +#include "gen.hpp" + GEN_NS_BEGIN struct Builder diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.cpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.cpp index 5ab06d6..5eed464 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.cpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.cpp @@ -1,8 +1,9 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -17,6 +18,7 @@ #pragma GCC diagnostic ignored "-Wswitch" #pragma GCC diagnostic ignored "-Wunused-variable" #endif + #if ! defined( GEN_DONT_ENFORCE_GEN_TIME_GUARD ) && ! defined( GEN_TIME ) #error Gen.hpp : GEN_TIME not defined #endif @@ -24,6 +26,7 @@ #include "gen.hpp" GEN_NS_BEGIN + #pragma region StaticData // TODO : Convert global allocation strategy to use a slab allocation strategy. @@ -1943,7 +1946,7 @@ void CodeFn::to_string_def( String& result ) if ( ast->Attributes ) result.append_fmt( " %S ", ast->Attributes.to_string() ); - b32 prefix_specs = false; + bool prefix_specs = false; if ( ast->Specs ) { for ( SpecifierT spec : ast->Specs ) @@ -1996,7 +1999,7 @@ void CodeFn::to_string_fwd( String& result ) if ( ast->Attributes ) result.append_fmt( "%S ", ast->Attributes.to_string() ); - bool prefix_specs = false; + b32 prefix_specs = false; if ( ast->Specs ) { for ( SpecifierT spec : ast->Specs ) @@ -2225,7 +2228,14 @@ void CodeOpCast::to_string_def( String& result ) { if ( ast->Specs ) { - // TODO : Add support for specifies before the operator keyword + for ( SpecifierT spec : ast->Specs ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( "%*s ", spec_str.Len, spec_str.Ptr ); + } + } if ( ast->Name && ast->Name.length() ) result.append_fmt( "%Soperator %S()", ast->Name, ast->ValueType.to_string() ); @@ -2255,7 +2265,14 @@ void CodeOpCast::to_string_fwd( String& result ) { if ( ast->Specs ) { - // TODO : Add support for specifies before the operator keyword + for ( SpecifierT spec : ast->Specs ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( "%*s ", spec_str.Len, spec_str.Ptr ); + } + } result.append_fmt( "operator %S()", ast->ValueType.to_string() ); @@ -2309,7 +2326,7 @@ void CodeParam::to_string( String& result ) if ( ast->PostNameMacro ) { - result.append_fmt(" %S", ast->PostNameMacro.to_string() ); + result.append_fmt( " %S", ast->PostNameMacro.to_string() ); } if ( ast->Value ) @@ -2562,7 +2579,7 @@ String CodeType::to_string() void CodeType::to_string( String& result ) { -#if defined(GEN_USE_NEW_TYPENAME_PARSING) +#if defined( GEN_USE_NEW_TYPENAME_PARSING ) if ( ast->ReturnType && ast->Params ) { if ( ast->Attributes ) @@ -2737,9 +2754,9 @@ void CodeVar::to_string( String& result ) // Keep the chain going... if ( ast->NextVar ) result.append_fmt( ", %S", ast->NextVar.to_string() ); - + if ( ast->VarConstructorInit ) - result.append( " )"); + result.append( " )" ); return; } @@ -2775,11 +2792,11 @@ void CodeVar::to_string( String& result ) if ( ast->Value ) { if ( ast->VarConstructorInit ) - result.append_fmt( "( %S", ast->Value.to_string() ); + result.append_fmt( "( %S ", ast->Value.to_string() ); else result.append_fmt( " = %S", ast->Value.to_string() ); } - + if ( ast->NextVar ) result.append_fmt( ", %S", ast->NextVar.to_string() ); @@ -2824,7 +2841,7 @@ void CodeVar::to_string( String& result ) result.append_fmt( ", %S", ast->NextVar.to_string() ); if ( ast->VarConstructorInit ) - result.append(")"); + result.append( " )" ); result.append( ";" ); @@ -3016,17 +3033,16 @@ internal void define_constants() spec_##Type_ = def_specifiers( num_args( __VA_ARGS__ ), __VA_ARGS__ ); \ spec_##Type_.set_global(); -#pragma push_macro("FORCEINLINE") -#pragma push_macro("global") -#pragma push_macro("internal") -#pragma push_macro("local_persist") -#pragma push_macro("neverinline") +#pragma push_macro( "FORCEINLINE" ) +#pragma push_macro( "global" ) +#pragma push_macro( "internal" ) +#pragma push_macro( "local_persist" ) +#pragma push_macro( "neverinline" ) #undef FORCEINLINE #undef global #undef internal #undef local_persist #undef neverinline - def_constant_spec( const, ESpecifier::Const ); def_constant_spec( consteval, ESpecifier::Consteval ); def_constant_spec( constexpr, ESpecifier::Constexpr ); @@ -3051,14 +3067,14 @@ internal void define_constants() def_constant_spec( virtual, ESpecifier::Virtual ); def_constant_spec( volatile, ESpecifier::Volatile ) - spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist ); + spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist ); spec_local_persist.set_global(); -#pragma pop_macro("FORCEINLINE") -#pragma pop_macro("global") -#pragma pop_macro("internal") -#pragma pop_macro("local_persist") -#pragma pop_macro("neverinline") +#pragma pop_macro( "FORCEINLINE" ) +#pragma pop_macro( "global" ) +#pragma pop_macro( "internal" ) +#pragma pop_macro( "local_persist" ) +#pragma pop_macro( "neverinline" ) #undef def_constant_spec } @@ -3203,7 +3219,7 @@ AllocatorInfo get_string_allocator( s32 str_length ) uw size_req = str_length + sizeof( String::Header ) + sizeof( char* ); - if ( last->TotalUsed + sw(size_req) > last->TotalSize ) + if ( last->TotalUsed + sw( size_req ) > last->TotalSize ) { Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena ); @@ -5692,8 +5708,8 @@ namespace parser #define GEN_DEFINE_ATTRIBUTE_TOKENS \ Entry( Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Attribute_API_Import, "GEN_API_Import_Code" ) \ Entry( Attribute_UE_DEPRECATED, "UE_DEPRECATED" ) Entry( Attribute_UMG_API, "UMG_API" ) Entry( Attribute_COREUOBJECT_API, "COREUOBJECT_API" ) \ - Entry( Attribute_ENGINE_API, "ENGINE_API" ) Entry( Attribute_GASA_API, "GASA_API" ) \ - Entry( Attribute_GAMEPLAYABILITIES_API, "GAMEPLAYABILITIES_API" ) + Entry( Attribute_ENGINE_API, "ENGINE_API" ) Entry( Attribute_GAMEPLAYABILITIES_API, "GAMEPLAYABILITIES_API" ) \ + Entry( Attribute_GASA_API, "GASA_API" ) enum Type : u32 { @@ -5798,12 +5814,12 @@ namespace parser Attribute_UMG_API, Attribute_COREUOBJECT_API, Attribute_ENGINE_API, - Attribute_GASA_API, Attribute_GAMEPLAYABILITIES_API, + Attribute_GASA_API, NumTokens }; - StrC to_str( Type type ) + inline StrC to_str( Type type ) { local_persist StrC lookup[] { { sizeof( "__invalid__" ), "__invalid__" }, @@ -5907,13 +5923,13 @@ namespace parser { sizeof( "UMG_API" ), "UMG_API" }, { sizeof( "COREUOBJECT_API" ), "COREUOBJECT_API" }, { sizeof( "ENGINE_API" ), "ENGINE_API" }, - { sizeof( "GASA_API" ), "GASA_API" }, { sizeof( "GAMEPLAYABILITIES_API" ), "GAMEPLAYABILITIES_API" }, + { sizeof( "GASA_API" ), "GASA_API" }, }; return lookup[type]; } - Type to_type( StrC str ) + inline Type to_type( StrC str ) { local_persist u32 keymap[NumTokens]; do_once_start for ( u32 index = 0; index < NumTokens; index++ ) @@ -6139,7 +6155,8 @@ namespace parser Lex_ReturnNull, }; - FORCEINLINE s32 lex_preprocessor_directive( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& preprocessor_defines, Token& token ) + FORCEINLINE + s32 lex_preprocessor_directive( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& defines, Token& token ) { char const* hash = scanner; Tokens.append( { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } ); @@ -6267,7 +6284,7 @@ namespace parser Tokens.append( name ); u64 key = crc32( name.Text, name.Length ); - preprocessor_defines.set( key, name ); + defines.set( key, name ); } Token preprocess_content = { scanner, 0, TokType::Preprocess_Content, line, column, TF_Preprocess }; @@ -6383,7 +6400,8 @@ namespace parser return Lex_Continue; // Skip found token, its all handled here. } - FORCEINLINE void lex_found_token( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& preprocessor_defines, Token& token ) + FORCEINLINE + void lex_found_token( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& defines, Token& token ) { if ( token.Type != TokType::Invalid ) { @@ -6440,7 +6458,7 @@ namespace parser else key = crc32( token.Text, token.Length ); - StrC* define = preprocessor_defines.get( key ); + StrC* define = defines.get( key ); if ( define ) { token.Type = TokType::Preprocess_Macro; @@ -6510,7 +6528,7 @@ namespace parser { s32 length = 0; char const* scanner = entry.Data; - while ( entry.length() > length && char_is_alphanumeric( *scanner ) || *scanner == '_' ) + while ( entry.length() > length && ( char_is_alphanumeric( *scanner ) || *scanner == '_' ) ) { scanner++; length++; @@ -7122,19 +7140,19 @@ namespace parser } // Handle number literal suffixes in a botched way - if (left && ( - current == 'l' || current == 'L' || // long/long long - current == 'u' || current == 'U' || // unsigned - current == 'f' || current == 'F' || // float - current == 'i' || current == 'I' || // imaginary - current == 'z' || current == 'Z')) // complex + if ( left + && ( current == 'l' || current == 'L' || // long/long long + current == 'u' || current == 'U' || // unsigned + current == 'f' || current == 'F' || // float + current == 'i' || current == 'I' || // imaginary + current == 'z' || current == 'Z' ) ) // complex { char prev = current; move_forward(); token.Length++; - + // Handle 'll'/'LL' as a special case when we just processed an 'l'/'L' - if (left && (prev == 'l' || prev == 'L') && (current == 'l' || current == 'L')) + if ( left && ( prev == 'l' || prev == 'L' ) && ( current == 'l' || current == 'L' ) ) { move_forward(); token.Length++; @@ -7841,7 +7859,7 @@ namespace parser return { nullptr }; } - internal Code parse_class_struct( TokType which, bool binplace_def = false ) + internal Code parse_class_struct( TokType which, bool inplace_def = false ) { if ( which != TokType::Decl_Class && which != TokType::Decl_Struct ) { @@ -7922,7 +7940,7 @@ namespace parser // : , ... { } CodeComment inline_cmt = NoCode; - if ( ! binplace_def ) + if ( ! inplace_def ) { Token stmt_end = currtok; eat( TokType::Statement_End ); @@ -8518,6 +8536,10 @@ namespace parser s32 level = 0; while ( left && currtok.Type != TokType::Statement_End && ( currtok.Type != TokType::Comma || level > 0 ) ) { + if ( currtok.Type == TokType::BraceCurly_Open ) + level++; + if ( currtok.Type == TokType::BraceCurly_Close ) + level--; if ( currtok.Type == TokType::Capture_Start ) level++; else if ( currtok.Type == TokType::Capture_End ) @@ -8996,7 +9018,7 @@ namespace parser if ( found_operator_cast_outside_class_implmentation ) { - member = parse_operator_cast(); + member = parse_operator_cast( specifiers ); // ::operator () { ... } break; } @@ -9607,7 +9629,6 @@ namespace parser return result; } - __pragma(optimize("",off)) internal Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers ) { push_scope(); @@ -9665,8 +9686,8 @@ namespace parser } else { - Token name = parse_identifier(); - Context.Scope->Name = name; + Token name = parse_identifier(); + Context.Scope->Name = name; bool detected_capture = check( TokType::Capture_Start ); @@ -9674,7 +9695,7 @@ namespace parser // ( 350.0f , <--- Could be the scenario // Example : // idx +1 +2 - bool detected_comma = Context.Tokens.Arr[ Context.Tokens.Idx + 2 ].Type == TokType::Comma; + bool detected_comma = Context.Tokens.Arr[Context.Tokens.Idx + 2].Type == TokType::Comma; if ( detected_capture && ! detected_comma ) { // Dealing with a function @@ -9699,7 +9720,6 @@ namespace parser Context.pop(); return result; } - __pragma(optimize("",on)) internal CodePragma parse_pragma() { @@ -9807,7 +9827,7 @@ namespace parser // template::Value)> // class T ... and then ^this^ UE_REQUIRES shows up // So we need to consume that. - if ( check( TokType::Preprocess_Macro )) + if ( check( TokType::Preprocess_Macro ) ) { post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro ); } @@ -9831,7 +9851,8 @@ namespace parser s32 capture_level = 0; s32 template_level = 0; - while ( left && ( currtok.Type != TokType::Comma ) && template_level >= 0 && CheckEndParams() || capture_level > 0 || template_level > 0 ) + while ( ( left && ( currtok.Type != TokType::Comma ) && template_level >= 0 && CheckEndParams() ) || ( capture_level > 0 || template_level > 0 ) + ) { if ( currtok.Text[0] == '<' ) ++template_level; @@ -9919,7 +9940,7 @@ namespace parser // template::Value)> // class T ... and then ^this^ UE_REQUIRES shows up // So we need to consume that. - if ( check( TokType::Preprocess_Macro )) + if ( check( TokType::Preprocess_Macro ) ) { post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro ); } @@ -9943,7 +9964,8 @@ namespace parser s32 capture_level = 0; s32 template_level = 0; - while ( left && currtok.Type != TokType::Comma && template_level >= 0 && CheckEndParams() || capture_level > 0 || template_level > 0 ) + while ( ( left && currtok.Type != TokType::Comma && template_level >= 0 && CheckEndParams() ) || ( capture_level > 0 || template_level > 0 ) + ) { if ( currtok.Text[0] == '<' ) ++template_level; @@ -10019,7 +10041,7 @@ namespace parser } CodePreprocessCond cond = (CodePreprocessCond)make_code(); - cond->Type = scast( CodeT, currtok.Type - ( ETokType::Preprocess_If - ECode::Preprocess_If ) ); + cond->Type = scast( CodeT, currtok.Type - ( TokType::Preprocess_If - ECode::Preprocess_If ) ); eat( currtok.Type ); // # @@ -10199,9 +10221,9 @@ namespace parser { push_scope(); - Code array_expr = parse_array_decl(); - Code expr = { nullptr }; - Code bitfield_expr = { nullptr }; + Code array_expr = parse_array_decl(); + Code expr = { nullptr }; + Code bitfield_expr = { nullptr }; b32 using_constructor_initializer = false; @@ -10235,17 +10257,17 @@ namespace parser expr = untyped_str( expr_tok ); // = { } } - + if ( currtok.Type == TokType::Capture_Start ) { - eat( TokType:: Capture_Start); + eat( TokType::Capture_Start ); // ( - - Token expr_token = currtok; + + Token expr_token = currtok; using_constructor_initializer = true; - s32 level = 0; + s32 level = 0; while ( left && ( currtok.Type != TokType::Capture_End || level > 0 ) ) { if ( currtok.Type == TokType::Capture_Start ) @@ -10357,7 +10379,7 @@ namespace parser } result->VarConstructorInit = using_constructor_initializer; - + Context.pop(); return result; } @@ -10416,6 +10438,8 @@ namespace parser break; } + // eat(currtok.Type); + if ( specifiers ) specifiers.append( spec ); else @@ -10447,10 +10471,10 @@ namespace parser return result; } - internal CodeClass parse_class( bool binplace_def ) + internal CodeClass parse_class( bool inplace_def ) { push_scope(); - CodeClass result = (CodeClass)parse_class_struct( TokType::Decl_Class, binplace_def ); + CodeClass result = (CodeClass)parse_class_struct( TokType::Decl_Class, inplace_def ); Context.pop(); return result; } @@ -10653,7 +10677,7 @@ namespace parser return result; } - internal CodeEnum parse_enum( bool binplace_def ) + internal CodeEnum parse_enum( bool inplace_def ) { using namespace ECode; push_scope(); @@ -10813,6 +10837,13 @@ namespace parser // = , } + // Consume inline comments + // if ( currtok.Type == TokType::Comment && prevtok.Line == currtok.Line ) + // { + // eat( TokType::Comment ); + // = , // + // } + entry.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)entry.Text; member = untyped_str( entry ); @@ -10835,7 +10866,7 @@ namespace parser CodeComment inline_cmt = NoCode; - if ( ! binplace_def ) + if ( ! inplace_def ) { Token stmt_end = currtok; eat( TokType::Statement_End ); @@ -11181,8 +11212,6 @@ namespace parser { push_scope(); - // TODO : Specifiers attributed to the cast - // Operator's namespace if not within same class. Token name = NullToken; if ( check( TokType::Identifier ) ) @@ -11290,10 +11319,10 @@ namespace parser return result; } - internal inline CodeStruct parse_struct( bool binplace_def ) + internal inline CodeStruct parse_struct( bool inplace_def ) { push_scope(); - CodeStruct result = (CodeStruct)parse_class_struct( TokType::Decl_Struct, binplace_def ); + CodeStruct result = (CodeStruct)parse_class_struct( TokType::Decl_Struct, inplace_def ); Context.pop(); return result; } @@ -11608,6 +11637,18 @@ else if ( currtok.Type == TokType::DeclType ) name = currtok; eat( TokType::Type_Typename ); // + + if ( ! from_template ) + { + name = parse_identifier(); + Context.Scope->Name = name; + if ( ! name ) + { + log_failure( "Error, failed to type signature\n%s", Context.to_string() ); + Context.pop(); + return CodeInvalid; + } + } } // The usual Identifier type signature that may have namespace qualifiers diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.dep.cpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.dep.cpp index 2e49b03..fb828df 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.dep.cpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.dep.cpp @@ -1,10 +1,11 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #include "gen.dep.hpp" #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -19,9 +20,6 @@ #pragma GCC diagnostic ignored "-Wswitch" #pragma GCC diagnostic ignored "-Wunused-variable" #endif -#if ! defined( GEN_DONT_ENFORCE_GEN_TIME_GUARD ) && ! defined( GEN_TIME ) -#error Gen.hpp : GEN_TIME not defined -#endif #pragma region Macros and Includes @@ -2258,7 +2256,7 @@ internal GEN_FILE_WRITE_AT_PROC( _memory_file_write ) { Array arr = { d->buf }; - if ( arr.get_header()->Capacity < uw(new_cap) ) + if ( arr.get_header()->Capacity < uw( new_cap ) ) { if ( ! arr.grow( (s64)( new_cap ) ) ) return false; @@ -2476,4 +2474,3 @@ GEN_NS_END #ifdef __GNUC__ #pragma GCC diagnostic pop #endif - diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.dep.hpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.dep.hpp index bd2345c..dbe3796 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.dep.hpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.dep.hpp @@ -1,9 +1,11 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) + #pragma once #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -148,6 +150,10 @@ #endif GEN_NS_BEGIN +#ifdef GEN_INTELLISENSE_DIRECTIVES +#pragma once +#include "header_start.hpp" +#endif #pragma region Macros @@ -159,6 +165,7 @@ GEN_NS_BEGIN #define internal static // Internal linkage #define local_persist static // Local Persisting variables +#pragma region ForceInline Definition #ifdef GEN_COMPILER_MSVC #define FORCEINLINE __forceinline #define neverinline __declspec( noinline ) @@ -177,18 +184,23 @@ GEN_NS_BEGIN #define FORCEINLINE #define neverinline #endif +#pragma endregion ForceInline Definition // Bits +#ifndef bit #define bit( Value ) ( 1 << Value ) #define bitfield_is_equal( Type, Field, Mask ) ( ( Type( Mask ) & Type( Field ) ) == Type( Mask ) ) +#endif // Casting +#ifndef ccast #define ccast( Type, Value ) ( *const_cast( &( Value ) ) ) #define pcast( Type, Value ) ( *reinterpret_cast( &( Value ) ) ) #define rcast( Type, Value ) reinterpret_cast( Value ) #define scast( Type, Value ) static_cast( Value ) +#endif // Num Arguments (Varadics) // #if defined(__GNUC__) || defined(__clang__) @@ -1105,13 +1117,16 @@ struct Arena return alignment_offset; } -#pragma push_macro("check") +// This id is defined by Unreal for asserts +#pragma push_macro( "check" ) #undef check + void check() { GEN_ASSERT( TempCount == 0 ); } -#pragma pop_macro("check") + +#pragma pop_macro( "check" ) void free() { @@ -1575,7 +1590,7 @@ struct Array { return 2 * value + 8; } - + bool append( Array other ) { return append( other, other.num() ); @@ -1689,7 +1704,7 @@ struct Array if ( begin < 0 || end > header.Num ) return false; - for ( sw idx = sw(begin); idx < sw(end); idx++ ) + for ( sw idx = sw( begin ); idx < sw( end ); idx++ ) { Data[idx] = value; } @@ -1847,7 +1862,7 @@ struct HashTable static HashTable init( AllocatorInfo allocator ) { - HashTable result = init_reserve(allocator, 8); + HashTable result = init_reserve( allocator, 8 ); return result; } @@ -1855,10 +1870,10 @@ struct HashTable { HashTable result = { { nullptr }, { nullptr } }; - result.Hashes = Array::init_reserve( allocator, num ); + result.Hashes = Array::init_reserve( allocator, num ); result.Hashes.get_header()->Num = num; result.Hashes.resize( num ); - result.Hashes.fill( 0, num, -1); + result.Hashes.fill( 0, num, -1 ); result.Entries = Array::init_reserve( allocator, num ); return result; @@ -1867,7 +1882,7 @@ struct HashTable void clear( void ) { Entries.clear(); - Hashes.fill( 0, Hashes.num(), -1); + Hashes.fill( 0, Hashes.num(), -1 ); } void destroy( void ) @@ -1894,7 +1909,7 @@ struct HashTable { GEN_ASSERT_NOT_NULL( map_proc ); - for ( sw idx = 0; idx < Entries.num(); idx++ ) + for ( sw idx = 0; idx < sw( Entries.num() ); ++idx ) { map_proc( Entries[idx].Key, Entries[idx].Value ); } @@ -1906,7 +1921,7 @@ struct HashTable { GEN_ASSERT_NOT_NULL( map_proc ); - for ( sw idx = 0; idx < Entries.num(); idx++ ) + for ( sw idx = 0; idx < sw( Entries.num() ); ++idx ) { map_proc( Entries[idx].Key, &Entries[idx].Value ); } @@ -1923,7 +1938,7 @@ struct HashTable sw last_added_index; HashTable new_ht = init_reserve( Hashes.get_header()->Allocator, new_num ); - for ( sw idx = 0; idx < sw(Entries.num()); ++idx ) + for ( sw idx = 0; idx < sw( Entries.num() ); ++idx ) { FindResult find_result; @@ -1948,13 +1963,13 @@ struct HashTable { sw idx; - for ( idx = 0; idx < Entries.num(); idx++ ) + for ( idx = 0; idx < sw( Entries.num() ); idx++ ) Entries[idx].Next = -1; - for ( idx = 0; idx < Hashes.num(); idx++ ) + for ( idx = 0; idx < sw( Hashes.num() ); idx++ ) Hashes[idx] = -1; - for ( idx = 0; idx < Entries.num(); idx++ ) + for ( idx = 0; idx < sw( Entries.num() ); idx++ ) { Entry* entry; FindResult find_result; @@ -2020,7 +2035,7 @@ struct HashTable sw slot( u64 key ) { - for ( sw idx = 0; idx < Hashes.num(); ++idx ) + for ( sw idx = 0; idx < sw( Hashes.num() ); ++idx ) if ( Hashes[idx] == key ) return idx; @@ -2065,8 +2080,8 @@ protected: b32 full() { - uw critical_load = uw( CriticalLoadScale * f32(Hashes.num()) ); - b32 result = Entries.num() > critical_load; + uw critical_load = uw( CriticalLoadScale * f32( Hashes.num() ) ); + b32 result = Entries.num() > critical_load; return result; } }; @@ -2088,26 +2103,25 @@ struct StrC sw Len; char const* Ptr; - char const& operator[]( sw index ) const - { - return Ptr[index]; - } - operator char const*() const { return Ptr; } + + char const& operator[]( sw index ) const + { + return Ptr[index]; + } }; -#define cast_to_strc( str ) *rcast( StrC*, str - sizeof( sw ) ) -#define txt( text ) \ - StrC \ - { \ - sizeof( (text) ) - 1, (text) \ +#define cast_to_strc( str ) *rcast( StrC*, ( str ) - sizeof( sw ) ) +#define txt( text ) \ + StrC \ + { \ + sizeof( text ) - 1, ( text ) \ } -inline -StrC to_str( char const* str ) +inline StrC to_str( char const* str ) { return { str_len( str ), str }; } @@ -2179,7 +2193,7 @@ struct String static bool are_equal( String lhs, StrC rhs ) { - if ( lhs.length() != (rhs.Len - 1) ) + if ( lhs.length() != ( rhs.Len ) ) return false; for ( sw idx = 0; idx < lhs.length(); ++idx ) @@ -2218,7 +2232,7 @@ struct String header.Length = curr_len + length; } - return true; + return str != nullptr; } bool append( StrC str ) @@ -2257,24 +2271,6 @@ struct String get_header().Length = 0; } - b32 starts_with( StrC substring ) const - { - if (substring.Len > length()) - return false; - - b32 result = str_compare(Data, substring.Ptr, substring.Len ) == 0; - return result; - } - - b32 starts_with( String substring ) const - { - if (substring.length() > length()) - return false; - - b32 result = str_compare(Data, substring, substring.length() - 1 ) == 0; - return result; - } - String duplicate( AllocatorInfo allocator ) const { return make_length( allocator, Data, length() ); @@ -2302,6 +2298,24 @@ struct String return header.Length; } + b32 starts_with( StrC substring ) const + { + if ( substring.Len > length() ) + return false; + + b32 result = str_compare( Data, substring.Ptr, substring.Len ) == 0; + return result; + } + + b32 starts_with( String substring ) const + { + if ( substring.length() > length() ) + return false; + + b32 result = str_compare( Data, substring, substring.length() - 1 ) == 0; + return result; + } + void skip_line() { #define current ( *scanner ) @@ -2428,7 +2442,7 @@ struct String operator bool() { - return Data != nullptr; + return Data != nullptr; } operator char*() @@ -2883,4 +2897,3 @@ GEN_NS_END #ifdef __GNUC__ #pragma GCC diagnostic pop #endif - diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.hpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.hpp index 9daab5b..3a16af3 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.hpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.hpp @@ -1,28 +1,11 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #pragma once -/* - gencpp: An attempt at "simple" staged metaprogramming for c/c++. - - See Readme.md for more information from the project repository. - - Public Address: - https://github.com/Ed94/gencpp -*/ -#if ! defined( GEN_DONT_ENFORCE_GEN_TIME_GUARD ) && ! defined( GEN_TIME ) -#error Gen.hpp : GEN_TIME not defined -#endif - -//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. -// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl -#ifndef GEN_ROLL_OWN_DEPENDENCIES -#include "gen.dep.hpp" -#endif - #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -38,6 +21,26 @@ #pragma GCC diagnostic ignored "-Wunused-variable" #endif +/* + gencpp: An attempt at "simple" staged metaprogramming for c/c++. + + See Readme.md for more information from the project repository. + + Public Address: + https://github.com/Ed94/gencpp + + This is a variant intended for use with Unreal Engine 5 +*/ +#if ! defined( GEN_DONT_ENFORCE_GEN_TIME_GUARD ) && ! defined( GEN_TIME ) +#error Gen.hpp : GEN_TIME not defined +#endif + +//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. +// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl +#ifndef GEN_ROLL_OWN_DEPENDENCIES +#include "gen.dep.hpp" +#endif + #ifndef GEN_NS_BEGIN #ifdef GEN_DONT_USE_NAMESPACE #define GEN_NS @@ -121,8 +124,7 @@ enum class ModuleFlag : u32 Invalid, }; -inline -StrC to_str( ModuleFlag flag ) +inline StrC to_str( ModuleFlag flag ) { local_persist StrC lookup[(u32)ModuleFlag::Num_ModuleFlags] = { { sizeof( "__none__" ), "__none__" }, @@ -136,8 +138,7 @@ StrC to_str( ModuleFlag flag ) return lookup[(u32)flag]; } -inline -ModuleFlag operator|( ModuleFlag A, ModuleFlag B ) +inline ModuleFlag operator|( ModuleFlag A, ModuleFlag B ) { return (ModuleFlag)( (u32)A | (u32)B ); } @@ -222,8 +223,7 @@ namespace ECode NumTypes }; - inline - StrC to_str( Type type ) + inline StrC to_str( Type type ) { local_persist StrC lookup[] { { sizeof( "Invalid" ), "Invalid" }, @@ -348,8 +348,7 @@ namespace EOperator NumOps }; - inline - StrC to_str( Type op ) + inline StrC to_str( Type op ) { local_persist StrC lookup[] { { sizeof( "INVALID" ), "INVALID" }, @@ -440,14 +439,12 @@ namespace ESpecifier NumSpecifiers }; - inline - bool is_trailing( Type specifier ) + inline bool is_trailing( Type specifier ) { return specifier > Virtual; } - inline - StrC to_str( Type type ) + inline StrC to_str( Type type ) { local_persist StrC lookup[] { { sizeof( "INVALID" ), "INVALID" }, @@ -480,8 +477,7 @@ namespace ESpecifier return lookup[type]; } - inline - Type to_type( StrC str ) + inline Type to_type( StrC str ) { local_persist u32 keymap[NumSpecifiers]; do_once_start for ( u32 index = 0; index < NumSpecifiers; index++ ) @@ -845,8 +841,8 @@ struct AST { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = // NextVar->Value ) - AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) - AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) + AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) + AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) }; }; @@ -886,7 +882,7 @@ struct AST OperatorT Op; AccessSpec ParentAccess; s32 NumEntries; - s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. + s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. }; }; @@ -928,8 +924,8 @@ struct AST_POD { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = // NextVar->Value ) - AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) - AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) + AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) + AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) }; }; @@ -969,7 +965,7 @@ struct AST_POD OperatorT Op; AccessSpec ParentAccess; s32 NumEntries; - s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. + s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. }; }; @@ -2640,8 +2636,8 @@ struct AST_Param CodeType ValueType; Code Macro; Code Value; - Code PostNameMacro; // Thanks Unreal - // char _PAD_PROPERTIES_3_[sizeof( AST* )]; + Code PostNameMacro; // Thanks Unreal + // char _PAD_PROPERTIES_3_[sizeof( AST* )]; }; }; @@ -3426,8 +3422,7 @@ Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... ); #pragma region Inlines -inline -void AST::append( AST* other ) +inline void AST::append( AST* other ) { if ( other->Parent ) other = other->duplicate(); @@ -3450,8 +3445,7 @@ void AST::append( AST* other ) NumEntries++; } -inline -Code& AST::entry( u32 idx ) +inline Code& AST::entry( u32 idx ) { AST** current = &Front; while ( idx >= 0 && current != nullptr ) @@ -3466,26 +3460,22 @@ Code& AST::entry( u32 idx ) return *rcast( Code*, current ); } -inline -bool AST::has_entries() +inline bool AST::has_entries() { return NumEntries > 0; } -inline -char const* AST::type_str() +inline char const* AST::type_str() { return ECode::to_str( Type ); } -inline -AST::operator Code() +inline AST::operator Code() { return { this }; } -inline -Code& Code::operator++() +inline Code& Code::operator++() { if ( ast ) ast = ast->Next; @@ -3493,8 +3483,7 @@ Code& Code::operator++() return *this; } -inline -void CodeClass::add_interface( CodeType type ) +inline void CodeClass::add_interface( CodeType type ) { CodeType possible_slot = ast->ParentType; if ( possible_slot.ast ) @@ -3513,8 +3502,7 @@ void CodeClass::add_interface( CodeType type ) possible_slot.ast = type.ast; } -inline -void CodeParam::append( CodeParam other ) +inline void CodeParam::append( CodeParam other ) { AST* self = (AST*)ast; AST* entry = (AST*)other.ast; @@ -3537,8 +3525,7 @@ void CodeParam::append( CodeParam other ) self->NumEntries++; } -inline -CodeParam CodeParam::get( s32 idx ) +inline CodeParam CodeParam::get( s32 idx ) { CodeParam param = *this; do @@ -3547,27 +3534,23 @@ CodeParam CodeParam::get( s32 idx ) return { nullptr }; param = { (AST_Param*)param.raw()->Next }; - } - while ( --idx != 0 ); + } while ( --idx ); - return { nullptr }; + return param; } -inline -bool CodeParam::has_entries() +inline bool CodeParam::has_entries() { return ast->NumEntries > 0; } -inline -CodeParam& CodeParam::operator++() +inline CodeParam& CodeParam::operator++() { ast = ast->Next.ast; return *this; } -inline -void CodeStruct::add_interface( CodeType type ) +inline void CodeStruct::add_interface( CodeType type ) { CodeType possible_slot = ast->ParentType; if ( possible_slot.ast ) @@ -3586,8 +3569,7 @@ void CodeStruct::add_interface( CodeType type ) possible_slot.ast = type.ast; } -inline -CodeBody def_body( CodeT type ) +inline CodeBody def_body( CodeT type ) { switch ( type ) { @@ -3613,8 +3595,7 @@ CodeBody def_body( CodeT type ) return (CodeBody)result; } -inline -StrC token_fmt_impl( sw num, ... ) +inline StrC token_fmt_impl( sw num, ... ) { local_persist thread_local char buf[GEN_PRINTF_MAXLEN] = { 0 }; mem_set( buf, 0, GEN_PRINTF_MAXLEN ); @@ -3629,16 +3610,14 @@ StrC token_fmt_impl( sw num, ... ) #pragma region generated code inline implementation -inline -char const* Code::debug_str() +inline char const* Code::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code Code::duplicate() +inline Code Code::duplicate() { if ( ast == nullptr ) { @@ -3648,25 +3627,21 @@ Code Code::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool Code::is_equal( Code other ) +inline bool Code::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool Code::is_valid() +inline bool Code::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void Code::set_global() +inline void Code::set_global() { if ( ast == nullptr ) { @@ -3719,25 +3694,21 @@ inline Code CodeBody::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeBody::is_equal( Code other ) +inline bool CodeBody::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeBody::is_valid() +inline bool CodeBody::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeBody::set_global() +inline void CodeBody::set_global() { if ( ast == nullptr ) { @@ -3747,8 +3718,7 @@ void CodeBody::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeBody& CodeBody::operator=( Code other ) +inline CodeBody& CodeBody::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -3759,34 +3729,29 @@ CodeBody& CodeBody::operator=( Code other ) return *this; } -inline -bool CodeBody::operator==( Code other ) +inline bool CodeBody::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeBody::operator!=( Code other ) +inline bool CodeBody::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeBody::operator bool() +inline CodeBody::operator bool() { return ast != nullptr; } -inline -char const* CodeAttributes::debug_str() +inline char const* CodeAttributes::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeAttributes::duplicate() +inline Code CodeAttributes::duplicate() { if ( ast == nullptr ) { @@ -3796,25 +3761,21 @@ Code CodeAttributes::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeAttributes::is_equal( Code other ) +inline bool CodeAttributes::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeAttributes::is_valid() +inline bool CodeAttributes::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeAttributes::set_global() +inline void CodeAttributes::set_global() { if ( ast == nullptr ) { @@ -3824,8 +3785,7 @@ void CodeAttributes::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeAttributes& CodeAttributes::operator=( Code other ) +inline CodeAttributes& CodeAttributes::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -3836,38 +3796,32 @@ CodeAttributes& CodeAttributes::operator=( Code other ) return *this; } -inline -bool CodeAttributes::operator==( Code other ) +inline bool CodeAttributes::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeAttributes::operator!=( Code other ) +inline bool CodeAttributes::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeAttributes::operator bool() +inline CodeAttributes::operator bool() { return ast != nullptr; } -inline -AST* CodeAttributes::raw() +inline AST* CodeAttributes::raw() { return rcast( AST*, ast ); } -inline -CodeAttributes::operator Code() +inline CodeAttributes::operator Code() { return *rcast( Code*, this ); } -inline -AST_Attributes* CodeAttributes::operator->() +inline AST_Attributes* CodeAttributes::operator->() { if ( ast == nullptr ) { @@ -3877,16 +3831,14 @@ AST_Attributes* CodeAttributes::operator->() return ast; } -inline -char const* CodeComment::debug_str() +inline char const* CodeComment::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeComment::duplicate() +inline Code CodeComment::duplicate() { if ( ast == nullptr ) { @@ -3896,25 +3848,21 @@ Code CodeComment::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeComment::is_equal( Code other ) +inline bool CodeComment::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeComment::is_valid() +inline bool CodeComment::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeComment::set_global() +inline void CodeComment::set_global() { if ( ast == nullptr ) { @@ -3924,8 +3872,7 @@ void CodeComment::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeComment& CodeComment::operator=( Code other ) +inline CodeComment& CodeComment::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -3936,38 +3883,32 @@ CodeComment& CodeComment::operator=( Code other ) return *this; } -inline -bool CodeComment::operator==( Code other ) +inline bool CodeComment::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeComment::operator!=( Code other ) +inline bool CodeComment::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeComment::operator bool() +inline CodeComment::operator bool() { return ast != nullptr; } -inline -AST* CodeComment::raw() +inline AST* CodeComment::raw() { return rcast( AST*, ast ); } -inline -CodeComment::operator Code() +inline CodeComment::operator Code() { return *rcast( Code*, this ); } -inline -AST_Comment* CodeComment::operator->() +inline AST_Comment* CodeComment::operator->() { if ( ast == nullptr ) { @@ -3977,16 +3918,14 @@ AST_Comment* CodeComment::operator->() return ast; } -inline -char const* CodeConstructor::debug_str() +inline char const* CodeConstructor::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeConstructor::duplicate() +inline Code CodeConstructor::duplicate() { if ( ast == nullptr ) { @@ -3996,25 +3935,21 @@ Code CodeConstructor::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeConstructor::is_equal( Code other ) +inline bool CodeConstructor::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeConstructor::is_valid() +inline bool CodeConstructor::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeConstructor::set_global() +inline void CodeConstructor::set_global() { if ( ast == nullptr ) { @@ -4024,8 +3959,7 @@ void CodeConstructor::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeConstructor& CodeConstructor::operator=( Code other ) +inline CodeConstructor& CodeConstructor::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4036,38 +3970,32 @@ CodeConstructor& CodeConstructor::operator=( Code other ) return *this; } -inline -bool CodeConstructor::operator==( Code other ) +inline bool CodeConstructor::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeConstructor::operator!=( Code other ) +inline bool CodeConstructor::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeConstructor::operator bool() +inline CodeConstructor::operator bool() { return ast != nullptr; } -inline -AST* CodeConstructor::raw() +inline AST* CodeConstructor::raw() { return rcast( AST*, ast ); } -inline -CodeConstructor::operator Code() +inline CodeConstructor::operator Code() { return *rcast( Code*, this ); } -inline -AST_Constructor* CodeConstructor::operator->() +inline AST_Constructor* CodeConstructor::operator->() { if ( ast == nullptr ) { @@ -4077,16 +4005,14 @@ AST_Constructor* CodeConstructor::operator->() return ast; } -inline -char const* CodeClass::debug_str() +inline char const* CodeClass::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeClass::duplicate() +inline Code CodeClass::duplicate() { if ( ast == nullptr ) { @@ -4096,25 +4022,21 @@ Code CodeClass::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeClass::is_equal( Code other ) +inline bool CodeClass::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeClass::is_valid() +inline bool CodeClass::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeClass::set_global() +inline void CodeClass::set_global() { if ( ast == nullptr ) { @@ -4124,8 +4046,7 @@ void CodeClass::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeClass& CodeClass::operator=( Code other ) +inline CodeClass& CodeClass::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4136,34 +4057,29 @@ CodeClass& CodeClass::operator=( Code other ) return *this; } -inline -bool CodeClass::operator==( Code other ) +inline bool CodeClass::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeClass::operator!=( Code other ) +inline bool CodeClass::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeClass::operator bool() +inline CodeClass::operator bool() { return ast != nullptr; } -inline -char const* CodeDefine::debug_str() +inline char const* CodeDefine::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeDefine::duplicate() +inline Code CodeDefine::duplicate() { if ( ast == nullptr ) { @@ -4173,25 +4089,21 @@ Code CodeDefine::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeDefine::is_equal( Code other ) +inline bool CodeDefine::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeDefine::is_valid() +inline bool CodeDefine::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeDefine::set_global() +inline void CodeDefine::set_global() { if ( ast == nullptr ) { @@ -4201,8 +4113,7 @@ void CodeDefine::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeDefine& CodeDefine::operator=( Code other ) +inline CodeDefine& CodeDefine::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4213,38 +4124,32 @@ CodeDefine& CodeDefine::operator=( Code other ) return *this; } -inline -bool CodeDefine::operator==( Code other ) +inline bool CodeDefine::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeDefine::operator!=( Code other ) +inline bool CodeDefine::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeDefine::operator bool() +inline CodeDefine::operator bool() { return ast != nullptr; } -inline -AST* CodeDefine::raw() +inline AST* CodeDefine::raw() { return rcast( AST*, ast ); } -inline -CodeDefine::operator Code() +inline CodeDefine::operator Code() { return *rcast( Code*, this ); } -inline -AST_Define* CodeDefine::operator->() +inline AST_Define* CodeDefine::operator->() { if ( ast == nullptr ) { @@ -4254,16 +4159,14 @@ AST_Define* CodeDefine::operator->() return ast; } -inline -char const* CodeDestructor::debug_str() +inline char const* CodeDestructor::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeDestructor::duplicate() +inline Code CodeDestructor::duplicate() { if ( ast == nullptr ) { @@ -4273,25 +4176,21 @@ Code CodeDestructor::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeDestructor::is_equal( Code other ) +inline bool CodeDestructor::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeDestructor::is_valid() +inline bool CodeDestructor::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeDestructor::set_global() +inline void CodeDestructor::set_global() { if ( ast == nullptr ) { @@ -4301,8 +4200,7 @@ void CodeDestructor::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeDestructor& CodeDestructor::operator=( Code other ) +inline CodeDestructor& CodeDestructor::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4313,38 +4211,32 @@ CodeDestructor& CodeDestructor::operator=( Code other ) return *this; } -inline -bool CodeDestructor::operator==( Code other ) +inline bool CodeDestructor::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeDestructor::operator!=( Code other ) +inline bool CodeDestructor::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeDestructor::operator bool() +inline CodeDestructor::operator bool() { return ast != nullptr; } -inline -AST* CodeDestructor::raw() +inline AST* CodeDestructor::raw() { return rcast( AST*, ast ); } -inline -CodeDestructor::operator Code() +inline CodeDestructor::operator Code() { return *rcast( Code*, this ); } -inline -AST_Destructor* CodeDestructor::operator->() +inline AST_Destructor* CodeDestructor::operator->() { if ( ast == nullptr ) { @@ -4354,16 +4246,14 @@ AST_Destructor* CodeDestructor::operator->() return ast; } -inline -char const* CodeEnum::debug_str() +inline char const* CodeEnum::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeEnum::duplicate() +inline Code CodeEnum::duplicate() { if ( ast == nullptr ) { @@ -4373,25 +4263,21 @@ Code CodeEnum::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeEnum::is_equal( Code other ) +inline bool CodeEnum::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeEnum::is_valid() +inline bool CodeEnum::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeEnum::set_global() +inline void CodeEnum::set_global() { if ( ast == nullptr ) { @@ -4401,8 +4287,7 @@ void CodeEnum::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeEnum& CodeEnum::operator=( Code other ) +inline CodeEnum& CodeEnum::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4413,38 +4298,32 @@ CodeEnum& CodeEnum::operator=( Code other ) return *this; } -inline -bool CodeEnum::operator==( Code other ) +inline bool CodeEnum::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeEnum::operator!=( Code other ) +inline bool CodeEnum::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeEnum::operator bool() +inline CodeEnum::operator bool() { return ast != nullptr; } -inline -AST* CodeEnum::raw() +inline AST* CodeEnum::raw() { return rcast( AST*, ast ); } -inline -CodeEnum::operator Code() +inline CodeEnum::operator Code() { return *rcast( Code*, this ); } -inline -AST_Enum* CodeEnum::operator->() +inline AST_Enum* CodeEnum::operator->() { if ( ast == nullptr ) { @@ -4454,16 +4333,14 @@ AST_Enum* CodeEnum::operator->() return ast; } -inline -char const* CodeExec::debug_str() +inline char const* CodeExec::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeExec::duplicate() +inline Code CodeExec::duplicate() { if ( ast == nullptr ) { @@ -4473,25 +4350,21 @@ Code CodeExec::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeExec::is_equal( Code other ) +inline bool CodeExec::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeExec::is_valid() +inline bool CodeExec::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeExec::set_global() +inline void CodeExec::set_global() { if ( ast == nullptr ) { @@ -4501,8 +4374,7 @@ void CodeExec::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeExec& CodeExec::operator=( Code other ) +inline CodeExec& CodeExec::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4513,38 +4385,32 @@ CodeExec& CodeExec::operator=( Code other ) return *this; } -inline -bool CodeExec::operator==( Code other ) +inline bool CodeExec::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeExec::operator!=( Code other ) +inline bool CodeExec::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeExec::operator bool() +inline CodeExec::operator bool() { return ast != nullptr; } -inline -AST* CodeExec::raw() +inline AST* CodeExec::raw() { return rcast( AST*, ast ); } -inline -CodeExec::operator Code() +inline CodeExec::operator Code() { return *rcast( Code*, this ); } -inline -AST_Exec* CodeExec::operator->() +inline AST_Exec* CodeExec::operator->() { if ( ast == nullptr ) { @@ -4554,16 +4420,14 @@ AST_Exec* CodeExec::operator->() return ast; } -inline -char const* CodeExtern::debug_str() +inline char const* CodeExtern::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeExtern::duplicate() +inline Code CodeExtern::duplicate() { if ( ast == nullptr ) { @@ -4573,25 +4437,21 @@ Code CodeExtern::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeExtern::is_equal( Code other ) +inline bool CodeExtern::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeExtern::is_valid() +inline bool CodeExtern::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeExtern::set_global() +inline void CodeExtern::set_global() { if ( ast == nullptr ) { @@ -4601,8 +4461,7 @@ void CodeExtern::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeExtern& CodeExtern::operator=( Code other ) +inline CodeExtern& CodeExtern::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4613,38 +4472,32 @@ CodeExtern& CodeExtern::operator=( Code other ) return *this; } -inline -bool CodeExtern::operator==( Code other ) +inline bool CodeExtern::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeExtern::operator!=( Code other ) +inline bool CodeExtern::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeExtern::operator bool() +inline CodeExtern::operator bool() { return ast != nullptr; } -inline -AST* CodeExtern::raw() +inline AST* CodeExtern::raw() { return rcast( AST*, ast ); } -inline -CodeExtern::operator Code() +inline CodeExtern::operator Code() { return *rcast( Code*, this ); } -inline -AST_Extern* CodeExtern::operator->() +inline AST_Extern* CodeExtern::operator->() { if ( ast == nullptr ) { @@ -4654,16 +4507,14 @@ AST_Extern* CodeExtern::operator->() return ast; } -inline -char const* CodeFriend::debug_str() +inline char const* CodeFriend::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeFriend::duplicate() +inline Code CodeFriend::duplicate() { if ( ast == nullptr ) { @@ -4673,25 +4524,21 @@ Code CodeFriend::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeFriend::is_equal( Code other ) +inline bool CodeFriend::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeFriend::is_valid() +inline bool CodeFriend::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeFriend::set_global() +inline void CodeFriend::set_global() { if ( ast == nullptr ) { @@ -4701,8 +4548,7 @@ void CodeFriend::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeFriend& CodeFriend::operator=( Code other ) +inline CodeFriend& CodeFriend::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4713,38 +4559,32 @@ CodeFriend& CodeFriend::operator=( Code other ) return *this; } -inline -bool CodeFriend::operator==( Code other ) +inline bool CodeFriend::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeFriend::operator!=( Code other ) +inline bool CodeFriend::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeFriend::operator bool() +inline CodeFriend::operator bool() { return ast != nullptr; } -inline -AST* CodeFriend::raw() +inline AST* CodeFriend::raw() { return rcast( AST*, ast ); } -inline -CodeFriend::operator Code() +inline CodeFriend::operator Code() { return *rcast( Code*, this ); } -inline -AST_Friend* CodeFriend::operator->() +inline AST_Friend* CodeFriend::operator->() { if ( ast == nullptr ) { @@ -4754,16 +4594,14 @@ AST_Friend* CodeFriend::operator->() return ast; } -inline -char const* CodeFn::debug_str() +inline char const* CodeFn::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeFn::duplicate() +inline Code CodeFn::duplicate() { if ( ast == nullptr ) { @@ -4773,25 +4611,21 @@ Code CodeFn::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeFn::is_equal( Code other ) +inline bool CodeFn::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeFn::is_valid() +inline bool CodeFn::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeFn::set_global() +inline void CodeFn::set_global() { if ( ast == nullptr ) { @@ -4801,8 +4635,7 @@ void CodeFn::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeFn& CodeFn::operator=( Code other ) +inline CodeFn& CodeFn::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4813,38 +4646,32 @@ CodeFn& CodeFn::operator=( Code other ) return *this; } -inline -bool CodeFn::operator==( Code other ) +inline bool CodeFn::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeFn::operator!=( Code other ) +inline bool CodeFn::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeFn::operator bool() +inline CodeFn::operator bool() { return ast != nullptr; } -inline -AST* CodeFn::raw() +inline AST* CodeFn::raw() { return rcast( AST*, ast ); } -inline -CodeFn::operator Code() +inline CodeFn::operator Code() { return *rcast( Code*, this ); } -inline -AST_Fn* CodeFn::operator->() +inline AST_Fn* CodeFn::operator->() { if ( ast == nullptr ) { @@ -4854,16 +4681,14 @@ AST_Fn* CodeFn::operator->() return ast; } -inline -char const* CodeInclude::debug_str() +inline char const* CodeInclude::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeInclude::duplicate() +inline Code CodeInclude::duplicate() { if ( ast == nullptr ) { @@ -4873,25 +4698,21 @@ Code CodeInclude::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeInclude::is_equal( Code other ) +inline bool CodeInclude::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeInclude::is_valid() +inline bool CodeInclude::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeInclude::set_global() +inline void CodeInclude::set_global() { if ( ast == nullptr ) { @@ -4901,8 +4722,7 @@ void CodeInclude::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeInclude& CodeInclude::operator=( Code other ) +inline CodeInclude& CodeInclude::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4913,38 +4733,32 @@ CodeInclude& CodeInclude::operator=( Code other ) return *this; } -inline -bool CodeInclude::operator==( Code other ) +inline bool CodeInclude::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeInclude::operator!=( Code other ) +inline bool CodeInclude::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeInclude::operator bool() +inline CodeInclude::operator bool() { return ast != nullptr; } -inline -AST* CodeInclude::raw() +inline AST* CodeInclude::raw() { return rcast( AST*, ast ); } -inline -CodeInclude::operator Code() +inline CodeInclude::operator Code() { return *rcast( Code*, this ); } -inline -AST_Include* CodeInclude::operator->() +inline AST_Include* CodeInclude::operator->() { if ( ast == nullptr ) { @@ -4954,16 +4768,14 @@ AST_Include* CodeInclude::operator->() return ast; } -inline -char const* CodeModule::debug_str() +inline char const* CodeModule::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeModule::duplicate() +inline Code CodeModule::duplicate() { if ( ast == nullptr ) { @@ -4973,25 +4785,21 @@ Code CodeModule::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeModule::is_equal( Code other ) +inline bool CodeModule::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeModule::is_valid() +inline bool CodeModule::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeModule::set_global() +inline void CodeModule::set_global() { if ( ast == nullptr ) { @@ -5001,8 +4809,7 @@ void CodeModule::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeModule& CodeModule::operator=( Code other ) +inline CodeModule& CodeModule::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5013,38 +4820,32 @@ CodeModule& CodeModule::operator=( Code other ) return *this; } -inline -bool CodeModule::operator==( Code other ) +inline bool CodeModule::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeModule::operator!=( Code other ) +inline bool CodeModule::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeModule::operator bool() +inline CodeModule::operator bool() { return ast != nullptr; } -inline -AST* CodeModule::raw() +inline AST* CodeModule::raw() { return rcast( AST*, ast ); } -inline -CodeModule::operator Code() +inline CodeModule::operator Code() { return *rcast( Code*, this ); } -inline -AST_Module* CodeModule::operator->() +inline AST_Module* CodeModule::operator->() { if ( ast == nullptr ) { @@ -5054,16 +4855,14 @@ AST_Module* CodeModule::operator->() return ast; } -inline -char const* CodeNS::debug_str() +inline char const* CodeNS::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeNS::duplicate() +inline Code CodeNS::duplicate() { if ( ast == nullptr ) { @@ -5073,25 +4872,21 @@ Code CodeNS::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeNS::is_equal( Code other ) +inline bool CodeNS::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeNS::is_valid() +inline bool CodeNS::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeNS::set_global() +inline void CodeNS::set_global() { if ( ast == nullptr ) { @@ -5101,8 +4896,7 @@ void CodeNS::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeNS& CodeNS::operator=( Code other ) +inline CodeNS& CodeNS::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5113,38 +4907,32 @@ CodeNS& CodeNS::operator=( Code other ) return *this; } -inline -bool CodeNS::operator==( Code other ) +inline bool CodeNS::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeNS::operator!=( Code other ) +inline bool CodeNS::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeNS::operator bool() +inline CodeNS::operator bool() { return ast != nullptr; } -inline -AST* CodeNS::raw() +inline AST* CodeNS::raw() { return rcast( AST*, ast ); } -inline -CodeNS::operator Code() +inline CodeNS::operator Code() { return *rcast( Code*, this ); } -inline -AST_NS* CodeNS::operator->() +inline AST_NS* CodeNS::operator->() { if ( ast == nullptr ) { @@ -5154,16 +4942,14 @@ AST_NS* CodeNS::operator->() return ast; } -inline -char const* CodeOperator::debug_str() +inline char const* CodeOperator::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeOperator::duplicate() +inline Code CodeOperator::duplicate() { if ( ast == nullptr ) { @@ -5173,25 +4959,21 @@ Code CodeOperator::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeOperator::is_equal( Code other ) +inline bool CodeOperator::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeOperator::is_valid() +inline bool CodeOperator::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeOperator::set_global() +inline void CodeOperator::set_global() { if ( ast == nullptr ) { @@ -5201,8 +4983,7 @@ void CodeOperator::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeOperator& CodeOperator::operator=( Code other ) +inline CodeOperator& CodeOperator::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5213,38 +4994,32 @@ CodeOperator& CodeOperator::operator=( Code other ) return *this; } -inline -bool CodeOperator::operator==( Code other ) +inline bool CodeOperator::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeOperator::operator!=( Code other ) +inline bool CodeOperator::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeOperator::operator bool() +inline CodeOperator::operator bool() { return ast != nullptr; } -inline -AST* CodeOperator::raw() +inline AST* CodeOperator::raw() { return rcast( AST*, ast ); } -inline -CodeOperator::operator Code() +inline CodeOperator::operator Code() { return *rcast( Code*, this ); } -inline -AST_Operator* CodeOperator::operator->() +inline AST_Operator* CodeOperator::operator->() { if ( ast == nullptr ) { @@ -5254,16 +5029,14 @@ AST_Operator* CodeOperator::operator->() return ast; } -inline -char const* CodeOpCast::debug_str() +inline char const* CodeOpCast::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeOpCast::duplicate() +inline Code CodeOpCast::duplicate() { if ( ast == nullptr ) { @@ -5273,25 +5046,21 @@ Code CodeOpCast::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeOpCast::is_equal( Code other ) +inline bool CodeOpCast::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeOpCast::is_valid() +inline bool CodeOpCast::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeOpCast::set_global() +inline void CodeOpCast::set_global() { if ( ast == nullptr ) { @@ -5301,8 +5070,7 @@ void CodeOpCast::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeOpCast& CodeOpCast::operator=( Code other ) +inline CodeOpCast& CodeOpCast::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5313,38 +5081,32 @@ CodeOpCast& CodeOpCast::operator=( Code other ) return *this; } -inline -bool CodeOpCast::operator==( Code other ) +inline bool CodeOpCast::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeOpCast::operator!=( Code other ) +inline bool CodeOpCast::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeOpCast::operator bool() +inline CodeOpCast::operator bool() { return ast != nullptr; } -inline -AST* CodeOpCast::raw() +inline AST* CodeOpCast::raw() { return rcast( AST*, ast ); } -inline -CodeOpCast::operator Code() +inline CodeOpCast::operator Code() { return *rcast( Code*, this ); } -inline -AST_OpCast* CodeOpCast::operator->() +inline AST_OpCast* CodeOpCast::operator->() { if ( ast == nullptr ) { @@ -5354,16 +5116,14 @@ AST_OpCast* CodeOpCast::operator->() return ast; } -inline -char const* CodeParam::debug_str() +inline char const* CodeParam::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeParam::duplicate() +inline Code CodeParam::duplicate() { if ( ast == nullptr ) { @@ -5373,28 +5133,21 @@ Code CodeParam::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeParam::is_equal( Code other ) +inline bool CodeParam::is_equal( Code other ) { - if ( ast == nullptr && other.ast == nullptr) - return true; - if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeParam::is_valid() +inline bool CodeParam::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeParam::set_global() +inline void CodeParam::set_global() { if ( ast == nullptr ) { @@ -5404,8 +5157,7 @@ void CodeParam::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeParam& CodeParam::operator=( Code other ) +inline CodeParam& CodeParam::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5416,34 +5168,29 @@ CodeParam& CodeParam::operator=( Code other ) return *this; } -inline -bool CodeParam::operator==( Code other ) +inline bool CodeParam::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeParam::operator!=( Code other ) +inline bool CodeParam::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeParam::operator bool() +inline CodeParam::operator bool() { return ast != nullptr; } -inline -char const* CodePragma::debug_str() +inline char const* CodePragma::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodePragma::duplicate() +inline Code CodePragma::duplicate() { if ( ast == nullptr ) { @@ -5453,25 +5200,21 @@ Code CodePragma::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodePragma::is_equal( Code other ) +inline bool CodePragma::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodePragma::is_valid() +inline bool CodePragma::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodePragma::set_global() +inline void CodePragma::set_global() { if ( ast == nullptr ) { @@ -5481,8 +5224,7 @@ void CodePragma::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodePragma& CodePragma::operator=( Code other ) +inline CodePragma& CodePragma::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5493,38 +5235,32 @@ CodePragma& CodePragma::operator=( Code other ) return *this; } -inline -bool CodePragma::operator==( Code other ) +inline bool CodePragma::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodePragma::operator!=( Code other ) +inline bool CodePragma::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodePragma::operator bool() +inline CodePragma::operator bool() { return ast != nullptr; } -inline -AST* CodePragma::raw() +inline AST* CodePragma::raw() { return rcast( AST*, ast ); } -inline -CodePragma::operator Code() +inline CodePragma::operator Code() { return *rcast( Code*, this ); } -inline -AST_Pragma* CodePragma::operator->() +inline AST_Pragma* CodePragma::operator->() { if ( ast == nullptr ) { @@ -5534,16 +5270,14 @@ AST_Pragma* CodePragma::operator->() return ast; } -inline -char const* CodePreprocessCond::debug_str() +inline char const* CodePreprocessCond::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodePreprocessCond::duplicate() +inline Code CodePreprocessCond::duplicate() { if ( ast == nullptr ) { @@ -5553,25 +5287,21 @@ Code CodePreprocessCond::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodePreprocessCond::is_equal( Code other ) +inline bool CodePreprocessCond::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodePreprocessCond::is_valid() +inline bool CodePreprocessCond::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodePreprocessCond::set_global() +inline void CodePreprocessCond::set_global() { if ( ast == nullptr ) { @@ -5581,8 +5311,7 @@ void CodePreprocessCond::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodePreprocessCond& CodePreprocessCond::operator=( Code other ) +inline CodePreprocessCond& CodePreprocessCond::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5593,38 +5322,32 @@ CodePreprocessCond& CodePreprocessCond::operator=( Code other ) return *this; } -inline -bool CodePreprocessCond::operator==( Code other ) +inline bool CodePreprocessCond::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodePreprocessCond::operator!=( Code other ) +inline bool CodePreprocessCond::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodePreprocessCond::operator bool() +inline CodePreprocessCond::operator bool() { return ast != nullptr; } -inline -AST* CodePreprocessCond::raw() +inline AST* CodePreprocessCond::raw() { return rcast( AST*, ast ); } -inline -CodePreprocessCond::operator Code() +inline CodePreprocessCond::operator Code() { return *rcast( Code*, this ); } -inline -AST_PreprocessCond* CodePreprocessCond::operator->() +inline AST_PreprocessCond* CodePreprocessCond::operator->() { if ( ast == nullptr ) { @@ -5634,16 +5357,14 @@ AST_PreprocessCond* CodePreprocessCond::operator->() return ast; } -inline -char const* CodeSpecifiers::debug_str() +inline char const* CodeSpecifiers::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeSpecifiers::duplicate() +inline Code CodeSpecifiers::duplicate() { if ( ast == nullptr ) { @@ -5653,25 +5374,21 @@ Code CodeSpecifiers::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeSpecifiers::is_equal( Code other ) +inline bool CodeSpecifiers::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeSpecifiers::is_valid() +inline bool CodeSpecifiers::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeSpecifiers::set_global() +inline void CodeSpecifiers::set_global() { if ( ast == nullptr ) { @@ -5681,8 +5398,7 @@ void CodeSpecifiers::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeSpecifiers& CodeSpecifiers::operator=( Code other ) +inline CodeSpecifiers& CodeSpecifiers::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5693,34 +5409,29 @@ CodeSpecifiers& CodeSpecifiers::operator=( Code other ) return *this; } -inline -bool CodeSpecifiers::operator==( Code other ) +inline bool CodeSpecifiers::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeSpecifiers::operator!=( Code other ) +inline bool CodeSpecifiers::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeSpecifiers::operator bool() +inline CodeSpecifiers::operator bool() { return ast != nullptr; } -inline -char const* CodeStruct::debug_str() +inline char const* CodeStruct::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeStruct::duplicate() +inline Code CodeStruct::duplicate() { if ( ast == nullptr ) { @@ -5730,25 +5441,21 @@ Code CodeStruct::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeStruct::is_equal( Code other ) +inline bool CodeStruct::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeStruct::is_valid() +inline bool CodeStruct::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeStruct::set_global() +inline void CodeStruct::set_global() { if ( ast == nullptr ) { @@ -5758,8 +5465,7 @@ void CodeStruct::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeStruct& CodeStruct::operator=( Code other ) +inline CodeStruct& CodeStruct::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5770,34 +5476,29 @@ CodeStruct& CodeStruct::operator=( Code other ) return *this; } -inline -bool CodeStruct::operator==( Code other ) +inline bool CodeStruct::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeStruct::operator!=( Code other ) +inline bool CodeStruct::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeStruct::operator bool() +inline CodeStruct::operator bool() { return ast != nullptr; } -inline -char const* CodeTemplate::debug_str() +inline char const* CodeTemplate::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeTemplate::duplicate() +inline Code CodeTemplate::duplicate() { if ( ast == nullptr ) { @@ -5807,25 +5508,21 @@ Code CodeTemplate::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeTemplate::is_equal( Code other ) +inline bool CodeTemplate::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeTemplate::is_valid() +inline bool CodeTemplate::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeTemplate::set_global() +inline void CodeTemplate::set_global() { if ( ast == nullptr ) { @@ -5835,8 +5532,7 @@ void CodeTemplate::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeTemplate& CodeTemplate::operator=( Code other ) +inline CodeTemplate& CodeTemplate::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5847,38 +5543,32 @@ CodeTemplate& CodeTemplate::operator=( Code other ) return *this; } -inline -bool CodeTemplate::operator==( Code other ) +inline bool CodeTemplate::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeTemplate::operator!=( Code other ) +inline bool CodeTemplate::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeTemplate::operator bool() +inline CodeTemplate::operator bool() { return ast != nullptr; } -inline -AST* CodeTemplate::raw() +inline AST* CodeTemplate::raw() { return rcast( AST*, ast ); } -inline -CodeTemplate::operator Code() +inline CodeTemplate::operator Code() { return *rcast( Code*, this ); } -inline -AST_Template* CodeTemplate::operator->() +inline AST_Template* CodeTemplate::operator->() { if ( ast == nullptr ) { @@ -5888,16 +5578,14 @@ AST_Template* CodeTemplate::operator->() return ast; } -inline -char const* CodeType::debug_str() +inline char const* CodeType::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeType::duplicate() +inline Code CodeType::duplicate() { if ( ast == nullptr ) { @@ -5907,25 +5595,21 @@ Code CodeType::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeType::is_equal( Code other ) +inline bool CodeType::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeType::is_valid() +inline bool CodeType::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeType::set_global() +inline void CodeType::set_global() { if ( ast == nullptr ) { @@ -5935,8 +5619,7 @@ void CodeType::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeType& CodeType::operator=( Code other ) +inline CodeType& CodeType::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5947,38 +5630,32 @@ CodeType& CodeType::operator=( Code other ) return *this; } -inline -bool CodeType::operator==( Code other ) +inline bool CodeType::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeType::operator!=( Code other ) +inline bool CodeType::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeType::operator bool() +inline CodeType::operator bool() { return ast != nullptr; } -inline -AST* CodeType::raw() +inline AST* CodeType::raw() { return rcast( AST*, ast ); } -inline -CodeType::operator Code() +inline CodeType::operator Code() { return *rcast( Code*, this ); } -inline -AST_Type* CodeType::operator->() +inline AST_Type* CodeType::operator->() { if ( ast == nullptr ) { @@ -5988,16 +5665,14 @@ AST_Type* CodeType::operator->() return ast; } -inline -char const* CodeTypedef::debug_str() +inline char const* CodeTypedef::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeTypedef::duplicate() +inline Code CodeTypedef::duplicate() { if ( ast == nullptr ) { @@ -6007,25 +5682,21 @@ Code CodeTypedef::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeTypedef::is_equal( Code other ) +inline bool CodeTypedef::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeTypedef::is_valid() +inline bool CodeTypedef::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeTypedef::set_global() +inline void CodeTypedef::set_global() { if ( ast == nullptr ) { @@ -6035,8 +5706,7 @@ void CodeTypedef::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeTypedef& CodeTypedef::operator=( Code other ) +inline CodeTypedef& CodeTypedef::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -6047,38 +5717,32 @@ CodeTypedef& CodeTypedef::operator=( Code other ) return *this; } -inline -bool CodeTypedef::operator==( Code other ) +inline bool CodeTypedef::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeTypedef::operator!=( Code other ) +inline bool CodeTypedef::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeTypedef::operator bool() +inline CodeTypedef::operator bool() { return ast != nullptr; } -inline -AST* CodeTypedef::raw() +inline AST* CodeTypedef::raw() { return rcast( AST*, ast ); } -inline -CodeTypedef::operator Code() +inline CodeTypedef::operator Code() { return *rcast( Code*, this ); } -inline -AST_Typedef* CodeTypedef::operator->() +inline AST_Typedef* CodeTypedef::operator->() { if ( ast == nullptr ) { @@ -6088,16 +5752,14 @@ AST_Typedef* CodeTypedef::operator->() return ast; } -inline -char const* CodeUnion::debug_str() +inline char const* CodeUnion::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeUnion::duplicate() +inline Code CodeUnion::duplicate() { if ( ast == nullptr ) { @@ -6107,25 +5769,21 @@ Code CodeUnion::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeUnion::is_equal( Code other ) +inline bool CodeUnion::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeUnion::is_valid() +inline bool CodeUnion::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeUnion::set_global() +inline void CodeUnion::set_global() { if ( ast == nullptr ) { @@ -6135,8 +5793,7 @@ void CodeUnion::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeUnion& CodeUnion::operator=( Code other ) +inline CodeUnion& CodeUnion::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -6147,38 +5804,32 @@ CodeUnion& CodeUnion::operator=( Code other ) return *this; } -inline -bool CodeUnion::operator==( Code other ) +inline bool CodeUnion::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeUnion::operator!=( Code other ) +inline bool CodeUnion::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeUnion::operator bool() +inline CodeUnion::operator bool() { return ast != nullptr; } -inline -AST* CodeUnion::raw() +inline AST* CodeUnion::raw() { return rcast( AST*, ast ); } -inline -CodeUnion::operator Code() +inline CodeUnion::operator Code() { return *rcast( Code*, this ); } -inline -AST_Union* CodeUnion::operator->() +inline AST_Union* CodeUnion::operator->() { if ( ast == nullptr ) { @@ -6188,16 +5839,14 @@ AST_Union* CodeUnion::operator->() return ast; } -inline -char const* CodeUsing::debug_str() +inline char const* CodeUsing::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeUsing::duplicate() +inline Code CodeUsing::duplicate() { if ( ast == nullptr ) { @@ -6207,25 +5856,21 @@ Code CodeUsing::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeUsing::is_equal( Code other ) +inline bool CodeUsing::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeUsing::is_valid() +inline bool CodeUsing::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeUsing::set_global() +inline void CodeUsing::set_global() { if ( ast == nullptr ) { @@ -6235,8 +5880,7 @@ void CodeUsing::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeUsing& CodeUsing::operator=( Code other ) +inline CodeUsing& CodeUsing::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -6247,38 +5891,32 @@ CodeUsing& CodeUsing::operator=( Code other ) return *this; } -inline -bool CodeUsing::operator==( Code other ) +inline bool CodeUsing::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeUsing::operator!=( Code other ) +inline bool CodeUsing::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeUsing::operator bool() +inline CodeUsing::operator bool() { return ast != nullptr; } -inline -AST* CodeUsing::raw() +inline AST* CodeUsing::raw() { return rcast( AST*, ast ); } -inline -CodeUsing::operator Code() +inline CodeUsing::operator Code() { return *rcast( Code*, this ); } -inline -AST_Using* CodeUsing::operator->() +inline AST_Using* CodeUsing::operator->() { if ( ast == nullptr ) { @@ -6288,16 +5926,14 @@ AST_Using* CodeUsing::operator->() return ast; } -inline -char const* CodeVar::debug_str() +inline char const* CodeVar::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -inline -Code CodeVar::duplicate() +inline Code CodeVar::duplicate() { if ( ast == nullptr ) { @@ -6307,25 +5943,21 @@ Code CodeVar::duplicate() return { rcast( AST*, ast )->duplicate() }; } -inline -bool CodeVar::is_equal( Code other ) +inline bool CodeVar::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -inline -bool CodeVar::is_valid() +inline bool CodeVar::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -inline -void CodeVar::set_global() +inline void CodeVar::set_global() { if ( ast == nullptr ) { @@ -6335,8 +5967,7 @@ void CodeVar::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -inline -CodeVar& CodeVar::operator=( Code other ) +inline CodeVar& CodeVar::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -6347,38 +5978,32 @@ CodeVar& CodeVar::operator=( Code other ) return *this; } -inline -bool CodeVar::operator==( Code other ) +inline bool CodeVar::operator==( Code other ) { return (AST*)ast == other.ast; } -inline -bool CodeVar::operator!=( Code other ) +inline bool CodeVar::operator!=( Code other ) { return (AST*)ast != other.ast; } -inline -CodeVar::operator bool() +inline CodeVar::operator bool() { return ast != nullptr; } -inline -AST* CodeVar::raw() +inline AST* CodeVar::raw() { return rcast( AST*, ast ); } -inline -CodeVar::operator Code() +inline CodeVar::operator Code() { return *rcast( Code*, this ); } -inline -AST_Var* CodeVar::operator->() +inline AST_Var* CodeVar::operator->() { if ( ast == nullptr ) { @@ -6392,338 +6017,282 @@ AST_Var* CodeVar::operator->() #pragma region generated AST/Code cast implementation -inline -AST::operator CodeBody() +inline AST::operator CodeBody() { return { rcast( AST_Body*, this ) }; } -inline -Code::operator CodeBody() const +inline Code::operator CodeBody() const { return { (AST_Body*)ast }; } -inline -AST::operator CodeAttributes() +inline AST::operator CodeAttributes() { return { rcast( AST_Attributes*, this ) }; } -inline -Code::operator CodeAttributes() const +inline Code::operator CodeAttributes() const { return { (AST_Attributes*)ast }; } -inline -AST::operator CodeComment() +inline AST::operator CodeComment() { return { rcast( AST_Comment*, this ) }; } -inline -Code::operator CodeComment() const +inline Code::operator CodeComment() const { return { (AST_Comment*)ast }; } -inline -AST::operator CodeConstructor() +inline AST::operator CodeConstructor() { return { rcast( AST_Constructor*, this ) }; } -inline -Code::operator CodeConstructor() const +inline Code::operator CodeConstructor() const { return { (AST_Constructor*)ast }; } -inline -AST::operator CodeClass() +inline AST::operator CodeClass() { return { rcast( AST_Class*, this ) }; } -inline -Code::operator CodeClass() const +inline Code::operator CodeClass() const { return { (AST_Class*)ast }; } -inline -AST::operator CodeDefine() +inline AST::operator CodeDefine() { return { rcast( AST_Define*, this ) }; } -inline -Code::operator CodeDefine() const +inline Code::operator CodeDefine() const { return { (AST_Define*)ast }; } -inline -AST::operator CodeDestructor() +inline AST::operator CodeDestructor() { return { rcast( AST_Destructor*, this ) }; } -inline -Code::operator CodeDestructor() const +inline Code::operator CodeDestructor() const { return { (AST_Destructor*)ast }; } -inline -AST::operator CodeEnum() +inline AST::operator CodeEnum() { return { rcast( AST_Enum*, this ) }; } -inline -Code::operator CodeEnum() const +inline Code::operator CodeEnum() const { return { (AST_Enum*)ast }; } -inline -AST::operator CodeExec() +inline AST::operator CodeExec() { return { rcast( AST_Exec*, this ) }; } -inline -Code::operator CodeExec() const +inline Code::operator CodeExec() const { return { (AST_Exec*)ast }; } -inline -AST::operator CodeExtern() +inline AST::operator CodeExtern() { return { rcast( AST_Extern*, this ) }; } -inline -Code::operator CodeExtern() const +inline Code::operator CodeExtern() const { return { (AST_Extern*)ast }; } -inline -AST::operator CodeFriend() +inline AST::operator CodeFriend() { return { rcast( AST_Friend*, this ) }; } -inline -Code::operator CodeFriend() const +inline Code::operator CodeFriend() const { return { (AST_Friend*)ast }; } -inline -AST::operator CodeFn() +inline AST::operator CodeFn() { return { rcast( AST_Fn*, this ) }; } -inline -Code::operator CodeFn() const +inline Code::operator CodeFn() const { return { (AST_Fn*)ast }; } -inline -AST::operator CodeInclude() +inline AST::operator CodeInclude() { return { rcast( AST_Include*, this ) }; } -inline -Code::operator CodeInclude() const +inline Code::operator CodeInclude() const { return { (AST_Include*)ast }; } -inline -AST::operator CodeModule() +inline AST::operator CodeModule() { return { rcast( AST_Module*, this ) }; } -inline -Code::operator CodeModule() const +inline Code::operator CodeModule() const { return { (AST_Module*)ast }; } -inline -AST::operator CodeNS() +inline AST::operator CodeNS() { return { rcast( AST_NS*, this ) }; } -inline -Code::operator CodeNS() const +inline Code::operator CodeNS() const { return { (AST_NS*)ast }; } -inline -AST::operator CodeOperator() +inline AST::operator CodeOperator() { return { rcast( AST_Operator*, this ) }; } -inline -Code::operator CodeOperator() const +inline Code::operator CodeOperator() const { return { (AST_Operator*)ast }; } -inline -AST::operator CodeOpCast() +inline AST::operator CodeOpCast() { return { rcast( AST_OpCast*, this ) }; } -inline -Code::operator CodeOpCast() const +inline Code::operator CodeOpCast() const { return { (AST_OpCast*)ast }; } -inline -AST::operator CodeParam() +inline AST::operator CodeParam() { return { rcast( AST_Param*, this ) }; } -inline -Code::operator CodeParam() const +inline Code::operator CodeParam() const { return { (AST_Param*)ast }; } -inline -AST::operator CodePragma() +inline AST::operator CodePragma() { return { rcast( AST_Pragma*, this ) }; } -inline -Code::operator CodePragma() const +inline Code::operator CodePragma() const { return { (AST_Pragma*)ast }; } -inline -AST::operator CodePreprocessCond() +inline AST::operator CodePreprocessCond() { return { rcast( AST_PreprocessCond*, this ) }; } -inline -Code::operator CodePreprocessCond() const +inline Code::operator CodePreprocessCond() const { return { (AST_PreprocessCond*)ast }; } -inline -AST::operator CodeSpecifiers() +inline AST::operator CodeSpecifiers() { return { rcast( AST_Specifiers*, this ) }; } -inline -Code::operator CodeSpecifiers() const +inline Code::operator CodeSpecifiers() const { return { (AST_Specifiers*)ast }; } -inline -AST::operator CodeStruct() +inline AST::operator CodeStruct() { return { rcast( AST_Struct*, this ) }; } -inline -Code::operator CodeStruct() const +inline Code::operator CodeStruct() const { return { (AST_Struct*)ast }; } -inline -AST::operator CodeTemplate() +inline AST::operator CodeTemplate() { return { rcast( AST_Template*, this ) }; } -inline -Code::operator CodeTemplate() const +inline Code::operator CodeTemplate() const { return { (AST_Template*)ast }; } -inline -AST::operator CodeType() +inline AST::operator CodeType() { return { rcast( AST_Type*, this ) }; } -inline -Code::operator CodeType() const +inline Code::operator CodeType() const { return { (AST_Type*)ast }; } -inline -AST::operator CodeTypedef() +inline AST::operator CodeTypedef() { return { rcast( AST_Typedef*, this ) }; } -inline -Code::operator CodeTypedef() const +inline Code::operator CodeTypedef() const { return { (AST_Typedef*)ast }; } -inline -AST::operator CodeUnion() +inline AST::operator CodeUnion() { return { rcast( AST_Union*, this ) }; } -inline -Code::operator CodeUnion() const +inline Code::operator CodeUnion() const { return { (AST_Union*)ast }; } -inline -AST::operator CodeUsing() +inline AST::operator CodeUsing() { return { rcast( AST_Using*, this ) }; } -inline -Code::operator CodeUsing() const +inline Code::operator CodeUsing() const { return { (AST_Using*)ast }; } -inline -AST::operator CodeVar() +inline AST::operator CodeVar() { return { rcast( AST_Var*, this ) }; } -inline -Code::operator CodeVar() const +inline Code::operator CodeVar() const { return { (AST_Var*)ast }; } diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.scanner.cpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.scanner.cpp index 9ca5125..8e64a0c 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.scanner.cpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.scanner.cpp @@ -1,10 +1,9 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) - -#include "gen.scanner.hpp" +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -20,6 +19,8 @@ #pragma GCC diagnostic ignored "-Wunused-variable" #endif +#include "gen.scanner.hpp" + GEN_NS_BEGIN #pragma region ADT @@ -56,7 +57,7 @@ u8 adt_destroy_branch( ADT_Node* node ) GEN_ASSERT_NOT_NULL( node ); if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes ) { - for ( sw i = 0; i < scast(sw, node->nodes.num()); ++i ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); ++i ) { adt_destroy_branch( node->nodes + i ); } @@ -86,7 +87,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ) return NULL; } - for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { if ( ! str_compare( node->nodes[i].name, name ) ) { @@ -96,7 +97,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ) if ( deep_search ) { - for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { ADT_Node* res = adt_find( node->nodes + i, name, deep_search ); @@ -152,7 +153,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value ) internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value ) { - for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { if ( ! str_compare( node->nodes[i].name, name ) ) { @@ -227,7 +228,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) /* run a value comparison against any child that is an object node */ else if ( node->type == EADT_TYPE_ARRAY ) { - for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { ADT_Node* child = &node->nodes[i]; if ( child->type != EADT_TYPE_OBJECT ) @@ -245,7 +246,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) /* [value] */ else { - for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { ADT_Node* child = &node->nodes[i]; if ( _adt_get_value( child, l_b2 ) ) @@ -277,7 +278,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) else { sw idx = (sw)str_to_i64( buf, NULL, 10 ); - if ( idx >= 0 && idx < scast(sw, node->nodes.num()) ) + if ( idx >= 0 && idx < scast( sw, node->nodes.num() ) ) { found_node = &node->nodes[idx]; @@ -302,7 +303,7 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, sw index ) if ( ! parent->nodes ) return NULL; - if ( index < 0 || index > scast(sw, parent->nodes.num()) ) + if ( index < 0 || index > scast( sw, parent->nodes.num() ) ) return NULL; ADT_Node o = { 0 }; @@ -963,7 +964,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b } } - if ( columnIndex >= scast(sw, root->nodes.num()) ) + if ( columnIndex >= scast( sw, root->nodes.num() ) ) { adt_append_arr( root, NULL ); } @@ -1005,7 +1006,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b /* consider first row as a header. */ if ( has_header ) { - for ( sw i = 0; i < scast(sw, root->nodes.num()); i++ ) + for ( sw i = 0; i < scast( sw, root->nodes.num() ); i++ ) { CSV_Object* col = root->nodes + i; CSV_Object* hdr = col->nodes; diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.scanner.hpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.scanner.hpp index 4e6c94a..bda531a 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.scanner.hpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.scanner.hpp @@ -1,12 +1,11 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #pragma once -#include "gen.hpp" - #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -22,6 +21,8 @@ #pragma GCC diagnostic ignored "-Wunused-variable" #endif +#include "gen.hpp" + GEN_NS_BEGIN #pragma region ADT @@ -453,7 +454,7 @@ GEN_IMPL_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj ) // This is a simple file reader that reads the entire file into memory. // It has an extra option to skip the first few lines for undesired includes. // This is done so that includes can be kept in dependency and component files so that intellisense works. -Code scan_file( char const* path ) +inline Code scan_file( char const* path ) { FileInfo file; diff --git a/Project/Source/GasaGen/GasaGen.cpp b/Project/Source/GasaGen/GasaGen.cpp index c8bafaa..8d14884 100644 --- a/Project/Source/GasaGen/GasaGen.cpp +++ b/Project/Source/GasaGen/GasaGen.cpp @@ -3,6 +3,7 @@ #define GEN_EXPOSE_BACKEND // #define GEN_DEFINE_ATTRIBUTE_TOKENS #define GEN_IMPLEMENTATION +#include "gen.dep.cpp" #include "gen.cpp" #include "gen.builder.cpp" // #include "gen.scanner.hpp" @@ -82,16 +83,16 @@ int gen_main() PreprocessorDefines.append( get_cached_string(str_UE_REQUIRES)); } - gen_UGasaAttributeSet(); - gen_FGasaDevOptionsCache(); - gen_UHostWidgetController(); + // gen_UGasaAttributeSet(); + // gen_FGasaDevOptionsCache(); + // gen_UHostWidgetController(); // gen_netslime_interfaces(); // One offs - if (0) + if (1) { - // ue_parse_testing(); - swap_SBlueprintActionMenu_Construct(); + ue_parse_testing(); + //swap_SBlueprintActionMenu_Construct(); } return 0; } diff --git a/Project/Source/GasaGen/gen.builder.cpp b/Project/Source/GasaGen/gen.builder.cpp index 64d4751..16257a7 100644 --- a/Project/Source/GasaGen/gen.builder.cpp +++ b/Project/Source/GasaGen/gen.builder.cpp @@ -1,4 +1,23 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" +#pragma clang diagnostic ignored "-Wswitch" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wvarargs" +#pragma clang diagnostic ignored "-Wunused-function" +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wcomment" +#pragma GCC diagnostic ignored "-Wswitch" +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif #include "gen.builder.hpp" @@ -14,6 +33,7 @@ Builder Builder::open( char const* path ) log_failure( "gen::File::open - Could not open file: %s", path ); return result; } + result.Buffer = String::make_reserve( GlobalAllocator, Builder_StrBufferReserve ); // log_fmt("$Builder - Opened file: %s\n", result.File.filename ); @@ -49,7 +69,7 @@ void Builder::print_fmt( char const* fmt, ... ) void Builder::write() { - bool result = file_write( &File, Buffer, Buffer.length() ); + b32 result = file_write( &File, Buffer, Buffer.length() ); if ( result == false ) log_failure( "gen::File::write - Failed to write to file: %s\n", file_name( &File ) ); @@ -60,3 +80,11 @@ void Builder::write() } GEN_NS_END + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/Project/Source/GasaGen/gen.builder.hpp b/Project/Source/GasaGen/gen.builder.hpp index b5e2025..ef56f6d 100644 --- a/Project/Source/GasaGen/gen.builder.hpp +++ b/Project/Source/GasaGen/gen.builder.hpp @@ -1,4 +1,23 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" +#pragma clang diagnostic ignored "-Wswitch" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wvarargs" +#pragma clang diagnostic ignored "-Wunused-function" +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wcomment" +#pragma GCC diagnostic ignored "-Wswitch" +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif #pragma once @@ -22,3 +41,11 @@ struct Builder }; GEN_NS_END + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/Project/Source/GasaGen/gen.cpp b/Project/Source/GasaGen/gen.cpp index d557b84..5eed464 100644 --- a/Project/Source/GasaGen/gen.cpp +++ b/Project/Source/GasaGen/gen.cpp @@ -1,8 +1,9 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) -#if __clang__ +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -10,25 +11,20 @@ #pragma clang diagnostic ignored "-Wunused-function" #endif -#if __GNUC__ +#ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunknown-pragmas" #pragma GCC diagnostic ignored "-Wcomment" #pragma GCC diagnostic ignored "-Wswitch" #pragma GCC diagnostic ignored "-Wunused-variable" #endif + #if ! defined( GEN_DONT_ENFORCE_GEN_TIME_GUARD ) && ! defined( GEN_TIME ) #error Gen.hpp : GEN_TIME not defined #endif #include "gen.hpp" -//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file. -//! Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl -#ifndef GEN_ROLL_OWN_DEPENDENCIES -#include "gen.dep.cpp" -#endif - GEN_NS_BEGIN #pragma region StaticData @@ -1654,7 +1650,7 @@ void CodeClass::to_string_def( String& result ) while ( interface ) { result.append_fmt( ", %S", interface.to_string() ); - interface = interface->Next ? interface->Next->cast() : Code { nullptr }; + interface = interface->Next ? interface->Next->cast() : CodeType { nullptr }; } } else if ( ast->Name ) @@ -1950,7 +1946,7 @@ void CodeFn::to_string_def( String& result ) if ( ast->Attributes ) result.append_fmt( " %S ", ast->Attributes.to_string() ); - b32 prefix_specs = false; + bool prefix_specs = false; if ( ast->Specs ) { for ( SpecifierT spec : ast->Specs ) @@ -2003,7 +1999,7 @@ void CodeFn::to_string_fwd( String& result ) if ( ast->Attributes ) result.append_fmt( "%S ", ast->Attributes.to_string() ); - bool prefix_specs = false; + b32 prefix_specs = false; if ( ast->Specs ) { for ( SpecifierT spec : ast->Specs ) @@ -2232,7 +2228,14 @@ void CodeOpCast::to_string_def( String& result ) { if ( ast->Specs ) { - // TODO : Add support for specifies before the operator keyword + for ( SpecifierT spec : ast->Specs ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( "%*s ", spec_str.Len, spec_str.Ptr ); + } + } if ( ast->Name && ast->Name.length() ) result.append_fmt( "%Soperator %S()", ast->Name, ast->ValueType.to_string() ); @@ -2262,7 +2265,14 @@ void CodeOpCast::to_string_fwd( String& result ) { if ( ast->Specs ) { - // TODO : Add support for specifies before the operator keyword + for ( SpecifierT spec : ast->Specs ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( "%*s ", spec_str.Len, spec_str.Ptr ); + } + } result.append_fmt( "operator %S()", ast->ValueType.to_string() ); @@ -2316,7 +2326,7 @@ void CodeParam::to_string( String& result ) if ( ast->PostNameMacro ) { - result.append_fmt(" %S", ast->PostNameMacro.to_string() ); + result.append_fmt( " %S", ast->PostNameMacro.to_string() ); } if ( ast->Value ) @@ -2461,7 +2471,7 @@ void CodeStruct::to_string_def( String& result ) while ( interface ) { result.append_fmt( ", %S", interface.to_string() ); - interface = interface->Next ? interface->Next->cast() : Code { nullptr }; + interface = interface->Next ? interface->Next->cast() : CodeType { nullptr }; } } else if ( ast->Name ) @@ -2569,7 +2579,7 @@ String CodeType::to_string() void CodeType::to_string( String& result ) { -#if GEN_USE_NEW_TYPENAME_PARSING +#if defined( GEN_USE_NEW_TYPENAME_PARSING ) if ( ast->ReturnType && ast->Params ) { if ( ast->Attributes ) @@ -2734,12 +2744,20 @@ void CodeVar::to_string( String& result ) } if ( ast->Value ) - result.append_fmt( " = %S", ast->Value.to_string() ); + { + if ( ast->VarConstructorInit ) + result.append_fmt( "( %S ", ast->Value.to_string() ); + else + result.append_fmt( " = %S", ast->Value.to_string() ); + } // Keep the chain going... if ( ast->NextVar ) result.append_fmt( ", %S", ast->NextVar.to_string() ); + if ( ast->VarConstructorInit ) + result.append( " )" ); + return; } @@ -2772,11 +2790,19 @@ void CodeVar::to_string( String& result ) result.append_fmt( " : %S", ast->BitfieldSize.to_string() ); if ( ast->Value ) - result.append_fmt( " = %S", ast->Value.to_string() ); + { + if ( ast->VarConstructorInit ) + result.append_fmt( "( %S ", ast->Value.to_string() ); + else + result.append_fmt( " = %S", ast->Value.to_string() ); + } if ( ast->NextVar ) result.append_fmt( ", %S", ast->NextVar.to_string() ); + if ( ast->VarConstructorInit ) + result.append( " )" ); + if ( ast->InlineCmt ) result.append_fmt( "; %S", ast->InlineCmt->Content ); else @@ -2804,11 +2830,19 @@ void CodeVar::to_string( String& result ) result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name ); if ( ast->Value ) - result.append_fmt( " = %S", ast->Value.to_string() ); + { + if ( ast->VarConstructorInit ) + result.append_fmt( "( %S ", ast->Value.to_string() ); + else + result.append_fmt( " = %S", ast->Value.to_string() ); + } if ( ast->NextVar ) result.append_fmt( ", %S", ast->NextVar.to_string() ); + if ( ast->VarConstructorInit ) + result.append( " )" ); + result.append( ";" ); if ( ast->InlineCmt ) @@ -3185,7 +3219,7 @@ AllocatorInfo get_string_allocator( s32 str_length ) uw size_req = str_length + sizeof( String::Header ) + sizeof( char* ); - if ( last->TotalUsed + size_req > last->TotalSize ) + if ( last->TotalUsed + sw( size_req ) > last->TotalSize ) { Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena ); @@ -5674,8 +5708,8 @@ namespace parser #define GEN_DEFINE_ATTRIBUTE_TOKENS \ Entry( Attribute_API_Export, "GEN_API_Export_Code" ) Entry( Attribute_API_Import, "GEN_API_Import_Code" ) \ Entry( Attribute_UE_DEPRECATED, "UE_DEPRECATED" ) Entry( Attribute_UMG_API, "UMG_API" ) Entry( Attribute_COREUOBJECT_API, "COREUOBJECT_API" ) \ - Entry( Attribute_ENGINE_API, "ENGINE_API" ) Entry( Attribute_GASA_API, "GASA_API" ) \ - Entry( Attribute_GAMEPLAYABILITIES_API, "GAMEPLAYABILITIES_API" ) + Entry( Attribute_ENGINE_API, "ENGINE_API" ) Entry( Attribute_GAMEPLAYABILITIES_API, "GAMEPLAYABILITIES_API" ) \ + Entry( Attribute_GASA_API, "GASA_API" ) enum Type : u32 { @@ -5780,12 +5814,12 @@ namespace parser Attribute_UMG_API, Attribute_COREUOBJECT_API, Attribute_ENGINE_API, - Attribute_GASA_API, Attribute_GAMEPLAYABILITIES_API, + Attribute_GASA_API, NumTokens }; - StrC to_str( Type type ) + inline StrC to_str( Type type ) { local_persist StrC lookup[] { { sizeof( "__invalid__" ), "__invalid__" }, @@ -5889,13 +5923,13 @@ namespace parser { sizeof( "UMG_API" ), "UMG_API" }, { sizeof( "COREUOBJECT_API" ), "COREUOBJECT_API" }, { sizeof( "ENGINE_API" ), "ENGINE_API" }, - { sizeof( "GASA_API" ), "GASA_API" }, { sizeof( "GAMEPLAYABILITIES_API" ), "GAMEPLAYABILITIES_API" }, + { sizeof( "GASA_API" ), "GASA_API" }, }; return lookup[type]; } - Type to_type( StrC str ) + inline Type to_type( StrC str ) { local_persist u32 keymap[NumTokens]; do_once_start for ( u32 index = 0; index < NumTokens; index++ ) @@ -6121,7 +6155,8 @@ namespace parser Lex_ReturnNull, }; - FORCEINLINE s32 lex_preprocessor_directive( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& defines, Token& token ) + FORCEINLINE + s32 lex_preprocessor_directive( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& defines, Token& token ) { char const* hash = scanner; Tokens.append( { hash, 1, TokType::Preprocess_Hash, line, column, TF_Preprocess } ); @@ -6365,7 +6400,8 @@ namespace parser return Lex_Continue; // Skip found token, its all handled here. } - FORCEINLINE void lex_found_token( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& defines, Token& token ) + FORCEINLINE + void lex_found_token( StrC& content, s32& left, char const*& scanner, s32& line, s32& column, HashTable& defines, Token& token ) { if ( token.Type != TokType::Invalid ) { @@ -6492,7 +6528,7 @@ namespace parser { s32 length = 0; char const* scanner = entry.Data; - while ( entry.length() > length && char_is_alphanumeric( *scanner ) || *scanner == '_' ) + while ( entry.length() > length && ( char_is_alphanumeric( *scanner ) || *scanner == '_' ) ) { scanner++; length++; @@ -7102,6 +7138,26 @@ namespace parser move_forward(); token.Length++; } + + // Handle number literal suffixes in a botched way + if ( left + && ( current == 'l' || current == 'L' || // long/long long + current == 'u' || current == 'U' || // unsigned + current == 'f' || current == 'F' || // float + current == 'i' || current == 'I' || // imaginary + current == 'z' || current == 'Z' ) ) // complex + { + char prev = current; + move_forward(); + token.Length++; + + // Handle 'll'/'LL' as a special case when we just processed an 'l'/'L' + if ( left && ( prev == 'l' || prev == 'L' ) && ( current == 'l' || current == 'L' ) ) + { + move_forward(); + token.Length++; + } + } } goto FoundToken; @@ -8480,6 +8536,10 @@ namespace parser s32 level = 0; while ( left && currtok.Type != TokType::Statement_End && ( currtok.Type != TokType::Comma || level > 0 ) ) { + if ( currtok.Type == TokType::BraceCurly_Open ) + level++; + if ( currtok.Type == TokType::BraceCurly_Close ) + level--; if ( currtok.Type == TokType::Capture_Start ) level++; else if ( currtok.Type == TokType::Capture_End ) @@ -8525,8 +8585,6 @@ namespace parser return CodeInvalid; } - - return CodeInvalid; } // Function parsing is handled in multiple places because its initial signature is shared with variable parsing @@ -8960,7 +9018,7 @@ namespace parser if ( found_operator_cast_outside_class_implmentation ) { - member = parse_operator_cast(); + member = parse_operator_cast( specifiers ); // ::operator () { ... } break; } @@ -9628,10 +9686,17 @@ namespace parser } else { - Token name = parse_identifier(); - Context.Scope->Name = name; + Token name = parse_identifier(); + Context.Scope->Name = name; - if ( check( TokType::Capture_Start ) ) + bool detected_capture = check( TokType::Capture_Start ); + + // Check three tokens ahead to make sure that were not dealing with a constructor initialization... + // ( 350.0f , <--- Could be the scenario + // Example : + // idx +1 +2 + bool detected_comma = Context.Tokens.Arr[Context.Tokens.Idx + 2].Type == TokType::Comma; + if ( detected_capture && ! detected_comma ) { // Dealing with a function result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name ); @@ -9762,7 +9827,7 @@ namespace parser // template::Value)> // class T ... and then ^this^ UE_REQUIRES shows up // So we need to consume that. - if ( check( TokType::Preprocess_Macro )) + if ( check( TokType::Preprocess_Macro ) ) { post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro ); } @@ -9786,7 +9851,8 @@ namespace parser s32 capture_level = 0; s32 template_level = 0; - while ( left && ( currtok.Type != TokType::Comma ) && template_level >= 0 && CheckEndParams() || capture_level > 0 || template_level > 0 ) + while ( ( left && ( currtok.Type != TokType::Comma ) && template_level >= 0 && CheckEndParams() ) || ( capture_level > 0 || template_level > 0 ) + ) { if ( currtok.Text[0] == '<' ) ++template_level; @@ -9874,7 +9940,7 @@ namespace parser // template::Value)> // class T ... and then ^this^ UE_REQUIRES shows up // So we need to consume that. - if ( check( TokType::Preprocess_Macro )) + if ( check( TokType::Preprocess_Macro ) ) { post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro ); } @@ -9898,7 +9964,8 @@ namespace parser s32 capture_level = 0; s32 template_level = 0; - while ( left && currtok.Type != TokType::Comma && template_level >= 0 && CheckEndParams() || capture_level > 0 || template_level > 0 ) + while ( ( left && currtok.Type != TokType::Comma && template_level >= 0 && CheckEndParams() ) || ( capture_level > 0 || template_level > 0 ) + ) { if ( currtok.Text[0] == '<' ) ++template_level; @@ -9974,7 +10041,7 @@ namespace parser } CodePreprocessCond cond = (CodePreprocessCond)make_code(); - cond->Type = scast( CodeT, currtok.Type - ( ETokType::Preprocess_If - ECode::Preprocess_If ) ); + cond->Type = scast( CodeT, currtok.Type - ( TokType::Preprocess_If - ECode::Preprocess_If ) ); eat( currtok.Type ); // # @@ -10154,9 +10221,11 @@ namespace parser { push_scope(); - Code array_expr = parse_array_decl(); - Code expr = { nullptr }; - Code bitfield_expr = { nullptr }; + Code array_expr = parse_array_decl(); + Code expr = { nullptr }; + Code bitfield_expr = { nullptr }; + + b32 using_constructor_initializer = false; if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) { @@ -10189,6 +10258,33 @@ namespace parser // = { } } + if ( currtok.Type == TokType::Capture_Start ) + { + eat( TokType::Capture_Start ); + // ( + + Token expr_token = currtok; + + using_constructor_initializer = true; + + s32 level = 0; + while ( left && ( currtok.Type != TokType::Capture_End || level > 0 ) ) + { + if ( currtok.Type == TokType::Capture_Start ) + level++; + + else if ( currtok.Type == TokType::Capture_End && level > 0 ) + level--; + + eat( currtok.Type ); + } + + expr_token.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)expr_token.Text; + expr = untyped_str( expr_token ); + eat( TokType::Capture_End ); + // ( ) + } + if ( currtok.Type == TokType::Assign_Classifer ) { eat( TokType::Assign_Classifer ); @@ -10282,6 +10378,8 @@ namespace parser result->NextVar->Parent = result; } + result->VarConstructorInit = using_constructor_initializer; + Context.pop(); return result; } @@ -10340,6 +10438,8 @@ namespace parser break; } + // eat(currtok.Type); + if ( specifiers ) specifiers.append( spec ); else @@ -10737,6 +10837,13 @@ namespace parser // = , } + // Consume inline comments + // if ( currtok.Type == TokType::Comment && prevtok.Line == currtok.Line ) + // { + // eat( TokType::Comment ); + // = , // + // } + entry.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)entry.Text; member = untyped_str( entry ); @@ -11105,8 +11212,6 @@ namespace parser { push_scope(); - // TODO : Specifiers attributed to the cast - // Operator's namespace if not within same class. Token name = NullToken; if ( check( TokType::Identifier ) ) @@ -11532,6 +11637,18 @@ else if ( currtok.Type == TokType::DeclType ) name = currtok; eat( TokType::Type_Typename ); // + + if ( ! from_template ) + { + name = parse_identifier(); + Context.Scope->Name = name; + if ( ! name ) + { + log_failure( "Error, failed to type signature\n%s", Context.to_string() ); + Context.pop(); + return CodeInvalid; + } + } } // The usual Identifier type signature that may have namespace qualifiers @@ -12864,10 +12981,10 @@ Code untyped_token_fmt( s32 num_tokens, ... ) GEN_NS_END -#if __clang__ +#ifdef __clang__ #pragma clang diagnostic pop #endif -#if __GNUC__ +#ifdef __GNUC__ #pragma GCC diagnostic pop #endif diff --git a/Project/Source/GasaGen/gen.dep.cpp b/Project/Source/GasaGen/gen.dep.cpp index 268c89b..fb828df 100644 --- a/Project/Source/GasaGen/gen.dep.cpp +++ b/Project/Source/GasaGen/gen.dep.cpp @@ -1,7 +1,25 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) -// This file is intended to be included within gen.cpp (There is no pragma diagnostic ignores) +#include "gen.dep.hpp" +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" +#pragma clang diagnostic ignored "-Wswitch" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wvarargs" +#pragma clang diagnostic ignored "-Wunused-function" +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wcomment" +#pragma GCC diagnostic ignored "-Wswitch" +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif #pragma region Macros and Includes @@ -1651,7 +1669,7 @@ bool String::make_space_for( char const* str, sw add_len ) Data = rcast( char*, header + 1 ); - return str; + return true; } } @@ -2238,7 +2256,7 @@ internal GEN_FILE_WRITE_AT_PROC( _memory_file_write ) { Array arr = { d->buf }; - if ( arr.get_header()->Capacity < new_cap ) + if ( arr.get_header()->Capacity < uw( new_cap ) ) { if ( ! arr.grow( (s64)( new_cap ) ) ) return false; @@ -2448,3 +2466,11 @@ f64 time_rel( void ) #pragma endregion Timing GEN_NS_END + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/Project/Source/GasaGen/gen.dep.hpp b/Project/Source/GasaGen/gen.dep.hpp index d4238a5..dbe3796 100644 --- a/Project/Source/GasaGen/gen.dep.hpp +++ b/Project/Source/GasaGen/gen.dep.hpp @@ -1,9 +1,26 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) - -// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #pragma once +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" +#pragma clang diagnostic ignored "-Wswitch" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wvarargs" +#pragma clang diagnostic ignored "-Wunused-function" +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wcomment" +#pragma GCC diagnostic ignored "-Wswitch" +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif + #pragma region Platform Detection /* Platform architecture */ @@ -133,6 +150,10 @@ #endif GEN_NS_BEGIN +#ifdef GEN_INTELLISENSE_DIRECTIVES +#pragma once +#include "header_start.hpp" +#endif #pragma region Macros @@ -140,10 +161,11 @@ GEN_NS_BEGIN // Keywords -#define global static // Global variables +#define global // Global variables #define internal static // Internal linkage #define local_persist static // Local Persisting variables +#pragma region ForceInline Definition #ifdef GEN_COMPILER_MSVC #define FORCEINLINE __forceinline #define neverinline __declspec( noinline ) @@ -162,18 +184,23 @@ GEN_NS_BEGIN #define FORCEINLINE #define neverinline #endif +#pragma endregion ForceInline Definition // Bits +#ifndef bit #define bit( Value ) ( 1 << Value ) #define bitfield_is_equal( Type, Field, Mask ) ( ( Type( Mask ) & Type( Field ) ) == Type( Mask ) ) +#endif // Casting +#ifndef ccast #define ccast( Type, Value ) ( *const_cast( &( Value ) ) ) #define pcast( Type, Value ) ( *reinterpret_cast( &( Value ) ) ) #define rcast( Type, Value ) reinterpret_cast( Value ) #define scast( Type, Value ) static_cast( Value ) +#endif // Num Arguments (Varadics) // #if defined(__GNUC__) || defined(__clang__) @@ -1090,11 +1117,17 @@ struct Arena return alignment_offset; } +// This id is defined by Unreal for asserts +#pragma push_macro( "check" ) +#undef check + void check() { GEN_ASSERT( TempCount == 0 ); } +#pragma pop_macro( "check" ) + void free() { if ( Backing.Proc ) @@ -1557,7 +1590,7 @@ struct Array { return 2 * value + 8; } - + bool append( Array other ) { return append( other, other.num() ); @@ -1671,7 +1704,7 @@ struct Array if ( begin < 0 || end > header.Num ) return false; - for ( sw idx = begin; idx < end; idx++ ) + for ( sw idx = sw( begin ); idx < sw( end ); idx++ ) { Data[idx] = value; } @@ -1829,7 +1862,7 @@ struct HashTable static HashTable init( AllocatorInfo allocator ) { - HashTable result = init_reserve(allocator, 8); + HashTable result = init_reserve( allocator, 8 ); return result; } @@ -1837,10 +1870,10 @@ struct HashTable { HashTable result = { { nullptr }, { nullptr } }; - result.Hashes = Array::init_reserve( allocator, num ); + result.Hashes = Array::init_reserve( allocator, num ); result.Hashes.get_header()->Num = num; result.Hashes.resize( num ); - result.Hashes.fill( 0, num, -1); + result.Hashes.fill( 0, num, -1 ); result.Entries = Array::init_reserve( allocator, num ); return result; @@ -1849,7 +1882,7 @@ struct HashTable void clear( void ) { Entries.clear(); - Hashes.fill( 0, Hashes.num(), -1); + Hashes.fill( 0, Hashes.num(), -1 ); } void destroy( void ) @@ -1876,7 +1909,7 @@ struct HashTable { GEN_ASSERT_NOT_NULL( map_proc ); - for ( sw idx = 0; idx < Entries.num(); idx++ ) + for ( sw idx = 0; idx < sw( Entries.num() ); ++idx ) { map_proc( Entries[idx].Key, Entries[idx].Value ); } @@ -1888,7 +1921,7 @@ struct HashTable { GEN_ASSERT_NOT_NULL( map_proc ); - for ( sw idx = 0; idx < Entries.num(); idx++ ) + for ( sw idx = 0; idx < sw( Entries.num() ); ++idx ) { map_proc( Entries[idx].Key, &Entries[idx].Value ); } @@ -1905,7 +1938,7 @@ struct HashTable sw last_added_index; HashTable new_ht = init_reserve( Hashes.get_header()->Allocator, new_num ); - for ( sw idx = 0; idx < Entries.num(); ++idx ) + for ( sw idx = 0; idx < sw( Entries.num() ); ++idx ) { FindResult find_result; @@ -1930,13 +1963,13 @@ struct HashTable { sw idx; - for ( idx = 0; idx < Entries.num(); idx++ ) + for ( idx = 0; idx < sw( Entries.num() ); idx++ ) Entries[idx].Next = -1; - for ( idx = 0; idx < Hashes.num(); idx++ ) + for ( idx = 0; idx < sw( Hashes.num() ); idx++ ) Hashes[idx] = -1; - for ( idx = 0; idx < Entries.num(); idx++ ) + for ( idx = 0; idx < sw( Entries.num() ); idx++ ) { Entry* entry; FindResult find_result; @@ -2002,7 +2035,7 @@ struct HashTable sw slot( u64 key ) { - for ( sw idx = 0; idx < Hashes.num(); ++idx ) + for ( sw idx = 0; idx < sw( Hashes.num() ); ++idx ) if ( Hashes[idx] == key ) return idx; @@ -2047,8 +2080,8 @@ protected: b32 full() { - uw critical_load = uw( CriticalLoadScale * f32(Hashes.num()) ); - b32 result = Entries.num() > critical_load; + uw critical_load = uw( CriticalLoadScale * f32( Hashes.num() ) ); + b32 result = Entries.num() > critical_load; return result; } }; @@ -2070,25 +2103,25 @@ struct StrC sw Len; char const* Ptr; - char const& operator[]( sw index ) const - { - return Ptr[index]; - } - operator char const*() const { return Ptr; } + + char const& operator[]( sw index ) const + { + return Ptr[index]; + } }; -#define cast_to_strc( str ) *rcast( StrC*, str - sizeof( sw ) ) -#define txt( text ) \ - StrC \ - { \ - sizeof( (text) ) - 1, (text) \ +#define cast_to_strc( str ) *rcast( StrC*, ( str ) - sizeof( sw ) ) +#define txt( text ) \ + StrC \ + { \ + sizeof( text ) - 1, ( text ) \ } -StrC to_str( char const* str ) +inline StrC to_str( char const* str ) { return { str_len( str ), str }; } @@ -2160,7 +2193,7 @@ struct String static bool are_equal( String lhs, StrC rhs ) { - if ( lhs.length() != (rhs.Len - 1) ) + if ( lhs.length() != ( rhs.Len ) ) return false; for ( sw idx = 0; idx < lhs.length(); ++idx ) @@ -2199,7 +2232,7 @@ struct String header.Length = curr_len + length; } - return str; + return str != nullptr; } bool append( StrC str ) @@ -2238,24 +2271,6 @@ struct String get_header().Length = 0; } - b32 starts_with( StrC substring ) const - { - if (substring.Len > length()) - return false; - - b32 result = str_compare(Data, substring.Ptr, substring.Len ) == 0; - return result; - } - - b32 starts_with( String substring ) const - { - if (substring.length() > length()) - return false; - - b32 result = str_compare(Data, substring, substring.length() - 1 ) == 0; - return result; - } - String duplicate( AllocatorInfo allocator ) const { return make_length( allocator, Data, length() ); @@ -2283,6 +2298,24 @@ struct String return header.Length; } + b32 starts_with( StrC substring ) const + { + if ( substring.Len > length() ) + return false; + + b32 result = str_compare( Data, substring.Ptr, substring.Len ) == 0; + return result; + } + + b32 starts_with( String substring ) const + { + if ( substring.length() > length() ) + return false; + + b32 result = str_compare( Data, substring, substring.length() - 1 ) == 0; + return result; + } + void skip_line() { #define current ( *scanner ) @@ -2409,7 +2442,7 @@ struct String operator bool() { - return Data; + return Data != nullptr; } operator char*() @@ -2856,3 +2889,11 @@ u64 time_rel_ms( void ); #pragma endregion Timing GEN_NS_END + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/Project/Source/GasaGen/gen.hpp b/Project/Source/GasaGen/gen.hpp index 5307239..3a16af3 100644 --- a/Project/Source/GasaGen/gen.hpp +++ b/Project/Source/GasaGen/gen.hpp @@ -1,10 +1,11 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #pragma once -#if __clang__ +#ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic ignored "-Wunknown-pragmas" @@ -12,14 +13,13 @@ #pragma clang diagnostic ignored "-Wunused-function" #endif -#if __GNUC__ +#ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunknown-pragmas" #pragma GCC diagnostic ignored "-Wcomment" #pragma GCC diagnostic ignored "-Wswitch" #pragma GCC diagnostic ignored "-Wunused-variable" #endif -#pragma once /* gencpp: An attempt at "simple" staged metaprogramming for c/c++. @@ -28,6 +28,8 @@ Public Address: https://github.com/Ed94/gencpp + + This is a variant intended for use with Unreal Engine 5 */ #if ! defined( GEN_DONT_ENFORCE_GEN_TIME_GUARD ) && ! defined( GEN_TIME ) #error Gen.hpp : GEN_TIME not defined @@ -122,7 +124,7 @@ enum class ModuleFlag : u32 Invalid, }; -StrC to_str( ModuleFlag flag ) +inline StrC to_str( ModuleFlag flag ) { local_persist StrC lookup[(u32)ModuleFlag::Num_ModuleFlags] = { { sizeof( "__none__" ), "__none__" }, @@ -136,7 +138,7 @@ StrC to_str( ModuleFlag flag ) return lookup[(u32)flag]; } -ModuleFlag operator|( ModuleFlag A, ModuleFlag B ) +inline ModuleFlag operator|( ModuleFlag A, ModuleFlag B ) { return (ModuleFlag)( (u32)A | (u32)B ); } @@ -221,7 +223,7 @@ namespace ECode NumTypes }; - StrC to_str( Type type ) + inline StrC to_str( Type type ) { local_persist StrC lookup[] { { sizeof( "Invalid" ), "Invalid" }, @@ -346,7 +348,7 @@ namespace EOperator NumOps }; - StrC to_str( Type op ) + inline StrC to_str( Type op ) { local_persist StrC lookup[] { { sizeof( "INVALID" ), "INVALID" }, @@ -437,12 +439,12 @@ namespace ESpecifier NumSpecifiers }; - bool is_trailing( Type specifier ) + inline bool is_trailing( Type specifier ) { return specifier > Virtual; } - StrC to_str( Type type ) + inline StrC to_str( Type type ) { local_persist StrC lookup[] { { sizeof( "INVALID" ), "INVALID" }, @@ -475,7 +477,7 @@ namespace ESpecifier return lookup[type]; } - Type to_type( StrC str ) + inline Type to_type( StrC str ) { local_persist u32 keymap[NumSpecifiers]; do_once_start for ( u32 index = 0; index < NumSpecifiers; index++ ) @@ -839,8 +841,8 @@ struct AST { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = // NextVar->Value ) - AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) - AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) + AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) + AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) }; }; @@ -880,6 +882,7 @@ struct AST OperatorT Op; AccessSpec ParentAccess; s32 NumEntries; + s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. }; }; @@ -921,8 +924,8 @@ struct AST_POD { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = // NextVar->Value ) - AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) - AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) + AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) + AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) }; }; @@ -962,6 +965,7 @@ struct AST_POD OperatorT Op; AccessSpec ParentAccess; s32 NumEntries; + s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. }; }; @@ -2632,8 +2636,8 @@ struct AST_Param CodeType ValueType; Code Macro; Code Value; - Code PostNameMacro; // Thanks Unreal - // char _PAD_PROPERTIES_3_[sizeof( AST* )]; + Code PostNameMacro; // Thanks Unreal + // char _PAD_PROPERTIES_3_[sizeof( AST* )]; }; }; @@ -3168,7 +3172,7 @@ struct AST_Var StringCached Name; CodeT Type; ModuleFlag ModuleFlags; - char _PAD_UNUSED_[sizeof( u32 )]; + s32 VarConstructorInit; }; static_assert( sizeof( AST_Var ) == sizeof( AST ), "ERROR: AST_Var is not the same size as AST" ); @@ -3418,7 +3422,7 @@ Code untyped_token_fmt( char const* fmt, s32 num_tokens, ... ); #pragma region Inlines -void AST::append( AST* other ) +inline void AST::append( AST* other ) { if ( other->Parent ) other = other->duplicate(); @@ -3441,7 +3445,7 @@ void AST::append( AST* other ) NumEntries++; } -Code& AST::entry( u32 idx ) +inline Code& AST::entry( u32 idx ) { AST** current = &Front; while ( idx >= 0 && current != nullptr ) @@ -3456,22 +3460,22 @@ Code& AST::entry( u32 idx ) return *rcast( Code*, current ); } -bool AST::has_entries() +inline bool AST::has_entries() { - return NumEntries; + return NumEntries > 0; } -char const* AST::type_str() +inline char const* AST::type_str() { return ECode::to_str( Type ); } -AST::operator Code() +inline AST::operator Code() { return { this }; } -Code& Code::operator++() +inline Code& Code::operator++() { if ( ast ) ast = ast->Next; @@ -3479,7 +3483,7 @@ Code& Code::operator++() return *this; } -void CodeClass::add_interface( CodeType type ) +inline void CodeClass::add_interface( CodeType type ) { CodeType possible_slot = ast->ParentType; if ( possible_slot.ast ) @@ -3498,7 +3502,7 @@ void CodeClass::add_interface( CodeType type ) possible_slot.ast = type.ast; } -void CodeParam::append( CodeParam other ) +inline void CodeParam::append( CodeParam other ) { AST* self = (AST*)ast; AST* entry = (AST*)other.ast; @@ -3521,7 +3525,7 @@ void CodeParam::append( CodeParam other ) self->NumEntries++; } -CodeParam CodeParam::get( s32 idx ) +inline CodeParam CodeParam::get( s32 idx ) { CodeParam param = *this; do @@ -3529,24 +3533,24 @@ CodeParam CodeParam::get( s32 idx ) if ( ! ++param ) return { nullptr }; - return { (AST_Param*)param.raw()->Next }; + param = { (AST_Param*)param.raw()->Next }; } while ( --idx ); - return { nullptr }; + return param; } -bool CodeParam::has_entries() +inline bool CodeParam::has_entries() { return ast->NumEntries > 0; } -CodeParam& CodeParam::operator++() +inline CodeParam& CodeParam::operator++() { ast = ast->Next.ast; return *this; } -void CodeStruct::add_interface( CodeType type ) +inline void CodeStruct::add_interface( CodeType type ) { CodeType possible_slot = ast->ParentType; if ( possible_slot.ast ) @@ -3565,7 +3569,7 @@ void CodeStruct::add_interface( CodeType type ) possible_slot.ast = type.ast; } -CodeBody def_body( CodeT type ) +inline CodeBody def_body( CodeT type ) { switch ( type ) { @@ -3591,7 +3595,7 @@ CodeBody def_body( CodeT type ) return (CodeBody)result; } -StrC token_fmt_impl( sw num, ... ) +inline StrC token_fmt_impl( sw num, ... ) { local_persist thread_local char buf[GEN_PRINTF_MAXLEN] = { 0 }; mem_set( buf, 0, GEN_PRINTF_MAXLEN ); @@ -3606,14 +3610,14 @@ StrC token_fmt_impl( sw num, ... ) #pragma region generated code inline implementation -char const* Code::debug_str() +inline char const* Code::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code Code::duplicate() +inline Code Code::duplicate() { if ( ast == nullptr ) { @@ -3623,22 +3627,21 @@ Code Code::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool Code::is_equal( Code other ) +inline bool Code::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool Code::is_valid() +inline bool Code::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void Code::set_global() +inline void Code::set_global() { if ( ast == nullptr ) { @@ -3648,7 +3651,7 @@ void Code::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -Code& Code::operator=( Code other ) +inline Code& Code::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -3659,29 +3662,29 @@ Code& Code::operator=( Code other ) return *this; } -bool Code::operator==( Code other ) +inline bool Code::operator==( Code other ) { return (AST*)ast == other.ast; } -bool Code::operator!=( Code other ) +inline bool Code::operator!=( Code other ) { return (AST*)ast != other.ast; } -Code::operator bool() +inline Code::operator bool() { return ast != nullptr; } -char const* CodeBody::debug_str() +inline char const* CodeBody::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeBody::duplicate() +inline Code CodeBody::duplicate() { if ( ast == nullptr ) { @@ -3691,22 +3694,21 @@ Code CodeBody::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeBody::is_equal( Code other ) +inline bool CodeBody::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeBody::is_valid() +inline bool CodeBody::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeBody::set_global() +inline void CodeBody::set_global() { if ( ast == nullptr ) { @@ -3716,7 +3718,7 @@ void CodeBody::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeBody& CodeBody::operator=( Code other ) +inline CodeBody& CodeBody::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -3727,29 +3729,29 @@ CodeBody& CodeBody::operator=( Code other ) return *this; } -bool CodeBody::operator==( Code other ) +inline bool CodeBody::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeBody::operator!=( Code other ) +inline bool CodeBody::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeBody::operator bool() +inline CodeBody::operator bool() { return ast != nullptr; } -char const* CodeAttributes::debug_str() +inline char const* CodeAttributes::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeAttributes::duplicate() +inline Code CodeAttributes::duplicate() { if ( ast == nullptr ) { @@ -3759,22 +3761,21 @@ Code CodeAttributes::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeAttributes::is_equal( Code other ) +inline bool CodeAttributes::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeAttributes::is_valid() +inline bool CodeAttributes::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeAttributes::set_global() +inline void CodeAttributes::set_global() { if ( ast == nullptr ) { @@ -3784,7 +3785,7 @@ void CodeAttributes::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeAttributes& CodeAttributes::operator=( Code other ) +inline CodeAttributes& CodeAttributes::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -3795,32 +3796,32 @@ CodeAttributes& CodeAttributes::operator=( Code other ) return *this; } -bool CodeAttributes::operator==( Code other ) +inline bool CodeAttributes::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeAttributes::operator!=( Code other ) +inline bool CodeAttributes::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeAttributes::operator bool() +inline CodeAttributes::operator bool() { return ast != nullptr; } -AST* CodeAttributes::raw() +inline AST* CodeAttributes::raw() { return rcast( AST*, ast ); } -CodeAttributes::operator Code() +inline CodeAttributes::operator Code() { return *rcast( Code*, this ); } -AST_Attributes* CodeAttributes::operator->() +inline AST_Attributes* CodeAttributes::operator->() { if ( ast == nullptr ) { @@ -3830,14 +3831,14 @@ AST_Attributes* CodeAttributes::operator->() return ast; } -char const* CodeComment::debug_str() +inline char const* CodeComment::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeComment::duplicate() +inline Code CodeComment::duplicate() { if ( ast == nullptr ) { @@ -3847,22 +3848,21 @@ Code CodeComment::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeComment::is_equal( Code other ) +inline bool CodeComment::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeComment::is_valid() +inline bool CodeComment::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeComment::set_global() +inline void CodeComment::set_global() { if ( ast == nullptr ) { @@ -3872,7 +3872,7 @@ void CodeComment::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeComment& CodeComment::operator=( Code other ) +inline CodeComment& CodeComment::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -3883,32 +3883,32 @@ CodeComment& CodeComment::operator=( Code other ) return *this; } -bool CodeComment::operator==( Code other ) +inline bool CodeComment::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeComment::operator!=( Code other ) +inline bool CodeComment::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeComment::operator bool() +inline CodeComment::operator bool() { return ast != nullptr; } -AST* CodeComment::raw() +inline AST* CodeComment::raw() { return rcast( AST*, ast ); } -CodeComment::operator Code() +inline CodeComment::operator Code() { return *rcast( Code*, this ); } -AST_Comment* CodeComment::operator->() +inline AST_Comment* CodeComment::operator->() { if ( ast == nullptr ) { @@ -3918,14 +3918,14 @@ AST_Comment* CodeComment::operator->() return ast; } -char const* CodeConstructor::debug_str() +inline char const* CodeConstructor::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeConstructor::duplicate() +inline Code CodeConstructor::duplicate() { if ( ast == nullptr ) { @@ -3935,22 +3935,21 @@ Code CodeConstructor::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeConstructor::is_equal( Code other ) +inline bool CodeConstructor::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeConstructor::is_valid() +inline bool CodeConstructor::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeConstructor::set_global() +inline void CodeConstructor::set_global() { if ( ast == nullptr ) { @@ -3960,7 +3959,7 @@ void CodeConstructor::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeConstructor& CodeConstructor::operator=( Code other ) +inline CodeConstructor& CodeConstructor::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -3971,32 +3970,32 @@ CodeConstructor& CodeConstructor::operator=( Code other ) return *this; } -bool CodeConstructor::operator==( Code other ) +inline bool CodeConstructor::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeConstructor::operator!=( Code other ) +inline bool CodeConstructor::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeConstructor::operator bool() +inline CodeConstructor::operator bool() { return ast != nullptr; } -AST* CodeConstructor::raw() +inline AST* CodeConstructor::raw() { return rcast( AST*, ast ); } -CodeConstructor::operator Code() +inline CodeConstructor::operator Code() { return *rcast( Code*, this ); } -AST_Constructor* CodeConstructor::operator->() +inline AST_Constructor* CodeConstructor::operator->() { if ( ast == nullptr ) { @@ -4006,14 +4005,14 @@ AST_Constructor* CodeConstructor::operator->() return ast; } -char const* CodeClass::debug_str() +inline char const* CodeClass::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeClass::duplicate() +inline Code CodeClass::duplicate() { if ( ast == nullptr ) { @@ -4023,22 +4022,21 @@ Code CodeClass::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeClass::is_equal( Code other ) +inline bool CodeClass::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeClass::is_valid() +inline bool CodeClass::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeClass::set_global() +inline void CodeClass::set_global() { if ( ast == nullptr ) { @@ -4048,7 +4046,7 @@ void CodeClass::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeClass& CodeClass::operator=( Code other ) +inline CodeClass& CodeClass::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4059,29 +4057,29 @@ CodeClass& CodeClass::operator=( Code other ) return *this; } -bool CodeClass::operator==( Code other ) +inline bool CodeClass::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeClass::operator!=( Code other ) +inline bool CodeClass::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeClass::operator bool() +inline CodeClass::operator bool() { return ast != nullptr; } -char const* CodeDefine::debug_str() +inline char const* CodeDefine::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeDefine::duplicate() +inline Code CodeDefine::duplicate() { if ( ast == nullptr ) { @@ -4091,22 +4089,21 @@ Code CodeDefine::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeDefine::is_equal( Code other ) +inline bool CodeDefine::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeDefine::is_valid() +inline bool CodeDefine::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeDefine::set_global() +inline void CodeDefine::set_global() { if ( ast == nullptr ) { @@ -4116,7 +4113,7 @@ void CodeDefine::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeDefine& CodeDefine::operator=( Code other ) +inline CodeDefine& CodeDefine::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4127,32 +4124,32 @@ CodeDefine& CodeDefine::operator=( Code other ) return *this; } -bool CodeDefine::operator==( Code other ) +inline bool CodeDefine::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeDefine::operator!=( Code other ) +inline bool CodeDefine::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeDefine::operator bool() +inline CodeDefine::operator bool() { return ast != nullptr; } -AST* CodeDefine::raw() +inline AST* CodeDefine::raw() { return rcast( AST*, ast ); } -CodeDefine::operator Code() +inline CodeDefine::operator Code() { return *rcast( Code*, this ); } -AST_Define* CodeDefine::operator->() +inline AST_Define* CodeDefine::operator->() { if ( ast == nullptr ) { @@ -4162,14 +4159,14 @@ AST_Define* CodeDefine::operator->() return ast; } -char const* CodeDestructor::debug_str() +inline char const* CodeDestructor::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeDestructor::duplicate() +inline Code CodeDestructor::duplicate() { if ( ast == nullptr ) { @@ -4179,22 +4176,21 @@ Code CodeDestructor::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeDestructor::is_equal( Code other ) +inline bool CodeDestructor::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeDestructor::is_valid() +inline bool CodeDestructor::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeDestructor::set_global() +inline void CodeDestructor::set_global() { if ( ast == nullptr ) { @@ -4204,7 +4200,7 @@ void CodeDestructor::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeDestructor& CodeDestructor::operator=( Code other ) +inline CodeDestructor& CodeDestructor::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4215,32 +4211,32 @@ CodeDestructor& CodeDestructor::operator=( Code other ) return *this; } -bool CodeDestructor::operator==( Code other ) +inline bool CodeDestructor::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeDestructor::operator!=( Code other ) +inline bool CodeDestructor::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeDestructor::operator bool() +inline CodeDestructor::operator bool() { return ast != nullptr; } -AST* CodeDestructor::raw() +inline AST* CodeDestructor::raw() { return rcast( AST*, ast ); } -CodeDestructor::operator Code() +inline CodeDestructor::operator Code() { return *rcast( Code*, this ); } -AST_Destructor* CodeDestructor::operator->() +inline AST_Destructor* CodeDestructor::operator->() { if ( ast == nullptr ) { @@ -4250,14 +4246,14 @@ AST_Destructor* CodeDestructor::operator->() return ast; } -char const* CodeEnum::debug_str() +inline char const* CodeEnum::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeEnum::duplicate() +inline Code CodeEnum::duplicate() { if ( ast == nullptr ) { @@ -4267,22 +4263,21 @@ Code CodeEnum::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeEnum::is_equal( Code other ) +inline bool CodeEnum::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeEnum::is_valid() +inline bool CodeEnum::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeEnum::set_global() +inline void CodeEnum::set_global() { if ( ast == nullptr ) { @@ -4292,7 +4287,7 @@ void CodeEnum::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeEnum& CodeEnum::operator=( Code other ) +inline CodeEnum& CodeEnum::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4303,32 +4298,32 @@ CodeEnum& CodeEnum::operator=( Code other ) return *this; } -bool CodeEnum::operator==( Code other ) +inline bool CodeEnum::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeEnum::operator!=( Code other ) +inline bool CodeEnum::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeEnum::operator bool() +inline CodeEnum::operator bool() { return ast != nullptr; } -AST* CodeEnum::raw() +inline AST* CodeEnum::raw() { return rcast( AST*, ast ); } -CodeEnum::operator Code() +inline CodeEnum::operator Code() { return *rcast( Code*, this ); } -AST_Enum* CodeEnum::operator->() +inline AST_Enum* CodeEnum::operator->() { if ( ast == nullptr ) { @@ -4338,14 +4333,14 @@ AST_Enum* CodeEnum::operator->() return ast; } -char const* CodeExec::debug_str() +inline char const* CodeExec::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeExec::duplicate() +inline Code CodeExec::duplicate() { if ( ast == nullptr ) { @@ -4355,22 +4350,21 @@ Code CodeExec::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeExec::is_equal( Code other ) +inline bool CodeExec::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeExec::is_valid() +inline bool CodeExec::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeExec::set_global() +inline void CodeExec::set_global() { if ( ast == nullptr ) { @@ -4380,7 +4374,7 @@ void CodeExec::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeExec& CodeExec::operator=( Code other ) +inline CodeExec& CodeExec::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4391,32 +4385,32 @@ CodeExec& CodeExec::operator=( Code other ) return *this; } -bool CodeExec::operator==( Code other ) +inline bool CodeExec::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeExec::operator!=( Code other ) +inline bool CodeExec::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeExec::operator bool() +inline CodeExec::operator bool() { return ast != nullptr; } -AST* CodeExec::raw() +inline AST* CodeExec::raw() { return rcast( AST*, ast ); } -CodeExec::operator Code() +inline CodeExec::operator Code() { return *rcast( Code*, this ); } -AST_Exec* CodeExec::operator->() +inline AST_Exec* CodeExec::operator->() { if ( ast == nullptr ) { @@ -4426,14 +4420,14 @@ AST_Exec* CodeExec::operator->() return ast; } -char const* CodeExtern::debug_str() +inline char const* CodeExtern::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeExtern::duplicate() +inline Code CodeExtern::duplicate() { if ( ast == nullptr ) { @@ -4443,22 +4437,21 @@ Code CodeExtern::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeExtern::is_equal( Code other ) +inline bool CodeExtern::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeExtern::is_valid() +inline bool CodeExtern::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeExtern::set_global() +inline void CodeExtern::set_global() { if ( ast == nullptr ) { @@ -4468,7 +4461,7 @@ void CodeExtern::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeExtern& CodeExtern::operator=( Code other ) +inline CodeExtern& CodeExtern::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4479,32 +4472,32 @@ CodeExtern& CodeExtern::operator=( Code other ) return *this; } -bool CodeExtern::operator==( Code other ) +inline bool CodeExtern::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeExtern::operator!=( Code other ) +inline bool CodeExtern::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeExtern::operator bool() +inline CodeExtern::operator bool() { return ast != nullptr; } -AST* CodeExtern::raw() +inline AST* CodeExtern::raw() { return rcast( AST*, ast ); } -CodeExtern::operator Code() +inline CodeExtern::operator Code() { return *rcast( Code*, this ); } -AST_Extern* CodeExtern::operator->() +inline AST_Extern* CodeExtern::operator->() { if ( ast == nullptr ) { @@ -4514,14 +4507,14 @@ AST_Extern* CodeExtern::operator->() return ast; } -char const* CodeFriend::debug_str() +inline char const* CodeFriend::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeFriend::duplicate() +inline Code CodeFriend::duplicate() { if ( ast == nullptr ) { @@ -4531,22 +4524,21 @@ Code CodeFriend::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeFriend::is_equal( Code other ) +inline bool CodeFriend::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeFriend::is_valid() +inline bool CodeFriend::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeFriend::set_global() +inline void CodeFriend::set_global() { if ( ast == nullptr ) { @@ -4556,7 +4548,7 @@ void CodeFriend::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeFriend& CodeFriend::operator=( Code other ) +inline CodeFriend& CodeFriend::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4567,32 +4559,32 @@ CodeFriend& CodeFriend::operator=( Code other ) return *this; } -bool CodeFriend::operator==( Code other ) +inline bool CodeFriend::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeFriend::operator!=( Code other ) +inline bool CodeFriend::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeFriend::operator bool() +inline CodeFriend::operator bool() { return ast != nullptr; } -AST* CodeFriend::raw() +inline AST* CodeFriend::raw() { return rcast( AST*, ast ); } -CodeFriend::operator Code() +inline CodeFriend::operator Code() { return *rcast( Code*, this ); } -AST_Friend* CodeFriend::operator->() +inline AST_Friend* CodeFriend::operator->() { if ( ast == nullptr ) { @@ -4602,14 +4594,14 @@ AST_Friend* CodeFriend::operator->() return ast; } -char const* CodeFn::debug_str() +inline char const* CodeFn::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeFn::duplicate() +inline Code CodeFn::duplicate() { if ( ast == nullptr ) { @@ -4619,22 +4611,21 @@ Code CodeFn::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeFn::is_equal( Code other ) +inline bool CodeFn::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeFn::is_valid() +inline bool CodeFn::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeFn::set_global() +inline void CodeFn::set_global() { if ( ast == nullptr ) { @@ -4644,7 +4635,7 @@ void CodeFn::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeFn& CodeFn::operator=( Code other ) +inline CodeFn& CodeFn::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4655,32 +4646,32 @@ CodeFn& CodeFn::operator=( Code other ) return *this; } -bool CodeFn::operator==( Code other ) +inline bool CodeFn::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeFn::operator!=( Code other ) +inline bool CodeFn::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeFn::operator bool() +inline CodeFn::operator bool() { return ast != nullptr; } -AST* CodeFn::raw() +inline AST* CodeFn::raw() { return rcast( AST*, ast ); } -CodeFn::operator Code() +inline CodeFn::operator Code() { return *rcast( Code*, this ); } -AST_Fn* CodeFn::operator->() +inline AST_Fn* CodeFn::operator->() { if ( ast == nullptr ) { @@ -4690,14 +4681,14 @@ AST_Fn* CodeFn::operator->() return ast; } -char const* CodeInclude::debug_str() +inline char const* CodeInclude::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeInclude::duplicate() +inline Code CodeInclude::duplicate() { if ( ast == nullptr ) { @@ -4707,22 +4698,21 @@ Code CodeInclude::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeInclude::is_equal( Code other ) +inline bool CodeInclude::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeInclude::is_valid() +inline bool CodeInclude::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeInclude::set_global() +inline void CodeInclude::set_global() { if ( ast == nullptr ) { @@ -4732,7 +4722,7 @@ void CodeInclude::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeInclude& CodeInclude::operator=( Code other ) +inline CodeInclude& CodeInclude::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4743,32 +4733,32 @@ CodeInclude& CodeInclude::operator=( Code other ) return *this; } -bool CodeInclude::operator==( Code other ) +inline bool CodeInclude::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeInclude::operator!=( Code other ) +inline bool CodeInclude::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeInclude::operator bool() +inline CodeInclude::operator bool() { return ast != nullptr; } -AST* CodeInclude::raw() +inline AST* CodeInclude::raw() { return rcast( AST*, ast ); } -CodeInclude::operator Code() +inline CodeInclude::operator Code() { return *rcast( Code*, this ); } -AST_Include* CodeInclude::operator->() +inline AST_Include* CodeInclude::operator->() { if ( ast == nullptr ) { @@ -4778,14 +4768,14 @@ AST_Include* CodeInclude::operator->() return ast; } -char const* CodeModule::debug_str() +inline char const* CodeModule::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeModule::duplicate() +inline Code CodeModule::duplicate() { if ( ast == nullptr ) { @@ -4795,22 +4785,21 @@ Code CodeModule::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeModule::is_equal( Code other ) +inline bool CodeModule::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeModule::is_valid() +inline bool CodeModule::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeModule::set_global() +inline void CodeModule::set_global() { if ( ast == nullptr ) { @@ -4820,7 +4809,7 @@ void CodeModule::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeModule& CodeModule::operator=( Code other ) +inline CodeModule& CodeModule::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4831,32 +4820,32 @@ CodeModule& CodeModule::operator=( Code other ) return *this; } -bool CodeModule::operator==( Code other ) +inline bool CodeModule::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeModule::operator!=( Code other ) +inline bool CodeModule::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeModule::operator bool() +inline CodeModule::operator bool() { return ast != nullptr; } -AST* CodeModule::raw() +inline AST* CodeModule::raw() { return rcast( AST*, ast ); } -CodeModule::operator Code() +inline CodeModule::operator Code() { return *rcast( Code*, this ); } -AST_Module* CodeModule::operator->() +inline AST_Module* CodeModule::operator->() { if ( ast == nullptr ) { @@ -4866,14 +4855,14 @@ AST_Module* CodeModule::operator->() return ast; } -char const* CodeNS::debug_str() +inline char const* CodeNS::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeNS::duplicate() +inline Code CodeNS::duplicate() { if ( ast == nullptr ) { @@ -4883,22 +4872,21 @@ Code CodeNS::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeNS::is_equal( Code other ) +inline bool CodeNS::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeNS::is_valid() +inline bool CodeNS::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeNS::set_global() +inline void CodeNS::set_global() { if ( ast == nullptr ) { @@ -4908,7 +4896,7 @@ void CodeNS::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeNS& CodeNS::operator=( Code other ) +inline CodeNS& CodeNS::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -4919,32 +4907,32 @@ CodeNS& CodeNS::operator=( Code other ) return *this; } -bool CodeNS::operator==( Code other ) +inline bool CodeNS::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeNS::operator!=( Code other ) +inline bool CodeNS::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeNS::operator bool() +inline CodeNS::operator bool() { return ast != nullptr; } -AST* CodeNS::raw() +inline AST* CodeNS::raw() { return rcast( AST*, ast ); } -CodeNS::operator Code() +inline CodeNS::operator Code() { return *rcast( Code*, this ); } -AST_NS* CodeNS::operator->() +inline AST_NS* CodeNS::operator->() { if ( ast == nullptr ) { @@ -4954,14 +4942,14 @@ AST_NS* CodeNS::operator->() return ast; } -char const* CodeOperator::debug_str() +inline char const* CodeOperator::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeOperator::duplicate() +inline Code CodeOperator::duplicate() { if ( ast == nullptr ) { @@ -4971,22 +4959,21 @@ Code CodeOperator::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeOperator::is_equal( Code other ) +inline bool CodeOperator::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeOperator::is_valid() +inline bool CodeOperator::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeOperator::set_global() +inline void CodeOperator::set_global() { if ( ast == nullptr ) { @@ -4996,7 +4983,7 @@ void CodeOperator::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeOperator& CodeOperator::operator=( Code other ) +inline CodeOperator& CodeOperator::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5007,32 +4994,32 @@ CodeOperator& CodeOperator::operator=( Code other ) return *this; } -bool CodeOperator::operator==( Code other ) +inline bool CodeOperator::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeOperator::operator!=( Code other ) +inline bool CodeOperator::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeOperator::operator bool() +inline CodeOperator::operator bool() { return ast != nullptr; } -AST* CodeOperator::raw() +inline AST* CodeOperator::raw() { return rcast( AST*, ast ); } -CodeOperator::operator Code() +inline CodeOperator::operator Code() { return *rcast( Code*, this ); } -AST_Operator* CodeOperator::operator->() +inline AST_Operator* CodeOperator::operator->() { if ( ast == nullptr ) { @@ -5042,14 +5029,14 @@ AST_Operator* CodeOperator::operator->() return ast; } -char const* CodeOpCast::debug_str() +inline char const* CodeOpCast::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeOpCast::duplicate() +inline Code CodeOpCast::duplicate() { if ( ast == nullptr ) { @@ -5059,22 +5046,21 @@ Code CodeOpCast::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeOpCast::is_equal( Code other ) +inline bool CodeOpCast::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeOpCast::is_valid() +inline bool CodeOpCast::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeOpCast::set_global() +inline void CodeOpCast::set_global() { if ( ast == nullptr ) { @@ -5084,7 +5070,7 @@ void CodeOpCast::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeOpCast& CodeOpCast::operator=( Code other ) +inline CodeOpCast& CodeOpCast::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5095,32 +5081,32 @@ CodeOpCast& CodeOpCast::operator=( Code other ) return *this; } -bool CodeOpCast::operator==( Code other ) +inline bool CodeOpCast::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeOpCast::operator!=( Code other ) +inline bool CodeOpCast::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeOpCast::operator bool() +inline CodeOpCast::operator bool() { return ast != nullptr; } -AST* CodeOpCast::raw() +inline AST* CodeOpCast::raw() { return rcast( AST*, ast ); } -CodeOpCast::operator Code() +inline CodeOpCast::operator Code() { return *rcast( Code*, this ); } -AST_OpCast* CodeOpCast::operator->() +inline AST_OpCast* CodeOpCast::operator->() { if ( ast == nullptr ) { @@ -5130,14 +5116,14 @@ AST_OpCast* CodeOpCast::operator->() return ast; } -char const* CodeParam::debug_str() +inline char const* CodeParam::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeParam::duplicate() +inline Code CodeParam::duplicate() { if ( ast == nullptr ) { @@ -5147,25 +5133,21 @@ Code CodeParam::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeParam::is_equal( Code other ) +inline bool CodeParam::is_equal( Code other ) { - if ( ast == nullptr && other.ast == nullptr) - return true; - if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeParam::is_valid() +inline bool CodeParam::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeParam::set_global() +inline void CodeParam::set_global() { if ( ast == nullptr ) { @@ -5175,7 +5157,7 @@ void CodeParam::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeParam& CodeParam::operator=( Code other ) +inline CodeParam& CodeParam::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5186,29 +5168,29 @@ CodeParam& CodeParam::operator=( Code other ) return *this; } -bool CodeParam::operator==( Code other ) +inline bool CodeParam::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeParam::operator!=( Code other ) +inline bool CodeParam::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeParam::operator bool() +inline CodeParam::operator bool() { return ast != nullptr; } -char const* CodePragma::debug_str() +inline char const* CodePragma::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodePragma::duplicate() +inline Code CodePragma::duplicate() { if ( ast == nullptr ) { @@ -5218,22 +5200,21 @@ Code CodePragma::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodePragma::is_equal( Code other ) +inline bool CodePragma::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodePragma::is_valid() +inline bool CodePragma::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodePragma::set_global() +inline void CodePragma::set_global() { if ( ast == nullptr ) { @@ -5243,7 +5224,7 @@ void CodePragma::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodePragma& CodePragma::operator=( Code other ) +inline CodePragma& CodePragma::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5254,32 +5235,32 @@ CodePragma& CodePragma::operator=( Code other ) return *this; } -bool CodePragma::operator==( Code other ) +inline bool CodePragma::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodePragma::operator!=( Code other ) +inline bool CodePragma::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodePragma::operator bool() +inline CodePragma::operator bool() { return ast != nullptr; } -AST* CodePragma::raw() +inline AST* CodePragma::raw() { return rcast( AST*, ast ); } -CodePragma::operator Code() +inline CodePragma::operator Code() { return *rcast( Code*, this ); } -AST_Pragma* CodePragma::operator->() +inline AST_Pragma* CodePragma::operator->() { if ( ast == nullptr ) { @@ -5289,14 +5270,14 @@ AST_Pragma* CodePragma::operator->() return ast; } -char const* CodePreprocessCond::debug_str() +inline char const* CodePreprocessCond::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodePreprocessCond::duplicate() +inline Code CodePreprocessCond::duplicate() { if ( ast == nullptr ) { @@ -5306,22 +5287,21 @@ Code CodePreprocessCond::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodePreprocessCond::is_equal( Code other ) +inline bool CodePreprocessCond::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodePreprocessCond::is_valid() +inline bool CodePreprocessCond::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodePreprocessCond::set_global() +inline void CodePreprocessCond::set_global() { if ( ast == nullptr ) { @@ -5331,7 +5311,7 @@ void CodePreprocessCond::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodePreprocessCond& CodePreprocessCond::operator=( Code other ) +inline CodePreprocessCond& CodePreprocessCond::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5342,32 +5322,32 @@ CodePreprocessCond& CodePreprocessCond::operator=( Code other ) return *this; } -bool CodePreprocessCond::operator==( Code other ) +inline bool CodePreprocessCond::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodePreprocessCond::operator!=( Code other ) +inline bool CodePreprocessCond::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodePreprocessCond::operator bool() +inline CodePreprocessCond::operator bool() { return ast != nullptr; } -AST* CodePreprocessCond::raw() +inline AST* CodePreprocessCond::raw() { return rcast( AST*, ast ); } -CodePreprocessCond::operator Code() +inline CodePreprocessCond::operator Code() { return *rcast( Code*, this ); } -AST_PreprocessCond* CodePreprocessCond::operator->() +inline AST_PreprocessCond* CodePreprocessCond::operator->() { if ( ast == nullptr ) { @@ -5377,14 +5357,14 @@ AST_PreprocessCond* CodePreprocessCond::operator->() return ast; } -char const* CodeSpecifiers::debug_str() +inline char const* CodeSpecifiers::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeSpecifiers::duplicate() +inline Code CodeSpecifiers::duplicate() { if ( ast == nullptr ) { @@ -5394,22 +5374,21 @@ Code CodeSpecifiers::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeSpecifiers::is_equal( Code other ) +inline bool CodeSpecifiers::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeSpecifiers::is_valid() +inline bool CodeSpecifiers::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeSpecifiers::set_global() +inline void CodeSpecifiers::set_global() { if ( ast == nullptr ) { @@ -5419,7 +5398,7 @@ void CodeSpecifiers::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeSpecifiers& CodeSpecifiers::operator=( Code other ) +inline CodeSpecifiers& CodeSpecifiers::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5430,29 +5409,29 @@ CodeSpecifiers& CodeSpecifiers::operator=( Code other ) return *this; } -bool CodeSpecifiers::operator==( Code other ) +inline bool CodeSpecifiers::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeSpecifiers::operator!=( Code other ) +inline bool CodeSpecifiers::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeSpecifiers::operator bool() +inline CodeSpecifiers::operator bool() { return ast != nullptr; } -char const* CodeStruct::debug_str() +inline char const* CodeStruct::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeStruct::duplicate() +inline Code CodeStruct::duplicate() { if ( ast == nullptr ) { @@ -5462,22 +5441,21 @@ Code CodeStruct::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeStruct::is_equal( Code other ) +inline bool CodeStruct::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeStruct::is_valid() +inline bool CodeStruct::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeStruct::set_global() +inline void CodeStruct::set_global() { if ( ast == nullptr ) { @@ -5487,7 +5465,7 @@ void CodeStruct::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeStruct& CodeStruct::operator=( Code other ) +inline CodeStruct& CodeStruct::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5498,29 +5476,29 @@ CodeStruct& CodeStruct::operator=( Code other ) return *this; } -bool CodeStruct::operator==( Code other ) +inline bool CodeStruct::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeStruct::operator!=( Code other ) +inline bool CodeStruct::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeStruct::operator bool() +inline CodeStruct::operator bool() { return ast != nullptr; } -char const* CodeTemplate::debug_str() +inline char const* CodeTemplate::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeTemplate::duplicate() +inline Code CodeTemplate::duplicate() { if ( ast == nullptr ) { @@ -5530,22 +5508,21 @@ Code CodeTemplate::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeTemplate::is_equal( Code other ) +inline bool CodeTemplate::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeTemplate::is_valid() +inline bool CodeTemplate::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeTemplate::set_global() +inline void CodeTemplate::set_global() { if ( ast == nullptr ) { @@ -5555,7 +5532,7 @@ void CodeTemplate::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeTemplate& CodeTemplate::operator=( Code other ) +inline CodeTemplate& CodeTemplate::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5566,32 +5543,32 @@ CodeTemplate& CodeTemplate::operator=( Code other ) return *this; } -bool CodeTemplate::operator==( Code other ) +inline bool CodeTemplate::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeTemplate::operator!=( Code other ) +inline bool CodeTemplate::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeTemplate::operator bool() +inline CodeTemplate::operator bool() { return ast != nullptr; } -AST* CodeTemplate::raw() +inline AST* CodeTemplate::raw() { return rcast( AST*, ast ); } -CodeTemplate::operator Code() +inline CodeTemplate::operator Code() { return *rcast( Code*, this ); } -AST_Template* CodeTemplate::operator->() +inline AST_Template* CodeTemplate::operator->() { if ( ast == nullptr ) { @@ -5601,14 +5578,14 @@ AST_Template* CodeTemplate::operator->() return ast; } -char const* CodeType::debug_str() +inline char const* CodeType::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeType::duplicate() +inline Code CodeType::duplicate() { if ( ast == nullptr ) { @@ -5618,22 +5595,21 @@ Code CodeType::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeType::is_equal( Code other ) +inline bool CodeType::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeType::is_valid() +inline bool CodeType::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeType::set_global() +inline void CodeType::set_global() { if ( ast == nullptr ) { @@ -5643,7 +5619,7 @@ void CodeType::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeType& CodeType::operator=( Code other ) +inline CodeType& CodeType::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5654,32 +5630,32 @@ CodeType& CodeType::operator=( Code other ) return *this; } -bool CodeType::operator==( Code other ) +inline bool CodeType::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeType::operator!=( Code other ) +inline bool CodeType::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeType::operator bool() +inline CodeType::operator bool() { return ast != nullptr; } -AST* CodeType::raw() +inline AST* CodeType::raw() { return rcast( AST*, ast ); } -CodeType::operator Code() +inline CodeType::operator Code() { return *rcast( Code*, this ); } -AST_Type* CodeType::operator->() +inline AST_Type* CodeType::operator->() { if ( ast == nullptr ) { @@ -5689,14 +5665,14 @@ AST_Type* CodeType::operator->() return ast; } -char const* CodeTypedef::debug_str() +inline char const* CodeTypedef::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeTypedef::duplicate() +inline Code CodeTypedef::duplicate() { if ( ast == nullptr ) { @@ -5706,22 +5682,21 @@ Code CodeTypedef::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeTypedef::is_equal( Code other ) +inline bool CodeTypedef::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeTypedef::is_valid() +inline bool CodeTypedef::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeTypedef::set_global() +inline void CodeTypedef::set_global() { if ( ast == nullptr ) { @@ -5731,7 +5706,7 @@ void CodeTypedef::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeTypedef& CodeTypedef::operator=( Code other ) +inline CodeTypedef& CodeTypedef::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5742,32 +5717,32 @@ CodeTypedef& CodeTypedef::operator=( Code other ) return *this; } -bool CodeTypedef::operator==( Code other ) +inline bool CodeTypedef::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeTypedef::operator!=( Code other ) +inline bool CodeTypedef::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeTypedef::operator bool() +inline CodeTypedef::operator bool() { return ast != nullptr; } -AST* CodeTypedef::raw() +inline AST* CodeTypedef::raw() { return rcast( AST*, ast ); } -CodeTypedef::operator Code() +inline CodeTypedef::operator Code() { return *rcast( Code*, this ); } -AST_Typedef* CodeTypedef::operator->() +inline AST_Typedef* CodeTypedef::operator->() { if ( ast == nullptr ) { @@ -5777,14 +5752,14 @@ AST_Typedef* CodeTypedef::operator->() return ast; } -char const* CodeUnion::debug_str() +inline char const* CodeUnion::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeUnion::duplicate() +inline Code CodeUnion::duplicate() { if ( ast == nullptr ) { @@ -5794,22 +5769,21 @@ Code CodeUnion::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeUnion::is_equal( Code other ) +inline bool CodeUnion::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeUnion::is_valid() +inline bool CodeUnion::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeUnion::set_global() +inline void CodeUnion::set_global() { if ( ast == nullptr ) { @@ -5819,7 +5793,7 @@ void CodeUnion::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeUnion& CodeUnion::operator=( Code other ) +inline CodeUnion& CodeUnion::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5830,32 +5804,32 @@ CodeUnion& CodeUnion::operator=( Code other ) return *this; } -bool CodeUnion::operator==( Code other ) +inline bool CodeUnion::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeUnion::operator!=( Code other ) +inline bool CodeUnion::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeUnion::operator bool() +inline CodeUnion::operator bool() { return ast != nullptr; } -AST* CodeUnion::raw() +inline AST* CodeUnion::raw() { return rcast( AST*, ast ); } -CodeUnion::operator Code() +inline CodeUnion::operator Code() { return *rcast( Code*, this ); } -AST_Union* CodeUnion::operator->() +inline AST_Union* CodeUnion::operator->() { if ( ast == nullptr ) { @@ -5865,14 +5839,14 @@ AST_Union* CodeUnion::operator->() return ast; } -char const* CodeUsing::debug_str() +inline char const* CodeUsing::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeUsing::duplicate() +inline Code CodeUsing::duplicate() { if ( ast == nullptr ) { @@ -5882,22 +5856,21 @@ Code CodeUsing::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeUsing::is_equal( Code other ) +inline bool CodeUsing::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeUsing::is_valid() +inline bool CodeUsing::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeUsing::set_global() +inline void CodeUsing::set_global() { if ( ast == nullptr ) { @@ -5907,7 +5880,7 @@ void CodeUsing::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeUsing& CodeUsing::operator=( Code other ) +inline CodeUsing& CodeUsing::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -5918,32 +5891,32 @@ CodeUsing& CodeUsing::operator=( Code other ) return *this; } -bool CodeUsing::operator==( Code other ) +inline bool CodeUsing::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeUsing::operator!=( Code other ) +inline bool CodeUsing::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeUsing::operator bool() +inline CodeUsing::operator bool() { return ast != nullptr; } -AST* CodeUsing::raw() +inline AST* CodeUsing::raw() { return rcast( AST*, ast ); } -CodeUsing::operator Code() +inline CodeUsing::operator Code() { return *rcast( Code*, this ); } -AST_Using* CodeUsing::operator->() +inline AST_Using* CodeUsing::operator->() { if ( ast == nullptr ) { @@ -5953,14 +5926,14 @@ AST_Using* CodeUsing::operator->() return ast; } -char const* CodeVar::debug_str() +inline char const* CodeVar::debug_str() { if ( ast == nullptr ) return "Code::debug_str: AST is null!"; return rcast( AST*, ast )->debug_str(); } -Code CodeVar::duplicate() +inline Code CodeVar::duplicate() { if ( ast == nullptr ) { @@ -5970,22 +5943,21 @@ Code CodeVar::duplicate() return { rcast( AST*, ast )->duplicate() }; } -bool CodeVar::is_equal( Code other ) +inline bool CodeVar::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { - log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); - return false; + return ast == nullptr && other.ast == nullptr; } return rcast( AST*, ast )->is_equal( other.ast ); } -bool CodeVar::is_valid() +inline bool CodeVar::is_valid() { return (AST*)ast != nullptr && rcast( AST*, ast )->Type != CodeT::Invalid; } -void CodeVar::set_global() +inline void CodeVar::set_global() { if ( ast == nullptr ) { @@ -5995,7 +5967,7 @@ void CodeVar::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -CodeVar& CodeVar::operator=( Code other ) +inline CodeVar& CodeVar::operator=( Code other ) { if ( other.ast && other->Parent ) { @@ -6006,32 +5978,32 @@ CodeVar& CodeVar::operator=( Code other ) return *this; } -bool CodeVar::operator==( Code other ) +inline bool CodeVar::operator==( Code other ) { return (AST*)ast == other.ast; } -bool CodeVar::operator!=( Code other ) +inline bool CodeVar::operator!=( Code other ) { return (AST*)ast != other.ast; } -CodeVar::operator bool() +inline CodeVar::operator bool() { return ast != nullptr; } -AST* CodeVar::raw() +inline AST* CodeVar::raw() { return rcast( AST*, ast ); } -CodeVar::operator Code() +inline CodeVar::operator Code() { return *rcast( Code*, this ); } -AST_Var* CodeVar::operator->() +inline AST_Var* CodeVar::operator->() { if ( ast == nullptr ) { @@ -6045,282 +6017,282 @@ AST_Var* CodeVar::operator->() #pragma region generated AST/Code cast implementation -AST::operator CodeBody() +inline AST::operator CodeBody() { return { rcast( AST_Body*, this ) }; } -Code::operator CodeBody() const +inline Code::operator CodeBody() const { return { (AST_Body*)ast }; } -AST::operator CodeAttributes() +inline AST::operator CodeAttributes() { return { rcast( AST_Attributes*, this ) }; } -Code::operator CodeAttributes() const +inline Code::operator CodeAttributes() const { return { (AST_Attributes*)ast }; } -AST::operator CodeComment() +inline AST::operator CodeComment() { return { rcast( AST_Comment*, this ) }; } -Code::operator CodeComment() const +inline Code::operator CodeComment() const { return { (AST_Comment*)ast }; } -AST::operator CodeConstructor() +inline AST::operator CodeConstructor() { return { rcast( AST_Constructor*, this ) }; } -Code::operator CodeConstructor() const +inline Code::operator CodeConstructor() const { return { (AST_Constructor*)ast }; } -AST::operator CodeClass() +inline AST::operator CodeClass() { return { rcast( AST_Class*, this ) }; } -Code::operator CodeClass() const +inline Code::operator CodeClass() const { return { (AST_Class*)ast }; } -AST::operator CodeDefine() +inline AST::operator CodeDefine() { return { rcast( AST_Define*, this ) }; } -Code::operator CodeDefine() const +inline Code::operator CodeDefine() const { return { (AST_Define*)ast }; } -AST::operator CodeDestructor() +inline AST::operator CodeDestructor() { return { rcast( AST_Destructor*, this ) }; } -Code::operator CodeDestructor() const +inline Code::operator CodeDestructor() const { return { (AST_Destructor*)ast }; } -AST::operator CodeEnum() +inline AST::operator CodeEnum() { return { rcast( AST_Enum*, this ) }; } -Code::operator CodeEnum() const +inline Code::operator CodeEnum() const { return { (AST_Enum*)ast }; } -AST::operator CodeExec() +inline AST::operator CodeExec() { return { rcast( AST_Exec*, this ) }; } -Code::operator CodeExec() const +inline Code::operator CodeExec() const { return { (AST_Exec*)ast }; } -AST::operator CodeExtern() +inline AST::operator CodeExtern() { return { rcast( AST_Extern*, this ) }; } -Code::operator CodeExtern() const +inline Code::operator CodeExtern() const { return { (AST_Extern*)ast }; } -AST::operator CodeFriend() +inline AST::operator CodeFriend() { return { rcast( AST_Friend*, this ) }; } -Code::operator CodeFriend() const +inline Code::operator CodeFriend() const { return { (AST_Friend*)ast }; } -AST::operator CodeFn() +inline AST::operator CodeFn() { return { rcast( AST_Fn*, this ) }; } -Code::operator CodeFn() const +inline Code::operator CodeFn() const { return { (AST_Fn*)ast }; } -AST::operator CodeInclude() +inline AST::operator CodeInclude() { return { rcast( AST_Include*, this ) }; } -Code::operator CodeInclude() const +inline Code::operator CodeInclude() const { return { (AST_Include*)ast }; } -AST::operator CodeModule() +inline AST::operator CodeModule() { return { rcast( AST_Module*, this ) }; } -Code::operator CodeModule() const +inline Code::operator CodeModule() const { return { (AST_Module*)ast }; } -AST::operator CodeNS() +inline AST::operator CodeNS() { return { rcast( AST_NS*, this ) }; } -Code::operator CodeNS() const +inline Code::operator CodeNS() const { return { (AST_NS*)ast }; } -AST::operator CodeOperator() +inline AST::operator CodeOperator() { return { rcast( AST_Operator*, this ) }; } -Code::operator CodeOperator() const +inline Code::operator CodeOperator() const { return { (AST_Operator*)ast }; } -AST::operator CodeOpCast() +inline AST::operator CodeOpCast() { return { rcast( AST_OpCast*, this ) }; } -Code::operator CodeOpCast() const +inline Code::operator CodeOpCast() const { return { (AST_OpCast*)ast }; } -AST::operator CodeParam() +inline AST::operator CodeParam() { return { rcast( AST_Param*, this ) }; } -Code::operator CodeParam() const +inline Code::operator CodeParam() const { return { (AST_Param*)ast }; } -AST::operator CodePragma() +inline AST::operator CodePragma() { return { rcast( AST_Pragma*, this ) }; } -Code::operator CodePragma() const +inline Code::operator CodePragma() const { return { (AST_Pragma*)ast }; } -AST::operator CodePreprocessCond() +inline AST::operator CodePreprocessCond() { return { rcast( AST_PreprocessCond*, this ) }; } -Code::operator CodePreprocessCond() const +inline Code::operator CodePreprocessCond() const { return { (AST_PreprocessCond*)ast }; } -AST::operator CodeSpecifiers() +inline AST::operator CodeSpecifiers() { return { rcast( AST_Specifiers*, this ) }; } -Code::operator CodeSpecifiers() const +inline Code::operator CodeSpecifiers() const { return { (AST_Specifiers*)ast }; } -AST::operator CodeStruct() +inline AST::operator CodeStruct() { return { rcast( AST_Struct*, this ) }; } -Code::operator CodeStruct() const +inline Code::operator CodeStruct() const { return { (AST_Struct*)ast }; } -AST::operator CodeTemplate() +inline AST::operator CodeTemplate() { return { rcast( AST_Template*, this ) }; } -Code::operator CodeTemplate() const +inline Code::operator CodeTemplate() const { return { (AST_Template*)ast }; } -AST::operator CodeType() +inline AST::operator CodeType() { return { rcast( AST_Type*, this ) }; } -Code::operator CodeType() const +inline Code::operator CodeType() const { return { (AST_Type*)ast }; } -AST::operator CodeTypedef() +inline AST::operator CodeTypedef() { return { rcast( AST_Typedef*, this ) }; } -Code::operator CodeTypedef() const +inline Code::operator CodeTypedef() const { return { (AST_Typedef*)ast }; } -AST::operator CodeUnion() +inline AST::operator CodeUnion() { return { rcast( AST_Union*, this ) }; } -Code::operator CodeUnion() const +inline Code::operator CodeUnion() const { return { (AST_Union*)ast }; } -AST::operator CodeUsing() +inline AST::operator CodeUsing() { return { rcast( AST_Using*, this ) }; } -Code::operator CodeUsing() const +inline Code::operator CodeUsing() const { return { (AST_Using*)ast }; } -AST::operator CodeVar() +inline AST::operator CodeVar() { return { rcast( AST_Var*, this ) }; } -Code::operator CodeVar() const +inline Code::operator CodeVar() const { return { (AST_Var*)ast }; } @@ -6513,10 +6485,10 @@ extern AllocatorInfo Allocator_TypeTable; #endif GEN_NS_END -#if __clang__ +#ifdef __clang__ #pragma clang diagnostic pop #endif -#if __GNUC__ +#ifdef __GNUC__ #pragma GCC diagnostic pop #endif diff --git a/Project/Source/GasaGen/gen.scanner.cpp b/Project/Source/GasaGen/gen.scanner.cpp index ba068ec..8e64a0c 100644 --- a/Project/Source/GasaGen/gen.scanner.cpp +++ b/Project/Source/GasaGen/gen.scanner.cpp @@ -1,4 +1,23 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" +#pragma clang diagnostic ignored "-Wswitch" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wvarargs" +#pragma clang diagnostic ignored "-Wunused-function" +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wcomment" +#pragma GCC diagnostic ignored "-Wswitch" +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif #include "gen.scanner.hpp" @@ -38,7 +57,7 @@ u8 adt_destroy_branch( ADT_Node* node ) GEN_ASSERT_NOT_NULL( node ); if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes ) { - for ( sw i = 0; i < node->nodes.num(); ++i ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); ++i ) { adt_destroy_branch( node->nodes + i ); } @@ -68,7 +87,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ) return NULL; } - for ( sw i = 0; i < node->nodes.num(); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { if ( ! str_compare( node->nodes[i].name, name ) ) { @@ -78,7 +97,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ) if ( deep_search ) { - for ( sw i = 0; i < node->nodes.num(); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { ADT_Node* res = adt_find( node->nodes + i, name, deep_search ); @@ -134,7 +153,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value ) internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value ) { - for ( sw i = 0; i < node->nodes.num(); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { if ( ! str_compare( node->nodes[i].name, name ) ) { @@ -209,7 +228,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) /* run a value comparison against any child that is an object node */ else if ( node->type == EADT_TYPE_ARRAY ) { - for ( sw i = 0; i < node->nodes.num(); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { ADT_Node* child = &node->nodes[i]; if ( child->type != EADT_TYPE_OBJECT ) @@ -227,7 +246,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) /* [value] */ else { - for ( sw i = 0; i < node->nodes.num(); i++ ) + for ( sw i = 0; i < scast( sw, node->nodes.num() ); i++ ) { ADT_Node* child = &node->nodes[i]; if ( _adt_get_value( child, l_b2 ) ) @@ -259,7 +278,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri ) else { sw idx = (sw)str_to_i64( buf, NULL, 10 ); - if ( idx >= 0 && idx < node->nodes.num() ) + if ( idx >= 0 && idx < scast( sw, node->nodes.num() ) ) { found_node = &node->nodes[idx]; @@ -284,7 +303,7 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, sw index ) if ( ! parent->nodes ) return NULL; - if ( index < 0 || index > parent->nodes.num() ) + if ( index < 0 || index > scast( sw, parent->nodes.num() ) ) return NULL; ADT_Node o = { 0 }; @@ -945,7 +964,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b } } - if ( columnIndex >= root->nodes.num() ) + if ( columnIndex >= scast( sw, root->nodes.num() ) ) { adt_append_arr( root, NULL ); } @@ -987,7 +1006,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b /* consider first row as a header. */ if ( has_header ) { - for ( sw i = 0; i < root->nodes.num(); i++ ) + for ( sw i = 0; i < scast( sw, root->nodes.num() ); i++ ) { CSV_Object* col = root->nodes + i; CSV_Object* hdr = col->nodes; @@ -1107,3 +1126,11 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi #pragma endregion CSV GEN_NS_END + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/Project/Source/GasaGen/gen.scanner.hpp b/Project/Source/GasaGen/gen.scanner.hpp index dc7ebf8..bda531a 100644 --- a/Project/Source/GasaGen/gen.scanner.hpp +++ b/Project/Source/GasaGen/gen.scanner.hpp @@ -1,7 +1,26 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) +// This file was generated automatially by gencpp's unreal.cpp (See: https://github.com/Ed94/gencpp) #pragma once +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-const-variable" +#pragma clang diagnostic ignored "-Wunused-but-set-variable" +#pragma clang diagnostic ignored "-Wswitch" +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wvarargs" +#pragma clang diagnostic ignored "-Wunused-function" +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wcomment" +#pragma GCC diagnostic ignored "-Wswitch" +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif + #include "gen.hpp" GEN_NS_BEGIN @@ -435,7 +454,7 @@ GEN_IMPL_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj ) // This is a simple file reader that reads the entire file into memory. // It has an extra option to skip the first few lines for undesired includes. // This is done so that includes can be kept in dependency and component files so that intellisense works. -Code scan_file( char const* path ) +inline Code scan_file( char const* path ) { FileInfo file; @@ -591,3 +610,11 @@ CodeFile scan_file( char const* path ) } #endif GEN_NS_END + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif