From 9495fc2985e1ecce07ec436e589b11f7cdf07263 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 11 Sep 2023 18:34:37 -0400 Subject: [PATCH 1/5] Updates to documentation --- Readme.md | 14 ++++--- docs/Parsing.md | 1 + docs/Readme.md | 99 +++++++++++++++++++---------------------------- project/Readme.md | 8 ++-- 4 files changed, 53 insertions(+), 69 deletions(-) diff --git a/Readme.md b/Readme.md index 537721f..3c6cc67 100644 --- a/Readme.md +++ b/Readme.md @@ -5,14 +5,18 @@ 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. +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 -The project has reached an *alpha* state, all the current functionality works for the test cases but it will most likely break in many other cases. +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. -A `natvis` and `natstepfilter` are provided in the scripts directory. +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.*** @@ -123,7 +127,7 @@ struct ArrayHeader ``` **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, beaware its pretty slow...)* +*(The library currently uses clang-format for formatting, beware its pretty slow...)* ## Building diff --git a/docs/Parsing.md b/docs/Parsing.md index 198df87..62c84df 100644 --- a/docs/Parsing.md +++ b/docs/Parsing.md @@ -60,6 +60,7 @@ Exceptions: * 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. diff --git a/docs/Readme.md b/docs/Readme.md index 1cb5738..bb9ef04 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -32,7 +32,7 @@ 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. +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. @@ -70,28 +70,36 @@ Data layout of AST struct: 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; // Function, Operator, Type symbol, Variable + AST* Specs; // Destructor, Function, Operator, Typename, Variable union { - AST* InitializerList; // Constructor, Destructor - AST* ParentType; // Class, Struct - AST* ReturnType; // Function, Operator + 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* BitfieldSize; // Varaiable (Class/Struct Data Member) - AST* Params; // Function, Operator, Template + AST* BitfieldSize; // Variable (Class/Struct Data Member) + AST* Params; // Constructor, Function, Operator, Template, Typename }; union { - AST* ArrExpr; // Type Symbol - AST* Body; // Class, Constructr, Destructor, Enum, Function, Namespace, Struct, Union - AST* Declaration; // Friend, Template - AST* Value; // Parameter, Variable + 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 - SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + StringCached Content; // Attributes, Comment, Execution, Include + struct { + SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + AST* NextSpecs; // Specifiers + }; }; union { AST* Prev; @@ -107,11 +115,13 @@ StringCached Name; CodeT Type; ModuleFlag ModuleFlags; union { - b32 IsFunction; // Used by typedef to not serialize the name field. + 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`* @@ -142,6 +152,13 @@ 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. @@ -233,6 +250,7 @@ Interface :`` * def_operator_cast * def_param * def_params +* def_pragma * def_preprocess_cond * def_specifier * def_specifiers @@ -382,8 +400,8 @@ The following are provided predefined by the library as they are commonly used: * `module_global_fragment` * `module_private_fragment` * `fmt_newline` -* `pragma_once` * `param_varaidc` (Used for varadic definitions) +* `pragma_once` * `preprocess_else` * `preprocess_endif` * `spec_const` @@ -392,6 +410,7 @@ The following are provided predefined by the library as they are commonly used: * `spec_constinit` * `spec_extern_linkage` (extern) * `spec_final` +* `spec_forceinline` * `spec_global` (global macro) * `spec_inline` * `spec_internal_linkage` (internal macro) @@ -429,8 +448,8 @@ Optionally the following may be defined if `GEN_DEFINE_LIBRARY_CODE_CONSTANTS` i * `t_u16` * `t_u32` * `t_u64` -* `t_sw` -* `t_uw` +* `t_sw` (ssize_t) +* `t_uw` (size_t) * `t_f32` * `t_f64` @@ -458,50 +477,10 @@ Editor and Scanner are disabled by default, use `GEN_FEATURE_EDITOR` and `GEN_FE ### 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. +* 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. -### Editor is for editing a series of files/asts based on a set of requests provided to it +### Scanner Auxillary Interface -**Note: Not implemented yet** - -* The purpose is to overrite a specific file, it places its contents in a buffer to scan. -* If editing an AST it will generate a new ast as a result (ASTs are not edited). -* Requests are populated using the following interface: - * add : Add code. - * remove : Remove code. - * replace: Replace code. - -All three have the same parameters with exception to remove which only has SymbolInfo and Policy: - -* SymbolInfo: - * File : The file the symbol resides in. Leave null to indicate to search all files. Leave null to indicated all-file search. - * Marker : #define symbol that indicates a location or following signature is valid to manipulate. Leave null to indicate the signature should only be used. - * Signature : Use a Code symbol to find a valid location to manipulate, can be further filtered with the marker. Leave null to indicate the marker should only be used. - -* Policy : Additional policy info for completing the request (empty for now) -* Code : Code to inject if adding, or replace existing code with. - -Additionally if `GEN_FEATURE_EDITOR_REFACTOR` is defined, refactor( file_path, specification_path ) wil be made available. -Refactor is based of the refactor library and uses its interface. -It will on call add a request to the queue to run the refactor script on the file. - -### Scanner allows the user to sift through a series of files/asts based on a set of requests provided to it - -**Note: Not implemented yet** - -* The purpose is to grab definitions to generate metadata or generate new code from these definitions. -* Requests are populated using the add( SymbolInfo, Policy ) function. The symbol info is the same as the one used for the editor. So is the case with Policy. - -The file will only be read from, no writing supported. - -### Additional Info (Editor and Scanner) - -When all requests have been populated, call process_requests(). -It will provide an output of receipt data of the results when it completes. - -Files may be added to the Editor and Scanner additionally with add_files( num, files ). -This is intended for when you have requests that are for multiple files. - -Request queue in both Editor and Scanner are cleared once process_requests completes. +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/Readme.md b/project/Readme.md index d5016b0..0b5e35d 100644 --- a/project/Readme.md +++ b/project/Readme.md @@ -8,8 +8,7 @@ They contain includes for its various components: `components/.< Dependencies are bundled into `gen.dep.`. Just like the `gen.` they include their components: `dependencies/.` -The fle processors are in their own respective files. (Ex: `file_processors/.` ) -They directly include `depedencies/file_handling.` as the core library does not include file processing by defualt. +Code not making up the core library is located in `auxiliary/.`. These are optional extensions or tools for the library. **TODO : Right now the library is not finished, as such the first self-hosting iteration is still WIP** Both libraries use *pre-generated* (self-hosting I guess) version of the library to then generate the latest version of itself. @@ -30,10 +29,11 @@ Feature Macros: * `GEN_ENFORCE_STRONG_CODE_TYPES` : Enforces casts to filtered code types. * `GEN_EXPOSE_BACKEND` : Will expose symbols meant for internal use only. * `GEN_ROLL_OWN_DEPENDENCIES` : Optional override so that user may define the dependencies themselves. +* `GEN_DONT_ALLOW_INVALID_CODE` (Not implemented yet) : Will fail when an invalid code is constructed, parsed, or serialized. ## On multi-threading -Currently unsupported. +Currently unsupported. I want the library to be *stable* and *correct*, with the addition of exhausting all basic single-threaded optimizations before I consider multi-threading. ## Extending the library @@ -51,5 +51,5 @@ Names or Content fields are interned strings and thus showed be cached using `ge `def_operator` is the most sophisticated constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid. The library has its code segmented into component files, use it to help create a derived version without needing to have to rewrite a generated file directly or build on top of the header via composition or inheritance. -When the scanner is implemented, this will be even easier to customize. +The parser is documented under `docs/Parsing.md` and `docs/Parser_Algo.md`. From 4b48b96a79b93434f697e56f768b3c0a92725718 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 11 Sep 2023 23:22:53 -0400 Subject: [PATCH 2/5] WIP : better AST::debug_str() Now its more contexually rich to the ast type, however I need to hookup tokens from parsing to the AST. There needs to be a way for the debug string to lookup the token and provide the contexual line. Can either pass it ( TokArray* toks ) from the parser on failure (or `CodeFile`).. Technically there is more than enough room for another Token* ptr. I could add another and specifiers would still have at minimum 14 slots before needing to extended to next specs. **************... yeah --- Readme.md | 3 +- docs/Parsing.md | 2 +- gencpp.10x | 19 +- gencpp.sln | 41 +++- gencpp.vcxproj | 227 ++++++++++++++---- gencpp.vcxproj.filters | 19 ++ gencpp.vcxproj.user | 23 +- project/auxillary/scanner.hpp | 55 ++--- project/bootstrap.cpp | 1 + project/components/ast.cpp | 292 +++++++++++++++++++++-- project/components/ast.hpp | 20 +- project/components/ast_types.hpp | 59 ++--- project/components/gen/ast_inlines.hpp | 1 + project/components/gen/ecode.hpp | 1 + project/components/gen/eoperator.hpp | 1 + project/components/gen/especifier.hpp | 1 + project/components/header_end.hpp | 1 + project/components/interface.cpp | 1 + project/components/interface.parsing.cpp | 5 +- project/components/interface.upfront.cpp | 4 +- project/components/static_data.cpp | 1 + project/components/types.hpp | 16 +- 22 files changed, 635 insertions(+), 158 deletions(-) diff --git a/Readme.md b/Readme.md index 3c6cc67..d15ac94 100644 --- a/Readme.md +++ b/Readme.md @@ -5,8 +5,7 @@ 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). - +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 diff --git a/docs/Parsing.md b/docs/Parsing.md index 62c84df..39010dd 100644 --- a/docs/Parsing.md +++ b/docs/Parsing.md @@ -2,7 +2,7 @@ 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 5000 loc. +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 5500 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. diff --git a/gencpp.10x b/gencpp.10x index c8d06e3..29874bd 100644 --- a/gencpp.10x +++ b/gencpp.10x @@ -8,21 +8,22 @@ true false false - powershell ./scripts/test.gen_run.ps1 + pwsh ./scripts/build.ps1 msvc debug bootstrap - powershell ./scripts/clean.ps1 + psh ./scripts/clean.ps1 ./test/gen/build/gencpp.exe - powershell ./scripts/build.ps1 + pwsh ./scripts/build.ps1 ./test/gen/build/gencpp.exe - gencpp.sln + false Debug Release + bootstrap debug x64 @@ -41,6 +42,7 @@ GEN_TIME GEN_SYSTEM_WINDOWS + GEN_INTELLISENSE_DIRECTIVES @@ -48,10 +50,19 @@ + + bootstrap debug:x64 + + + Debug + + bootstrap debug + + x64 diff --git a/gencpp.sln b/gencpp.sln index 720de80..ea81492 100644 --- a/gencpp.sln +++ b/gencpp.sln @@ -7,20 +7,37 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gencpp", "gencpp.vcxproj", EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 + bootstrap debug|x64 = bootstrap debug|x64 + bootstrap debug|x86 = bootstrap debug|x86 + bootstrap release|x64 = bootstrap release|x64 + bootstrap release|x86 = bootstrap release|x86 + singleheader debug|x64 = singleheader debug|x64 + singleheader debug|x86 = singleheader debug|x86 + singleheader release|x64 = singleheader release|x64 + singleheader release|x86 = singleheader release|x86 + test debug|x64 = test debug|x64 + test debug|x86 = test debug|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {53AF600D-C09C-4F39-83E0-E022AA9479F2}.Debug|x64.ActiveCfg = Debug|x64 - {53AF600D-C09C-4F39-83E0-E022AA9479F2}.Debug|x64.Build.0 = Debug|x64 - {53AF600D-C09C-4F39-83E0-E022AA9479F2}.Debug|x86.ActiveCfg = Debug|Win32 - {53AF600D-C09C-4F39-83E0-E022AA9479F2}.Debug|x86.Build.0 = Debug|Win32 - {53AF600D-C09C-4F39-83E0-E022AA9479F2}.Release|x64.ActiveCfg = Release|x64 - {53AF600D-C09C-4F39-83E0-E022AA9479F2}.Release|x64.Build.0 = Release|x64 - {53AF600D-C09C-4F39-83E0-E022AA9479F2}.Release|x86.ActiveCfg = Release|Win32 - {53AF600D-C09C-4F39-83E0-E022AA9479F2}.Release|x86.Build.0 = Release|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap debug|x64.ActiveCfg = bootstrap release|x64 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap debug|x64.Build.0 = bootstrap release|x64 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap debug|x86.ActiveCfg = bootstrap debug|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap debug|x86.Build.0 = bootstrap debug|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap release|x64.ActiveCfg = bootstrap release|x64 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap release|x86.ActiveCfg = bootstrap release|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.bootstrap release|x86.Build.0 = bootstrap release|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader debug|x64.ActiveCfg = singleheader debug|x64 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader debug|x64.Build.0 = singleheader debug|x64 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader debug|x86.ActiveCfg = singleheader debug|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader debug|x86.Build.0 = singleheader debug|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader release|x64.ActiveCfg = bootstrap debug|x64 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader release|x64.Build.0 = bootstrap debug|x64 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader release|x86.ActiveCfg = singleheader release|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.singleheader release|x86.Build.0 = singleheader release|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.test debug|x64.ActiveCfg = test debug|x64 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.test debug|x64.Build.0 = test debug|x64 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.test debug|x86.ActiveCfg = test debug|Win32 + {53AF600D-C09C-4F39-83E0-E022AA9479F2}.test debug|x86.Build.0 = test debug|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/gencpp.vcxproj b/gencpp.vcxproj index 957f357..33bde5a 100644 --- a/gencpp.vcxproj +++ b/gencpp.vcxproj @@ -1,20 +1,44 @@ - - Debug + + bootstrap debug Win32 - - Release - Win32 - - - Debug + + bootstrap debug x64 - - Release + + bootstrap release + Win32 + + + bootstrap release + x64 + + + singleheader debug + Win32 + + + singleheader debug + x64 + + + singleheader release + Win32 + + + singleheader release + x64 + + + test debug + Win32 + + + test debug x64 @@ -25,24 +49,54 @@ 10.0 - + Makefile true v143 - - Makefile - false - v143 - - + Makefile true v143 - + Makefile - false + true + v143 + + + Makefile + true + v143 + + + Makefile + true + v143 + + + Makefile + true + v143 + + + Makefile + true + v143 + + + Makefile + true + v143 + + + Makefile + true + v143 + + + Makefile + true v143 @@ -50,48 +104,132 @@ - + - + - + - + + + + + + + + + + + + + + + + + + + - + ./scripts/build.ps1 ./scripts/clean.ps1 ./scripts/build.ps1 WIN32;_DEBUG;$(NMakePreprocessorDefinitions) - + ./scripts/build.ps1 ./scripts/clean.ps1 ./scripts/build.ps1 - WIN32;NDEBUG;$(NMakePreprocessorDefinitions) + WIN32;_DEBUG;$(NMakePreprocessorDefinitions) - - powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" - powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" - powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" - GEN_TIME;$(NMakePreprocessorDefinitions) - $(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath) - $(ProjectDir)project;$(ProjectDir)test;$(SourcePath) + + ./scripts/build.ps1 + ./scripts/clean.ps1 + ./scripts/build.ps1 + WIN32;_DEBUG;$(NMakePreprocessorDefinitions) - - powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" - powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" - powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" - GEN_TIME;$(NMakePreprocessorDefinitions) - $(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath) - $(ProjectDir)project;$(ProjectDir)test;$(SourcePath) + + ./scripts/build.ps1 + ./scripts/clean.ps1 + ./scripts/build.ps1 + WIN32;_DEBUG;$(NMakePreprocessorDefinitions) - + + ./scripts/build.ps1 + ./scripts/clean.ps1 + ./scripts/build.ps1 + WIN32;_DEBUG;$(NMakePreprocessorDefinitions) + + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug bootstrap + + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) + $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) + $(ProjectDir)project;$(SourcePath) + + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug test + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) + $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) + $(ProjectDir)project;$(SourcePath) + + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug singleheader + + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) + $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) + $(ProjectDir)project;$(SourcePath) + + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc release singleheader + + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) + $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) + $(ProjectDir)project;$(SourcePath) + + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc release bootstrap + + + pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) + $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) + $(ProjectDir)project;$(SourcePath) + + + + stdc11 + + + + + stdc11 + + + + + stdc11 + + + + + stdc11 + + + stdc11 @@ -105,6 +243,7 @@ + @@ -124,6 +263,10 @@ + + + + @@ -153,6 +296,7 @@ + @@ -174,6 +318,7 @@ + diff --git a/gencpp.vcxproj.filters b/gencpp.vcxproj.filters index cd9c640..7c5e189 100644 --- a/gencpp.vcxproj.filters +++ b/gencpp.vcxproj.filters @@ -129,6 +129,9 @@ Source Files + + Source Files + @@ -275,6 +278,21 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + @@ -297,6 +315,7 @@ + diff --git a/gencpp.vcxproj.user b/gencpp.vcxproj.user index 568a826..4b348cc 100644 --- a/gencpp.vcxproj.user +++ b/gencpp.vcxproj.user @@ -3,14 +3,29 @@ true - + false WindowsLocalDebugger - C:\projects\gencpp\test\gen\build\gencpp.exe + $(ProjectDir)project\build\bootstrap.exe - + false WindowsLocalDebugger - C:\projects\gencpp\test\gen\build\gencpp.exe + $(ProjectDir)project\build\bootstrap.exe + + + false + WindowsLocalDebugger + $(ProjectDir)project\build\bootstrap.exe + + + false + WindowsLocalDebugger + $(ProjectDir)project\build\bootstrap.exe + + + false + WindowsLocalDebugger + $(ProjectDir)project\build\bootstrap.exe \ No newline at end of file diff --git a/project/auxillary/scanner.hpp b/project/auxillary/scanner.hpp index 6b6b435..242ff51 100644 --- a/project/auxillary/scanner.hpp +++ b/project/auxillary/scanner.hpp @@ -120,45 +120,40 @@ Code scan_file( char const* path ) } #if 0 -struct Policy +struct CodeFile { - // Nothing for now. + using namespace Parser; + + String FilePath; + TokArray Tokens; + Array ParseFailures; + Code CodeRoot; }; -struct SymbolInfo +namespace Parser { - StringCached File; - char const* Marker; - Code Signature; -}; - -struct Scanner -{ - struct RequestEntry + struct ParseFailure { - SymbolInfo Info; + String Reason; + Code Node; }; +} - struct Receipt - { - StringCached File; - Code Defintion; - bool Result; - }; +CodeFile scan_file( char const* path ) +{ + using namespace Parser; - AllocatorInfo MemAlloc; + CodeFile + result = {}; + result.FilePath = String::make( GlobalAllocator, path ); - static void set_allocator( AllocatorInfo allocator ); + Code code = scan_file( path ); + result.CodeRoot = code; - Array Files; - String Buffer; - Array Requests; + ParseContext context = parser_get_last_context(); + result.Tokens = context.Tokens; + result.ParseFailures = context.Failures; - void add_files( s32 num, char const** files ); - - void add( SymbolInfo signature, Policy policy ); - - bool process_requests( Array out_receipts ); -}; + return result; +} #endif - diff --git a/project/bootstrap.cpp b/project/bootstrap.cpp index 6e661ed..facf3c9 100644 --- a/project/bootstrap.cpp +++ b/project/bootstrap.cpp @@ -148,6 +148,7 @@ int gen_main() CodeBody gen_component_header = def_global_body( args( def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ), pragma_once, + def_include(txt("types.hpp")), preprocess_endif, fmt_newline, untyped_str( to_str(generation_notice) ) diff --git a/project/components/ast.cpp b/project/components/ast.cpp index 837da3f..11f8fc9 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -6,32 +6,276 @@ Code Code::Global; Code Code::Invalid; +// This serializes all the data-members in a "debug" format, where each member is printed with its associated value. char const* AST::debug_str() { + String result = String::make_reserve( GlobalAllocator, kilobytes(1) ); + +#if 1 if ( Parent ) + result.append_fmt( "\n\tParent : %S %S", Parent->type_str(), Name ? Name : "" ); + else + result.append_fmt( "\n\tParent : %S", "Null" ); + + result.append_fmt( "\n\tName : %S", Name ? Name : "Null" ); + result.append_fmt( "\n\tType : %S", type_str() ); + result.append_fmt( "\n\tModule Flags : %S", to_str( ModuleFlags ) ); + result.append_fmt( "\n\tToken : %d", Token ); + + switch ( Type ) { - String - result = String::make_reserve( GlobalAllocator, kilobytes(1) ); - result.append_fmt( - "\n\tType : %s" - "\n\tParent : %s %s" - "\n\tName : %s" - , type_str() - , Parent->type_str() - , Parent->Name, Name ? Name : "" - ); + using namespace ECode; - return result; + case Invalid: + case NewLine: + case Access_Private: + case Access_Protected: + case Access_Public: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + break; + + case Untyped: + case Execution: + case Comment: + case PlatformAttributes: + case Preprocess_Define: + case Preprocess_Include: + case Preprocess_Pragma: + case Preprocess_If: + case Preprocess_ElIf: + case Preprocess_Else: + case Preprocess_IfDef: + case Preprocess_IfNotDef: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tContent: %S", Content ); + break; + + case Class: + case Struct: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" ); + result.append_fmt( "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" ); + result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + break; + + case Constructor: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" ); + result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + break; + + case Destructor: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + break; + + case Enum: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); + result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + break; + + case Extern_Linkage: + case Namespace: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tBody: %S", Body ? Body->debug_str() : "Null" ); + break; + + case Friend: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" ); + break; + + case Function: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); + result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + break; + + case Module: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + break; + + case Operator: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); + result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + result.append_fmt( "\n\tOp : %S", to_str( Op ) ); + break; + + case Operator_Cast: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); + result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + break; + + case Parameters: + result.append_fmt( "\n\tNumEntries: %d", NumEntries ); + result.append_fmt( "\n\tLast : %S", Last->Name ); + result.append_fmt( "\n\tNext : %S", Next->Name ); + result.append_fmt( "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); + result.append_fmt( "\n\tValue : %S", Value ? Value->to_string() : "Null" ); + break; + + case Specifiers: + { + result.append_fmt( "\n\tNumEntries: %d", NumEntries ); + result.append( "\n\tArrSpecs: " ); + + s32 idx = 0; + s32 left = NumEntries; + while ( left-- ) + { + StrC spec = ESpecifier::to_str( ArrSpecs[idx] ); + result.append_fmt( "%.*s, ", spec.Len, spec.Ptr ); + idx++; + } + result.append_fmt( "\n\tNextSpecs: %S", NextSpecs ? NextSpecs->debug_str() : "Null" ); + } + break; + + case Template: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + result.append_fmt( "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" ); + break; + + case Typedef: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); + break; + + case Typename: + result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tReturnType : %S", ReturnType ? ReturnType->to_string() : "Null" ); + result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + result.append_fmt( "\n\tArrExpr : %S", ArrExpr ? ArrExpr->to_string() : "Null" ); + break; + + case Union: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); + break; + + case Using: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); + break; + + case Variable: + + if ( Parent && Parent->Type == Variable ) + { + // Its a NextVar + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tValue : %S", Value ? Value->to_string() : "Null" ); + result.append_fmt( "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" ); + result.append_fmt( "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" ); + break; + } + + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); + result.append_fmt( "\n\tBitfieldSize: %S", BitfieldSize ? BitfieldSize->to_string() : "Null" ); + result.append_fmt( "\n\tValue : %S", Value ? Value->to_string() : "Null" ); + result.append_fmt( "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" ); + break; } - - String - result = String::make_reserve( GlobalAllocator, kilobytes(1) ); - result.append_fmt( - "\n\tType : %s" - "\n\tName : %s" - , type_str() - , Name ? Name : "" - ); +#endif return result; } @@ -61,7 +305,11 @@ String AST::to_string() using namespace ECode; case Invalid: + #ifdef GEN_DONT_ALLOW_INVALID_CODE log_failure("Attempted to serialize invalid code! - %S", Parent ? Parent->debug_str() : Name ); + #else + result.append_fmt( "Invalid Code!" ); + #endif break; case NewLine: @@ -71,6 +319,7 @@ String AST::to_string() case Untyped: case Execution: case Comment: + case PlatformAttributes: result.append( Content ); break; @@ -80,9 +329,6 @@ String AST::to_string() result.append( Name ); break; - case PlatformAttributes: - result.append( Content ); - case Class: { if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) diff --git a/project/components/ast.hpp b/project/components/ast.hpp index c1468ba..9169404 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -41,10 +41,10 @@ struct CodeBody; // These are to offer ease of use and optionally strong type safety for the AST. struct CodeAttributes; struct CodeComment; -struct CodeConstructor; -struct CodeDestructor; struct CodeClass; +struct CodeConstructor; struct CodeDefine; +struct CodeDestructor; struct CodeEnum; struct CodeExec; struct CodeExtern; @@ -217,14 +217,14 @@ struct AST uw ArrSpecs_Cap = ( AST_POD_Size - - sizeof(AST*) * 3 + - sizeof(AST*) * 4 - sizeof(StringCached) - sizeof(CodeT) - sizeof(ModuleFlag) - sizeof(u32) - sizeof(s32) ) - / sizeof(SpecifierT) - 1; // -1 for 4 extra bytes + / sizeof(SpecifierT); // -1 for 4 extra bytes union { struct @@ -255,7 +255,10 @@ struct AST }; }; StringCached Content; // Attributes, Comment, Execution, Include - SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + struct { + SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + AST* NextSpecs; // Specifiers + }; }; union { AST* Prev; @@ -310,8 +313,11 @@ struct AST_POD AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. }; }; - StringCached Content; // Attributes, Comment, Execution, Include - SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + StringCached Content; // Attributes, Comment, Execution, Include + struct { + SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + AST* NextSpecs; // Specifiers + }; }; union { AST* Prev; diff --git a/project/components/ast_types.hpp b/project/components/ast_types.hpp index 03ed5d0..228e429 100644 --- a/project/components/ast_types.hpp +++ b/project/components/ast_types.hpp @@ -12,7 +12,7 @@ struct AST_Body { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; Code Front; Code Back; Code Parent; @@ -27,7 +27,7 @@ static_assert( sizeof(AST_Body) == sizeof(AST), "ERROR: AST_Filtered is not the struct AST_Attributes { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; StringCached Content; }; Code Prev; @@ -43,7 +43,7 @@ static_assert( sizeof(AST_Attributes) == sizeof(AST), "ERROR: AST_Attributes is struct AST_Comment { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; StringCached Content; }; Code Prev; @@ -59,7 +59,7 @@ static_assert( sizeof(AST_Comment) == sizeof(AST), "ERROR: AST_Comment is not th struct AST_Class { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; // Only supported by forward declarations @@ -71,7 +71,7 @@ struct AST_Class char _PAD_PROPERTIES_2_[ sizeof(AST*) ]; }; }; - CodeType Last; + CodeType Prev; CodeType Next; Code Parent; StringCached Name; @@ -85,7 +85,7 @@ static_assert( sizeof(AST_Class) == sizeof(AST), "ERROR: AST_Class is not the sa struct AST_Constructor { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; // Only supported by forward declarations @@ -110,7 +110,7 @@ static_assert( sizeof(AST_Constructor) == sizeof(AST), "ERROR: AST_Constructor i struct AST_Define { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; StringCached Content; }; Code Prev; @@ -126,7 +126,7 @@ static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the struct AST_Destructor { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; @@ -150,7 +150,7 @@ static_assert( sizeof(AST_Destructor) == sizeof(AST), "ERROR: AST_Destructor is struct AST_Enum { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; @@ -176,7 +176,7 @@ static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same struct AST_Exec { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; StringCached Content; }; Code Prev; @@ -192,7 +192,7 @@ static_assert( sizeof(AST_Exec) == sizeof(AST), "ERROR: AST_Exec is not the same struct AST_Extern { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { char _PAD_PROPERTIES_[ sizeof(AST*) * 5 ]; @@ -213,7 +213,7 @@ static_assert( sizeof(AST_Extern) == sizeof(AST), "ERROR: AST_Extern is not the struct AST_Include { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; StringCached Content; }; Code Prev; @@ -229,7 +229,7 @@ static_assert( sizeof(AST_Include) == sizeof(AST), "ERROR: AST_Include is not th struct AST_Friend { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; @@ -251,7 +251,7 @@ static_assert( sizeof(AST_Friend) == sizeof(AST), "ERROR: AST_Friend is not the struct AST_Fn { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; @@ -276,7 +276,7 @@ static_assert( sizeof(AST_Fn) == sizeof(AST), "ERROR: AST_Fn is not the same siz struct AST_Module { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; Code Prev; Code Next; Code Parent; @@ -291,7 +291,7 @@ static_assert( sizeof(AST_Module) == sizeof(AST), "ERROR: AST_Module is not the struct AST_NS { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { char _PAD_PROPERTIES_[ sizeof(AST*) * 5 ]; CodeBody Body; @@ -312,7 +312,7 @@ static_assert( sizeof(AST_NS) == sizeof(AST), "ERROR: AST_NS is not the same siz struct AST_Operator { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; @@ -338,7 +338,7 @@ static_assert( sizeof(AST_Operator) == sizeof(AST), "ERROR: AST_Operator is not struct AST_OpCast { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; @@ -363,7 +363,7 @@ static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the struct AST_Param { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ]; @@ -387,7 +387,7 @@ static_assert( sizeof(AST_Param) == sizeof(AST), "ERROR: AST_Param is not the sa struct AST_Pragma { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; StringCached Content; }; Code Prev; @@ -403,7 +403,7 @@ static_assert( sizeof(AST_Pragma) == sizeof(AST), "ERROR: AST_Pragma is not the struct AST_PreprocessCond { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; StringCached Content; }; Code Prev; @@ -419,6 +419,7 @@ static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_Preprocess struct AST_Specifiers { SpecifierT ArrSpecs[ AST::ArrSpecs_Cap ]; + CodeSpecifiers NextSpecs; Code Prev; Code Next; Code Parent; @@ -433,7 +434,7 @@ struct AST_Specifiers struct AST_Struct { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; @@ -445,7 +446,7 @@ struct AST_Struct char _PAD_PROPERTIES_2_[ sizeof(AST*) ]; }; }; - CodeType Last; + CodeType Prev; CodeType Next; Code Parent; StringCached Name; @@ -459,7 +460,7 @@ static_assert( sizeof(AST_Struct) == sizeof(AST), "ERROR: AST_Struct is not the struct AST_Template { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ]; @@ -482,7 +483,7 @@ static_assert( sizeof(AST_Template) == sizeof(AST), "ERROR: AST_Template is not struct AST_Type { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { char _PAD_INLINE_CMT_[ sizeof(AST*) ]; @@ -508,7 +509,7 @@ static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same struct AST_Typedef { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; @@ -531,7 +532,7 @@ static_assert( sizeof(AST_Typedef) == sizeof(AST), "ERROR: AST_Typedef is not th struct AST_Union { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { char _PAD_INLINE_CMT_[ sizeof(AST*) ]; @@ -555,7 +556,7 @@ static_assert( sizeof(AST_Union) == sizeof(AST), "ERROR: AST_Union is not the sa struct AST_Using { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; @@ -579,7 +580,7 @@ static_assert( sizeof(AST_Using) == sizeof(AST), "ERROR: AST_Using is not the sa struct AST_Var { union { - char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; struct { CodeComment InlineCmt; diff --git a/project/components/gen/ast_inlines.hpp b/project/components/gen/ast_inlines.hpp index de72dbf..20846b4 100644 --- a/project/components/gen/ast_inlines.hpp +++ b/project/components/gen/ast_inlines.hpp @@ -1,5 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once +#include "types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/gen/ecode.hpp b/project/components/gen/ecode.hpp index ee46c90..678c476 100644 --- a/project/components/gen/ecode.hpp +++ b/project/components/gen/ecode.hpp @@ -1,5 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once +#include "types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/gen/eoperator.hpp b/project/components/gen/eoperator.hpp index 3feb117..b1ab7c9 100644 --- a/project/components/gen/eoperator.hpp +++ b/project/components/gen/eoperator.hpp @@ -1,5 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once +#include "types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/gen/especifier.hpp b/project/components/gen/especifier.hpp index e94dfd1..7e53adc 100644 --- a/project/components/gen/especifier.hpp +++ b/project/components/gen/especifier.hpp @@ -1,5 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once +#include "types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/header_end.hpp b/project/components/header_end.hpp index efc2424..01ebf53 100644 --- a/project/components/header_end.hpp +++ b/project/components/header_end.hpp @@ -86,6 +86,7 @@ extern CodeSpecifiers spec_internal_linkage; extern CodeSpecifiers spec_local_persist; extern CodeSpecifiers spec_mutable; extern CodeSpecifiers spec_neverinline; +extern CodeSpecifiers spec_noexcept; extern CodeSpecifiers spec_override; extern CodeSpecifiers spec_ptr; extern CodeSpecifiers spec_pure; diff --git a/project/components/interface.cpp b/project/components/interface.cpp index 8050ca1..44d41cd 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -203,6 +203,7 @@ void define_constants() def_constant_spec( local_persist, ESpecifier::Local_Persist ); def_constant_spec( mutable, ESpecifier::Mutable ); def_constant_spec( neverinline, ESpecifier::NeverInline ); + def_constant_spec( noexcept, ESpecifier::NoExceptions ); def_constant_spec( override, ESpecifier::Override ); def_constant_spec( ptr, ESpecifier::Ptr ); def_constant_spec( pure, ESpecifier::Pure ) diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index 8089f90..b0f6b46 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -5050,8 +5050,9 @@ CodeType parse_type( bool* typedef_is_function ) using namespace ECode; CodeType - result = (CodeType) make_code(); - result->Type = Typename; + result = (CodeType) make_code(); + result->Type = Typename; + result->Token = Context.Scope->Start; // Need to wait until were using the new parsing method to do this. String name_stripped = strip_formatting( name, strip_formatting_dont_preserve_newlines ); diff --git a/project/components/interface.upfront.cpp b/project/components/interface.upfront.cpp index 0fca812..5b602f7 100644 --- a/project/components/interface.upfront.cpp +++ b/project/components/interface.upfront.cpp @@ -861,8 +861,8 @@ CodeInclude def_include( StrC path, bool foreign ) } StrC content = foreign ? - to_str( str_fmt_buf( "<%.*s>\n", path.Len, path.Ptr )) - : to_str( str_fmt_buf( "\"%.*s\"\n", path.Len, path.Ptr )); + to_str( str_fmt_buf( "<%.*s>", path.Len, path.Ptr )) + : to_str( str_fmt_buf( "\"%.*s\"", path.Len, path.Ptr )); Code result = make_code(); diff --git a/project/components/static_data.cpp b/project/components/static_data.cpp index c5e9eab..cf08c6c 100644 --- a/project/components/static_data.cpp +++ b/project/components/static_data.cpp @@ -58,6 +58,7 @@ global CodeSpecifiers spec_inline; global CodeSpecifiers spec_internal_linkage; global CodeSpecifiers spec_local_persist; global CodeSpecifiers spec_mutable; +global CodeSpecifiers spec_noexcept; global CodeSpecifiers spec_neverinline; global CodeSpecifiers spec_override; global CodeSpecifiers spec_ptr; diff --git a/project/components/types.hpp b/project/components/types.hpp index bd8e760..460145e 100644 --- a/project/components/types.hpp +++ b/project/components/types.hpp @@ -56,12 +56,26 @@ enum class ModuleFlag : u32 None = 0, Export = bit(0), Import = bit(1), - // Private = bit(2), Num_ModuleFlags, Invalid, }; +StrC to_str( ModuleFlag flag ) +{ + local_persist + StrC lookup[ (u32)ModuleFlag::Num_ModuleFlags ] = { + { sizeof("__none__"), "__none__" }, + { sizeof("export"), "export" }, + { sizeof("import"), "import" }, + }; + + if ( flag > ModuleFlag::Import ) + return { sizeof("invalid"), "invalid" }; + + return lookup[ (u32)flag ]; +} + ModuleFlag operator|( ModuleFlag A, ModuleFlag B) { return (ModuleFlag)( (u32)A | (u32)B ); From a8708abf8b90249b41d13e7b0f2708794a8a2aa2 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 25 Sep 2023 12:12:11 -0400 Subject: [PATCH 3/5] WIP : Various changes to project before small hiatus. (Broken) I need to manually review these as the changes have various errors that are difficult to diagnose why. I took a break to do handmade hero and now a bit rusty. --- docs/AST_Design.md | 37 ++++++ docs/{ASTs.md => AST_Types.md} | 13 +- docs/Parsing.md | 2 - docs/Readme.md | 1 + gencpp.10x | 2 +- project/Readme.md | 5 + project/bootstrap.cpp | 2 +- project/components/ast.cpp | 148 ++++++++++++----------- project/components/ast.hpp | 41 ++++--- project/components/ast_types.hpp | 74 ++++++------ project/components/gen/ecode.hpp | 2 +- project/components/gen/eoperator.hpp | 2 +- project/components/gen/especifier.hpp | 2 +- project/components/interface.cpp | 18 +-- project/components/interface.parsing.cpp | 24 +++- project/components/types.hpp | 9 ++ project/dependencies/debug.hpp | 2 +- scripts/build.ci.ps1 | 48 +++++++- 18 files changed, 277 insertions(+), 155 deletions(-) create mode 100644 docs/AST_Design.md rename docs/{ASTs.md => AST_Types.md} (96%) diff --git a/docs/AST_Design.md b/docs/AST_Design.md new file mode 100644 index 0000000..284e0ac --- /dev/null +++ b/docs/AST_Design.md @@ -0,0 +1,37 @@ +# Forward + +Was never satisfied with how I did the wrap of the management of the AST. +For C++, the current design may be as good as it gets for the limitations of the langauge. + +I'll at least try in this issue to brainstorm something simpiler without losing ergonomics. +This will also be a good place to document the current design. + +## Current Design + +`AST` is the actual managed node object for the library. +Its raw and really not meant to be used directly. + +All user interaction must be with its pointer so the type they deal with is `AST*`. +For user-facing code, they should never be giveen a nullptr. Instead, they should be given a designated `Invalid` AST node. + +In order to abstract away constant use of `AST*`, I wanted to provide a wrapper for it. + +The simpliest being just a type alias. + +```cpp +using Code = AST*; +``` + +This is what the genc library would have to use due to its constraints of a langauge. +Anything else and it would either be an unergonomic mess of struct wrapping with a mess of macros & procedures to interface with it. + +Further, to provide intuitive filters on the AST, there are AST types (covered in [AST_Types.md](AST_Types.md)). + +These are pure PODS that just have the lay members relevant to the type of AST node they represent. +Each of them has a Code type alias specific to it. + +Again, the simpliest case for these would be a type alias. + +```cpp +using struct AST_Typedef CodeTypedef; +``` diff --git a/docs/ASTs.md b/docs/AST_Types.md similarity index 96% rename from docs/ASTs.md rename to docs/AST_Types.md index ea065df..5b3acf7 100644 --- a/docs/ASTs.md +++ b/docs/AST_Types.md @@ -1,4 +1,4 @@ -# ASTs Documentation +# AST Types Documentation While the Readme for docs covers the data layout per AST, this will focus on the AST types avaialble, and their nuances. @@ -95,12 +95,12 @@ The upfront constructor: `def_comment` expects to recieve a comment without the Fields: ```cpp -CodeComment InlineCmt; // Only supported by forward declarations +CodeComment InlineCmt; // Only supported by forward declarations CodeAttributes Attributes; CodeType ParentType; CodeBody Body; -CodeType Last; // Used to store references to interfaces -CodeType Next; // Used to store references to interfaces +CodeType Prev; // Used to store references to interfaces +CodeType Next; // Used to store references to interfaces Code Parent; StringCached Name; CodeT Type; @@ -115,7 +115,7 @@ Serialization: ; // Class - : , public , ... + : , public Next>, ... { }; @@ -145,7 +145,8 @@ Serialization: Name>( ); // Constructor - Name>( ): + Name>( ) + : { } diff --git a/docs/Parsing.md b/docs/Parsing.md index 39010dd..91deb93 100644 --- a/docs/Parsing.md +++ b/docs/Parsing.md @@ -67,7 +67,6 @@ Adding your own exceptions is possible by simply modifying the parser to allow f *Note: You could interpret this strictness as a feature. This would allow the user to see if their codebase or a third-party's codebase some some egregious preprocessor abuse.* - The lexing and parsing takes shortcuts from whats expected in the standard. * Numeric literals are not checked for validity. @@ -80,4 +79,3 @@ The lexing and parsing takes shortcuts from whats expected in the standard. * Parsing attributes can be extended to support user defined macros by defining `GEN_DEFINE_ATTRIBUTE_TOKENS` (see `gen.hpp` for the formatting) Empty lines used throughout the file are preserved for formatting purposes during ast serialization. - diff --git a/docs/Readme.md b/docs/Readme.md index bb9ef04..9300a1d 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -42,6 +42,7 @@ Otherwise the library is free of any templates. **There is no support for validating expressions.** Its difficult to parse without enough benefits (At the metaprogramming level). +I plan to add this only at the tail of the project parsing milestone. **Only trivial template support is provided.** The intention is for only simple, non-recursive substitution. diff --git a/gencpp.10x b/gencpp.10x index 29874bd..3619e7e 100644 --- a/gencpp.10x +++ b/gencpp.10x @@ -19,7 +19,7 @@ pwsh ./scripts/build.ps1 ./test/gen/build/gencpp.exe - false + true Debug Release diff --git a/project/Readme.md b/project/Readme.md index 0b5e35d..04ec394 100644 --- a/project/Readme.md +++ b/project/Readme.md @@ -53,3 +53,8 @@ Names or Content fields are interned strings and thus showed be cached using `ge The library has its code segmented into component files, use it to help create a derived version without needing to have to rewrite a generated file directly or build on top of the header via composition or inheritance. The parser is documented under `docs/Parsing.md` and `docs/Parser_Algo.md`. + +## A note on compilation and runtime generation speed + +The library is designed to be fast to compile and generate code at runtime as fast as resonable possible on a debug build. +Its recommended that your metaprogam be compiled using a single translation unit (unity build). diff --git a/project/bootstrap.cpp b/project/bootstrap.cpp index facf3c9..6e05e92 100644 --- a/project/bootstrap.cpp +++ b/project/bootstrap.cpp @@ -148,7 +148,7 @@ int gen_main() CodeBody gen_component_header = def_global_body( args( def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ), pragma_once, - def_include(txt("types.hpp")), + def_include(txt("components/types.hpp")), preprocess_endif, fmt_newline, untyped_str( to_str(generation_notice) ) diff --git a/project/components/ast.cpp b/project/components/ast.cpp index 11f8fc9..9f9d49d 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -11,7 +11,6 @@ char const* AST::debug_str() { String result = String::make_reserve( GlobalAllocator, kilobytes(1) ); -#if 1 if ( Parent ) result.append_fmt( "\n\tParent : %S %S", Parent->type_str(), Name ? Name : "" ); else @@ -20,7 +19,6 @@ char const* AST::debug_str() result.append_fmt( "\n\tName : %S", Name ? Name : "Null" ); result.append_fmt( "\n\tType : %S", type_str() ); result.append_fmt( "\n\tModule Flags : %S", to_str( ModuleFlags ) ); - result.append_fmt( "\n\tToken : %d", Token ); switch ( Type ) { @@ -71,6 +69,19 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Class_Fwd: + case Struct_Fwd: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tParentAccess: %s", ParentType ? to_str( ParentAccess ) : "No Parent" ); + result.append_fmt( "\n\tParentType : %s", ParentType ? ParentType->type_str() : "Null" ); + break; + case Constructor: if ( Prev ) result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); @@ -84,6 +95,18 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Constructor_Fwd: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tInitializerList: %S", InitializerList ? InitializerList->to_string() : "Null" ); + result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + break; + case Destructor: if ( Prev ) result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); @@ -95,7 +118,11 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Destructor_Fwd: + break; + case Enum: + case Enum_Class: if ( Prev ) result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); if ( Next ) @@ -107,6 +134,10 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Enum_Class_Fwd: + + break; + case Extern_Linkage: case Namespace: if ( Prev ) @@ -275,7 +306,6 @@ char const* AST::debug_str() result.append_fmt( "\n\tNextVar : %S", NextVar ? NextVar->debug_str() : "Null" ); break; } -#endif return result; } @@ -334,43 +364,37 @@ String AST::to_string() if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) result.append( "export " ); - if ( Attributes || ParentType ) + result.append( "class " ); + + if ( Attributes ) { - result.append( "class " ); + result.append_fmt( "%S ", Attributes->to_string() ); + } - if ( Attributes ) + if ( ParentType ) + { + char const* access_level = to_str( ParentAccess ); + + result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); + + CodeType interface = ParentType->Next->cast< CodeType >(); + if ( interface ) + result.append( "\n" ); + + while ( interface ) { - result.append_fmt( "%S ", Attributes->to_string() ); - } - - if ( ParentType ) - { - char const* access_level = to_str( ParentAccess ); - - result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); - - CodeType interface = ParentType->Next->cast< CodeType >(); - if ( interface ) - result.append( "\n" ); - - while ( interface ) - { - result.append_fmt( ", %S", interface.to_string() ); - interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; - } - - result.append_fmt( "\n{\n%S\n}", Body->to_string() ); - } - else - { - result.append_fmt( "%S \n{\n%S\n}", Name, Body->to_string() ); + result.append_fmt( ", %S", interface.to_string() ); + interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; } } - else + + if ( InlineCmt ) { - result.append_fmt( "class %S\n{\n%S\n}", Name, Body->to_string() ); + result.append_fmt( " // %S", InlineCmt->Content ); } + result.append_fmt( "\n{\n%S\n}", Body->to_string() ); + if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) result.append(";\n"); } @@ -409,6 +433,9 @@ String AST::to_string() if ( InitializerList ) result.append_fmt( " : %S", InitializerList->to_string() ); + if ( InlineCmt ) + result.append_fmt( " // %S", InlineCmt->Content ); + result.append_fmt( "\n{\n%S\n}\n", Body->to_string() ); } break; @@ -930,56 +957,39 @@ String AST::to_string() if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) result.append( "export " ); - if ( Name == nullptr) + result.append( "struct " ); + + if ( Attributes ) { - result.append_fmt( "struct\n{\n%S\n};\n", Body->to_string() ); - break; + result.append_fmt( "%S ", Attributes->to_string() ); } - if ( Attributes || ParentType ) + if ( ParentType ) { - result.append( "struct " ); + char const* access_level = to_str( ParentAccess ); - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); + result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); - if ( ParentType ) + CodeType interface = ParentType->Next->cast< CodeType >(); + if ( interface ) + result.append( "\n" ); + + while ( interface ) { - char const* access_level = to_str( ParentAccess ); - - result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); - - CodeType interface = ParentType->Next->cast< CodeType >(); - if ( interface ) - result.append( "\n" ); - - while ( interface ) - { - result.append_fmt( ", %S", interface.to_string() ); - - interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; - } - - result.append_fmt( "\n{\n%S\n}", Body->to_string() ); - } - else - { - if ( Name ) - result.append_fmt( "%S \n{\n%S\n}", Name, Body->to_string() ); + result.append_fmt( ", %S", interface.to_string() ); + interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; } } - else + + if ( InlineCmt ) { - result.append_fmt( "struct %S\n{\n%S\n}", Name, Body->to_string() ); + result.append_fmt( " // %S", InlineCmt->Content ); } + result.append_fmt( "\n{\n%S\n}", Body->to_string() ); + if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - { - if ( InlineCmt ) - result.append_fmt("; %S", InlineCmt->Content ); - else - result.append(";\n"); - } + result.append(";\n"); } break; diff --git a/project/components/ast.hpp b/project/components/ast.hpp index 9169404..a986b88 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -67,6 +67,11 @@ struct CodeUnion; struct CodeUsing; struct CodeVar; +// namespace Parser +// { +// struct Token; +// } + /* AST* wrapper - Not constantly have to append the '*' as this is written often.. @@ -82,7 +87,7 @@ struct Code static Code Invalid; # pragma endregion Statics -# define Using_Code( Typename ) \ +# define Using_Code( Typename ) \ char const* debug_str(); \ Code duplicate(); \ bool is_equal( Code other ); \ @@ -108,7 +113,7 @@ struct Code return ast; } Code& operator ++(); - Code& operator*() + auto& operator*() { return *this; } @@ -157,7 +162,7 @@ struct Code_POD static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" ); // Desired width of the AST data structure. -constexpr u32 AST_POD_Size = 128; +constexpr int AST_POD_Size = 128; /* Simple AST POD with functionality to seralize into C++ syntax. @@ -214,17 +219,20 @@ struct AST # pragma endregion Member Functions constexpr static - uw ArrSpecs_Cap = + int ArrSpecs_Cap = + #if 1 ( AST_POD_Size - - sizeof(AST*) * 4 - - sizeof(StringCached) - - sizeof(CodeT) + - sizeof(void*) * 4 + // - sizeof(Parser::Token*) + // - sizeof(AST*) + - sizeof(void*) + - sizeof(int) - sizeof(ModuleFlag) - - sizeof(u32) - - sizeof(s32) + - sizeof(int) ) / sizeof(SpecifierT); // -1 for 4 extra bytes + #endif union { struct @@ -251,13 +259,13 @@ struct AST }; union { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) - AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. + AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) }; }; StringCached Content; // Attributes, Comment, Execution, Include struct { SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers - AST* NextSpecs; // Specifiers + AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. }; }; union { @@ -269,6 +277,7 @@ struct AST AST* Next; AST* Back; }; + // Parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing. AST* Parent; StringCached Name; CodeT Type; @@ -280,7 +289,6 @@ struct AST AccessSpec ParentAccess; s32 NumEntries; }; - s32 Token; // Handle to the token, stored in the CodeFile (Otherwise unretrivable) }; struct AST_POD @@ -310,13 +318,13 @@ struct AST_POD }; union { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) - AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. + AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) }; }; StringCached Content; // Attributes, Comment, Execution, Include struct { SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers - AST* NextSpecs; // Specifiers + AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. }; }; union { @@ -328,6 +336,7 @@ struct AST_POD AST* Next; AST* Back; }; + // Parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing. AST* Parent; StringCached Name; CodeT Type; @@ -339,9 +348,11 @@ struct AST_POD AccessSpec ParentAccess; s32 NumEntries; }; - s32 Token; // Handle to the token, stored in the CodeFile (Otherwise unretrivable) }; +constexpr int specifierT_size = sizeof(SpecifierT); +constexpr int AST_SIZE = sizeof(AST); + // Its intended for the AST to have equivalent size to its POD. // All extra functionality within the AST namespace should just be syntatic sugar. static_assert( sizeof(AST) == sizeof(AST_POD), "ERROR: AST IS NOT POD" ); diff --git a/project/components/ast_types.hpp b/project/components/ast_types.hpp index 228e429..0690faa 100644 --- a/project/components/ast_types.hpp +++ b/project/components/ast_types.hpp @@ -15,14 +15,14 @@ struct AST_Body char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; Code Front; Code Back; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; s32 NumEntries; - s32 Token; }; -static_assert( sizeof(AST_Body) == sizeof(AST), "ERROR: AST_Filtered is not the same size as AST"); +static_assert( sizeof(AST_Body) == sizeof(AST), "ERROR: AST_Body is not the same size as AST"); struct AST_Attributes { @@ -32,11 +32,11 @@ struct AST_Attributes }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Attributes) == sizeof(AST), "ERROR: AST_Attributes is not the same size as AST"); @@ -48,11 +48,11 @@ struct AST_Comment }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Comment) == sizeof(AST), "ERROR: AST_Comment is not the same size as AST"); @@ -73,12 +73,12 @@ struct AST_Class }; CodeType Prev; CodeType Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; AccessSpec ParentAccess; - s32 Token; }; static_assert( sizeof(AST_Class) == sizeof(AST), "ERROR: AST_Class is not the same size as AST"); @@ -99,11 +99,11 @@ struct AST_Constructor }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; char _PAD_NAME_[ sizeof(StringCached) ]; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Constructor) == sizeof(AST), "ERROR: AST_Constructor is not the same size as AST"); @@ -115,11 +115,11 @@ struct AST_Define }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the same size as AST"); @@ -139,11 +139,11 @@ struct AST_Destructor }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; char _PAD_NAME_[ sizeof(StringCached) ]; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Destructor) == sizeof(AST), "ERROR: AST_Destructor is not the same size as AST"); @@ -164,12 +164,12 @@ struct AST_Enum }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST"); @@ -181,11 +181,11 @@ struct AST_Exec }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Exec) == sizeof(AST), "ERROR: AST_Exec is not the same size as AST"); @@ -202,11 +202,11 @@ struct AST_Extern }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Extern) == sizeof(AST), "ERROR: AST_Extern is not the same size as AST"); @@ -218,11 +218,11 @@ struct AST_Include }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Include) == sizeof(AST), "ERROR: AST_Include is not the same size as AST"); @@ -240,11 +240,11 @@ struct AST_Friend }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Friend) == sizeof(AST), "ERROR: AST_Friend is not the same size as AST"); @@ -264,13 +264,13 @@ struct AST_Fn }; }; Code Prev; - Code Parent; Code Next; + Parser::Token* Token; + Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Fn) == sizeof(AST), "ERROR: AST_Fn is not the same size as AST"); @@ -279,12 +279,12 @@ struct AST_Module char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ]; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Module) == sizeof(AST), "ERROR: AST_Module is not the same size as AST"); @@ -300,12 +300,12 @@ struct AST_NS }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_NS) == sizeof(AST), "ERROR: AST_NS is not the same size as AST"); @@ -324,14 +324,14 @@ struct AST_Operator char _PAD_PROPERTIES_ [ sizeof(AST*) ]; }; }; - Code Prev; - Code Next; - Code Parent; - StringCached Name; - CodeT Type; - ModuleFlag ModuleFlags; - OperatorT Op; - s32 Token; + Code Prev; + Code Next; + Parser::Token* Token; + Code Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + OperatorT Op; }; static_assert( sizeof(AST_Operator) == sizeof(AST), "ERROR: AST_Operator is not the same size as AST"); @@ -352,11 +352,11 @@ struct AST_OpCast }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the same size as AST"); @@ -375,12 +375,12 @@ struct AST_Param }; CodeParam Last; CodeParam Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; s32 NumEntries; - s32 Token; }; static_assert( sizeof(AST_Param) == sizeof(AST), "ERROR: AST_Param is not the same size as AST"); @@ -392,11 +392,11 @@ struct AST_Pragma }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Pragma) == sizeof(AST), "ERROR: AST_Pragma is not the same size as AST"); @@ -408,11 +408,11 @@ struct AST_PreprocessCond }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_PreprocessCond) == sizeof(AST), "ERROR: AST_PreprocessCond is not the same size as AST"); @@ -422,12 +422,12 @@ struct AST_Specifiers CodeSpecifiers NextSpecs; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; s32 NumEntries; - s32 Token; }; static_assert( sizeof(AST_Specifiers) == sizeof(AST), "ERROR: AST_Specifier is not the same size as AST"); @@ -448,12 +448,12 @@ struct AST_Struct }; CodeType Prev; CodeType Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; AccessSpec ParentAccess; - s32 Token; }; static_assert( sizeof(AST_Struct) == sizeof(AST), "ERROR: AST_Struct is not the same size as AST"); @@ -471,12 +471,12 @@ struct AST_Template }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Template) == sizeof(AST), "ERROR: AST_Template is not the same size as AST"); @@ -497,12 +497,12 @@ struct AST_Type }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; b32 IsParamPack; - s32 Token; }; static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST"); @@ -520,12 +520,12 @@ struct AST_Typedef }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; b32 IsFunction; - s32 Token; }; static_assert( sizeof(AST_Typedef) == sizeof(AST), "ERROR: AST_Typedef is not the same size as AST"); @@ -544,12 +544,12 @@ struct AST_Union }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Union) == sizeof(AST), "ERROR: AST_Union is not the same size as AST"); @@ -568,12 +568,12 @@ struct AST_Using }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Using) == sizeof(AST), "ERROR: AST_Using is not the same size as AST"); @@ -594,12 +594,12 @@ struct AST_Var }; Code Prev; Code Next; + Parser::Token* Token; Code Parent; StringCached Name; CodeT Type; ModuleFlag ModuleFlags; char _PAD_UNUSED_[ sizeof(u32) ]; - s32 Token; }; static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST"); diff --git a/project/components/gen/ecode.hpp b/project/components/gen/ecode.hpp index 678c476..68877f7 100644 --- a/project/components/gen/ecode.hpp +++ b/project/components/gen/ecode.hpp @@ -1,6 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once -#include "types.hpp" +#include "components/Types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/gen/eoperator.hpp b/project/components/gen/eoperator.hpp index b1ab7c9..a26e8ce 100644 --- a/project/components/gen/eoperator.hpp +++ b/project/components/gen/eoperator.hpp @@ -1,6 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once -#include "types.hpp" +#include "components/types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/gen/especifier.hpp b/project/components/gen/especifier.hpp index 7e53adc..0a0e1cf 100644 --- a/project/components/gen/especifier.hpp +++ b/project/components/gen/especifier.hpp @@ -1,6 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once -#include "types.hpp" +#include "components/types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/interface.cpp b/project/components/interface.cpp index 44d41cd..917aa96 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -419,15 +419,15 @@ Code make_code() // mem_set( result.ast, 0, sizeof(AST) ); result->Type = ECode::Invalid; - result->Content = { nullptr }; - result->Prev = { nullptr }; - result->Next = { nullptr }; - result->Parent = { nullptr }; - result->Name = { nullptr }; - result->Type = ECode::Invalid; - result->ModuleFlags = ModuleFlag::Invalid; - result->NumEntries = 0; - result->Token = -1; + result->Content = { nullptr }; + result->Prev = { nullptr }; + result->Next = { nullptr }; + result->Token = nullptr; + result->Parent = { nullptr }; + result->Name = { nullptr }; + result->Type = ECode::Invalid; + result->ModuleFlags = ModuleFlag::Invalid; + result->NumEntries = 0; return result; } diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index b0f6b46..c929f6b 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -6,6 +6,18 @@ namespace Parser { + enum TokFlags : u32 + { + TF_Operator = bit(0), + TF_Assign = bit(0), + TF_Preprocess = bit(1), + TF_Comment = bit(2), + TF_Attribute = bit(3), + TF_AccessSpecifier = bit(4), + TF_Specifier = bit(5), + TF_EndDefinition = bit(6), // Either ; or } + }; + struct Token { char const* Text; @@ -251,11 +263,6 @@ namespace Parser return true; } - enum TokFlags : u32 - { - IsAssign = bit(0), - }; - global Array Tokens; neverinline @@ -1638,6 +1645,7 @@ CodeAttributes parse_attributes() { eat( TokType::Attribute_Open); + start = currtok; while ( left && currtok.Type != TokType::Attribute_Close ) { eat( currtok.Type ); @@ -1653,6 +1661,7 @@ CodeAttributes parse_attributes() eat(TokType::Capture_Start); eat(TokType::Capture_Start); + start = currtok; while ( left && currtok.Type != TokType::Capture_End ) { eat(currtok.Type); @@ -1669,6 +1678,7 @@ CodeAttributes parse_attributes() eat( TokType::Decl_MSVC_Attribute ); eat( TokType::Capture_Start); + start = currtok; while ( left && currtok.Type != TokType::Capture_End ) { eat(currtok.Type); @@ -1697,6 +1707,7 @@ CodeAttributes parse_attributes() result->Type = ECode::PlatformAttributes; result->Name = get_cached_string( name_stripped ); result->Content = result->Name; + // result->Token = return (CodeAttributes) result; } @@ -1717,6 +1728,7 @@ CodeComment parse_comment() result->Type = ECode::Comment; result->Content = get_cached_string( currtok_noskip ); result->Name = result->Content; + // result->Token = currtok_noskip; eat( TokType::Comment ); Context.pop(); @@ -5052,7 +5064,7 @@ CodeType parse_type( bool* typedef_is_function ) CodeType result = (CodeType) make_code(); result->Type = Typename; - result->Token = Context.Scope->Start; + // result->Token = Context.Scope->Start; // Need to wait until were using the new parsing method to do this. String name_stripped = strip_formatting( name, strip_formatting_dont_preserve_newlines ); diff --git a/project/components/types.hpp b/project/components/types.hpp index 460145e..b9d5437 100644 --- a/project/components/types.hpp +++ b/project/components/types.hpp @@ -41,6 +41,15 @@ char const* to_str( AccessSpec type ) return lookup[ (u32)type ]; } + +enum CodeFlag : u32 +{ + FunctionType = bit(0), + ParamPack = bit(1), + Module_Export = bit(2), + Module_Import = bit(3), +}; + // Used to indicate if enum definitoin is an enum class or regular enum. enum class EnumT : u8 { diff --git a/project/dependencies/debug.hpp b/project/dependencies/debug.hpp index 43d50cb..40e7747 100644 --- a/project/dependencies/debug.hpp +++ b/project/dependencies/debug.hpp @@ -1,4 +1,4 @@ -#ifdef GEN_INTELLISENSE_DIRECTIVESj +#ifdef GEN_INTELLISENSE_DIRECTIVES # pragma once # include "basic_types.hpp" #endif diff --git a/scripts/build.ci.ps1 b/scripts/build.ci.ps1 index e1a4db6..4f3d812 100644 --- a/scripts/build.ci.ps1 +++ b/scripts/build.ci.ps1 @@ -113,6 +113,39 @@ function run-linker } } +function run-compile-and-link +{ + param( $vendor, $unit, $compiler_args, $linker_args ) + + write-host "`Compiling & Linking $unit" + write-host "Compiler config:" + $compiler_args | ForEach-Object { + write-host $_ -ForegroundColor Cyan + } + write-host "Linker config:" + $linker_args | ForEach-Object { + write-host $_ -ForegroundColor Cyan + } + + $time_taken = Measure-Command { + & $vendor $compiler_args $linker_args 2>&1 | ForEach-Object { + $color = 'White' + switch ($_){ + { $_ -match "error" } { $color = 'Red' ; break } + { $_ -match "warning" } { $color = 'Yellow'; break } + } + write-host `t $_ -ForegroundColor $color + } + } + + # if ( Test-Path($binary) ) { + # write-host "$binary compile & link finished in $($time_taken.TotalMilliseconds) ms" + # } + # else { + # write-host "Compile & Link failed for $binary" -ForegroundColor Red + # } +} + if ( $vendor -match "clang" ) { # https://clang.llvm.org/docs/ClangCommandLineReference.html @@ -173,7 +206,8 @@ if ( $vendor -match "clang" ) $flag_wall, $flag_preprocess_non_intergrated, ( $flag_define + 'GEN_TIME' ), - ( $flag_path_output + $object ), + # ( $flag_path_output + $object ), + ( $flag_path_output + $executable ) ( $flag_include + $includes ) ) if ( $release -eq $false ) { @@ -188,8 +222,8 @@ if ( $vendor -match "clang" ) # $compiler_args += $flag_preprocess - $compiler_args += $flag_compile, $unit - run-compiler $compiler $unit $compiler_args + # $compiler_args += $flag_compile, $unit + # run-compiler $compiler $unit $compiler_args $linker_args = @( $flag_link_win_subsystem_console, @@ -207,8 +241,12 @@ if ( $vendor -match "clang" ) $linker_args += $_ + '.lib' } - $linker_args += $object - run-linker $linker $executable $linker_args + # $linker_args += $object + # run-linker $linker $executable $linker_args + + $compiler_args += $unit + # $linker_args += $object + run-compile-and-link $compiler $unit $compiler_args } $compiler = 'clang++' From 754bcfb31e2ddce01d1b91cc1781b093400be8f7 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 25 Sep 2023 16:42:29 -0400 Subject: [PATCH 4/5] Fixes to get it back to where I was last at with the const specifier issue --- gencpp.10x | 10 +- gencpp.vcxproj | 19 +--- project/bootstrap.cpp | 21 ++-- project/components/ast.cpp | 136 ++++++++++++++++------- project/components/ast.hpp | 38 ++++--- project/components/gen/ast_inlines.hpp | 2 +- project/components/gen/ecode.hpp | 2 +- project/components/gen/etoktype.cpp | 7 +- project/components/interface.parsing.cpp | 2 +- project/dependencies/debug.cpp | 3 + project/dependencies/printing.cpp | 2 + project/dependencies/src_start.cpp | 4 + project/dependencies/string_ops.cpp | 1 + 13 files changed, 155 insertions(+), 92 deletions(-) diff --git a/gencpp.10x b/gencpp.10x index 3619e7e..5940354 100644 --- a/gencpp.10x +++ b/gencpp.10x @@ -32,11 +32,11 @@ C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.36.32532\include C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.36.32532\ATLMFC\include C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\VS\include - C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt - C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\um - C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\shared - C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\winrt - C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\cppwinrt + C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt + C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um + C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared + C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt + C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um diff --git a/gencpp.vcxproj b/gencpp.vcxproj index 33bde5a..9567848 100644 --- a/gencpp.vcxproj +++ b/gencpp.vcxproj @@ -170,15 +170,15 @@ pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" - GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) - $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions) + $(ProjectDir)project;$(IncludePath) $(ProjectDir)project;$(SourcePath) pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug test pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" - GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions) $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) $(ProjectDir)project;$(SourcePath) @@ -187,7 +187,7 @@ pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" - GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions) $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) $(ProjectDir)project;$(SourcePath) @@ -196,7 +196,7 @@ pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" - GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions) $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) $(ProjectDir)project;$(SourcePath) @@ -205,7 +205,7 @@ pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1" - GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;$(NMakePreprocessorDefinitions) + GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions) $(ProjectDir)project;$(ProjectDir)test;$(IncludePath) $(ProjectDir)project;$(SourcePath) @@ -236,7 +236,6 @@ - @@ -271,10 +270,6 @@ - - - - @@ -325,8 +320,6 @@ - - diff --git a/project/bootstrap.cpp b/project/bootstrap.cpp index 6e05e92..ad7f698 100644 --- a/project/bootstrap.cpp +++ b/project/bootstrap.cpp @@ -97,6 +97,15 @@ int gen_main() src.write(); } + CodeBody gen_component_header = def_global_body( args( + def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ), + pragma_once, + def_include(txt("components/types.hpp")), + preprocess_endif, + fmt_newline, + untyped_str( to_str(generation_notice) ) + )); + // gen.hpp { Code header_start = scan_file( "components/header_start.hpp" ); @@ -145,15 +154,6 @@ int gen_main() header.print( pop_ignores ); header.write(); - CodeBody gen_component_header = def_global_body( args( - def_preprocess_cond( PreprocessCond_IfDef, txt("GEN_INTELLISENSE_DIRECTIVES") ), - pragma_once, - def_include(txt("components/types.hpp")), - preprocess_endif, - fmt_newline, - untyped_str( to_str(generation_notice) ) - )); - Builder header_ecode = Builder::open( "components/gen/ecode.hpp" ); header_ecode.print( gen_component_header ); @@ -223,8 +223,7 @@ int gen_main() Builder src_etoktype = Builder::open( "components/gen/etoktype.cpp" ); - src_etoktype.print_fmt( generation_notice ); - src_etoktype.print( pragma_once ); + src_etoktype.print( gen_component_header ); src_etoktype.print( nspaced_etoktype ); src_etoktype.write(); } diff --git a/project/components/ast.cpp b/project/components/ast.cpp index 9f9d49d..e5b82b4 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -30,9 +30,9 @@ char const* AST::debug_str() case Access_Protected: case Access_Public: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); break; case Untyped: @@ -48,9 +48,9 @@ char const* AST::debug_str() case Preprocess_IfDef: case Preprocess_IfNotDef: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tContent: %S", Content ); break; @@ -58,9 +58,9 @@ char const* AST::debug_str() case Class: case Struct: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); @@ -72,9 +72,9 @@ char const* AST::debug_str() case Class_Fwd: case Struct_Fwd: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmd : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); @@ -84,9 +84,9 @@ char const* AST::debug_str() case Constructor: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); @@ -97,9 +97,9 @@ char const* AST::debug_str() case Constructor_Fwd: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); @@ -109,9 +109,9 @@ char const* AST::debug_str() case Destructor: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); @@ -124,9 +124,9 @@ char const* AST::debug_str() case Enum: case Enum_Class: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); @@ -134,25 +134,33 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Enum_Fwd: case Enum_Class_Fwd: - + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tUnderlying Type : %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); break; case Extern_Linkage: case Namespace: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tBody: %S", Body ? Body->debug_str() : "Null" ); break; case Friend: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" ); @@ -160,9 +168,9 @@ char const* AST::debug_str() case Function: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); @@ -172,18 +180,32 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Function_Fwd: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); + result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + break; + case Module: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); break; case Operator: + case Operator_Member: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); @@ -194,11 +216,26 @@ char const* AST::debug_str() result.append_fmt( "\n\tOp : %S", to_str( Op ) ); break; + case Operator_Fwd: + case Operator_Member_Fwd: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tReturnType: %S", ReturnType ? ReturnType->to_string() : "Null" ); + result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); + result.append_fmt( "\n\tOp : %S", to_str( Op ) ); + break; + case Operator_Cast: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); @@ -206,6 +243,17 @@ char const* AST::debug_str() result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); break; + case Operator_Cast_Fwd: + if ( Prev ) + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + if ( Next ) + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); + + result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); + result.append_fmt( "\n\tSpecs : %S", Specs ? Specs->to_string() : "Null" ); + result.append_fmt( "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" ); + break; + case Parameters: result.append_fmt( "\n\tNumEntries: %d", NumEntries ); result.append_fmt( "\n\tLast : %S", Last->Name ); @@ -233,9 +281,9 @@ char const* AST::debug_str() case Template: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tParams : %S", Params ? Params->to_string() : "Null" ); result.append_fmt( "\n\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" ); @@ -243,12 +291,12 @@ char const* AST::debug_str() case Typedef: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); - result.append_fmt( "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); + result.append_fmt( "\n\tUnderlyingType: %S", UnderlyingType ? UnderlyingType->to_string() : "Null" ); break; case Typename: @@ -261,9 +309,9 @@ char const* AST::debug_str() case Union: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tAttributes: %S", Attributes ? Attributes->to_string() : "Null" ); result.append_fmt( "\n\tBody : %S", Body ? Body->debug_str() : "Null" ); @@ -271,9 +319,9 @@ char const* AST::debug_str() case Using: if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); @@ -293,9 +341,9 @@ char const* AST::debug_str() } if ( Prev ) - result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tPrev: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); if ( Next ) - result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ); + result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" ); result.append_fmt( "\n\tInlineCmt : %S", InlineCmt ? InlineCmt->Content : "Null" ); result.append_fmt( "\n\tAttributes : %S", Attributes ? Attributes->to_string() : "Null" ); @@ -387,6 +435,10 @@ String AST::to_string() interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; } } + else if ( Name ) + { + result.append( Name ); + } if ( InlineCmt ) { @@ -980,6 +1032,10 @@ String AST::to_string() interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; } } + else if ( Name ) + { + result.append( Name ); + } if ( InlineCmt ) { diff --git a/project/components/ast.hpp b/project/components/ast.hpp index a986b88..46a8311 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -67,10 +67,10 @@ struct CodeUnion; struct CodeUsing; struct CodeVar; -// namespace Parser -// { -// struct Token; -// } +namespace Parser +{ + struct Token; +} /* AST* wrapper @@ -162,7 +162,7 @@ struct Code_POD static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" ); // Desired width of the AST data structure. -constexpr int AST_POD_Size = 128; +constexpr int const AST_POD_Size = 128; /* Simple AST POD with functionality to seralize into C++ syntax. @@ -220,19 +220,17 @@ struct AST constexpr static int ArrSpecs_Cap = - #if 1 ( AST_POD_Size - - sizeof(void*) * 4 - // - sizeof(Parser::Token*) - // - sizeof(AST*) - - sizeof(void*) - - sizeof(int) + - sizeof(AST*) * 3 + - sizeof(Parser::Token*) + - sizeof(AST*) + - sizeof(StringCached) + - sizeof(CodeT) - sizeof(ModuleFlag) - sizeof(int) ) - / sizeof(SpecifierT); // -1 for 4 extra bytes - #endif + / sizeof(int) - 1; // -1 for 4 extra bytes union { struct @@ -264,7 +262,7 @@ struct AST }; StringCached Content; // Attributes, Comment, Execution, Include struct { - SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + SpecifierT ArrSpecs[ArrSpecs_Cap]; // Specifiers AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. }; }; @@ -277,7 +275,7 @@ struct AST AST* Next; AST* Back; }; - // Parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing. + Parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing. AST* Parent; StringCached Name; CodeT Type; @@ -336,7 +334,7 @@ struct AST_POD AST* Next; AST* Back; }; - // Parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing. + Parser::Token* Token; // Reference to starting token, only avaialble if it was derived from parsing. AST* Parent; StringCached Name; CodeT Type; @@ -350,8 +348,12 @@ struct AST_POD }; }; -constexpr int specifierT_size = sizeof(SpecifierT); -constexpr int AST_SIZE = sizeof(AST); +struct test { + SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. +}; + +constexpr int pls = sizeof(test); // Its intended for the AST to have equivalent size to its POD. // All extra functionality within the AST namespace should just be syntatic sugar. diff --git a/project/components/gen/ast_inlines.hpp b/project/components/gen/ast_inlines.hpp index 20846b4..a7ff8c0 100644 --- a/project/components/gen/ast_inlines.hpp +++ b/project/components/gen/ast_inlines.hpp @@ -1,6 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once -#include "types.hpp" +#include "components/types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/gen/ecode.hpp b/project/components/gen/ecode.hpp index 68877f7..82cef85 100644 --- a/project/components/gen/ecode.hpp +++ b/project/components/gen/ecode.hpp @@ -1,6 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once -#include "components/Types.hpp" +#include "components/types.hpp" #endif // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) diff --git a/project/components/gen/etoktype.cpp b/project/components/gen/etoktype.cpp index db84d4c..bcab4ce 100644 --- a/project/components/gen/etoktype.cpp +++ b/project/components/gen/etoktype.cpp @@ -1,6 +1,9 @@ -// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) - +#ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once +#include "components/types.hpp" +#endif + +// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) namespace Parser { diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index c929f6b..2f86926 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -3921,7 +3921,7 @@ CodeEnum parse_enum( bool inplace_def ) while ( left && currtok_noskip.Type != TokType::BraceCurly_Close ) { - if ( currtok.Type == TokType::Preprocess_Hash ) + if ( currtok_noskip.Type == TokType::Preprocess_Hash ) eat( TokType::Preprocess_Hash ); switch ( currtok_noskip.Type ) diff --git a/project/dependencies/debug.cpp b/project/dependencies/debug.cpp index 3b5adef..c5aaf59 100644 --- a/project/dependencies/debug.cpp +++ b/project/dependencies/debug.cpp @@ -1,5 +1,8 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES # pragma once +# include "debug.hpp" +# include "basic_types.hpp" +# include "src_start.cpp" #endif #pragma region Debug diff --git a/project/dependencies/printing.cpp b/project/dependencies/printing.cpp index f3fef3d..7589271 100644 --- a/project/dependencies/printing.cpp +++ b/project/dependencies/printing.cpp @@ -1,5 +1,7 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES # pragma once +# include "filesystem.hpp" +# include "strings.hpp" # include "string_ops.cpp" #endif diff --git a/project/dependencies/src_start.cpp b/project/dependencies/src_start.cpp index dda2e1d..02d804e 100644 --- a/project/dependencies/src_start.cpp +++ b/project/dependencies/src_start.cpp @@ -1,3 +1,7 @@ +#ifdef GEN_INTELLISENSE_DIRECTIVES +# include "header_start.hpp" +#endif + #pragma region Macros and Includes # include diff --git a/project/dependencies/string_ops.cpp b/project/dependencies/string_ops.cpp index 28729da..e163e7d 100644 --- a/project/dependencies/string_ops.cpp +++ b/project/dependencies/string_ops.cpp @@ -1,5 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES # pragma once +# include "string_ops.hpp" # include "debug.cpp" #endif From 729c891cbd5e4733b05c49952d0a7c99f2224a45 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Mon, 25 Sep 2023 17:48:16 -0400 Subject: [PATCH 5/5] Last fixes before handmade hero hiatus --- project/components/ast.cpp | 75 ++++++++++++++++++++---- project/components/ast.hpp | 4 +- project/components/interface.parsing.cpp | 3 +- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/project/components/ast.cpp b/project/components/ast.cpp index e5b82b4..b457bb6 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -690,13 +690,25 @@ String AST::to_string() case Function: { if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); + result.append( "export" ); if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); + result.append_fmt( " %S ", Attributes->to_string() ); if ( Specs ) - result.append_fmt( "%S", Specs->to_string() ); + { + for ( SpecifierT spec : Specs->cast() ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( Attributes || Specs ) + result.append( "\n" ); if ( ReturnType ) result.append_fmt( "%S %S(", ReturnType->to_string(), Name ); @@ -735,7 +747,21 @@ String AST::to_string() result.append_fmt( "%S ", Attributes->to_string() ); if ( Specs ) - result.append_fmt( "%S", Specs->to_string() ); + { + for ( SpecifierT spec : Specs->cast() ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( Attributes || Specs ) + { + result.append("\n" ); + } if ( ReturnType ) result.append_fmt( "%S %S(", ReturnType->to_string(), Name ); @@ -795,7 +821,24 @@ String AST::to_string() result.append_fmt( "%S ", Attributes->to_string() ); if ( Attributes ) - result.append_fmt( "%S\n", Attributes->to_string() ); + result.append_fmt( "%S ", Attributes->to_string() ); + + if ( Specs ) + { + for ( SpecifierT spec : Specs->cast() ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( Attributes || Specs ) + { + result.append("\n" ); + } if ( ReturnType ) result.append_fmt( "%S %S (", ReturnType->to_string(), Name ); @@ -834,7 +877,21 @@ String AST::to_string() result.append_fmt( "%S\n", Attributes->to_string() ); if ( Specs ) - result.append_fmt( "%S\n", Specs->to_string() ); + { + for ( SpecifierT spec : Specs->cast() ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( Attributes || Specs ) + { + result.append("\n" ); + } result.append_fmt( "%S %S (", ReturnType->to_string(), Name ); @@ -991,12 +1048,6 @@ String AST::to_string() s32 left = NumEntries; while ( left-- ) { - if ( ESpecifier::is_trailing( ArrSpecs[idx]) && ArrSpecs[idx] != ESpecifier::Const ) - { - idx++; - continue; - } - StrC spec = ESpecifier::to_str( ArrSpecs[idx] ); result.append_fmt( "%.*s ", spec.Len, spec.Ptr ); idx++; diff --git a/project/components/ast.hpp b/project/components/ast.hpp index 46a8311..4ddcb90 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -257,7 +257,7 @@ struct AST }; union { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) - AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) + AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) }; }; StringCached Content; // Attributes, Comment, Execution, Include @@ -316,7 +316,7 @@ struct AST_POD }; union { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) - AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) + AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) }; }; StringCached Content; // Attributes, Comment, Execution, Include diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index 2f86926..e90c8f0 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -2296,6 +2296,7 @@ CodeFn parse_function_after_name( CodeParam params = parse_params(); + // These have to be kept separate from the return type's specifiers. while ( left && currtok.is_specifier() ) { if ( specifiers.ast == nullptr ) @@ -4784,7 +4785,7 @@ CodeType parse_type( bool* typedef_is_function ) #if 0 else if ( currtok.Type == TokType::DeclType ) { - // Will have a capture and its own parsing rules, were going to just shove everything in a string. + // Will have a capture and its own parsing rules, were going to just shove everything in a string (for now). name = currtok; eat( TokType::DeclType );