Added constructor and destructor supported (UNTESTED)

Just compiles and generates...

Also fixed a bug where parsing didn't have a token for virtual specifiers...
This commit is contained in:
Edward R. Gonzalez 2023-08-07 03:10:45 -04:00
parent c2319b9651
commit c2f8c8aeb1
17 changed files with 511 additions and 72 deletions

View File

@ -145,6 +145,70 @@ String AST::to_string()
} }
break; break;
case Constructor:
{
result.append( Parent->Name );
if ( Params )
result.append_fmt( "( %s )", Params->to_string() );
else
result.append( "(void)" );
if ( InitializerList )
result.append_fmt( " : %s", InitializerList->to_string() );
result.append_fmt( "\n{\n%s\n}", Body->to_string() );
}
break;
case Constructor_Fwd:
{
result.append( Parent->Name );
if ( Params )
result.append_fmt( "( %s )", Params->to_string() );
else
result.append( "(void);" );
}
break;
case Destructor:
{
if ( Specs )
{
CodeSpecifiers specs = Specs->cast<CodeSpecifiers>();
if ( specs.has( ESpecifier::Virtual ) )
result.append_fmt( "virtual ~%s()", Parent->Name );
else
result.append_fmt( "~%s()", Parent->Name );
}
else
result.append_fmt( "~%s()", Parent->Name );
result.append_fmt( "\n{\n%s\n}", Body->to_string() );
}
break;
case Destructor_Fwd:
{
if ( Specs )
{
CodeSpecifiers specs = Specs->cast<CodeSpecifiers>();
if ( specs.has( ESpecifier::Virtual ) )
result.append_fmt( "virtual ~%s();", Parent->Name );
else
result.append_fmt( "~%s()", Parent->Name );
if ( specs.has( ESpecifier::Pure ) )
result.append( " = 0;" );
}
else
result.append_fmt( "~%s();", Parent->Name );
}
break;
case Enum: case Enum:
{ {
if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export ))

View File

@ -2,8 +2,10 @@ struct AST;
struct AST_Body; struct AST_Body;
struct AST_Attributes; struct AST_Attributes;
struct AST_Comment; struct AST_Comment;
struct AST_Constructor;
struct AST_Class; struct AST_Class;
struct AST_Define; struct AST_Define;
struct AST_Destructor;
struct AST_Enum; struct AST_Enum;
struct AST_Exec; struct AST_Exec;
struct AST_Extern; struct AST_Extern;
@ -31,6 +33,8 @@ struct CodeBody;
// These are to offer ease of use and optionally strong type safety for the AST. // These are to offer ease of use and optionally strong type safety for the AST.
struct CodeAttributes; struct CodeAttributes;
struct CodeComment; struct CodeComment;
struct CodeConstructor;
struct CodeDestructor;
struct CodeClass; struct CodeClass;
struct CodeDefine; struct CodeDefine;
struct CodeEnum; struct CodeEnum;
@ -108,6 +112,8 @@ struct Code
#endif #endif
operator CodeAttributes() const; operator CodeAttributes() const;
operator CodeComment() const; operator CodeComment() const;
operator CodeConstructor() const;
operator CodeDestructor() const;
operator CodeClass() const; operator CodeClass() const;
operator CodeDefine() const; operator CodeDefine() const;
operator CodeExec() const; operator CodeExec() const;
@ -171,6 +177,8 @@ struct AST
operator CodeBody(); operator CodeBody();
operator CodeAttributes(); operator CodeAttributes();
operator CodeComment(); operator CodeComment();
operator CodeConstructor();
operator CodeDestructor();
operator CodeClass(); operator CodeClass();
operator CodeDefine(); operator CodeDefine();
operator CodeEnum(); operator CodeEnum();
@ -214,18 +222,19 @@ struct AST
AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
AST* Specs; // Function, Operator, Type symbol, Variable AST* Specs; // Function, Operator, Type symbol, Variable
union { union {
AST* ParentType; // Class, Struct AST* InitializerList; // Constructor, Destructor
AST* ReturnType; // Function, Operator AST* ParentType; // Class, Struct
AST* UnderlyingType; // Enum, Typedef AST* ReturnType; // Function, Operator
AST* ValueType; // Parameter, Variable AST* UnderlyingType; // Enum, Typedef
AST* ValueType; // Parameter, Variable
}; };
union { union {
AST* Params; // Function, Operator, Template AST* BitfieldSize; // Varaiable (Class/Struct Data Member)
AST* BitfieldSize; // Varaiable (Class/Struct Data Member) AST* Params; // Function, Operator, Template
}; };
union { union {
AST* ArrExpr; // Type Symbol AST* ArrExpr; // Type Symbol
AST* Body; // Class, Enum, Function, Namespace, Struct, Union AST* Body; // Class, Constructr, Destructor, Enum, Function, Namespace, Struct, Union
AST* Declaration; // Friend, Template AST* Declaration; // Friend, Template
AST* Value; // Parameter, Variable AST* Value; // Parameter, Variable
}; };
@ -261,18 +270,19 @@ struct AST_POD
AST* Attributes; // Class, Enum, Function, Struct, Typename, Union, Using, Variable AST* Attributes; // Class, Enum, Function, Struct, Typename, Union, Using, Variable
AST* Specs; // Function, Operator, Type symbol, Variable AST* Specs; // Function, Operator, Type symbol, Variable
union { union {
AST* ParentType; // Class, Struct AST* InitializerList; // Constructor, Destructor
AST* ReturnType; // Function, Operator AST* ParentType; // Class, Struct
AST* UnderlyingType; // Enum, Typedef AST* ReturnType; // Function, Operator
AST* ValueType; // Parameter, Variable AST* UnderlyingType; // Enum, Typedef
AST* ValueType; // Parameter, Variable
}; };
union { union {
AST* Params; // Function, Operator, Template AST* BitfieldSize; // Varaiable (Class/Struct Data Member)
AST* BitfieldSize; // Varaiable (Class/Struct Data Member) AST* Params; // Function, Operator, Template
}; };
union { union {
AST* ArrExpr; // Type Symbol AST* ArrExpr; // Type Symbol
AST* Body; // Class, Enum, Function, Namespace, Struct, Union AST* Body; // Class, Constructr, Destructor, Enum, Function, Namespace, Struct, Union
AST* Declaration; // Friend, Template AST* Declaration; // Friend, Template
AST* Value; // Parameter, Variable AST* Value; // Parameter, Variable
}; };
@ -536,7 +546,9 @@ struct CodeStruct
Define_CodeType( Attributes ); Define_CodeType( Attributes );
Define_CodeType( Comment ); Define_CodeType( Comment );
Define_CodeType( Constructor );
Define_CodeType( Define ); Define_CodeType( Define );
Define_CodeType( Destructor );
Define_CodeType( Enum ); Define_CodeType( Enum );
Define_CodeType( Exec ); Define_CodeType( Exec );
Define_CodeType( Extern ); Define_CodeType( Extern );

View File

@ -71,6 +71,27 @@ struct AST_Class
}; };
static_assert( sizeof(AST_Class) == sizeof(AST), "ERROR: AST_Class is not the same size as AST"); static_assert( sizeof(AST_Class) == sizeof(AST), "ERROR: AST_Class is not the same size as AST");
struct AST_Constructor
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
struct
{
char _PAD_PROPERTIES_ [ sizeof(AST*) * 3 ];
Code InitializerList;
CodeParam Params;
Code Body;
};
};
Code Prev;
Code Next;
Code Parent;
StringCached Name;
CodeT Type;
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
};
static_assert( sizeof(AST_Constructor) == sizeof(AST), "ERROR: AST_Constructor is not the same size as AST");
struct AST_Define struct AST_Define
{ {
union { union {
@ -86,6 +107,27 @@ struct AST_Define
}; };
static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the same size as AST"); static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the same size as AST");
struct AST_Destructor
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
struct
{
char _PAD_PROPERTIES_ [ sizeof(AST*) * 1 ];
CodeSpecifiers Specs;
char _PAD_PROPERTIES_2_ [ sizeof(AST*) * 2 ];
Code Body;
};
};
Code Prev;
Code Next;
Code Parent;
StringCached Name;
CodeT Type;
char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ];
};
static_assert( sizeof(AST_Destructor) == sizeof(AST), "ERROR: AST_Destructor is not the same size as AST");
struct AST_Enum struct AST_Enum
{ {
union { union {

View File

@ -81,6 +81,7 @@ extern CodeSpecifiers spec_mutable;
extern CodeSpecifiers spec_neverinline; extern CodeSpecifiers spec_neverinline;
extern CodeSpecifiers spec_override; extern CodeSpecifiers spec_override;
extern CodeSpecifiers spec_ptr; extern CodeSpecifiers spec_ptr;
extern CodeSpecifiers spec_pure;
extern CodeSpecifiers spec_ref; extern CodeSpecifiers spec_ref;
extern CodeSpecifiers spec_register; extern CodeSpecifiers spec_register;
extern CodeSpecifiers spec_rvalue; extern CodeSpecifiers spec_rvalue;

View File

@ -197,6 +197,7 @@ void define_constants()
def_constant_spec( neverinline, ESpecifier::NeverInline ); def_constant_spec( neverinline, ESpecifier::NeverInline );
def_constant_spec( override, ESpecifier::Override ); def_constant_spec( override, ESpecifier::Override );
def_constant_spec( ptr, ESpecifier::Ptr ); def_constant_spec( ptr, ESpecifier::Ptr );
def_constant_spec( pure, ESpecifier::Pure )
def_constant_spec( ref, ESpecifier::Ref ); def_constant_spec( ref, ESpecifier::Ref );
def_constant_spec( register, ESpecifier::Register ); def_constant_spec( register, ESpecifier::Register );
def_constant_spec( rvalue, ESpecifier::RValue ); def_constant_spec( rvalue, ESpecifier::RValue );

View File

@ -45,8 +45,12 @@ CodeClass def_class( StrC name
, ModuleFlag mflags = ModuleFlag::None , ModuleFlag mflags = ModuleFlag::None
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 ); , CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
CodeConstructor def_constructor( CodeParam params = NoCode, Code initializer_list = NoCode, Code body = NoCode );
CodeDefine def_define( StrC name, StrC content ); CodeDefine def_define( StrC name, StrC content );
CodeDestructor def_destructor( Code body = NoCode, CodeSpecifiers specifiers = NoCode );
CodeEnum def_enum( StrC name CodeEnum def_enum( StrC name
, Code body = NoCode, CodeType type = NoCode , Code body = NoCode, CodeType type = NoCode
, EnumT specifier = EnumRegular, CodeAttributes attributes = NoCode , EnumT specifier = EnumRegular, CodeAttributes attributes = NoCode
@ -136,23 +140,25 @@ CodeBody def_union_body ( s32 num, Code* codes );
#pragma region Parsing #pragma region Parsing
CodeClass parse_class ( StrC class_def ); CodeClass parse_class ( StrC class_def );
CodeEnum parse_enum ( StrC enum_def ); CodeConstructor parse_constructor ( StrC constructor_def );
CodeBody parse_export_body ( StrC export_def ); CodeDestructor parse_destructor ( StrC destructor_def );
CodeExtern parse_extern_link ( StrC exten_link_def); CodeEnum parse_enum ( StrC enum_def );
CodeFriend parse_friend ( StrC friend_def ); CodeBody parse_export_body ( StrC export_def );
CodeFn parse_function ( StrC fn_def ); CodeExtern parse_extern_link ( StrC exten_link_def );
CodeBody parse_global_body ( StrC body_def ); CodeFriend parse_friend ( StrC friend_def );
CodeNS parse_namespace ( StrC namespace_def ); CodeFn parse_function ( StrC fn_def );
CodeOperator parse_operator ( StrC operator_def ); CodeBody parse_global_body ( StrC body_def );
CodeOpCast parse_operator_cast( StrC operator_def ); CodeNS parse_namespace ( StrC namespace_def );
CodeStruct parse_struct ( StrC struct_def ); CodeOperator parse_operator ( StrC operator_def );
CodeTemplate parse_template ( StrC template_def ); CodeOpCast parse_operator_cast( StrC operator_def );
CodeType parse_type ( StrC type_def ); CodeStruct parse_struct ( StrC struct_def );
CodeTypedef parse_typedef ( StrC typedef_def ); CodeTemplate parse_template ( StrC template_def );
CodeUnion parse_union ( StrC union_def ); CodeType parse_type ( StrC type_def );
CodeUsing parse_using ( StrC using_def ); CodeTypedef parse_typedef ( StrC typedef_def );
CodeVar parse_variable ( StrC var_def ); CodeUnion parse_union ( StrC union_def );
CodeUsing parse_using ( StrC using_def );
CodeVar parse_variable ( StrC var_def );
#pragma endregion Parsing #pragma endregion Parsing

View File

@ -89,6 +89,21 @@ namespace Parser
return Arr[idx - 1]; return Arr[idx - 1];
} }
Token& next( bool skip_new_lines = false )
{
s32 idx = this->Idx;
if ( skip_new_lines )
{
while ( Arr[idx].Type == TokType::NewLine )
idx++;
return Arr[idx];
}
return Arr[idx + 1];
}
Token& operator []( s32 idx ) Token& operator []( s32 idx )
{ {
return Arr[idx]; return Arr[idx];
@ -1098,6 +1113,7 @@ if ( def.Ptr == nullptr ) \
# define currtok_noskip Context.Tokens.current( dont_skip_new_lines ) # define currtok_noskip Context.Tokens.current( dont_skip_new_lines )
# define currtok Context.Tokens.current() # define currtok Context.Tokens.current()
# define prevtok Context.Tokens.previous() # define prevtok Context.Tokens.previous()
# define nexttok Context.Tokens.next()
# define eat( Type_ ) Context.Tokens.__eat( Type_ ) # define eat( Type_ ) Context.Tokens.__eat( Type_ )
# define left ( Context.Tokens.Arr.num() - Context.Tokens.Idx ) # define left ( Context.Tokens.Arr.num() - Context.Tokens.Idx )
@ -1113,22 +1129,24 @@ if ( def.Ptr == nullptr ) \
internal Code parse_function_body(); internal Code parse_function_body();
internal Code parse_global_nspace(); internal Code parse_global_nspace();
internal CodeClass parse_class ( bool inplace_def = false ); internal CodeClass parse_class ( bool inplace_def = false );
internal CodeEnum parse_enum ( bool inplace_def = false ); internal CodeConstructor parse_constructor ();
internal CodeBody parse_export_body (); internal CodeDestructor parse_destructor ( CodeSpecifiers specifiers = NoCode );
internal CodeBody parse_extern_link_body(); internal CodeEnum parse_enum ( bool inplace_def = false );
internal CodeExtern parse_exten_link (); internal CodeBody parse_export_body ();
internal CodeFriend parse_friend (); internal CodeBody parse_extern_link_body();
internal CodeFn parse_function (); internal CodeExtern parse_exten_link ();
internal CodeNS parse_namespace (); internal CodeFriend parse_friend ();
internal CodeOpCast parse_operator_cast (); internal CodeFn parse_function ();
internal CodeStruct parse_struct ( bool inplace_def = false ); internal CodeNS parse_namespace ();
internal CodeVar parse_variable (); internal CodeOpCast parse_operator_cast ();
internal CodeTemplate parse_template (); internal CodeStruct parse_struct ( bool inplace_def = false );
internal CodeType parse_type (); internal CodeVar parse_variable ();
internal CodeTypedef parse_typedef (); internal CodeTemplate parse_template ();
internal CodeUnion parse_union ( bool inplace_def = false ); internal CodeType parse_type ();
internal CodeUsing parse_using (); internal CodeTypedef parse_typedef ();
internal CodeUnion parse_union ( bool inplace_def = false );
internal CodeUsing parse_using ();
constexpr bool inplace_def = true; constexpr bool inplace_def = true;
@ -2471,7 +2489,7 @@ Code parse_complicated_definition( Parser::TokType which )
} }
internal internal
CodeBody parse_class_struct_body( Parser::TokType which ) CodeBody parse_class_struct_body( Parser::TokType which, Parser::Token name = Parser::NullToken )
{ {
using namespace Parser; using namespace Parser;
using namespace ECode; using namespace ECode;
@ -2566,6 +2584,16 @@ CodeBody parse_class_struct_body( Parser::TokType which )
member = parse_using(); member = parse_using();
break; break;
case TokType::Operator:
if ( currtok.Text[0] != '~' )
{
log_failure( "Operator token found in global body but not destructor unary negation\n%s", Context.to_string() );
return CodeInvalid;
}
member = parse_destructor();
break;
case TokType::Preprocess_Define: case TokType::Preprocess_Define:
member = parse_define(); member = parse_define();
break; break;
@ -2661,6 +2689,12 @@ CodeBody parse_class_struct_body( Parser::TokType which )
{ {
specifiers = def_specifiers( NumSpecifiers, specs_found ); specifiers = def_specifiers( NumSpecifiers, specs_found );
} }
if ( currtok.Type == TokType::Operator && currtok.Text[0] == '~' )
{
member = parse_destructor( specifiers );
break;
}
} }
//! Fallthrough intentional //! Fallthrough intentional
case TokType::Identifier: case TokType::Identifier:
@ -2673,6 +2707,15 @@ CodeBody parse_class_struct_body( Parser::TokType which )
case TokType::Type_int: case TokType::Type_int:
case TokType::Type_double: case TokType::Type_double:
{ {
if ( nexttok.Type == TokType::Capture_Start && name.Length && currtok.Type == TokType::Identifier )
{
if ( str_compare( name.Text, currtok.Text, name.Length ) == 0 )
{
member = parse_constructor();
break;
}
}
member = parse_operator_function_or_variable( expects_function, attributes, specifiers ); member = parse_operator_function_or_variable( expects_function, attributes, specifiers );
} }
break; break;
@ -2775,7 +2818,7 @@ Code parse_class_struct( Parser::TokType which, bool inplace_def = false )
if ( check( TokType::BraceCurly_Open ) ) if ( check( TokType::BraceCurly_Open ) )
{ {
body = parse_class_struct_body( which ); body = parse_class_struct_body( which, name );
} }
if ( ! inplace_def ) if ( ! inplace_def )
@ -3122,6 +3165,158 @@ CodeClass parse_class( StrC def )
return result; return result;
} }
internal
CodeConstructor parse_constructor()
{
using namespace Parser;
push_scope();
Token identifier = parse_identifier();
CodeParam params = parse_params();
Code initializer_list = { nullptr };
CodeBody body = { nullptr };
if ( check( TokType::Assign_Classifer ) )
{
eat( TokType::Assign_Classifer );
Token initializer_list_tok;
s32 level = 0;
while ( left && ( currtok.Type != TokType::BraceCurly_Open || level > 0 ) )
{
if ( currtok.Type == TokType::BraceCurly_Open )
level++;
else if ( currtok.Type == TokType::BraceCurly_Close )
level--;
eat( currtok.Type );
}
initializer_list_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)initializer_list_tok.Text;
initializer_list = untyped_str( initializer_list_tok );
body = parse_function_body();
}
else if ( check( TokType::BraceCurly_Open ) )
{
body = parse_function_body();
}
CodeConstructor result = (CodeConstructor) make_code();
if ( params )
result->Params = params;
if ( initializer_list )
result->InitializerList = initializer_list;
if ( body )
{
result->Body = body;
result->Type = ECode::Constructor;
}
else
result->Type = ECode::Constructor_Fwd;
Context.pop();
return result;
}
CodeConstructor parse_constructor( StrC def )
{
check_parse_args( def );
using namespace Parser;
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
return CodeInvalid;
Context.Tokens = toks;
CodeConstructor result = parse_constructor();
return result;
}
internal
CodeDestructor parse_destructor( CodeSpecifiers specifiers )
{
using namespace Parser;
push_scope();
if ( check( TokType::Spec_Virtual ) )
{
if ( specifiers )
specifiers.append( ESpecifier::Virtual );
else
specifiers = def_specifier( ESpecifier::Virtual );
eat( TokType::Spec_Virtual );
}
if ( left && currtok.Text[0] == '~' )
eat( TokType::Operator );
else
{
log_failure( "Expected destructor '~' token\n%s", Context.to_string() );
return CodeInvalid;
}
Token identifier = parse_identifier();
CodeBody body = { nullptr };
eat( TokType::Capture_Start );
eat( TokType::Capture_End );
if ( check( TokType::Operator ) && currtok.Text[0] == '=' )
{
eat( TokType::Operator );
if ( left && currtok.Text[0] == '0' )
{
eat( TokType::Number );
specifiers.append( ESpecifier::Pure );
}
else
{
log_failure( "Pure specifier expected due to '=' token\n%s", Context.to_string() );
return CodeInvalid;
}
}
if ( check( TokType::BraceCurly_Open ) )
body = parse_function_body();
CodeDestructor result = (CodeDestructor) make_code();
if ( specifiers )
result->Specs = specifiers;
if ( body )
{
result->Body = body;
result->Type = ECode::Destructor;
}
else
result->Type = ECode::Destructor_Fwd;
Context.pop();
return result;
}
CodeDestructor parse_destructor( StrC def )
{
check_parse_args( def );
using namespace Parser;
TokArray toks = lex( def );
if ( toks.Arr == nullptr )
return CodeInvalid;
Context.Tokens = toks;
CodeDestructor result = parse_destructor();
return result;
}
internal internal
CodeEnum parse_enum( bool inplace_def ) CodeEnum parse_enum( bool inplace_def )
{ {
@ -3474,7 +3669,7 @@ CodeFn parse_functon()
s32 NumSpecifiers = 0; s32 NumSpecifiers = 0;
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifiers specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag::None;
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
@ -4550,6 +4745,7 @@ CodeVar parse_variable( StrC def )
# undef check_parse_args # undef check_parse_args
# undef currtok # undef currtok
# undef prevtok # undef prevtok
# undef nexttok
# undef eat # undef eat
# undef left # undef left
# undef check # undef check

View File

@ -422,6 +422,53 @@ CodeComment def_comment( StrC content )
return (CodeComment) result; return (CodeComment) result;
} }
CodeConstructor def_constructor( CodeParam params, Code initializer_list, Code body )
{
using namespace ECode;
if ( params && params->Type != Parameters )
{
log_failure("gen::def_constructor: params must be of Parameters type - %s", params.debug_str());
return CodeInvalid;
}
CodeConstructor
result = (CodeConstructor) make_code();
if ( params )
{
result->Params = params;
}
if ( initializer_list )
{
result->InitializerList = initializer_list;
}
if ( body )
{
switch ( body->Type )
{
case Function_Body:
case Untyped:
break;
default:
log_failure("gen::def_constructor: body must be either of Function_Body or Untyped type - %s", body.debug_str());
return CodeInvalid;
}
result->Type = Constructor;
result->Body = body;
}
else
{
result->Type = Constructor_Fwd;
}
return result;
}
CodeClass def_class( StrC name CodeClass def_class( StrC name
, Code body , Code body
, CodeType parent, AccessSpec parent_access , CodeType parent, AccessSpec parent_access
@ -512,6 +559,45 @@ CodeDefine def_define( StrC name, StrC content )
return result; return result;
} }
CodeDestructor def_destructor( Code body, CodeSpecifiers specifiers )
{
using namespace ECode;
if ( specifiers && specifiers->Type != Specifiers )
{
log_failure( "gen::def_destructor: specifiers was not a 'Specifiers' type: %s", specifiers.debug_str() );
return CodeInvalid;
}
CodeDestructor result = (CodeDestructor) make_code();
if ( specifiers )
result->Specs = specifiers;
if ( body )
{
switch ( body->Type )
{
case Function_Body:
case Untyped:
break;
default:
log_failure("gen::def_destructor: body must be either of Function_Body or Untyped type - %s", body.debug_str());
return CodeInvalid;
}
result->Type = Destructor;
result->Body = body;
}
else
{
result->Type = Destructor_Fwd;
}
return result;
}
CodeEnum def_enum( StrC name CodeEnum def_enum( StrC name
, Code body, CodeType type , Code body, CodeType type
, EnumT specifier, CodeAttributes attributes , EnumT specifier, CodeAttributes attributes

View File

@ -55,6 +55,7 @@ global CodeSpecifiers spec_mutable;
global CodeSpecifiers spec_neverinline; global CodeSpecifiers spec_neverinline;
global CodeSpecifiers spec_override; global CodeSpecifiers spec_override;
global CodeSpecifiers spec_ptr; global CodeSpecifiers spec_ptr;
global CodeSpecifiers spec_pure;
global CodeSpecifiers spec_ref; global CodeSpecifiers spec_ref;
global CodeSpecifiers spec_register; global CodeSpecifiers spec_register;
global CodeSpecifiers spec_rvalue; global CodeSpecifiers spec_rvalue;

View File

@ -102,7 +102,9 @@ Define_CodeImpl( CodeBody );
Define_CodeImpl( CodeAttributes ); Define_CodeImpl( CodeAttributes );
Define_CodeImpl( CodeComment ); Define_CodeImpl( CodeComment );
Define_CodeImpl( CodeClass ); Define_CodeImpl( CodeClass );
Define_CodeImpl( CodeConstructor );
Define_CodeImpl( CodeDefine ); Define_CodeImpl( CodeDefine );
Define_CodeImpl( CodeDestructor );
Define_CodeImpl( CodeEnum ); Define_CodeImpl( CodeEnum );
Define_CodeImpl( CodeExec ); Define_CodeImpl( CodeExec );
Define_CodeImpl( CodeExtern ); Define_CodeImpl( CodeExtern );
@ -127,7 +129,9 @@ Define_CodeImpl( CodeVar );
Define_CodeType_Impl( Attributes ); Define_CodeType_Impl( Attributes );
Define_CodeType_Impl( Comment ); Define_CodeType_Impl( Comment );
Define_CodeType_Impl( Constructor );
Define_CodeType_Impl( Define ); Define_CodeType_Impl( Define );
Define_CodeType_Impl( Destructor );
Define_CodeType_Impl( Enum ); Define_CodeType_Impl( Enum );
Define_CodeType_Impl( Exec ); Define_CodeType_Impl( Exec );
Define_CodeType_Impl( Extern ); Define_CodeType_Impl( Extern );
@ -159,8 +163,10 @@ AST::operator Code ## typename() \
Define_AST_Cast( Body ); Define_AST_Cast( Body );
Define_AST_Cast( Attributes ); Define_AST_Cast( Attributes );
Define_AST_Cast( Comment ); Define_AST_Cast( Comment );
Define_AST_Cast( Constructor );
Define_AST_Cast( Class ); Define_AST_Cast( Class );
Define_AST_Cast( Define ); Define_AST_Cast( Define );
Define_AST_Cast( Destructor );
Define_AST_Cast( Enum ); Define_AST_Cast( Enum );
Define_AST_Cast( Exec ); Define_AST_Cast( Exec );
Define_AST_Cast( Extern ); Define_AST_Cast( Extern );
@ -192,8 +198,10 @@ Code::operator Code ## type() const \
Define_CodeCast( Attributes ); Define_CodeCast( Attributes );
Define_CodeCast( Comment ); Define_CodeCast( Comment );
Define_CodeCast( Constructor );
Define_CodeCast( Class ); Define_CodeCast( Class );
Define_CodeCast( Define ); Define_CodeCast( Define );
Define_CodeCast( Destructor );
Define_CodeCast( Exec ); Define_CodeCast( Exec );
Define_CodeCast( Enum ); Define_CodeCast( Enum );
Define_CodeCast( Extern ); Define_CodeCast( Extern );

View File

@ -14,6 +14,10 @@ namespace ECode
Entry( Class ) \ Entry( Class ) \
Entry( Class_Fwd ) \ Entry( Class_Fwd ) \
Entry( Class_Body ) \ Entry( Class_Body ) \
Entry( Constructor ) \
Entry( Constructor_Fwd ) \
Entry( Destructor ) \
Entry( Destructor_Fwd ) \
Entry( Enum ) \ Entry( Enum ) \
Entry( Enum_Fwd ) \ Entry( Enum_Fwd ) \
Entry( Enum_Body ) \ Entry( Enum_Body ) \

View File

@ -31,7 +31,8 @@ namespace ESpecifier
Entry( Virtual, virtual ) \ Entry( Virtual, virtual ) \
Entry( Const, const ) \ Entry( Const, const ) \
Entry( Final, final ) \ Entry( Final, final ) \
Entry( Override, override ) Entry( Override, override ) \
Entry( Pure, = 0 )
enum Type : u32 enum Type : u32
{ {

View File

@ -88,6 +88,7 @@ namespace Parser
Entry( Spec_Override, "override" ) \ Entry( Spec_Override, "override" ) \
Entry( Spec_Static, "static" ) \ Entry( Spec_Static, "static" ) \
Entry( Spec_ThreadLocal, "thread_local" ) \ Entry( Spec_ThreadLocal, "thread_local" ) \
Entry( Spec_Virtual, "virtual" ) \
Entry( Spec_Volatile, "volatile") \ Entry( Spec_Volatile, "volatile") \
Entry( Star, "*" ) \ Entry( Star, "*" ) \
Entry( Statement_End, ";" ) \ Entry( Statement_End, ";" ) \

View File

@ -9,6 +9,10 @@ PlatformAttributes
Class Class
Class_Fwd Class_Fwd
Class_Body Class_Body
Constructor
Constructor_Fwd
Destructor
Destructor_Fwd
Enum Enum
Enum_Fwd Enum_Fwd
Enum_Body Enum_Body

1 Invalid
9 Class
10 Class_Fwd
11 Class_Body
12 Constructor
13 Constructor_Fwd
14 Destructor
15 Destructor_Fwd
16 Enum
17 Enum_Fwd
18 Enum_Body

View File

@ -21,3 +21,4 @@ Virtual, virtual
Const, const Const, const
Final, final Final, final
Override, override Override, override
Pure, = 0

1 Invalid INVALID
21 Const const
22 Final final
23 Override override
24 Pure = 0

View File

@ -71,6 +71,7 @@ Spec_Override, "override"
Spec_Static, "static" Spec_Static, "static"
Spec_ThreadLocal, "thread_local" Spec_ThreadLocal, "thread_local"
Spec_Volatile, "volatile" Spec_Volatile, "volatile"
Spec_Virtual, "virtual"
Star, "*" Star, "*"
Statement_End, ";" Statement_End, ";"
StaticAssert, "static_assert" StaticAssert, "static_assert"

1 Invalid __invalid__
71 Spec_Static static
72 Spec_ThreadLocal thread_local
73 Spec_Volatile volatile
74 Spec_Virtual virtual
75 Star *
76 Statement_End ;
77 StaticAssert static_assert

View File

@ -437,8 +437,10 @@ CodeBody gen_ast_inlines()
CodeBody impl_code_body = parse_global_body( token_fmt( "typename", StrC name(CodeBody), code_impl_tmpl )); CodeBody impl_code_body = parse_global_body( token_fmt( "typename", StrC name(CodeBody), code_impl_tmpl ));
CodeBody impl_code_attr = parse_global_body( token_fmt( "typename", StrC name(CodeAttributes), code_impl_tmpl )); CodeBody impl_code_attr = parse_global_body( token_fmt( "typename", StrC name(CodeAttributes), code_impl_tmpl ));
CodeBody impl_code_cmt = parse_global_body( token_fmt( "typename", StrC name(CodeComment), code_impl_tmpl )); CodeBody impl_code_cmt = parse_global_body( token_fmt( "typename", StrC name(CodeComment), code_impl_tmpl ));
CodeBody impl_code_constr = parse_global_body( token_fmt( "typename", StrC name(CodeConstructor), code_impl_tmpl ));
CodeBody impl_code_class = parse_global_body( token_fmt( "typename", StrC name(CodeClass), code_impl_tmpl )); CodeBody impl_code_class = parse_global_body( token_fmt( "typename", StrC name(CodeClass), code_impl_tmpl ));
CodeBody impl_code_define = parse_global_body( token_fmt( "typename", StrC name(CodeDefine), code_impl_tmpl )); CodeBody impl_code_define = parse_global_body( token_fmt( "typename", StrC name(CodeDefine), code_impl_tmpl ));
CodeBody impl_code_destruct = parse_global_body( token_fmt( "typename", StrC name(CodeDestructor), code_impl_tmpl ));
CodeBody impl_code_enum = parse_global_body( token_fmt( "typename", StrC name(CodeEnum), code_impl_tmpl )); CodeBody impl_code_enum = parse_global_body( token_fmt( "typename", StrC name(CodeEnum), code_impl_tmpl ));
CodeBody impl_code_exec = parse_global_body( token_fmt( "typename", StrC name(CodeExec), code_impl_tmpl )); CodeBody impl_code_exec = parse_global_body( token_fmt( "typename", StrC name(CodeExec), code_impl_tmpl ));
CodeBody impl_code_extern = parse_global_body( token_fmt( "typename", StrC name(CodeExtern), code_impl_tmpl )); CodeBody impl_code_extern = parse_global_body( token_fmt( "typename", StrC name(CodeExtern), code_impl_tmpl ));
@ -461,27 +463,29 @@ CodeBody gen_ast_inlines()
CodeBody impl_code_using = parse_global_body( token_fmt( "typename", StrC name(CodeUsing), code_impl_tmpl )); CodeBody impl_code_using = parse_global_body( token_fmt( "typename", StrC name(CodeUsing), code_impl_tmpl ));
CodeBody impl_code_var = parse_global_body( token_fmt( "typename", StrC name(CodeVar), code_impl_tmpl )); CodeBody impl_code_var = parse_global_body( token_fmt( "typename", StrC name(CodeVar), code_impl_tmpl ));
impl_code_attr. append( parse_global_body( token_fmt( "typename", StrC name(Attributes), codetype_impl_tmpl ))); impl_code_attr. append( parse_global_body( token_fmt( "typename", StrC name(Attributes), codetype_impl_tmpl )));
impl_code_cmt. append( parse_global_body( token_fmt( "typename", StrC name(Comment), codetype_impl_tmpl ))); impl_code_cmt. append( parse_global_body( token_fmt( "typename", StrC name(Comment), codetype_impl_tmpl )));
impl_code_define. append( parse_global_body( token_fmt( "typename", StrC name(Define), codetype_impl_tmpl ))); impl_code_constr. append( parse_global_body( token_fmt( "typename", StrC name(Constructor), codetype_impl_tmpl )));
impl_code_enum. append( parse_global_body( token_fmt( "typename", StrC name(Enum), codetype_impl_tmpl ))); impl_code_define. append( parse_global_body( token_fmt( "typename", StrC name(Define), codetype_impl_tmpl )));
impl_code_exec. append( parse_global_body( token_fmt( "typename", StrC name(Exec), codetype_impl_tmpl ))); impl_code_destruct.append( parse_global_body( token_fmt( "typename", StrC name(Destructor), codetype_impl_tmpl )));
impl_code_extern. append( parse_global_body( token_fmt( "typename", StrC name(Extern), codetype_impl_tmpl ))); impl_code_enum. append( parse_global_body( token_fmt( "typename", StrC name(Enum), codetype_impl_tmpl )));
impl_code_include.append( parse_global_body( token_fmt( "typename", StrC name(Include), codetype_impl_tmpl ))); impl_code_exec. append( parse_global_body( token_fmt( "typename", StrC name(Exec), codetype_impl_tmpl )));
impl_code_friend. append( parse_global_body( token_fmt( "typename", StrC name(Friend), codetype_impl_tmpl ))); impl_code_extern. append( parse_global_body( token_fmt( "typename", StrC name(Extern), codetype_impl_tmpl )));
impl_code_fn. append( parse_global_body( token_fmt( "typename", StrC name(Fn), codetype_impl_tmpl ))); impl_code_include. append( parse_global_body( token_fmt( "typename", StrC name(Include), codetype_impl_tmpl )));
impl_code_module. append( parse_global_body( token_fmt( "typename", StrC name(Module), codetype_impl_tmpl ))); impl_code_friend. append( parse_global_body( token_fmt( "typename", StrC name(Friend), codetype_impl_tmpl )));
impl_code_ns. append( parse_global_body( token_fmt( "typename", StrC name(NS), codetype_impl_tmpl ))); impl_code_fn. append( parse_global_body( token_fmt( "typename", StrC name(Fn), codetype_impl_tmpl )));
impl_code_op. append( parse_global_body( token_fmt( "typename", StrC name(Operator), codetype_impl_tmpl ))); impl_code_module. append( parse_global_body( token_fmt( "typename", StrC name(Module), codetype_impl_tmpl )));
impl_code_opcast. append( parse_global_body( token_fmt( "typename", StrC name(OpCast), codetype_impl_tmpl ))); impl_code_ns. append( parse_global_body( token_fmt( "typename", StrC name(NS), codetype_impl_tmpl )));
impl_code_pragma .append( parse_global_body( token_fmt( "typename", StrC name(Pragma), codetype_impl_tmpl ))); impl_code_op. append( parse_global_body( token_fmt( "typename", StrC name(Operator), codetype_impl_tmpl )));
impl_code_precond.append( parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), codetype_impl_tmpl ))); impl_code_opcast. append( parse_global_body( token_fmt( "typename", StrC name(OpCast), codetype_impl_tmpl )));
impl_code_tmpl. append( parse_global_body( token_fmt( "typename", StrC name(Template), codetype_impl_tmpl ))); impl_code_pragma . append( parse_global_body( token_fmt( "typename", StrC name(Pragma), codetype_impl_tmpl )));
impl_code_type. append( parse_global_body( token_fmt( "typename", StrC name(Type), codetype_impl_tmpl ))); impl_code_precond. append( parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), codetype_impl_tmpl )));
impl_code_typedef.append( parse_global_body( token_fmt( "typename", StrC name(Typedef), codetype_impl_tmpl ))); impl_code_tmpl. append( parse_global_body( token_fmt( "typename", StrC name(Template), codetype_impl_tmpl )));
impl_code_union. append( parse_global_body( token_fmt( "typename", StrC name(Union), codetype_impl_tmpl ))); impl_code_type. append( parse_global_body( token_fmt( "typename", StrC name(Type), codetype_impl_tmpl )));
impl_code_using. append( parse_global_body( token_fmt( "typename", StrC name(Using), codetype_impl_tmpl ))); impl_code_typedef. append( parse_global_body( token_fmt( "typename", StrC name(Typedef), codetype_impl_tmpl )));
impl_code_var. append( parse_global_body( token_fmt( "typename", StrC name(Var), codetype_impl_tmpl ))); impl_code_union. append( parse_global_body( token_fmt( "typename", StrC name(Union), codetype_impl_tmpl )));
impl_code_using. append( parse_global_body( token_fmt( "typename", StrC name(Using), 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(
AST::operator Code<typename>() AST::operator Code<typename>()
@ -498,8 +502,10 @@ CodeBody gen_ast_inlines()
CodeBody impl_cast_body = parse_global_body( token_fmt( "typename", StrC name(Body), cast_tmpl )); CodeBody impl_cast_body = parse_global_body( token_fmt( "typename", StrC name(Body), cast_tmpl ));
CodeBody impl_cast_attribute = parse_global_body( token_fmt( "typename", StrC name(Attributes), cast_tmpl )); CodeBody impl_cast_attribute = parse_global_body( token_fmt( "typename", StrC name(Attributes), cast_tmpl ));
CodeBody impl_cast_cmt = parse_global_body( token_fmt( "typename", StrC name(Comment), cast_tmpl )); CodeBody impl_cast_cmt = parse_global_body( token_fmt( "typename", StrC name(Comment), cast_tmpl ));
CodeBody impl_cast_constr = parse_global_body( token_fmt( "typename", StrC name(Constructor), cast_tmpl ));
CodeBody impl_cast_class = parse_global_body( token_fmt( "typename", StrC name(Class), cast_tmpl )); CodeBody impl_cast_class = parse_global_body( token_fmt( "typename", StrC name(Class), cast_tmpl ));
CodeBody impl_cast_define = parse_global_body( token_fmt( "typename", StrC name(Define), cast_tmpl )); CodeBody impl_cast_define = parse_global_body( token_fmt( "typename", StrC name(Define), cast_tmpl ));
CodeBody impl_cast_destruct = parse_global_body( token_fmt( "typename", StrC name(Destructor), cast_tmpl ));
CodeBody impl_cast_enum = parse_global_body( token_fmt( "typename", StrC name(Enum), cast_tmpl )); CodeBody impl_cast_enum = parse_global_body( token_fmt( "typename", StrC name(Enum), cast_tmpl ));
CodeBody impl_cast_exec = parse_global_body( token_fmt( "typename", StrC name(Exec), cast_tmpl )); CodeBody impl_cast_exec = parse_global_body( token_fmt( "typename", StrC name(Exec), cast_tmpl ));
CodeBody impl_cast_extern = parse_global_body( token_fmt( "typename", StrC name(Extern), cast_tmpl )); CodeBody impl_cast_extern = parse_global_body( token_fmt( "typename", StrC name(Extern), cast_tmpl ));
@ -529,8 +535,10 @@ CodeBody gen_ast_inlines()
impl_code_body, impl_code_body,
impl_code_attr, impl_code_attr,
impl_code_cmt, impl_code_cmt,
impl_code_constr,
impl_code_class, impl_code_class,
impl_code_define, impl_code_define,
impl_code_destruct,
impl_code_enum, impl_code_enum,
impl_code_exec, impl_code_exec,
impl_code_extern, impl_code_extern,
@ -560,8 +568,10 @@ CodeBody gen_ast_inlines()
impl_cast_body, impl_cast_body,
impl_cast_attribute, impl_cast_attribute,
impl_cast_cmt, impl_cast_cmt,
impl_cast_constr,
impl_cast_class, impl_cast_class,
impl_cast_define, impl_cast_define,
impl_cast_destruct,
impl_cast_enum, impl_cast_enum,
impl_cast_exec, impl_cast_exec,
impl_cast_extern, impl_cast_extern,