mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 07:44:45 -08:00
Readme : Updated usage.
This commit is contained in:
parent
1ba187e3d5
commit
3647cdefd1
117
Readme.md
117
Readme.md
@ -36,6 +36,7 @@ A metaprogram is built to generate files before the main program is built. We'll
|
|||||||
In order to keep the locality of this code within the same files the following pattern may be used:
|
In order to keep the locality of this code within the same files the following pattern may be used:
|
||||||
|
|
||||||
Within `program.cpp` :
|
Within `program.cpp` :
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include "gen.hpp"
|
#include "gen.hpp"
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ Within `program.cpp` :
|
|||||||
|
|
||||||
u32 gen_main()
|
u32 gen_main()
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -53,30 +54,90 @@ u32 gen_main()
|
|||||||
#ifndef gen_time
|
#ifndef gen_time
|
||||||
#include "program.gen.cpp"
|
#include "program.gen.cpp"
|
||||||
|
|
||||||
// Regular runtime dependent on the generated code here.
|
// Regular runtime dependent on the generated code here.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
```
|
```
|
||||||
This is ofc entirely optional and the metaprogram can be quite separated from the runtime in file organization.
|
|
||||||
|
|
||||||
The design a constructive builder of a sort of AST for the code to generate.
|
The design a constructive builder of a sort of AST for the code to generate.
|
||||||
The user is given `Code` typed objects that are used to build up the AST.
|
The user is given `Code` typed objects that are used to build up the AST.
|
||||||
|
|
||||||
Example:
|
Example using each construction interface:
|
||||||
|
|
||||||
|
#### Upfrontl
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
Code t_uw = def_type( name(uw) );
|
||||||
|
Code t_allocator = def_type( name(allocator) );
|
||||||
|
Code t_string_cosnt = def_type( name(char), def_specifiers( 3, ESpecifier::Const, ESpeciifer::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 = make_struct_body( num, cap, mem_alloc );
|
||||||
|
|
||||||
|
header = def_struct( name(ArrayHeader), __, __, body );
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Incremental
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Types are done the same with upfront. Incremental does not have a full interface replacment.
|
||||||
|
|
||||||
// Get a Code AST from the CodePool.
|
// Get a Code AST from the CodePool.
|
||||||
Code header = make_struct( "Header" );
|
Code header = make_struct( name(ArrayHeader) );
|
||||||
{
|
{
|
||||||
// Make a struct body.
|
// Make a struct body.
|
||||||
Code body = header.body();
|
Code body = header.body();
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
body->add( def_varaible( uw, "Num") );
|
body->add( def_variable( t_uw, name(Num)) );
|
||||||
body->add( def_varaible( uw, "Capacity") );
|
body->add( def_variable( t_uw, name(Capacity)) );
|
||||||
body->add( def_varaible( allocator, "Allocator") );
|
body->add( def_variable( t_allocator, name(Allocator)) );
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This will generate the following C code:
|
#### Parse
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
Code header = parse_struct( code(
|
||||||
|
struct ArrayHeader
|
||||||
|
{
|
||||||
|
uw Num;
|
||||||
|
uw Capacity;
|
||||||
|
allocator Allocator;
|
||||||
|
};
|
||||||
|
));
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Parse will automatically generate any types that have not been used previously.
|
||||||
|
|
||||||
|
#### Undtyped
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
Code header = untyped_str(
|
||||||
|
R("struct ArrayHeader
|
||||||
|
{
|
||||||
|
#define Using_ArrayHeader_Data \
|
||||||
|
uw Num; \
|
||||||
|
uw Capacity; \
|
||||||
|
allocator Allocator;
|
||||||
|
Using_ArrayHeader_Data
|
||||||
|
};)"
|
||||||
|
);
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
`name` is a helper macro for providing a string literal with its size, intended for the name paraemter of functions.
|
||||||
|
`code` is a helper macro for providing a string literal with its size, but intended for a code string parameters.
|
||||||
|
|
||||||
|
|
||||||
|
All three constrcuton interfaces will generate the following C code:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
struct ArrayHeader
|
struct ArrayHeader
|
||||||
{
|
{
|
||||||
@ -85,6 +146,7 @@ struct ArrayHeader
|
|||||||
allocator Allocator;
|
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.**
|
**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.**
|
||||||
|
|
||||||
## Gen's DSL
|
## Gen's DSL
|
||||||
@ -98,22 +160,35 @@ GEN_DEFINE_DSL
|
|||||||
Using the previous example to show usage:
|
Using the previous example to show usage:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
Code type_ns(uw) = type( uw );
|
||||||
|
Code type_ns(allocator) = type( allocator );
|
||||||
|
Code type_ns(string_const) = type( char, specifiers( Const, Ptr ) );
|
||||||
|
|
||||||
make( struct, ArrayHeader )
|
make( struct, ArrayHeader )
|
||||||
{
|
{
|
||||||
Code
|
Code
|
||||||
body = ArrayHeader.body();
|
body = ArrayHeader.body();
|
||||||
body->add_var( uw, Num );
|
body->add( variable( uw, Num ));
|
||||||
body->add_var( uw, Capacity );
|
body->add( variable( uw, Capacity ));
|
||||||
body->add_var( allocaotr, Allocator );
|
body->add( variable( allocaotr, Allocator ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Or using parse!
|
||||||
|
Code type_ns(uw) = type_code( uw );
|
||||||
|
Code type_ns(allocator) = type_code( allocator );
|
||||||
|
Code type_ns(string_const) = type_code( char const* );
|
||||||
|
|
||||||
|
Code header = struct_code(
|
||||||
|
struct ArrayHeader
|
||||||
|
{
|
||||||
|
uw Num;
|
||||||
|
uw Capacity;
|
||||||
|
allocator Allocator;
|
||||||
|
};
|
||||||
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
The `__` represents the `UnusedCode` value constant, of unneeded varaibles.
|
`type_ns` is a helper macro for providing refering to a typename if using the c-namespace naming convention.
|
||||||
The DSL purposefully has no nested macros, with the follwing exceptions:
|
|
||||||
|
|
||||||
* `__VA_ARGS__` for parameter expnasion
|
|
||||||
* `VA_NARGS( __VA_ARGS__ )` for determing number of paramters
|
|
||||||
* `txt(Value_)` and `txt_with_length(Value_)` to serialize a value type identifier.
|
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
@ -460,11 +535,11 @@ Thus a rule of thumb is if its a simple definition you can get away with just th
|
|||||||
|
|
||||||
However, if:
|
However, if:
|
||||||
|
|
||||||
* The code being generated becomes complex
|
* Your compile time complexity becomes large.
|
||||||
* You enjoy actually *seeing* the generated code instead of just the error symbols or the pdb symbols.
|
* You enjoy actually *seeing* the generated code instead of just the error symbols or the pdb symbols.
|
||||||
* You value your debugging expereince, and would like to debug your metaprogram, without having to step through the debug version of the compiler (if you even can)
|
* You value your debugging expereince, and would like to debug your metaprogram, without having to step through the debug version of the compiler (if you even can)
|
||||||
* You want to roll your own runtime reflection system
|
* Want to roll your own reflection system
|
||||||
* You want to maintain a series of libraries for internal use, but don't want to deal with manaual merging as often when they update.
|
* Want to maintain a series of libraries for internal use, but don't want to deal with manaual merging as often when they update.
|
||||||
* Want to create tailored headers for your code or for your libraries since you usually don't need the majority of the code within them.
|
* Want to create tailored headers for your code or for your libraries since you usually don't need the majority of the code within them.
|
||||||
|
|
||||||
Then this might help you boostrap a toolset todo so.
|
Then this might help you boostrap a toolset todo so.
|
||||||
|
Loading…
Reference in New Issue
Block a user