mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-23 00:04:45 -08:00
Compare commits
No commits in common. "cb898595b09d276592aeb788c7b7586b952c1d9f" and "401f85f673212e1eae359485913df08171d5ad00" have entirely different histories.
cb898595b0
...
401f85f673
10
Readme.md
10
Readme.md
@ -10,16 +10,18 @@ Its not meant to be a black box metaprogramming utility, it should be easy to in
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
If your going to metaprogram, you can never have enough docs on your tooling...
|
||||||
|
|
||||||
* [docs - General](./docs/Readme.md): Overview and additional docs
|
* [docs - General](./docs/Readme.md): Overview and additional docs
|
||||||
* [AST_Design](./docs/AST_Design.md): Overvie of ASTs
|
* [AST_Design](./docs/AST_Design.md): Overvie of ASTs
|
||||||
* [AST Types](./docs/AST_Types.md): Listing of all AST types along with their Code type interface.
|
* [AST Types](./docs/AST_Types.md): Listing of all AST types along with their Code type interface.
|
||||||
* [Parsing](./docs/Parsing.md): Overview of the parsing interface.
|
* [Parsing](./docs/Parsing.md): Overview of the parsing interface.
|
||||||
* [Parser Algo](./docs/Parser_Algo.md): In-depth breakdown of the parser's implementation.
|
* [Parser Algo](./docs/Parser_Algo.md): In-depth breakdown of the parser's implementation.
|
||||||
* [base](./base/Readme.md): Essential (base) library.
|
* [base](./base/Readme.md): Essential (base) library.
|
||||||
* [gen_c_library](./gen_c_library/): C11 library variant generation (single header and segmeented).
|
* [gen_c_library](./gen_c_library/Readme.md): C11 library variant generation (single header and segmeented).
|
||||||
* [gen_segmented](./gen_segmented/): Segemented C++ (`gen.<hpp/cpp>`, `gen.dep.<hpp/cpp>`) generation
|
* [gen_segmented](./gen_segmented/Readme.md): Segemented C++ (`gen.<hpp/cpp>`, `gen.dep.<hpp/cpp>`) generation
|
||||||
* [gen_singleheader](./gen_singleheader/): Singlehader C++ generation `gen.hpp`
|
* [gen_singleheader](./gen_singleheader/Readme.md): Singlehader C++ generation `gen.hpp`
|
||||||
* [gen_unreal_engine](./gen_unreal_engine/): Unreal Engine thirdparty code generation.
|
* [gen_unreal_engine](./gen_unreal_engine/Readme.md): Unreal Engine thirdparty code generation.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@ Standard formats:
|
|||||||
|
|
||||||
Code not making up the core library is located in `auxiliary/<auxiliary_name>.<hpp/cpp>`. These are optional extensions or tools for the library.
|
Code not making up the core library is located in `auxiliary/<auxiliary_name>.<hpp/cpp>`. These are optional extensions or tools for the library.
|
||||||
|
|
||||||
|
*Note: A variant of the C++ library could be generated where those additonal support features are removed (see gen_c_library implementation for an idea of how)*
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
The project has no external dependencies beyond:
|
The project has no external dependencies beyond:
|
||||||
@ -69,11 +71,7 @@ This library was written in a subset of C++ where the following are not used at
|
|||||||
* Exceptions
|
* Exceptions
|
||||||
|
|
||||||
Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.
|
Polymorphic & Member-functions are used as an ergonomic choice, along with a conserative use of operator overloads.
|
||||||
The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C.
|
The base library itself does not use anything but C-like features to allow for generating a derviative compatiable with C (WIP).
|
||||||
|
|
||||||
Member function support or free-functions with reference object passing are wrapped in `! GEN_C_LIKE CPP` preprocess conditionals.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## C++ template usage
|
## C++ template usage
|
||||||
|
|
||||||
@ -119,7 +117,7 @@ The vast majority of macros should be single-line subsitutions that either add:
|
|||||||
|
|
||||||
There are ***five*** header files which are automatically generated using [base_codegen.hpp](./helpers/base_codegen.hpp) by [base.cpp](./base.cpp). They are all located in [components/gen](./components/gen/).
|
There are ***five*** header files which are automatically generated using [base_codegen.hpp](./helpers/base_codegen.hpp) by [base.cpp](./base.cpp). They are all located in [components/gen](./components/gen/).
|
||||||
|
|
||||||
* [`ecodetypes.hpp`](./components/gen/ecode.hpp): `CodeType` enum definition and related implementaiton. Generation is based off of [`ECodeType.csv](./enums/ECodeTypes.csv).
|
* [`ecode.hpp`](./components/gen/ecode.hpp): `CodeType` enum definition and related implementaiton. Generation is based off of [`ECodeType.csv](./enums/ECodeTypes.csv).
|
||||||
* [`especifier.hpp`](./components/gen/especifier.hpp): `Specifier` enum definition, etc. Generated using [`ESpecifier.csv`](./enums/ESpecifier.csv).
|
* [`especifier.hpp`](./components/gen/especifier.hpp): `Specifier` enum definition, etc. Generated using [`ESpecifier.csv`](./enums/ESpecifier.csv).
|
||||||
* [`eoperator.hpp`](./components/gen/eoperator.hpp): `Operator` enum definition, etc. Generated using [`EOperator.hpp`](./enums/EOperator.csv).
|
* [`eoperator.hpp`](./components/gen/eoperator.hpp): `Operator` enum definition, etc. Generated using [`EOperator.hpp`](./enums/EOperator.csv).
|
||||||
* [`etoktype.cpp`](./components/gen/etoktype.cpp): `TokType` enum defininition, etc. Used by the lexer and parser backend. Uses two csvs:
|
* [`etoktype.cpp`](./components/gen/etoktype.cpp): `TokType` enum defininition, etc. Used by the lexer and parser backend. Uses two csvs:
|
||||||
@ -137,7 +135,7 @@ Currently unsupported. I want the library to be *stable* and *correct*, with the
|
|||||||
|
|
||||||
This library is relatively very small (for parsing C++), and can be extended without much hassle.
|
This library is relatively very small (for parsing C++), and can be extended without much hassle.
|
||||||
|
|
||||||
The convention you'll see used throughout the upfront interface of the library is as follows:
|
The convention you'll see used throughout the interface of the library is as follows:
|
||||||
|
|
||||||
1. Check name or parameters to make sure they are valid for the construction requested
|
1. Check name or parameters to make sure they are valid for the construction requested
|
||||||
2. Create a code object using `make_code`.
|
2. Create a code object using `make_code`.
|
||||||
@ -148,7 +146,7 @@ Names or Content fields are interned strings and thus showed be cached using `ge
|
|||||||
|
|
||||||
`def_operator` is the most sophisticated upfront constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid.
|
`def_operator` is the most sophisticated upfront constructor as it has multiple permutations of definitions that could be created that are not trivial to determine if valid.
|
||||||
|
|
||||||
The parser is documented under [`docs/Parsing.md`](../docs/Parsing.md) and [`docs/Parser_Algo.md`](../docs/Parser_Algo.md). Extending it is more serious.
|
The parser is documented under `docs/Parsing.md` and `docs/Parser_Algo.md`. Extending it is more serious, but resolution of a parse for a given internal parse procedure is well documented.
|
||||||
|
|
||||||
## A note on compilation and runtime generation speed
|
## A note on compilation and runtime generation speed
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ int gen_main()
|
|||||||
CodeBody especifier = gen_especifier( "enums/ESpecifier.csv" );
|
CodeBody especifier = gen_especifier( "enums/ESpecifier.csv" );
|
||||||
CodeBody ast_inlines = gen_ast_inlines();
|
CodeBody ast_inlines = gen_ast_inlines();
|
||||||
|
|
||||||
Builder header_ecode = builder_open( "components/gen/ecodetypes.hpp" );
|
Builder header_ecode = builder_open( "components/gen/ecode.hpp" );
|
||||||
builder_print( & header_ecode, gen_component_header );
|
builder_print( & header_ecode, gen_component_header );
|
||||||
builder_print( & header_ecode, format(ecode) );
|
builder_print( & header_ecode, format(ecode) );
|
||||||
builder_write( & header_ecode);
|
builder_write( & header_ecode);
|
||||||
|
@ -497,7 +497,7 @@ void code_to_string_ptr( Code self, String* result )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_Parameters:
|
case CT_Parameters:
|
||||||
params_to_string_ref(cast(CodeParams, self), result );
|
params_to_string_ref(cast(CodeParam, self), result );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CT_Preprocess_Define:
|
case CT_Preprocess_Define:
|
||||||
|
@ -37,7 +37,7 @@ struct AST_Module;
|
|||||||
struct AST_NS;
|
struct AST_NS;
|
||||||
struct AST_Operator;
|
struct AST_Operator;
|
||||||
struct AST_OpCast;
|
struct AST_OpCast;
|
||||||
struct AST_Params;
|
struct AST_Param;
|
||||||
struct AST_Pragma;
|
struct AST_Pragma;
|
||||||
struct AST_PreprocessCond;
|
struct AST_PreprocessCond;
|
||||||
struct AST_Specifiers;
|
struct AST_Specifiers;
|
||||||
@ -109,7 +109,7 @@ typedef AST_Module* CodeModule;
|
|||||||
typedef AST_NS* CodeNS;
|
typedef AST_NS* CodeNS;
|
||||||
typedef AST_Operator* CodeOperator;
|
typedef AST_Operator* CodeOperator;
|
||||||
typedef AST_OpCast* CodeOpCast;
|
typedef AST_OpCast* CodeOpCast;
|
||||||
typedef AST_Params* CodeParams;
|
typedef AST_Param* CodeParam;
|
||||||
typedef AST_PreprocessCond* CodePreprocessCond;
|
typedef AST_PreprocessCond* CodePreprocessCond;
|
||||||
typedef AST_Pragma* CodePragma;
|
typedef AST_Pragma* CodePragma;
|
||||||
typedef AST_Specifiers* CodeSpecifiers;
|
typedef AST_Specifiers* CodeSpecifiers;
|
||||||
@ -131,7 +131,7 @@ struct CodeModule;
|
|||||||
struct CodeNS;
|
struct CodeNS;
|
||||||
struct CodeOperator;
|
struct CodeOperator;
|
||||||
struct CodeOpCast;
|
struct CodeOpCast;
|
||||||
struct CodeParams;
|
struct CodeParam;
|
||||||
struct CodePreprocessCond;
|
struct CodePreprocessCond;
|
||||||
struct CodePragma;
|
struct CodePragma;
|
||||||
struct CodeSpecifiers;
|
struct CodeSpecifiers;
|
||||||
@ -209,7 +209,6 @@ struct CodeStmt_Switch;
|
|||||||
struct CodeStmt_While;
|
struct CodeStmt_While;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// GEN_EXECUTION_EXPRESSION_SUPPORT
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GEN_COMPILER_C
|
#if GEN_COMPILER_C
|
||||||
@ -230,6 +229,8 @@ struct CodeUsing;
|
|||||||
struct CodeVar;
|
struct CodeVar;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#undef Define_Code
|
||||||
|
|
||||||
GEN_NS_PARSER_BEGIN
|
GEN_NS_PARSER_BEGIN
|
||||||
|
|
||||||
struct Token;
|
struct Token;
|
||||||
@ -342,7 +343,7 @@ struct Code
|
|||||||
operator CodeNS() const;
|
operator CodeNS() const;
|
||||||
operator CodeOperator() const;
|
operator CodeOperator() const;
|
||||||
operator CodeOpCast() const;
|
operator CodeOpCast() const;
|
||||||
operator CodeParams() const;
|
operator CodeParam() const;
|
||||||
operator CodePragma() const;
|
operator CodePragma() const;
|
||||||
operator CodePreprocessCond() const;
|
operator CodePreprocessCond() const;
|
||||||
operator CodeSpecifiers() const;
|
operator CodeSpecifiers() const;
|
||||||
@ -455,7 +456,7 @@ struct AST
|
|||||||
Operator Op;
|
Operator Op;
|
||||||
AccessSpec ParentAccess;
|
AccessSpec ParentAccess;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
s32 VarParenthesizedInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
|
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST is not size of AST_POD_Size" );
|
static_assert( sizeof(AST) == AST_POD_Size, "ERROR: AST is not size of AST_POD_Size" );
|
||||||
|
@ -127,7 +127,7 @@ struct AST_Constructor
|
|||||||
char _PAD_PROPERTIES_ [ sizeof(AST*) * 1 ];
|
char _PAD_PROPERTIES_ [ sizeof(AST*) * 1 ];
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
Code InitializerList;
|
Code InitializerList;
|
||||||
CodeParams Params;
|
CodeParam Params;
|
||||||
Code Body;
|
Code Body;
|
||||||
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
|
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
|
||||||
};
|
};
|
||||||
@ -550,7 +550,7 @@ struct AST_Fn
|
|||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeTypename ReturnType;
|
CodeTypename ReturnType;
|
||||||
CodeParams Params;
|
CodeParam Params;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
@ -613,7 +613,7 @@ struct AST_Operator
|
|||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeTypename ReturnType;
|
CodeTypename ReturnType;
|
||||||
CodeParams Params;
|
CodeParam Params;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
char _PAD_PROPERTIES_ [ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
@ -654,7 +654,7 @@ struct AST_OpCast
|
|||||||
};
|
};
|
||||||
static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the same size as AST");
|
static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the same size as AST");
|
||||||
|
|
||||||
struct AST_Params
|
struct AST_Param
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
|
||||||
@ -669,15 +669,15 @@ struct AST_Params
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Name;
|
StringCached Name;
|
||||||
CodeParams Last;
|
CodeParam Last;
|
||||||
CodeParams Next;
|
CodeParam Next;
|
||||||
Token* Tok;
|
Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Params) == sizeof(AST), "ERROR: AST_Params is not the same size as AST");
|
static_assert( sizeof(AST_Param) == sizeof(AST), "ERROR: AST_Param is not the same size as AST");
|
||||||
|
|
||||||
struct AST_Pragma
|
struct AST_Pragma
|
||||||
{
|
{
|
||||||
@ -971,7 +971,7 @@ struct AST_Template
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
|
char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ];
|
||||||
CodeParams Params;
|
CodeParam Params;
|
||||||
Code Declaration;
|
Code Declaration;
|
||||||
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
|
||||||
};
|
};
|
||||||
@ -1000,7 +1000,7 @@ struct AST_Type
|
|||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
Code QualifierID;
|
Code QualifierID;
|
||||||
// CodeTypename ReturnType; // Only used for function signatures
|
// CodeTypename ReturnType; // Only used for function signatures
|
||||||
// CodeParams Params; // Only used for function signatures
|
// CodeParam Params; // Only used for function signatures
|
||||||
Code ArrExpr;
|
Code ArrExpr;
|
||||||
// CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
|
// CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
|
||||||
};
|
};
|
||||||
@ -1017,6 +1017,7 @@ struct AST_Type
|
|||||||
static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST");
|
static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO(Ed): Add support for preserving the typename's keyword qualifier (struct, class, enum, etc), mostly needed for C.
|
||||||
struct AST_Typename
|
struct AST_Typename
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
@ -1027,7 +1028,7 @@ struct AST_Typename
|
|||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeTypename ReturnType; // Only used for function signatures
|
CodeTypename ReturnType; // Only used for function signatures
|
||||||
CodeParams Params; // Only used for function signatures
|
CodeParam Params; // Only used for function signatures
|
||||||
Code ArrExpr;
|
Code ArrExpr;
|
||||||
CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
|
CodeSpecifiers SpecsFuncSuffix; // Only used for function signatures
|
||||||
};
|
};
|
||||||
@ -1139,7 +1140,7 @@ struct AST_Var
|
|||||||
Code Parent;
|
Code Parent;
|
||||||
CodeType Type;
|
CodeType Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
s32 VarParenthesizedInit;
|
s32 VarConstructorInit;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST");
|
static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST");
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ void class_to_string_def( CodeClass self, String* result )
|
|||||||
|
|
||||||
while ( interface )
|
while ( interface )
|
||||||
{
|
{
|
||||||
string_append_fmt( result, ", public %S", typename_to_string(interface) );
|
string_append_fmt( result, ", %S", typename_to_string(interface) );
|
||||||
interface = interface->Next ? cast(CodeTypename, interface->Next) : NullCode;
|
interface = interface->Next ? cast(CodeTypename, interface->Next) : NullCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -863,7 +863,7 @@ void opcast_to_string_fwd(CodeOpCast self, String* result )
|
|||||||
string_append_fmt( result, "operator %S();\n", typename_to_string(self->ValueType) );
|
string_append_fmt( result, "operator %S();\n", typename_to_string(self->ValueType) );
|
||||||
}
|
}
|
||||||
|
|
||||||
String params_to_string(CodeParams self)
|
String params_to_string(CodeParam self)
|
||||||
{
|
{
|
||||||
GEN_ASSERT(self);
|
GEN_ASSERT(self);
|
||||||
GEN_ASSERT(self);
|
GEN_ASSERT(self);
|
||||||
@ -872,7 +872,7 @@ String params_to_string(CodeParams self)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void params_to_string_ref( CodeParams self, String* result )
|
void params_to_string_ref( CodeParam self, String* result )
|
||||||
{
|
{
|
||||||
GEN_ASSERT(self);
|
GEN_ASSERT(self);
|
||||||
GEN_ASSERT(result);
|
GEN_ASSERT(result);
|
||||||
@ -904,7 +904,7 @@ void params_to_string_ref( CodeParams self, String* result )
|
|||||||
|
|
||||||
if ( self->NumEntries - 1 > 0 )
|
if ( self->NumEntries - 1 > 0 )
|
||||||
{
|
{
|
||||||
for ( CodeParams param = begin_CodeParams(self->Next); param != end_CodeParams(self->Next); param = next_CodeParams(self->Next, param) )
|
for ( CodeParam param = begin_CodeParam(self->Next); param != end_CodeParam(self->Next); param = next_CodeParam(self->Next, param) )
|
||||||
{
|
{
|
||||||
string_append_fmt( result, ", %S", params_to_string(param) );
|
string_append_fmt( result, ", %S", params_to_string(param) );
|
||||||
}
|
}
|
||||||
@ -1385,7 +1385,7 @@ void var_to_string_ref(CodeVar self, String* result )
|
|||||||
|
|
||||||
if ( self->Value )
|
if ( self->Value )
|
||||||
{
|
{
|
||||||
if ( self->VarParenthesizedInit )
|
if ( self->VarConstructorInit )
|
||||||
string_append_fmt( result, "( %S ", code_to_string(self->Value) );
|
string_append_fmt( result, "( %S ", code_to_string(self->Value) );
|
||||||
else
|
else
|
||||||
string_append_fmt( result, " = %S", code_to_string(self->Value) );
|
string_append_fmt( result, " = %S", code_to_string(self->Value) );
|
||||||
@ -1395,7 +1395,7 @@ void var_to_string_ref(CodeVar self, String* result )
|
|||||||
if ( self->NextVar )
|
if ( self->NextVar )
|
||||||
string_append_fmt( result, ", %S", var_to_string(self->NextVar) );
|
string_append_fmt( result, ", %S", var_to_string(self->NextVar) );
|
||||||
|
|
||||||
if ( self->VarParenthesizedInit )
|
if ( self->VarConstructorInit )
|
||||||
string_append_strc( result, txt(" )"));
|
string_append_strc( result, txt(" )"));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -1431,7 +1431,7 @@ void var_to_string_ref(CodeVar self, String* result )
|
|||||||
|
|
||||||
if ( self->Value )
|
if ( self->Value )
|
||||||
{
|
{
|
||||||
if ( self->VarParenthesizedInit )
|
if ( self->VarConstructorInit )
|
||||||
string_append_fmt( result, "( %S ", code_to_string(self->Value) );
|
string_append_fmt( result, "( %S ", code_to_string(self->Value) );
|
||||||
else
|
else
|
||||||
string_append_fmt( result, " = %S", code_to_string(self->Value) );
|
string_append_fmt( result, " = %S", code_to_string(self->Value) );
|
||||||
@ -1440,7 +1440,7 @@ void var_to_string_ref(CodeVar self, String* result )
|
|||||||
if ( self->NextVar )
|
if ( self->NextVar )
|
||||||
string_append_fmt( result, ", %S", var_to_string(self->NextVar) );
|
string_append_fmt( result, ", %S", var_to_string(self->NextVar) );
|
||||||
|
|
||||||
if ( self->VarParenthesizedInit )
|
if ( self->VarConstructorInit )
|
||||||
string_append_strc( result, txt(" )"));
|
string_append_strc( result, txt(" )"));
|
||||||
|
|
||||||
if ( self->InlineCmt )
|
if ( self->InlineCmt )
|
||||||
@ -1471,7 +1471,7 @@ void var_to_string_ref(CodeVar self, String* result )
|
|||||||
|
|
||||||
if ( self->Value )
|
if ( self->Value )
|
||||||
{
|
{
|
||||||
if ( self->VarParenthesizedInit )
|
if ( self->VarConstructorInit )
|
||||||
string_append_fmt( result, "( %S ", code_to_string(self->Value) );
|
string_append_fmt( result, "( %S ", code_to_string(self->Value) );
|
||||||
else
|
else
|
||||||
string_append_fmt( result, " = %S", code_to_string(self->Value) );
|
string_append_fmt( result, " = %S", code_to_string(self->Value) );
|
||||||
@ -1480,7 +1480,7 @@ void var_to_string_ref(CodeVar self, String* result )
|
|||||||
if ( self->NextVar )
|
if ( self->NextVar )
|
||||||
string_append_fmt( result, ", %S", var_to_string( self->NextVar) );
|
string_append_fmt( result, ", %S", var_to_string( self->NextVar) );
|
||||||
|
|
||||||
if ( self->VarParenthesizedInit )
|
if ( self->VarConstructorInit )
|
||||||
string_append_strc( result, txt(" )"));
|
string_append_strc( result, txt(" )"));
|
||||||
|
|
||||||
string_append_strc( result, txt(";") );
|
string_append_strc( result, txt(";") );
|
||||||
|
@ -32,15 +32,15 @@ String class_to_string ( CodeClass self );
|
|||||||
void class_to_string_def( CodeClass self, String* result );
|
void class_to_string_def( CodeClass self, String* result );
|
||||||
void class_to_string_fwd( CodeClass self, String* result );
|
void class_to_string_fwd( CodeClass self, String* result );
|
||||||
|
|
||||||
void params_append (CodeParams params, CodeParams param );
|
void params_append (CodeParam params, CodeParam param );
|
||||||
CodeParams params_get (CodeParams params, s32 idx);
|
CodeParam params_get (CodeParam params, s32 idx);
|
||||||
bool params_has_entries (CodeParams params );
|
bool params_has_entries (CodeParam params );
|
||||||
String params_to_string (CodeParams params );
|
String params_to_string (CodeParam params );
|
||||||
void params_to_string_ref(CodeParams params, String* result );
|
void params_to_string_ref(CodeParam params, String* result );
|
||||||
|
|
||||||
CodeParams begin_CodeParams(CodeParams params);
|
CodeParam begin_CodeParam(CodeParam params);
|
||||||
CodeParams end_CodeParams (CodeParams params);
|
CodeParam end_CodeParam (CodeParam params);
|
||||||
CodeParams next_CodeParams (CodeParams params, CodeParams entry_iter);
|
CodeParam next_CodeParam (CodeParam params, CodeParam entry_iter);
|
||||||
|
|
||||||
bool specifiers_append (CodeSpecifiers specifiers, Specifier spec);
|
bool specifiers_append (CodeSpecifiers specifiers, Specifier spec);
|
||||||
s32 specifiers_has (CodeSpecifiers specifiers, Specifier spec);
|
s32 specifiers_has (CodeSpecifiers specifiers, Specifier spec);
|
||||||
@ -188,28 +188,28 @@ struct CodeClass
|
|||||||
AST_Class* ast;
|
AST_Class* ast;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CodeParams
|
struct CodeParam
|
||||||
{
|
{
|
||||||
#if ! GEN_C_LIKE_CPP
|
#if ! GEN_C_LIKE_CPP
|
||||||
Using_Code( CodeParams );
|
Using_Code( CodeParam );
|
||||||
forceinline void append( CodeParams other );
|
forceinline void append( CodeParam other );
|
||||||
forceinline CodeParams get( s32 idx );
|
forceinline CodeParam get( s32 idx );
|
||||||
forceinline bool has_entries();
|
forceinline bool has_entries();
|
||||||
forceinline String to_string();
|
forceinline String to_string();
|
||||||
forceinline void to_string( String& result );
|
forceinline void to_string( String& result );
|
||||||
|
|
||||||
forceinline CodeParams begin() { return begin_CodeParams(* this); }
|
forceinline CodeParam begin() { return begin_CodeParam(* this); }
|
||||||
forceinline CodeParams end() { return end_CodeParams(* this); }
|
forceinline CodeParam end() { return end_CodeParam(* this); }
|
||||||
#endif
|
#endif
|
||||||
Using_CodeOps( CodeParams );
|
Using_CodeOps( CodeParam );
|
||||||
forceinline operator Code() { return { (AST*)ast }; }
|
forceinline operator Code() { return { (AST*)ast }; }
|
||||||
forceinline CodeParams operator*() { return * this; }
|
forceinline CodeParam operator*() { return * this; }
|
||||||
forceinline AST_Params* operator->() {
|
forceinline AST_Param* operator->() {
|
||||||
GEN_ASSERT(ast);
|
GEN_ASSERT(ast);
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
CodeParams& operator++();
|
CodeParam& operator++();
|
||||||
AST_Params* ast;
|
AST_Param* ast;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CodeSpecifiers
|
struct CodeSpecifiers
|
||||||
@ -951,7 +951,7 @@ struct InvalidCode_ImplictCaster
|
|||||||
operator CodeNS () const { return cast(CodeNS, Code_Invalid); }
|
operator CodeNS () const { return cast(CodeNS, Code_Invalid); }
|
||||||
operator CodeOperator () const { return cast(CodeOperator, Code_Invalid); }
|
operator CodeOperator () const { return cast(CodeOperator, Code_Invalid); }
|
||||||
operator CodeOpCast () const { return cast(CodeOpCast, Code_Invalid); }
|
operator CodeOpCast () const { return cast(CodeOpCast, Code_Invalid); }
|
||||||
operator CodeParams () const { return cast(CodeParams, Code_Invalid); }
|
operator CodeParam () const { return cast(CodeParam, Code_Invalid); }
|
||||||
operator CodePragma () const { return cast(CodePragma, Code_Invalid); }
|
operator CodePragma () const { return cast(CodePragma, Code_Invalid); }
|
||||||
operator CodePreprocessCond() const { return cast(CodePreprocessCond, Code_Invalid); }
|
operator CodePreprocessCond() const { return cast(CodePreprocessCond, Code_Invalid); }
|
||||||
operator CodeSpecifiers () const { return cast(CodeSpecifiers, Code_Invalid); }
|
operator CodeSpecifiers () const { return cast(CodeSpecifiers, Code_Invalid); }
|
||||||
@ -984,7 +984,7 @@ struct NullCode_ImplicitCaster
|
|||||||
operator CodeNS () const { return {nullptr}; }
|
operator CodeNS () const { return {nullptr}; }
|
||||||
operator CodeOperator () const { return {nullptr}; }
|
operator CodeOperator () const { return {nullptr}; }
|
||||||
operator CodeOpCast () const { return {nullptr}; }
|
operator CodeOpCast () const { return {nullptr}; }
|
||||||
operator CodeParams () const { return {nullptr}; }
|
operator CodeParam () const { return {nullptr}; }
|
||||||
operator CodePragma () const { return {nullptr}; }
|
operator CodePragma () const { return {nullptr}; }
|
||||||
operator CodePreprocessCond() const { return {nullptr}; }
|
operator CodePreprocessCond() const { return {nullptr}; }
|
||||||
operator CodeSpecifiers () const { return {nullptr}; }
|
operator CodeSpecifiers () const { return {nullptr}; }
|
||||||
@ -1015,15 +1015,15 @@ forceinline String to_string ( CodeClass self ) { ret
|
|||||||
forceinline void to_string_def( CodeClass self, String& result ) { return class_to_string_def(self, & result); }
|
forceinline void to_string_def( CodeClass self, String& result ) { return class_to_string_def(self, & result); }
|
||||||
forceinline void to_string_fwd( CodeClass self, String& result ) { return class_to_string_fwd(self, & result); }
|
forceinline void to_string_fwd( CodeClass self, String& result ) { return class_to_string_fwd(self, & result); }
|
||||||
|
|
||||||
forceinline void append (CodeParams params, CodeParams param ) { return params_append(params, param); }
|
forceinline void append (CodeParam params, CodeParam param ) { return params_append(params, param); }
|
||||||
forceinline CodeParams get (CodeParams params, s32 idx) { return params_get(params, idx); }
|
forceinline CodeParam get (CodeParam params, s32 idx) { return params_get(params, idx); }
|
||||||
forceinline bool has_entries(CodeParams params ) { return params_has_entries(params); }
|
forceinline bool has_entries(CodeParam params ) { return params_has_entries(params); }
|
||||||
forceinline String to_string (CodeParams params ) { return params_to_string(params); }
|
forceinline String to_string (CodeParam params ) { return params_to_string(params); }
|
||||||
forceinline void to_string (CodeParams params, String& result ) { return params_to_string_ref(params, & result); }
|
forceinline void to_string (CodeParam params, String& result ) { return params_to_string_ref(params, & result); }
|
||||||
|
|
||||||
forceinline CodeParams begin(CodeParams params) { return begin_CodeParams(params); }
|
forceinline CodeParam begin(CodeParam params) { return begin_CodeParam(params); }
|
||||||
forceinline CodeParams end (CodeParams params) { return end_CodeParams(params); }
|
forceinline CodeParam end (CodeParam params) { return end_CodeParam(params); }
|
||||||
forceinline CodeParams next (CodeParams params, CodeParams entry_iter) { return next_CodeParams(params, entry_iter); }
|
forceinline CodeParam next (CodeParam params, CodeParam entry_iter) { return next_CodeParam(params, entry_iter); }
|
||||||
|
|
||||||
forceinline bool append (CodeSpecifiers specifiers, Specifier spec) { return specifiers_append(specifiers, spec); }
|
forceinline bool append (CodeSpecifiers specifiers, Specifier spec) { return specifiers_append(specifiers, spec); }
|
||||||
forceinline s32 has (CodeSpecifiers specifiers, Specifier spec) { return specifiers_has(specifiers, spec); }
|
forceinline s32 has (CodeSpecifiers specifiers, Specifier spec) { return specifiers_has(specifiers, spec); }
|
||||||
|
@ -520,7 +520,7 @@ inline AST_OpCast* CodeOpCast::operator->()
|
|||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CodeParams& CodeParams::operator=( Code other )
|
inline CodeParam& CodeParam::operator=( Code other )
|
||||||
{
|
{
|
||||||
if ( other.ast != nullptr && other->Parent != nullptr )
|
if ( other.ast != nullptr && other->Parent != nullptr )
|
||||||
{
|
{
|
||||||
@ -531,7 +531,7 @@ inline CodeParams& CodeParams::operator=( Code other )
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline CodeParams::operator bool()
|
inline CodeParam::operator bool()
|
||||||
{
|
{
|
||||||
return ast != nullptr;
|
return ast != nullptr;
|
||||||
}
|
}
|
||||||
@ -906,9 +906,9 @@ forceinline Code::operator CodeOpCast() const
|
|||||||
return { (AST_OpCast*)ast };
|
return { (AST_OpCast*)ast };
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline Code::operator CodeParams() const
|
forceinline Code::operator CodeParam() const
|
||||||
{
|
{
|
||||||
return { (AST_Params*)ast };
|
return { (AST_Param*)ast };
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline Code::operator CodePragma() const
|
forceinline Code::operator CodePragma() const
|
||||||
|
@ -53,8 +53,6 @@ constexpr s32 MaxUntypedStrLength = GEN_MAX_UNTYPED_STR_LENGTH;
|
|||||||
constexpr s32 LexAllocator_Size = GEN_LEX_ALLOCATOR_SIZE;
|
constexpr s32 LexAllocator_Size = GEN_LEX_ALLOCATOR_SIZE;
|
||||||
constexpr s32 Builder_StrBufferReserve = GEN_BUILDER_STR_BUFFER_RESERVE;
|
constexpr s32 Builder_StrBufferReserve = GEN_BUILDER_STR_BUFFER_RESERVE;
|
||||||
|
|
||||||
extern StrC enum_underlying_sig;
|
|
||||||
|
|
||||||
extern Code access_public;
|
extern Code access_public;
|
||||||
extern Code access_protected;
|
extern Code access_protected;
|
||||||
extern Code access_private;
|
extern Code access_private;
|
||||||
@ -69,7 +67,7 @@ extern Code fmt_newline;
|
|||||||
|
|
||||||
extern CodePragma pragma_once;
|
extern CodePragma pragma_once;
|
||||||
|
|
||||||
extern CodeParams param_varadic;
|
extern CodeParam param_varadic;
|
||||||
|
|
||||||
extern CodePreprocessCond preprocess_else;
|
extern CodePreprocessCond preprocess_else;
|
||||||
extern CodePreprocessCond preprocess_endif;
|
extern CodePreprocessCond preprocess_endif;
|
||||||
|
@ -178,9 +178,9 @@ void class_add_interface( CodeClass self, CodeTypename type )
|
|||||||
}
|
}
|
||||||
#pragma endregion CodeClass
|
#pragma endregion CodeClass
|
||||||
|
|
||||||
#pragma region CodeParams
|
#pragma region CodeParam
|
||||||
inline
|
inline
|
||||||
void params_append( CodeParams appendee, CodeParams other )
|
void params_append( CodeParam appendee, CodeParam other )
|
||||||
{
|
{
|
||||||
GEN_ASSERT(appendee);
|
GEN_ASSERT(appendee);
|
||||||
GEN_ASSERT(other);
|
GEN_ASSERT(other);
|
||||||
@ -206,37 +206,37 @@ void params_append( CodeParams appendee, CodeParams other )
|
|||||||
self->NumEntries++;
|
self->NumEntries++;
|
||||||
}
|
}
|
||||||
inline
|
inline
|
||||||
CodeParams params_get(CodeParams self, s32 idx )
|
CodeParam params_get(CodeParam self, s32 idx )
|
||||||
{
|
{
|
||||||
GEN_ASSERT(self);
|
GEN_ASSERT(self);
|
||||||
CodeParams param = self;
|
CodeParam param = self;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ( ++ param != nullptr )
|
if ( ++ param != nullptr )
|
||||||
return NullCode;
|
return NullCode;
|
||||||
|
|
||||||
param = cast(CodeParams, cast(Code, param)->Next);
|
param = cast(CodeParam, cast(Code, param)->Next);
|
||||||
}
|
}
|
||||||
while ( --idx );
|
while ( --idx );
|
||||||
|
|
||||||
return param;
|
return param;
|
||||||
}
|
}
|
||||||
forceinline
|
forceinline
|
||||||
bool params_has_entries(CodeParams self)
|
bool params_has_entries(CodeParam self)
|
||||||
{
|
{
|
||||||
GEN_ASSERT(self);
|
GEN_ASSERT(self);
|
||||||
return self->NumEntries > 0;
|
return self->NumEntries > 0;
|
||||||
}
|
}
|
||||||
#if GEN_COMPILER_CPP
|
#if GEN_COMPILER_CPP
|
||||||
forceinline
|
forceinline
|
||||||
CodeParams& CodeParams::operator ++()
|
CodeParam& CodeParam::operator ++()
|
||||||
{
|
{
|
||||||
* this = ast->Next;
|
* this = ast->Next;
|
||||||
return * this;
|
return * this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
forceinline
|
forceinline
|
||||||
CodeParams begin_CodeParams(CodeParams params)
|
CodeParam begin_CodeParam(CodeParam params)
|
||||||
{
|
{
|
||||||
if ( params != nullptr )
|
if ( params != nullptr )
|
||||||
return params;
|
return params;
|
||||||
@ -244,18 +244,18 @@ CodeParams begin_CodeParams(CodeParams params)
|
|||||||
return NullCode;
|
return NullCode;
|
||||||
}
|
}
|
||||||
forceinline
|
forceinline
|
||||||
CodeParams end_CodeParams(CodeParams params)
|
CodeParam end_CodeParam(CodeParam params)
|
||||||
{
|
{
|
||||||
// return { (AST_Params*) rcast( AST*, ast)->Last };
|
// return { (AST_Param*) rcast( AST*, ast)->Last };
|
||||||
return NullCode;
|
return NullCode;
|
||||||
}
|
}
|
||||||
forceinline
|
forceinline
|
||||||
CodeParams next_CodeParams(CodeParams params, CodeParams param_iter)
|
CodeParam next_CodeParam(CodeParam params, CodeParam param_iter)
|
||||||
{
|
{
|
||||||
GEN_ASSERT(param_iter);
|
GEN_ASSERT(param_iter);
|
||||||
return param_iter->Next;
|
return param_iter->Next;
|
||||||
}
|
}
|
||||||
#pragma endregion CodeParams
|
#pragma endregion CodeParam
|
||||||
|
|
||||||
#pragma region CodeSpecifiers
|
#pragma region CodeSpecifiers
|
||||||
inline
|
inline
|
||||||
|
@ -131,7 +131,7 @@ void define_constants()
|
|||||||
pragma_once->Content = pragma_once->Name;
|
pragma_once->Content = pragma_once->Name;
|
||||||
code_set_global((Code)pragma_once);
|
code_set_global((Code)pragma_once);
|
||||||
|
|
||||||
param_varadic = (CodeParams) make_code();
|
param_varadic = (CodeParam) make_code();
|
||||||
param_varadic->Type = CT_Parameters;
|
param_varadic->Type = CT_Parameters;
|
||||||
param_varadic->Name = get_cached_string( txt("...") );
|
param_varadic->Name = get_cached_string( txt("...") );
|
||||||
param_varadic->ValueType = t_empty;
|
param_varadic->ValueType = t_empty;
|
||||||
@ -183,6 +183,7 @@ void define_constants()
|
|||||||
#endif
|
#endif
|
||||||
# undef def_constant_code_type
|
# undef def_constant_code_type
|
||||||
|
|
||||||
|
|
||||||
spec_const = def_specifier( Spec_Const); code_set_global( cast(Code, spec_const ));
|
spec_const = def_specifier( Spec_Const); code_set_global( cast(Code, spec_const ));
|
||||||
spec_consteval = def_specifier( Spec_Consteval); code_set_global( cast(Code, spec_consteval ));;
|
spec_consteval = def_specifier( Spec_Consteval); code_set_global( cast(Code, spec_consteval ));;
|
||||||
spec_constexpr = def_specifier( Spec_Constexpr); code_set_global( cast(Code, spec_constexpr ));;
|
spec_constexpr = def_specifier( Spec_Constexpr); code_set_global( cast(Code, spec_constexpr ));;
|
||||||
@ -211,10 +212,9 @@ void define_constants()
|
|||||||
spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
|
spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
|
||||||
code_set_global(cast(Code, spec_local_persist));
|
code_set_global(cast(Code, spec_local_persist));
|
||||||
|
|
||||||
if (enum_underlying_sig.Len == 0) {
|
# pragma push_macro("enum_underlying")
|
||||||
enum_underlying_sig = txt("enum_underlying(");
|
array_append(PreprocessorDefines, txt("enum_underlying("));
|
||||||
}
|
# pragma pop_macro("enum_underlying")
|
||||||
array_append(PreprocessorDefines, enum_underlying_sig);
|
|
||||||
|
|
||||||
# undef def_constant_spec
|
# undef def_constant_spec
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ struct Opts_def_struct {
|
|||||||
CodeClass def_class( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
CodeClass def_class( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_constructor {
|
struct Opts_def_constructor {
|
||||||
CodeParams params;
|
CodeParam params;
|
||||||
Code initializer_list;
|
Code initializer_list;
|
||||||
Code body;
|
Code body;
|
||||||
};
|
};
|
||||||
@ -86,7 +86,6 @@ struct Opts_def_enum {
|
|||||||
EnumT specifier;
|
EnumT specifier;
|
||||||
CodeAttributes attributes;
|
CodeAttributes attributes;
|
||||||
ModuleFlag mflags;
|
ModuleFlag mflags;
|
||||||
Code type_macro;
|
|
||||||
};
|
};
|
||||||
CodeEnum def_enum( StrC name, Opts_def_enum opts GEN_PARAM_DEFAULT );
|
CodeEnum def_enum( StrC name, Opts_def_enum opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
@ -95,7 +94,7 @@ CodeExtern def_extern_link( StrC name, CodeBody body );
|
|||||||
CodeFriend def_friend ( Code symbol );
|
CodeFriend def_friend ( Code symbol );
|
||||||
|
|
||||||
struct Opts_def_function {
|
struct Opts_def_function {
|
||||||
CodeParams params;
|
CodeParam params;
|
||||||
CodeTypename ret_type;
|
CodeTypename ret_type;
|
||||||
CodeBody body;
|
CodeBody body;
|
||||||
CodeSpecifiers specs;
|
CodeSpecifiers specs;
|
||||||
@ -112,7 +111,7 @@ CodeModule def_module ( StrC name, Opts_def_module opts GEN
|
|||||||
CodeNS def_namespace( StrC name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT );
|
CodeNS def_namespace( StrC name, CodeBody body, Opts_def_namespace opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_operator {
|
struct Opts_def_operator {
|
||||||
CodeParams params;
|
CodeParam params;
|
||||||
CodeTypename ret_type;
|
CodeTypename ret_type;
|
||||||
CodeBody body;
|
CodeBody body;
|
||||||
CodeSpecifiers specifiers;
|
CodeSpecifiers specifiers;
|
||||||
@ -128,7 +127,7 @@ struct Opts_def_operator_cast {
|
|||||||
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
|
CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_param { Code value; };
|
struct Opts_def_param { Code value; };
|
||||||
CodeParams def_param ( CodeTypename type, StrC name, Opts_def_param opts GEN_PARAM_DEFAULT );
|
CodeParam def_param ( CodeTypename type, StrC name, Opts_def_param opts GEN_PARAM_DEFAULT );
|
||||||
CodePragma def_pragma( StrC directive );
|
CodePragma def_pragma( StrC directive );
|
||||||
|
|
||||||
CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC content );
|
CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC content );
|
||||||
@ -138,7 +137,7 @@ CodeSpecifiers def_specifier( Specifier specifier );
|
|||||||
CodeStruct def_struct( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
CodeStruct def_struct( StrC name, Opts_def_struct opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_template { ModuleFlag mflags; };
|
struct Opts_def_template { ModuleFlag mflags; };
|
||||||
CodeTemplate def_template( CodeParams params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT );
|
CodeTemplate def_template( CodeParam params, Code definition, Opts_def_template opts GEN_PARAM_DEFAULT );
|
||||||
|
|
||||||
struct Opts_def_type {
|
struct Opts_def_type {
|
||||||
ETypenameTag type_tag;
|
ETypenameTag type_tag;
|
||||||
@ -197,8 +196,8 @@ CodeBody def_global_body ( s32 num, ... );
|
|||||||
CodeBody def_global_body ( s32 num, Code* codes );
|
CodeBody def_global_body ( s32 num, Code* codes );
|
||||||
CodeBody def_namespace_body ( s32 num, ... );
|
CodeBody def_namespace_body ( s32 num, ... );
|
||||||
CodeBody def_namespace_body ( s32 num, Code* codes );
|
CodeBody def_namespace_body ( s32 num, Code* codes );
|
||||||
CodeParams def_params ( s32 num, ... );
|
CodeParam def_params ( s32 num, ... );
|
||||||
CodeParams def_params ( s32 num, CodeParams* params );
|
CodeParam def_params ( s32 num, CodeParam* params );
|
||||||
CodeSpecifiers def_specifiers ( s32 num, ... );
|
CodeSpecifiers def_specifiers ( s32 num, ... );
|
||||||
CodeSpecifiers def_specifiers ( s32 num, Specifier* specs );
|
CodeSpecifiers def_specifiers ( s32 num, Specifier* specs );
|
||||||
CodeBody def_struct_body ( s32 num, ... );
|
CodeBody def_struct_body ( s32 num, ... );
|
||||||
|
@ -13,7 +13,7 @@ enum OpValidateResult : u32
|
|||||||
};
|
};
|
||||||
|
|
||||||
internal neverinline
|
internal neverinline
|
||||||
OpValidateResult operator__validate( Operator op, CodeParams params_code, CodeTypename ret_type, CodeSpecifiers specifier )
|
OpValidateResult operator__validate( Operator op, CodeParam params_code, CodeTypename ret_type, CodeSpecifiers specifier )
|
||||||
{
|
{
|
||||||
if ( op == Op_Invalid )
|
if ( op == Op_Invalid )
|
||||||
{
|
{
|
||||||
@ -497,7 +497,7 @@ CodeComment def_comment( StrC content )
|
|||||||
|
|
||||||
CodeConstructor def_constructor( Opts_def_constructor p )
|
CodeConstructor def_constructor( Opts_def_constructor p )
|
||||||
{
|
{
|
||||||
CodeParams params = p.params;
|
CodeParam params = p.params;
|
||||||
Code initializer_list = p.initializer_list;
|
Code initializer_list = p.initializer_list;
|
||||||
Code body = p.body;
|
Code body = p.body;
|
||||||
|
|
||||||
@ -700,7 +700,6 @@ CodeEnum def_enum( StrC name, Opts_def_enum p )
|
|||||||
EnumT specifier = p.specifier;
|
EnumT specifier = p.specifier;
|
||||||
CodeAttributes attributes = p.attributes;
|
CodeAttributes attributes = p.attributes;
|
||||||
ModuleFlag mflags = p.mflags;
|
ModuleFlag mflags = p.mflags;
|
||||||
Code type_macro = p.type_macro;
|
|
||||||
|
|
||||||
name_check( def_enum, name );
|
name_check( def_enum, name );
|
||||||
|
|
||||||
@ -752,10 +751,6 @@ CodeEnum def_enum( StrC name, Opts_def_enum p )
|
|||||||
{
|
{
|
||||||
result->UnderlyingType = type;
|
result->UnderlyingType = type;
|
||||||
}
|
}
|
||||||
else if ( type_macro )
|
|
||||||
{
|
|
||||||
result->UnderlyingTypeMacro = type_macro;
|
|
||||||
}
|
|
||||||
else if ( result->Type != CT_Enum_Class_Fwd && result->Type != CT_Enum_Fwd )
|
else if ( result->Type != CT_Enum_Class_Fwd && result->Type != CT_Enum_Fwd )
|
||||||
{
|
{
|
||||||
log_failure( "gen::def_enum: enum forward declaration must have an underlying type" );
|
log_failure( "gen::def_enum: enum forward declaration must have an underlying type" );
|
||||||
@ -834,7 +829,7 @@ CodeFriend def_friend( Code declaration )
|
|||||||
|
|
||||||
CodeFn def_function( StrC name, Opts_def_function p )
|
CodeFn def_function( StrC name, Opts_def_function p )
|
||||||
{
|
{
|
||||||
CodeParams params = p.params;
|
CodeParam params = p.params;
|
||||||
CodeTypename ret_type = p.ret_type;
|
CodeTypename ret_type = p.ret_type;
|
||||||
CodeBody body = p.body;
|
CodeBody body = p.body;
|
||||||
CodeSpecifiers specifiers = p.specs;
|
CodeSpecifiers specifiers = p.specs;
|
||||||
@ -974,7 +969,7 @@ CodeNS def_namespace( StrC name, CodeBody body, Opts_def_namespace p )
|
|||||||
|
|
||||||
CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator p )
|
CodeOperator def_operator( Operator op, StrC nspace, Opts_def_operator p )
|
||||||
{
|
{
|
||||||
CodeParams params_code = p.params;
|
CodeParam params_code = p.params;
|
||||||
CodeTypename ret_type = p.ret_type;
|
CodeTypename ret_type = p.ret_type;
|
||||||
CodeBody body = p.body;
|
CodeBody body = p.body;
|
||||||
CodeSpecifiers specifiers = p.specifiers;
|
CodeSpecifiers specifiers = p.specifiers;
|
||||||
@ -1098,7 +1093,7 @@ CodeOpCast def_operator_cast( CodeTypename type, Opts_def_operator_cast p )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParams def_param( CodeTypename type, StrC name, Opts_def_param p )
|
CodeParam def_param( CodeTypename type, StrC name, Opts_def_param p )
|
||||||
{
|
{
|
||||||
name_check( def_param, name );
|
name_check( def_param, name );
|
||||||
null_check( def_param, type );
|
null_check( def_param, type );
|
||||||
@ -1115,8 +1110,8 @@ CodeParams def_param( CodeTypename type, StrC name, Opts_def_param p )
|
|||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParams
|
CodeParam
|
||||||
result = (CodeParams) make_code();
|
result = (CodeParam) make_code();
|
||||||
result->Type = CT_Parameters;
|
result->Type = CT_Parameters;
|
||||||
result->Name = get_cached_string( name );
|
result->Name = get_cached_string( name );
|
||||||
|
|
||||||
@ -1252,7 +1247,7 @@ CodeStruct def_struct( StrC name, Opts_def_struct p )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeTemplate def_template( CodeParams params, Code declaration, Opts_def_template p )
|
CodeTemplate def_template( CodeParam params, Code declaration, Opts_def_template p )
|
||||||
{
|
{
|
||||||
null_check( def_template, declaration );
|
null_check( def_template, declaration );
|
||||||
|
|
||||||
@ -2069,7 +2064,7 @@ CodeBody def_namespace_body( s32 num, Code* codes )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParams def_params( s32 num, ... )
|
CodeParam def_params( s32 num, ... )
|
||||||
{
|
{
|
||||||
def_body_start( def_params );
|
def_body_start( def_params );
|
||||||
|
|
||||||
@ -2077,7 +2072,7 @@ CodeParams def_params( s32 num, ... )
|
|||||||
va_start(va, num);
|
va_start(va, num);
|
||||||
|
|
||||||
Code_POD pod = va_arg(va, Code_POD);
|
Code_POD pod = va_arg(va, Code_POD);
|
||||||
CodeParams param = pcast( CodeParams, pod );
|
CodeParam param = pcast( CodeParam, pod );
|
||||||
|
|
||||||
null_check( def_params, param );
|
null_check( def_params, param );
|
||||||
|
|
||||||
@ -2087,12 +2082,12 @@ CodeParams def_params( s32 num, ... )
|
|||||||
return InvalidCode;
|
return InvalidCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParams result = (CodeParams) code_duplicate(param);
|
CodeParam result = (CodeParam) code_duplicate(param);
|
||||||
|
|
||||||
while ( -- num )
|
while ( -- num )
|
||||||
{
|
{
|
||||||
pod = va_arg(va, Code_POD);
|
pod = va_arg(va, Code_POD);
|
||||||
param = pcast( CodeParams, pod );
|
param = pcast( CodeParam, pod );
|
||||||
|
|
||||||
if ( param->Type != CT_Parameters )
|
if ( param->Type != CT_Parameters )
|
||||||
{
|
{
|
||||||
@ -2107,7 +2102,7 @@ CodeParams def_params( s32 num, ... )
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParams def_params( s32 num, CodeParams* codes )
|
CodeParam def_params( s32 num, CodeParam* codes )
|
||||||
{
|
{
|
||||||
def_body_code_array_start( def_params );
|
def_body_code_array_start( def_params );
|
||||||
|
|
||||||
@ -2124,11 +2119,11 @@ CodeParams def_params( s32 num, CodeParams* codes )
|
|||||||
return InvalidCode; \
|
return InvalidCode; \
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParams current = (CodeParams)code_duplicate(* codes);
|
CodeParam current = (CodeParam)code_duplicate(* codes);
|
||||||
check_current(current);
|
check_current(current);
|
||||||
|
|
||||||
CodeParams
|
CodeParam
|
||||||
result = (CodeParams) make_code();
|
result = (CodeParam) make_code();
|
||||||
result->Name = current->Name;
|
result->Name = current->Name;
|
||||||
result->Type = current->Type;
|
result->Type = current->Type;
|
||||||
result->ValueType = current->ValueType;
|
result->ValueType = current->ValueType;
|
||||||
|
@ -663,10 +663,6 @@ TokArray lex( StrC content )
|
|||||||
|
|
||||||
switch ( current )
|
switch ( current )
|
||||||
{
|
{
|
||||||
if (array_back(Lexer_Tokens)->Length > 100 ) {
|
|
||||||
__debugbreak();
|
|
||||||
}
|
|
||||||
|
|
||||||
case '#':
|
case '#':
|
||||||
{
|
{
|
||||||
s32 result = lex_preprocessor_directive( ctx );
|
s32 result = lex_preprocessor_directive( ctx );
|
||||||
|
@ -225,7 +225,7 @@ internal CodeInclude parse_include ();
|
|||||||
internal CodeOperator parse_operator_after_ret_type ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename ret_type );
|
internal CodeOperator parse_operator_after_ret_type ( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeTypename ret_type );
|
||||||
internal Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers );
|
internal Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers );
|
||||||
internal CodePragma parse_pragma ();
|
internal CodePragma parse_pragma ();
|
||||||
internal CodeParams parse_params ( bool use_template_capture );
|
internal CodeParam parse_params ( bool use_template_capture );
|
||||||
internal CodePreprocessCond parse_preprocess_cond ();
|
internal CodePreprocessCond parse_preprocess_cond ();
|
||||||
internal Code parse_simple_preprocess ( TokType which, bool dont_consume_braces );
|
internal Code parse_simple_preprocess ( TokType which, bool dont_consume_braces );
|
||||||
internal Code parse_static_assert ();
|
internal Code parse_static_assert ();
|
||||||
@ -797,10 +797,11 @@ Code parse_class_struct( TokType which, bool inplace_def )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( which == Tok_Decl_Class )
|
if ( which == Tok_Decl_Class )
|
||||||
result = cast(Code, def_class( tok_to_str(name), def_assign( body, parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), mflags ) ));
|
result = cast(Code, def_class( tok_to_str(name), def_assign( body, parent, access, attributes, nullptr, 0, mflags ) ));
|
||||||
|
|
||||||
else
|
else
|
||||||
result = cast(Code, def_struct( tok_to_str(name), def_assign( body, (CodeTypename)parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), mflags ) ));
|
result = cast(Code, def_struct( tok_to_str(name), def_assign( body, (CodeTypename)parent, access, attributes, nullptr, 0, mflags ) ));
|
||||||
|
|
||||||
|
|
||||||
if ( inline_cmt )
|
if ( inline_cmt )
|
||||||
result->InlineCmt = cast(Code, inline_cmt);
|
result->InlineCmt = cast(Code, inline_cmt);
|
||||||
@ -1478,7 +1479,7 @@ CodeFn parse_function_after_name(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
push_scope();
|
push_scope();
|
||||||
CodeParams params = parse_params(parser_use_parenthesis);
|
CodeParam params = parse_params(parser_use_parenthesis);
|
||||||
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Parameters> )
|
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Parameters> )
|
||||||
|
|
||||||
// TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers.
|
// TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers.
|
||||||
@ -2515,7 +2516,7 @@ CodeOperator parse_operator_after_ret_type(
|
|||||||
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op>
|
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op>
|
||||||
|
|
||||||
// Parse Params
|
// Parse Params
|
||||||
CodeParams params = parse_params(parser_use_parenthesis);
|
CodeParam params = parse_params(parser_use_parenthesis);
|
||||||
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> )
|
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> )
|
||||||
|
|
||||||
if ( params == nullptr && op == Op_Multiply )
|
if ( params == nullptr && op == Op_Multiply )
|
||||||
@ -2693,7 +2694,7 @@ CodePragma parse_pragma()
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal inline
|
internal inline
|
||||||
CodeParams parse_params( bool use_template_capture )
|
CodeParam parse_params( bool use_template_capture )
|
||||||
{
|
{
|
||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
@ -2822,7 +2823,7 @@ CodeParams parse_params( bool use_template_capture )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParams result = ( CodeParams )make_code();
|
CodeParam result = ( CodeParam )make_code();
|
||||||
result->Type = CT_Parameters;
|
result->Type = CT_Parameters;
|
||||||
|
|
||||||
result->Macro = macro;
|
result->Macro = macro;
|
||||||
@ -2939,7 +2940,7 @@ CodeParams parse_params( bool use_template_capture )
|
|||||||
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, ..
|
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> = <Expression>, ..
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeParams param = ( CodeParams )make_code();
|
CodeParam param = ( CodeParam )make_code();
|
||||||
param->Type = CT_Parameters;
|
param->Type = CT_Parameters;
|
||||||
|
|
||||||
param->Macro = macro;
|
param->Macro = macro;
|
||||||
@ -3371,7 +3372,7 @@ CodeVar parse_variable_after_name(
|
|||||||
result->NextVar->Parent = cast(Code, result);
|
result->NextVar->Parent = cast(Code, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
result->VarParenthesizedInit = using_constructor_initializer;
|
result->VarConstructorInit = using_constructor_initializer;
|
||||||
|
|
||||||
parser_pop(& Context);
|
parser_pop(& Context);
|
||||||
return result;
|
return result;
|
||||||
@ -3475,7 +3476,7 @@ CodeConstructor parser_parse_constructor( CodeSpecifiers specifiers )
|
|||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
Token identifier = parse_identifier(nullptr);
|
Token identifier = parse_identifier(nullptr);
|
||||||
CodeParams params = parse_params(parser_not_from_template);
|
CodeParam params = parse_params(parser_not_from_template);
|
||||||
// <Name> ( <Parameters> )
|
// <Name> ( <Parameters> )
|
||||||
|
|
||||||
Code initializer_list = NullCode;
|
Code initializer_list = NullCode;
|
||||||
@ -3730,7 +3731,8 @@ CodeEnum parser_parse_enum( bool inplace_def )
|
|||||||
else if ( currtok.Type == Tok_Preprocess_Macro )
|
else if ( currtok.Type == Tok_Preprocess_Macro )
|
||||||
{
|
{
|
||||||
// We'll support the enum_underlying macro
|
// We'll support the enum_underlying macro
|
||||||
if ( strc_contains( tok_to_str(currtok), enum_underlying_sig) )
|
StrC sig = txt("enum_underlying(");
|
||||||
|
if ( strc_contains( tok_to_str(currtok), sig) )
|
||||||
{
|
{
|
||||||
use_macro_underlying = true;
|
use_macro_underlying = true;
|
||||||
underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro, parser_dont_consume_braces );
|
underlying_macro = parse_simple_preprocess( Tok_Preprocess_Macro, parser_dont_consume_braces );
|
||||||
@ -4038,7 +4040,7 @@ CodeFriend parser_parse_friend()
|
|||||||
function = parse_function_after_name( ModuleFlag_None, NullCode, specifiers, type, name );
|
function = parse_function_after_name( ModuleFlag_None, NullCode, specifiers, type, name );
|
||||||
|
|
||||||
// Parameter list
|
// Parameter list
|
||||||
// CodeParams params = parse_params();
|
// CodeParam params = parse_params();
|
||||||
// friend <ReturnType> <Name> ( <Parameters> )
|
// friend <ReturnType> <Name> ( <Parameters> )
|
||||||
|
|
||||||
// function = make_code();
|
// function = make_code();
|
||||||
@ -4408,7 +4410,7 @@ CodeTemplate parser_parse_template()
|
|||||||
eat( Tok_Decl_Template );
|
eat( Tok_Decl_Template );
|
||||||
// <export> template
|
// <export> template
|
||||||
|
|
||||||
CodeParams params = parse_params( UseTemplateCapture );
|
CodeParam params = parse_params( UseTemplateCapture );
|
||||||
if ( cast(Code, params) == Code_Invalid )
|
if ( cast(Code, params) == Code_Invalid )
|
||||||
{
|
{
|
||||||
parser_pop(& Context);
|
parser_pop(& Context);
|
||||||
@ -4773,10 +4775,10 @@ else if ( currtok.Type == Tok_DeclType )
|
|||||||
|
|
||||||
// For function type signatures
|
// For function type signatures
|
||||||
CodeTypename return_type = NullCode;
|
CodeTypename return_type = NullCode;
|
||||||
CodeParams params = NullCode;
|
CodeParam params = NullCode;
|
||||||
|
|
||||||
#ifdef GEN_USE_NEW_TYPENAME_PARSING
|
#ifdef GEN_USE_NEW_TYPENAME_PARSING
|
||||||
CodeParams params_nested = NullCode;
|
CodeParam params_nested = NullCode;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool is_function_typename = false;
|
bool is_function_typename = false;
|
||||||
@ -5581,12 +5583,6 @@ CodeVar parser_parse_variable()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal
|
|
||||||
CodeTypename parser_parse_type_alt( bool from_template, bool* typedef_is_functon )
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GEN_NS_PARSER_END
|
GEN_NS_PARSER_END
|
||||||
|
|
||||||
#ifdef CHECK_WAS_DEFINED
|
#ifdef CHECK_WAS_DEFINED
|
||||||
|
@ -28,8 +28,6 @@ global AllocatorInfo Allocator_TypeTable = {0};
|
|||||||
|
|
||||||
#pragma region Constants
|
#pragma region Constants
|
||||||
|
|
||||||
global StrC enum_underlying_sig;
|
|
||||||
|
|
||||||
global Code access_public;
|
global Code access_public;
|
||||||
global Code access_protected;
|
global Code access_protected;
|
||||||
global Code access_private;
|
global Code access_private;
|
||||||
@ -42,7 +40,7 @@ global Code module_private_fragment;
|
|||||||
|
|
||||||
global Code fmt_newline;
|
global Code fmt_newline;
|
||||||
|
|
||||||
global CodeParams param_varadic;
|
global CodeParam param_varadic;
|
||||||
|
|
||||||
global CodePragma pragma_once;
|
global CodePragma pragma_once;
|
||||||
|
|
||||||
|
@ -284,4 +284,121 @@
|
|||||||
# define GEN_OPITMIZE_MAPPINGS_END
|
# define GEN_OPITMIZE_MAPPINGS_END
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if GEN_COMPILER_C
|
||||||
|
// ____ _ ______ _ _ ____ _ __ _
|
||||||
|
// / ___} (_) | ____} | | (_) / __ \ | | | |(_)
|
||||||
|
// | | ___ ___ _ __ ___ _ __ _ ___ | |__ _ _ _ __ ___| |_ _ ___ _ __ | | | |_ _____ _ __ | | ___ __ _ __| | _ _ __ __ _
|
||||||
|
// | |{__ |/ _ \ '_ \ / _ \ '__} |/ __| | __} | | | '_ \ / __} __} |/ _ \| '_ \ | | | \ \ / / _ \ '_ \| |/ _ \ / _` |/ _` || | '_ \ / _` |
|
||||||
|
// | |__j | __/ | | | __/ | | | (__ | | | |_| | | | | (__| l_| | (_) | | | | | l__| |\ V / __/ | | | | (_) | (_| | (_| || | | | | (_| |
|
||||||
|
// \____/ \___}_l l_l\___}_l l_l\___| l_l \__,_l_l l_l\___}\__}_l\___/l_l l_l \____/ \_/ \___}_l l_l_l\___/ \__,_l\__,_l|_|_| |_|\__, |
|
||||||
|
// This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in: __| |
|
||||||
|
// https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md {___/
|
||||||
|
// Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unobfuscated as possible.
|
||||||
|
|
||||||
|
#define GEN_COMMA_OPERATOR , // The comma operator is used by preprocessor macros to delimit arguments, so we have to represent it via a macro to prevent parsing incorrectly.
|
||||||
|
|
||||||
|
// Helper macros for argument selection
|
||||||
|
#define GEN_SELECT_ARG_1( _1, ... ) _1 // <-- Of all th args passed pick _1.
|
||||||
|
#define GEN_SELECT_ARG_2( _1, _2, ... ) _2 // <-- Of all the args passed pick _2.
|
||||||
|
#define GEN_SELECT_ARG_3( _1, _2, _3, ... ) _3 // etc..
|
||||||
|
|
||||||
|
#define GEN_GENERIC_SEL_ENTRY_TYPE GEN_SELECT_ARG_1 // Use the arg expansion macro to select arg 1 which should have the type.
|
||||||
|
#define GEN_GENERIC_SEL_ENTRY_FUNCTION GEN_SELECT_ARG_2 // Use the arg expansion macro to select arg 2 which should have the function.
|
||||||
|
#define GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER GEN_SELECT_ARG_3 // Use the arg expansion macro to select arg 3 which should have the comma delimiter ','.
|
||||||
|
|
||||||
|
#define GEN_RESOLVED_FUNCTION_CALL // Just used to indicate where the call "occurs"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( macro ) includes a _Generic slot only if the specified macro is defined (as type, function_name).
|
||||||
|
// It takes advantage of the fact that if the macro is defined, then the expanded text will contain a comma.
|
||||||
|
// Expands to ',' if it can find (type): (function) <comma_operator: ',' >
|
||||||
|
// Where GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER is specifically looking for that <comma> ,
|
||||||
|
#define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ) GEN_COMMA_OPERATOR, , )
|
||||||
|
// ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma
|
||||||
|
// The slot won't exist if that comma is not found. |
|
||||||
|
|
||||||
|
// For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
|
||||||
|
typedef struct GENCPP_NO_RESOLVED_GENERIC_SELECTION GENCPP_NO_RESOLVED_GENERIC_SELECTION;
|
||||||
|
struct GENCPP_NO_RESOLVED_GENERIC_SELECTION {
|
||||||
|
void* _THE_VOID_SLOT_;
|
||||||
|
};
|
||||||
|
GENCPP_NO_RESOLVED_GENERIC_SELECTION const gen_generic_selection_fail = {0};
|
||||||
|
// Which will provide the message: error: called object type 'struct NO_RESOLVED_GENERIC_SELECTION' is not a function or function pointer
|
||||||
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Below are generated on demand for an overlaod depdendent on a type:
|
||||||
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic( \
|
||||||
|
(selector_arg), /* Select Via Expression*/ \
|
||||||
|
/* Extendibility slots: */ \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
||||||
|
default: gen_generic_selection_fail \
|
||||||
|
) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
|
||||||
|
// ----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Then each definiton of a function has an associated define:
|
||||||
|
#// #define GENERIC_SLOT_<#>_<generic identifier> <typename>, <function_to_resolve>
|
||||||
|
|
||||||
|
// Then somehwere later on
|
||||||
|
// <etc> <return_type> <function_id> ( <arguments> ) { <implementation> }
|
||||||
|
|
||||||
|
// Concrete example:
|
||||||
|
|
||||||
|
// To add support for long:
|
||||||
|
#define GENERIC_SLOT_1_gen_example_hash long, gen_example_hash__P_long
|
||||||
|
size_t gen_example_hash__P_long( long val ) { return val * 2654435761ull; }
|
||||||
|
|
||||||
|
// To add support for long long:
|
||||||
|
#define GENERIC_SLOT_2_gen_example_hash long long, gen_example_hash__P_long_long
|
||||||
|
size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
|
||||||
|
|
||||||
|
// If using an Editor with support for syntax hightlighting macros: HASH__ARGS_SIG_1 and HASH_ARGS_SIG_2 should show color highlighting indicating the slot is enabled,
|
||||||
|
// or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
|
||||||
|
#define gen_hash_example( function_arguments ) _Generic( \
|
||||||
|
(function_arguments), /* Select Via Expression*/ \
|
||||||
|
/* Extendibility slots: */ \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_1 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_2 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_3 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_4 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_5 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_6 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_7 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_8 ) \
|
||||||
|
default: gen_generic_selection_fail \
|
||||||
|
) GEN_RESOLVED_FUNCTION_CALL( function_arguments )
|
||||||
|
|
||||||
|
// Additional Variations:
|
||||||
|
|
||||||
|
// If the function takes more than one argument the following is used:
|
||||||
|
#define GEN_FUNCTION_GENERIC_EXAMPLE_VARADIC( selector_arg, ... ) _Generic( \
|
||||||
|
(selector_arg), \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 ) \
|
||||||
|
/* ... */ \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N ) \
|
||||||
|
default: gen_generic_selection_fail \
|
||||||
|
) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ )
|
||||||
|
|
||||||
|
// If the function does not take the arugment as a parameter:
|
||||||
|
#define GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( selector_arg ) _Generic( \
|
||||||
|
( GEN_TYPE_TO_EXP(selector_arg) ), \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 ) \
|
||||||
|
/* ... */ \
|
||||||
|
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N ) \
|
||||||
|
default: gen_generic_selection_fail \
|
||||||
|
) GEN_RESOLVED_FUNCTION_CALL()
|
||||||
|
|
||||||
|
// Used to keep the _Generic keyword happy as bare types are not considered "expressions"
|
||||||
|
#define GEN_TYPE_TO_EXP(type) (* (type*)NULL)
|
||||||
|
// Instead of using this macro, you'll see it directly expanded by the code generation.
|
||||||
|
|
||||||
|
// typedef void* GEN_GenericExampleType;
|
||||||
|
// GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( GEN_GenericExampleType );
|
||||||
|
|
||||||
|
// END OF ------------------------ _Generic function overloading ----------------------------------------- END OF
|
||||||
|
#endif
|
||||||
|
|
||||||
#pragma endregion Macros
|
#pragma endregion Macros
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
GEN_NS_BEGIN
|
GEN_NS_BEGIN
|
||||||
|
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#include "components/gen/ecodetypes.hpp"
|
#include "components/gen/ecode.hpp"
|
||||||
#include "components/gen/eoperator.hpp"
|
#include "components/gen/eoperator.hpp"
|
||||||
#include "components/gen/especifier.hpp"
|
#include "components/gen/especifier.hpp"
|
||||||
|
|
||||||
|
@ -536,7 +536,7 @@ CodeBody gen_ast_inlines()
|
|||||||
CodeBody impl_code_ns = parse_global_body( token_fmt( "typename", StrC name(CodeNS), code_impl_tmpl ));
|
CodeBody impl_code_ns = parse_global_body( token_fmt( "typename", StrC name(CodeNS), code_impl_tmpl ));
|
||||||
CodeBody impl_code_op = parse_global_body( token_fmt( "typename", StrC name(CodeOperator), code_impl_tmpl ));
|
CodeBody impl_code_op = parse_global_body( token_fmt( "typename", StrC name(CodeOperator), code_impl_tmpl ));
|
||||||
CodeBody impl_code_opcast = parse_global_body( token_fmt( "typename", StrC name(CodeOpCast), code_impl_tmpl ));
|
CodeBody impl_code_opcast = parse_global_body( token_fmt( "typename", StrC name(CodeOpCast), code_impl_tmpl ));
|
||||||
CodeBody impl_code_params = parse_global_body( token_fmt( "typename", StrC name(CodeParams), code_impl_tmpl ));
|
CodeBody impl_code_param = parse_global_body( token_fmt( "typename", StrC name(CodeParam), code_impl_tmpl ));
|
||||||
CodeBody impl_code_pragma = parse_global_body( token_fmt( "typename", StrC name(CodePragma), code_impl_tmpl ));
|
CodeBody impl_code_pragma = parse_global_body( token_fmt( "typename", StrC name(CodePragma), code_impl_tmpl ));
|
||||||
CodeBody impl_code_precond = parse_global_body( token_fmt( "typename", StrC name(CodePreprocessCond), code_impl_tmpl ));
|
CodeBody impl_code_precond = parse_global_body( token_fmt( "typename", StrC name(CodePreprocessCond), code_impl_tmpl ));
|
||||||
CodeBody impl_code_specs = parse_global_body( token_fmt( "typename", StrC name(CodeSpecifiers), code_impl_tmpl ));
|
CodeBody impl_code_specs = parse_global_body( token_fmt( "typename", StrC name(CodeSpecifiers), code_impl_tmpl ));
|
||||||
@ -599,7 +599,7 @@ CodeBody gen_ast_inlines()
|
|||||||
CodeBody impl_cast_ns = parse_global_body( token_fmt( "typename", StrC name(NS), cast_tmpl ));
|
CodeBody impl_cast_ns = parse_global_body( token_fmt( "typename", StrC name(NS), cast_tmpl ));
|
||||||
CodeBody impl_cast_op = parse_global_body( token_fmt( "typename", StrC name(Operator), cast_tmpl ));
|
CodeBody impl_cast_op = parse_global_body( token_fmt( "typename", StrC name(Operator), cast_tmpl ));
|
||||||
CodeBody impl_cast_opcast = parse_global_body( token_fmt( "typename", StrC name(OpCast), cast_tmpl ));
|
CodeBody impl_cast_opcast = parse_global_body( token_fmt( "typename", StrC name(OpCast), cast_tmpl ));
|
||||||
CodeBody impl_cast_params = parse_global_body( token_fmt( "typename", StrC name(Params), cast_tmpl ));
|
CodeBody impl_cast_param = parse_global_body( token_fmt( "typename", StrC name(Param), cast_tmpl ));
|
||||||
CodeBody impl_cast_pragma = parse_global_body( token_fmt( "typename", StrC name(Pragma), cast_tmpl ));
|
CodeBody impl_cast_pragma = parse_global_body( token_fmt( "typename", StrC name(Pragma), cast_tmpl ));
|
||||||
CodeBody impl_cast_precond = parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), cast_tmpl ));
|
CodeBody impl_cast_precond = parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), cast_tmpl ));
|
||||||
CodeBody impl_cast_specs = parse_global_body( token_fmt( "typename", StrC name(Specifiers), cast_tmpl ));
|
CodeBody impl_cast_specs = parse_global_body( token_fmt( "typename", StrC name(Specifiers), cast_tmpl ));
|
||||||
@ -632,7 +632,7 @@ CodeBody gen_ast_inlines()
|
|||||||
impl_code_ns,
|
impl_code_ns,
|
||||||
impl_code_op,
|
impl_code_op,
|
||||||
impl_code_opcast,
|
impl_code_opcast,
|
||||||
impl_code_params,
|
impl_code_param,
|
||||||
impl_code_pragma,
|
impl_code_pragma,
|
||||||
impl_code_precond,
|
impl_code_precond,
|
||||||
impl_code_specs,
|
impl_code_specs,
|
||||||
@ -666,7 +666,7 @@ CodeBody gen_ast_inlines()
|
|||||||
impl_cast_ns,
|
impl_cast_ns,
|
||||||
impl_cast_op,
|
impl_cast_op,
|
||||||
impl_cast_opcast,
|
impl_cast_opcast,
|
||||||
impl_cast_params,
|
impl_cast_param,
|
||||||
impl_cast_pragma,
|
impl_cast_pragma,
|
||||||
impl_cast_precond,
|
impl_cast_precond,
|
||||||
impl_cast_specs,
|
impl_cast_specs,
|
||||||
|
@ -39,8 +39,6 @@ The full definitions of all asts are within:
|
|||||||
* [`ast_types.hpp`](../base/components/ast_types.hpp)
|
* [`ast_types.hpp`](../base/components/ast_types.hpp)
|
||||||
* [`code_types.hpp`](../base/components/ast_types.hpp)
|
* [`code_types.hpp`](../base/components/ast_types.hpp)
|
||||||
|
|
||||||
The C/C++ interface procedures are located with `ast.hpp` (for the Code type), and `code_types.hpp` for all others.
|
|
||||||
|
|
||||||
## Serialization
|
## Serialization
|
||||||
|
|
||||||
All code types can either serialize using a function of the pattern:
|
All code types can either serialize using a function of the pattern:
|
||||||
@ -54,5 +52,7 @@ String <prefix>_to_string(Code code);
|
|||||||
Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator.
|
Where the first generates strings allocated using Allocator_StringArena and the other appends an existing strings with their backed allocator.
|
||||||
|
|
||||||
Serialization of for the AST is defined for `Code` in [`ast.chpp`](../base/components/ast.cpp) with `code_to_string_ptr` & `code_to_string`.
|
Serialization of for the AST is defined for `Code` in [`ast.chpp`](../base/components/ast.cpp) with `code_to_string_ptr` & `code_to_string`.
|
||||||
|
|
||||||
Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).
|
Serializtion for the rest of the code types is within [`code_serialization.cpp`](../base/components/code_serialization.cpp).
|
||||||
Gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after serializing.
|
|
||||||
|
gencpp's serialization does not provide coherent formatting of the code. The user should use a formatter after.
|
||||||
|
@ -25,11 +25,11 @@ These are containers representing a scope body of a definition that can be of th
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Name;
|
|
||||||
Code Front;
|
Code Front;
|
||||||
Code Back;
|
Code Back;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
```
|
```
|
||||||
@ -37,15 +37,14 @@ s32 NumEntries;
|
|||||||
The `Front` member represents the start of the link list and `Back` the end.
|
The `Front` member represents the start of the link list and `Back` the end.
|
||||||
NumEntries is the number of entries in the body.
|
NumEntries is the number of entries in the body.
|
||||||
|
|
||||||
Parent should have a compatible CodeType type for the type of defintion used.
|
Parent should have a compatible ECode type for the type of defintion used.
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
|
|
||||||
Will output only the entries, the braces are handled by the parent.
|
Will output only the entries, the braces are handled by the parent.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
<Front>
|
<Front>...
|
||||||
...
|
|
||||||
<Back>
|
<Back>
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -57,11 +56,11 @@ Fields:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StringCached Content;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -81,11 +80,11 @@ Fields:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StringCached Content;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -109,11 +108,11 @@ CodeComment InlineCmt; // Only supported by forward declarations
|
|||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeType ParentType;
|
CodeType ParentType;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
CodeType Prev; // Used to store references to interfaces
|
||||||
CodeType Prev;
|
CodeType Next; // Used to store references to interfaces
|
||||||
CodeType Next;
|
parser::Token* Tok;
|
||||||
Token* Tok;
|
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
AccessSpec ParentAccess;
|
AccessSpec ParentAccess;
|
||||||
@ -132,7 +131,7 @@ Serialization:
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
You'll notice that only one parent type is supported only with parent access. This library only supports single inheritance, the rest are assumed to be interfaces and are given public acess specifiers.
|
You'll notice that only one parent type is supported only with parent access. This library only supports single inheritance, the rest must be done through interfaces.
|
||||||
|
|
||||||
## Constructor
|
## Constructor
|
||||||
|
|
||||||
@ -141,13 +140,13 @@ Fields:
|
|||||||
```cpp
|
```cpp
|
||||||
CodeComment InlineCmt; // Only supported by forward declarations
|
CodeComment InlineCmt; // Only supported by forward declarations
|
||||||
Code InitializerList;
|
Code InitializerList;
|
||||||
CodeParams Params;
|
CodeParam Params;
|
||||||
Code Body;
|
Code Body;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -179,11 +178,11 @@ Fields:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StringCached Content;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -201,11 +200,11 @@ Fields:
|
|||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
Code Body;
|
Code Body;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -236,28 +235,24 @@ Fields:
|
|||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeType UnderlyingType;
|
CodeType UnderlyingType;
|
||||||
Code UnderlyingTypeMacro;
|
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
StringCached Name;
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
|
|
||||||
UnderlyingTypeMacro is a macro the library natively supports: `enum_underlying(type)` that is meant to behave as a wrapper for underlying type assignment.
|
|
||||||
The `enum_underlying_sig` is a `StrC` global var that can be set which will be defined within `PreprocessorDefines` and used in `parser_parse_enum` to identify a valid macro.
|
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// Enum_Fwd
|
// Enum_Fwd
|
||||||
<ModuleFlags> enum class <Name> : <UnderlyingType> or <UnderlyingTypeMacro> ; <InlineCmt>
|
<ModuleFlags> enum class <Name> : <UnderlyingType>; <InlineCmt>
|
||||||
|
|
||||||
// Enum
|
// Enum
|
||||||
<ModuleFlags> <enum or enum class> <Name> : <UnderlyingType> or <UnderlyingTypeMacro>
|
<ModuleFlags> <enum or enum class> <Name> : <UnderlyingType>
|
||||||
{
|
{
|
||||||
<Body>
|
<Body>
|
||||||
};
|
};
|
||||||
@ -272,11 +267,11 @@ Fields:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StringCached Content;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -292,11 +287,11 @@ Fields:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -315,11 +310,11 @@ Fields:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StringCached Content;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -338,11 +333,11 @@ Fields:
|
|||||||
```cpp
|
```cpp
|
||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
Code Declaration;
|
Code Declaration;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -361,13 +356,13 @@ CodeComment InlineCmt;
|
|||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeType ReturnType;
|
CodeType ReturnType;
|
||||||
CodeParams Params;
|
CodeParam Params;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
@ -390,11 +385,11 @@ Serialization:
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
@ -411,11 +406,11 @@ Fields:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
@ -429,7 +424,7 @@ Serialization:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Operator Overload (Operator)
|
## Operator Overload
|
||||||
|
|
||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
@ -438,13 +433,13 @@ CodeComment InlineCmt;
|
|||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeType ReturnType;
|
CodeType ReturnType;
|
||||||
CodeParams Params;
|
CodeParam Params;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
OperatorT Op;
|
OperatorT Op;
|
||||||
@ -463,7 +458,7 @@ Serialization:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Operator Cast Overload ( User-Defined Type Conversion, OpCast )
|
## Operator Cast Overload ( User-Defined Type Conversion )
|
||||||
|
|
||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
@ -472,11 +467,11 @@ CodeComment InlineCmt;
|
|||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeType ValueType;
|
CodeType ValueType;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -493,7 +488,7 @@ Serialization:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters (AST_Params)
|
## Parameters (AST_Param)
|
||||||
|
|
||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
@ -501,12 +496,11 @@ Fields:
|
|||||||
CodeType ValueType;
|
CodeType ValueType;
|
||||||
Code Macro;
|
Code Macro;
|
||||||
Code Value;
|
Code Value;
|
||||||
Code PostNameMacro;
|
CodeParam Last;
|
||||||
StringCached Name;
|
CodeParam Next;
|
||||||
CodeParams Last;
|
parser::Token* Tok;
|
||||||
CodeParams Next;
|
|
||||||
Token* Tok;
|
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
```
|
```
|
||||||
@ -516,7 +510,7 @@ Serialization:
|
|||||||
```cpp
|
```cpp
|
||||||
<Macro>, <Next> ... <Last>
|
<Macro>, <Next> ... <Last>
|
||||||
|
|
||||||
<Macro> <ValueType> <Name> <PostNameMacro> = <Value>, <Next>... <Last>
|
<Macro> <ValueType> <Name>, <Next>... <Last>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Pragma
|
## Pragma
|
||||||
@ -525,11 +519,11 @@ Fields:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StringCached Content;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -545,11 +539,11 @@ Fields:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
StringCached Content;
|
StringCached Content;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
paser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -566,11 +560,11 @@ Fields:
|
|||||||
```cpp
|
```cpp
|
||||||
SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ];
|
SpecifierT ArrSpecs[ AST_ArrSpecs_Cap ];
|
||||||
CodeSpecifiers NextSpecs;
|
CodeSpecifiers NextSpecs;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
```
|
```
|
||||||
@ -586,13 +580,13 @@ Serialization:
|
|||||||
Fields:
|
Fields:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
CodeParams Params;
|
CodeParam Params;
|
||||||
Code Declaration;
|
Code Declaration;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
@ -615,30 +609,23 @@ Fields:
|
|||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeSpecifiers Specs;
|
CodeSpecifiers Specs;
|
||||||
CodeReturnType ReturnType;
|
CodeReturnType ReturnType;
|
||||||
CodeParams Params;
|
CodeParam Params;
|
||||||
Code ArrExpr;
|
Code ArrExpr;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
StringCached Name;
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
b32 IsParamPack;
|
b32 IsParamPack;
|
||||||
ETypenameTag TypeTag;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
<Attributes> <TypeTag> <Name> <Specs> <IsParamPack ?: ...>
|
<Attributes> <Name> <Specs> <IsParamPack ?: ...>
|
||||||
// Function
|
|
||||||
<Attributes> <ReturnType> <Name> <Params> <Specs>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`<Name>` currently has the full serialization of anything with
|
|
||||||
|
|
||||||
*Note: ArrExpr is not used in serialization by `typename_to_string_ref` its instead handled by a parent AST's serailization (variable, typedef, using).*
|
|
||||||
|
|
||||||
## Typedef
|
## Typedef
|
||||||
|
|
||||||
Behave as usual except function or macro typedefs.
|
Behave as usual except function or macro typedefs.
|
||||||
@ -649,11 +636,11 @@ Fields:
|
|||||||
```cpp
|
```cpp
|
||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
Code UnderlyingType;
|
Code UnderlyingType;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok
|
parse::Token* Tok
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
b32 IsFunction;
|
b32 IsFunction;
|
||||||
@ -663,16 +650,11 @@ Serialization:
|
|||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
// Regular
|
// Regular
|
||||||
<ModuleFlags> typedef <UnderlyingType> <Name> <UnderlyingType-ArrExpr>; <InlineCmt>
|
<ModuleFlags> typedef <UnderlyingType> <Name>; <InlineCmt>
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
<ModuleFlags> typedef <ReturnType> <Name>( <Parameters> ); <InlineCmt>
|
||||||
// Currently:
|
<ModuleFlags> typedef <ReturnType> ( <Expression that yeilds an Identifier signature> )( <Parameters> ); <InlineCmt>
|
||||||
<ModuleFlags> typedef <UnderlyingType (Serialized expression)>; <InlineCmt>
|
|
||||||
|
|
||||||
// Desired: Not handled yet
|
|
||||||
<ModuleFlags> typedef <UnderlyingType->ReturnType> UnderlyingType->Name> <UnderlyingType-ArrExpr> ( <UnderlyingType->Parameters> ); <InlineCmt>
|
|
||||||
<ModuleFlags> typedef <UnderlyingType->ReturnType> ( <Name->Namespace> for<Specs->has(Spec_Ptr) ?: *> <UnderlyingType->Name> <UnderlyingType-ArrExpr> ) ( <UnderlyingType->Parameters> ); <InlineCmt>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Union
|
## Union
|
||||||
@ -682,11 +664,11 @@ Fields:
|
|||||||
```cpp
|
```cpp
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeBody Body;
|
CodeBody Body;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
@ -708,11 +690,11 @@ Fields:
|
|||||||
CodeComment InlineCmt;
|
CodeComment InlineCmt;
|
||||||
CodeAttributes Attributes;
|
CodeAttributes Attributes;
|
||||||
CodeType UnderlyingType;
|
CodeType UnderlyingType;
|
||||||
StringCached Name;
|
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
```
|
```
|
||||||
@ -740,15 +722,14 @@ CodeSpecifiers Specs;
|
|||||||
CodeType ValueType;
|
CodeType ValueType;
|
||||||
Code BitfieldSize;
|
Code BitfieldSize;
|
||||||
Code Value;
|
Code Value;
|
||||||
StringCached Name;
|
|
||||||
CodeVar NextVar;
|
CodeVar NextVar;
|
||||||
Code Prev;
|
Code Prev;
|
||||||
Code Next;
|
Code Next;
|
||||||
Token* Tok;
|
parser::Token* Tok;
|
||||||
Code Parent;
|
Code Parent;
|
||||||
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
s32 VarParenthesizedInit;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Serialization:
|
Serialization:
|
||||||
@ -759,7 +740,4 @@ Serialization:
|
|||||||
|
|
||||||
// Bitfield
|
// Bitfield
|
||||||
<ModuleFlags> <Attributes> <Specs> <ValueType> <Name> : <BitfieldSize> = <Value>, NextVar ...; <InlineCmt>
|
<ModuleFlags> <Attributes> <Specs> <ValueType> <Name> : <BitfieldSize> = <Value>, NextVar ...; <InlineCmt>
|
||||||
|
|
||||||
// VarParenthesizedInit
|
|
||||||
<Attributes> <Specs> <ValueType> <Name>( <Value>, NextVar ... ); <InlineCmt>
|
|
||||||
```
|
```
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
The library features a naive single-pass parser tailored for only what the library needs to construct the supported syntax of C++ into its AST for *"front-end"* meta-programming purposes.
|
The library features a naive single-pass parser tailored for only what the library needs to construct the supported syntax of C++ into its AST for *"front-end"* meta-programming purposes.
|
||||||
|
|
||||||
This parser does not, and should not do the compiler's job. By only supporting this minimal set of features, the parser is kept (so far) around ~7000 loc. I hope to keep it under 10k loc worst case.
|
This parser does not, and should not do the compiler's job. By only supporting this minimal set of features, the parser is kept (so far) around ~5600 loc. I hope to keep it under 10k loc worst case.
|
||||||
|
|
||||||
You can think of this parser as *frontend parser* vs a *semantic parser*. Its intuitively similar to WYSIWYG. What you ***precerive*** as the syntax from the user-side before the compiler gets a hold of it, is what you get.
|
You can think of this parser as *frontend parser* vs a *semantic parser*. Its intuitively similar to WYSIWYG. What you ***precerive*** as the syntax from the user-side before the compiler gets a hold of it, is what you get.
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ The following CodeTypes are used which the user may optionally use strong typing
|
|||||||
* CodeNS
|
* CodeNS
|
||||||
* CodeOperator
|
* CodeOperator
|
||||||
* CodeOpCast
|
* CodeOpCast
|
||||||
* CodeParams : Has support for `for : range` iterating across parameters.
|
* CodeParam : Has support for `for : range` iterating across parameters.
|
||||||
* CodePreprocessCond
|
* CodePreprocessCond
|
||||||
* CodePragma
|
* CodePragma
|
||||||
* CodeSpecifiers : Has support for `for : range` iterating across specifiers.
|
* CodeSpecifiers : Has support for `for : range` iterating across specifiers.
|
||||||
@ -412,8 +412,4 @@ There are two provided auxillary interfaces:
|
|||||||
|
|
||||||
### Scanner Auxillary Interface
|
### Scanner Auxillary Interface
|
||||||
|
|
||||||
* The purpose is to scan or parse files
|
|
||||||
* Some with two basic functions to convert a fil to code: `scan_file` and `parse_file`
|
|
||||||
* `scan_file`: Merely grabs the file and stores it in an untyped Code.
|
|
||||||
* `parse_file`: Will parse the file using `parse_global_body` and return a `CodeBody`.
|
|
||||||
* Two basic functions for grabbing columns from a CSV: `parse_csv_one_column` and `parse_csv_two_columns`
|
|
||||||
|
@ -87,7 +87,6 @@ int gen_main()
|
|||||||
#pragma region Resolve Dependencies
|
#pragma region Resolve Dependencies
|
||||||
Code header_platform = scan_file( path_base "dependencies/platform.hpp" );
|
Code header_platform = scan_file( path_base "dependencies/platform.hpp" );
|
||||||
Code header_macros = scan_file( path_base "dependencies/macros.hpp" );
|
Code header_macros = scan_file( path_base "dependencies/macros.hpp" );
|
||||||
Code header_generic_macros = scan_file( "components/generic_macros.hpp" );
|
|
||||||
Code header_basic_types = scan_file( path_base "dependencies/basic_types.hpp" );
|
Code header_basic_types = scan_file( path_base "dependencies/basic_types.hpp" );
|
||||||
Code header_debug = scan_file( path_base "dependencies/debug.hpp" );
|
Code header_debug = scan_file( path_base "dependencies/debug.hpp" );
|
||||||
Code header_string_ops = scan_file( path_base "dependencies/string_ops.hpp" );
|
Code header_string_ops = scan_file( path_base "dependencies/string_ops.hpp" );
|
||||||
@ -749,7 +748,7 @@ R"(#define AST_ArrSpecs_Cap \
|
|||||||
txt("CodeOperator"),
|
txt("CodeOperator"),
|
||||||
txt("CodeOpCast"),
|
txt("CodeOpCast"),
|
||||||
txt("CodePragma"),
|
txt("CodePragma"),
|
||||||
txt("CodeParams"),
|
txt("CodeParam"),
|
||||||
txt("CodePreprocessCond"),
|
txt("CodePreprocessCond"),
|
||||||
txt("CodeSpecifiers"),
|
txt("CodeSpecifiers"),
|
||||||
txt("CodeTemplate"),
|
txt("CodeTemplate"),
|
||||||
@ -801,7 +800,7 @@ R"(#define AST_ArrSpecs_Cap \
|
|||||||
// Resolve generic's arguments
|
// Resolve generic's arguments
|
||||||
b32 has_args = fn->Params->NumEntries > 1;
|
b32 has_args = fn->Params->NumEntries > 1;
|
||||||
String params_str = String::make_reserve(GlobalAllocator, 32);
|
String params_str = String::make_reserve(GlobalAllocator, 32);
|
||||||
for (CodeParams param = fn->Params->Next; param != fn->Params.end(); ++ param) {
|
for (CodeParam param = fn->Params->Next; param != fn->Params.end(); ++ param) {
|
||||||
// We skip the first parameter as its always going to be the code for selection
|
// We skip the first parameter as its always going to be the code for selection
|
||||||
if (param->Next == nullptr) {
|
if (param->Next == nullptr) {
|
||||||
params_str.append_fmt( "%SC", param->Name );
|
params_str.append_fmt( "%SC", param->Name );
|
||||||
@ -936,7 +935,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
|||||||
}
|
}
|
||||||
|
|
||||||
b32 handled= false;
|
b32 handled= false;
|
||||||
for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_")))
|
for ( CodeParam opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_")))
|
||||||
{
|
{
|
||||||
// Convert the definition to use a default struct: https://vxtwitter.com/vkrajacic/status/1749816169736073295
|
// Convert the definition to use a default struct: https://vxtwitter.com/vkrajacic/status/1749816169736073295
|
||||||
StrC prefix = txt("def_");
|
StrC prefix = txt("def_");
|
||||||
@ -946,7 +945,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
|||||||
// Resolve define's arguments
|
// Resolve define's arguments
|
||||||
b32 has_args = fn->Params->NumEntries > 1;
|
b32 has_args = fn->Params->NumEntries > 1;
|
||||||
String params_str = String::make_reserve(GlobalAllocator, 32);
|
String params_str = String::make_reserve(GlobalAllocator, 32);
|
||||||
for (CodeParams other_param = fn->Params; other_param != opt_param; ++ other_param) {
|
for (CodeParam other_param = fn->Params; other_param != opt_param; ++ other_param) {
|
||||||
if ( other_param == opt_param ) {
|
if ( other_param == opt_param ) {
|
||||||
params_str.append_fmt( "%SC", other_param->Name );
|
params_str.append_fmt( "%SC", other_param->Name );
|
||||||
break;
|
break;
|
||||||
@ -1211,7 +1210,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
|||||||
CodeFn fn = cast(CodeFn, entry);
|
CodeFn fn = cast(CodeFn, entry);
|
||||||
Code prev = entry->Prev;
|
Code prev = entry->Prev;
|
||||||
|
|
||||||
for ( CodeParams arr_param : fn->Params )
|
for ( CodeParam arr_param : fn->Params )
|
||||||
if ( fn->Name.starts_with(txt("def_"))
|
if ( fn->Name.starts_with(txt("def_"))
|
||||||
&& ( (arr_param->ValueType->Name.starts_with(txt("Specifier")) && fn->Params->NumEntries > 1)
|
&& ( (arr_param->ValueType->Name.starts_with(txt("Specifier")) && fn->Params->NumEntries > 1)
|
||||||
|| arr_param->ValueType->Name.starts_with(txt("Code")) )
|
|| arr_param->ValueType->Name.starts_with(txt("Code")) )
|
||||||
@ -1223,7 +1222,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
|||||||
postfix_arr.free();
|
postfix_arr.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( CodeParams opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_")))
|
for ( CodeParam opt_param : fn->Params ) if (opt_param->ValueType->Name.starts_with(txt("Opts_")))
|
||||||
{
|
{
|
||||||
StrC prefix = txt("def_");
|
StrC prefix = txt("def_");
|
||||||
StrC actual_name = { fn->Name.Len - prefix.Len, fn->Name.Ptr + prefix.Len };
|
StrC actual_name = { fn->Name.Len - prefix.Len, fn->Name.Ptr + prefix.Len };
|
||||||
@ -1482,7 +1481,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
|||||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||||
|
|
||||||
header.print( r_header_macros );
|
header.print( r_header_macros );
|
||||||
header.print( header_generic_macros );
|
|
||||||
header.print( r_header_basic_types );
|
header.print( r_header_basic_types );
|
||||||
header.print( r_header_debug );
|
header.print( r_header_debug );
|
||||||
header.print( rf_header_memory );
|
header.print( rf_header_memory );
|
||||||
@ -1619,7 +1617,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
|
|||||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||||
|
|
||||||
header.print( r_header_macros );
|
header.print( r_header_macros );
|
||||||
header.print( header_generic_macros );
|
|
||||||
header.print( r_header_basic_types );
|
header.print( r_header_basic_types );
|
||||||
header.print( r_header_debug );
|
header.print( r_header_debug );
|
||||||
header.print( rf_header_memory );
|
header.print( rf_header_memory );
|
||||||
|
@ -337,7 +337,7 @@ word CodeNS, gen_CodeNS
|
|||||||
word CodeOperator, gen_CodeOperator
|
word CodeOperator, gen_CodeOperator
|
||||||
word CodeOpCast, gen_CodeOpCast
|
word CodeOpCast, gen_CodeOpCast
|
||||||
word CodePragma, gen_CodePragma
|
word CodePragma, gen_CodePragma
|
||||||
word CodeParams, gen_CodeParams
|
word CodeParam, gen_CodeParam
|
||||||
word CodePreprocessCo, gen_CodePreprocessCo
|
word CodePreprocessCo, gen_CodePreprocessCo
|
||||||
word CodeSpecifiers, gen_CodeSpecifiers
|
word CodeSpecifiers, gen_CodeSpecifiers
|
||||||
word CodeTemplate, gen_CodeTemplate
|
word CodeTemplate, gen_CodeTemplate
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
|
|
||||||
#pragma region _Generic Macros
|
|
||||||
// ____ _ ______ _ _ ____ _ __ _
|
|
||||||
// / ___} (_) | ____} | | (_) / __ \ | | | |(_)
|
|
||||||
// | | ___ ___ _ __ ___ _ __ _ ___ | |__ _ _ _ __ ___| |_ _ ___ _ __ | | | |_ _____ _ __ | | ___ __ _ __| | _ _ __ __ _
|
|
||||||
// | |{__ |/ _ \ '_ \ / _ \ '__} |/ __| | __} | | | '_ \ / __} __} |/ _ \| '_ \ | | | \ \ / / _ \ '_ \| |/ _ \ / _` |/ _` || | '_ \ / _` |
|
|
||||||
// | |__j | __/ | | | __/ | | | (__ | | | |_| | | | | (__| l_| | (_) | | | | | l__| |\ V / __/ | | | | (_) | (_| | (_| || | | | | (_| |
|
|
||||||
// \____/ \___}_l l_l\___}_l l_l\___| l_l \__,_l_l l_l\___}\__}_l\___/l_l l_l \____/ \_/ \___}_l l_l_l\___/ \__,_l\__,_l|_|_| |_|\__, |
|
|
||||||
// This implemnents macros for utilizing "The Naive Extendible _Generic Macro" explained in: __| |
|
|
||||||
// https://github.com/JacksonAllan/CC/blob/main/articles/Better_C_Generics_Part_1_The_Extendible_Generic.md {___/
|
|
||||||
// Since gencpp is used to generate the c-library, it was choosen over the more novel implementations to keep the macros as easy to understand and unobfuscated as possible.
|
|
||||||
|
|
||||||
#define GEN_COMMA_OPERATOR , // The comma operator is used by preprocessor macros to delimit arguments, so we have to represent it via a macro to prevent parsing incorrectly.
|
|
||||||
|
|
||||||
// Helper macros for argument selection
|
|
||||||
#define GEN_SELECT_ARG_1( _1, ... ) _1 // <-- Of all th args passed pick _1.
|
|
||||||
#define GEN_SELECT_ARG_2( _1, _2, ... ) _2 // <-- Of all the args passed pick _2.
|
|
||||||
#define GEN_SELECT_ARG_3( _1, _2, _3, ... ) _3 // etc..
|
|
||||||
|
|
||||||
#define GEN_GENERIC_SEL_ENTRY_TYPE GEN_SELECT_ARG_1 // Use the arg expansion macro to select arg 1 which should have the type.
|
|
||||||
#define GEN_GENERIC_SEL_ENTRY_FUNCTION GEN_SELECT_ARG_2 // Use the arg expansion macro to select arg 2 which should have the function.
|
|
||||||
#define GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER GEN_SELECT_ARG_3 // Use the arg expansion macro to select arg 3 which should have the comma delimiter ','.
|
|
||||||
|
|
||||||
#define GEN_RESOLVED_FUNCTION_CALL // Just used to indicate where the call "occurs"
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
// GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( macro ) includes a _Generic slot only if the specified macro is defined (as type, function_name).
|
|
||||||
// It takes advantage of the fact that if the macro is defined, then the expanded text will contain a comma.
|
|
||||||
// Expands to ',' if it can find (type): (function) <comma_operator: ',' >
|
|
||||||
// Where GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER is specifically looking for that <comma> ,
|
|
||||||
#define GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( slot_exp ) GEN_GENERIC_SEL_ENTRY_COMMA_DELIMITER( slot_exp, GEN_GENERIC_SEL_ENTRY_TYPE( slot_exp, ): GEN_GENERIC_SEL_ENTRY_FUNCTION( slot_exp, ) GEN_COMMA_OPERATOR, , )
|
|
||||||
// ^ Selects the comma ^ is the type ^ is the function ^ Insert a comma
|
|
||||||
// The slot won't exist if that comma is not found. |
|
|
||||||
|
|
||||||
// For the occastion where an expression didn't resolve to a selection option the "default: <value>" will be set to:
|
|
||||||
typedef struct GENCPP_NO_RESOLVED_GENERIC_SELECTION GENCPP_NO_RESOLVED_GENERIC_SELECTION;
|
|
||||||
struct GENCPP_NO_RESOLVED_GENERIC_SELECTION {
|
|
||||||
void* _THE_VOID_SLOT_;
|
|
||||||
};
|
|
||||||
GENCPP_NO_RESOLVED_GENERIC_SELECTION const gen_generic_selection_fail = {0};
|
|
||||||
// Which will provide the message: error: called object type 'struct NO_RESOLVED_GENERIC_SELECTION' is not a function or function pointer
|
|
||||||
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Below are generated on demand for an overlaod depdendent on a type:
|
|
||||||
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
#define GEN_FUNCTION_GENERIC_EXAMPLE( selector_arg ) _Generic( \
|
|
||||||
(selector_arg), /* Select Via Expression*/ \
|
|
||||||
/* Extendibility slots: */ \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
|
||||||
default: gen_generic_selection_fail \
|
|
||||||
) GEN_RESOLVED_FUNCTION_CALL( selector_arg )
|
|
||||||
// ----------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Then each definiton of a function has an associated define:
|
|
||||||
#// #define GENERIC_SLOT_<#>_<generic identifier> <typename>, <function_to_resolve>
|
|
||||||
|
|
||||||
// Then somehwere later on
|
|
||||||
// <etc> <return_type> <function_id> ( <arguments> ) { <implementation> }
|
|
||||||
|
|
||||||
// Concrete example:
|
|
||||||
|
|
||||||
// To add support for long:
|
|
||||||
#define GENERIC_SLOT_1_gen_example_hash long, gen_example_hash__P_long
|
|
||||||
size_t gen_example_hash__P_long( long val ) { return val * 2654435761ull; }
|
|
||||||
|
|
||||||
// To add support for long long:
|
|
||||||
#define GENERIC_SLOT_2_gen_example_hash long long, gen_example_hash__P_long_long
|
|
||||||
size_t gen_example_hash__P_long_long( long long val ) { return val * 2654435761ull; }
|
|
||||||
|
|
||||||
// If using an Editor with support for syntax hightlighting macros: HASH__ARGS_SIG_1 and HASH_ARGS_SIG_2 should show color highlighting indicating the slot is enabled,
|
|
||||||
// or, "defined" for usage during the compilation pass that handles the _Generic instrinsic.
|
|
||||||
#define gen_hash_example( function_arguments ) _Generic( \
|
|
||||||
(function_arguments), /* Select Via Expression*/ \
|
|
||||||
/* Extendibility slots: */ \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_1 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_2 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_3 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_4 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_5 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_6 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_7 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( HASH__ARGS_SIG_8 ) \
|
|
||||||
default: gen_generic_selection_fail \
|
|
||||||
) GEN_RESOLVED_FUNCTION_CALL( function_arguments )
|
|
||||||
|
|
||||||
// Additional Variations:
|
|
||||||
|
|
||||||
// If the function takes more than one argument the following is used:
|
|
||||||
#define GEN_FUNCTION_GENERIC_EXAMPLE_VARADIC( selector_arg, ... ) _Generic( \
|
|
||||||
(selector_arg), \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 ) \
|
|
||||||
/* ... */ \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N ) \
|
|
||||||
default: gen_generic_selection_fail \
|
|
||||||
) GEN_RESOLVED_FUNCTION_CALL( selector_arg, __VA_ARG__ )
|
|
||||||
|
|
||||||
// If the function does not take the arugment as a parameter:
|
|
||||||
#define GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( selector_arg ) _Generic( \
|
|
||||||
( GEN_TYPE_TO_EXP(selector_arg) ), \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_1 ) \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT( FunctionID__ARGS_SIG_2 ) \
|
|
||||||
/* ... */ \
|
|
||||||
GEN_IF_MACRO_DEFINED_INCLUDE_THIS_SLOT(FunctionID__ARGS_SIG_N ) \
|
|
||||||
default: gen_generic_selection_fail \
|
|
||||||
) GEN_RESOLVED_FUNCTION_CALL()
|
|
||||||
|
|
||||||
// Used to keep the _Generic keyword happy as bare types are not considered "expressions"
|
|
||||||
#define GEN_TYPE_TO_EXP(type) (* (type*)NULL)
|
|
||||||
// Instead of using this macro, you'll see it directly expanded by the code generation.
|
|
||||||
|
|
||||||
// typedef void* GEN_GenericExampleType;
|
|
||||||
// GEN_FUNCTION_GENERIC_EXAMPLE_DIRECT_TYPE( GEN_GenericExampleType );
|
|
||||||
#pragma endregion _Generic Macros
|
|
@ -174,7 +174,7 @@ CodeFn rename_function_to_unique_symbol(CodeFn fn, StrC optional_prefix = txt(""
|
|||||||
|
|
||||||
// Add parameter types to create a unique signature
|
// Add parameter types to create a unique signature
|
||||||
bool first_param = true;
|
bool first_param = true;
|
||||||
for (CodeParams param = fn->Params; param.ast; param = param->Next)
|
for (CodeParam param = fn->Params; param.ast; param = param->Next)
|
||||||
{
|
{
|
||||||
if (param->ValueType)
|
if (param->ValueType)
|
||||||
{
|
{
|
||||||
|
@ -266,7 +266,7 @@
|
|||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
|
|
||||||
<Type Name="gen::AST_Params">
|
<Type Name="gen::AST_Param">
|
||||||
<DisplayString>{Name} Type: {Type}</DisplayString>
|
<DisplayString>{Name} Type: {Type}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="ValueType">ValueType</Item>
|
<Item Name="ValueType">ValueType</Item>
|
||||||
@ -553,7 +553,7 @@
|
|||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
|
|
||||||
<Type Name="gen::CodeParams">
|
<Type Name="gen::CodeParam">
|
||||||
<DisplayString Condition="ast == nullptr">Null</DisplayString>
|
<DisplayString Condition="ast == nullptr">Null</DisplayString>
|
||||||
<DisplayString Condition="ast != nullptr">{ast->Name} {ast->Type}</DisplayString>
|
<DisplayString Condition="ast != nullptr">{ast->Name} {ast->Type}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
|
@ -30,32 +30,15 @@ struct AnotherTemplate {
|
|||||||
T value;
|
T value;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef decltype(nullptr) ( MyClass:: * InsaneComplexTypeDef )
|
typedef decltype(nullptr) (MyClass::*InsaneComplexTypeDef)
|
||||||
(
|
(
|
||||||
decltype( (MyEnum::VAL1 == MyEnum::VAL2) ? 1 : 2.0 )
|
decltype((MyEnum::VAL1 == MyEnum::VAL2) ? 1 : 2.0)(TemplateStruct<decltype(OuterStruct().unionInstance.inner), 5>::*ptr)[5][alignof(double)],
|
||||||
( TemplateStruct< decltype(OuterStruct().unionInstance.inner), 5> :: * ptr ) [5] [ alignof(double) ],
|
std::function<void *(TemplateStruct<int, 10>&&, void (MyClass::*memFnPtr)(TemplateStruct<decltype(OuterStruct().unionInstance.inner)>))>,
|
||||||
std::function<
|
int (MyClass::*&refToMemFnPtr)(TemplateStruct<int, 10>),
|
||||||
void *
|
int (TemplateStruct<int, 10>::*memberPointer)[10],
|
||||||
(
|
typename std::tuple_element<0, std::tuple<AnotherTemplate<TemplateStruct<decltype(OuterStruct().unionInstance), 3>>>>::type::*complexMember,
|
||||||
TemplateStruct<int, 10> &&,
|
template<typename U> typename AnotherTemplate<U>::*templateMember
|
||||||
void ( MyClass:: * memFnPtr )(
|
|
||||||
TemplateStruct<
|
|
||||||
decltype(OuterStruct().unionInstance.inner)
|
|
||||||
>
|
|
||||||
)
|
|
||||||
)
|
|
||||||
>,
|
|
||||||
int ( MyClass :: * & refToMemFnPtr )( TemplateStruct<int, 10> ) ,
|
|
||||||
int ( TemplateStruct<int, 10>:: * memberPointer) [10],
|
|
||||||
typename std::tuple_element<
|
|
||||||
0,
|
|
||||||
std::tuple<
|
|
||||||
AnotherTemplate<
|
|
||||||
TemplateStruct< decltype(OuterStruct().unionInstance), 3 >
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> :: type :: * complexMember,
|
|
||||||
template<typename U> typename AnotherTemplate<U> :: * templateMember
|
|
||||||
char&&...,
|
char&&...,
|
||||||
)
|
)
|
||||||
volatile const && noexcept;
|
volatile const && noexcept;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user