diff --git a/project/components/ast.cpp b/project/components/ast.cpp index a1c2494..682338a 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -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(); + + 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(); + + 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 )) diff --git a/project/components/ast.hpp b/project/components/ast.hpp index f0bd1d6..b1a7297 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -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 ); diff --git a/project/components/ast_types.hpp b/project/components/ast_types.hpp index 4ed13a6..20fe388 100644 --- a/project/components/ast_types.hpp +++ b/project/components/ast_types.hpp @@ -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 { diff --git a/project/components/header_end.hpp b/project/components/header_end.hpp index 978bbb7..520fac1 100644 --- a/project/components/header_end.hpp +++ b/project/components/header_end.hpp @@ -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; diff --git a/project/components/interface.cpp b/project/components/interface.cpp index 1c68eca..4e4988f 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -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 ); diff --git a/project/components/interface.hpp b/project/components/interface.hpp index 3e75498..f62cc7c 100644 --- a/project/components/interface.hpp +++ b/project/components/interface.hpp @@ -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 diff --git a/project/components/interface.parsing.cpp b/project/components/interface.parsing.cpp index 23c0bf8..6bea715 100644 --- a/project/components/interface.parsing.cpp +++ b/project/components/interface.parsing.cpp @@ -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 diff --git a/project/components/interface.upfront.cpp b/project/components/interface.upfront.cpp index 2ef3677..1795673 100644 --- a/project/components/interface.upfront.cpp +++ b/project/components/interface.upfront.cpp @@ -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 diff --git a/project/components/static_data.cpp b/project/components/static_data.cpp index 1044162..edcc7f6 100644 --- a/project/components/static_data.cpp +++ b/project/components/static_data.cpp @@ -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; diff --git a/project/components/temp/ast_inlines.hpp b/project/components/temp/ast_inlines.hpp index e215041..37ecca3 100644 --- a/project/components/temp/ast_inlines.hpp +++ b/project/components/temp/ast_inlines.hpp @@ -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 ); diff --git a/project/components/temp/ecode.hpp b/project/components/temp/ecode.hpp index a324adb..891a848 100644 --- a/project/components/temp/ecode.hpp +++ b/project/components/temp/ecode.hpp @@ -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 ) \ diff --git a/project/components/temp/especifier.hpp b/project/components/temp/especifier.hpp index f72b506..9c371f0 100644 --- a/project/components/temp/especifier.hpp +++ b/project/components/temp/especifier.hpp @@ -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 { diff --git a/project/components/temp/etoktype.cpp b/project/components/temp/etoktype.cpp index 9f5553c..bcb8bb8 100644 --- a/project/components/temp/etoktype.cpp +++ b/project/components/temp/etoktype.cpp @@ -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, ";" ) \ diff --git a/project/enums/ECode.csv b/project/enums/ECode.csv index 7dfea54..fb2546c 100644 --- a/project/enums/ECode.csv +++ b/project/enums/ECode.csv @@ -9,6 +9,10 @@ PlatformAttributes Class Class_Fwd Class_Body +Constructor +Constructor_Fwd +Destructor +Destructor_Fwd Enum Enum_Fwd Enum_Body diff --git a/project/enums/ESpecifier.csv b/project/enums/ESpecifier.csv index 736628e..954a883 100644 --- a/project/enums/ESpecifier.csv +++ b/project/enums/ESpecifier.csv @@ -21,3 +21,4 @@ Virtual, virtual Const, const Final, final Override, override +Pure, = 0 diff --git a/project/enums/ETokType.csv b/project/enums/ETokType.csv index ad8849a..d4e2e01 100644 --- a/project/enums/ETokType.csv +++ b/project/enums/ETokType.csv @@ -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" diff --git a/project/helpers/helper.hpp b/project/helpers/helper.hpp index 648498d..69a0135 100644 --- a/project/helpers/helper.hpp +++ b/project/helpers/helper.hpp @@ -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() @@ -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,