8 Commits

Author SHA1 Message Date
Ed_
912cc6b538 Bugfixes during hiatus
Found while doing some metaprogramming for day 42 of handmade hero.
2023-10-22 21:41:36 -04:00
Ed_
3dd5482a46 set ContinuationIndentWidth to 4 for clang format. 2023-10-01 20:19:16 -04:00
Ed_
632fa10027 Updated readme with partial hiatus notice. 2023-10-01 12:37:29 -04:00
Ed_
6498b13658 Fix for non-foreign include content not getting parsed correctly. 2023-10-01 12:16:15 -04:00
Ed_
7f562cd77f Merge branch 'dev' 2023-09-28 20:36:12 -04:00
Ed_
3a0e971ebf Bugfix for parse_variable, const check for prefix specifiers causing infinite loop. 2023-09-28 20:35:20 -04:00
Ed_
4997cb5878 Merge pull request #45 from Ed94/dev
Dev
2023-09-25 17:50:16 -04:00
Ed_
729c891cbd Last fixes before handmade hero hiatus 2023-09-25 17:48:16 -04:00
9 changed files with 155 additions and 69 deletions

View File

@ -10,6 +10,8 @@ Its not meant to be a black box metaprogramming utility, it should be easy to in
## Notes ## Notes
**On Partial Hiatus: Working on handmade hero for now. Only fixes will be pushed as I come across them until I get what I want done from the series**
This project is still in development (very much an alpha state), so expect bugs and missing features. This project is still in development (very much an alpha state), so expect bugs and missing features.
See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos. See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos.

View File

@ -330,6 +330,7 @@
<ClCompile Include="project\dependencies\strings.cpp" /> <ClCompile Include="project\dependencies\strings.cpp" />
<ClCompile Include="project\dependencies\string_ops.cpp" /> <ClCompile Include="project\dependencies\string_ops.cpp" />
<ClCompile Include="project\dependencies\timing.cpp" /> <ClCompile Include="project\dependencies\timing.cpp" />
<ClCompile Include="project\Example.cpp" />
<ClCompile Include="project\gen.cpp" /> <ClCompile Include="project\gen.cpp" />
<ClCompile Include="project\gen.dep.cpp" /> <ClCompile Include="project\gen.dep.cpp" />
<ClCompile Include="singleheader\singleheader.cpp" /> <ClCompile Include="singleheader\singleheader.cpp" />

View File

@ -690,13 +690,25 @@ String AST::to_string()
case Function: case Function:
{ {
if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export ))
result.append( "export " ); result.append( "export" );
if ( Attributes ) if ( Attributes )
result.append_fmt( "%S ", Attributes->to_string() ); result.append_fmt( " %S ", Attributes->to_string() );
if ( Specs ) if ( Specs )
result.append_fmt( "%S", Specs->to_string() ); {
for ( SpecifierT spec : Specs->cast<CodeSpecifiers>() )
{
if ( ! ESpecifier::is_trailing( spec ) )
{
StrC spec_str = ESpecifier::to_str( spec );
result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr );
}
}
}
if ( Attributes || Specs )
result.append( "\n" );
if ( ReturnType ) if ( ReturnType )
result.append_fmt( "%S %S(", ReturnType->to_string(), Name ); result.append_fmt( "%S %S(", ReturnType->to_string(), Name );
@ -735,7 +747,21 @@ String AST::to_string()
result.append_fmt( "%S ", Attributes->to_string() ); result.append_fmt( "%S ", Attributes->to_string() );
if ( Specs ) if ( Specs )
result.append_fmt( "%S", Specs->to_string() ); {
for ( SpecifierT spec : Specs->cast<CodeSpecifiers>() )
{
if ( ! ESpecifier::is_trailing( spec ) )
{
StrC spec_str = ESpecifier::to_str( spec );
result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr );
}
}
}
if ( Attributes || Specs )
{
result.append("\n" );
}
if ( ReturnType ) if ( ReturnType )
result.append_fmt( "%S %S(", ReturnType->to_string(), Name ); result.append_fmt( "%S %S(", ReturnType->to_string(), Name );
@ -795,7 +821,24 @@ String AST::to_string()
result.append_fmt( "%S ", Attributes->to_string() ); result.append_fmt( "%S ", Attributes->to_string() );
if ( Attributes ) if ( Attributes )
result.append_fmt( "%S\n", Attributes->to_string() ); result.append_fmt( "%S ", Attributes->to_string() );
if ( Specs )
{
for ( SpecifierT spec : Specs->cast<CodeSpecifiers>() )
{
if ( ! ESpecifier::is_trailing( spec ) )
{
StrC spec_str = ESpecifier::to_str( spec );
result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr );
}
}
}
if ( Attributes || Specs )
{
result.append("\n" );
}
if ( ReturnType ) if ( ReturnType )
result.append_fmt( "%S %S (", ReturnType->to_string(), Name ); result.append_fmt( "%S %S (", ReturnType->to_string(), Name );
@ -834,7 +877,21 @@ String AST::to_string()
result.append_fmt( "%S\n", Attributes->to_string() ); result.append_fmt( "%S\n", Attributes->to_string() );
if ( Specs ) if ( Specs )
result.append_fmt( "%S\n", Specs->to_string() ); {
for ( SpecifierT spec : Specs->cast<CodeSpecifiers>() )
{
if ( ! ESpecifier::is_trailing( spec ) )
{
StrC spec_str = ESpecifier::to_str( spec );
result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr );
}
}
}
if ( Attributes || Specs )
{
result.append("\n" );
}
result.append_fmt( "%S %S (", ReturnType->to_string(), Name ); result.append_fmt( "%S %S (", ReturnType->to_string(), Name );
@ -991,12 +1048,6 @@ String AST::to_string()
s32 left = NumEntries; s32 left = NumEntries;
while ( left-- ) while ( left-- )
{ {
if ( ESpecifier::is_trailing( ArrSpecs[idx]) && ArrSpecs[idx] != ESpecifier::Const )
{
idx++;
continue;
}
StrC spec = ESpecifier::to_str( ArrSpecs[idx] ); StrC spec = ESpecifier::to_str( ArrSpecs[idx] );
result.append_fmt( "%.*s ", spec.Len, spec.Ptr ); result.append_fmt( "%.*s ", spec.Len, spec.Ptr );
idx++; idx++;
@ -1074,7 +1125,10 @@ String AST::to_string()
if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export ))
result.append( "export " ); result.append( "export " );
if ( Params )
result.append_fmt( "template< %S >\n%S", Params->to_string(), Declaration->to_string() ); result.append_fmt( "template< %S >\n%S", Params->to_string(), Declaration->to_string() );
else
result.append_fmt( "template<>\n%S", Declaration->to_string() );
} }
break; break;

View File

@ -257,7 +257,7 @@ struct AST
}; };
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* SpecsFuncSuffix; // 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 )
}; };
}; };
StringCached Content; // Attributes, Comment, Execution, Include StringCached Content; // Attributes, Comment, Execution, Include
@ -316,7 +316,7 @@ 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* SpecsFuncSuffix; // 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 )
}; };
}; };
StringCached Content; // Attributes, Comment, Execution, Include StringCached Content; // Attributes, Comment, Execution, Include

View File

@ -175,21 +175,21 @@ void define_constants()
#endif #endif
# undef def_constant_code_type # undef def_constant_code_type
# pragma push_macro( "forceinline" )
# pragma push_macro( "global" )
# pragma push_macro( "internal" )
# pragma push_macro( "local_persist" )
# pragma push_macro( "neverinline" )
# undef forceinline
# undef global
# undef internal
# undef local_persist
# undef neverinline
# define def_constant_spec( Type_, ... ) \ # define def_constant_spec( Type_, ... ) \
spec_##Type_ = def_specifiers( num_args(__VA_ARGS__), __VA_ARGS__); \ spec_##Type_ = def_specifiers( num_args(__VA_ARGS__), __VA_ARGS__); \
spec_##Type_.set_global(); spec_##Type_.set_global();
# pragma push_macro("forceinline")
# pragma push_macro("global")
# pragma push_macro("internal")
# pragma push_macro("local_persist")
# pragma push_macro("neverinline")
# undef forceinline
# undef global
# undef internal
# undef local_persist
# undef neverinline
def_constant_spec( const, ESpecifier::Const ); def_constant_spec( const, ESpecifier::Const );
def_constant_spec( consteval, ESpecifier::Consteval ); def_constant_spec( consteval, ESpecifier::Consteval );
def_constant_spec( constexpr, ESpecifier::Constexpr ); def_constant_spec( constexpr, ESpecifier::Constexpr );
@ -218,11 +218,11 @@ void define_constants()
spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist ); spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist );
spec_local_persist.set_global(); spec_local_persist.set_global();
# pragma pop_macro( "forceinline" ) # pragma pop_macro("forceinline")
# pragma pop_macro( "global" ) # pragma pop_macro("global")
# pragma pop_macro( "internal" ) # pragma pop_macro("internal")
# pragma pop_macro( "local_persist" ) # pragma pop_macro("local_persist")
# pragma pop_macro( "neverinline" ) # pragma pop_macro("neverinline")
# undef def_constant_spec # undef def_constant_spec
} }

View File

@ -509,6 +509,8 @@ namespace Parser
); );
return { { nullptr }, 0 }; return { { nullptr }, 0 };
} }
move_forward();
content.Length++;
while ( left && current != '"' && current != '>' ) while ( left && current != '"' && current != '>' )
{ {
@ -773,6 +775,18 @@ namespace Parser
if (left) if (left)
move_forward(); move_forward();
if ( current == '=' )
{
token.Length++;
token.IsAssign = true;
// token.Flags |= TokFlags::Assignment;
// token.Type = TokType::Assign_Multiply;
if ( left )
move_forward();
}
goto FoundToken; goto FoundToken;
} }
case ';': case ';':
@ -971,7 +985,14 @@ namespace Parser
if ( left ) if ( left )
{ {
if ( current == '/' ) if ( current == '=' )
{
// token.Type = TokeType::Assign_Divide;
move_forward();
token.Length++;
token.IsAssign = true;
}
else if ( current == '/' )
{ {
token.Type = TokType::Comment; token.Type = TokType::Comment;
token.Length = 2; token.Length = 2;
@ -2296,6 +2317,7 @@ CodeFn parse_function_after_name(
CodeParam params = parse_params(); CodeParam params = parse_params();
// These have to be kept separate from the return type's specifiers.
while ( left && currtok.is_specifier() ) while ( left && currtok.is_specifier() )
{ {
if ( specifiers.ast == nullptr ) if ( specifiers.ast == nullptr )
@ -2817,7 +2839,7 @@ CodeOperator parse_operator_after_ret_type(
if ( currtok.Text[1] == '=' ) if ( currtok.Text[1] == '=' )
op = Assign_Add; op = Assign_Add;
if ( currtok.Text[1] == '+' ) else if ( currtok.Text[1] == '+' )
op = Increment; op = Increment;
else else
@ -2837,7 +2859,7 @@ CodeOperator parse_operator_after_ret_type(
break; break;
} }
if ( currtok.Text[1] == '=' ) else if ( currtok.Text[1] == '=' )
op = Assign_Subtract; op = Assign_Subtract;
else else
@ -3193,6 +3215,12 @@ CodeParam parse_params( bool use_template_capture )
Context.pop(); Context.pop();
return { nullptr }; return { nullptr };
} }
else if ( check ( TokType::Operator ) && currtok.Text[0] == '>' )
{
eat( TokType::Operator );
Context.pop();
return { nullptr };
}
CodeType type = { nullptr }; CodeType type = { nullptr };
Code value = { nullptr }; Code value = { nullptr };
@ -4784,7 +4812,7 @@ CodeType parse_type( bool* typedef_is_function )
#if 0 #if 0
else if ( currtok.Type == TokType::DeclType ) else if ( currtok.Type == TokType::DeclType )
{ {
// Will have a capture and its own parsing rules, were going to just shove everything in a string. // Will have a capture and its own parsing rules, were going to just shove everything in a string (for now).
name = currtok; name = currtok;
eat( TokType::DeclType ); eat( TokType::DeclType );
@ -5619,7 +5647,7 @@ CodeVar parse_variable()
// Ignore const specifiers, they're handled by the type // Ignore const specifiers, they're handled by the type
if ( spec == ESpecifier::Const ) if ( spec == ESpecifier::Const )
continue; break;
specs_found[NumSpecifiers] = spec; specs_found[NumSpecifiers] = spec;
NumSpecifiers++; NumSpecifiers++;

View File

@ -36,12 +36,12 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
} }
# define check_param_eq_ret() \ # define check_param_eq_ret() \
if ( ! is_member_symbol && params_code->ValueType != ret_type ) \ if ( ! is_member_symbol && ! params_code->ValueType.is_equal( ret_type) ) \
{ \ { \
log_failure("gen_def_operator: operator%s requires first parameter to equal return type\n" \ log_failure("gen::def_operator: operator%s requires first parameter to equal return type\n" \
"param types: %s\n" \ "param types: %s\n" \
"return type: %s", \ "return type: %s", \
to_str(op), \ to_str(op).Ptr, \
params_code.debug_str(), \ params_code.debug_str(), \
ret_type.debug_str() \ ret_type.debug_str() \
); \ ); \
@ -947,6 +947,7 @@ CodeOperator def_operator( OperatorT op, StrC nspace
result = (CodeOperator) make_code(); result = (CodeOperator) make_code();
result->Name = get_cached_string( { str_len(name), name } ); result->Name = get_cached_string( { str_len(name), name } );
result->ModuleFlags = mflags; result->ModuleFlags = mflags;
result->Op = op;
if ( body ) if ( body )
{ {

View File

@ -32,7 +32,7 @@ CodeBody gen_ecode( char const* path )
CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", (StrC)enum_entries, "enum Type : u32 { <entries> NumTypes };")); CodeEnum enum_code = parse_enum(gen::token_fmt_impl((3 + 1) / 2, "entries", (StrC)enum_entries, "enum Type : u32 { <entries> NumTypes };"));
#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(
StrC to_str( Type type ) StrC to_str( Type type )
@ -45,7 +45,7 @@ CodeBody gen_ecode( char const* path )
return lookup[ type ]; return lookup[ type ];
} }
))); )));
#pragma pop_macro( "local_persist" ) #pragma pop_macro("local_persist")
CodeNS nspace = def_namespace( name(ECode), def_namespace_body( args( enum_code, to_str ) ) ); CodeNS nspace = def_namespace( name(ECode), def_namespace_body( args( enum_code, to_str ) ) );
CodeUsing code_t = def_using( name(CodeT), def_type( name(ECode::Type) ) ); CodeUsing code_t = def_using( name(CodeT), def_type( name(ECode::Type) ) );
@ -86,7 +86,7 @@ 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(
StrC to_str( Type op ) StrC to_str( Type op )
@ -99,7 +99,7 @@ CodeBody gen_eoperator( char const* path )
return lookup[ op ]; return lookup[ op ];
} }
))); )));
#pragma pop_macro( "local_persist" ) #pragma pop_macro("local_persist")
CodeNS nspace = def_namespace( name(EOperator), def_namespace_body( args( enum_code, to_str ) ) ); CodeNS nspace = def_namespace( name(EOperator), def_namespace_body( args( enum_code, to_str ) ) );
@ -148,11 +148,11 @@ CodeBody gen_especifier( char const* path )
} }
))); )));
#pragma push_macro( "local_persist" ) #pragma push_macro("local_persist")
#pragma push_macro( "do_once_start" ) #pragma push_macro("do_once_start")
#pragma push_macro( "do_once_end" ) #pragma push_macro("do_once_end")
#pragma push_macro( "forceinline" ) #pragma push_macro("forceinline")
#pragma push_macro( "neverinline" ) #pragma push_macro("neverinline")
#undef local_persist #undef local_persist
#undef do_once_start #undef do_once_start
#undef do_once_end #undef do_once_end
@ -197,11 +197,11 @@ CodeBody gen_especifier( char const* path )
return Invalid; return Invalid;
} }
))); )));
#pragma pop_macro( "local_persist" ) #pragma pop_macro("local_persist")
#pragma pop_macro( "do_once_start" ) #pragma pop_macro("do_once_start")
#pragma pop_macro( "do_once_end" ) #pragma pop_macro("do_once_end")
#pragma pop_macro( "forceinline" ) #pragma pop_macro("forceinline")
#pragma pop_macro( "neverinline" ) #pragma pop_macro("neverinline")
CodeNS nspace = def_namespace( name(ESpecifier), def_namespace_body( args( enum_code, is_trailing, to_str, to_type ) ) ); CodeNS nspace = def_namespace( name(ESpecifier), def_namespace_body( args( enum_code, is_trailing, to_str, to_type ) ) );
@ -260,10 +260,10 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
attribute_define_entries.append( "\n"); attribute_define_entries.append( "\n");
} }
#pragma push_macro( "GEN_DEFINE_ATTRIBUTE_TOKENS" ) #pragma push_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
#undef GEN_DEFINE_ATTRIBUTE_TOKENS #undef GEN_DEFINE_ATTRIBUTE_TOKENS
CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), attribute_define_entries ); CodeDefine attribute_entires_def = def_define( name(GEN_DEFINE_ATTRIBUTE_TOKENS), attribute_define_entries );
#pragma pop_macro( "GEN_DEFINE_ATTRIBUTE_TOKENS" ) #pragma pop_macro("GEN_DEFINE_ATTRIBUTE_TOKENS")
CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, "attribute_toks", (StrC)attribute_entries, stringize( CodeEnum enum_code = parse_enum(token_fmt("entries", (StrC)enum_entries, "attribute_toks", (StrC)attribute_entries, stringize(
enum Type : u32 enum Type : u32
@ -274,9 +274,9 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
}; };
))); )));
#pragma push_macro( "local_persist" ) #pragma push_macro("local_persist")
#pragma push_macro( "do_once_start" ) #pragma push_macro("do_once_start")
#pragma push_macro( "do_once_end" ) #pragma push_macro("do_once_end")
#undef local_persist #undef local_persist
#undef do_once_start #undef do_once_start
#undef do_once_end #undef do_once_end
@ -320,9 +320,9 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
return Invalid; return Invalid;
} }
))); )));
#pragma pop_macro( "local_persist" ) #pragma pop_macro("local_persist")
#pragma pop_macro( "do_once_start" ) #pragma pop_macro("do_once_start")
#pragma pop_macro( "do_once_end" ) #pragma pop_macro("do_once_end")
CodeNS nspace = def_namespace( name(ETokType), def_namespace_body( args( attribute_entires_def, enum_code, to_str, to_type ) ) ); CodeNS nspace = def_namespace( name(ETokType), def_namespace_body( args( attribute_entires_def, enum_code, to_str, to_type ) ) );
CodeUsing td_toktype = def_using( name(TokType), def_type( name(ETokType::Type) ) ); CodeUsing td_toktype = def_using( name(TokType), def_type( name(ETokType::Type) ) );

View File

@ -86,7 +86,7 @@ CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth : 4 ConstructorInitializerIndentWidth : 4
ContinuationIndentWidth: 0 ContinuationIndentWidth: 4
Cpp11BracedListStyle: false Cpp11BracedListStyle: false