diff --git a/.gitignore b/.gitignore index 92a34a8..c52c02d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ build/* .vs **/*.gen.* +**/gen/gen.hpp +**/gen/gen.cpp gencpp.hpp gencpp.cpp diff --git a/Readme.md b/Readme.md index 6e10d65..3fc44da 100644 --- a/Readme.md +++ b/Readme.md @@ -48,13 +48,15 @@ The project has no external dependencies beyond: Dependencies for the project are wrapped within `GENCPP_ROLL_OWN_DEPENDENCIES` (Defining it will disable them). The majority of the dependency's implementation was derived from the [c-zpl library](https://github.com/zpl-c/zpl). -This library was written a subset of C++ where the following are avoided: +This library was written a subset of C++ where the following are not used at all: * RAII (Constructors/Destructors), lifetimes are managed using named static or regular functions. * Language provide dynamic dispatch, RTTI * Object-Oriented Inheritance +* Exceptions -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. +There are only 4 template definitions in the entire library. (`Array`, `Hashtable`, `swap`, and `AST/Code::cast`) A `natvis` and `natstepfilter` are provided in the scripts directory. @@ -133,19 +135,20 @@ Code header = parse_struct( code( ### Untyped ```cpp -Code header = untyped_str( code( +Code header = code_str( struct ArrayHeader { uw Num; uw Capacity; allocator Allocator; }; -)); +); ``` `name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions. `code` is a helper macro for providing a string literal with its size, but intended for code string parameters. `args` is a helper macro for providing the number of arguments to varadic constructors. +`code_str` is a helper macro for writting `untyped_str( code( ))` All three constrcuton interfaces will generate the following C code: @@ -164,6 +167,8 @@ struct ArrayHeader An example of building is provided within project, singleheader, and test. +(All generated files go to a corresponding `*/gen` directory) + **Project** `gen.bootstrap.cpp` generates a segmented version of the library following a more traditional cpp convention. @@ -171,7 +176,7 @@ With the exception that: *The component hpp and cpp files are all included into **Singleheader** -`gen.singleheader.cpp` generated a single-header version of the library following the convention shown in popular libraries such as: gb, stb, and zpl. +`gen.singleheader.cpp` generates a single-header version of the library following the convention shown in popular libraries such as: gb, stb, and zpl. **Test** @@ -285,12 +290,12 @@ The width dictates how much the static array can hold before it must give way to constexpr static uw ArrSpecs_Cap = ( - AST_POD_Size - - sizeof(AST*) * 3 - - sizeof(StringCached) - - sizeof(CodeT) - - sizeof(ModuleFlag) - - sizeof(s32) + AST_POD_Size + - sizeof(AST*) * 3 + - sizeof(StringCached) + - sizeof(CodeT) + - sizeof(ModuleFlag) + - sizeof(s32) ) / sizeof(SpecifierT) -1; // -1 for 4 extra bytes (Odd num of AST*) ``` @@ -330,6 +335,8 @@ Two generic templated containers are used throughout the library: Both Code and AST definitions have a `template< class Type> Code/AST cast()`. Its just an alternative way to explicitly cast to each other. +`template< class Type> swap( Type& a, Type& b)` is used over a macro. + Otherwise the library is free of any templates. The following CodeTypes are used which the user may optionally use strong typing with if they enable: `GEN_ENFORCE_STRONG_CODE_TYPES` @@ -704,7 +711,8 @@ 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. -If extendeding parsing capability, ECode, ESpecifier, may need to be modified along with making a new `AST_` and `Code` if its desired to preserve the same interface. The lexer (see the `Parser` namespace in `gen.cpp`) will most likely also need to be extended to support any unsupported or custom tokens. +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. # TODO @@ -720,7 +728,7 @@ If extendeding parsing capability, ECode, ESpecifier, may need to be modified al * It would allow me to remove the filesystem dependencies and related functions outside of gen base headers. ( At least 1k loc reduced ) * ADT and the CSV parser depend on it as well. The `str_fmt_file` related functions do as well but they can be ommited. * Scanner and editor will also depend on it so they would need to include w/e the depency header for all three file-interacting interfaces. - * `gen.dep.files.hpp` + * `gen.files_handling.hpp` * Convert GlobalAllocator to a slab allocator: ```md diff --git a/project/Readme.md b/project/Readme.md index 44800ab..3269add 100644 --- a/project/Readme.md +++ b/project/Readme.md @@ -1,6 +1,6 @@ # Documentation -The core library is contained within `gen.hpp` and `gen.cpp`. +The core library is contained within `gen.hpp` and `gen.cpp`. Things related to the editor and scanner are in their own respective files. (Ex: `gen.scanner.` ) Dependencies are within `gen.dep.` @@ -8,11 +8,12 @@ Dependencies are within `gen.dep.` The library is fragmented into a series of headers and sources files meant to be scanned in and then generated to a tailored format for the target `gen` files. -Both libraries use *pre-generated* (self-hosting I guess) version of the library to then generate the latest version of itself. +Both libraries use *pre-generated* (self-hosting I guess) version of the library to then generate the latest version of itself. (sort of a verification that the generated version is equivalent) -The default `gen.bootstrap.cpp` located in the project folder is meant to be produce a standard segmeneted library, where the components of the library -have relatively dedicated header and source files. With dependencies included at the top of the file and each header starting with a pragma once. +The default `gen.bootstrap.cpp` located in the project folder is meant to be produce a standard segmeneted library (WIP), where the components of the library +have relatively dedicated header and source files. With dependencies included at the top of the file and each header starting with a pragma once. +This will overwrite the existing library implementation in the immediate directory. Use those to get a general idea of how to make your own tailored version. diff --git a/project/gen.bootstrap.cpp b/project/gen.bootstrap.cpp index a784e37..aa9688c 100644 --- a/project/gen.bootstrap.cpp +++ b/project/gen.bootstrap.cpp @@ -50,7 +50,7 @@ int gen_main() Code header_start = scan_file( "components/gen.header_start.hpp" ); Code nspace_macro = untyped_str( namespace_by_default ? nspace_default : nspace_non_default ); - gen_header.open( "gencpp.hpp" ); + gen_header.open( "gen/gen.hpp" ); gen_header.print_fmt("#pragma once\n\n"); gen_header.print( push_ignores ); gen_header.print( header_start ); diff --git a/scripts/bootstrap.ci.ps1 b/scripts/bootstrap.ci.ps1 index f10c4e1..8a3158a 100644 --- a/scripts/bootstrap.ci.ps1 +++ b/scripts/bootstrap.ci.ps1 @@ -16,6 +16,7 @@ foreach ( $arg in $args ) $path_root = git rev-parse --show-toplevel $path_project = Join-Path $path_root project $path_project_build = Join-Path $path_project build +$path_project_gen = Join-Path $path_project gen write-host "`n`nBuilding gencpp bootstrap`n" @@ -41,6 +42,10 @@ Push-Location $path_root Pop-Location Push-location $path_project +if ( -not(Test-Path($path_project_gen) )) { + New-Item -ItemType Directory -Path $path_project_gen +} + # Run meta-program $gencpp_bootstrap = Join-Path $path_project_build gencpp_bootstrap.exe diff --git a/scripts/clean.ps1 b/scripts/clean.ps1 index 1477f01..c49abf5 100644 --- a/scripts/clean.ps1 +++ b/scripts/clean.ps1 @@ -7,6 +7,8 @@ $path_gen_build = Join-Path $path_gen build $path_test_build = Join-Path $path_test build $path_project_build = Join-Path $path_project build $path_singleheader_build = Join-Path $path_singleheader build +$path_project_gen = Join-Path $path_project gen +$path_singleheader_gen = Join-Path $path_singleheader gen if ( Test-Path $path_project_build) { @@ -28,17 +30,17 @@ if ( Test-Path $path_gen_build ) Remove-Item $path_gen_build -Recurse } -[string[]] $include = 'gencpp.hpp', 'gencpp.cpp' +[string[]] $include = 'gen.hpp', 'gen.cpp' [string[]] $exclude = -$files = Get-ChildItem -Recurse -Path $path_project -Include $include -Exclude $exclude +$files = Get-ChildItem -Recurse -Path $path_project_gen -Include $include -Exclude $exclude if ( $files ) { Remove-Item $files } -$files = Get-ChildItem -Recurse -Path $path_singleheader -Include $include -Exclude $exclude +$files = Get-ChildItem -Recurse -Path $path_singleheader_gen -Include $include -Exclude $exclude if ( $files ) { diff --git a/scripts/singleheader.ci.ps1 b/scripts/singleheader.ci.ps1 index 628d2d9..a9a042e 100644 --- a/scripts/singleheader.ci.ps1 +++ b/scripts/singleheader.ci.ps1 @@ -16,6 +16,7 @@ foreach ( $arg in $args ) $path_root = git rev-parse --show-toplevel $path_singleheader = Join-Path $path_root singleheader $path_singleheader_build = Join-Path $path_singleheader build +$path_singleheader_gen = Join-Path $path_singleheader gen write-host "`n`nBuilding gencpp bootstrap`n" @@ -41,6 +42,10 @@ Push-Location $path_root Pop-Location Push-location $path_singleheader +if ( -not(Test-Path($path_singleheader_gen) )) { + New-Item -ItemType Directory -Path $path_singleheader_gen +} + # Run meta-program $gencpp_singleheader = Join-Path $path_singleheader_build gencpp_singleheader.exe diff --git a/singleheader/gen.singleheader.cpp b/singleheader/gen.singleheader.cpp index 9af9306..0967a6c 100644 --- a/singleheader/gen.singleheader.cpp +++ b/singleheader/gen.singleheader.cpp @@ -50,7 +50,7 @@ int gen_main() Code nspace_macro = untyped_str( namespace_by_default ? nspace_default : nspace_non_default ); Builder gen_header; - gen_header.open( "gencpp.hpp" ); + gen_header.open( "gen/gen.hpp" ); gen_header.print( push_ignores ); // Headers