Merge pull request #45 from Ed94/dev

Dev
This commit is contained in:
Edward R. Gonzalez 2023-09-25 17:50:16 -04:00 committed by GitHub
commit 4997cb5878
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 1102 additions and 404 deletions

View File

@ -5,14 +5,17 @@ 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 +126,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

37
docs/AST_Design.md Normal file
View File

@ -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;
```

View File

@ -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:
<ModuleFlags> <class/struct> <Name>; <InlineCmt>
// Class
<ModuleFlags> <class/struct> <Attributes> <Name> : <ParentAccess> <ParentType>, public <Next>, ...<Last>
<ModuleFlags> <class/struct> <Attributes> <Name> : <ParentAccess> <ParentType>, public <ParentType->Next>, ... <InlineCmt>
{
<Body>
};
@ -145,7 +145,8 @@ Serialization:
<Specs> <Parent->Name>( <Params> ); <InlineCmt>
// Constructor
<Specs> <Parent->Name>( <Params> ): <InitializerList>
<Specs> <Parent->Name>( <Params> ) <InlineCmt>
: <InitializerList>
{
<Body>
}

View File

@ -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.
@ -60,13 +60,13 @@ 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.
*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.
@ -79,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.

View File

@ -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.
@ -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.
@ -70,28 +71,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 +116,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 +153,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 +251,7 @@ Interface :``
* def_operator_cast
* def_param
* def_params
* def_pragma
* def_preprocess_cond
* def_specifier
* def_specifiers
@ -382,8 +401,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 +411,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 +449,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 +478,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.

View File

@ -8,21 +8,22 @@
<ShowEmptyFolders>true</ShowEmptyFolders>
<IsVirtual>false</IsVirtual>
<IsFolder>false</IsFolder>
<BuildCommand>powershell ./scripts/test.gen_run.ps1</BuildCommand>
<BuildCommand>pwsh ./scripts/build.ps1 msvc debug bootstrap</BuildCommand>
<RebuildCommand></RebuildCommand>
<BuildFileCommand></BuildFileCommand>
<CleanCommand>powershell ./scripts/clean.ps1</CleanCommand>
<CleanCommand>psh ./scripts/clean.ps1</CleanCommand>
<BuildWorkingDirectory></BuildWorkingDirectory>
<CancelBuild></CancelBuild>
<RunCommand>./test/gen/build/gencpp.exe</RunCommand>
<RunCommandWorkingDirectory></RunCommandWorkingDirectory>
<DebugCommand>powershell ./scripts/build.ps1</DebugCommand>
<DebugCommand>pwsh ./scripts/build.ps1</DebugCommand>
<ExePathCommand>./test/gen/build/gencpp.exe</ExePathCommand>
<DebugSln>gencpp.sln</DebugSln>
<UseVisualStudioEnvBat>false</UseVisualStudioEnvBat>
<DebugSln></DebugSln>
<UseVisualStudioEnvBat>true</UseVisualStudioEnvBat>
<Configurations>
<Configuration>Debug</Configuration>
<Configuration>Release</Configuration>
<Configuration>bootstrap debug</Configuration>
</Configurations>
<Platforms>
<Platform>x64</Platform>
@ -31,16 +32,17 @@
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.36.32532\include</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.36.32532\ATLMFC\include</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\VS\include</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\um</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\shared</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\winrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\\cppwinrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt</AdditionalIncludePath>
<AdditionalIncludePath>C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um</AdditionalIncludePath>
</AdditionalIncludePaths>
<Defines>
<Define>GEN_TIME</Define>
<Define>GEN_SYSTEM_WINDOWS</Define>
<Define>GEN_INTELLISENSE_DIRECTIVES</Define>
</Defines>
<ConfigProperties>
<ConfigAndPlatform>
@ -48,10 +50,19 @@
<Defines></Defines>
<ForceIncludes></ForceIncludes>
</ConfigAndPlatform>
<ConfigAndPlatform>
<Name>bootstrap debug:x64</Name>
<Defines></Defines>
<ForceIncludes></ForceIncludes>
</ConfigAndPlatform>
<Config>
<Name>Debug</Name>
<Defines></Defines>
</Config>
<Config>
<Name>bootstrap debug</Name>
<Defines></Defines>
</Config>
<Platform>
<Name>x64</Name>
<Defines></Defines>

View File

@ -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

View File

@ -1,20 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<ProjectConfiguration Include="bootstrap debug|Win32">
<Configuration>bootstrap debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<ProjectConfiguration Include="bootstrap debug|x64">
<Configuration>bootstrap debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<ProjectConfiguration Include="bootstrap release|Win32">
<Configuration>bootstrap release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="bootstrap release|x64">
<Configuration>bootstrap release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="singleheader debug|Win32">
<Configuration>singleheader debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="singleheader debug|x64">
<Configuration>singleheader debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="singleheader release|Win32">
<Configuration>singleheader release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="singleheader release|x64">
<Configuration>singleheader release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="test debug|Win32">
<Configuration>test debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="test debug|x64">
<Configuration>test debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
@ -25,24 +49,54 @@
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -50,61 +104,145 @@
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='test debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|Win32'">
<NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
<NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
<NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
<NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|Win32'">
<NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
<NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
<NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
<NMakePreprocessorDefinitions>WIN32;NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1"</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1"</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>GEN_TIME;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<IncludePath>$(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
<SourcePath>$(ProjectDir)project;$(ProjectDir)test;$(SourcePath)</SourcePath>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|Win32'">
<NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
<NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
<NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
<NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1"</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1"</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>powershell.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>GEN_TIME;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<IncludePath>$(ProjectDir)thirdparty;$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
<SourcePath>$(ProjectDir)project;$(ProjectDir)test;$(SourcePath)</SourcePath>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|Win32'">
<NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
<NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
<NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
<NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|Win32'">
<NMakeBuildCommandLine>./scripts/build.ps1</NMakeBuildCommandLine>
<NMakeCleanCommandLine>./scripts/clean.ps1</NMakeCleanCommandLine>
<NMakeReBuildCommandLine>./scripts/build.ps1</NMakeReBuildCommandLine>
<NMakePreprocessorDefinitions>WIN32;_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'">
<NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug bootstrap</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<IncludePath>$(ProjectDir)project;$(IncludePath)</IncludePath>
<SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'">
<NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug test</NMakeBuildCommandLine>
<NMakeReBuildCommandLine />
<NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<IncludePath>$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
<SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'">
<NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc debug singleheader</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<IncludePath>$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
<SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'">
<NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc release singleheader</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<IncludePath>$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
<SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'">
<NMakeBuildCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\build.ps1" msvc release bootstrap</NMakeBuildCommandLine>
<NMakeReBuildCommandLine>
</NMakeReBuildCommandLine>
<NMakeCleanCommandLine>pwsh.exe -ExecutionPolicy Unrestricted -File "$(ProjectDir)scripts\clean.ps1"</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>GEN_INTELLISENSE_DIRECTIVES;GEN_TIME;GEN_BENCHMARK;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<IncludePath>$(ProjectDir)project;$(ProjectDir)test;$(IncludePath)</IncludePath>
<SourcePath>$(ProjectDir)project;$(SourcePath)</SourcePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'">
<ClCompile>
<LanguageStandard_C>stdc11</LanguageStandard_C>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'">
<ClCompile>
<LanguageStandard_C>stdc11</LanguageStandard_C>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'">
<ClCompile>
<LanguageStandard_C>stdc11</LanguageStandard_C>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'">
<ClCompile>
<LanguageStandard_C>stdc11</LanguageStandard_C>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'">
<ClCompile>
<LanguageStandard_C>stdc11</LanguageStandard_C>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<None Include=".editorconfig" />
<None Include="project\components\temp\Readme.md" />
<None Include="project\enums\AttributeTokens.csv" />
<None Include="project\enums\ECode.csv" />
<None Include="project\enums\EOperator.csv" />
<None Include="project\enums\ESpecifier.csv" />
<None Include="project\enums\ETokType.csv" />
<None Include="Readme.md" />
<None Include="scripts\.clang-format" />
<None Include="scripts\build.ci.ps1" />
<None Include="scripts\build.ps1" />
<None Include="scripts\clean.ps1" />
@ -124,14 +262,14 @@
<ClInclude Include="project\auxillary\scanner.hpp" />
<ClInclude Include="project\components\ast.hpp" />
<ClInclude Include="project\components\ast_types.hpp" />
<ClInclude Include="project\components\gen\ast_inlines.hpp" />
<ClInclude Include="project\components\gen\ecode.hpp" />
<ClInclude Include="project\components\gen\eoperator.hpp" />
<ClInclude Include="project\components\gen\especifier.hpp" />
<ClInclude Include="project\components\header_end.hpp" />
<ClInclude Include="project\components\header_start.hpp" />
<ClInclude Include="project\components\inlines.hpp" />
<ClInclude Include="project\components\interface.hpp" />
<ClInclude Include="project\components\temp\ast_inlines.hpp" />
<ClInclude Include="project\components\temp\ecode.hpp" />
<ClInclude Include="project\components\temp\eoperator.hpp" />
<ClInclude Include="project\components\temp\especifier.hpp" />
<ClInclude Include="project\components\types.hpp" />
<ClInclude Include="project\dependencies\basic_types.hpp" />
<ClInclude Include="project\dependencies\containers.hpp" />
@ -153,6 +291,7 @@
<ClInclude Include="project\helpers\push_ignores.inline.hpp" />
<ClInclude Include="project\helpers\undef.macros.hpp" />
<ClInclude Include="singleheader\components\header_start.hpp" />
<ClInclude Include="test\CURSED_TYPEDEF.h" />
<ClInclude Include="test\DummyInclude.hpp" />
<ClInclude Include="test\Parsed\Buffer.Parsed.hpp" />
<ClInclude Include="test\Parsed\HashTable.Parsed.hpp" />
@ -174,14 +313,13 @@
<ClCompile Include="project\bootstrap.cpp" />
<ClCompile Include="project\components\ast.cpp" />
<ClCompile Include="project\components\ast_case_macros.cpp" />
<ClCompile Include="project\components\gen\etoktype.cpp" />
<ClCompile Include="project\components\interface.cpp" />
<ClCompile Include="project\components\interface.parsing.cpp" />
<ClCompile Include="project\components\interface.untyped.cpp" />
<ClCompile Include="project\components\interface.upfront.cpp" />
<ClCompile Include="project\components\src_start.cpp" />
<ClCompile Include="project\components\static_data.cpp" />
<ClCompile Include="project\components\temp\etoktype.cpp" />
<ClCompile Include="project\components\untyped.cpp" />
<ClCompile Include="project\dependencies\debug.cpp" />
<ClCompile Include="project\dependencies\filesystem.cpp" />
<ClCompile Include="project\dependencies\hashing.cpp" />

View File

@ -129,6 +129,9 @@
<ClCompile Include="project\components\interface.untyped.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="project\components\gen\etoktype.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="project\gen.hpp">
@ -275,6 +278,21 @@
<ClInclude Include="singleheader\components\header_start.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="project\components\gen\ast_inlines.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="project\components\gen\ecode.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="project\components\gen\eoperator.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="project\components\gen\especifier.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="test\CURSED_TYPEDEF.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include=".editorconfig" />
@ -297,6 +315,7 @@
<None Include="scripts\helpers\target_arch.psm1" />
<None Include="scripts\package_release.ps1" />
<None Include="scripts\refactor.ps1" />
<None Include="scripts\.clang-format" />
</ItemGroup>
<ItemGroup>
<Natvis Include=".vscode\gencpp.natvis" />

View File

@ -3,14 +3,29 @@
<PropertyGroup>
<ShowAllFiles>true</ShowAllFiles>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap debug|x64'">
<LocalDebuggerAttach>false</LocalDebuggerAttach>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>C:\projects\gencpp\test\gen\build\gencpp.exe</LocalDebuggerCommand>
<LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='test debug|x64'">
<LocalDebuggerAttach>false</LocalDebuggerAttach>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>C:\projects\gencpp\test\gen\build\gencpp.exe</LocalDebuggerCommand>
<LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader debug|x64'">
<LocalDebuggerAttach>false</LocalDebuggerAttach>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='singleheader release|x64'">
<LocalDebuggerAttach>false</LocalDebuggerAttach>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='bootstrap release|x64'">
<LocalDebuggerAttach>false</LocalDebuggerAttach>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommand>$(ProjectDir)project\build\bootstrap.exe</LocalDebuggerCommand>
</PropertyGroup>
</Project>

View File

@ -8,8 +8,7 @@ They contain includes for its various components: `components/<component_name>.<
Dependencies are bundled into `gen.dep.<hpp/cpp>`.
Just like the `gen.<hpp/cpp>` they include their components: `dependencies/<dependency_name>.<hpp/cpp>`
The fle processors are in their own respective files. (Ex: `file_processors/<file_processor>.<hpp/cpp>` )
They directly include `depedencies/file_handling.<hpp/cpp>` as the core library does not include file processing by defualt.
Code not making up the core library is located in `auxiliary/<auxiliary_name>.<hpp/cpp>`. 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,10 @@ 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`.
## 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).

View File

@ -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<ParseFailure> 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<FileInfo> Files;
String Buffer;
Array<RequestEntry> 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<Receipt> out_receipts );
};
return result;
}
#endif

View File

@ -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,14 +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,
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 );
@ -222,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();
}

View File

@ -6,33 +6,355 @@
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 ( 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 ) );
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 ? Prev->Name : "Null" );
if ( Next )
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
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 ? Prev->Name : "Null" );
if ( Next )
result.append_fmt( "\n\tNext: %S %S", Prev->type_str(), Prev->Name ? Prev->Name : "Null" );
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 ? Prev->Name : "Null" );
if ( Next )
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" );
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 Class_Fwd:
case Struct_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\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 ? 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\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 Constructor_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\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 ? 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\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 ? 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" );
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 ? Prev->Name : "Null" );
if ( Next )
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 ? 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\tDeclaration: %S", Declaration ? Declaration->to_string() : "Null" );
break;
case Function:
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\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 ? Prev->Name : "Null" );
if ( Next )
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 ? 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\tBody : %S", Body ? Body->debug_str() : "Null" );
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 ? 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" );
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 );
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 ? Prev->Name : "Null" );
if ( Next )
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" );
break;
case Typedef:
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\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 ? Prev->Name : "Null" );
if ( Next )
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" );
break;
case Using:
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\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 ? 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\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 : ""
);
return result;
}
@ -61,7 +383,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 +397,7 @@ String AST::to_string()
case Untyped:
case Execution:
case Comment:
case PlatformAttributes:
result.append( Content );
break;
@ -80,51 +407,46 @@ String AST::to_string()
result.append( Name );
break;
case PlatformAttributes:
result.append( Content );
case Class:
{
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
else if ( Name )
{
result.append_fmt( "class %S\n{\n%S\n}", Name, Body->to_string() );
result.append( Name );
}
if ( InlineCmt )
{
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");
}
@ -163,6 +485,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;
@ -365,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<CodeSpecifiers>() )
{
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 );
@ -410,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<CodeSpecifiers>() )
{
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 );
@ -470,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<CodeSpecifiers>() )
{
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 );
@ -509,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<CodeSpecifiers>() )
{
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 );
@ -666,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++;
@ -684,56 +1060,43 @@ 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
else if ( Name )
{
result.append_fmt( "struct %S\n{\n%S\n}", Name, Body->to_string() );
result.append( Name );
}
if ( InlineCmt )
{
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;

View File

@ -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;
@ -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 const AST_POD_Size = 128;
/*
Simple AST POD with functionality to seralize into C++ syntax.
@ -214,17 +219,18 @@ struct AST
# pragma endregion Member Functions
constexpr static
uw ArrSpecs_Cap =
int ArrSpecs_Cap =
(
AST_POD_Size
- sizeof(AST*) * 3
- sizeof(Parser::Token*)
- sizeof(AST*)
- sizeof(StringCached)
- sizeof(CodeT)
- sizeof(ModuleFlag)
- sizeof(u32)
- sizeof(s32)
- sizeof(int)
)
/ sizeof(SpecifierT) - 1; // -1 for 4 extra bytes
/ sizeof(int) - 1; // -1 for 4 extra bytes
union {
struct
@ -251,11 +257,14 @@ 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* 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
SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers
struct {
SpecifierT ArrSpecs[ArrSpecs_Cap]; // Specifiers
AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
};
};
union {
AST* Prev;
@ -266,6 +275,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;
@ -277,7 +287,6 @@ struct AST
AccessSpec ParentAccess;
s32 NumEntries;
};
s32 Token; // Handle to the token, stored in the CodeFile (Otherwise unretrivable)
};
struct AST_POD
@ -307,11 +316,14 @@ 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* 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
SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers
StringCached Content; // Attributes, Comment, Execution, Include
struct {
SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers
AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used.
};
};
union {
AST* Prev;
@ -322,6 +334,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;
@ -333,9 +346,15 @@ struct AST_POD
AccessSpec ParentAccess;
s32 NumEntries;
};
s32 Token; // Handle to the token, stored in the CodeFile (Otherwise unretrivable)
};
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.
static_assert( sizeof(AST) == sizeof(AST_POD), "ERROR: AST IS NOT POD" );

View File

@ -12,54 +12,54 @@
struct AST_Body
{
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
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
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
StringCached Content;
};
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");
struct AST_Comment
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
StringCached Content;
};
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");
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,21 +71,21 @@ struct AST_Class
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
};
};
CodeType Last;
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");
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
@ -99,34 +99,34 @@ 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");
struct AST_Define
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
StringCached Content;
};
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");
struct AST_Destructor
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -139,18 +139,18 @@ 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");
struct AST_Enum
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -164,35 +164,35 @@ 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");
struct AST_Exec
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
StringCached Content;
};
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");
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 ];
@ -202,34 +202,34 @@ 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");
struct AST_Include
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
StringCached Content;
};
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");
struct AST_Friend
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -240,18 +240,18 @@ 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");
struct AST_Fn
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -264,34 +264,34 @@ 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");
struct AST_Module
{
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
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");
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;
@ -300,19 +300,19 @@ 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");
struct AST_Operator
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -324,21 +324,21 @@ 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");
struct AST_OpCast
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -352,18 +352,18 @@ 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");
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 ];
@ -375,65 +375,66 @@ 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");
struct AST_Pragma
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
StringCached Content;
};
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");
struct AST_PreprocessCond
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
StringCached Content;
};
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");
struct AST_Specifiers
{
SpecifierT ArrSpecs[ AST::ArrSpecs_Cap ];
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");
struct AST_Struct
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -445,21 +446,21 @@ struct AST_Struct
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
};
};
CodeType Last;
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");
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 ];
@ -470,19 +471,19 @@ 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");
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*) ];
@ -496,19 +497,19 @@ 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");
struct AST_Typedef
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -519,19 +520,19 @@ 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");
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*) ];
@ -543,19 +544,19 @@ 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");
struct AST_Using
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -567,19 +568,19 @@ 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");
struct AST_Var
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
struct
{
CodeComment InlineCmt;
@ -593,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");

View File

@ -1,5 +1,6 @@
#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)

View File

@ -1,5 +1,6 @@
#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)

View File

@ -1,5 +1,6 @@
#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)

View File

@ -1,5 +1,6 @@
#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)

View File

@ -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
{

View File

@ -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;

View File

@ -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 )
@ -418,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;
}

View File

@ -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<Token> 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();
@ -2284,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 )
@ -3909,7 +3922,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 )
@ -4772,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 );
@ -5050,8 +5063,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 );

View File

@ -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();

View File

@ -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;

View File

@ -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
{
@ -56,12 +65,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 );

View File

@ -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

View File

@ -1,4 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVESj
#ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once
# include "basic_types.hpp"
#endif

View File

@ -1,5 +1,7 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once
# include "filesystem.hpp"
# include "strings.hpp"
# include "string_ops.cpp"
#endif

View File

@ -1,3 +1,7 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# include "header_start.hpp"
#endif
#pragma region Macros and Includes
# include <stdio.h>

View File

@ -1,5 +1,6 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once
# include "string_ops.hpp"
# include "debug.cpp"
#endif

View File

@ -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++'