mirror of
https://github.com/Ed94/gencpp.git
synced 2024-11-10 02:54:53 -08:00
Upfront constructors almost completely fleshed out.
This commit is contained in:
parent
03d37d614b
commit
6ca30828c0
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@ -8,7 +8,13 @@
|
|||||||
"xtr1common": "cpp",
|
"xtr1common": "cpp",
|
||||||
"xutility": "cpp",
|
"xutility": "cpp",
|
||||||
"initializer_list": "cpp",
|
"initializer_list": "cpp",
|
||||||
"table.h": "c"
|
"table.h": "c",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"xmemory": "cpp"
|
||||||
},
|
},
|
||||||
"C_Cpp.intelliSenseEngineFallback": "disabled"
|
"C_Cpp.intelliSenseEngineFallback": "disabled"
|
||||||
}
|
}
|
@ -109,9 +109,9 @@ sw token_fmt_va( char* buf, uw buf_size, char const* fmt, s32 num_tokens, va_lis
|
|||||||
|
|
||||||
char const* token = fmt;
|
char const* token = fmt;
|
||||||
|
|
||||||
s32 key = crc32( token, tok_len );
|
u32 key = crc32( token, tok_len );
|
||||||
TokEntry value = * tokmap_get( & tok_map, key );
|
TokEntry value = * tokmap_get( & tok_map, key );
|
||||||
s32 left = value.Length;
|
sw left = value.Length;
|
||||||
|
|
||||||
while ( left-- )
|
while ( left-- )
|
||||||
{
|
{
|
||||||
|
@ -61,9 +61,11 @@ using zpl::alloc;
|
|||||||
using zpl::arena_allocator;
|
using zpl::arena_allocator;
|
||||||
using zpl::arena_init_from_memory;
|
using zpl::arena_init_from_memory;
|
||||||
using zpl::arena_free;
|
using zpl::arena_free;
|
||||||
|
using zpl::bprintf;
|
||||||
using zpl::char_is_alpha;
|
using zpl::char_is_alpha;
|
||||||
using zpl::char_is_space;
|
using zpl::char_is_space;
|
||||||
using zpl::crc32;
|
using zpl::crc32;
|
||||||
|
using zpl::free_all;
|
||||||
using zpl::memset;
|
using zpl::memset;
|
||||||
using zpl::pool_allocator;
|
using zpl::pool_allocator;
|
||||||
using zpl::pool_init;
|
using zpl::pool_init;
|
||||||
|
877
project/gen.cpp
877
project/gen.cpp
File diff suppressed because it is too large
Load Diff
451
project/gen.hpp
451
project/gen.hpp
@ -30,22 +30,23 @@
|
|||||||
|
|
||||||
These features are in as they either are not horrible when used conservatively or are a performance benefit (modules).
|
These features are in as they either are not horrible when used conservatively or are a performance benefit (modules).
|
||||||
|
|
||||||
When it comes to expressions:
|
#### When it comes to expressions:
|
||||||
There is no parse API for validating expressions (possibly will add in the future).
|
|
||||||
This reason there isn't one: thats where the can of worms open for parsing validation.
|
|
||||||
For most metaprogramming (espcially for c/c++), expression validation is not necessary, it can be done by the compiler for the runtime program.
|
|
||||||
Most of the time, the critical complex metaprogramming conundrums are actaully producing the frame of abstractions around the expressions.
|
|
||||||
Thus its not very much a priority to add such a level of complexity to the library when there isn't a high reward or need for it.
|
|
||||||
|
|
||||||
To further this point, lets say you do have an error with an expressions composition.
|
There is no support for validating expressions.
|
||||||
It will either be caught by the c++ compiler when compiling the target program, or at runtime for the program.
|
The reason: thats where the can of worms open for parsing validation. This library would most likey more than double in size with that addition alone.
|
||||||
|
For most metaprogramming (espcially for C/C++), expression validation is not necessary for metaprogramming, it can be done by the compiler for the runtime program.
|
||||||
|
Most of the time, the critical complex metaprogramming conundrums are actaully producing the frame of abstractions around the expressions.
|
||||||
|
Thus its not very much a priority to add such a level of complexity to the library when there isn't a high reward or need for it.
|
||||||
|
|
||||||
* If its not caught by the compiler, the only downside is the error appers on the generated function.
|
To further this point, lets say you do have an error with an expressions composition.
|
||||||
Those with knowledge of how that definition was generated know where to find the code that inlined that expression in that file for that definition.
|
It will either be caught by the c++ compiler when compiling the target program, or at runtime for the program.
|
||||||
* If its caught at runtime. The expression will be shown in a stack trace if debug symbols are enabled in the generated function body.
|
|
||||||
Yet again those with knowledge of how that definition was generated know where to find the code that inlined that expression.
|
|
||||||
|
|
||||||
In both these cases will get objectively better debug information than you would normally get on most c++ compilers with complex macros or templates.
|
* If its not caught by the compiler, the only downside is the error appers on the generated function.
|
||||||
|
Those with knowledge of how that definition was generated know where to find the code that inlined that expression in that file for that definition.
|
||||||
|
* If its caught at runtime. The expression will be shown in a stack trace if debug symbols are enabled in the generated function body.
|
||||||
|
Yet again those with knowledge of how that definition was generated know where to find the code that inlined that expression.
|
||||||
|
|
||||||
|
In both these cases the user will get objectively better debug information than you would normally get on most c++ compilers/editors using complex macros or templates.
|
||||||
|
|
||||||
### The Data & Interface:
|
### The Data & Interface:
|
||||||
|
|
||||||
@ -58,31 +59,48 @@
|
|||||||
* ASTs are wrapped for the user in a Code struct which essentially a warpper for a AST* type.
|
* ASTs are wrapped for the user in a Code struct which essentially a warpper for a AST* type.
|
||||||
* Both AST and Code have member symbols but their data layout is enforced to be POD types.
|
* Both AST and Code have member symbols but their data layout is enforced to be POD types.
|
||||||
* This library treats memory failures as fatal.
|
* This library treats memory failures as fatal.
|
||||||
* The default setup assumes large definition sets may be provided to bodies so AST::Entires are dynamic arrays.
|
* The AST's data union is can either hold a static array of AST*'s, a dynmaic array if the the static capacity is not enough, or a cached string content.
|
||||||
* They're allocated to arenas currently and are pretty wasteful if they go over their reserve size (its never recycled).
|
* The dynamic array is allocated to arenas currently and are pretty wasteful if they go over their reserve size (its never recycled).
|
||||||
* Most likely will need to implement a dynamic-sized bucket allocation strategy for the entry arrays if memory is getting stressed.
|
|
||||||
* Otherwise if you are using fixed size entries and your definitions are under 128~512 entries for the body, you may be better of with a fixed-sized array.
|
|
||||||
|
|
||||||
Data layout of AST struct:
|
Data layout of AST struct:
|
||||||
|
|
||||||
AST* Parent;
|
union {
|
||||||
CachedString Name;
|
AST* ArrStatic[ArrS_Cap];
|
||||||
CachedString Comment;
|
Array(AST*) Entries;
|
||||||
union {
|
StringCached Content;
|
||||||
array(AST*) Entries;
|
|
||||||
CachedString Content;
|
};
|
||||||
};
|
AST* Parent;
|
||||||
CodeT Type;
|
StringCached Name;
|
||||||
OperatorT Op;
|
StringCached Comment;
|
||||||
bool Readonly;
|
CodeT Type;
|
||||||
u8 _64_Align[23];
|
OperatorT Op;
|
||||||
|
bool Readonly;
|
||||||
|
bool DynamicEntries;
|
||||||
|
u8 StaticIndex;
|
||||||
|
u8 _Align_Pad[6];
|
||||||
|
|
||||||
*`CodeT` is a typedef for `ECode::Type` which is the type of the enum.*
|
*`CodeT` is a typedef for `ECode::Type` which is the type of the enum.*
|
||||||
|
|
||||||
|
AST widths are setup to be AST_POD_Size.
|
||||||
|
The width dictates how much the static array can hold before it must give way to using an allocated array:
|
||||||
|
constexpr static
|
||||||
|
u32 ArrS_Cap =
|
||||||
|
( AST_POD_Size
|
||||||
|
- sizeof(AST*)
|
||||||
|
- sizeof(StringCached) * 2
|
||||||
|
- sizeof(CodeT)
|
||||||
|
- sizeof(OperatorT)
|
||||||
|
- sizeof(bool) * 2
|
||||||
|
- sizeof(u8) * 7 )
|
||||||
|
/ sizeof(AST*);
|
||||||
|
|
||||||
|
Ex: If the AST_POD_Size is 256 the capacity of the static array is 26.
|
||||||
|
|
||||||
ASTs can be set to readonly by calling Code's lock() member function.
|
ASTs can be set to readonly by calling Code's lock() member function.
|
||||||
Adding comments is always available even if the AST is set to readonly.
|
Adding comments is always available even if the AST is set to readonly.
|
||||||
|
|
||||||
Data Notes:
|
#### Misc
|
||||||
|
|
||||||
* The allocator definitions used are exposed to the user incase they want to dictate memory usage
|
* The allocator definitions used are exposed to the user incase they want to dictate memory usage
|
||||||
* You'll find the memory handling in `init`, `gen_string_allocator`, `get_cached_string`, `make_code`, and `make_code_entries`.
|
* You'll find the memory handling in `init`, `gen_string_allocator`, `get_cached_string`, `make_code`, and `make_code_entries`.
|
||||||
@ -261,6 +279,16 @@
|
|||||||
Code <name> = parse_<function name>( gen_code_str );
|
Code <name> = parse_<function name>( gen_code_str );
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Extent of operator overload validation:
|
||||||
|
|
||||||
|
The AST and constructors will be able to validate that the arguments provided for the operator type match the expected form:
|
||||||
|
* If return type must match a parameter
|
||||||
|
* If number of parameters is correct
|
||||||
|
* If added as a member symbol to a class or struct, that operator matches the requirements for the class (types match up)
|
||||||
|
|
||||||
|
The user is responsible for making sure the code types provided are correct
|
||||||
|
and have the desired specifiers assigned to them beforehand.
|
||||||
|
|
||||||
## Code generation and modification
|
## Code generation and modification
|
||||||
|
|
||||||
There are three provided interfaces:
|
There are three provided interfaces:
|
||||||
@ -318,12 +346,10 @@
|
|||||||
|
|
||||||
Request queue in both Editor and Scanner are cleared once process_requests completes.
|
Request queue in both Editor and Scanner are cleared once process_requests completes.
|
||||||
|
|
||||||
### Notes on multi-threading:
|
### On multi-threading:
|
||||||
|
|
||||||
Its intended eventually for this library to support multi-threading at some point,
|
Currently supported but want to. The following changes would have to be made:
|
||||||
however for now it does not.
|
* Setup static data accesss with fences if more than one thread will generate ASTs ( or keep a different set for each thread)
|
||||||
The following changes would have to be made:
|
|
||||||
* Setup static data accesss with fences if more than one thread will generate ASTs
|
|
||||||
* Make sure local peristent data of functions are also thread local.
|
* Make sure local peristent data of functions are also thread local.
|
||||||
* The builder should be done on a per-thread basis.
|
* The builder should be done on a per-thread basis.
|
||||||
* Due to the design of the editor and scanner, it will most likely
|
* Due to the design of the editor and scanner, it will most likely
|
||||||
@ -352,9 +378,6 @@
|
|||||||
#include "Bloat.hpp"
|
#include "Bloat.hpp"
|
||||||
|
|
||||||
// Temporarily here for debugging purposes.
|
// Temporarily here for debugging purposes.
|
||||||
#define gentime
|
|
||||||
|
|
||||||
|
|
||||||
#define GEN_BAN_CPP_TEMPLATES
|
#define GEN_BAN_CPP_TEMPLATES
|
||||||
#define GEN_DEFINE_DSL
|
#define GEN_DEFINE_DSL
|
||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
@ -364,7 +387,7 @@
|
|||||||
#define GEN_FEATURE_SCANNER
|
#define GEN_FEATURE_SCANNER
|
||||||
|
|
||||||
|
|
||||||
#ifdef gentime
|
#ifdef gen_time
|
||||||
namespace gen
|
namespace gen
|
||||||
{
|
{
|
||||||
using LogFailType = sw(*)(char const*, ...);
|
using LogFailType = sw(*)(char const*, ...);
|
||||||
@ -383,38 +406,40 @@ namespace gen
|
|||||||
|
|
||||||
namespace ECode
|
namespace ECode
|
||||||
{
|
{
|
||||||
# define Define_Types \
|
# define Define_Types \
|
||||||
Entry( Untyped ) \
|
Entry( Untyped ) \
|
||||||
Entry( Access_Public ) \
|
Entry( Access_Public ) \
|
||||||
Entry( Access_Protected ) \
|
Entry( Access_Protected ) \
|
||||||
Entry( Access_Private ) \
|
Entry( Access_Private ) \
|
||||||
Entry( Class ) \
|
Entry( Class ) \
|
||||||
Entry( Class_FwdDecl ) \
|
Entry( Class_Fwd ) \
|
||||||
Entry( Class_Body ) \
|
Entry( Class_Body ) \
|
||||||
Entry( Enum ) \
|
Entry( Enum ) \
|
||||||
Entry( Enum_FwdDecl ) \
|
Entry( Enum_Fwd ) \
|
||||||
Entry( Enum_Body ) \
|
Entry( Enum_Body ) \
|
||||||
Entry( Enum_Class ) \
|
Entry( Enum_Class ) \
|
||||||
Entry( Enum_Class_FwdDecl ) \
|
Entry( Enum_Class_Fwd ) \
|
||||||
Entry( Execution ) \
|
Entry( Execution ) \
|
||||||
Entry( Friend ) \
|
Entry( Friend ) \
|
||||||
Entry( Function ) \
|
Entry( Function ) \
|
||||||
Entry( Function_FwdDecl ) \
|
Entry( Function_Fwd ) \
|
||||||
Entry( Function_Body ) \
|
Entry( Function_Body ) \
|
||||||
Entry( Global_Body ) \
|
Entry( Global_Body ) \
|
||||||
Entry( Namespace ) \
|
Entry( Namespace ) \
|
||||||
Entry( Namespace_Body ) \
|
Entry( Namespace_Body ) \
|
||||||
Entry( Operator ) \
|
Entry( Operator ) \
|
||||||
Entry( Operator_FwdDecl ) \
|
Entry( Operator_Fwd ) \
|
||||||
Entry( Parameters ) \
|
Entry( Operator_Member ) \
|
||||||
Entry( Specifiers ) \
|
Entry( Operator_Member_Fwd ) \
|
||||||
Entry( Struct ) \
|
Entry( Parameters ) \
|
||||||
Entry( Struct_FwdDecl ) \
|
Entry( Specifiers ) \
|
||||||
Entry( Struct_Body ) \
|
Entry( Struct ) \
|
||||||
Entry( Variable ) \
|
Entry( Struct_Fwd ) \
|
||||||
Entry( Typedef ) \
|
Entry( Struct_Body ) \
|
||||||
Entry( Typename ) \
|
Entry( Variable ) \
|
||||||
Entry( Using ) \
|
Entry( Typedef ) \
|
||||||
|
Entry( Typename ) \
|
||||||
|
Entry( Using ) \
|
||||||
Entry( Using_Namespace )
|
Entry( Using_Namespace )
|
||||||
|
|
||||||
enum Type : u32
|
enum Type : u32
|
||||||
@ -428,7 +453,7 @@ namespace gen
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char const* str( Type type )
|
char const* to_str( Type type )
|
||||||
{
|
{
|
||||||
static
|
static
|
||||||
char const* lookup[Num_Types] = {
|
char const* lookup[Num_Types] = {
|
||||||
@ -520,7 +545,7 @@ namespace gen
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
char const* str( Type op )
|
char const* to_str( Type op )
|
||||||
{
|
{
|
||||||
using something = u8;
|
using something = u8;
|
||||||
typedef u8 another;
|
typedef u8 another;
|
||||||
@ -568,24 +593,19 @@ namespace gen
|
|||||||
Entry( Constexpr, constexpr ) \
|
Entry( Constexpr, constexpr ) \
|
||||||
Entry( Constinit, constinit ) \
|
Entry( Constinit, constinit ) \
|
||||||
Entry( Export, export ) \
|
Entry( Export, export ) \
|
||||||
Entry( Explicit, explicit ) \
|
|
||||||
Entry( External_Linkage, extern ) \
|
Entry( External_Linkage, extern ) \
|
||||||
Entry( Import, import ) \
|
Entry( Import, import ) \
|
||||||
Entry( Inline, inline ) \
|
Entry( Inline, inline ) \
|
||||||
Entry( Internal_Linkage, static ) \
|
Entry( Internal_Linkage, static ) \
|
||||||
Entry( Final, final ) \
|
|
||||||
Entry( Local_Persist, static ) \
|
Entry( Local_Persist, static ) \
|
||||||
Entry( Module, module ) \
|
Entry( Module, module ) \
|
||||||
Entry( Mutable, mutable ) \
|
Entry( Mutable, mutable ) \
|
||||||
Entry( NoExcept, noexcept ) \
|
Entry( Ptr, * ) \
|
||||||
Entry( Override, override ) \
|
Entry( Ref, & ) \
|
||||||
Entry( Pointer, * ) \
|
|
||||||
Entry( Reference, & ) \
|
|
||||||
Entry( Register, register ) \
|
Entry( Register, register ) \
|
||||||
Entry( RValue, && ) \
|
Entry( RValue, && ) \
|
||||||
Entry( Static_Member, static ) \
|
Entry( Static_Member, static ) \
|
||||||
Entry( Thread_Local, Thread_Local_Code ) \
|
Entry( Thread_Local, Thread_Local_Code ) \
|
||||||
Entry( Virtual, virtual ) \
|
|
||||||
Entry( Volatile, volatile )
|
Entry( Volatile, volatile )
|
||||||
|
|
||||||
enum Type : u32
|
enum Type : u32
|
||||||
@ -641,6 +661,16 @@ namespace gen
|
|||||||
using SpecifierT = ESpecifier::Type;
|
using SpecifierT = ESpecifier::Type;
|
||||||
|
|
||||||
#pragma region Data Structures
|
#pragma region Data Structures
|
||||||
|
// Implements basic string interning. Data structure is based off the ZPL Hashtable.
|
||||||
|
ZPL_TABLE_DECLARE( ZPL_EXTERN, StringTable, str_tbl_, String );
|
||||||
|
|
||||||
|
// Represents strings cached with the string table.
|
||||||
|
// Should never be modified, if changed string is desired, cache_string( str ) another.
|
||||||
|
using StringCached = char const*;
|
||||||
|
|
||||||
|
// Desired width of the AST data structure.
|
||||||
|
ct u32 AST_POD_Size = 256;
|
||||||
|
|
||||||
// TODO: If perf needs it, convert layout an SOA format.
|
// TODO: If perf needs it, convert layout an SOA format.
|
||||||
/*
|
/*
|
||||||
Simple AST POD with functionality to seralize into C++ syntax.
|
Simple AST POD with functionality to seralize into C++ syntax.
|
||||||
@ -648,28 +678,24 @@ namespace gen
|
|||||||
ASTs are currently stored as an AOS. They are always reconstructed on demand.
|
ASTs are currently stored as an AOS. They are always reconstructed on demand.
|
||||||
Thus redundant AST can easily occur.
|
Thus redundant AST can easily occur.
|
||||||
Not sure if its better to store them in a hashmap.
|
Not sure if its better to store them in a hashmap.
|
||||||
|
|
||||||
|
Any type specific functions assume the construction of the AST was done correctly.
|
||||||
*/
|
*/
|
||||||
struct AST
|
struct AST
|
||||||
{
|
{
|
||||||
# pragma region Member Functions
|
# pragma region Member Functions
|
||||||
|
|
||||||
|
// Used with incremental constructors
|
||||||
|
// Adds and checks entries to see if they are valid additions the type of ast.
|
||||||
bool add( AST* other );
|
bool add( AST* other );
|
||||||
|
|
||||||
forceinline
|
inline
|
||||||
void add_entry( AST* other )
|
void add_entry( AST* other );
|
||||||
{
|
|
||||||
AST* to_add = other->Parent ?
|
|
||||||
other->duplicate() : other;
|
|
||||||
|
|
||||||
array_append( Entries, to_add );
|
|
||||||
|
|
||||||
to_add->Parent = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
AST* body()
|
AST* body()
|
||||||
{
|
{
|
||||||
return Entries && array_count(Entries) ?
|
return Entries[0];
|
||||||
Entries[0] : nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
@ -678,39 +704,76 @@ namespace gen
|
|||||||
AST* duplicate();
|
AST* duplicate();
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
bool has_entries() const
|
bool has_entries()
|
||||||
{
|
{
|
||||||
static bool lookup[ ECode::Num_Types] = {
|
return Entries[0];
|
||||||
false, // Invalid
|
|
||||||
false, // Untyped
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true, // Global_Body
|
|
||||||
true, // Parameters
|
|
||||||
true, // Proc
|
|
||||||
true, // Proc_Body
|
|
||||||
true, // Proc_Forward
|
|
||||||
false, // Specifies
|
|
||||||
true, // Struct
|
|
||||||
true, // Struct_Body
|
|
||||||
true, // Variable
|
|
||||||
true, // Typedef
|
|
||||||
true, // Typename
|
|
||||||
true, // Using
|
|
||||||
};
|
|
||||||
|
|
||||||
return lookup[Type];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
bool is_invalid() const
|
bool is_invalid()
|
||||||
{
|
{
|
||||||
return Type != ECode::Invalid;
|
return Type != ECode::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
char const* debug_str() const
|
s32 num_entries()
|
||||||
|
{
|
||||||
|
return DynamicEntries ? array_count(Entries) : StaticIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
AST* get_param( s32 index )
|
||||||
|
{
|
||||||
|
if ( index <= 0 )
|
||||||
|
return this;
|
||||||
|
|
||||||
|
return Entries[ index + 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
s32 param_count()
|
||||||
|
{
|
||||||
|
// The first entry (which holds the type) represents the first parameter.
|
||||||
|
return num_entries();
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
AST* param_type()
|
||||||
|
{
|
||||||
|
return Entries[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Typename
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool typename_is_ptr()
|
||||||
|
{
|
||||||
|
zpl::assert_crash("not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool typename_is_ref()
|
||||||
|
{
|
||||||
|
zpl::assert_crash("not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
AST* typename_specifiers()
|
||||||
|
{
|
||||||
|
return Entries[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// AST*& operator=(AST* const& b)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Serialization
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
char const* debug_str()
|
||||||
{
|
{
|
||||||
char const* fmt = txt(
|
char const* fmt = txt(
|
||||||
\nCode Debug:
|
\nCode Debug:
|
||||||
@ -725,7 +788,7 @@ namespace gen
|
|||||||
// Thus if its desired to keep the debug str
|
// Thus if its desired to keep the debug str
|
||||||
// for multiple calls to bprintf,
|
// for multiple calls to bprintf,
|
||||||
// allocate this to proper string.
|
// allocate this to proper string.
|
||||||
return zpl::bprintf( fmt
|
return bprintf( fmt
|
||||||
, type_str()
|
, type_str()
|
||||||
, Readonly ? "true" : "false"
|
, Readonly ? "true" : "false"
|
||||||
, Parent ? Parent->Name : ""
|
, Parent ? Parent->Name : ""
|
||||||
@ -735,40 +798,60 @@ namespace gen
|
|||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
char const* type_str() const
|
char const* type_str()
|
||||||
{
|
{
|
||||||
return ECode::str( Type );
|
return ECode::to_str( Type );
|
||||||
}
|
}
|
||||||
|
|
||||||
String to_string() const;
|
String to_string() const;
|
||||||
# pragma endregion Member Functions
|
# pragma endregion Member Functions
|
||||||
|
constexpr
|
||||||
|
static uw ArrS_Cap =
|
||||||
|
( AST_POD_Size
|
||||||
|
- sizeof(AST*)
|
||||||
|
- sizeof(StringCached) * 2
|
||||||
|
- sizeof(CodeT)
|
||||||
|
- sizeof(OperatorT)
|
||||||
|
- sizeof(bool) * 2
|
||||||
|
- sizeof(u8) * 7 )
|
||||||
|
/ sizeof(AST*);
|
||||||
|
|
||||||
# define Using_Code_POD \
|
// SpecifierT Specifiers[] \
|
||||||
AST* Parent; \
|
|
||||||
StringCached Name; \
|
|
||||||
StringCached Comment; \
|
|
||||||
union { \
|
|
||||||
Array(AST*) Entries; \
|
|
||||||
StringCached Content; \
|
|
||||||
}; \
|
|
||||||
CodeT Type; \
|
|
||||||
OperatorT Op; \
|
|
||||||
bool Readonly; \
|
|
||||||
u8 _64_Align[23];
|
|
||||||
|
|
||||||
Using_Code_POD;
|
// Size : 256 bytes
|
||||||
|
# define Using_Code_POD \
|
||||||
|
union { \
|
||||||
|
AST* ArrStatic[AST::ArrS_Cap]; \
|
||||||
|
Array(AST*) Entries; \
|
||||||
|
StringCached Content; \
|
||||||
|
}; \
|
||||||
|
AST* Parent; \
|
||||||
|
StringCached Name; \
|
||||||
|
StringCached Comment; \
|
||||||
|
CodeT Type; \
|
||||||
|
OperatorT Op; \
|
||||||
|
bool Readonly; \
|
||||||
|
bool DynamicEntries; \
|
||||||
|
u8 StaticIndex; \
|
||||||
|
u8 _Align_Pad[6];
|
||||||
|
|
||||||
|
Using_Code_POD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CodePOD
|
struct CodePOD
|
||||||
{
|
{
|
||||||
Using_Code_POD;
|
Using_Code_POD
|
||||||
# undef Using_CodePOD;
|
# undef Using_CodePOD;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ct sw size_AST = sizeof(AST);
|
||||||
|
ct sw size_POD = sizeof(CodePOD);
|
||||||
|
|
||||||
// Its intended for the AST to have equivalent size to its POD.
|
// Its intended for the AST to have equivalent size to its POD.
|
||||||
// All extra functionality within the AST namespace should just be syntatic sugar.
|
// All extra functionality within the AST namespace should just be syntatic sugar.
|
||||||
static_assert( sizeof(AST) == sizeof(CodePOD), "ERROR: AST IS NOT POD" );
|
static_assert( sizeof(AST) == sizeof(CodePOD), "ERROR: AST IS NOT POD" );
|
||||||
|
static_assert( sizeof(CodePOD) == AST_POD_Size, "ERROR: AST POD is not size of AST_POD_Size" );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AST* typedef as to not constantly have to add the '*' as this is written often..
|
AST* typedef as to not constantly have to add the '*' as this is written often..
|
||||||
@ -782,7 +865,7 @@ namespace gen
|
|||||||
{
|
{
|
||||||
# pragma region Statics
|
# pragma region Statics
|
||||||
// Used internally for the most part to identify invaidly generated code.
|
// Used internally for the most part to identify invaidly generated code.
|
||||||
static const Code Invalid;
|
static Code Invalid;
|
||||||
# pragma endregion Statics
|
# pragma endregion Statics
|
||||||
|
|
||||||
# pragma region Member Functions
|
# pragma region Member Functions
|
||||||
@ -824,22 +907,37 @@ namespace gen
|
|||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
operator bool() const
|
char const* to_string()
|
||||||
|
{
|
||||||
|
return ast->to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
operator bool()
|
||||||
{
|
{
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator ==( Code other ) const
|
forceinline
|
||||||
|
bool operator ==( Code other )
|
||||||
{
|
{
|
||||||
return ast == other.ast;
|
return ast == other.ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
|
bool operator !=( Code other )
|
||||||
|
{
|
||||||
|
return ast != other.ast;
|
||||||
|
}
|
||||||
|
|
||||||
|
forceinline
|
||||||
operator AST*()
|
operator AST*()
|
||||||
{
|
{
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
Code& operator =( Code other )
|
forceinline
|
||||||
|
Code& operator=( Code other )
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if ( ast == nullptr )
|
||||||
{
|
{
|
||||||
@ -861,7 +959,7 @@ namespace gen
|
|||||||
}
|
}
|
||||||
|
|
||||||
forceinline
|
forceinline
|
||||||
AST* operator ->()
|
AST* operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if ( ast == nullptr )
|
||||||
{
|
{
|
||||||
@ -889,13 +987,6 @@ namespace gen
|
|||||||
ct Code NoCode = { nullptr };
|
ct Code NoCode = { nullptr };
|
||||||
// extern const Code InvalidCode;
|
// extern const Code InvalidCode;
|
||||||
|
|
||||||
// Implements basic string interning. Data structure is based off the ZPL Hashtable.
|
|
||||||
ZPL_TABLE_DECLARE( ZPL_EXTERN, StringTable, str_tbl_, String );
|
|
||||||
|
|
||||||
// Represents strings cached with the string table.
|
|
||||||
// Should never be modified, if changed string is desired, cache_string( str ) another.
|
|
||||||
using StringCached = char const*;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Type Table: Used to store Typename ASTs. Types are registered by their string literal value.
|
Type Table: Used to store Typename ASTs. Types are registered by their string literal value.
|
||||||
|
|
||||||
@ -911,10 +1002,13 @@ namespace gen
|
|||||||
// This currently just initializes the CodePool.
|
// This currently just initializes the CodePool.
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
// Use this only if you know you generated the code you needed to a file.
|
/*
|
||||||
// And rather get rid of current code asts instead of growing the pool memory.
|
Use this only if you know you generated the code you needed to a file.
|
||||||
// This generally can be done everytime a file is generated
|
And rather get rid of current code asts instead of growing the pool memory.
|
||||||
void clear_code_pool();
|
This generally can be done everytime a file is generated
|
||||||
|
TODO: In order for this to work, the type map needs its own arenas so do specifiers.
|
||||||
|
*/
|
||||||
|
void clear_code_memory();
|
||||||
|
|
||||||
// Used internally to retrive or make string allocations.
|
// Used internally to retrive or make string allocations.
|
||||||
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
|
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
|
||||||
@ -964,11 +1058,13 @@ namespace gen
|
|||||||
|
|
||||||
Code def_class_body ( s32 num, ... );
|
Code def_class_body ( s32 num, ... );
|
||||||
Code def_enum_body ( u32 num, ... );
|
Code def_enum_body ( u32 num, ... );
|
||||||
Code def_enum_body ( u32 num, Code* Values );
|
Code def_enum_body ( u32 num, Code* codes );
|
||||||
Code def_global_body ( s32 num, ... );
|
Code def_global_body ( s32 num, ... );
|
||||||
|
Code def_global_body ( s32 num, Code* codes );
|
||||||
Code def_function_body ( s32 num, ... );
|
Code def_function_body ( s32 num, ... );
|
||||||
Code def_function_body ( s32 num, Code* codes );
|
Code def_function_body ( s32 num, Code* codes );
|
||||||
Code def_namespace_body ( s32 num, ... );
|
Code def_namespace_body ( s32 num, ... );
|
||||||
|
Code def_namespace_body ( s32 num, Code* codes );
|
||||||
Code def_params ( s32 num, ... );
|
Code def_params ( s32 num, ... );
|
||||||
Code def_params ( s32 num, Code* params );
|
Code def_params ( s32 num, Code* params );
|
||||||
Code def_specifiers ( s32 num , ... );
|
Code def_specifiers ( s32 num , ... );
|
||||||
@ -1274,12 +1370,6 @@ namespace gen
|
|||||||
{
|
{
|
||||||
// Predefined typename codes. Are set to readonly and are setup during gen::init()
|
// Predefined typename codes. Are set to readonly and are setup during gen::init()
|
||||||
|
|
||||||
extern Code type_ns( void );
|
|
||||||
|
|
||||||
extern Code type_ns( bool );
|
|
||||||
extern Code type_ns( char );
|
|
||||||
extern Code type_ns( wchar_t );
|
|
||||||
|
|
||||||
extern Code type_ns( s8 );
|
extern Code type_ns( s8 );
|
||||||
extern Code type_ns( s16 );
|
extern Code type_ns( s16 );
|
||||||
extern Code type_ns( s32 );
|
extern Code type_ns( s32 );
|
||||||
@ -1309,7 +1399,7 @@ namespace gen
|
|||||||
ct s32 InitSize_TypeTable = megabytes(4);
|
ct s32 InitSize_TypeTable = megabytes(4);
|
||||||
|
|
||||||
ct s32 CodePool_NumBlocks = 4096;
|
ct s32 CodePool_NumBlocks = 4096;
|
||||||
ct s32 CodeEntiresPool_NumBlocks = 4096;
|
ct s32 InitSize_CodeEntiresArray = 512;
|
||||||
ct s32 SizePer_CodeEntriresArena = megabytes(16);
|
ct s32 SizePer_CodeEntriresArena = megabytes(16);
|
||||||
ct s32 SizePer_StringArena = megabytes(32);
|
ct s32 SizePer_StringArena = megabytes(32);
|
||||||
|
|
||||||
@ -1319,6 +1409,12 @@ namespace gen
|
|||||||
|
|
||||||
// Predefined Codes. Are set to readonly and are setup during gen::init()
|
// Predefined Codes. Are set to readonly and are setup during gen::init()
|
||||||
|
|
||||||
|
extern Code type_ns( void );
|
||||||
|
extern Code type_ns( int );
|
||||||
|
extern Code type_ns( bool );
|
||||||
|
extern Code type_ns( char );
|
||||||
|
extern Code type_ns( wchar_t );
|
||||||
|
|
||||||
extern Code access_public;
|
extern Code access_public;
|
||||||
extern Code access_protected;
|
extern Code access_protected;
|
||||||
extern Code access_private;
|
extern Code access_private;
|
||||||
@ -1333,3 +1429,44 @@ namespace gen
|
|||||||
|
|
||||||
// end: gen_time
|
// end: gen_time
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma region Inlines
|
||||||
|
namespace gen
|
||||||
|
{
|
||||||
|
inline void AST::add_entry( AST* other )
|
||||||
|
{
|
||||||
|
AST* to_add = other->Parent ?
|
||||||
|
other->duplicate() : other;
|
||||||
|
|
||||||
|
if (DynamicEntries)
|
||||||
|
array_append( Entries, to_add );
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( StaticIndex < ArrS_Cap )
|
||||||
|
{
|
||||||
|
ArrStatic[StaticIndex] = to_add;
|
||||||
|
StaticIndex++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Entries = make_code_entries();
|
||||||
|
|
||||||
|
s32 index = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
array_append( Entries, ArrStatic[index] );
|
||||||
|
}
|
||||||
|
while ( StaticIndex--, StaticIndex );
|
||||||
|
|
||||||
|
array_append( Entries, to_add );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
to_add->Parent = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma endregion Inlines
|
||||||
|
|
||||||
|
#pragma region Undefines
|
||||||
|
#pragma endregion Undefines
|
||||||
|
@ -22,6 +22,6 @@ endif
|
|||||||
# add_project_arguments('-E', language : ['c', 'cpp'])
|
# add_project_arguments('-E', language : ['c', 'cpp'])
|
||||||
# add_global_arguments( '-E', language : ['cpp'])
|
# add_global_arguments( '-E', language : ['cpp'])
|
||||||
|
|
||||||
add_project_arguments('-Dgentime', language : ['c', 'cpp'])
|
add_project_arguments('-Dgen_time', language : ['c', 'cpp'])
|
||||||
|
|
||||||
executable( 'gencpp', sources, include_directories : includes )
|
executable( 'gencpp', sources, include_directories : includes )
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "Bloat.cpp"
|
#include "Bloat.cpp"
|
||||||
|
|
||||||
|
|
||||||
#ifdef gentime
|
#ifdef gen_time
|
||||||
#include "gen.cpp"
|
#include "gen.cpp"
|
||||||
|
|
||||||
int gen_main()
|
int gen_main()
|
||||||
@ -19,7 +19,7 @@ int gen_main()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef comptime
|
#ifdef runtime
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user