2023-04-01 22:07:44 -07:00
# gencpp
An attempt at simple staged metaprogramming for c/c++.
2023-07-18 21:14:15 -07:00
The library API is a composition of code element constructors.
2023-04-22 19:24:55 -07:00
These build up a code AST to then serialize with a file builder.
2023-07-24 11:30:35 -07:00
This code base attempts follow the [handmade philosophy ](https://handmade.network/manifesto ),
its not meant to be a black box metaprogramming utility, its meant for the user to extend for their project domain.
2023-04-03 00:55:28 -07:00
## Notes
2023-07-29 02:52:06 -07:00
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.
The [issues ](https://github.com/Ed94/gencpp/issues ) marked with v1.0 Feature indicate whats left before the library is considered feature complete.
2023-07-24 08:20:13 -07:00
2023-07-15 20:38:53 -07:00
A `natvis` and `natstepfilter` are provided in the scripts directory.
2023-07-12 00:15:52 -07:00
***The editor and scanner have not been implemented yet. The scanner will come first, then the editor.***
2023-06-28 22:37:42 -07:00
2023-08-01 02:17:24 -07:00
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...
2023-07-15 23:26:55 -07:00
2023-04-03 23:04:19 -07:00
## Usage
2023-04-01 22:07:44 -07:00
2023-07-18 21:14:15 -07:00
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.
2023-04-01 22:07:44 -07:00
2023-04-02 09:35:14 -07:00
`gen.cpp` \`s `main()` is defined as `gen_main()` which the user will have to define once for their program. There they will dictate everything that should be generated.
2023-04-01 22:07:44 -07:00
In order to keep the locality of this code within the same files the following pattern may be used:
Within `program.cpp` :
2023-04-07 23:16:25 -07:00
2023-04-01 22:07:44 -07:00
```cpp
2023-07-18 21:14:15 -07:00
#ifdef GEN_TIME
2023-04-01 22:07:44 -07:00
#include "gen.hpp"
...
u32 gen_main()
{
2023-04-07 23:16:25 -07:00
...
2023-04-01 22:07:44 -07:00
}
#endif
2023-07-18 21:14:15 -07:00
#ifndef GEN_TIME
2023-04-01 22:07:44 -07:00
#include "program.gen.cpp"
2023-04-07 23:16:25 -07:00
// Regular runtime dependent on the generated code here.
2023-04-01 22:07:44 -07:00
#endif
2023-04-07 23:16:25 -07:00
2023-04-01 22:07:44 -07:00
```
2023-07-12 00:15:52 -07:00
The design uses a constructive builder API for the code to generate.
2023-07-29 02:52:06 -07:00
The user is provided `Code` objects that are used to build up the AST.
2023-04-03 23:04:19 -07:00
2023-04-07 23:16:25 -07:00
Example using each construction interface:
2023-04-22 19:24:55 -07:00
### Upfront
2023-04-07 23:16:25 -07:00
```cpp
Code t_uw = def_type( name(uw) );
Code t_allocator = def_type( name(allocator) );
2023-07-12 00:41:16 -07:00
Code t_string_const = def_type( name(char), def_specifiers( args( ESpecifier::Const, ESpecifier::Ptr ) ));
2023-04-07 23:16:25 -07:00
Code header;
{
Code num = def_variable( t_uw, name(Num) );
Code cap = def_variable( t_uw, name(Capacity) );
Code mem_alloc = def_variable( t_allocator, name(Allocator) );
2023-07-12 00:41:16 -07:00
Code body = def_struct_body( args( num, cap, mem_alloc ) );
2023-04-07 23:16:25 -07:00
header = def_struct( name(ArrayHeader), __ , __ , body );
}
```
2023-04-22 19:24:55 -07:00
### Parse
2023-04-07 23:16:25 -07:00
```cpp
Code header = parse_struct( code(
struct ArrayHeader
{
uw Num;
uw Capacity;
allocator Allocator;
};
));
```
2023-06-28 22:37:42 -07:00
### Untyped
2023-04-07 23:16:25 -07:00
```cpp
2023-07-24 20:10:10 -07:00
Code header = code_str(
2023-04-22 19:24:55 -07:00
struct ArrayHeader
2023-04-07 23:16:25 -07:00
{
2023-04-22 19:24:55 -07:00
uw Num;
uw Capacity;
2023-04-07 23:16:25 -07:00
allocator Allocator;
2023-04-22 19:24:55 -07:00
};
2023-07-24 20:10:10 -07:00
);
2023-04-07 23:16:25 -07:00
```
2023-07-18 21:14:15 -07:00
`name` is a helper macro for providing a string literal with its size, intended for the name parameter of functions.
2023-07-12 00:41:16 -07:00
`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.
2023-07-24 20:10:10 -07:00
`code_str` is a helper macro for writting `untyped_str( code( <content> ))`
2023-04-07 23:16:25 -07:00
All three constrcuton interfaces will generate the following C code:
2023-04-03 23:04:19 -07:00
```cpp
struct ArrayHeader
{
2023-04-04 13:13:48 -07:00
uw Num;
uw Capacity;
allocator Allocator;
2023-04-03 23:04:19 -07:00
};
```
2023-04-07 23:16:25 -07:00
2023-04-03 23:04:19 -07:00
**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.**
2023-07-29 02:52:06 -07:00
*(The library currently uses clang-format for formatting, beaware its pretty slow...)*
2023-04-03 23:04:19 -07:00
2023-04-01 22:07:44 -07:00
## Building
2023-07-29 02:52:06 -07:00
See the [scripts directory ](scripts/ ).