mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 07:44:45 -08:00
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:
parent
c2319b9651
commit
c2f8c8aeb1
@ -145,6 +145,70 @@ String AST::to_string()
|
||||
}
|
||||
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:
|
||||
{
|
||||
if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export ))
|
||||
|
@ -2,8 +2,10 @@ struct AST;
|
||||
struct AST_Body;
|
||||
struct AST_Attributes;
|
||||
struct AST_Comment;
|
||||
struct AST_Constructor;
|
||||
struct AST_Class;
|
||||
struct AST_Define;
|
||||
struct AST_Destructor;
|
||||
struct AST_Enum;
|
||||
struct AST_Exec;
|
||||
struct AST_Extern;
|
||||
@ -31,6 +33,8 @@ struct CodeBody;
|
||||
// These are to offer ease of use and optionally strong type safety for the AST.
|
||||
struct CodeAttributes;
|
||||
struct CodeComment;
|
||||
struct CodeConstructor;
|
||||
struct CodeDestructor;
|
||||
struct CodeClass;
|
||||
struct CodeDefine;
|
||||
struct CodeEnum;
|
||||
@ -108,6 +112,8 @@ struct Code
|
||||
#endif
|
||||
operator CodeAttributes() const;
|
||||
operator CodeComment() const;
|
||||
operator CodeConstructor() const;
|
||||
operator CodeDestructor() const;
|
||||
operator CodeClass() const;
|
||||
operator CodeDefine() const;
|
||||
operator CodeExec() const;
|
||||
@ -171,6 +177,8 @@ struct AST
|
||||
operator CodeBody();
|
||||
operator CodeAttributes();
|
||||
operator CodeComment();
|
||||
operator CodeConstructor();
|
||||
operator CodeDestructor();
|
||||
operator CodeClass();
|
||||
operator CodeDefine();
|
||||
operator CodeEnum();
|
||||
@ -214,18 +222,19 @@ struct AST
|
||||
AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable
|
||||
AST* Specs; // Function, Operator, Type symbol, Variable
|
||||
union {
|
||||
AST* ParentType; // Class, Struct
|
||||
AST* ReturnType; // Function, Operator
|
||||
AST* UnderlyingType; // Enum, Typedef
|
||||
AST* ValueType; // Parameter, Variable
|
||||
AST* InitializerList; // Constructor, Destructor
|
||||
AST* ParentType; // Class, Struct
|
||||
AST* ReturnType; // Function, Operator
|
||||
AST* UnderlyingType; // Enum, Typedef
|
||||
AST* ValueType; // Parameter, Variable
|
||||
};
|
||||
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 {
|
||||
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* Value; // Parameter, Variable
|
||||
};
|
||||
@ -261,18 +270,19 @@ struct AST_POD
|
||||
AST* Attributes; // Class, Enum, Function, Struct, Typename, Union, Using, Variable
|
||||
AST* Specs; // Function, Operator, Type symbol, Variable
|
||||
union {
|
||||
AST* ParentType; // Class, Struct
|
||||
AST* ReturnType; // Function, Operator
|
||||
AST* UnderlyingType; // Enum, Typedef
|
||||
AST* ValueType; // Parameter, Variable
|
||||
AST* InitializerList; // Constructor, Destructor
|
||||
AST* ParentType; // Class, Struct
|
||||
AST* ReturnType; // Function, Operator
|
||||
AST* UnderlyingType; // Enum, Typedef
|
||||
AST* ValueType; // Parameter, Variable
|
||||
};
|
||||
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 {
|
||||
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* Value; // Parameter, Variable
|
||||
};
|
||||
@ -536,7 +546,9 @@ struct CodeStruct
|
||||
|
||||
Define_CodeType( Attributes );
|
||||
Define_CodeType( Comment );
|
||||
Define_CodeType( Constructor );
|
||||
Define_CodeType( Define );
|
||||
Define_CodeType( Destructor );
|
||||
Define_CodeType( Enum );
|
||||
Define_CodeType( Exec );
|
||||
Define_CodeType( Extern );
|
||||
|
@ -71,6 +71,27 @@ struct AST_Class
|
||||
};
|
||||
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
|
||||
{
|
||||
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");
|
||||
|
||||
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
|
||||
{
|
||||
union {
|
||||
|
@ -81,6 +81,7 @@ extern CodeSpecifiers spec_mutable;
|
||||
extern CodeSpecifiers spec_neverinline;
|
||||
extern CodeSpecifiers spec_override;
|
||||
extern CodeSpecifiers spec_ptr;
|
||||
extern CodeSpecifiers spec_pure;
|
||||
extern CodeSpecifiers spec_ref;
|
||||
extern CodeSpecifiers spec_register;
|
||||
extern CodeSpecifiers spec_rvalue;
|
||||
|
@ -197,6 +197,7 @@ void define_constants()
|
||||
def_constant_spec( neverinline, ESpecifier::NeverInline );
|
||||
def_constant_spec( override, ESpecifier::Override );
|
||||
def_constant_spec( ptr, ESpecifier::Ptr );
|
||||
def_constant_spec( pure, ESpecifier::Pure )
|
||||
def_constant_spec( ref, ESpecifier::Ref );
|
||||
def_constant_spec( register, ESpecifier::Register );
|
||||
def_constant_spec( rvalue, ESpecifier::RValue );
|
||||
|
@ -45,8 +45,12 @@ CodeClass def_class( StrC name
|
||||
, ModuleFlag mflags = ModuleFlag::None
|
||||
, 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 );
|
||||
|
||||
CodeDestructor def_destructor( Code body = NoCode, CodeSpecifiers specifiers = NoCode );
|
||||
|
||||
CodeEnum def_enum( StrC name
|
||||
, Code body = NoCode, CodeType type = NoCode
|
||||
, EnumT specifier = EnumRegular, CodeAttributes attributes = NoCode
|
||||
@ -136,23 +140,25 @@ CodeBody def_union_body ( s32 num, Code* codes );
|
||||
|
||||
#pragma region Parsing
|
||||
|
||||
CodeClass parse_class ( StrC class_def );
|
||||
CodeEnum parse_enum ( StrC enum_def );
|
||||
CodeBody parse_export_body ( StrC export_def );
|
||||
CodeExtern parse_extern_link ( StrC exten_link_def);
|
||||
CodeFriend parse_friend ( StrC friend_def );
|
||||
CodeFn parse_function ( StrC fn_def );
|
||||
CodeBody parse_global_body ( StrC body_def );
|
||||
CodeNS parse_namespace ( StrC namespace_def );
|
||||
CodeOperator parse_operator ( StrC operator_def );
|
||||
CodeOpCast parse_operator_cast( StrC operator_def );
|
||||
CodeStruct parse_struct ( StrC struct_def );
|
||||
CodeTemplate parse_template ( StrC template_def );
|
||||
CodeType parse_type ( StrC type_def );
|
||||
CodeTypedef parse_typedef ( StrC typedef_def );
|
||||
CodeUnion parse_union ( StrC union_def );
|
||||
CodeUsing parse_using ( StrC using_def );
|
||||
CodeVar parse_variable ( StrC var_def );
|
||||
CodeClass parse_class ( StrC class_def );
|
||||
CodeConstructor parse_constructor ( StrC constructor_def );
|
||||
CodeDestructor parse_destructor ( StrC destructor_def );
|
||||
CodeEnum parse_enum ( StrC enum_def );
|
||||
CodeBody parse_export_body ( StrC export_def );
|
||||
CodeExtern parse_extern_link ( StrC exten_link_def );
|
||||
CodeFriend parse_friend ( StrC friend_def );
|
||||
CodeFn parse_function ( StrC fn_def );
|
||||
CodeBody parse_global_body ( StrC body_def );
|
||||
CodeNS parse_namespace ( StrC namespace_def );
|
||||
CodeOperator parse_operator ( StrC operator_def );
|
||||
CodeOpCast parse_operator_cast( StrC operator_def );
|
||||
CodeStruct parse_struct ( StrC struct_def );
|
||||
CodeTemplate parse_template ( StrC template_def );
|
||||
CodeType parse_type ( StrC type_def );
|
||||
CodeTypedef parse_typedef ( StrC typedef_def );
|
||||
CodeUnion parse_union ( StrC union_def );
|
||||
CodeUsing parse_using ( StrC using_def );
|
||||
CodeVar parse_variable ( StrC var_def );
|
||||
|
||||
#pragma endregion Parsing
|
||||
|
||||
|
@ -89,6 +89,21 @@ namespace Parser
|
||||
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 )
|
||||
{
|
||||
return Arr[idx];
|
||||
@ -1098,6 +1113,7 @@ if ( def.Ptr == nullptr ) \
|
||||
# define currtok_noskip Context.Tokens.current( dont_skip_new_lines )
|
||||
# define currtok Context.Tokens.current()
|
||||
# define prevtok Context.Tokens.previous()
|
||||
# define nexttok Context.Tokens.next()
|
||||
# define eat( Type_ ) Context.Tokens.__eat( Type_ )
|
||||
# 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_global_nspace();
|
||||
|
||||
internal CodeClass parse_class ( bool inplace_def = false );
|
||||
internal CodeEnum parse_enum ( bool inplace_def = false );
|
||||
internal CodeBody parse_export_body ();
|
||||
internal CodeBody parse_extern_link_body();
|
||||
internal CodeExtern parse_exten_link ();
|
||||
internal CodeFriend parse_friend ();
|
||||
internal CodeFn parse_function ();
|
||||
internal CodeNS parse_namespace ();
|
||||
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 CodeTypedef parse_typedef ();
|
||||
internal CodeUnion parse_union ( bool inplace_def = false );
|
||||
internal CodeUsing parse_using ();
|
||||
internal CodeClass parse_class ( bool inplace_def = false );
|
||||
internal CodeConstructor parse_constructor ();
|
||||
internal CodeDestructor parse_destructor ( CodeSpecifiers specifiers = NoCode );
|
||||
internal CodeEnum parse_enum ( bool inplace_def = false );
|
||||
internal CodeBody parse_export_body ();
|
||||
internal CodeBody parse_extern_link_body();
|
||||
internal CodeExtern parse_exten_link ();
|
||||
internal CodeFriend parse_friend ();
|
||||
internal CodeFn parse_function ();
|
||||
internal CodeNS parse_namespace ();
|
||||
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 CodeTypedef parse_typedef ();
|
||||
internal CodeUnion parse_union ( bool inplace_def = false );
|
||||
internal CodeUsing parse_using ();
|
||||
|
||||
constexpr bool inplace_def = true;
|
||||
|
||||
@ -2471,7 +2489,7 @@ Code parse_complicated_definition( Parser::TokType which )
|
||||
}
|
||||
|
||||
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 ECode;
|
||||
@ -2566,6 +2584,16 @@ CodeBody parse_class_struct_body( Parser::TokType which )
|
||||
member = parse_using();
|
||||
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:
|
||||
member = parse_define();
|
||||
break;
|
||||
@ -2661,6 +2689,12 @@ CodeBody parse_class_struct_body( Parser::TokType which )
|
||||
{
|
||||
specifiers = def_specifiers( NumSpecifiers, specs_found );
|
||||
}
|
||||
|
||||
if ( currtok.Type == TokType::Operator && currtok.Text[0] == '~' )
|
||||
{
|
||||
member = parse_destructor( specifiers );
|
||||
break;
|
||||
}
|
||||
}
|
||||
//! Fallthrough intentional
|
||||
case TokType::Identifier:
|
||||
@ -2673,6 +2707,15 @@ CodeBody parse_class_struct_body( Parser::TokType which )
|
||||
case TokType::Type_int:
|
||||
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 );
|
||||
}
|
||||
break;
|
||||
@ -2775,7 +2818,7 @@ Code parse_class_struct( Parser::TokType which, bool inplace_def = false )
|
||||
|
||||
if ( check( TokType::BraceCurly_Open ) )
|
||||
{
|
||||
body = parse_class_struct_body( which );
|
||||
body = parse_class_struct_body( which, name );
|
||||
}
|
||||
|
||||
if ( ! inplace_def )
|
||||
@ -3122,6 +3165,158 @@ CodeClass parse_class( StrC def )
|
||||
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
|
||||
CodeEnum parse_enum( bool inplace_def )
|
||||
{
|
||||
@ -3474,7 +3669,7 @@ CodeFn parse_functon()
|
||||
s32 NumSpecifiers = 0;
|
||||
|
||||
CodeAttributes attributes = { nullptr };
|
||||
CodeSpecifiers specifiers = { nullptr };
|
||||
CodeSpecifiers specifiers = { nullptr };
|
||||
ModuleFlag mflags = ModuleFlag::None;
|
||||
|
||||
if ( check(TokType::Module_Export) )
|
||||
@ -4550,6 +4745,7 @@ CodeVar parse_variable( StrC def )
|
||||
# undef check_parse_args
|
||||
# undef currtok
|
||||
# undef prevtok
|
||||
# undef nexttok
|
||||
# undef eat
|
||||
# undef left
|
||||
# undef check
|
||||
|
@ -422,6 +422,53 @@ CodeComment def_comment( StrC content )
|
||||
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
|
||||
, Code body
|
||||
, CodeType parent, AccessSpec parent_access
|
||||
@ -512,6 +559,45 @@ CodeDefine def_define( StrC name, StrC content )
|
||||
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
|
||||
, Code body, CodeType type
|
||||
, EnumT specifier, CodeAttributes attributes
|
||||
|
@ -55,6 +55,7 @@ global CodeSpecifiers spec_mutable;
|
||||
global CodeSpecifiers spec_neverinline;
|
||||
global CodeSpecifiers spec_override;
|
||||
global CodeSpecifiers spec_ptr;
|
||||
global CodeSpecifiers spec_pure;
|
||||
global CodeSpecifiers spec_ref;
|
||||
global CodeSpecifiers spec_register;
|
||||
global CodeSpecifiers spec_rvalue;
|
||||
|
@ -102,7 +102,9 @@ Define_CodeImpl( CodeBody );
|
||||
Define_CodeImpl( CodeAttributes );
|
||||
Define_CodeImpl( CodeComment );
|
||||
Define_CodeImpl( CodeClass );
|
||||
Define_CodeImpl( CodeConstructor );
|
||||
Define_CodeImpl( CodeDefine );
|
||||
Define_CodeImpl( CodeDestructor );
|
||||
Define_CodeImpl( CodeEnum );
|
||||
Define_CodeImpl( CodeExec );
|
||||
Define_CodeImpl( CodeExtern );
|
||||
@ -127,7 +129,9 @@ Define_CodeImpl( CodeVar );
|
||||
|
||||
Define_CodeType_Impl( Attributes );
|
||||
Define_CodeType_Impl( Comment );
|
||||
Define_CodeType_Impl( Constructor );
|
||||
Define_CodeType_Impl( Define );
|
||||
Define_CodeType_Impl( Destructor );
|
||||
Define_CodeType_Impl( Enum );
|
||||
Define_CodeType_Impl( Exec );
|
||||
Define_CodeType_Impl( Extern );
|
||||
@ -159,8 +163,10 @@ AST::operator Code ## typename() \
|
||||
Define_AST_Cast( Body );
|
||||
Define_AST_Cast( Attributes );
|
||||
Define_AST_Cast( Comment );
|
||||
Define_AST_Cast( Constructor );
|
||||
Define_AST_Cast( Class );
|
||||
Define_AST_Cast( Define );
|
||||
Define_AST_Cast( Destructor );
|
||||
Define_AST_Cast( Enum );
|
||||
Define_AST_Cast( Exec );
|
||||
Define_AST_Cast( Extern );
|
||||
@ -192,8 +198,10 @@ Code::operator Code ## type() const \
|
||||
|
||||
Define_CodeCast( Attributes );
|
||||
Define_CodeCast( Comment );
|
||||
Define_CodeCast( Constructor );
|
||||
Define_CodeCast( Class );
|
||||
Define_CodeCast( Define );
|
||||
Define_CodeCast( Destructor );
|
||||
Define_CodeCast( Exec );
|
||||
Define_CodeCast( Enum );
|
||||
Define_CodeCast( Extern );
|
||||
|
@ -14,6 +14,10 @@ namespace ECode
|
||||
Entry( Class ) \
|
||||
Entry( Class_Fwd ) \
|
||||
Entry( Class_Body ) \
|
||||
Entry( Constructor ) \
|
||||
Entry( Constructor_Fwd ) \
|
||||
Entry( Destructor ) \
|
||||
Entry( Destructor_Fwd ) \
|
||||
Entry( Enum ) \
|
||||
Entry( Enum_Fwd ) \
|
||||
Entry( Enum_Body ) \
|
||||
|
@ -31,7 +31,8 @@ namespace ESpecifier
|
||||
Entry( Virtual, virtual ) \
|
||||
Entry( Const, const ) \
|
||||
Entry( Final, final ) \
|
||||
Entry( Override, override )
|
||||
Entry( Override, override ) \
|
||||
Entry( Pure, = 0 )
|
||||
|
||||
enum Type : u32
|
||||
{
|
||||
|
@ -88,6 +88,7 @@ namespace Parser
|
||||
Entry( Spec_Override, "override" ) \
|
||||
Entry( Spec_Static, "static" ) \
|
||||
Entry( Spec_ThreadLocal, "thread_local" ) \
|
||||
Entry( Spec_Virtual, "virtual" ) \
|
||||
Entry( Spec_Volatile, "volatile") \
|
||||
Entry( Star, "*" ) \
|
||||
Entry( Statement_End, ";" ) \
|
||||
|
@ -9,6 +9,10 @@ PlatformAttributes
|
||||
Class
|
||||
Class_Fwd
|
||||
Class_Body
|
||||
Constructor
|
||||
Constructor_Fwd
|
||||
Destructor
|
||||
Destructor_Fwd
|
||||
Enum
|
||||
Enum_Fwd
|
||||
Enum_Body
|
||||
|
|
@ -21,3 +21,4 @@ Virtual, virtual
|
||||
Const, const
|
||||
Final, final
|
||||
Override, override
|
||||
Pure, = 0
|
||||
|
|
@ -71,6 +71,7 @@ Spec_Override, "override"
|
||||
Spec_Static, "static"
|
||||
Spec_ThreadLocal, "thread_local"
|
||||
Spec_Volatile, "volatile"
|
||||
Spec_Virtual, "virtual"
|
||||
Star, "*"
|
||||
Statement_End, ";"
|
||||
StaticAssert, "static_assert"
|
||||
|
|
@ -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_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_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_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_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 ));
|
||||
@ -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_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_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_enum. append( parse_global_body( token_fmt( "typename", StrC name(Enum), codetype_impl_tmpl )));
|
||||
impl_code_exec. append( parse_global_body( token_fmt( "typename", StrC name(Exec), codetype_impl_tmpl )));
|
||||
impl_code_extern. append( parse_global_body( token_fmt( "typename", StrC name(Extern), codetype_impl_tmpl )));
|
||||
impl_code_include.append( parse_global_body( token_fmt( "typename", StrC name(Include), codetype_impl_tmpl )));
|
||||
impl_code_friend. append( parse_global_body( token_fmt( "typename", StrC name(Friend), codetype_impl_tmpl )));
|
||||
impl_code_fn. append( parse_global_body( token_fmt( "typename", StrC name(Fn), codetype_impl_tmpl )));
|
||||
impl_code_module. append( parse_global_body( token_fmt( "typename", StrC name(Module), codetype_impl_tmpl )));
|
||||
impl_code_ns. append( parse_global_body( token_fmt( "typename", StrC name(NS), codetype_impl_tmpl )));
|
||||
impl_code_op. append( parse_global_body( token_fmt( "typename", StrC name(Operator), codetype_impl_tmpl )));
|
||||
impl_code_opcast. append( parse_global_body( token_fmt( "typename", StrC name(OpCast), codetype_impl_tmpl )));
|
||||
impl_code_pragma .append( parse_global_body( token_fmt( "typename", StrC name(Pragma), codetype_impl_tmpl )));
|
||||
impl_code_precond.append( parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), codetype_impl_tmpl )));
|
||||
impl_code_tmpl. append( parse_global_body( token_fmt( "typename", StrC name(Template), codetype_impl_tmpl )));
|
||||
impl_code_type. append( parse_global_body( token_fmt( "typename", StrC name(Type), codetype_impl_tmpl )));
|
||||
impl_code_typedef.append( parse_global_body( token_fmt( "typename", StrC name(Typedef), 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 )));
|
||||
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_constr. append( parse_global_body( token_fmt( "typename", StrC name(Constructor), codetype_impl_tmpl )));
|
||||
impl_code_define. append( parse_global_body( token_fmt( "typename", StrC name(Define), codetype_impl_tmpl )));
|
||||
impl_code_destruct.append( parse_global_body( token_fmt( "typename", StrC name(Destructor), codetype_impl_tmpl )));
|
||||
impl_code_enum. append( parse_global_body( token_fmt( "typename", StrC name(Enum), codetype_impl_tmpl )));
|
||||
impl_code_exec. append( parse_global_body( token_fmt( "typename", StrC name(Exec), codetype_impl_tmpl )));
|
||||
impl_code_extern. append( parse_global_body( token_fmt( "typename", StrC name(Extern), codetype_impl_tmpl )));
|
||||
impl_code_include. append( parse_global_body( token_fmt( "typename", StrC name(Include), codetype_impl_tmpl )));
|
||||
impl_code_friend. append( parse_global_body( token_fmt( "typename", StrC name(Friend), codetype_impl_tmpl )));
|
||||
impl_code_fn. append( parse_global_body( token_fmt( "typename", StrC name(Fn), codetype_impl_tmpl )));
|
||||
impl_code_module. append( parse_global_body( token_fmt( "typename", StrC name(Module), codetype_impl_tmpl )));
|
||||
impl_code_ns. append( parse_global_body( token_fmt( "typename", StrC name(NS), codetype_impl_tmpl )));
|
||||
impl_code_op. append( parse_global_body( token_fmt( "typename", StrC name(Operator), codetype_impl_tmpl )));
|
||||
impl_code_opcast. append( parse_global_body( token_fmt( "typename", StrC name(OpCast), codetype_impl_tmpl )));
|
||||
impl_code_pragma . append( parse_global_body( token_fmt( "typename", StrC name(Pragma), codetype_impl_tmpl )));
|
||||
impl_code_precond. append( parse_global_body( token_fmt( "typename", StrC name(PreprocessCond), codetype_impl_tmpl )));
|
||||
impl_code_tmpl. append( parse_global_body( token_fmt( "typename", StrC name(Template), codetype_impl_tmpl )));
|
||||
impl_code_type. append( parse_global_body( token_fmt( "typename", StrC name(Type), codetype_impl_tmpl )));
|
||||
impl_code_typedef. append( parse_global_body( token_fmt( "typename", StrC name(Typedef), 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(
|
||||
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_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_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_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_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 ));
|
||||
@ -529,8 +535,10 @@ CodeBody gen_ast_inlines()
|
||||
impl_code_body,
|
||||
impl_code_attr,
|
||||
impl_code_cmt,
|
||||
impl_code_constr,
|
||||
impl_code_class,
|
||||
impl_code_define,
|
||||
impl_code_destruct,
|
||||
impl_code_enum,
|
||||
impl_code_exec,
|
||||
impl_code_extern,
|
||||
@ -560,8 +568,10 @@ CodeBody gen_ast_inlines()
|
||||
impl_cast_body,
|
||||
impl_cast_attribute,
|
||||
impl_cast_cmt,
|
||||
impl_cast_constr,
|
||||
impl_cast_class,
|
||||
impl_cast_define,
|
||||
impl_cast_destruct,
|
||||
impl_cast_enum,
|
||||
impl_cast_exec,
|
||||
impl_cast_extern,
|
||||
|
Loading…
Reference in New Issue
Block a user