mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 15:54:45 -08:00
Compare commits
No commits in common. "f90c0a59b67b88a2c51ee7a7e30b7aa4127aa382" and "e1592ba410df7e06d0d7186cd8bc500517d5bfe5" have entirely different histories.
f90c0a59b6
...
e1592ba410
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@ -41,15 +41,6 @@
|
|||||||
"cwd": "${workspaceFolder}/singleheader/",
|
"cwd": "${workspaceFolder}/singleheader/",
|
||||||
"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
|
"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "cppvsdbg",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Debug unreal vsdbg",
|
|
||||||
"program": "${workspaceFolder}/unreal_engine/build/unreal.exe",
|
|
||||||
"args": [],
|
|
||||||
"cwd": "${workspaceFolder}/unreal_engine/",
|
|
||||||
"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "cppvsdbg",
|
"type": "cppvsdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
Builder Builder::open( char const* path )
|
Builder Builder::open( char const* path )
|
||||||
{
|
{
|
||||||
Builder result;
|
Builder result;
|
||||||
|
|
||||||
FileError error = file_open_mode( & result.File, EFileMode_WRITE, path );
|
FileError error = file_open_mode( & result.File, EFileMode_WRITE, path );
|
||||||
if ( error != EFileError_NONE )
|
if ( error != EFileError_NONE )
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ void Builder::print_fmt( char const* fmt, ... )
|
|||||||
|
|
||||||
void Builder::write()
|
void Builder::write()
|
||||||
{
|
{
|
||||||
b32 result = file_write( & File, Buffer, Buffer.length() );
|
bool result = file_write( & File, Buffer, Buffer.length() );
|
||||||
|
|
||||||
if ( result == false )
|
if ( result == false )
|
||||||
log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & File ) );
|
log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & File ) );
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||||
# include "scanner.hpp"
|
# include "scanner.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
// This is a simple file reader that reads the entire file into memory.
|
// This is a simple file reader that reads the entire file into memory.
|
||||||
// It has an extra option to skip the first few lines for undesired includes.
|
// It has an extra option to skip the first few lines for undesired includes.
|
||||||
// This is done so that includes can be kept in dependency and component files so that intellisense works.
|
// This is done so that includes can be kept in dependency and component files so that intellisense works.
|
||||||
inline
|
|
||||||
Code scan_file( char const* path )
|
Code scan_file( char const* path )
|
||||||
{
|
{
|
||||||
FileInfo file;
|
FileInfo file;
|
||||||
|
@ -283,7 +283,6 @@ int gen_main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gen_scanner.cpp
|
// gen_scanner.cpp
|
||||||
if (1)
|
|
||||||
{
|
{
|
||||||
Code parsing = scan_file( "dependencies/parsing.cpp" );
|
Code parsing = scan_file( "dependencies/parsing.cpp" );
|
||||||
Code scanner = scan_file( "auxillary/scanner.cpp" );
|
Code scanner = scan_file( "auxillary/scanner.cpp" );
|
||||||
@ -294,7 +293,7 @@ int gen_main()
|
|||||||
src.print( def_include( txt("gen.scanner.hpp") ) );
|
src.print( def_include( txt("gen.scanner.hpp") ) );
|
||||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||||
src.print( parsing );
|
src.print( parsing );
|
||||||
// src.print( scanner );
|
src.print( scanner );
|
||||||
src.print_fmt( "GEN_NS_END\n" );
|
src.print_fmt( "GEN_NS_END\n" );
|
||||||
src.write();
|
src.write();
|
||||||
}
|
}
|
||||||
|
@ -339,14 +339,13 @@ struct AST
|
|||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
AST* ArrExpr; // Typename
|
AST* ArrExpr; // Typename
|
||||||
AST* Body; // Class, Constructor, Destructor, Enum, Friend, Function, Namespace, Struct, Union
|
AST* Body; // Class, Constructr, Destructor, Enum, Friend, Function, Namespace, Struct, Union
|
||||||
AST* Declaration; // Friend, Template
|
AST* Declaration; // Friend, Template
|
||||||
AST* Value; // Parameter, Variable
|
AST* Value; // Parameter, Variable
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
|
AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
|
||||||
AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
|
AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
|
||||||
AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Content; // Attributes, Comment, Execution, Include
|
StringCached Content; // Attributes, Comment, Execution, Include
|
||||||
@ -376,7 +375,6 @@ struct AST
|
|||||||
OperatorT Op;
|
OperatorT Op;
|
||||||
AccessSpec ParentAccess;
|
AccessSpec ParentAccess;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -409,7 +407,6 @@ struct AST_POD
|
|||||||
union {
|
union {
|
||||||
AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
|
AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
|
||||||
AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
|
AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
|
||||||
AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
StringCached Content; // Attributes, Comment, Execution, Include
|
StringCached Content; // Attributes, Comment, Execution, Include
|
||||||
@ -439,7 +436,6 @@ struct AST_POD
|
|||||||
OperatorT Op;
|
OperatorT Op;
|
||||||
AccessSpec ParentAccess;
|
AccessSpec ParentAccess;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -644,8 +644,7 @@ struct AST_Param
|
|||||||
CodeType ValueType;
|
CodeType ValueType;
|
||||||
Code Macro;
|
Code Macro;
|
||||||
Code Value;
|
Code Value;
|
||||||
Code PostNameMacro; // Thanks Unreal
|
char _PAD_PROPERTIES_3_[ sizeof(AST*) ];
|
||||||
// char _PAD_PROPERTIES_3_[sizeof( AST* )];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
CodeParam Last;
|
CodeParam Last;
|
||||||
@ -1116,7 +1115,7 @@ struct AST_Var
|
|||||||
StringCached Name;
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
s32 VarConstructorInit;
|
char _PAD_UNUSED_[ sizeof(u32) ];
|
||||||
};
|
};
|
||||||
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");
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ void CodeFn::to_string_def( String& result )
|
|||||||
if ( ast->Attributes )
|
if ( ast->Attributes )
|
||||||
result.append_fmt( " %S ", ast->Attributes.to_string() );
|
result.append_fmt( " %S ", ast->Attributes.to_string() );
|
||||||
|
|
||||||
bool prefix_specs = false;
|
b32 prefix_specs = false;
|
||||||
if ( ast->Specs )
|
if ( ast->Specs )
|
||||||
{
|
{
|
||||||
for ( SpecifierT spec : ast->Specs )
|
for ( SpecifierT spec : ast->Specs )
|
||||||
@ -764,14 +764,7 @@ void CodeOpCast::to_string_def( String& result )
|
|||||||
{
|
{
|
||||||
if ( ast->Specs )
|
if ( ast->Specs )
|
||||||
{
|
{
|
||||||
for ( SpecifierT spec : ast->Specs )
|
// TODO : Add support for specifies before the operator keyword
|
||||||
{
|
|
||||||
if ( ! ESpecifier::is_trailing( spec ) )
|
|
||||||
{
|
|
||||||
StrC spec_str = ESpecifier::to_str( spec );
|
|
||||||
result.append_fmt( "%*s ", spec_str.Len, spec_str.Ptr );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ast->Name && ast->Name.length() )
|
if ( ast->Name && ast->Name.length() )
|
||||||
result.append_fmt( "%Soperator %S()", ast->Name, ast->ValueType.to_string() );
|
result.append_fmt( "%Soperator %S()", ast->Name, ast->ValueType.to_string() );
|
||||||
@ -801,14 +794,7 @@ void CodeOpCast::to_string_fwd( String& result )
|
|||||||
{
|
{
|
||||||
if ( ast->Specs )
|
if ( ast->Specs )
|
||||||
{
|
{
|
||||||
for ( SpecifierT spec : ast->Specs )
|
// TODO : Add support for specifies before the operator keyword
|
||||||
{
|
|
||||||
if ( ! ESpecifier::is_trailing( spec ) )
|
|
||||||
{
|
|
||||||
StrC spec_str = ESpecifier::to_str( spec );
|
|
||||||
result.append_fmt( "%*s ", spec_str.Len, spec_str.Ptr );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.append_fmt( "operator %S()", ast->ValueType.to_string() );
|
result.append_fmt( "operator %S()", ast->ValueType.to_string() );
|
||||||
|
|
||||||
@ -861,11 +847,6 @@ void CodeParam::to_string( String& result )
|
|||||||
else if ( ast->ValueType )
|
else if ( ast->ValueType )
|
||||||
result.append_fmt( " %S", ast->ValueType.to_string() );
|
result.append_fmt( " %S", ast->ValueType.to_string() );
|
||||||
|
|
||||||
if ( ast->PostNameMacro )
|
|
||||||
{
|
|
||||||
result.append_fmt(" %S", ast->PostNameMacro.to_string() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ast->Value )
|
if ( ast->Value )
|
||||||
result.append_fmt( " = %S", ast->Value.to_string() );
|
result.append_fmt( " = %S", ast->Value.to_string() );
|
||||||
|
|
||||||
@ -1115,7 +1096,7 @@ String CodeType::to_string()
|
|||||||
|
|
||||||
void CodeType::to_string( String& result )
|
void CodeType::to_string( String& result )
|
||||||
{
|
{
|
||||||
#if defined(GEN_USE_NEW_TYPENAME_PARSING)
|
#if GEN_USE_NEW_TYPENAME_PARSING
|
||||||
if ( ast->ReturnType && ast->Params )
|
if ( ast->ReturnType && ast->Params )
|
||||||
{
|
{
|
||||||
if ( ast->Attributes )
|
if ( ast->Attributes )
|
||||||
@ -1272,7 +1253,7 @@ void CodeVar::to_string( String& result )
|
|||||||
|
|
||||||
result.append( ast->Name );
|
result.append( ast->Name );
|
||||||
|
|
||||||
if ( ast->ValueType->ArrExpr )
|
if ( ast->ValueType && ast->ValueType->ArrExpr )
|
||||||
{
|
{
|
||||||
result.append_fmt( "[ %S ]", ast->ValueType->ArrExpr.to_string() );
|
result.append_fmt( "[ %S ]", ast->ValueType->ArrExpr.to_string() );
|
||||||
|
|
||||||
@ -1285,20 +1266,12 @@ void CodeVar::to_string( String& result )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( ast->Value )
|
if ( ast->Value )
|
||||||
{
|
result.append_fmt( " = %S", ast->Value.to_string() );
|
||||||
if ( ast->VarConstructorInit )
|
|
||||||
result.append_fmt( "( %S ", ast->Value.to_string() );
|
|
||||||
else
|
|
||||||
result.append_fmt( " = %S", ast->Value.to_string() );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep the chain going...
|
// Keep the chain going...
|
||||||
if ( ast->NextVar )
|
if ( ast->NextVar )
|
||||||
result.append_fmt( ", %S", ast->NextVar.to_string() );
|
result.append_fmt( ", %S", ast->NextVar.to_string() );
|
||||||
|
|
||||||
if ( ast->VarConstructorInit )
|
|
||||||
result.append( " )");
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1331,19 +1304,11 @@ void CodeVar::to_string( String& result )
|
|||||||
result.append_fmt( " : %S", ast->BitfieldSize.to_string() );
|
result.append_fmt( " : %S", ast->BitfieldSize.to_string() );
|
||||||
|
|
||||||
if ( ast->Value )
|
if ( ast->Value )
|
||||||
{
|
result.append_fmt( " = %S", ast->Value.to_string() );
|
||||||
if ( ast->VarConstructorInit )
|
|
||||||
result.append_fmt( "( %S ", ast->Value.to_string() );
|
|
||||||
else
|
|
||||||
result.append_fmt( " = %S", ast->Value.to_string() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ast->NextVar )
|
if ( ast->NextVar )
|
||||||
result.append_fmt( ", %S", ast->NextVar.to_string() );
|
result.append_fmt( ", %S", ast->NextVar.to_string() );
|
||||||
|
|
||||||
if ( ast->VarConstructorInit )
|
|
||||||
result.append( " )");
|
|
||||||
|
|
||||||
if ( ast->InlineCmt )
|
if ( ast->InlineCmt )
|
||||||
result.append_fmt("; %S", ast->InlineCmt->Content);
|
result.append_fmt("; %S", ast->InlineCmt->Content);
|
||||||
else
|
else
|
||||||
@ -1371,19 +1336,11 @@ void CodeVar::to_string( String& result )
|
|||||||
result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name );
|
result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name );
|
||||||
|
|
||||||
if ( ast->Value )
|
if ( ast->Value )
|
||||||
{
|
result.append_fmt( " = %S", ast->Value.to_string() );
|
||||||
if ( ast->VarConstructorInit )
|
|
||||||
result.append_fmt( "( %S ", ast->Value.to_string() );
|
|
||||||
else
|
|
||||||
result.append_fmt( " = %S", ast->Value.to_string() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ast->NextVar )
|
if ( ast->NextVar )
|
||||||
result.append_fmt( ", %S", ast->NextVar.to_string() );
|
result.append_fmt( ", %S", ast->NextVar.to_string() );
|
||||||
|
|
||||||
if ( ast->VarConstructorInit )
|
|
||||||
result.append( " )");
|
|
||||||
|
|
||||||
result.append( ";" );
|
result.append( ";" );
|
||||||
|
|
||||||
if ( ast->InlineCmt )
|
if ( ast->InlineCmt )
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -72,7 +72,7 @@ namespace ECode
|
|||||||
NumTypes
|
NumTypes
|
||||||
};
|
};
|
||||||
|
|
||||||
inline StrC to_str( Type type )
|
StrC to_str( Type type )
|
||||||
{
|
{
|
||||||
local_persist StrC lookup[] {
|
local_persist StrC lookup[] {
|
||||||
{ sizeof( "Invalid" ), "Invalid" },
|
{ sizeof( "Invalid" ), "Invalid" },
|
||||||
|
@ -59,7 +59,7 @@ namespace EOperator
|
|||||||
NumOps
|
NumOps
|
||||||
};
|
};
|
||||||
|
|
||||||
inline StrC to_str( Type op )
|
StrC to_str( Type op )
|
||||||
{
|
{
|
||||||
local_persist StrC lookup[] {
|
local_persist StrC lookup[] {
|
||||||
{ sizeof( "INVALID" ), "INVALID" },
|
{ sizeof( "INVALID" ), "INVALID" },
|
||||||
|
@ -38,12 +38,12 @@ namespace ESpecifier
|
|||||||
NumSpecifiers
|
NumSpecifiers
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool is_trailing( Type specifier )
|
bool is_trailing( Type specifier )
|
||||||
{
|
{
|
||||||
return specifier > Virtual;
|
return specifier > Virtual;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StrC to_str( Type type )
|
StrC to_str( Type type )
|
||||||
{
|
{
|
||||||
local_persist StrC lookup[] {
|
local_persist StrC lookup[] {
|
||||||
{ sizeof( "INVALID" ), "INVALID" },
|
{ sizeof( "INVALID" ), "INVALID" },
|
||||||
@ -76,7 +76,7 @@ namespace ESpecifier
|
|||||||
return lookup[type];
|
return lookup[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Type to_type( StrC str )
|
Type to_type( StrC str )
|
||||||
{
|
{
|
||||||
local_persist u32 keymap[NumSpecifiers];
|
local_persist u32 keymap[NumSpecifiers];
|
||||||
do_once_start for ( u32 index = 0; index < NumSpecifiers; index++ )
|
do_once_start for ( u32 index = 0; index < NumSpecifiers; index++ )
|
||||||
|
@ -113,7 +113,7 @@ namespace parser
|
|||||||
NumTokens
|
NumTokens
|
||||||
};
|
};
|
||||||
|
|
||||||
inline StrC to_str( Type type )
|
StrC to_str( Type type )
|
||||||
{
|
{
|
||||||
local_persist StrC lookup[] {
|
local_persist StrC lookup[] {
|
||||||
{ sizeof( "__invalid__" ), "__invalid__" },
|
{ sizeof( "__invalid__" ), "__invalid__" },
|
||||||
@ -217,7 +217,7 @@ namespace parser
|
|||||||
return lookup[type];
|
return lookup[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Type to_type( StrC str )
|
Type to_type( StrC str )
|
||||||
{
|
{
|
||||||
local_persist u32 keymap[NumTokens];
|
local_persist u32 keymap[NumTokens];
|
||||||
do_once_start for ( u32 index = 0; index < NumTokens; index++ )
|
do_once_start for ( u32 index = 0; index < NumTokens; index++ )
|
||||||
|
@ -63,6 +63,7 @@ extern CodeAttributes attrib_api_import;
|
|||||||
extern Code module_global_fragment;
|
extern Code module_global_fragment;
|
||||||
extern Code module_private_fragment;
|
extern Code module_private_fragment;
|
||||||
|
|
||||||
|
// Exposed, but this is really used for parsing.
|
||||||
extern Code fmt_newline;
|
extern Code fmt_newline;
|
||||||
|
|
||||||
extern CodePragma pragma_once;
|
extern CodePragma pragma_once;
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include "interface.hpp"
|
#include "interface.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline
|
|
||||||
void AST::append( AST* other )
|
void AST::append( AST* other )
|
||||||
{
|
{
|
||||||
if ( other->Parent )
|
if ( other->Parent )
|
||||||
@ -28,7 +27,6 @@ void AST::append( AST* other )
|
|||||||
NumEntries++;
|
NumEntries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
Code& AST::entry( u32 idx )
|
Code& AST::entry( u32 idx )
|
||||||
{
|
{
|
||||||
AST** current = & Front;
|
AST** current = & Front;
|
||||||
@ -44,25 +42,21 @@ Code& AST::entry( u32 idx )
|
|||||||
return * rcast( Code*, current);
|
return * rcast( Code*, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
bool AST::has_entries()
|
bool AST::has_entries()
|
||||||
{
|
{
|
||||||
return NumEntries > 0;
|
return NumEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
char const* AST::type_str()
|
char const* AST::type_str()
|
||||||
{
|
{
|
||||||
return ECode::to_str( Type );
|
return ECode::to_str( Type );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
AST::operator Code()
|
AST::operator Code()
|
||||||
{
|
{
|
||||||
return { this };
|
return { this };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
Code& Code::operator ++()
|
Code& Code::operator ++()
|
||||||
{
|
{
|
||||||
if ( ast )
|
if ( ast )
|
||||||
@ -71,7 +65,6 @@ Code& Code::operator ++()
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
void CodeClass::add_interface( CodeType type )
|
void CodeClass::add_interface( CodeType type )
|
||||||
{
|
{
|
||||||
CodeType possible_slot = ast->ParentType;
|
CodeType possible_slot = ast->ParentType;
|
||||||
@ -91,7 +84,6 @@ void CodeClass::add_interface( CodeType type )
|
|||||||
possible_slot.ast = type.ast;
|
possible_slot.ast = type.ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
void CodeParam::append( CodeParam other )
|
void CodeParam::append( CodeParam other )
|
||||||
{
|
{
|
||||||
AST* self = (AST*) ast;
|
AST* self = (AST*) ast;
|
||||||
@ -115,7 +107,6 @@ void CodeParam::append( CodeParam other )
|
|||||||
self->NumEntries++;
|
self->NumEntries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
CodeParam CodeParam::get( s32 idx )
|
CodeParam CodeParam::get( s32 idx )
|
||||||
{
|
{
|
||||||
CodeParam param = *this;
|
CodeParam param = *this;
|
||||||
@ -124,27 +115,24 @@ CodeParam CodeParam::get( s32 idx )
|
|||||||
if ( ! ++ param )
|
if ( ! ++ param )
|
||||||
return { nullptr };
|
return { nullptr };
|
||||||
|
|
||||||
param = { (AST_Param*) param.raw()->Next };
|
return { (AST_Param*) param.raw()->Next };
|
||||||
}
|
}
|
||||||
while ( --idx );
|
while ( --idx );
|
||||||
|
|
||||||
return param;
|
return { nullptr };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
bool CodeParam::has_entries()
|
bool CodeParam::has_entries()
|
||||||
{
|
{
|
||||||
return ast->NumEntries > 0;
|
return ast->NumEntries > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
CodeParam& CodeParam::operator ++()
|
CodeParam& CodeParam::operator ++()
|
||||||
{
|
{
|
||||||
ast = ast->Next.ast;
|
ast = ast->Next.ast;
|
||||||
return * this;
|
return * this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
void CodeStruct::add_interface( CodeType type )
|
void CodeStruct::add_interface( CodeType type )
|
||||||
{
|
{
|
||||||
CodeType possible_slot = ast->ParentType;
|
CodeType possible_slot = ast->ParentType;
|
||||||
@ -164,7 +152,6 @@ void CodeStruct::add_interface( CodeType type )
|
|||||||
possible_slot.ast = type.ast;
|
possible_slot.ast = type.ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
CodeBody def_body( CodeT type )
|
CodeBody def_body( CodeT type )
|
||||||
{
|
{
|
||||||
switch ( type )
|
switch ( type )
|
||||||
@ -192,7 +179,6 @@ CodeBody def_body( CodeT type )
|
|||||||
return (CodeBody)result;
|
return (CodeBody)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
StrC token_fmt_impl( sw num, ... )
|
StrC token_fmt_impl( sw num, ... )
|
||||||
{
|
{
|
||||||
local_persist thread_local
|
local_persist thread_local
|
||||||
|
@ -374,7 +374,7 @@ AllocatorInfo get_string_allocator( s32 str_length )
|
|||||||
|
|
||||||
uw size_req = str_length + sizeof(String::Header) + sizeof(char*);
|
uw size_req = str_length + sizeof(String::Header) + sizeof(char*);
|
||||||
|
|
||||||
if ( last->TotalUsed + sw(size_req) > last->TotalSize )
|
if ( last->TotalUsed + size_req > last->TotalSize )
|
||||||
{
|
{
|
||||||
Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
||||||
|
|
||||||
|
@ -1202,26 +1202,6 @@ TokArray lex( StrC content )
|
|||||||
move_forward();
|
move_forward();
|
||||||
token.Length++;
|
token.Length++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle number literal suffixes in a botched way
|
|
||||||
if (left && (
|
|
||||||
current == 'l' || current == 'L' || // long/long long
|
|
||||||
current == 'u' || current == 'U' || // unsigned
|
|
||||||
current == 'f' || current == 'F' || // float
|
|
||||||
current == 'i' || current == 'I' || // imaginary
|
|
||||||
current == 'z' || current == 'Z')) // complex
|
|
||||||
{
|
|
||||||
char prev = current;
|
|
||||||
move_forward();
|
|
||||||
token.Length++;
|
|
||||||
|
|
||||||
// Handle 'll'/'LL' as a special case when we just processed an 'l'/'L'
|
|
||||||
if (left && (prev == 'l' || prev == 'L') && (current == 'l' || current == 'L'))
|
|
||||||
{
|
|
||||||
move_forward();
|
|
||||||
token.Length++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
goto FoundToken;
|
goto FoundToken;
|
||||||
|
@ -481,7 +481,7 @@ Code parse_array_decl()
|
|||||||
|
|
||||||
if ( check( TokType::Operator ) && currtok.Text[0] == '[' && currtok.Text[1] == ']' )
|
if ( check( TokType::Operator ) && currtok.Text[0] == '[' && currtok.Text[1] == ']' )
|
||||||
{
|
{
|
||||||
Code array_expr = untyped_str( currtok );
|
Code array_expr = untyped_str( get_cached_string(txt(" ")) );
|
||||||
eat( TokType::Operator );
|
eat( TokType::Operator );
|
||||||
// []
|
// []
|
||||||
|
|
||||||
@ -554,6 +554,44 @@ Code parse_array_decl()
|
|||||||
return { nullptr };
|
return { nullptr };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal inline
|
||||||
|
Code parse_assignment_expression()
|
||||||
|
{
|
||||||
|
Code expr = { nullptr };
|
||||||
|
|
||||||
|
eat( TokType::Operator );
|
||||||
|
// <Attributes> <Specifiers> <ValueType> <Name> =
|
||||||
|
|
||||||
|
Token expr_tok = currtok;
|
||||||
|
|
||||||
|
if ( currtok.Type == TokType::Statement_End && currtok.Type != TokType::Comma )
|
||||||
|
{
|
||||||
|
log_failure( "Expected expression after assignment operator\n%s", Context.to_string() );
|
||||||
|
Context.pop();
|
||||||
|
return CodeInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 level = 0;
|
||||||
|
while ( left && currtok.Type != TokType::Statement_End && (currtok.Type != TokType::Comma || level > 0) )
|
||||||
|
{
|
||||||
|
if (currtok.Type == TokType::BraceCurly_Open )
|
||||||
|
level++;
|
||||||
|
if (currtok.Type == TokType::BraceCurly_Close )
|
||||||
|
level--;
|
||||||
|
if (currtok.Type == TokType::Capture_Start)
|
||||||
|
level++;
|
||||||
|
else if (currtok.Type == TokType::Capture_End)
|
||||||
|
level--;
|
||||||
|
|
||||||
|
eat( currtok.Type );
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_tok.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )expr_tok.Text - 1;
|
||||||
|
expr = untyped_str( expr_tok );
|
||||||
|
// = <Expression>
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
internal inline
|
internal inline
|
||||||
CodeAttributes parse_attributes()
|
CodeAttributes parse_attributes()
|
||||||
{
|
{
|
||||||
@ -1311,14 +1349,17 @@ CodeDefine parse_define()
|
|||||||
eat( TokType::Identifier );
|
eat( TokType::Identifier );
|
||||||
// #define <Name>
|
// #define <Name>
|
||||||
|
|
||||||
|
// Defines don't necessarily need content.
|
||||||
|
#if 0
|
||||||
if ( ! check( TokType::Preprocess_Content ))
|
if ( ! check( TokType::Preprocess_Content ))
|
||||||
{
|
{
|
||||||
log_failure( "Error, expected content after #define %s\n%s", define->Name, Context.to_string() );
|
log_failure( "Error, expected content after #define %s\n%s", define->Name, Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return CodeInvalid;
|
return CodeInvalid;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( currtok.Length == 0 )
|
if ( check(TokType::Preprocess_Content) && currtok.Length != 0 )
|
||||||
{
|
{
|
||||||
define->Content = get_cached_string( currtok );
|
define->Content = get_cached_string( currtok );
|
||||||
eat( TokType::Preprocess_Content );
|
eat( TokType::Preprocess_Content );
|
||||||
@ -1336,44 +1377,6 @@ CodeDefine parse_define()
|
|||||||
return define;
|
return define;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline
|
|
||||||
Code parse_assignment_expression()
|
|
||||||
{
|
|
||||||
Code expr = { nullptr };
|
|
||||||
|
|
||||||
eat( TokType::Operator );
|
|
||||||
// <Attributes> <Specifiers> <ValueType> <Name> =
|
|
||||||
|
|
||||||
Token expr_tok = currtok;
|
|
||||||
|
|
||||||
if ( currtok.Type == TokType::Statement_End && currtok.Type != TokType::Comma )
|
|
||||||
{
|
|
||||||
log_failure( "Expected expression after assignment operator\n%s", Context.to_string() );
|
|
||||||
Context.pop();
|
|
||||||
return CodeInvalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 level = 0;
|
|
||||||
while ( left && currtok.Type != TokType::Statement_End && (currtok.Type != TokType::Comma || level > 0) )
|
|
||||||
{
|
|
||||||
if (currtok.Type == TokType::BraceCurly_Open )
|
|
||||||
level++;
|
|
||||||
if (currtok.Type == TokType::BraceCurly_Close )
|
|
||||||
level--;
|
|
||||||
if (currtok.Type == TokType::Capture_Start)
|
|
||||||
level++;
|
|
||||||
else if (currtok.Type == TokType::Capture_End)
|
|
||||||
level--;
|
|
||||||
|
|
||||||
eat( currtok.Type );
|
|
||||||
}
|
|
||||||
|
|
||||||
expr_tok.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )expr_tok.Text - 1;
|
|
||||||
expr = untyped_str( expr_tok );
|
|
||||||
// = <Expression>
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal inline
|
internal inline
|
||||||
Code parse_forward_or_definition( TokType which, bool is_inplace )
|
Code parse_forward_or_definition( TokType which, bool is_inplace )
|
||||||
{
|
{
|
||||||
@ -1404,6 +1407,8 @@ Code parse_forward_or_definition( TokType which, bool is_inplace )
|
|||||||
|
|
||||||
return CodeInvalid;
|
return CodeInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CodeInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function parsing is handled in multiple places because its initial signature is shared with variable parsing
|
// Function parsing is handled in multiple places because its initial signature is shared with variable parsing
|
||||||
@ -1750,6 +1755,7 @@ CodeBody parse_global_nspace( CodeT which )
|
|||||||
case TokType::Spec_Internal_Linkage:
|
case TokType::Spec_Internal_Linkage:
|
||||||
case TokType::Spec_NeverInline:
|
case TokType::Spec_NeverInline:
|
||||||
case TokType::Spec_Static:
|
case TokType::Spec_Static:
|
||||||
|
case TokType::Spec_ThreadLocal:
|
||||||
{
|
{
|
||||||
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
|
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
|
||||||
s32 NumSpecifiers = 0;
|
s32 NumSpecifiers = 0;
|
||||||
@ -1773,6 +1779,7 @@ CodeBody parse_global_nspace( CodeT which )
|
|||||||
case ESpecifier::NeverInline:
|
case ESpecifier::NeverInline:
|
||||||
case ESpecifier::Static:
|
case ESpecifier::Static:
|
||||||
case ESpecifier::Volatile:
|
case ESpecifier::Volatile:
|
||||||
|
case ESpecifier::Thread_Local:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESpecifier::Consteval:
|
case ESpecifier::Consteval:
|
||||||
@ -1850,7 +1857,7 @@ CodeBody parse_global_nspace( CodeT which )
|
|||||||
|
|
||||||
if ( found_operator_cast_outside_class_implmentation )
|
if ( found_operator_cast_outside_class_implmentation )
|
||||||
{
|
{
|
||||||
member = parse_operator_cast( specifiers );
|
member = parse_operator_cast();
|
||||||
// <Attributes> <Specifiers> <Name>::operator <Type>() { ... }
|
// <Attributes> <Specifiers> <Name>::operator <Type>() { ... }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2293,7 +2300,7 @@ CodeOperator parse_operator_after_ret_type(
|
|||||||
case '<':
|
case '<':
|
||||||
{
|
{
|
||||||
if ( currtok.Text[1] == '=' )
|
if ( currtok.Text[1] == '=' )
|
||||||
op = LEqual;
|
op = LesserEqual;
|
||||||
|
|
||||||
else if ( currtok.Text[1] == '<' )
|
else if ( currtok.Text[1] == '<' )
|
||||||
{
|
{
|
||||||
@ -2533,14 +2540,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|||||||
Token name = parse_identifier();
|
Token name = parse_identifier();
|
||||||
Context.Scope->Name = name;
|
Context.Scope->Name = name;
|
||||||
|
|
||||||
bool detected_capture = check( TokType::Capture_Start );
|
if ( check( TokType::Capture_Start) )
|
||||||
|
|
||||||
// Check three tokens ahead to make sure that were not dealing with a constructor initialization...
|
|
||||||
// ( 350.0f , <--- Could be the scenario
|
|
||||||
// Example : <Capture_Start> <Value> <Comma>
|
|
||||||
// idx +1 +2
|
|
||||||
bool detected_comma = Context.Tokens.Arr[ Context.Tokens.Idx + 2 ].Type == TokType::Comma;
|
|
||||||
if ( detected_capture && ! detected_comma )
|
|
||||||
{
|
{
|
||||||
// Dealing with a function
|
// Dealing with a function
|
||||||
result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name );
|
result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name );
|
||||||
@ -2625,11 +2625,10 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
return { nullptr };
|
return { nullptr };
|
||||||
}
|
}
|
||||||
|
|
||||||
Code macro = { nullptr };
|
Code macro = { nullptr };
|
||||||
CodeType type = { nullptr };
|
CodeType type = { nullptr };
|
||||||
Code value = { nullptr };
|
Code value = { nullptr };
|
||||||
Token name = NullToken;
|
Token name = NullToken;
|
||||||
Code post_name_macro = { nullptr };
|
|
||||||
|
|
||||||
if ( check( TokType::Varadic_Argument ) )
|
if ( check( TokType::Varadic_Argument ) )
|
||||||
{
|
{
|
||||||
@ -2671,15 +2670,6 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
// ( <Macro> <ValueType> <Name>
|
// ( <Macro> <ValueType> <Name>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unreal has yet another type of macro:
|
|
||||||
// template<class T UE_REQUIRES(TPointerIsConvertibleFromTo<T, UInterface>::Value)>
|
|
||||||
// class T ... and then ^this^ UE_REQUIRES shows up
|
|
||||||
// So we need to consume that.
|
|
||||||
if ( check( TokType::Preprocess_Macro ))
|
|
||||||
{
|
|
||||||
post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro );
|
|
||||||
}
|
|
||||||
|
|
||||||
// In template captures you can have a typename have direct assignment without a name
|
// In template captures you can have a typename have direct assignment without a name
|
||||||
// typename = typename ...
|
// typename = typename ...
|
||||||
// Which would result in a static value type from a struct expansion (traditionally)
|
// Which would result in a static value type from a struct expansion (traditionally)
|
||||||
@ -2699,7 +2689,7 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
|
|
||||||
s32 capture_level = 0;
|
s32 capture_level = 0;
|
||||||
s32 template_level = 0;
|
s32 template_level = 0;
|
||||||
while ( (left && ( currtok.Type != TokType::Comma ) && template_level >= 0 && CheckEndParams()) || (capture_level > 0 || template_level > 0) )
|
while ( left && (currtok.Type != TokType::Comma) && template_level >= 0 && (CheckEndParams() || capture_level > 0 || template_level > 0) )
|
||||||
{
|
{
|
||||||
if (currtok.Text[ 0 ] == '<')
|
if (currtok.Text[ 0 ] == '<')
|
||||||
++ template_level;
|
++ template_level;
|
||||||
@ -2783,15 +2773,6 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name>
|
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unreal has yet another type of macro:
|
|
||||||
// template<class T UE_REQUIRES(TPointerIsConvertibleFromTo<T, UInterface>::Value)>
|
|
||||||
// class T ... and then ^this^ UE_REQUIRES shows up
|
|
||||||
// So we need to consume that.
|
|
||||||
if ( check( TokType::Preprocess_Macro ))
|
|
||||||
{
|
|
||||||
post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro );
|
|
||||||
}
|
|
||||||
|
|
||||||
// In template captures you can have a typename have direct assignment without a name
|
// In template captures you can have a typename have direct assignment without a name
|
||||||
// typename = typename ...
|
// typename = typename ...
|
||||||
// Which would result in a static value type from a struct expansion (traditionally)
|
// Which would result in a static value type from a struct expansion (traditionally)
|
||||||
@ -2811,10 +2792,10 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
|
|
||||||
s32 capture_level = 0;
|
s32 capture_level = 0;
|
||||||
s32 template_level = 0;
|
s32 template_level = 0;
|
||||||
while ( (left
|
while ( left
|
||||||
&& currtok.Type != TokType::Comma
|
&& currtok.Type != TokType::Comma
|
||||||
&& template_level >= 0
|
&& template_level >= 0
|
||||||
&& CheckEndParams()) || (capture_level > 0 || template_level > 0) )
|
&& (CheckEndParams() || capture_level > 0 || template_level > 0) )
|
||||||
{
|
{
|
||||||
if (currtok.Text[ 0 ] == '<')
|
if (currtok.Text[ 0 ] == '<')
|
||||||
++ template_level;
|
++ template_level;
|
||||||
@ -2848,8 +2829,7 @@ CodeParam parse_params( bool use_template_capture )
|
|||||||
if ( name.Length > 0 )
|
if ( name.Length > 0 )
|
||||||
param->Name = get_cached_string( name );
|
param->Name = get_cached_string( name );
|
||||||
|
|
||||||
param->PostNameMacro = post_name_macro;
|
param->ValueType = type;
|
||||||
param->ValueType = type;
|
|
||||||
|
|
||||||
if ( value )
|
if ( value )
|
||||||
param->Value = value;
|
param->Value = value;
|
||||||
@ -2892,7 +2872,7 @@ CodePreprocessCond parse_preprocess_cond()
|
|||||||
|
|
||||||
CodePreprocessCond
|
CodePreprocessCond
|
||||||
cond = (CodePreprocessCond) make_code();
|
cond = (CodePreprocessCond) make_code();
|
||||||
cond->Type = scast(CodeT, currtok.Type - ( TokType::Preprocess_If - ECode::Preprocess_If ) );
|
cond->Type = scast(CodeT, currtok.Type - (s32(ETokType::Preprocess_If) - s32(ECode::Preprocess_If)) );
|
||||||
eat( currtok.Type );
|
eat( currtok.Type );
|
||||||
// #<Conditional>
|
// #<Conditional>
|
||||||
|
|
||||||
@ -3087,8 +3067,6 @@ CodeVar parse_variable_after_name(
|
|||||||
Code expr = { nullptr };
|
Code expr = { nullptr };
|
||||||
Code bitfield_expr = { nullptr };
|
Code bitfield_expr = { nullptr };
|
||||||
|
|
||||||
b32 using_constructor_initializer = false;
|
|
||||||
|
|
||||||
if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) )
|
if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) )
|
||||||
{
|
{
|
||||||
// <Attributes> <Specifiers> <ValueType> <Name> = <Expression>
|
// <Attributes> <Specifiers> <ValueType> <Name> = <Expression>
|
||||||
@ -3120,33 +3098,6 @@ CodeVar parse_variable_after_name(
|
|||||||
// <Attributes> <Specifiers> <ValueType> <Name> = { <Expression> }
|
// <Attributes> <Specifiers> <ValueType> <Name> = { <Expression> }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( currtok.Type == TokType::Capture_Start )
|
|
||||||
{
|
|
||||||
eat( TokType:: Capture_Start);
|
|
||||||
// <Attributes> <Specifiers> <ValueType> <Name> (
|
|
||||||
|
|
||||||
Token expr_token = currtok;
|
|
||||||
|
|
||||||
using_constructor_initializer = true;
|
|
||||||
|
|
||||||
s32 level = 0;
|
|
||||||
while ( left && ( currtok.Type != TokType::Capture_End || level > 0 ) )
|
|
||||||
{
|
|
||||||
if ( currtok.Type == TokType::Capture_Start )
|
|
||||||
level++;
|
|
||||||
|
|
||||||
else if ( currtok.Type == TokType::Capture_End && level > 0 )
|
|
||||||
level--;
|
|
||||||
|
|
||||||
eat( currtok.Type );
|
|
||||||
}
|
|
||||||
|
|
||||||
expr_token.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)expr_token.Text;
|
|
||||||
expr = untyped_str( expr_token );
|
|
||||||
eat( TokType::Capture_End );
|
|
||||||
// <Attributes> <Specifiers> <ValueType> <Name> ( <Expression> )
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( currtok.Type == TokType::Assign_Classifer )
|
if ( currtok.Type == TokType::Assign_Classifer )
|
||||||
{
|
{
|
||||||
eat( TokType::Assign_Classifer );
|
eat( TokType::Assign_Classifer );
|
||||||
@ -3241,8 +3192,6 @@ CodeVar parse_variable_after_name(
|
|||||||
result->NextVar->Parent = result;
|
result->NextVar->Parent = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result->VarConstructorInit = using_constructor_initializer;
|
|
||||||
|
|
||||||
Context.pop();
|
Context.pop();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -3297,7 +3246,7 @@ CodeVar parse_variable_declaration_list()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eat(currtok.Type);
|
eat(currtok.Type);
|
||||||
|
|
||||||
if ( specifiers )
|
if ( specifiers )
|
||||||
specifiers.append( spec );
|
specifiers.append( spec );
|
||||||
@ -3701,11 +3650,11 @@ CodeEnum parse_enum( bool inplace_def )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Consume inline comments
|
// Consume inline comments
|
||||||
// if ( currtok.Type == TokType::Comment && prevtok.Line == currtok.Line )
|
if ( currtok.Type == TokType::Comment && prevtok.Line == currtok.Line )
|
||||||
// {
|
{
|
||||||
// eat( TokType::Comment );
|
eat( TokType::Comment );
|
||||||
// <Name> = <Expression> <Macro>, // <Inline Comment>
|
// <Name> = <Expression> <Macro>, // <Inline Comment>
|
||||||
// }
|
}
|
||||||
|
|
||||||
entry.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)entry.Text;
|
entry.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)entry.Text;
|
||||||
|
|
||||||
@ -4080,6 +4029,8 @@ CodeOpCast parse_operator_cast( CodeSpecifiers specifiers )
|
|||||||
{
|
{
|
||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
|
// TODO : Specifiers attributed to the cast
|
||||||
|
|
||||||
// Operator's namespace if not within same class.
|
// Operator's namespace if not within same class.
|
||||||
Token name = NullToken;
|
Token name = NullToken;
|
||||||
if ( check( TokType::Identifier ) )
|
if ( check( TokType::Identifier ) )
|
||||||
@ -4448,10 +4399,13 @@ CodeType parse_type( bool from_template, bool* typedef_is_function )
|
|||||||
else if ( currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Struct
|
else if ( currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Struct
|
||||||
|| currtok.Type == TokType::Decl_Union )
|
|| currtok.Type == TokType::Decl_Union )
|
||||||
{
|
{
|
||||||
|
Token fwd_key = currtok;
|
||||||
eat( currtok.Type );
|
eat( currtok.Type );
|
||||||
// <Attributes> <Specifiers> <class, enum, struct, union>
|
// <Attributes> <Specifiers> <class, enum, struct, union>
|
||||||
|
|
||||||
name = parse_identifier();
|
name = parse_identifier();
|
||||||
|
fwd_key.Length = sptr(name.Text + name.Length) - sptr(fwd_key.Text);
|
||||||
|
name = fwd_key;
|
||||||
|
|
||||||
// name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text;
|
// name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text;
|
||||||
// eat( TokType::Identifier );
|
// eat( TokType::Identifier );
|
||||||
@ -4508,18 +4462,6 @@ else if ( currtok.Type == TokType::DeclType )
|
|||||||
name = currtok;
|
name = currtok;
|
||||||
eat(TokType::Type_Typename);
|
eat(TokType::Type_Typename);
|
||||||
// <typename>
|
// <typename>
|
||||||
|
|
||||||
if ( ! from_template )
|
|
||||||
{
|
|
||||||
name = parse_identifier();
|
|
||||||
Context.Scope->Name = name;
|
|
||||||
if ( ! name )
|
|
||||||
{
|
|
||||||
log_failure( "Error, failed to type signature\n%s", Context.to_string() );
|
|
||||||
Context.pop();
|
|
||||||
return CodeInvalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The usual Identifier type signature that may have namespace qualifiers
|
// The usual Identifier type signature that may have namespace qualifiers
|
||||||
|
@ -9,3 +9,4 @@
|
|||||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
||||||
# include "gen.dep.cpp"
|
# include "gen.dep.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -71,7 +71,6 @@ enum class ModuleFlag : u32
|
|||||||
Invalid,
|
Invalid,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
|
||||||
StrC to_str( ModuleFlag flag )
|
StrC to_str( ModuleFlag flag )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
@ -87,7 +86,6 @@ StrC to_str( ModuleFlag flag )
|
|||||||
return lookup[ (u32)flag ];
|
return lookup[ (u32)flag ];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
|
||||||
ModuleFlag operator|( ModuleFlag A, ModuleFlag B)
|
ModuleFlag operator|( ModuleFlag A, ModuleFlag B)
|
||||||
{
|
{
|
||||||
return (ModuleFlag)( (u32)A | (u32)B );
|
return (ModuleFlag)( (u32)A | (u32)B );
|
||||||
|
@ -50,11 +50,6 @@ struct Array
|
|||||||
return 2 * value + 8;
|
return 2 * value + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append( Array other )
|
|
||||||
{
|
|
||||||
return append( other, other.num() );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool append( Type value )
|
bool append( Type value )
|
||||||
{
|
{
|
||||||
Header* header = get_header();
|
Header* header = get_header();
|
||||||
@ -163,7 +158,7 @@ struct Array
|
|||||||
if ( begin < 0 || end > header.Num )
|
if ( begin < 0 || end > header.Num )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for ( sw idx = sw(begin); idx < sw(end); idx++ )
|
for ( sw idx = begin; idx < end; idx++ )
|
||||||
{
|
{
|
||||||
Data[ idx ] = value;
|
Data[ idx ] = value;
|
||||||
}
|
}
|
||||||
@ -370,7 +365,7 @@ struct HashTable
|
|||||||
{
|
{
|
||||||
GEN_ASSERT_NOT_NULL( map_proc );
|
GEN_ASSERT_NOT_NULL( map_proc );
|
||||||
|
|
||||||
for ( sw idx = 0; idx < sw(Entries.num()); ++idx )
|
for ( sw idx = 0; idx < Entries.num(); idx++ )
|
||||||
{
|
{
|
||||||
map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
|
map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
|
||||||
}
|
}
|
||||||
@ -382,7 +377,7 @@ struct HashTable
|
|||||||
{
|
{
|
||||||
GEN_ASSERT_NOT_NULL( map_proc );
|
GEN_ASSERT_NOT_NULL( map_proc );
|
||||||
|
|
||||||
for ( sw idx = 0; idx < sw(Entries.num()); ++idx )
|
for ( sw idx = 0; idx < Entries.num(); idx++ )
|
||||||
{
|
{
|
||||||
map_proc( Entries[ idx ].Key, & Entries[ idx ].Value );
|
map_proc( Entries[ idx ].Key, & Entries[ idx ].Value );
|
||||||
}
|
}
|
||||||
@ -399,7 +394,7 @@ struct HashTable
|
|||||||
sw last_added_index;
|
sw last_added_index;
|
||||||
|
|
||||||
HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
|
HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
|
||||||
for ( sw idx = 0; idx < sw(Entries.num()); ++idx )
|
for ( sw idx = 0; idx < Entries.num(); ++idx )
|
||||||
{
|
{
|
||||||
FindResult find_result;
|
FindResult find_result;
|
||||||
|
|
||||||
@ -424,13 +419,13 @@ struct HashTable
|
|||||||
{
|
{
|
||||||
sw idx;
|
sw idx;
|
||||||
|
|
||||||
for ( idx = 0; idx < sw(Entries.num()); idx++ )
|
for ( idx = 0; idx < Entries.num(); idx++ )
|
||||||
Entries[ idx ].Next = -1;
|
Entries[ idx ].Next = -1;
|
||||||
|
|
||||||
for ( idx = 0; idx < sw(Hashes.num()); idx++ )
|
for ( idx = 0; idx < Hashes.num(); idx++ )
|
||||||
Hashes[ idx ] = -1;
|
Hashes[ idx ] = -1;
|
||||||
|
|
||||||
for ( idx = 0; idx < sw(Entries.num()); idx++ )
|
for ( idx = 0; idx < Entries.num(); idx++ )
|
||||||
{
|
{
|
||||||
Entry* entry;
|
Entry* entry;
|
||||||
FindResult find_result;
|
FindResult find_result;
|
||||||
@ -496,7 +491,7 @@ struct HashTable
|
|||||||
|
|
||||||
sw slot( u64 key )
|
sw slot( u64 key )
|
||||||
{
|
{
|
||||||
for ( sw idx = 0; idx < sw(Hashes.num()); ++idx )
|
for ( sw idx = 0; idx < Hashes.num(); ++idx )
|
||||||
if ( Hashes[ idx ] == key )
|
if ( Hashes[ idx ] == key )
|
||||||
return idx;
|
return idx;
|
||||||
|
|
||||||
|
@ -594,7 +594,7 @@ internal GEN_FILE_WRITE_AT_PROC( _memory_file_write )
|
|||||||
{
|
{
|
||||||
Array<u8> arr = { d->buf };
|
Array<u8> arr = { d->buf };
|
||||||
|
|
||||||
if ( arr.get_header()->Capacity < uw(new_cap) )
|
if ( arr.get_header()->Capacity < new_cap )
|
||||||
{
|
{
|
||||||
if ( ! arr.grow( ( s64 )( new_cap ) ) )
|
if ( ! arr.grow( ( s64 )( new_cap ) ) )
|
||||||
return false;
|
return false;
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#define internal static // Internal linkage
|
#define internal static // Internal linkage
|
||||||
#define local_persist static // Local Persisting variables
|
#define local_persist static // Local Persisting variables
|
||||||
|
|
||||||
#pragma region ForceInline Definition
|
|
||||||
#ifdef GEN_COMPILER_MSVC
|
#ifdef GEN_COMPILER_MSVC
|
||||||
# define forceinline __forceinline
|
# define forceinline __forceinline
|
||||||
# define neverinline __declspec( noinline )
|
# define neverinline __declspec( noinline )
|
||||||
@ -32,23 +31,18 @@
|
|||||||
# define forceinline
|
# define forceinline
|
||||||
# define neverinline
|
# define neverinline
|
||||||
#endif
|
#endif
|
||||||
#pragma endregion ForceInline Definition
|
|
||||||
|
|
||||||
// Bits
|
// Bits
|
||||||
|
|
||||||
#ifndef bit
|
|
||||||
#define bit( Value ) ( 1 << Value )
|
#define bit( Value ) ( 1 << Value )
|
||||||
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
|
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
|
||||||
#endif
|
|
||||||
|
|
||||||
// Casting
|
// Casting
|
||||||
|
|
||||||
#ifndef ccast
|
|
||||||
#define ccast( Type, Value ) ( * const_cast< Type* >( & (Value) ) )
|
#define ccast( Type, Value ) ( * const_cast< Type* >( & (Value) ) )
|
||||||
#define pcast( Type, Value ) ( * reinterpret_cast< Type* >( & ( Value ) ) )
|
#define pcast( Type, Value ) ( * reinterpret_cast< Type* >( & ( Value ) ) )
|
||||||
#define rcast( Type, Value ) reinterpret_cast< Type >( Value )
|
#define rcast( Type, Value ) reinterpret_cast< Type >( Value )
|
||||||
#define scast( Type, Value ) static_cast< Type >( Value )
|
#define scast( Type, Value ) static_cast< Type >( Value )
|
||||||
#endif
|
|
||||||
|
|
||||||
// Num Arguments (Varadics)
|
// Num Arguments (Varadics)
|
||||||
// #if defined(__GNUC__) || defined(__clang__)
|
// #if defined(__GNUC__) || defined(__clang__)
|
||||||
|
@ -445,14 +445,10 @@ struct Arena
|
|||||||
return alignment_offset;
|
return alignment_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This id is defined by Unreal for asserts
|
|
||||||
#pragma push_macro("check")
|
|
||||||
#undef check
|
|
||||||
void check()
|
void check()
|
||||||
{
|
{
|
||||||
GEN_ASSERT( TempCount == 0 );
|
GEN_ASSERT( TempCount == 0 );
|
||||||
}
|
}
|
||||||
#pragma pop_macro("check")
|
|
||||||
|
|
||||||
void free()
|
void free()
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ u8 adt_destroy_branch( ADT_Node* node )
|
|||||||
GEN_ASSERT_NOT_NULL( node );
|
GEN_ASSERT_NOT_NULL( node );
|
||||||
if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes )
|
if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes )
|
||||||
{
|
{
|
||||||
for ( sw i = 0; i < scast(sw, node->nodes.num()); ++i )
|
for ( sw i = 0; i < node->nodes.num(); ++i )
|
||||||
{
|
{
|
||||||
adt_destroy_branch( node->nodes + i );
|
adt_destroy_branch( node->nodes + i );
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
|
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||||
{
|
{
|
||||||
if ( ! str_compare( node->nodes[ i ].name, name ) )
|
if ( ! str_compare( node->nodes[ i ].name, name ) )
|
||||||
{
|
{
|
||||||
@ -76,7 +76,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
|
|||||||
|
|
||||||
if ( deep_search )
|
if ( deep_search )
|
||||||
{
|
{
|
||||||
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
|
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||||
{
|
{
|
||||||
ADT_Node* res = adt_find( node->nodes + i, name, deep_search );
|
ADT_Node* res = adt_find( node->nodes + i, name, deep_search );
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
|
|||||||
|
|
||||||
internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value )
|
internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value )
|
||||||
{
|
{
|
||||||
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
|
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||||
{
|
{
|
||||||
if ( ! str_compare( node->nodes[ i ].name, name ) )
|
if ( ! str_compare( node->nodes[ i ].name, name ) )
|
||||||
{
|
{
|
||||||
@ -207,7 +207,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
|
|||||||
/* run a value comparison against any child that is an object node */
|
/* run a value comparison against any child that is an object node */
|
||||||
else if ( node->type == EADT_TYPE_ARRAY )
|
else if ( node->type == EADT_TYPE_ARRAY )
|
||||||
{
|
{
|
||||||
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
|
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||||
{
|
{
|
||||||
ADT_Node* child = &node->nodes[ i ];
|
ADT_Node* child = &node->nodes[ i ];
|
||||||
if ( child->type != EADT_TYPE_OBJECT )
|
if ( child->type != EADT_TYPE_OBJECT )
|
||||||
@ -225,7 +225,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
|
|||||||
/* [value] */
|
/* [value] */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
|
for ( sw i = 0; i < node->nodes.num(); i++ )
|
||||||
{
|
{
|
||||||
ADT_Node* child = &node->nodes[ i ];
|
ADT_Node* child = &node->nodes[ i ];
|
||||||
if ( _adt_get_value( child, l_b2 ) )
|
if ( _adt_get_value( child, l_b2 ) )
|
||||||
@ -257,7 +257,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sw idx = ( sw )str_to_i64( buf, NULL, 10 );
|
sw idx = ( sw )str_to_i64( buf, NULL, 10 );
|
||||||
if ( idx >= 0 && idx < scast(sw, node->nodes.num()) )
|
if ( idx >= 0 && idx < node->nodes.num() )
|
||||||
{
|
{
|
||||||
found_node = &node->nodes[ idx ];
|
found_node = &node->nodes[ idx ];
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, sw index )
|
|||||||
if ( ! parent->nodes )
|
if ( ! parent->nodes )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ( index < 0 || index > scast(sw, parent->nodes.num()) )
|
if ( index < 0 || index > parent->nodes.num() )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ADT_Node o = { 0 };
|
ADT_Node o = { 0 };
|
||||||
@ -946,7 +946,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( columnIndex >= scast(sw, root->nodes.num()) )
|
if ( columnIndex >= root->nodes.num() )
|
||||||
{
|
{
|
||||||
adt_append_arr( root, NULL );
|
adt_append_arr( root, NULL );
|
||||||
}
|
}
|
||||||
@ -989,7 +989,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
|
|||||||
/* consider first row as a header. */
|
/* consider first row as a header. */
|
||||||
if ( has_header )
|
if ( has_header )
|
||||||
{
|
{
|
||||||
for ( sw i = 0; i < scast(sw, root->nodes.num()); i++ )
|
for ( sw i = 0; i < root->nodes.num(); i++ )
|
||||||
{
|
{
|
||||||
CSV_Object* col = root->nodes + i;
|
CSV_Object* col = root->nodes + i;
|
||||||
CSV_Object* hdr = col->nodes;
|
CSV_Object* hdr = col->nodes;
|
||||||
|
@ -124,7 +124,7 @@ bool String::make_space_for( char const* str, sw add_len )
|
|||||||
|
|
||||||
Data = rcast( char*, header + 1 );
|
Data = rcast( char*, header + 1 );
|
||||||
|
|
||||||
return true;
|
return str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma endregion String
|
#pragma endregion String
|
||||||
|
@ -18,7 +18,6 @@ struct StrC
|
|||||||
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(sw) )
|
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(sw) )
|
||||||
#define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
|
#define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
|
||||||
|
|
||||||
inline
|
|
||||||
StrC to_str( char const* str )
|
StrC to_str( char const* str )
|
||||||
{
|
{
|
||||||
return { str_len( str ), str };
|
return { str_len( str ), str };
|
||||||
@ -140,7 +139,7 @@ struct String
|
|||||||
|
|
||||||
header.Length = curr_len + length;
|
header.Length = curr_len + length;
|
||||||
}
|
}
|
||||||
return str != nullptr;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool append( StrC str)
|
bool append( StrC str)
|
||||||
@ -354,7 +353,7 @@ struct String
|
|||||||
|
|
||||||
operator bool()
|
operator bool()
|
||||||
{
|
{
|
||||||
return Data != nullptr;
|
return Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator char* ()
|
operator char* ()
|
||||||
|
@ -35,7 +35,6 @@ CodeBody gen_ecode( char const* path )
|
|||||||
#pragma push_macro("local_persist")
|
#pragma push_macro("local_persist")
|
||||||
#undef local_persist
|
#undef local_persist
|
||||||
CodeFn to_str = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
|
CodeFn to_str = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
|
||||||
inline
|
|
||||||
StrC to_str( Type type )
|
StrC to_str( Type type )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
@ -90,7 +89,6 @@ CodeBody gen_eoperator( char const* path )
|
|||||||
#pragma push_macro("local_persist")
|
#pragma push_macro("local_persist")
|
||||||
#undef local_persist
|
#undef local_persist
|
||||||
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
|
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
|
||||||
inline
|
|
||||||
StrC to_str( Type op )
|
StrC to_str( Type op )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
@ -144,7 +142,6 @@ CodeBody gen_especifier( char const* path )
|
|||||||
)));
|
)));
|
||||||
|
|
||||||
CodeFn is_trailing = parse_function(token_fmt("specifier", (StrC)to_str_entries, stringize(
|
CodeFn is_trailing = parse_function(token_fmt("specifier", (StrC)to_str_entries, stringize(
|
||||||
inline
|
|
||||||
bool is_trailing( Type specifier )
|
bool is_trailing( Type specifier )
|
||||||
{
|
{
|
||||||
return specifier > Virtual;
|
return specifier > Virtual;
|
||||||
@ -162,7 +159,6 @@ CodeBody gen_especifier( char const* path )
|
|||||||
#undef forceinline
|
#undef forceinline
|
||||||
#undef neverinline
|
#undef neverinline
|
||||||
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
|
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
|
||||||
inline
|
|
||||||
StrC to_str( Type type )
|
StrC to_str( Type type )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
@ -175,7 +171,6 @@ CodeBody gen_especifier( char const* path )
|
|||||||
)));
|
)));
|
||||||
|
|
||||||
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
|
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
|
||||||
inline
|
|
||||||
Type to_type( StrC str )
|
Type to_type( StrC str )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
@ -287,7 +282,6 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
|||||||
#undef do_once_start
|
#undef do_once_start
|
||||||
#undef do_once_end
|
#undef do_once_end
|
||||||
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, "attribute_toks", (StrC)to_str_attributes, stringize(
|
CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, "attribute_toks", (StrC)to_str_attributes, stringize(
|
||||||
inline
|
|
||||||
StrC to_str( Type type )
|
StrC to_str( Type type )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
@ -301,7 +295,6 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
|
|||||||
)));
|
)));
|
||||||
|
|
||||||
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
|
CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
|
||||||
inline
|
|
||||||
Type to_type( StrC str )
|
Type to_type( StrC str )
|
||||||
{
|
{
|
||||||
local_persist
|
local_persist
|
||||||
@ -346,7 +339,6 @@ CodeBody gen_ast_inlines()
|
|||||||
#undef log_failure
|
#undef log_failure
|
||||||
char const* code_impl_tmpl = stringize(
|
char const* code_impl_tmpl = stringize(
|
||||||
\n
|
\n
|
||||||
inline
|
|
||||||
char const* <typename>::debug_str()
|
char const* <typename>::debug_str()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if ( ast == nullptr )
|
||||||
@ -354,7 +346,6 @@ CodeBody gen_ast_inlines()
|
|||||||
|
|
||||||
return rcast(AST*, ast)->debug_str();
|
return rcast(AST*, ast)->debug_str();
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
Code <typename>::duplicate()
|
Code <typename>::duplicate()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if ( ast == nullptr )
|
||||||
@ -365,23 +356,19 @@ CodeBody gen_ast_inlines()
|
|||||||
|
|
||||||
return { rcast(AST*, ast)->duplicate() };
|
return { rcast(AST*, ast)->duplicate() };
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
bool <typename>::is_equal( Code other )
|
bool <typename>::is_equal( Code other )
|
||||||
{
|
{
|
||||||
if ( ast == nullptr || other.ast == nullptr )
|
if ( ast == nullptr || other.ast == nullptr )
|
||||||
{
|
{
|
||||||
// Just check if they're both null.
|
// Just check if they're both null.
|
||||||
// log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
|
return rcast(AST*, ast) == other.ast;
|
||||||
return ast == nullptr && other.ast == nullptr;
|
|
||||||
}
|
}
|
||||||
return rcast(AST*, ast)->is_equal( other.ast );
|
return rcast(AST*, ast)->is_equal( other.ast );
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
bool <typename>::is_valid()
|
bool <typename>::is_valid()
|
||||||
{
|
{
|
||||||
return (AST*) ast != nullptr && rcast( AST*, ast)->Type != CodeT::Invalid;
|
return (AST*) ast != nullptr && rcast( AST*, ast)->Type != CodeT::Invalid;
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
void <typename>::set_global()
|
void <typename>::set_global()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if ( ast == nullptr )
|
||||||
@ -392,7 +379,6 @@ CodeBody gen_ast_inlines()
|
|||||||
|
|
||||||
rcast(AST*, ast)->Parent = Code::Global.ast;
|
rcast(AST*, ast)->Parent = Code::Global.ast;
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
<typename>& <typename>::operator =( Code other )
|
<typename>& <typename>::operator =( Code other )
|
||||||
{
|
{
|
||||||
if ( other.ast && other->Parent )
|
if ( other.ast && other->Parent )
|
||||||
@ -404,17 +390,14 @@ CodeBody gen_ast_inlines()
|
|||||||
ast = rcast( decltype(ast), other.ast );
|
ast = rcast( decltype(ast), other.ast );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
bool <typename>::operator ==( Code other )
|
bool <typename>::operator ==( Code other )
|
||||||
{
|
{
|
||||||
return (AST*) ast == other.ast;
|
return (AST*) ast == other.ast;
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
bool <typename>::operator !=( Code other )
|
bool <typename>::operator !=( Code other )
|
||||||
{
|
{
|
||||||
return (AST*) ast != other.ast;
|
return (AST*) ast != other.ast;
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
<typename>::operator bool()
|
<typename>::operator bool()
|
||||||
{
|
{
|
||||||
return ast != nullptr;
|
return ast != nullptr;
|
||||||
@ -422,17 +405,14 @@ CodeBody gen_ast_inlines()
|
|||||||
);
|
);
|
||||||
|
|
||||||
char const* codetype_impl_tmpl = stringize(
|
char const* codetype_impl_tmpl = stringize(
|
||||||
inline
|
|
||||||
AST* Code<typename>::raw()
|
AST* Code<typename>::raw()
|
||||||
{
|
{
|
||||||
return rcast( AST*, ast );
|
return rcast( AST*, ast );
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
Code<typename>::operator Code()
|
Code<typename>::operator Code()
|
||||||
{
|
{
|
||||||
return *rcast( Code*, this );
|
return *rcast( Code*, this );
|
||||||
}
|
}
|
||||||
inline
|
|
||||||
AST_<typename>* Code<typename>::operator->()
|
AST_<typename>* Code<typename>::operator->()
|
||||||
{
|
{
|
||||||
if ( ast == nullptr )
|
if ( ast == nullptr )
|
||||||
@ -500,11 +480,12 @@ CodeBody gen_ast_inlines()
|
|||||||
impl_code_var. append( parse_global_body( token_fmt( "typename", StrC name(Var), codetype_impl_tmpl )));
|
impl_code_var. append( parse_global_body( token_fmt( "typename", StrC name(Var), codetype_impl_tmpl )));
|
||||||
|
|
||||||
char const* cast_tmpl = stringize(
|
char const* cast_tmpl = stringize(
|
||||||
inline AST::operator Code<typename>()
|
AST::operator Code<typename>()
|
||||||
{
|
{
|
||||||
return { rcast( AST_<typename>*, this ) };
|
return { rcast( AST_<typename>*, this ) };
|
||||||
}
|
}
|
||||||
inline Code::operator Code<typename>() const
|
|
||||||
|
Code::operator Code<typename>() const
|
||||||
{
|
{
|
||||||
return { (AST_<typename>*) ast };
|
return { (AST_<typename>*) ast };
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifdef __clang__
|
#if __clang__
|
||||||
# pragma clang diagnostic pop
|
# pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#if __GNUC__
|
||||||
# pragma GCC diagnostic pop
|
# pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifdef __clang__
|
#if __clang__
|
||||||
# pragma clang diagnostic push
|
# pragma clang diagnostic push
|
||||||
# pragma clang diagnostic ignored "-Wunused-const-variable"
|
# pragma clang diagnostic ignored "-Wunused-const-variable"
|
||||||
# pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
# pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
||||||
@ -9,7 +9,7 @@
|
|||||||
# pragma clang diagnostic ignored "-Wunused-function"
|
# pragma clang diagnostic ignored "-Wunused-function"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#if __GNUC__
|
||||||
# pragma GCC diagnostic push
|
# pragma GCC diagnostic push
|
||||||
# pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
# pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||||
# pragma GCC diagnostic ignored "-Wcomment"
|
# pragma GCC diagnostic ignored "-Wcomment"
|
||||||
|
@ -6,7 +6,6 @@ Import-Module ./helpers/target_arch.psm1
|
|||||||
$target_arch = Join-Path $PSScriptRoot 'helpers/target_arch.psm1'
|
$target_arch = Join-Path $PSScriptRoot 'helpers/target_arch.psm1'
|
||||||
$devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1'
|
$devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1'
|
||||||
$format_cpp = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1'
|
$format_cpp = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1'
|
||||||
$refactor_unreal = Join-Path $PSScriptRoot 'refactor_unreal.ps1'
|
|
||||||
$incremental_checks = Join-Path $PSScriptRoot 'helpers/incremental_checks.ps1'
|
$incremental_checks = Join-Path $PSScriptRoot 'helpers/incremental_checks.ps1'
|
||||||
$vendor_toolchain = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1'
|
$vendor_toolchain = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1'
|
||||||
|
|
||||||
@ -23,7 +22,6 @@ Push-Location $path_root
|
|||||||
$verbose = $false
|
$verbose = $false
|
||||||
[bool] $bootstrap = $false
|
[bool] $bootstrap = $false
|
||||||
[bool] $singleheader = $false
|
[bool] $singleheader = $false
|
||||||
[bool] $unreal = $false
|
|
||||||
[bool] $test = $false
|
[bool] $test = $false
|
||||||
|
|
||||||
[array] $vendors = @( "clang", "msvc" )
|
[array] $vendors = @( "clang", "msvc" )
|
||||||
@ -38,7 +36,6 @@ if ( $args ) { $args | ForEach-Object {
|
|||||||
"debug" { $release = $false }
|
"debug" { $release = $false }
|
||||||
"bootstrap" { $bootstrap = $true }
|
"bootstrap" { $bootstrap = $true }
|
||||||
"singleheader" { $singleheader = $true }
|
"singleheader" { $singleheader = $true }
|
||||||
"unreal" { $unreal = $true }
|
|
||||||
"test" { $test = $true }
|
"test" { $test = $true }
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
@ -67,7 +64,7 @@ else {
|
|||||||
$optimize = $true
|
$optimize = $true
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $bootstrap -eq $false -and $singleheader -eq $false -and $unreal -eq $false -and $test -eq $false ) {
|
if ( $bootstrap -eq $false -and $singleheader -eq $false -and $test -eq $false ) {
|
||||||
throw "No build target specified. One must be specified, this script will not assume one"
|
throw "No build target specified. One must be specified, this script will not assume one"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +80,6 @@ $path_build = Join-Path $path_root build
|
|||||||
$path_project = Join-Path $path_root project
|
$path_project = Join-Path $path_root project
|
||||||
$path_scripts = Join-Path $path_root scripts
|
$path_scripts = Join-Path $path_root scripts
|
||||||
$path_singleheader = Join-Path $path_root singleheader
|
$path_singleheader = Join-Path $path_root singleheader
|
||||||
$path_unreal = Join-Path $path_root unreal_engine
|
|
||||||
$path_test = Join-Path $path_root test
|
$path_test = Join-Path $path_root test
|
||||||
|
|
||||||
if ( $bootstrap )
|
if ( $bootstrap )
|
||||||
@ -166,46 +162,6 @@ if ( $singleheader )
|
|||||||
Pop-Location
|
Pop-Location
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $unreal )
|
|
||||||
{
|
|
||||||
$path_build = join-path $path_unreal build
|
|
||||||
$path_gen = join-path $path_unreal gen
|
|
||||||
|
|
||||||
if ( -not(Test-Path($path_build) )) {
|
|
||||||
New-Item -ItemType Directory -Path $path_build
|
|
||||||
}
|
|
||||||
if ( -not(Test-Path($path_gen) )) {
|
|
||||||
New-Item -ItemType Directory -Path $path_gen
|
|
||||||
}
|
|
||||||
|
|
||||||
$includes = @( $path_project )
|
|
||||||
$unit = join-path $path_unreal "unreal.cpp"
|
|
||||||
$executable = join-path $path_build "unreal.exe"
|
|
||||||
|
|
||||||
$compiler_args = @()
|
|
||||||
$compiler_args += ( $flag_define + 'GEN_TIME' )
|
|
||||||
|
|
||||||
$linker_args = @(
|
|
||||||
$flag_link_win_subsystem_console
|
|
||||||
)
|
|
||||||
|
|
||||||
build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
|
||||||
|
|
||||||
Push-Location $path_unreal
|
|
||||||
if ( Test-Path( $executable ) ) {
|
|
||||||
write-host "`nRunning unreal variant generator"
|
|
||||||
$time_taken = Measure-Command { & $executable
|
|
||||||
| ForEach-Object {
|
|
||||||
write-host `t $_ -ForegroundColor Green
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write-host "`n Unreal variant generator completed in $($time_taken.TotalMilliseconds) ms"
|
|
||||||
}
|
|
||||||
Pop-Location
|
|
||||||
|
|
||||||
. $refactor_unreal
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $test )
|
if ( $test )
|
||||||
{
|
{
|
||||||
$path_gen = join-path $path_test gen
|
$path_gen = join-path $path_test gen
|
||||||
@ -273,6 +229,7 @@ push-location $path_scripts
|
|||||||
if ( $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) )
|
if ( $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) )
|
||||||
{
|
{
|
||||||
$path_gen = join-path $path_project gen
|
$path_gen = join-path $path_project gen
|
||||||
|
$path_comp_gen = join-path $path_project components/gen
|
||||||
$include = @(
|
$include = @(
|
||||||
'gen.hpp', 'gen.cpp',
|
'gen.hpp', 'gen.cpp',
|
||||||
'gen.dep.hpp', 'gen.dep.cpp',
|
'gen.dep.hpp', 'gen.dep.cpp',
|
||||||
@ -295,19 +252,6 @@ if ( $singleheader -and (Test-Path (Join-Path $path_singleheader "gen/gen.hpp"))
|
|||||||
format-cpp $path_gen $include $exclude
|
format-cpp $path_gen $include $exclude
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $unreal -and (Test-Path( Join-Path $path_unreal "gen/gen.hpp")) )
|
|
||||||
{
|
|
||||||
$path_gen = join-path $path_unreal gen
|
|
||||||
$include = @(
|
|
||||||
'gen.hpp', 'gen.cpp',
|
|
||||||
'gen.dep.hpp', 'gen.dep.cpp',
|
|
||||||
'gen.builder.hpp', 'gen.builder.cpp'
|
|
||||||
'gen.scanner.hpp', 'gen.scanner.cpp'
|
|
||||||
)
|
|
||||||
$exclude = $null
|
|
||||||
format-cpp $path_gen $include $exclude
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( $test -and $false )
|
if ( $test -and $false )
|
||||||
{
|
{
|
||||||
$path_gen = join-path $path_test gen
|
$path_gen = join-path $path_test gen
|
||||||
|
@ -3,22 +3,20 @@ cls
|
|||||||
$build = Join-Path $PSScriptRoot 'build.ci.ps1'
|
$build = Join-Path $PSScriptRoot 'build.ci.ps1'
|
||||||
|
|
||||||
if ( $IsWindows ) {
|
if ( $IsWindows ) {
|
||||||
& $build release msvc bootstrap singleheader unreal
|
& $build release msvc bootstrap singleheader
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
& $build release clang bootstrap singleheader unreal
|
& $build release clang bootstrap singleheader
|
||||||
}
|
}
|
||||||
|
|
||||||
$path_root = git rev-parse --show-toplevel
|
$path_root = git rev-parse --show-toplevel
|
||||||
$path_docs = Join-Path $path_root docs
|
$path_docs = Join-Path $path_root docs
|
||||||
$path_project = Join-Path $path_root project
|
$path_project = Join-Path $path_root project
|
||||||
$path_project_gen = Join-Path $path_project gen
|
$path_project_gen = Join-Path $path_project gen
|
||||||
$path_singleheader = Join-Path $path_root singleheader
|
$path_singleheader = Join-Path $path_root singleheader
|
||||||
$path_singleheader_gen = Join-Path $path_singleheader gen
|
$path_singleheader_gen = Join-Path $path_singleheader gen
|
||||||
$path_unreal = Join-Path $path_root unreal_engine
|
$path_release = Join-Path $path_root release
|
||||||
$path_unreal_gen = Join-Path $path_unreal gen
|
$path_release_content = Join-Path $path_release content
|
||||||
$path_release = Join-Path $path_root release
|
|
||||||
$path_release_content = Join-Path $path_release content
|
|
||||||
|
|
||||||
if ( -not(Test-Path $path_release) ) {
|
if ( -not(Test-Path $path_release) ) {
|
||||||
New-Item -ItemType Directory -Path $path_release
|
New-Item -ItemType Directory -Path $path_release
|
||||||
@ -52,17 +50,5 @@ Remove-Item -Path $path_release_content\gen.hpp
|
|||||||
# Segmented
|
# Segmented
|
||||||
Copy-Item -Path $path_project_gen\* -Destination $path_release_content
|
Copy-Item -Path $path_project_gen\* -Destination $path_release_content
|
||||||
Compress-Archive -Path $path_release_content\* -DestinationPath $path_release\gencpp_segmented.zip -Force
|
Compress-Archive -Path $path_release_content\* -DestinationPath $path_release\gencpp_segmented.zip -Force
|
||||||
Remove-Item -Path $path_release_content\gen.dep.hpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.dep.cpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.hpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.cpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.builder.hpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.builder.cpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.scanner.hpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.scanner.cpp
|
|
||||||
|
|
||||||
# Unreal
|
|
||||||
Copy-Item -Path $path_unreal_gen\* -Destination $path_release_content
|
|
||||||
Compress-Archive -Path $path_release_content\* -DestinationPath $path_release\gencpp_unreal.zip -Force
|
|
||||||
|
|
||||||
Remove-Item -Path $path_release_content -Recurse
|
Remove-Item -Path $path_release_content -Recurse
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
[string] $format = $false
|
|
||||||
|
|
||||||
foreach ( $arg in $args )
|
|
||||||
{
|
|
||||||
if ( $arg -eq "format" )
|
|
||||||
{
|
|
||||||
$format = $true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[string[]] $include = 'gen.*.hpp', 'gen.*.cpp', 'gen.hpp', 'gen.cpp'
|
|
||||||
[string[]] $exclude
|
|
||||||
|
|
||||||
$path_root = git rev-parse --show-toplevel
|
|
||||||
$path_project = Join-Path $path_root project
|
|
||||||
$path_scripts = Join-Path $path_root scripts
|
|
||||||
$path_singlheader = Join-Path $path_root singleheader
|
|
||||||
$path_singleheader_comp = Join-Path $path_singlheader components
|
|
||||||
$path_unreal = Join-Path $path_root unreal_engine
|
|
||||||
$path_unreal_gen = Join-Path $path_unreal gen
|
|
||||||
|
|
||||||
$file_spec = Join-Path $path_scripts unreal.refactor
|
|
||||||
|
|
||||||
# Gather the files to be formatted.
|
|
||||||
$targetFiles = @()
|
|
||||||
$targetFiles += Get-ChildItem -Recurse -Path $path_unreal_gen -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName
|
|
||||||
# $targetFiles += Get-ChildItem -Recurse -Path $path_project -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName
|
|
||||||
# $targetFiles += Get-ChildItem -Recurse -Path $path_singleheader_comp -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName
|
|
||||||
|
|
||||||
# Format the files.
|
|
||||||
$formatParams = @(
|
|
||||||
'-i' # In-place
|
|
||||||
'-style=file:./.clang-format' # Search for a .clang-format file in the parent directory of the source file.
|
|
||||||
'-verbose'
|
|
||||||
)
|
|
||||||
|
|
||||||
write-host "Beginning refactor...`n"
|
|
||||||
|
|
||||||
$refactorParams = @(
|
|
||||||
# "-debug",
|
|
||||||
"-num=$($targetFiles.Count)"
|
|
||||||
"-src=$($targetFiles)",
|
|
||||||
"-spec=$($file_spec)"
|
|
||||||
)
|
|
||||||
|
|
||||||
& refactor $refactorParams
|
|
||||||
|
|
||||||
Write-Host "`nRefactoring complete`n`n"
|
|
||||||
|
|
||||||
if ( $format -eq $true ) {
|
|
||||||
Write-Host "Beginning format...`n"
|
|
||||||
|
|
||||||
& clang-format $formatParams $targetFiles
|
|
||||||
|
|
||||||
Write-Host "`nFormatting complete"
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
__VERSION 1
|
|
||||||
|
|
||||||
// This is a example template to be used with the refactor program
|
|
||||||
// Use it to refactor the naming convention of this library to your own.
|
|
||||||
// Can be used as an aid to help use use your project's implementation if it fullfills the dependencies of this project.
|
|
||||||
// Example: Most likely have a memory and string library already, just rename the functions and make sure the args are the same.
|
|
||||||
// Program: https://github.com/Ed94/refactor
|
|
||||||
|
|
||||||
// NOTE: Due to the current limitations of the program, not every symbol in the library can be renamed.
|
|
||||||
// This is due to the program not actually parsing C/C++.
|
|
||||||
|
|
||||||
// not : Ignore
|
|
||||||
// include : #includes
|
|
||||||
// word : Alphanumeric or underscore
|
|
||||||
// namespace : Prefix search and replace (c-namspaces).
|
|
||||||
// regex : Unavailable in __VERSION 1.
|
|
||||||
|
|
||||||
// Precedence (highest to lowest):
|
|
||||||
// word, namespace, regex
|
|
||||||
|
|
||||||
// Gen Macro namespace
|
|
||||||
// namespace GEN_, new_namespace_
|
|
||||||
|
|
||||||
word forceinline, FORCEINLINE
|
|
||||||
word spec_forceinline, spec_FORCEINLINE
|
|
@ -1,3 +0,0 @@
|
|||||||
# Unreal Engine Version Generator
|
|
||||||
|
|
||||||
This generates a variant of gencpp thats compatiable with use as a thirdparty module within a plugin or module of an Unreal Project or the Engine itself.
|
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
gencpp: An attempt at "simple" staged metaprogramming for c/c++.
|
|
||||||
|
|
||||||
See Readme.md for more information from the project repository.
|
|
||||||
|
|
||||||
Public Address:
|
|
||||||
https://github.com/Ed94/gencpp
|
|
||||||
|
|
||||||
This is a variant intended for use with Unreal Engine 5
|
|
||||||
*/
|
|
||||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
|
||||||
# error Gen.hpp : GEN_TIME not defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
|
||||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
|
||||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
|
||||||
# include "gen.dep.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GEN_NS_BEGIN
|
|
||||||
# ifdef GEN_DONT_USE_NAMESPACE
|
|
||||||
# define GEN_NS
|
|
||||||
# define GEN_NS_BEGIN
|
|
||||||
# define GEN_NS_END
|
|
||||||
# else
|
|
||||||
# define GEN_NS gen::
|
|
||||||
# define GEN_NS_BEGIN namespace gen {
|
|
||||||
# define GEN_NS_END }
|
|
||||||
# endif
|
|
||||||
#endif
|
|
@ -1,5 +0,0 @@
|
|||||||
#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
|
|
||||||
# error Gen.hpp : GEN_TIME not defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "gen.hpp"
|
|
@ -1,7 +0,0 @@
|
|||||||
API_Export, GEN_API_Export_Code
|
|
||||||
API_Import, GEN_API_Import_Code
|
|
||||||
UE_DEPRECATED, UE_DEPRECATED
|
|
||||||
UMG_API, UMG_API
|
|
||||||
COREUOBJECT_API, COREUOBJECT_API
|
|
||||||
ENGINE_API, ENGINE_API
|
|
||||||
GAMEPLAYABILITIES_API, GAMEPLAYABILITIES_API
|
|
|
@ -1,416 +0,0 @@
|
|||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
|
||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
|
|
||||||
#define GEN_EXPOSE_BACKEDN
|
|
||||||
#include "gen.cpp"
|
|
||||||
|
|
||||||
#include "helpers/push_ignores.inline.hpp"
|
|
||||||
#include "helpers/helper.hpp"
|
|
||||||
|
|
||||||
GEN_NS_BEGIN
|
|
||||||
#include "dependencies/parsing.cpp"
|
|
||||||
GEN_NS_END
|
|
||||||
|
|
||||||
#include "auxillary/builder.hpp"
|
|
||||||
#include "auxillary/builder.cpp"
|
|
||||||
#include "auxillary/scanner.hpp"
|
|
||||||
|
|
||||||
using namespace gen;
|
|
||||||
|
|
||||||
constexpr char const* generation_notice =
|
|
||||||
"// This file was generated automatially by gencpp's unreal.cpp "
|
|
||||||
"(See: https://github.com/Ed94/gencpp)\n\n";
|
|
||||||
|
|
||||||
constexpr StrC implementation_guard_start = txt(R"(
|
|
||||||
#pragma region GENCPP IMPLEMENTATION GUARD
|
|
||||||
#if defined(GEN_IMPLEMENTATION) && ! defined(GEN_IMPLEMENTED)
|
|
||||||
# define GEN_IMPLEMENTED
|
|
||||||
)");
|
|
||||||
|
|
||||||
constexpr StrC implementation_guard_end = txt(R"(
|
|
||||||
#endif
|
|
||||||
#pragma endregion GENCPP IMPLEMENTATION GUARD
|
|
||||||
)");
|
|
||||||
|
|
||||||
constexpr StrC roll_own_dependencies_guard_start = txt(R"(
|
|
||||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
|
|
||||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
|
|
||||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
|
|
||||||
|
|
||||||
)");
|
|
||||||
|
|
||||||
constexpr StrC roll_own_dependencies_guard_end = txt(R"(
|
|
||||||
// GEN_ROLL_OWN_DEPENDENCIES
|
|
||||||
#endif
|
|
||||||
)");
|
|
||||||
|
|
||||||
global bool generate_gen_dep = true;
|
|
||||||
global bool generate_builder = true;
|
|
||||||
global bool generate_editor = true;
|
|
||||||
global bool generate_scanner = true;
|
|
||||||
|
|
||||||
int gen_main()
|
|
||||||
{
|
|
||||||
#define project_dir "../project/"
|
|
||||||
gen::init();
|
|
||||||
|
|
||||||
Code push_ignores = scan_file( project_dir "helpers/push_ignores.inline.hpp" );
|
|
||||||
Code pop_ignores = scan_file( project_dir "helpers/pop_ignores.inline.hpp" );
|
|
||||||
|
|
||||||
Code ue_forceinline = code_str(FORCEINLINE);
|
|
||||||
// Code
|
|
||||||
|
|
||||||
// gen_dep.hpp
|
|
||||||
{
|
|
||||||
CodeBody header_start = def_body( CodeT::Global_Body );
|
|
||||||
{
|
|
||||||
FileContents content = file_read_contents( GlobalAllocator, true, project_dir "dependencies/header_start.hpp" );
|
|
||||||
CodeBody ori_header_start = parse_global_body( StrC { content.size, (char const*)content.data });
|
|
||||||
|
|
||||||
for (Code code = ori_header_start.begin();
|
|
||||||
code != ori_header_start.end();
|
|
||||||
++ code )
|
|
||||||
{
|
|
||||||
header_start.append(code);
|
|
||||||
if (code->Type == CodeT::Preprocess_Pragma && code->Content.starts_with(txt("once")))
|
|
||||||
{
|
|
||||||
header_start.append( fmt_newline );
|
|
||||||
header_start.append( push_ignores );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeBody macros = def_body( CodeT::Global_Body );
|
|
||||||
{
|
|
||||||
FileContents content = file_read_contents( GlobalAllocator, true, project_dir "dependencies/macros.hpp" );
|
|
||||||
CodeBody ori_macros = parse_global_body( StrC { content.size, (char const*)content.data });
|
|
||||||
|
|
||||||
for (Code code = ori_macros.begin();
|
|
||||||
code != ori_macros.end();
|
|
||||||
++ code )
|
|
||||||
{
|
|
||||||
switch (code->Type)
|
|
||||||
{
|
|
||||||
using namespace ECode;
|
|
||||||
case Preprocess_Define:
|
|
||||||
{
|
|
||||||
CodeDefine define = code.cast<CodeDefine>();
|
|
||||||
if ( define->Name.starts_with(txt("global")) )
|
|
||||||
{
|
|
||||||
macros.append(parse_global_body(txt("#define global // Global variables")));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
macros.append(define);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Preprocess_Pragma:
|
|
||||||
{
|
|
||||||
macros.append(code);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
local_persist bool found = false;
|
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
macros.append(code);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code->Content.starts_with(txt("region ForceInline Definition")))
|
|
||||||
{
|
|
||||||
macros.append(code);
|
|
||||||
++ code;
|
|
||||||
|
|
||||||
CodeBody replacement = parse_global_body(StrC(txt(
|
|
||||||
R"(#ifdef GEN_COMPILER_MSVC
|
|
||||||
#define FORCEINLINE __forceinline
|
|
||||||
#define neverinline __declspec( noinline )
|
|
||||||
#elif defined( GEN_COMPILER_GCC )
|
|
||||||
#define FORCEINLINE inline __attribute__( ( __always_inline__ ) )
|
|
||||||
#define neverinline __attribute__( ( __noinline__ ) )
|
|
||||||
#elif defined( GEN_COMPILER_CLANG )
|
|
||||||
#if __has_attribute( __always_inline__ )
|
|
||||||
#define FORCEINLINE inline __attribute__( ( __always_inline__ ) )
|
|
||||||
#define neverinline __attribute__( ( __noinline__ ) )
|
|
||||||
#else
|
|
||||||
#define FORCEINLINE
|
|
||||||
#define neverinline
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define FORCEINLINE
|
|
||||||
#define neverinline
|
|
||||||
#endif)")));
|
|
||||||
macros.append(replacement);
|
|
||||||
|
|
||||||
while (code->Type != ECode::Preprocess_Pragma
|
|
||||||
|| ! code->Content.starts_with(txt("endregion ForceInline Definition")))
|
|
||||||
++ code;
|
|
||||||
|
|
||||||
macros.append( code );
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
macros.append(code);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Code basic_types = scan_file( project_dir "dependencies/basic_types.hpp" );
|
|
||||||
Code debug = scan_file( project_dir "dependencies/debug.hpp" );
|
|
||||||
Code memory = scan_file( project_dir "dependencies/memory.hpp" );
|
|
||||||
Code string_ops = scan_file( project_dir "dependencies/string_ops.hpp" );
|
|
||||||
Code printing = scan_file( project_dir "dependencies/printing.hpp" );
|
|
||||||
Code containers = scan_file( project_dir "dependencies/containers.hpp" );
|
|
||||||
Code hashing = scan_file( project_dir "dependencies/hashing.hpp" );
|
|
||||||
Code strings = scan_file( project_dir "dependencies/strings.hpp" );
|
|
||||||
Code filesystem = scan_file( project_dir "dependencies/filesystem.hpp" );
|
|
||||||
Code timing = scan_file( project_dir "dependencies/timing.hpp" );
|
|
||||||
|
|
||||||
Builder
|
|
||||||
header = Builder::open("gen/gen.dep.hpp");
|
|
||||||
header.print_fmt( generation_notice );
|
|
||||||
header.print( header_start );
|
|
||||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
|
||||||
|
|
||||||
header.print( macros );
|
|
||||||
header.print( basic_types );
|
|
||||||
header.print( debug );
|
|
||||||
header.print( memory );
|
|
||||||
header.print( string_ops );
|
|
||||||
header.print( printing );
|
|
||||||
header.print( containers );
|
|
||||||
header.print( hashing );
|
|
||||||
header.print( strings );
|
|
||||||
header.print( filesystem );
|
|
||||||
header.print( timing );
|
|
||||||
|
|
||||||
header.print_fmt( "\nGEN_NS_END\n" );
|
|
||||||
header.print( fmt_newline );
|
|
||||||
header.print( pop_ignores );
|
|
||||||
header.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
// gen_dep.cpp
|
|
||||||
{
|
|
||||||
Code src_start = scan_file( project_dir "dependencies/src_start.cpp" );
|
|
||||||
Code debug = scan_file( project_dir "dependencies/debug.cpp" );
|
|
||||||
Code string_ops = scan_file( project_dir "dependencies/string_ops.cpp" );
|
|
||||||
Code printing = scan_file( project_dir "dependencies/printing.cpp" );
|
|
||||||
Code memory = scan_file( project_dir "dependencies/memory.cpp" );
|
|
||||||
Code hashing = scan_file( project_dir "dependencies/hashing.cpp" );
|
|
||||||
Code strings = scan_file( project_dir "dependencies/strings.cpp" );
|
|
||||||
Code filesystem = scan_file( project_dir "dependencies/filesystem.cpp" );
|
|
||||||
Code timing = scan_file( project_dir "dependencies/timing.cpp" );
|
|
||||||
|
|
||||||
Builder
|
|
||||||
src = Builder::open( "gen/gen.dep.cpp" );
|
|
||||||
src.print_fmt( generation_notice );
|
|
||||||
src.print( def_include(txt("gen.dep.hpp")));
|
|
||||||
src.print( fmt_newline );
|
|
||||||
src.print( push_ignores );
|
|
||||||
src.print( src_start );
|
|
||||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
|
||||||
|
|
||||||
src.print( debug );
|
|
||||||
src.print( string_ops );
|
|
||||||
src.print( printing );
|
|
||||||
src.print( hashing );
|
|
||||||
src.print( memory );
|
|
||||||
src.print( strings );
|
|
||||||
src.print( filesystem );
|
|
||||||
src.print( timing );
|
|
||||||
|
|
||||||
src.print_fmt( "\nGEN_NS_END\n" );
|
|
||||||
src.print( fmt_newline );
|
|
||||||
src.print( pop_ignores );
|
|
||||||
src.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
// gen.hpp
|
|
||||||
{
|
|
||||||
Code header_start = scan_file( "components/header_start.hpp" );
|
|
||||||
Code types = scan_file( project_dir "components/types.hpp" );
|
|
||||||
Code ast = scan_file( project_dir "components/ast.hpp" );
|
|
||||||
Code ast_types = scan_file( project_dir "components/ast_types.hpp" );
|
|
||||||
Code code_types = scan_file( project_dir "components/code_types.hpp" );
|
|
||||||
Code interface = scan_file( project_dir "components/interface.hpp" );
|
|
||||||
Code inlines = scan_file( project_dir "components/inlines.hpp" );
|
|
||||||
Code header_end = scan_file( project_dir "components/header_end.hpp" );
|
|
||||||
|
|
||||||
CodeBody ecode = gen_ecode ( project_dir "enums/ECode.csv" );
|
|
||||||
CodeBody eoperator = gen_eoperator ( project_dir "enums/EOperator.csv" );
|
|
||||||
CodeBody especifier = gen_especifier( project_dir "enums/ESpecifier.csv" );
|
|
||||||
CodeBody ast_inlines = gen_ast_inlines();
|
|
||||||
|
|
||||||
Builder
|
|
||||||
header = Builder::open( "gen/gen.hpp" );
|
|
||||||
header.print_fmt( generation_notice );
|
|
||||||
header.print_fmt( "#pragma once\n\n" );
|
|
||||||
header.print( push_ignores );
|
|
||||||
header.print( fmt_newline );
|
|
||||||
header.print( header_start );
|
|
||||||
header.print_fmt( "\nGEN_NS_BEGIN\n\n" );
|
|
||||||
|
|
||||||
header.print_fmt( "#pragma region Types\n" );
|
|
||||||
header.print( types );
|
|
||||||
header.print( ecode );
|
|
||||||
header.print( eoperator );
|
|
||||||
header.print( especifier );
|
|
||||||
header.print_fmt( "#pragma endregion Types\n\n" );
|
|
||||||
|
|
||||||
header.print_fmt( "#pragma region AST\n" );
|
|
||||||
header.print( ast );
|
|
||||||
header.print( code_types );
|
|
||||||
header.print( ast_types );
|
|
||||||
header.print_fmt( "\n#pragma endregion AST\n" );
|
|
||||||
|
|
||||||
header.print( interface );
|
|
||||||
|
|
||||||
header.print_fmt( "\n#pragma region Inlines\n" );
|
|
||||||
header.print( inlines );
|
|
||||||
header.print( fmt_newline );
|
|
||||||
header.print( ast_inlines );
|
|
||||||
header.print_fmt( "#pragma endregion Inlines\n" );
|
|
||||||
|
|
||||||
header.print( header_end );
|
|
||||||
header.print_fmt( "GEN_NS_END\n\n" );
|
|
||||||
header.print( pop_ignores );
|
|
||||||
header.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
// gen.cpp
|
|
||||||
{
|
|
||||||
Code src_start = scan_file( "components/src_start.cpp" );
|
|
||||||
Code static_data = scan_file( project_dir "components/static_data.cpp" );
|
|
||||||
Code ast_case_macros = scan_file( project_dir "components/ast_case_macros.cpp" );
|
|
||||||
Code ast = scan_file( project_dir "components/ast.cpp" );
|
|
||||||
Code code_serialization = scan_file( project_dir "components/code_serialization.cpp" );
|
|
||||||
Code interface = scan_file( project_dir "components/interface.cpp" );
|
|
||||||
Code upfront = scan_file( project_dir "components/interface.upfront.cpp" );
|
|
||||||
Code lexer = scan_file( project_dir "components/lexer.cpp" );
|
|
||||||
Code parser = scan_file( project_dir "components/parser.cpp" );
|
|
||||||
Code parsing_interface = scan_file( project_dir "components/interface.parsing.cpp" );
|
|
||||||
Code untyped = scan_file( project_dir "components/interface.untyped.cpp" );
|
|
||||||
|
|
||||||
// Note(Ed): The Attribute tokens need to be expanded and regenerated on a per-project/installation of this library for a specific codebase of Unreal.
|
|
||||||
// We can support an arbitrary set of modules or plugin apis for parsing
|
|
||||||
// but its up to the user to define them all (This will just provide whats I've used up till now).
|
|
||||||
CodeBody etoktype = gen_etoktype( project_dir "enums/ETokType.csv", "enums/AttributeTokens.csv" );
|
|
||||||
CodeNS nspaced_etoktype = def_namespace( name(parser), def_namespace_body( args(etoktype)) );
|
|
||||||
|
|
||||||
Builder
|
|
||||||
src = Builder::open( "gen/gen.cpp" );
|
|
||||||
src.print_fmt( generation_notice );
|
|
||||||
src.print( push_ignores );
|
|
||||||
src.print( fmt_newline );
|
|
||||||
src.print( src_start );
|
|
||||||
src.print( fmt_newline );
|
|
||||||
src.print_fmt( "GEN_NS_BEGIN\n");
|
|
||||||
|
|
||||||
src.print( static_data );
|
|
||||||
|
|
||||||
src.print_fmt( "\n#pragma region AST\n\n" );
|
|
||||||
src.print( ast_case_macros );
|
|
||||||
src.print( ast );
|
|
||||||
src.print( code_serialization );
|
|
||||||
src.print_fmt( "\n#pragma endregion AST\n" );
|
|
||||||
|
|
||||||
src.print_fmt( "\n#pragma region Interface\n" );
|
|
||||||
src.print( interface );
|
|
||||||
src.print( upfront );
|
|
||||||
src.print_fmt( "\n#pragma region Parsing\n\n" );
|
|
||||||
src.print( nspaced_etoktype );
|
|
||||||
src.print( lexer );
|
|
||||||
src.print( parser );
|
|
||||||
src.print( parsing_interface );
|
|
||||||
src.print( untyped );
|
|
||||||
src.print_fmt( "\n#pragma endregion Parsing\n\n" );
|
|
||||||
src.print_fmt( "#pragma endregion Interface\n\n" );
|
|
||||||
|
|
||||||
src.print_fmt( "GEN_NS_END\n\n");
|
|
||||||
src.print( pop_ignores );
|
|
||||||
src.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
// gen_builder.hpp
|
|
||||||
{
|
|
||||||
Code builder = scan_file( project_dir "auxillary/builder.hpp" );
|
|
||||||
|
|
||||||
Builder
|
|
||||||
header = Builder::open( "gen/gen.builder.hpp" );
|
|
||||||
header.print_fmt( generation_notice );
|
|
||||||
header.print( push_ignores );
|
|
||||||
header.print( fmt_newline );
|
|
||||||
header.print_fmt( "#pragma once\n\n" );
|
|
||||||
header.print( def_include( txt("gen.hpp") ));
|
|
||||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
|
||||||
header.print( builder );
|
|
||||||
header.print_fmt( "GEN_NS_END\n" );
|
|
||||||
header.print( fmt_newline );
|
|
||||||
header.print( pop_ignores );
|
|
||||||
header.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
// gen_builder.cpp
|
|
||||||
{
|
|
||||||
Code builder = scan_file( project_dir "auxillary/builder.cpp" );
|
|
||||||
|
|
||||||
Builder
|
|
||||||
src = Builder::open( "gen/gen.builder.cpp" );
|
|
||||||
src.print_fmt( generation_notice );
|
|
||||||
src.print( push_ignores );
|
|
||||||
src.print( fmt_newline );
|
|
||||||
src.print( def_include( txt("gen.builder.hpp") ) );
|
|
||||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
|
||||||
src.print( builder );
|
|
||||||
src.print_fmt( "\nGEN_NS_END\n" );
|
|
||||||
src.print( fmt_newline );
|
|
||||||
src.print( pop_ignores );
|
|
||||||
src.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
// gen_scanner.hpp
|
|
||||||
{
|
|
||||||
Code parsing = scan_file( project_dir "dependencies/parsing.hpp" );
|
|
||||||
Code scanner = scan_file( project_dir "auxillary/scanner.hpp" );
|
|
||||||
|
|
||||||
Builder
|
|
||||||
header = Builder::open( "gen/gen.scanner.hpp" );
|
|
||||||
header.print_fmt( generation_notice );
|
|
||||||
header.print_fmt( "#pragma once\n\n" );
|
|
||||||
header.print( push_ignores );
|
|
||||||
header.print( fmt_newline );
|
|
||||||
header.print( def_include( txt("gen.hpp") ) );
|
|
||||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
|
||||||
header.print( parsing );
|
|
||||||
header.print( scanner );
|
|
||||||
header.print_fmt( "GEN_NS_END\n" );
|
|
||||||
header.print( fmt_newline );
|
|
||||||
header.print( pop_ignores );
|
|
||||||
header.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
// gen.scanner.cpp
|
|
||||||
{
|
|
||||||
Code parsing = scan_file( project_dir "dependencies/parsing.cpp" );
|
|
||||||
Code scanner = scan_file( project_dir "auxillary/scanner.cpp" );
|
|
||||||
|
|
||||||
Builder
|
|
||||||
src = Builder::open( "gen/gen.scanner.cpp" );
|
|
||||||
src.print_fmt( generation_notice );
|
|
||||||
src.print( push_ignores );
|
|
||||||
src.print( fmt_newline );
|
|
||||||
src.print( def_include( txt("gen.scanner.hpp") ) );
|
|
||||||
src.print_fmt( "\nGEN_NS_BEGIN\n" );
|
|
||||||
src.print( parsing );
|
|
||||||
// src.print( scanner );
|
|
||||||
src.print_fmt( "GEN_NS_END\n" );
|
|
||||||
src.print( fmt_newline );
|
|
||||||
src.print( pop_ignores );
|
|
||||||
src.write();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user