Staged metaprogramming in C++ for C/C++
Go to file
Ed_ 5d7dfaf666 Heavy refactor..
Isolating large macros to their own directory (components/temp).
- Plan is to remove them soon with proper generation.

Added additional component files, separating the old data_structures header for a set of ast headers.
Header_end also had its inlines extracted out.
Necessary to complete the macro isolation.

ZPL parser dependencies were removed from the core library along with builder, its now generated in bootstrap as pare of making a gen_builder set of files.

Singleheader will be changed in next few commits to reflect this as well (By making builder deps and components a conditional option).

Tests are most likely all broken for now.
2023-08-03 11:01:43 -04:00
.vscode Finished initial implmentation bootstrap generation and singleheader implementation. 2023-07-25 15:12:51 -04:00
docs More progress on parsing 2023-08-01 05:17:24 -04:00
project Heavy refactor.. 2023-08-03 11:01:43 -04:00
scripts Heavy refactor.. 2023-08-03 11:01:43 -04:00
singleheader Heavy refactor.. 2023-08-03 11:01:43 -04:00
test Heavy refactor.. 2023-08-03 11:01:43 -04:00
.editorconfig WIP Change to code types [ Broken ] 2023-07-13 23:01:20 -04:00
.gitignore Finished initial implmentation bootstrap generation and singleheader implementation. 2023-07-25 15:12:51 -04:00
gencpp.10x Naive preprocessor support initial implementation (compiles and runs, not heavily tested) 2023-07-30 01:21:04 -04:00
gencpp.sln Updated Project configuration with various editors 2023-04-10 17:55:09 -04:00
gencpp.sln.DotSettings.user Parsing constructors passed the sanity test! 2023-07-10 22:14:51 -04:00
gencpp.vcxproj Reorganization of files, refactors, doc updates (WIP) 2023-07-29 05:52:06 -04:00
gencpp.vcxproj.filters "compentiazation" of gen.hpp and gen.cpp 2023-07-24 17:45:27 -04:00
gencpp.vcxproj.user Started to fix some runtime bugs. 2023-05-08 20:54:24 -04:00
LICENSE Create LICENSE 2023-07-11 01:18:58 -04:00
Readme.md More progress on parsing 2023-08-01 05:17:24 -04:00

gencpp

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,
its not meant to be a black box metaprogramming utility, its meant for the user to extend for their 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.
The issues marked with v1.0 Feature indicate whats left before the library is considered feature complete.

A natvis and natstepfilter are provided in the scripts directory.

The editor and scanner have not been implemented yet. The scanner will come first, then the editor.

A C variant is hosted here; I will complete it when this library is feature complete, it should be easier to make than this...

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.

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.

In order to keep the locality of this code within the same files the following pattern may be used:

Within program.cpp :

#ifdef GEN_TIME
#include "gen.hpp"

...

u32 gen_main()
{
    ...
}
#endif

#ifndef GEN_TIME
#include "program.gen.cpp"

    // Regular runtime dependent on the generated code here.
#endif

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.

Example using each construction interface:

Upfront

Code t_uw           = def_type( name(uw) );
Code t_allocator    = def_type( name(allocator) );
Code t_string_const = def_type( name(char), def_specifiers( args( ESpecifier::Const, ESpecifier::Ptr ) ));

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) );
    Code body      = def_struct_body( args( num, cap, mem_alloc ) );

    header = def_struct( name(ArrayHeader), __, __, body );
}

Parse

Code header = parse_struct( code(
    struct ArrayHeader
    {
        uw        Num;
        uw        Capacity;
        allocator Allocator;
    };
));

Untyped

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( <content> ))

All three constrcuton interfaces will generate the following C code:

struct ArrayHeader
{
    uw        Num;
    uw        Capacity;
    allocator Allocator;
};

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...)

Building

See the scripts directory.