|
|
|
@ -1143,7 +1143,7 @@ internal CodeOpCast parse_operator_cast ();
|
|
|
|
|
internal CodeStruct parse_struct ( bool inplace_def = false );
|
|
|
|
|
internal CodeVar parse_variable ();
|
|
|
|
|
internal CodeTemplate parse_template ();
|
|
|
|
|
internal CodeType parse_type ();
|
|
|
|
|
internal CodeType parse_type ( bool* is_function = nullptr );
|
|
|
|
|
internal CodeTypedef parse_typedef ();
|
|
|
|
|
internal CodeUnion parse_union ( bool inplace_def = false );
|
|
|
|
|
internal CodeUsing parse_using ();
|
|
|
|
@ -2358,6 +2358,47 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
|
|
|
|
|
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
|
|
|
|
|
Code parse_complicated_definition( Parser::TokType which )
|
|
|
|
|
{
|
|
|
|
@ -2366,43 +2407,6 @@ Code parse_complicated_definition( Parser::TokType which )
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
s32 idx = tokens.Idx;
|
|
|
|
@ -2422,7 +2426,7 @@ Code parse_complicated_definition( Parser::TokType which )
|
|
|
|
|
if ( (idx - 2 ) == tokens.Idx )
|
|
|
|
|
{
|
|
|
|
|
// Its a forward declaration only
|
|
|
|
|
goto PARSE_FORWARD_OR_DEFINITION;
|
|
|
|
|
return parse_foward_or_definition( which, is_inplace );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Token tok = tokens[ idx - 1 ];
|
|
|
|
@ -2451,7 +2455,7 @@ Code parse_complicated_definition( Parser::TokType which )
|
|
|
|
|
else if ( is_indirection )
|
|
|
|
|
{
|
|
|
|
|
// Its a indirection type with type ID using struct namespace.
|
|
|
|
|
// <which> <type_identifier> <identifier>;
|
|
|
|
|
// <which> <type_identifier>* <identifier>;
|
|
|
|
|
ok_to_parse = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2470,7 +2474,7 @@ Code parse_complicated_definition( Parser::TokType which )
|
|
|
|
|
{
|
|
|
|
|
// Its a definition
|
|
|
|
|
// <which> { ... };
|
|
|
|
|
goto PARSE_FORWARD_OR_DEFINITION;
|
|
|
|
|
return parse_foward_or_definition( which, is_inplace );
|
|
|
|
|
}
|
|
|
|
|
else if ( tok.Type == TokType::BraceSquare_Close)
|
|
|
|
|
{
|
|
|
|
@ -4142,7 +4146,7 @@ CodeTemplate parse_template( StrC def )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal
|
|
|
|
|
CodeType parse_type()
|
|
|
|
|
CodeType parse_type( bool* is_function )
|
|
|
|
|
{
|
|
|
|
|
using namespace Parser;
|
|
|
|
|
push_scope();
|
|
|
|
@ -4258,13 +4262,24 @@ CodeType parse_type()
|
|
|
|
|
eat( currtok.Type );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BruteforceCaptureAgain:
|
|
|
|
|
if ( check( TokType::Capture_Start ) && context_tok.Type != TokType::Decl_Operator )
|
|
|
|
|
bool is_first_capture = true;
|
|
|
|
|
while ( check( TokType::Capture_Start ) && context_tok.Type != TokType::Decl_Operator )
|
|
|
|
|
{
|
|
|
|
|
// Brute force capture the entire thing.
|
|
|
|
|
// Function typedefs are complicated and there are not worth dealing with for validation at this point...
|
|
|
|
|
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;
|
|
|
|
|
while ( left && ( currtok.Type != TokType::Capture_End || level > 0 ))
|
|
|
|
|
{
|
|
|
|
@ -4276,11 +4291,10 @@ BruteforceCaptureAgain:
|
|
|
|
|
|
|
|
|
|
eat( currtok.Type );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eat( TokType::Capture_End );
|
|
|
|
|
|
|
|
|
|
goto BruteforceCaptureAgain;
|
|
|
|
|
|
|
|
|
|
brute_sig.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)brute_sig.Text;
|
|
|
|
|
is_first_capture = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using namespace ECode;
|
|
|
|
@ -4331,9 +4345,10 @@ CodeTypedef parse_typedef()
|
|
|
|
|
using namespace Parser;
|
|
|
|
|
push_scope();
|
|
|
|
|
|
|
|
|
|
Token name = { nullptr, 0, TokType::Invalid };
|
|
|
|
|
Code array_expr = { nullptr };
|
|
|
|
|
Code type = { nullptr };
|
|
|
|
|
bool is_function = false;
|
|
|
|
|
Token name = { nullptr, 0, TokType::Invalid };
|
|
|
|
|
Code array_expr = { nullptr };
|
|
|
|
|
Code type = { nullptr };
|
|
|
|
|
|
|
|
|
|
ModuleFlag mflags = ModuleFlag::None;
|
|
|
|
|
|
|
|
|
@ -4356,27 +4371,109 @@ CodeTypedef parse_typedef()
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ( check( TokType::Decl_Enum ) )
|
|
|
|
|
type = parse_enum( from_typedef );
|
|
|
|
|
bool is_complicated =
|
|
|
|
|
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 ) )
|
|
|
|
|
type = parse_class( from_typedef );
|
|
|
|
|
if ( is_complicated )
|
|
|
|
|
{
|
|
|
|
|
TokArray tokens = Context.Tokens;
|
|
|
|
|
|
|
|
|
|
else if ( check(TokType::Decl_Struct ) )
|
|
|
|
|
type = parse_struct( from_typedef );
|
|
|
|
|
s32 idx = tokens.Idx;
|
|
|
|
|
s32 level = 0;
|
|
|
|
|
for ( ; idx < tokens.Arr.num(); idx ++ )
|
|
|
|
|
{
|
|
|
|
|
if ( tokens[idx].Type == TokType::BraceCurly_Open )
|
|
|
|
|
level++;
|
|
|
|
|
|
|
|
|
|
else if ( check(TokType::Decl_Union) )
|
|
|
|
|
type = parse_union( from_typedef );
|
|
|
|
|
if ( tokens[idx].Type == TokType::BraceCurly_Close )
|
|
|
|
|
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
|
|
|
|
|
type = parse_type();
|
|
|
|
|
type = parse_type( & is_function );
|
|
|
|
|
|
|
|
|
|
if ( check( TokType::Identifier ) )
|
|
|
|
|
{
|
|
|
|
|
name = currtok;
|
|
|
|
|
eat( TokType::Identifier );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
else if ( ! is_function )
|
|
|
|
|
{
|
|
|
|
|
log_failure( "Error, expected identifier for typedef\n%s", Context.to_string() );
|
|
|
|
|
Context.pop();
|
|
|
|
@ -4393,9 +4490,19 @@ CodeTypedef parse_typedef()
|
|
|
|
|
CodeTypedef
|
|
|
|
|
result = (CodeTypedef) make_code();
|
|
|
|
|
result->Type = Typedef;
|
|
|
|
|
result->Name = get_cached_string( name );
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if ( type->Type == Typename && array_expr && array_expr->Type != Invalid )
|
|
|
|
|