mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 15:54:45 -08:00
Removed incremental API, fixes for operator__validation
, added formatting pass on generated files
Decided not to support the incremental API, its not necessary as the ergonomics are not that big a deal. Got operators to pass the sanity base cases, which means now all upfront constructors pass the base cases! Next up is getting it to pass the array container generation.
This commit is contained in:
parent
19e58fea30
commit
257e9ebf11
60
Readme.md
60
Readme.md
@ -93,24 +93,6 @@ Code header;
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Incremental
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
// Types are done the same with upfront. Incremental does not have a full interface replacment.
|
|
||||||
|
|
||||||
// Get a Code AST from the CodePool.
|
|
||||||
Code header = make_struct( name(ArrayHeader) );
|
|
||||||
{
|
|
||||||
// Make a struct body.
|
|
||||||
Code body = header.body();
|
|
||||||
|
|
||||||
// Members
|
|
||||||
body->add( def_variable( t_uw, name(Num)) );
|
|
||||||
body->add( def_variable( t_uw, name(Capacity)) );
|
|
||||||
body->add( def_variable( t_allocator, name(Allocator)) );
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parse
|
### Parse
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@ -272,10 +254,9 @@ Data Notes:
|
|||||||
* This library treats memory failures as fatal.
|
* This library treats memory failures as fatal.
|
||||||
* Strings are stored in their own set of arenas. AST constructors use cached strings for names, and content.
|
* Strings are stored in their own set of arenas. AST constructors use cached strings for names, and content.
|
||||||
|
|
||||||
## There are four sets of interfaces for Code AST generation the library provides
|
## There are three sets of interfaces for Code AST generation the library provides
|
||||||
|
|
||||||
* Upfront
|
* Upfront
|
||||||
* Incremental
|
|
||||||
* Parsing
|
* Parsing
|
||||||
* Untyped
|
* Untyped
|
||||||
|
|
||||||
@ -335,40 +316,6 @@ Code <name>
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Incremental construction
|
|
||||||
|
|
||||||
A Code AST is provided but the body is not complete.
|
|
||||||
|
|
||||||
* code.add( AST* ) // Adds AST with validation.
|
|
||||||
* code.add_entry( AST* ) // Adds AST entry without validation.
|
|
||||||
|
|
||||||
Code ASTs may be explictly validated at anytime using Code's check() member function.
|
|
||||||
|
|
||||||
Interface :
|
|
||||||
|
|
||||||
* make_class
|
|
||||||
* make_enum
|
|
||||||
* make_export_body
|
|
||||||
* make_extern_linkage
|
|
||||||
* make_function
|
|
||||||
* make_global_body
|
|
||||||
* make_namespace
|
|
||||||
* make_operator
|
|
||||||
* make_params
|
|
||||||
* make_specifiers
|
|
||||||
* make_struct
|
|
||||||
* make_union
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
Code <name> = make_<function name>( ... )
|
|
||||||
{
|
|
||||||
<name>->add( ... );
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parse construction
|
### Parse construction
|
||||||
|
|
||||||
A string provided to the API is parsed for the intended language construct.
|
A string provided to the API is parsed for the intended language construct.
|
||||||
@ -616,8 +563,3 @@ Names or Content fields are interned strings and thus showed be cached using `ge
|
|||||||
* Generate a single-header library.
|
* Generate a single-header library.
|
||||||
* Generate a C-supported single-header library.
|
* Generate a C-supported single-header library.
|
||||||
* Actually get to version 1.
|
* Actually get to version 1.
|
||||||
* Review if the upfront or incremental constructors are actually a net benefit vs just using the parse constructors.
|
|
||||||
* They exist as a artifact of learning what was possible or not possible with staged metaprogramming in C++ (the parse interface was the last to get fleshed out)
|
|
||||||
* Most likely at least Incremental could possibly be removed in favor of just using the parse constructors.
|
|
||||||
* Possible merits are ergonomics for very dynamic generation or performance reasons.
|
|
||||||
* They'll most likely stay until its evident that they are not necessary.
|
|
||||||
|
@ -32,7 +32,6 @@ While getting fleshed out, all feature macros are defined on the top of the head
|
|||||||
|
|
||||||
These macros are:
|
These macros are:
|
||||||
|
|
||||||
* `GEN_DEFINE_DSL` : Define the preprocessor DSL for using the library interface
|
|
||||||
* `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage
|
* `GEN_DEFINE_LIBRARY_CORE_CONSTANTS` : Optional typename codes as they are non-standard to C/C++ and not necessary to library usage
|
||||||
* `GEN_ENCORCE_READONLY_AST` : Defines checks in Code when accessing the AST to make sure readonly marked ASTs are not mutated
|
* `GEN_ENCORCE_READONLY_AST` : Defines checks in Code when accessing the AST to make sure readonly marked ASTs are not mutated
|
||||||
* `GEN_FEATURE_INCREMENTAL` : Defines the incremental constructors
|
* `GEN_FEATURE_INCREMENTAL` : Defines the incremental constructors
|
||||||
@ -71,7 +70,7 @@ AST with.
|
|||||||
|
|
||||||
First set of fowards are either backend functions used for various aspects of AST generation or configurating allocators used for different containers.
|
First set of fowards are either backend functions used for various aspects of AST generation or configurating allocators used for different containers.
|
||||||
|
|
||||||
Interface fowards defined in order of: Upfront, Incremental, Parsing, Untyped.
|
Interface fowards defined in order of: Upfront, Parsing, Untyped.
|
||||||
|
|
||||||
From there forwards for the File handlers are defined: Builder, Editor, Scanner.
|
From there forwards for the File handlers are defined: Builder, Editor, Scanner.
|
||||||
|
|
||||||
|
669
project/gen.cpp
669
project/gen.cpp
@ -6,7 +6,6 @@
|
|||||||
namespace gen
|
namespace gen
|
||||||
{
|
{
|
||||||
ZPL_TABLE_DEFINE( StringTable, str_tbl_, String );
|
ZPL_TABLE_DEFINE( StringTable, str_tbl_, String );
|
||||||
// ZPL_TABLE_DEFINE( TypeTable, type_tbl_ , Code );
|
|
||||||
|
|
||||||
namespace StaticData
|
namespace StaticData
|
||||||
{
|
{
|
||||||
@ -151,278 +150,6 @@ namespace gen
|
|||||||
#pragma region AST
|
#pragma region AST
|
||||||
Code Code::Invalid;
|
Code Code::Invalid;
|
||||||
|
|
||||||
bool AST::add( AST* other )
|
|
||||||
{
|
|
||||||
#ifdef GEN_FEATURE_INCREMENTAL
|
|
||||||
if ( other == nullptr )
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Provided a null AST" );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( other->Type == ECode::Invalid )
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Provided an invalid AST" );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( Type )
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
|
|
||||||
case Invalid:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to an invalid AST." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Untyped:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to an untyped AST." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Comment:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a comment." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Access_Private:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a private access specifier." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Access_Protected:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a protected access specifier." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Access_Public:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a public access specifier." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Attributes:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to an attribute." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Class:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a class, only to its body" );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Class_Fwd:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a class forward declaration." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Class_Body:
|
|
||||||
switch ( other->Type )
|
|
||||||
{
|
|
||||||
AST_BODY_CLASS_UNALLOWED_TYPES
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add %s to a class body.", other->type_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Enum:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to an enum, only to its body" );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Enum_Fwd:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to an enum forward declaration." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Enum_Body:
|
|
||||||
if ( other->Type != Untyped )
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add an AST which is not untyped to an enum body." );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Execution:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to an execution block." );
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Export_Body:
|
|
||||||
switch ( other->Type )
|
|
||||||
{
|
|
||||||
AST_BODY_EXPORT_UNALLOWED_TYPES
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add %s to an export body.", other->type_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Extern_Linkage:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to an extern linkage, only to its body." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Extern_Linkage_Body:
|
|
||||||
switch ( other->Type )
|
|
||||||
{
|
|
||||||
AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add %s to an extern linkage body.", other->type_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Enum_Class:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to an enum class, only to its body" );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Enum_Class_Fwd:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to an enum class forward declaration." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Friend:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a friend declaration." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Function:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a function, only to its body" );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Function_Body:
|
|
||||||
switch ( other->Type )
|
|
||||||
{
|
|
||||||
AST_BODY_FUNCTION_UNALLOWED_TYPES
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add %s to a function body.", other->type_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Function_Fwd:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a function forward declaration." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Global_Body:
|
|
||||||
switch ( other->Type )
|
|
||||||
{
|
|
||||||
AST_BODY_GLOBAL_UNALLOWED_TYPES
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add %s to a global body.", other->type_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Module:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a module, only to its body" );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Namespace:
|
|
||||||
if ( Type != Global_Body )
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add a namespace to a non-global body." );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Namespace_Body:
|
|
||||||
switch ( other-> Type )
|
|
||||||
{
|
|
||||||
AST_BODY_NAMESPACE_UNALLOWED_TYPES
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add %s to a namespace body.", other->type_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Operator:
|
|
||||||
log_failure( "AST::add: Cannot add an operator, only to its body" );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Operator_Fwd:
|
|
||||||
log_failure( "AST::add: Cannot add an operator forward declaration." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Parameters:
|
|
||||||
log_failure( "AST::add: Cannot add to a parameter list, use AST::add_param instead" );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Preprocessor_Include:
|
|
||||||
log_failure( "AST::add: Cannot add an AST to a preprocessor include." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Specifiers:
|
|
||||||
log_failure( "AST::add: Cannot add to a specifier, use AST::add_specifier instead." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Struct:
|
|
||||||
log_failure( "AST::add: Cannot add to a struct, only to its body." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Struct_Body:
|
|
||||||
switch ( other->Type )
|
|
||||||
{
|
|
||||||
AST_BODY_STRUCT_UNALLOWED_TYPES
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add %s to a struct body.", other->type_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Typedef:
|
|
||||||
log_failure( "AST::add: Cannot add to a typedef." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Typename:
|
|
||||||
log_failure( "AST::add: Cannot add to a typename." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Union:
|
|
||||||
log_failure( "AST::add: Cannot add to a union, only to its body." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Union_Body:
|
|
||||||
if ( other->Type != Untyped )
|
|
||||||
{
|
|
||||||
log_failure( "AST::add: Cannot add an AST which is not untyped to a union body." );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Using:
|
|
||||||
log_failure( "AST::add: Cannot add to a using statement." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Using_Namespace:
|
|
||||||
log_failure( "AST::add: Cannot add to a using namespace statement." );
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case Variable:
|
|
||||||
log_failure( "AST::add: Cannot add to a variable." );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_entry( other );
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
log_failure( "AST::add: Incremental AST building is not enabled." );
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
AST* AST::duplicate()
|
AST* AST::duplicate()
|
||||||
{
|
{
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
@ -563,7 +290,6 @@ namespace gen
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Untyped:
|
case Untyped:
|
||||||
// result = string_append_length( result, Content, string_length( ccast(String, Content)) );
|
|
||||||
result.append( Content );
|
result.append( Content );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -623,7 +349,7 @@ namespace gen
|
|||||||
|
|
||||||
result.append( Name );
|
result.append( Name );
|
||||||
|
|
||||||
AST* parent = entry( idx );
|
AST const* parent = entry( idx );
|
||||||
|
|
||||||
if ( parent )
|
if ( parent )
|
||||||
{
|
{
|
||||||
@ -671,7 +397,7 @@ namespace gen
|
|||||||
{
|
{
|
||||||
s32 idx = 1;
|
s32 idx = 1;
|
||||||
|
|
||||||
AST* Entry = entry( idx);
|
AST const* Entry = entry( idx);
|
||||||
|
|
||||||
if ( Entry->Type == Attributes )
|
if ( Entry->Type == Attributes )
|
||||||
{
|
{
|
||||||
@ -724,7 +450,9 @@ namespace gen
|
|||||||
|
|
||||||
result.append( "enum class " );
|
result.append( "enum class " );
|
||||||
|
|
||||||
s32 idx = 0;
|
if ( num_entries() > 1 )
|
||||||
|
{
|
||||||
|
s32 idx = 1;
|
||||||
|
|
||||||
if ( entry( idx )->Type == Attributes )
|
if ( entry( idx )->Type == Attributes )
|
||||||
{
|
{
|
||||||
@ -742,15 +470,14 @@ namespace gen
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result.append_fmt( "%s\n%s{\n"
|
result.append_fmt( "%s\n{\n"
|
||||||
, Name
|
, Name
|
||||||
, indent_str
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result.append_fmt( "%s\n%s};"
|
result.append_fmt( "%s};"
|
||||||
, body()->to_string()
|
, body()->to_string()
|
||||||
, indent_str
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -968,7 +695,7 @@ namespace gen
|
|||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append_fmt( "%s operator %s (", entry( idx )->to_string(), Name );
|
result.append_fmt( "%s %s (", entry( idx )->to_string(), Name );
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
if ( entry( idx )->Type == Parameters )
|
if ( entry( idx )->Type == Parameters )
|
||||||
@ -981,10 +708,9 @@ namespace gen
|
|||||||
result.append_fmt( "void" );
|
result.append_fmt( "void" );
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append_fmt( ")\n%s{\n%s\n%s}"
|
result.append_fmt( ")\n%s{\n%s\n}"
|
||||||
, indent_str
|
, indent_str
|
||||||
, body()->to_string()
|
, body()->to_string()
|
||||||
, indent_str
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1004,7 +730,7 @@ namespace gen
|
|||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append_fmt( "%s operator%s(", entry( idx )->to_string(), Name );
|
result.append_fmt( "%s %s (", entry( idx )->to_string(), Name );
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
if ( entry( idx )->Type == Parameters )
|
if ( entry( idx )->Type == Parameters )
|
||||||
@ -1241,6 +967,38 @@ namespace gen
|
|||||||
|
|
||||||
#undef ProcessModuleFlags
|
#undef ProcessModuleFlags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AST::is_equal( AST* other )
|
||||||
|
{
|
||||||
|
if ( Type != other->Type )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch ( Type )
|
||||||
|
{
|
||||||
|
case ECode::Typedef:
|
||||||
|
case ECode::Typename:
|
||||||
|
{
|
||||||
|
if ( Name != other->Name )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( num_entries() != other->num_entries() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for ( s32 i = 0; i < num_entries(); ++i )
|
||||||
|
{
|
||||||
|
if ( entry( i ) != other->entry( i ) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( Name != other->Name )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#pragma endregion AST
|
#pragma endregion AST
|
||||||
|
|
||||||
#pragma region Gen Interface
|
#pragma region Gen Interface
|
||||||
@ -1728,7 +1486,7 @@ namespace gen
|
|||||||
switch ( params_code->param_count() )
|
switch ( params_code->param_count() )
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
if ( params_code->param_type() == type_ns(int) )
|
if ( params_code->param_type()->is_equal( type_ns(int) ) )
|
||||||
is_member_symbol = true;
|
is_member_symbol = true;
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -1738,7 +1496,7 @@ namespace gen
|
|||||||
case 2:
|
case 2:
|
||||||
check_param_eq_ret();
|
check_param_eq_ret();
|
||||||
|
|
||||||
if ( params_code->get_param(1) != type_ns(int) )
|
if ( ! params_code->get_param(1)->is_equal( type_ns(int) ) )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_operator: "
|
log_failure("gen::def_operator: "
|
||||||
"operator%s requires second parameter of non-member definition to be int for post-decrement",
|
"operator%s requires second parameter of non-member definition to be int for post-decrement",
|
||||||
@ -1772,7 +1530,7 @@ namespace gen
|
|||||||
return OpValidateResult::Fail;
|
return OpValidateResult::Fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( params_code->param_type() == ret_type )
|
if ( params_code->param_type()->is_equal( ret_type ) )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_operator: "
|
log_failure("gen::def_operator: "
|
||||||
"operator%s is non-member symbol yet first paramter does not equal return type\n"
|
"operator%s is non-member symbol yet first paramter does not equal return type\n"
|
||||||
@ -1814,7 +1572,7 @@ namespace gen
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if ( params_code->param_type() != ret_type )
|
if ( ! params_code->param_type()->is_equal( ret_type ) )
|
||||||
{
|
{
|
||||||
log_failure("gen::def_operator: "
|
log_failure("gen::def_operator: "
|
||||||
"operator%s is non-member symbol yet first paramter does not equal return type\n"
|
"operator%s is non-member symbol yet first paramter does not equal return type\n"
|
||||||
@ -1858,7 +1616,7 @@ namespace gen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ret_type != type_ns(bool) )
|
if ( ! ret_type->is_equal( type_ns(bool) ))
|
||||||
{
|
{
|
||||||
log_failure("gen::def_operator: operator%s return type must be of type bool - %s"
|
log_failure("gen::def_operator: operator%s return type must be of type bool - %s"
|
||||||
, to_str(op)
|
, to_str(op)
|
||||||
@ -2402,7 +2160,7 @@ namespace gen
|
|||||||
{
|
{
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
|
|
||||||
if ( body && body->Type != Function_Body )
|
if ( body && body->Type != Function_Body && body->Type != Untyped )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_operator: Body was provided but its not of function body type: %s", body->debug_str() );
|
log_failure( "gen::def_operator: Body was provided but its not of function body type: %s", body->debug_str() );
|
||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
@ -2561,10 +2319,6 @@ namespace gen
|
|||||||
return Code::Invalid;
|
return Code::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code cached = get_cached_type( name );
|
|
||||||
// if ( cached )
|
|
||||||
// return cached;
|
|
||||||
|
|
||||||
Code
|
Code
|
||||||
result = make_code();
|
result = make_code();
|
||||||
result->Name = get_cached_string( name );
|
result->Name = get_cached_string( name );
|
||||||
@ -2578,11 +2332,6 @@ namespace gen
|
|||||||
|
|
||||||
result.lock();
|
result.lock();
|
||||||
|
|
||||||
// s32 hash_length = name.Len > kilobytes(1) ? kilobytes(1) : name.Len;
|
|
||||||
// s32 key = crc32( name.Ptr, hash_length );
|
|
||||||
|
|
||||||
// type_tbl_set( & StaticData::TypeMap, key, result );
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3344,329 +3093,11 @@ namespace gen
|
|||||||
result.lock();
|
result.lock();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#pragma endregion Upfront Constructors
|
|
||||||
|
|
||||||
#pragma region Incremetnal Constructors
|
|
||||||
#ifdef GEN_FEATURE_INCREMENTAL
|
|
||||||
Code make_class( StrC name
|
|
||||||
, Code parent, AccessSpec parent_access
|
|
||||||
, Code specifiers, Code attributes
|
|
||||||
, ModuleFlag mflags )
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
|
|
||||||
name_check( make_struct, name );
|
|
||||||
|
|
||||||
if ( attributes && attributes->Type != Attributes )
|
|
||||||
{
|
|
||||||
log_failure( "gen::make_class: attributes was not a `Attributes` type: %s", attributes->debug_str() );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != Specifiers )
|
|
||||||
{
|
|
||||||
log_failure( "gen::make_class: specifiers was not a `Specifiers` type: %s", specifiers->debug_str() );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( parent && parent->Type != Struct )
|
|
||||||
{
|
|
||||||
log_failure( "gen::make_class: parent was not a `Struct` type: %s", parent->debug_str() );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = Struct;
|
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
result->ModuleFlags = mflags;
|
|
||||||
|
|
||||||
Code
|
|
||||||
body = make_code();
|
|
||||||
body->Type = Struct_Body;
|
|
||||||
|
|
||||||
result->add_entry( body );
|
|
||||||
|
|
||||||
if ( attributes )
|
|
||||||
result->add_entry( attributes );
|
|
||||||
|
|
||||||
if ( specifiers )
|
|
||||||
result->add_entry( specifiers );
|
|
||||||
|
|
||||||
if ( parent )
|
|
||||||
result->add_entry( parent );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_enum( StrC name, Code type, EnumT specifier, Code attributes, ModuleFlag mflags )
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
|
|
||||||
name_check( make_enum, name );
|
|
||||||
|
|
||||||
if ( attributes && attributes->Type != Attributes )
|
|
||||||
{
|
|
||||||
log_failure( "gen::make_enum: attributes was not a `Attributes` type: %s", attributes->debug_str() );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( type && type->Type != Typename )
|
|
||||||
{
|
|
||||||
log_failure("gen::make_enum: type provided is not of code type typename - %s", type->debug_str() );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = specifier == EnumClass ? Enum_Class : Enum;
|
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
result->ModuleFlags = mflags;
|
|
||||||
|
|
||||||
Code
|
|
||||||
body = make_code();
|
|
||||||
body->Type = Enum_Body;
|
|
||||||
|
|
||||||
result->add_entry( body );
|
|
||||||
|
|
||||||
if ( type )
|
|
||||||
result->add_entry( type );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_export_body( StrC name )
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = Export_Body;
|
|
||||||
|
|
||||||
if ( name && name.Len > 0 )
|
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_extern_link( StrC name, ModuleFlag mflags )
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
|
|
||||||
name_check( make_extern_linkage, name);
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = Extern_Linkage;
|
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
result->ModuleFlags = mflags;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_function( StrC name
|
|
||||||
, Code params, Code ret_type
|
|
||||||
, Code specifiers, Code attributes
|
|
||||||
, ModuleFlag mflags
|
|
||||||
)
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
|
|
||||||
name_check( make_function, name );
|
|
||||||
|
|
||||||
if ( attributes && attributes->Type != Attributes )
|
|
||||||
{
|
|
||||||
log_failure( "gen::make_function: attributes was not a `Attributes` type: %s", attributes->debug_str() );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != Specifiers )
|
|
||||||
{
|
|
||||||
log_failure( "gen::def_function: specifiers was not a `Specifiers` type" );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( params && params->Type != Parameters )
|
|
||||||
{
|
|
||||||
log_failure( "gen::def_function: params was not a `Parameters` type" );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ret_type == nullptr || ret_type->Type != Typename )
|
|
||||||
{
|
|
||||||
log_failure( "gen::def_function: ret_type was not a Typename" );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
result->Type = Function;
|
|
||||||
result->ModuleFlags = mflags;
|
|
||||||
|
|
||||||
Code
|
|
||||||
body = make_code();
|
|
||||||
body->Type = Function_Body;
|
|
||||||
|
|
||||||
result->add_entry( body );
|
|
||||||
|
|
||||||
if ( attributes )
|
|
||||||
result->add_entry( attributes );
|
|
||||||
|
|
||||||
if ( specifiers )
|
|
||||||
result->add_entry( specifiers );
|
|
||||||
|
|
||||||
if ( ret_type )
|
|
||||||
result->add_entry( ret_type );
|
|
||||||
|
|
||||||
if ( params )
|
|
||||||
result->add_entry( params );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_global_body( StrC name )
|
|
||||||
{
|
|
||||||
name_check( make_global_body, name );
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = ECode::Global_Body;
|
|
||||||
|
|
||||||
if ( name.Len > 0 )
|
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_namespace( StrC name, Code parent, ModuleFlag mflags )
|
|
||||||
{
|
|
||||||
name_check( make_namespace, name );
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = ECode::Namespace;
|
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
result->ModuleFlags = mflags;
|
|
||||||
|
|
||||||
Code
|
|
||||||
body = make_code();
|
|
||||||
body->Type = ECode::Namespace_Body;
|
|
||||||
|
|
||||||
result->add_entry( body );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_operator( OperatorT op, Code params_code, Code ret_type, Code specifiers, Code attributes, ModuleFlag mflags )
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
|
|
||||||
if ( attributes && attributes->Type != Attributes )
|
|
||||||
{
|
|
||||||
log_failure( "gen::make_operator: attributes was not a `Attributes` type: %s", attributes->debug_str() );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpValidateResult check_result = operator__validate( op, params_code, ret_type, specifiers );
|
|
||||||
|
|
||||||
if ( check_result == OpValidateResult::Fail )
|
|
||||||
{
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
char const* name = str_fmt_buf( "operator%s", to_str(op) );
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Name = get_cached_string( { str_len(name, MaxNameLength), name } );
|
|
||||||
result->ModuleFlags = mflags;
|
|
||||||
|
|
||||||
if ( attributes )
|
|
||||||
result->add_entry( attributes );
|
|
||||||
|
|
||||||
if ( specifiers )
|
|
||||||
result->add_entry( specifiers );
|
|
||||||
|
|
||||||
if (params_code)
|
|
||||||
result->add_entry( params_code );
|
|
||||||
|
|
||||||
result->add_entry( ret_type );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_params()
|
|
||||||
{
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = ECode::Parameters;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_specifiers()
|
|
||||||
{
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = ECode::Specifiers;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code make_struct( StrC name, Code parent, Code specifiers, Code attributes, ModuleFlag mflags )
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
|
|
||||||
name_check( make_struct, name );
|
|
||||||
|
|
||||||
if ( attributes && attributes->Type != Attributes )
|
|
||||||
{
|
|
||||||
log_failure( "gen::make_struct: attributes was not a `Attributes` type: %s", attributes->debug_str() );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( specifiers && specifiers->Type != Specifiers )
|
|
||||||
{
|
|
||||||
log_failure( "gen::make_struct: specifiers was not a `Specifiers` type" );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( parent && parent->Type != Struct )
|
|
||||||
{
|
|
||||||
log_failure( "gen::make_struct: parent was not a `Struct` type" );
|
|
||||||
return Code::Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
Code
|
|
||||||
result = make_code();
|
|
||||||
result->Type = Struct;
|
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
result->ModuleFlags = mflags;
|
|
||||||
|
|
||||||
Code
|
|
||||||
body = make_code();
|
|
||||||
body->Type = Function_Body;
|
|
||||||
|
|
||||||
result->add_entry( make_code() );
|
|
||||||
|
|
||||||
if ( attributes )
|
|
||||||
result->add_entry( attributes );
|
|
||||||
|
|
||||||
if ( specifiers )
|
|
||||||
result->add_entry( specifiers );
|
|
||||||
|
|
||||||
if ( parent )
|
|
||||||
result->add_entry( parent );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
# undef name_check
|
# undef name_check
|
||||||
# undef null_check
|
# undef null_check
|
||||||
# undef null_or_invalid_check
|
# undef null_or_invalid_check
|
||||||
#endif // GEN_FEATURE_INCREMENTAL
|
#pragma endregion Upfront Constructors
|
||||||
#pragma endregion Incremetnal Constructions
|
|
||||||
|
|
||||||
#pragma region Parsing Constructors
|
#pragma region Parsing Constructors
|
||||||
#ifdef GEN_FEATURE_PARSING
|
#ifdef GEN_FEATURE_PARSING
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "Bloat.hpp"
|
#include "Bloat.hpp"
|
||||||
|
|
||||||
// Temporarily here for debugging purposes.
|
// Temporarily here for debugging purposes.
|
||||||
// #define GEN_DEFINE_DSL
|
|
||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
||||||
// #define GEN_DONT_USE_FATAL
|
// #define GEN_DONT_USE_FATAL
|
||||||
// #define GEN_ENFORCE_READONLY_AST
|
// #define GEN_ENFORCE_READONLY_AST
|
||||||
@ -390,11 +389,6 @@ namespace gen
|
|||||||
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 );
|
|
||||||
|
|
||||||
void add_entry( AST* other );
|
void add_entry( AST* other );
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -413,7 +407,7 @@ namespace gen
|
|||||||
inline
|
inline
|
||||||
bool has_entries()
|
bool has_entries()
|
||||||
{
|
{
|
||||||
return entry( 0 );
|
return num_entries();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -422,6 +416,9 @@ namespace gen
|
|||||||
return Type != ECode::Invalid;
|
return Type != ECode::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool is_equal( AST* other );
|
||||||
|
|
||||||
inline
|
inline
|
||||||
s32 num_entries()
|
s32 num_entries()
|
||||||
{
|
{
|
||||||
@ -640,13 +637,13 @@ namespace gen
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
String to_string()
|
String to_string() const
|
||||||
{
|
{
|
||||||
return ast->to_string();
|
return ast->to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
operator bool()
|
operator bool() const
|
||||||
{
|
{
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
@ -718,21 +715,6 @@ namespace gen
|
|||||||
|
|
||||||
// Used when the its desired when omission is allowed in a definition.
|
// Used when the its desired when omission is allowed in a definition.
|
||||||
constexpr Code NoCode = { nullptr };
|
constexpr Code NoCode = { nullptr };
|
||||||
// extern const Code InvalidCode;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Type Table: Used to store Typename ASTs. Types are registered by their string literal value.
|
|
||||||
|
|
||||||
Provides interning specific to Typename ASTs.
|
|
||||||
Interning for other types should be possible (specifiers) with this, so long as they
|
|
||||||
don't have an set of child AST entries (Use the content field).
|
|
||||||
|
|
||||||
TODO: I'm not sure if this is viable.
|
|
||||||
ASTs are duplicated when added (parent is unique),
|
|
||||||
Parent is currently used for debug and serialization.
|
|
||||||
If these features are considered unnecessary, then caching would be fine.
|
|
||||||
*/
|
|
||||||
// ZPL_TABLE_DECLARE( ZPL_EXTERN, TypeTable, type_tbl_, Code );
|
|
||||||
#pragma endregion Data Structures
|
#pragma endregion Data Structures
|
||||||
|
|
||||||
#pragma region Gen Interface
|
#pragma region Gen Interface
|
||||||
@ -856,45 +838,6 @@ namespace gen
|
|||||||
Code def_union_body ( s32 num, Code* codes );
|
Code def_union_body ( s32 num, Code* codes );
|
||||||
# pragma endregion Upfront
|
# pragma endregion Upfront
|
||||||
|
|
||||||
# pragma region Incremental
|
|
||||||
# ifdef GEN_FEATURE_INCREMENTAL
|
|
||||||
Code make_class( StrC name
|
|
||||||
, Code parent = NoCode, AccessSpec access = AccessSpec::Default
|
|
||||||
, Code specifiers = NoCode, Code attributes = NoCode
|
|
||||||
, ModuleFlag mflags = ModuleFlag::None );
|
|
||||||
|
|
||||||
Code make_enum( StrC name
|
|
||||||
, Code type = NoCode, EnumT specifier = EnumRegular
|
|
||||||
, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
|
|
||||||
|
|
||||||
Code make_export_body( StrC name = { 1, "" } );
|
|
||||||
Code make_extern_link( s32 length, char const* name, ModuleFlag mflags = ModuleFlag::None );
|
|
||||||
|
|
||||||
Code make_function( StrC name
|
|
||||||
, Code params = NoCode, Code ret_type = NoCode
|
|
||||||
, Code specifiers = NoCode, Code attributes = NoCode
|
|
||||||
, ModuleFlag mflags = ModuleFlag::None );
|
|
||||||
|
|
||||||
Code make_global_body( StrC name = { 1, "" } );
|
|
||||||
Code make_namespace ( s32 length, char const* name, ModuleFlag mflags = ModuleFlag::None );
|
|
||||||
|
|
||||||
Code make_operator( OperatorT op
|
|
||||||
, Code params = NoCode, Code ret_type = NoCode
|
|
||||||
, Code specifiers = NoCode, Code attributes = NoCode
|
|
||||||
, ModuleFlag mflags = ModuleFlag::None );
|
|
||||||
|
|
||||||
Code make_params ();
|
|
||||||
Code make_specifiers();
|
|
||||||
|
|
||||||
Code make_struct( StrC name
|
|
||||||
, Code parent = NoCode, AccessSpec access = AccessSpec::Default
|
|
||||||
, Code specifiers = NoCode, Code attributes = NoCode
|
|
||||||
, ModuleFlag mflags = ModuleFlag::None );
|
|
||||||
|
|
||||||
Code make_union( StrC name, Code attributes = NoCode, ModuleFlag mflags = ModuleFlag::None );
|
|
||||||
# endif
|
|
||||||
# pragma endregion Incremental
|
|
||||||
|
|
||||||
#pragma region Parsing
|
#pragma region Parsing
|
||||||
#ifdef GEN_FEATURE_PARSING
|
#ifdef GEN_FEATURE_PARSING
|
||||||
Code parse_class ( StrC class_def );
|
Code parse_class ( StrC class_def );
|
||||||
@ -1062,10 +1005,8 @@ namespace gen
|
|||||||
# define gen_main main
|
# define gen_main main
|
||||||
|
|
||||||
# define __ NoCode
|
# define __ NoCode
|
||||||
# define spec_alignas( Value_ ) ESpecifier::Alignas, Value
|
|
||||||
|
|
||||||
// This represents the naming convention for all typename Codes generated.
|
// This represents the naming convention for all typename Codes generated.
|
||||||
// Used by the DSL but can also be used without it.
|
|
||||||
# define type_ns( Name_ ) t_##Name_
|
# define type_ns( Name_ ) t_##Name_
|
||||||
|
|
||||||
// Convienence for defining any name used with the gen api.
|
// Convienence for defining any name used with the gen api.
|
||||||
@ -1075,6 +1016,9 @@ namespace gen
|
|||||||
// Same as name just used to indicate intention of literal for code instead of names.
|
// Same as name just used to indicate intention of literal for code instead of names.
|
||||||
# define code( Code_ ) { txt_n_len( Code_ ) }
|
# define code( Code_ ) { txt_n_len( Code_ ) }
|
||||||
|
|
||||||
|
# define code_args( num, ... ) num, (Code[num]){ __VA_ARGS__ }
|
||||||
|
|
||||||
|
# define enum_entry( id ) "\t" #id ",\n"
|
||||||
#pragma endregion Macros
|
#pragma endregion Macros
|
||||||
|
|
||||||
#pragma region Constants
|
#pragma region Constants
|
||||||
|
@ -52,12 +52,29 @@ $path_scripts = Join-Path $path_root scripts
|
|||||||
$gencpp = Join-Path $path_gen_build gencpp.exe
|
$gencpp = Join-Path $path_gen_build gencpp.exe
|
||||||
|
|
||||||
Push-location $path_gen
|
Push-location $path_gen
|
||||||
# & $gencpp
|
|
||||||
|
Write-Host `nGenerating files...
|
||||||
|
& $gencpp
|
||||||
|
|
||||||
|
Write-Host `nBeginning format...
|
||||||
|
$formatParams = @(
|
||||||
|
'-i' # In-place
|
||||||
|
'-style=file' # Search for a .clang-format file in the parent directory of the source file.
|
||||||
|
'-verbose'
|
||||||
|
)
|
||||||
|
|
||||||
|
$include = @('*.gen.hpp', '*.gen.cpp')
|
||||||
|
$exclude = $null
|
||||||
|
|
||||||
|
$targetFiles = @(Get-ChildItem -Recurse -Path $path_gen -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName)
|
||||||
|
|
||||||
|
clang-format $formatParams $targetFiles
|
||||||
|
Write-Host "`nFormatting complete"
|
||||||
Pop-Location
|
Pop-Location
|
||||||
|
|
||||||
|
|
||||||
# Build the program depending on generated files.
|
# Build the program depending on generated files.
|
||||||
# if ( -not( Test-Path $path_test_build ) )
|
# if ( -not( Test-Path $path_test_build ) )k
|
||||||
# {
|
# {
|
||||||
# $args_meson = @()
|
# $args_meson = @()
|
||||||
# $args_meson += "setup"
|
# $args_meson += "setup"
|
||||||
|
5
singleheader/gen/Readme.md
Normal file
5
singleheader/gen/Readme.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Singleheader generator
|
||||||
|
|
||||||
|
This will require the scanner to be implemented before it can be done properly.
|
||||||
|
|
||||||
|
|
0
singleheader/gen/gen.singleheader.cpp
Normal file
0
singleheader/gen/gen.singleheader.cpp
Normal file
@ -1,4 +0,0 @@
|
|||||||
// Removes the genc_ namespace if desired
|
|
||||||
|
|
||||||
namespace genc_
|
|
||||||
|
|
0
singleheader/meson.build
Normal file
0
singleheader/meson.build
Normal file
@ -56,11 +56,9 @@ u32 gen_sanity()
|
|||||||
Code def;
|
Code def;
|
||||||
{
|
{
|
||||||
Code body = untyped_str( StrC::from(
|
Code body = untyped_str( StrC::from(
|
||||||
#define enum_entry( id ) "\t" #id ",\n"
|
|
||||||
enum_entry( A )
|
enum_entry( A )
|
||||||
enum_entry( B )
|
enum_entry( B )
|
||||||
enum_entry( C )
|
enum_entry( C )
|
||||||
#undef enum_entry
|
|
||||||
));
|
));
|
||||||
|
|
||||||
def = def_enum( name(ETestEnum), body, t_u8 );
|
def = def_enum( name(ETestEnum), body, t_u8 );
|
||||||
@ -120,7 +118,7 @@ u32 gen_sanity()
|
|||||||
|
|
||||||
// Include
|
// Include
|
||||||
{
|
{
|
||||||
Code include = def_include( StrC::from("DummyInclude.hpp") );
|
Code include = def_include( StrC::from("../DummyInclude.hpp") );
|
||||||
|
|
||||||
gen_sanity_file.print(include);
|
gen_sanity_file.print(include);
|
||||||
}
|
}
|
||||||
@ -161,7 +159,37 @@ u32 gen_sanity()
|
|||||||
|
|
||||||
// Operator
|
// Operator
|
||||||
{
|
{
|
||||||
// This is nasty...
|
// Going to make a bit flag set of overloads for this.
|
||||||
|
|
||||||
|
|
||||||
|
Code bitflagtest;
|
||||||
|
{
|
||||||
|
Code body = def_enum_body( 1, untyped_str( StrC::from(
|
||||||
|
enum_entry( A = 1 << 0 )
|
||||||
|
enum_entry( B = 1 << 1 )
|
||||||
|
enum_entry( C = 1 << 2 )
|
||||||
|
)));
|
||||||
|
bitflagtest = def_enum( name(EBitFlagtest), body, t_u8, EnumClass );
|
||||||
|
}
|
||||||
|
Code t_bitflag = def_type( name(EBitFlagtest) );
|
||||||
|
|
||||||
|
Code op_fwd, op_or;
|
||||||
|
{
|
||||||
|
Code params = def_params( code_args( 2,
|
||||||
|
def_param( t_bitflag, name(a) ),
|
||||||
|
def_param( t_bitflag, name(b) )
|
||||||
|
));
|
||||||
|
|
||||||
|
op_fwd = def_operator( EOperator::BOr, params, t_bitflag );
|
||||||
|
op_or = def_operator( EOperator::BOr, params, t_bitflag, untyped_str( code(
|
||||||
|
return EBitFlagtest( (u8)a | (u8)b );
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
gen_sanity_file.print(bitflagtest);
|
||||||
|
gen_sanity_file.print_fmt("\n");
|
||||||
|
gen_sanity_file.print(op_fwd);
|
||||||
|
gen_sanity_file.print(op_or);
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_sanity_file.print_fmt("\n");
|
gen_sanity_file.print_fmt("\n");
|
||||||
|
163
test/gen/.clang-format
Normal file
163
test/gen/.clang-format
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
# Format Style Options - Created with Clang Power Tools
|
||||||
|
---
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
|
||||||
|
AlignAfterOpenBracket: BlockIndent
|
||||||
|
AlignArrayOfStructures: Right
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: true
|
||||||
|
AlignCompound: true
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields: AcrossComments
|
||||||
|
AlignConsecutiveDeclarations: AcrossComments
|
||||||
|
AlignConsecutiveMacros: AcrossComments
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: DontAlign
|
||||||
|
|
||||||
|
AlignTrailingComments: true
|
||||||
|
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortLambdasOnASingleLine: None
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
|
||||||
|
# BreakAfterAttributes: Always
|
||||||
|
# BreakArrays: false
|
||||||
|
# BreakBeforeInlineASMColon: OnlyMultiline
|
||||||
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
|
BreakBeforeBraces: Allman
|
||||||
|
BreakBeforeInheritanceComma: true
|
||||||
|
BreakInheritanceList: BeforeComma
|
||||||
|
BreakBeforeConceptDeclarations: true
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakStringLiterals: true
|
||||||
|
|
||||||
|
ColumnLimit: 180
|
||||||
|
|
||||||
|
CompactNamespaces: true
|
||||||
|
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth : 4
|
||||||
|
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
|
||||||
|
DeriveLineEnding: true
|
||||||
|
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
|
||||||
|
FixNamespaceComments: true
|
||||||
|
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
|
||||||
|
|
||||||
|
IndentCaseBlocks: true
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
IndentRequires: true
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
|
||||||
|
# InsertNewlineAtEOF: true
|
||||||
|
InsertTrailingCommas: Wrapped
|
||||||
|
|
||||||
|
LambdaBodyIndentation: OuterScope
|
||||||
|
|
||||||
|
Language: Cpp
|
||||||
|
|
||||||
|
MaxEmptyLinesToKeep: 4
|
||||||
|
|
||||||
|
NamespaceIndentation: All
|
||||||
|
|
||||||
|
PointerAlignment: Left
|
||||||
|
|
||||||
|
QualifierAlignment: Leave
|
||||||
|
|
||||||
|
ReferenceAlignment: Left
|
||||||
|
|
||||||
|
ReflowComments: true
|
||||||
|
|
||||||
|
# RequiresExpressionIndentation: OuterScope
|
||||||
|
|
||||||
|
SeparateDefinitionBlocks: Always
|
||||||
|
|
||||||
|
ShortNamespaceLines: 40
|
||||||
|
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: true
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: true
|
||||||
|
SpaceBeforeCpp11BracedList: true
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpacesBeforeTrailingComments: 4
|
||||||
|
|
||||||
|
SpaceInEmptyBlock: true
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesInAngles: true
|
||||||
|
SpacesInCStyleCastParentheses: true
|
||||||
|
SpacesInConditionalStatement: true
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: 20
|
||||||
|
SpacesInParentheses: true
|
||||||
|
SpacesInSquareBrackets: true
|
||||||
|
|
||||||
|
Standard: c++17
|
||||||
|
|
||||||
|
TabWidth: 4
|
||||||
|
|
||||||
|
UseTab: ForIndentation
|
||||||
|
...
|
@ -3,15 +3,16 @@
|
|||||||
// The following will show a series of base cases for the gen api.
|
// The following will show a series of base cases for the gen api.
|
||||||
|
|
||||||
class TestEmptyClass;
|
class TestEmptyClass;
|
||||||
|
|
||||||
class TestEmptyClass
|
class TestEmptyClass
|
||||||
{
|
{
|
||||||
// Empty class body
|
// Empty class body
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef unsigned char u8;
|
typedef unsigned char u8;
|
||||||
|
|
||||||
enum ETestEnum : u8;
|
enum ETestEnum : u8;
|
||||||
|
|
||||||
enum ETestEnum : u8
|
enum ETestEnum : u8
|
||||||
{
|
{
|
||||||
A,
|
A,
|
||||||
@ -23,24 +24,21 @@ enum class ETestEnumClass : u8;
|
|||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
// Empty extern body
|
// Empty extern body
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestFriend
|
class TestFriend
|
||||||
{
|
{
|
||||||
friend class TestFriendFwd;
|
friend class TestFriendFwd;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void test_function( void );
|
void test_function( void );
|
||||||
|
|
||||||
void test_function( void )
|
void test_function( void )
|
||||||
{
|
{
|
||||||
// Empty function body
|
// Empty function body
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "DummyInclude.hpp"
|
#include "../DummyInclude.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace TestNamespace
|
namespace TestNamespace
|
||||||
{
|
{
|
||||||
@ -48,31 +46,43 @@ namespace TestNamespace
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class EBitFlagtest : u8
|
||||||
|
{
|
||||||
|
A = 1 << 0,
|
||||||
|
B = 1 << 1,
|
||||||
|
C = 1 << 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
EBitFlagtest operator|( EBitFlagtest a, EBitFlagtest b );
|
||||||
|
|
||||||
|
EBitFlagtest operator|( EBitFlagtest a, EBitFlagtest b )
|
||||||
|
{
|
||||||
|
return EBitFlagtest( ( u8 )a | ( u8 )b );
|
||||||
|
}
|
||||||
|
|
||||||
void test_function_wparam( u8 a );
|
void test_function_wparam( u8 a );
|
||||||
|
|
||||||
void test_function_wparams( u8 a, u8 b )
|
void test_function_wparams( u8 a, u8 b )
|
||||||
{
|
{
|
||||||
// Empty function body
|
// Empty function body
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_function_wparams2( u8 a, u8 b )
|
void test_function_wparams2( u8 a, u8 b )
|
||||||
{
|
{
|
||||||
// Empty function body
|
// Empty function body
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestEmptyStruct;
|
class TestEmptyStruct;
|
||||||
|
|
||||||
class TestEmptyStruct
|
class TestEmptyStruct
|
||||||
{
|
{
|
||||||
// Empty class body
|
// Empty class body
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
union TestEmptyUnion
|
union TestEmptyUnion
|
||||||
{
|
{
|
||||||
// Empty union body
|
// Empty union body
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using TestUsing = u8;
|
using TestUsing = u8;
|
||||||
@ -82,4 +92,3 @@ u8 test_variable;
|
|||||||
u8 test_variable2 = 0x12;
|
u8 test_variable2 = 0x12;
|
||||||
|
|
||||||
// End of base case tests.
|
// End of base case tests.
|
||||||
|
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
#include "Bloat.cpp"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef gen_time
|
|
||||||
#include "gen.cpp"
|
|
||||||
|
|
||||||
|
|
||||||
void case_untyped()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int gen_main()
|
|
||||||
{
|
|
||||||
Memory::setup();
|
|
||||||
|
|
||||||
log_fmt("\nPress any key after attaching to process\n");
|
|
||||||
getchar();
|
|
||||||
|
|
||||||
gen::init();
|
|
||||||
|
|
||||||
case_untyped();
|
|
||||||
|
|
||||||
Memory::cleanup();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef runtime
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user