mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 15:54:45 -08:00
Fixes for typedef serialization of functions..
Also fix for HashTable<>::rehash_fast not having finished implemenation... The typedef fix is a sort of hack (like how parsing the rest of the language feels like tbh...). I might make a def_typedef_fn to make it clearer how to define function typedefs using the upfront interface.
This commit is contained in:
parent
c4d5637a64
commit
ed3246c6b0
@ -722,7 +722,10 @@ String AST::to_string()
|
|||||||
|
|
||||||
result.append( "typedef ");
|
result.append( "typedef ");
|
||||||
|
|
||||||
result.append_fmt( "%s %s", UnderlyingType->to_string(), Name );
|
if ( IsFunction )
|
||||||
|
result.append( UnderlyingType->to_string() );
|
||||||
|
else
|
||||||
|
result.append_fmt( "%s %s", UnderlyingType->to_string(), Name );
|
||||||
|
|
||||||
if ( UnderlyingType->Type == Typename && UnderlyingType->ArrExpr )
|
if ( UnderlyingType->Type == Typename && UnderlyingType->ArrExpr )
|
||||||
{
|
{
|
||||||
|
@ -256,6 +256,7 @@ struct AST
|
|||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
union {
|
union {
|
||||||
|
b32 IsFunction; // Used by typedef to not serialize the name field.
|
||||||
OperatorT Op;
|
OperatorT Op;
|
||||||
AccessSpec ParentAccess;
|
AccessSpec ParentAccess;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
@ -304,6 +305,7 @@ struct AST_POD
|
|||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
union {
|
union {
|
||||||
|
b32 IsFunction; // Used by typedef to not serialize the name field.
|
||||||
OperatorT Op;
|
OperatorT Op;
|
||||||
AccessSpec ParentAccess;
|
AccessSpec ParentAccess;
|
||||||
s32 NumEntries;
|
s32 NumEntries;
|
||||||
|
@ -469,7 +469,7 @@ struct AST_Typedef
|
|||||||
StringCached Name;
|
StringCached Name;
|
||||||
CodeT Type;
|
CodeT Type;
|
||||||
ModuleFlag ModuleFlags;
|
ModuleFlag ModuleFlags;
|
||||||
char _PAD_UNUSED_[ sizeof(u32) ];
|
b32 IsFunction;
|
||||||
};
|
};
|
||||||
static_assert( sizeof(AST_Typedef) == sizeof(AST), "ERROR: AST_Typedef is not the same size as AST");
|
static_assert( sizeof(AST_Typedef) == sizeof(AST), "ERROR: AST_Typedef is not the same size as AST");
|
||||||
|
|
||||||
|
@ -1143,7 +1143,7 @@ internal CodeOpCast parse_operator_cast ();
|
|||||||
internal CodeStruct parse_struct ( bool inplace_def = false );
|
internal CodeStruct parse_struct ( bool inplace_def = false );
|
||||||
internal CodeVar parse_variable ();
|
internal CodeVar parse_variable ();
|
||||||
internal CodeTemplate parse_template ();
|
internal CodeTemplate parse_template ();
|
||||||
internal CodeType parse_type ();
|
internal CodeType parse_type ( bool* is_function = nullptr );
|
||||||
internal CodeTypedef parse_typedef ();
|
internal CodeTypedef parse_typedef ();
|
||||||
internal CodeUnion parse_union ( bool inplace_def = false );
|
internal CodeUnion parse_union ( bool inplace_def = false );
|
||||||
internal CodeUsing parse_using ();
|
internal CodeUsing parse_using ();
|
||||||
@ -2358,6 +2358,47 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal inline
|
||||||
|
Code parse_foward_or_definition( Parser::TokType which, bool is_inplace )
|
||||||
|
{
|
||||||
|
using namespace Parser;
|
||||||
|
|
||||||
|
Code result = CodeInvalid;
|
||||||
|
|
||||||
|
switch ( which )
|
||||||
|
{
|
||||||
|
case TokType::Decl_Class:
|
||||||
|
result = parse_class( is_inplace );
|
||||||
|
Context.pop();
|
||||||
|
return result;
|
||||||
|
|
||||||
|
case TokType::Decl_Enum:
|
||||||
|
result = parse_enum( is_inplace );
|
||||||
|
Context.pop();
|
||||||
|
return result;
|
||||||
|
|
||||||
|
case TokType::Decl_Struct:
|
||||||
|
result = parse_struct( is_inplace );
|
||||||
|
Context.pop();
|
||||||
|
return result;
|
||||||
|
|
||||||
|
case TokType::Decl_Union:
|
||||||
|
result = parse_union( is_inplace );
|
||||||
|
Context.pop();
|
||||||
|
return result;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_failure( "Error, wrong token type given to parse_complicated_definition "
|
||||||
|
"(only supports class, enum, struct, union) \n%s"
|
||||||
|
, Context.to_string() );
|
||||||
|
|
||||||
|
Context.pop();
|
||||||
|
return CodeInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CodeInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
internal inline
|
internal inline
|
||||||
Code parse_complicated_definition( Parser::TokType which )
|
Code parse_complicated_definition( Parser::TokType which )
|
||||||
{
|
{
|
||||||
@ -2366,43 +2407,6 @@ Code parse_complicated_definition( Parser::TokType which )
|
|||||||
|
|
||||||
bool is_inplace = false;
|
bool is_inplace = false;
|
||||||
|
|
||||||
labeled_scope_start
|
|
||||||
PARSE_FORWARD_OR_DEFINITION:
|
|
||||||
Code result = CodeInvalid;
|
|
||||||
|
|
||||||
// <which> <type_identifier>;
|
|
||||||
switch ( which )
|
|
||||||
{
|
|
||||||
case TokType::Decl_Class:
|
|
||||||
result = parse_class( is_inplace );
|
|
||||||
Context.pop();
|
|
||||||
return result;
|
|
||||||
|
|
||||||
case TokType::Decl_Enum:
|
|
||||||
result = parse_enum( is_inplace );
|
|
||||||
Context.pop();
|
|
||||||
return result;
|
|
||||||
|
|
||||||
case TokType::Decl_Struct:
|
|
||||||
result = parse_struct( is_inplace );
|
|
||||||
Context.pop();
|
|
||||||
return result;
|
|
||||||
|
|
||||||
case TokType::Decl_Union:
|
|
||||||
result = parse_union( is_inplace );
|
|
||||||
Context.pop();
|
|
||||||
return result;
|
|
||||||
|
|
||||||
default:
|
|
||||||
log_failure( "Error, wrong token type given to parse_complicated_definition "
|
|
||||||
"(only supports class, enum, struct, union) \n%s"
|
|
||||||
, Context.to_string() );
|
|
||||||
|
|
||||||
Context.pop();
|
|
||||||
return CodeInvalid;
|
|
||||||
}
|
|
||||||
labeled_scope_end
|
|
||||||
|
|
||||||
TokArray tokens = Context.Tokens;
|
TokArray tokens = Context.Tokens;
|
||||||
|
|
||||||
s32 idx = tokens.Idx;
|
s32 idx = tokens.Idx;
|
||||||
@ -2422,7 +2426,7 @@ Code parse_complicated_definition( Parser::TokType which )
|
|||||||
if ( (idx - 2 ) == tokens.Idx )
|
if ( (idx - 2 ) == tokens.Idx )
|
||||||
{
|
{
|
||||||
// Its a forward declaration only
|
// Its a forward declaration only
|
||||||
goto PARSE_FORWARD_OR_DEFINITION;
|
return parse_foward_or_definition( which, is_inplace );
|
||||||
}
|
}
|
||||||
|
|
||||||
Token tok = tokens[ idx - 1 ];
|
Token tok = tokens[ idx - 1 ];
|
||||||
@ -2451,7 +2455,7 @@ Code parse_complicated_definition( Parser::TokType which )
|
|||||||
else if ( is_indirection )
|
else if ( is_indirection )
|
||||||
{
|
{
|
||||||
// Its a indirection type with type ID using struct namespace.
|
// Its a indirection type with type ID using struct namespace.
|
||||||
// <which> <type_identifier> <identifier>;
|
// <which> <type_identifier>* <identifier>;
|
||||||
ok_to_parse = true;
|
ok_to_parse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2470,7 +2474,7 @@ Code parse_complicated_definition( Parser::TokType which )
|
|||||||
{
|
{
|
||||||
// Its a definition
|
// Its a definition
|
||||||
// <which> { ... };
|
// <which> { ... };
|
||||||
goto PARSE_FORWARD_OR_DEFINITION;
|
return parse_foward_or_definition( which, is_inplace );
|
||||||
}
|
}
|
||||||
else if ( tok.Type == TokType::BraceSquare_Close)
|
else if ( tok.Type == TokType::BraceSquare_Close)
|
||||||
{
|
{
|
||||||
@ -4142,7 +4146,7 @@ CodeTemplate parse_template( StrC def )
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
CodeType parse_type()
|
CodeType parse_type( bool* is_function )
|
||||||
{
|
{
|
||||||
using namespace Parser;
|
using namespace Parser;
|
||||||
push_scope();
|
push_scope();
|
||||||
@ -4258,13 +4262,24 @@ CodeType parse_type()
|
|||||||
eat( currtok.Type );
|
eat( currtok.Type );
|
||||||
}
|
}
|
||||||
|
|
||||||
BruteforceCaptureAgain:
|
bool is_first_capture = true;
|
||||||
if ( check( TokType::Capture_Start ) && context_tok.Type != TokType::Decl_Operator )
|
while ( check( TokType::Capture_Start ) && context_tok.Type != TokType::Decl_Operator )
|
||||||
{
|
{
|
||||||
// Brute force capture the entire thing.
|
// Brute force capture the entire thing.
|
||||||
// Function typedefs are complicated and there are not worth dealing with for validation at this point...
|
// Function typedefs are complicated and there are not worth dealing with for validation at this point...
|
||||||
eat( TokType::Capture_Start );
|
eat( TokType::Capture_Start );
|
||||||
|
|
||||||
|
if ( is_function && is_first_capture )
|
||||||
|
{
|
||||||
|
while ( check( TokType::Star ))
|
||||||
|
{
|
||||||
|
eat( TokType::Star );
|
||||||
|
}
|
||||||
|
|
||||||
|
* is_function = true;
|
||||||
|
eat( TokType::Identifier );
|
||||||
|
}
|
||||||
|
|
||||||
s32 level = 0;
|
s32 level = 0;
|
||||||
while ( left && ( currtok.Type != TokType::Capture_End || level > 0 ))
|
while ( left && ( currtok.Type != TokType::Capture_End || level > 0 ))
|
||||||
{
|
{
|
||||||
@ -4276,11 +4291,10 @@ BruteforceCaptureAgain:
|
|||||||
|
|
||||||
eat( currtok.Type );
|
eat( currtok.Type );
|
||||||
}
|
}
|
||||||
|
|
||||||
eat( TokType::Capture_End );
|
eat( TokType::Capture_End );
|
||||||
|
|
||||||
goto BruteforceCaptureAgain;
|
|
||||||
|
|
||||||
brute_sig.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)brute_sig.Text;
|
brute_sig.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)brute_sig.Text;
|
||||||
|
is_first_capture = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
@ -4331,9 +4345,10 @@ CodeTypedef parse_typedef()
|
|||||||
using namespace Parser;
|
using namespace Parser;
|
||||||
push_scope();
|
push_scope();
|
||||||
|
|
||||||
Token name = { nullptr, 0, TokType::Invalid };
|
bool is_function = false;
|
||||||
Code array_expr = { nullptr };
|
Token name = { nullptr, 0, TokType::Invalid };
|
||||||
Code type = { nullptr };
|
Code array_expr = { nullptr };
|
||||||
|
Code type = { nullptr };
|
||||||
|
|
||||||
ModuleFlag mflags = ModuleFlag::None;
|
ModuleFlag mflags = ModuleFlag::None;
|
||||||
|
|
||||||
@ -4356,27 +4371,109 @@ CodeTypedef parse_typedef()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( check( TokType::Decl_Enum ) )
|
bool is_complicated =
|
||||||
type = parse_enum( from_typedef );
|
currtok.Type == TokType::Decl_Enum
|
||||||
|
|| currtok.Type == TokType::Decl_Class
|
||||||
|
|| currtok.Type == TokType::Decl_Struct
|
||||||
|
|| currtok.Type == TokType::Decl_Union;
|
||||||
|
|
||||||
else if ( check(TokType::Decl_Class ) )
|
if ( is_complicated )
|
||||||
type = parse_class( from_typedef );
|
{
|
||||||
|
TokArray tokens = Context.Tokens;
|
||||||
|
|
||||||
else if ( check(TokType::Decl_Struct ) )
|
s32 idx = tokens.Idx;
|
||||||
type = parse_struct( from_typedef );
|
s32 level = 0;
|
||||||
|
for ( ; idx < tokens.Arr.num(); idx ++ )
|
||||||
|
{
|
||||||
|
if ( tokens[idx].Type == TokType::BraceCurly_Open )
|
||||||
|
level++;
|
||||||
|
|
||||||
else if ( check(TokType::Decl_Union) )
|
if ( tokens[idx].Type == TokType::BraceCurly_Close )
|
||||||
type = parse_union( from_typedef );
|
level--;
|
||||||
|
|
||||||
|
if ( level == 0 && tokens[idx].Type == TokType::Statement_End )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (idx - 2 ) == tokens.Idx )
|
||||||
|
{
|
||||||
|
// Its a forward declaration only
|
||||||
|
type = parse_foward_or_definition( currtok.Type, from_typedef );
|
||||||
|
}
|
||||||
|
|
||||||
|
Token tok = tokens[ idx - 1 ];
|
||||||
|
if ( tok.Type == TokType::Identifier )
|
||||||
|
{
|
||||||
|
tok = tokens[ idx - 2 ];
|
||||||
|
|
||||||
|
bool is_indirection = tok.Type == TokType::Ampersand
|
||||||
|
|| tok.Type == TokType::Star;
|
||||||
|
|
||||||
|
bool ok_to_parse = false;
|
||||||
|
|
||||||
|
if ( tok.Type == TokType::BraceCurly_Close )
|
||||||
|
{
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
int b;
|
||||||
|
}* Something;
|
||||||
|
|
||||||
|
|
||||||
|
// Its an inplace definition
|
||||||
|
// typdef <which> <type_identifier> { ... } <identifier>;
|
||||||
|
ok_to_parse = true;
|
||||||
|
}
|
||||||
|
else if ( tok.Type == TokType::Identifier && tokens[ idx - 3 ].Type == TokType::Decl_Struct )
|
||||||
|
{
|
||||||
|
// Its a variable with type ID using struct namespace.
|
||||||
|
// <which> <type_identifier> <identifier>;
|
||||||
|
ok_to_parse = true;
|
||||||
|
}
|
||||||
|
else if ( is_indirection )
|
||||||
|
{
|
||||||
|
// Its a indirection type with type ID using struct namespace.
|
||||||
|
// <which> <type_identifier>* <identifier>;
|
||||||
|
ok_to_parse = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! ok_to_parse )
|
||||||
|
{
|
||||||
|
log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() );
|
||||||
|
Context.pop();
|
||||||
|
return CodeInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = parse_type();
|
||||||
|
}
|
||||||
|
else if ( tok.Type == TokType::BraceCurly_Close )
|
||||||
|
{
|
||||||
|
// Its a definition
|
||||||
|
// <which> { ... };
|
||||||
|
type = parse_foward_or_definition( currtok.Type, from_typedef );
|
||||||
|
}
|
||||||
|
else if ( tok.Type == TokType::BraceSquare_Close)
|
||||||
|
{
|
||||||
|
// Its an array definition
|
||||||
|
// <which> <type_identifier> <identifier> [ ... ];
|
||||||
|
type = parse_type();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_failure( "Unsupported or bad member definition after struct declaration\n%s", Context.to_string() );
|
||||||
|
Context.pop();
|
||||||
|
return CodeInvalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
type = parse_type();
|
type = parse_type( & is_function );
|
||||||
|
|
||||||
if ( check( TokType::Identifier ) )
|
if ( check( TokType::Identifier ) )
|
||||||
{
|
{
|
||||||
name = currtok;
|
name = currtok;
|
||||||
eat( TokType::Identifier );
|
eat( TokType::Identifier );
|
||||||
}
|
}
|
||||||
else
|
else if ( ! is_function )
|
||||||
{
|
{
|
||||||
log_failure( "Error, expected identifier for typedef\n%s", Context.to_string() );
|
log_failure( "Error, expected identifier for typedef\n%s", Context.to_string() );
|
||||||
Context.pop();
|
Context.pop();
|
||||||
@ -4393,9 +4490,19 @@ CodeTypedef parse_typedef()
|
|||||||
CodeTypedef
|
CodeTypedef
|
||||||
result = (CodeTypedef) make_code();
|
result = (CodeTypedef) make_code();
|
||||||
result->Type = Typedef;
|
result->Type = Typedef;
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
result->ModuleFlags = mflags;
|
result->ModuleFlags = mflags;
|
||||||
|
|
||||||
|
if ( is_function )
|
||||||
|
{
|
||||||
|
result->Name = type->Name;
|
||||||
|
result->IsFunction = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result->Name = get_cached_string( name );
|
||||||
|
result->IsFunction = false;
|
||||||
|
}
|
||||||
|
|
||||||
result->UnderlyingType = type;
|
result->UnderlyingType = type;
|
||||||
|
|
||||||
if ( type->Type == Typename && array_expr && array_expr->Type != Invalid )
|
if ( type->Type == Typename && array_expr && array_expr->Type != Invalid )
|
||||||
|
@ -1221,7 +1221,6 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module
|
|||||||
{
|
{
|
||||||
using namespace ECode;
|
using namespace ECode;
|
||||||
|
|
||||||
name_check( def_typedef, name );
|
|
||||||
null_check( def_typedef, type );
|
null_check( def_typedef, type );
|
||||||
|
|
||||||
switch ( type->Type )
|
switch ( type->Type )
|
||||||
@ -1260,12 +1259,28 @@ CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes, Module
|
|||||||
|
|
||||||
CodeTypedef
|
CodeTypedef
|
||||||
result = (CodeTypedef) make_code();
|
result = (CodeTypedef) make_code();
|
||||||
result->Name = get_cached_string( name );
|
|
||||||
result->Type = ECode::Typedef;
|
result->Type = ECode::Typedef;
|
||||||
result->ModuleFlags = mflags;
|
result->ModuleFlags = mflags;
|
||||||
|
|
||||||
result->UnderlyingType = type;
|
result->UnderlyingType = type;
|
||||||
|
|
||||||
|
if ( name.Len <= 0 )
|
||||||
|
{
|
||||||
|
if (type->Type != Untyped)
|
||||||
|
{
|
||||||
|
log_failure( "gen::def_typedef: name was empty and type was not untyped (indicating its a function typedef) - %s", type.debug_str() );
|
||||||
|
return CodeInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
result->Name = get_cached_string( type->Name );
|
||||||
|
result->IsFunction = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result->Name = get_cached_string( name );
|
||||||
|
result->IsFunction = false;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,9 +424,16 @@ struct HashTable
|
|||||||
|
|
||||||
for ( idx = 0; idx < Entries.num(); idx++ )
|
for ( idx = 0; idx < Entries.num(); idx++ )
|
||||||
{
|
{
|
||||||
Entry* entry;
|
Entry* entry;
|
||||||
|
|
||||||
FindResult find_result;
|
FindResult find_result;
|
||||||
|
|
||||||
|
entry = & Entries[ idx ];
|
||||||
|
find_result = find( entry->Key );
|
||||||
|
|
||||||
|
if ( find_result.PrevIndex < 0 )
|
||||||
|
Hashes[ find_result.HashIndex ] = idx;
|
||||||
|
else
|
||||||
|
Entries[ find_result.PrevIndex ].Next = idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user