Updates to docs and scripts

This commit is contained in:
Edward R. Gonzalez 2024-12-10 16:38:01 -05:00
parent 2c51a2f9c8
commit 8e3e66b3c1
6 changed files with 86 additions and 171 deletions

View File

@ -5,26 +5,26 @@ An attempt at simple staged metaprogramming for C/C++.
The library API is a composition of code element constructors, and a non-standards-compliant single-pass C/C++ parser. The library API is a composition of code element constructors, and a non-standards-compliant single-pass C/C++ parser.
These build up a code AST to then serialize with a file builder, or can be traversed for staged-reflection of C/C++ code. These build up a code AST to then serialize with a file builder, or can be traversed for staged-reflection of C/C++ code.
This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto). This code base attempts follow the [handmade philosophy](https://handmade.network/manifesto).
Its not meant to be a black box metaprogramming utility, it should be easy to intergrate into a user's project domain. Its not meant to be a black box metaprogramming utility, it should be easy to intergrate into a user's project domain.
# Documentation
[]
## Notes ## Notes
**On Partial Hiatus: Life has got me tackling other issues..** **On Partial Hiatus: Life has got me tackling other issues..**
I will be passively updating the library with bug fixes and minor improvements as I use it for my personal projects. I will be passively updating the library with bug fixes and minor improvements as I use it for my personal projects.
There won't be any major reworks or features to this thing for a while. There won't be any major reworks or features to this thing for a while.
This project is still in development (very much an alpha state), so expect bugs and missing features. 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. See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos.
The library can already be used to generate code just fine, but the parser is where the most work is needed. If your C++ isn't "down to earth" expect issues. 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). A `natvis` and `natstepfilter` are provided in the scripts directory (its outdated, I'll update this readme when its not).
***The editor and scanner have not been implemented yet. The scanner will come first, then the editor.***
A C variant is hosted [here](https://github.com/Ed94/genc); I will complete it when this library is feature complete, it should be easier to make than this...
## Usage ## Usage
A metaprogram is built to generate files before the main program is built. We'll term runtime for this program as `GEN_TIME`. The metaprogram's core implementation are within `gen.hpp` and `gen.cpp` in the project directory. A metaprogram is built to generate files before the main program is built. We'll term runtime for this program as `GEN_TIME`. The metaprogram's core implementation are within `gen.hpp` and `gen.cpp` in the project directory.
@ -56,7 +56,7 @@ u32 gen_main()
#endif #endif
``` ```
The design uses a constructive builder API for the code to generate. The design uses a constructive builder API for the code to generate.
The user is provided `Code` objects that are used to build up the AST. The user is provided `Code` objects that are used to build up the AST.
Example using each construction interface: Example using each construction interface:
@ -112,8 +112,8 @@ Code header = code_str(
); );
``` ```
`name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions. `name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions.
`code` is a helper macro for providing a string literal with its size, but intended for code string parameters. `code` is a helper macro for providing a string literal with its size, but intended for code string parameters.
`args` is a helper macro for providing the number of arguments to varadic constructors. `args` is a helper macro for providing the number of arguments to varadic constructors.
`code_str` is a helper macro for writting `untyped_str( code( <content> ))` `code_str` is a helper macro for writting `untyped_str( code( <content> ))`

View File

@ -25,19 +25,6 @@ Standard formats:
Code not making up the core library is located in `auxiliary/<auxiliary_name>.<hpp/cpp>`. These are optional extensions or tools for the library. Code not making up the core library is located in `auxiliary/<auxiliary_name>.<hpp/cpp>`. These are optional extensions or tools for the library.
Feature Macros:
* `GEN_DEFINE_ATTRIBUTE_TOKENS` : Allows user to define their own attribute macros for use in parsing.
* This is auto-generated if using the bootstrap or single-header generation
* *Note: The user will use the `AttributeTokens.csv` when the library is fully self-hosting.*
* `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage
* `GEN_DONT_ENFORCE_GEN_TIME_GUARD` : By default, the library ( gen.hpp/ gen.cpp ) expects the macro `GEN_TIME` to be defined, this disables that.
* `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.
* `GEN_C_LIKE_PP` : Will prevent usage of function defnitions using references and structs with member functions.
Structs will still have user-defined operator conversions, for-range support, and other operator overloads
*Note: A variant of the C++ library could be generated where those additonal support features are removed (see gen_c_library implementation for an idea of how)* *Note: A variant of the C++ library could be generated where those additonal support features are removed (see gen_c_library implementation for an idea of how)*

View File

@ -14,7 +14,7 @@ The project has no external dependencies beyond:
* `io.h` (Windows with gcc) * `io.h` (Windows with gcc)
* `windows.h` (Windows) * `windows.h` (Windows)
Dependencies for the project are wrapped within `GENCPP_ROLL_OWN_DEPENDENCIES` (Defining it will disable them). Dependencies for the project are wrapped within `GENCPP_ROLL_OWN_DEPENDENCIES` (Defining it will disable them).
The majority of the dependency's implementation was derived from the [c-zpl library](https://github.com/zpl-c/zpl). The majority of the dependency's implementation was derived from the [c-zpl library](https://github.com/zpl-c/zpl).
This library was written in a subset of C++ where the following are not used at all: This library was written in a subset of C++ where the following are not used at all:
@ -24,10 +24,10 @@ This library was written in a subset of C++ where the following are not used at
* Object-Oriented Inheritance * Object-Oriented Inheritance
* Exceptions * Exceptions
Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads. Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.
The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C (WIP). The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C (WIP).
There are only 4 template definitions in the entire library. (`Array<Type>`, `Hashtable<Type>`, `swap<Type>`, and `AST/Code::cast<Type>`) There are only 4 template definitions in the entire library (C++ versions). (`Array<Type>`, `Hashtable<Type>`, `swap<Type>`, and `AST/Code::cast<Type>`)
Two generic templated containers are used throughout the library: Two generic templated containers are used throughout the library:
@ -43,94 +43,46 @@ Otherwise the library is free of any templates.
### *WHAT IS NOT PROVIDED* ### *WHAT IS NOT PROVIDED*
**There is no support for validating expressions.** **There is no support for validating expressions.**
Its difficult to parse without enough benefits (At the metaprogramming level). Its a [todo](https://github.com/Ed94/gencpp/issues/49)
I plan to add this only at the tail of the project parsing milestone.
**Only trivial template support is provided.** **Only trivial template support is provided.**
The intention is for only simple, non-recursive substitution. The intention is for only simple, non-recursive substitution.
The parameters of the template are treated like regular parameter AST entries. The parameters of the template are treated like regular parameter AST entries.
This means that the typename entry for the parameter AST would be either: This means that the typename entry for the parameter AST would be either:
* `class` * `class`
* `typename` * `typename`
* A fundamental type, function, or pointer type. * A fundamental type, function, or pointer type.
Anything beyond this usage is not supported by parse_template for arguments (at least not intentionally). ***Concepts and Constraints are not supported***
Use at your own mental peril. Its a [todo](https://github.com/Ed94/gencpp/issues/21)
*Concepts and Constraints are not supported, its usage is non-trivial substitution.* ### Feature Macros:
* `GEN_DEFINE_ATTRIBUTE_TOKENS` : Allows user to define their own attribute macros for use in parsing.
* This is auto-generated if using the bootstrap or single-header generation
* *Note: The user will use the `AttributeTokens.csv` when the library is fully self-hosting.*
* `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage
* `GEN_DONT_ENFORCE_GEN_TIME_GUARD` : By default, the library ( gen.hpp/ gen.cpp ) expects the macro `GEN_TIME` to be defined, this disables that.
* `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.
* `GEN_C_LIKE_PP` : Will prevent usage of function defnitions using references and structs with member functions.
Structs will still have user-defined operator conversions, for-range support, and other operator overloads
### The Data & Interface ### The Data & Interface
As mentioned in root readme, the user is provided Code objects by calling the constructor's functions to generate them or find existing matches. As mentioned in root readme, the user is provided Code objects by calling the constructor's functions to generate them or find existing matches.
The AST is managed by the library and provided to the user via its interface. The AST is managed by the library and provided to the user via its interface.
However, the user may specifiy memory configuration. However, the user may specifiy memory configuration.
Data layout of AST struct (Subject to heavily change with upcoming redesign): [Data layout of AST struct (Subject to heavily change with upcoming todos)](C:\projects\gencpp\base\components\ast.hpp#L396-462)
```cpp *`CodeT` is a typedef for `ECode::Type` which has an underlying type of `u32`*
union { *`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`*
struct *`StringCahced` is a typedef for `String const`, to denote it is an interned string*
{
AST* InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
AST* Specs; // Destructor, Function, Operator, Typename, Variable
union {
AST* InitializerList; // Constructor
AST* ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces.
AST* ReturnType; // Function, Operator, Typename
AST* UnderlyingType; // Enum, Typedef
AST* ValueType; // Parameter, Variable
};
union {
AST* Macro; // Parameters
AST* BitfieldSize; // Variable (Class/Struct Data Member)
AST* Params; // Constructor, Function, Operator, Template, Typename
};
union {
AST* ArrExpr; // Typename
AST* Body; // Class, Constructr, Destructor, Enum, Function, Namespace, Struct, Union
AST* Declaration; // Friend, Template
AST* Value; // Parameter, Variable
};
union {
AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
AST* SpecsFuncSuffix; // Only used with typenames, to store the function suffix if typename is function signature.
};
};
StringCached Content; // Attributes, Comment, Execution, Include
struct {
SpecifierT ArrSpecs[AST_ArrSpecs_Cap]; // Specifiers
AST* NextSpecs; // Specifiers
};
};
union {
AST* Prev;
AST* Front;
AST* Last;
};
union {
AST* Next;
AST* Back;
};
AST* Parent;
StringCached Name;
CodeT Type;
ModuleFlag ModuleFlags;
union {
b32 IsFunction; // Used by typedef to not serialize the name field.
b32 IsParamPack; // Used by typename to know if type should be considered a parameter pack.
OperatorT Op;
AccessSpec ParentAccess;
s32 NumEntries;
};
s32 Token; // Handle to the token, stored in the CodeFile (Otherwise unretrivable)
```
*`CodeT` is a typedef for `ECode::Type` which has an underlying type of `u32`*
*`OperatorT` is a typedef for `EOperator::Type` which has an underlying type of `u32`*
*`StringCahced` is a typedef for `String const`, to denote it is an interned string*
*`String` is the dynamically allocated string type for the library* *`String` is the dynamically allocated string type for the library*
AST widths are setup to be AST_POD_Size. AST widths are setup to be AST_POD_Size.
@ -302,7 +254,7 @@ def_global_body( args( ht_entry, array_ht_entry, hashtable ));
def_global_body( 3, ht_entry, array_ht_entry, hashtable ); def_global_body( 3, ht_entry, array_ht_entry, hashtable );
``` ```
If a more incremental approach is desired for the body ASTs, `Code def_body( CodeT type )` can be used to create an empty body. If a more incremental approach is desired for the body ASTs, `Code def_body( CodeT type )` can be used to create an empty body.
When the members have been populated use: `AST::validate_body` to verify that the members are valid entires for that type. When the members have been populated use: `AST::validate_body` to verify that the members are valid entires for that type.
### Parse construction ### Parse construction
@ -354,7 +306,7 @@ Interface :
* untyped_fmt * untyped_fmt
* untyped_token_fmt * untyped_token_fmt
During serialization any untyped Code AST has its string value directly injected inline of whatever context the content existed as an entry within. During serialization any untyped Code AST has its string value directly injected inline of whatever context the content existed as an entry within.
Even though these are not validated from somewhat correct c/c++ syntax or components, it doesn't mean that Untyped code can be added as any component of a Code AST: Even though these are not validated from somewhat correct c/c++ syntax or components, it doesn't mean that Untyped code can be added as any component of a Code AST:
* Untyped code cannot have children, thus there cannot be recursive injection this way. * Untyped code cannot have children, thus there cannot be recursive injection this way.
@ -474,11 +426,8 @@ and have the desired specifiers assigned to them beforehand.
There are three provided auxillary interfaces: There are three provided auxillary interfaces:
* Builder * Builder
* Editor
* Scanner * Scanner
Editor and Scanner are disabled by default, use `GEN_FEATURE_EDITOR` and `GEN_FEATURE_SCANNER` to enable them.
### Builder is a similar object to the jai language's string_builder ### Builder is a similar object to the jai language's string_builder
* The purpose of it is to generate a file. * The purpose of it is to generate a file.

View File

@ -3,36 +3,15 @@
# That or just rewrite it in an sh script and call it a day. # That or just rewrite it in an sh script and call it a day.
$devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1' $devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1'
$format_cpp = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1' $misc = Join-Path $PSScriptRoot 'helpers/misc.psm1'
$refactor_c_library = Join-Path $PSScriptRoot 'refactor_c_library.ps1' $refactor_c_library = Join-Path $PSScriptRoot 'refactor_c_library.ps1'
$refactor_unreal = Join-Path $PSScriptRoot 'refactor_unreal.ps1' $refactor_unreal = Join-Path $PSScriptRoot 'refactor_unreal.ps1'
$incremental_checks = Join-Path $PSScriptRoot 'helpers/incremental_checks.ps1' $incremental_checks = Join-Path $PSScriptRoot 'helpers/incremental_checks.ps1'
$vendor_toolchain = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1' $vendor_toolchain = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1'
function Get-ScriptRepoRoot { Import-Module $misc
$currentPath = $PSScriptRoot
while ($currentPath -ne $null -and $currentPath -ne "")
{
if (Test-Path (Join-Path $currentPath ".git")) {
return $currentPath
}
# Also check for .git file which indicates a submodule
$gitFile = Join-Path $currentPath ".git"
if (Test-Path $gitFile -PathType Leaf)
{
$gitContent = Get-Content $gitFile
if ($gitContent -match "gitdir: (.+)") {
return $currentPath
}
}
$currentPath = Split-Path $currentPath -Parent
}
throw "Unable to find repository root"
}
$path_root = Get-ScriptRepoRoot
# Import-Module $target_arch $path_root = Get-ScriptRepoRoot
Import-Module $format_cpp
Push-Location $path_root Push-Location $path_root

View File

@ -1,62 +1,42 @@
$path_root = git rev-parse --show-toplevel $path_root = git rev-parse --show-toplevel
$path_project = Join-Path $path_root project $path_base = Join-Path $path_root base
$path_project_build = Join-Path $path_project build $path_base_build = Join-Path $path_base build
$path_project_gen = Join-Path $path_project gen $path_singleheader = Join-Path $path_root singleheader
$path_singleheader = Join-Path $path_root singleheader
$path_singleheader_build = Join-Path $path_singleheader build $path_singleheader_build = Join-Path $path_singleheader build
$path_singleheader_gen = Join-Path $path_singleheader gen $path_singleheader_gen = Join-Path $path_singleheader gen
$path_test = Join-Path $path_root test $path_unreal = Join-Path $paht_root unreal
$path_test_build = Join-Path $path_test build $path_unreal_build = Join-Path $path_unreal build
$path_test_gen = Join-Path $path_test gen $path_unreal_gen = Join-Path $path_unreal gen
$path_x64 = Join-Path $path_root x64 $path_test = Join-Path $path_root test
$path_release = Join-Path $path_root release $path_test_build = Join-Path $path_test build
$path_test_gen = Join-Path $path_test gen
$path_x64 = Join-Path $path_root x64
$path_release = Join-Path $path_root release
if ( Test-Path $path_project_build) if ( Test-Path $path_project_build) {
{
Remove-Item $path_project_build -Recurse Remove-Item $path_project_build -Recurse
} }
if ( Test-Path $path_project_gen ) {
if ( Test-Path $path_project_gen )
{
Remove-Item $path_project_gen -Recurse Remove-Item $path_project_gen -Recurse
} }
if ( Test-Path $path_singleheader_build) {
if ( Test-Path $path_singleheader_build)
{
Remove-Item $path_singleheader_build -Recurse Remove-Item $path_singleheader_build -Recurse
} }
if ( Test-Path $path_singleheader_gen ) {
if ( Test-Path $path_singleheader_gen )
{
Remove-Item $path_singleheader_gen -Recurse Remove-Item $path_singleheader_gen -Recurse
} }
if ( Test-Path $path_unreal ) {
if ( Test-Path $path_test_build ) Remove-Item $path_unreal_build -Recurse
{ }
if ( Test-Path $path_test_build ) {
Remove-Item $path_test_build -Recurse Remove-Item $path_test_build -Recurse
} }
if ( Test-Path $path_test_gen ) {
if ( Test-Path $path_test_gen )
{
Remove-Item $path_test_gen -Recurse Remove-Item $path_test_gen -Recurse
} }
if ( Test-Path $path_x64) {
if ( Test-Path $path_x64)
{
Remove-Item $path_x64 -Recurse Remove-Item $path_x64 -Recurse
} }
if ( Test-Path $path_release ) {
if ( Test-Path $path_release )
{
Remove-Item $path_release -Recurse Remove-Item $path_release -Recurse
} }
$include = '*.h', '*.hpp', '*.cpp'
$exclude =
$files = Get-ChildItem -Recurse -Path $path_gen -Include $include -Exclude $exclude
if ( $files )
{
Remove-Item $files
}

20
scripts/helpers/misc.psm1 Normal file
View File

@ -0,0 +1,20 @@
function Get-ScriptRepoRoot {
$currentPath = $PSScriptRoot
while ($currentPath -ne $null -and $currentPath -ne "")
{
if (Test-Path (Join-Path $currentPath ".git")) {
return $currentPath
}
# Also check for .git file which indicates a submodule
$gitFile = Join-Path $currentPath ".git"
if (Test-Path $gitFile -PathType Leaf)
{
$gitContent = Get-Content $gitFile
if ($gitContent -match "gitdir: (.+)") {
return $currentPath
}
}
$currentPath = Split-Path $currentPath -Parent
}
throw "Unable to find repository root"
}