• R/O
  • SSH
  • HTTPS

eircompile: Commit


Commit MetaInfo

Revision69 (tree)
Time2021-12-25 08:05:44
Authorquiret

Log Message

- added COS type system unit tests + fixed some bugs
- added -> arrow operator to COS

Change Summary

Incremental Difference

--- testcompiler/src/cos_tests.cpp (revision 68)
+++ testcompiler/src/cos_tests.cpp (revision 69)
@@ -192,6 +192,10 @@
192192 // a.b
193193 using BinaryOperation::BinaryOperation;
194194 };
195+struct ArrowOperation : public BinaryOperation
196+{
197+ using BinaryOperation::BinaryOperation;
198+};
195199
196200 struct AssignAddOperation : public BinaryOperation
197201 {
@@ -229,6 +233,10 @@
229233 {
230234 using BinaryOperation::BinaryOperation;
231235 };
236+struct AssignArrowOperation : public BinaryOperation
237+{
238+ using BinaryOperation::BinaryOperation;
239+};
232240 struct AssignBitshiftLeftOperation : public BinaryOperation
233241 {
234242 using BinaryOperation::BinaryOperation;
@@ -568,14 +576,14 @@
568576 depVector <CatchStatement*> errors;
569577 };
570578
571-struct StructStatement : public COSNode
579+struct StructDefinition : public COSNode
572580 {
573- inline StructStatement( COSNode *name = nullptr, COSNode *body = nullptr ) noexcept : name( name ), body( body )
581+ inline StructDefinition( COSNode *name = nullptr, COSNode *body = nullptr ) noexcept : name( name ), body( body )
574582 {
575583 return;
576584 }
577- inline StructStatement( const StructStatement& ) = default;
578- inline StructStatement( StructStatement&& right ) noexcept
585+ inline StructDefinition( const StructDefinition& ) = default;
586+ inline StructDefinition( StructDefinition&& right ) noexcept
579587 {
580588 this->name = right.name;
581589 this->body = right.body;
@@ -587,14 +595,14 @@
587595 COSNode *name;
588596 COSNode *body;
589597 };
590-struct ConstructorStatement : public COSNode
598+struct ConstructorDefinition : public COSNode
591599 {
592- inline ConstructorStatement( depVector <COSNode*> params = {}, COSNode *body = nullptr ) noexcept : params( std::move( params ) ), body( body )
600+ inline ConstructorDefinition( depVector <COSNode*> params = {}, COSNode *body = nullptr ) noexcept : params( std::move( params ) ), body( body )
593601 {
594602 return;
595603 }
596- inline ConstructorStatement( const ConstructorStatement& ) = default;
597- inline ConstructorStatement( ConstructorStatement&& right ) noexcept : params( std::move( right.params ) )
604+ inline ConstructorDefinition( const ConstructorDefinition& ) = default;
605+ inline ConstructorDefinition( ConstructorDefinition&& right ) noexcept : params( std::move( right.params ) )
598606 {
599607 this->body = right.body;
600608
@@ -604,14 +612,14 @@
604612 depVector <COSNode*> params;
605613 COSNode *body;
606614 };
607-struct DestructorStatement : public COSNode
615+struct DestructorDefinition : public COSNode
608616 {
609- inline DestructorStatement( COSNode *body = nullptr ) noexcept
617+ inline DestructorDefinition( COSNode *body = nullptr ) noexcept
610618 {
611619 this->body = body;
612620 }
613- inline DestructorStatement( const DestructorStatement& ) = default;
614- inline DestructorStatement( DestructorStatement&& right ) noexcept
621+ inline DestructorDefinition( const DestructorDefinition& ) = default;
622+ inline DestructorDefinition( DestructorDefinition&& right ) noexcept
615623 {
616624 this->body = right.body;
617625
@@ -659,6 +667,7 @@
659667 BIT_OR,
660668 LOGICAL_NEGATE,
661669 DOT,
670+ ARROW,
662671 ASSIGN,
663672 BIT_NEGATE,
664673
@@ -671,6 +680,7 @@
671680 ASSIGN_BIT_AND,
672681 ASSIGN_BIT_OR,
673682 ASSIGN_DOT,
683+ ASSIGN_ARROW,
674684 ASSIGN_BITSHIFT_LEFT,
675685 ASSIGN_BITSHIFT_RIGHT,
676686
@@ -975,7 +985,7 @@
975985 };
976986 lexer.GetNamedProduction( "funcstatement" ).GetLastStep()->setSelector <direct_obj_build_selector <char, ReturnStatement, COSNode, return_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
977987 }
978- assert( lexer.CompileProduction( compiler, "optoksingle_epostfix", "\"<<\" | \">>\" | '+-*/%^&|!.=<>'" ) == true );
988+ assert( lexer.CompileProduction( compiler, "optoksingle_epostfix", "\"->\" | \"<<\" | \">>\" | '+-*/%^&|!.=<>'" ) == true );
979989 assert( lexer.CompileProduction( compiler, "optoksingle", "'~' | optoksingle_epostfix" ) == true );
980990 assert( lexer.CompileProduction( compiler, "optoks", "\"&&\" | \"||\" | optoksingle_epostfix '=' | optoksingle" ) == true );
981991 assert( lexer.CompileProduction( compiler, "spec", "\"operator\" spaces optok:optoks" ) == true );
@@ -1069,6 +1079,14 @@
10691079 {
10701080 assign_to->op_type = eOpType::ASSIGN_DOT;
10711081 }
1082+ else if ( value == "->" )
1083+ {
1084+ assign_to->op_type = eOpType::ARROW;
1085+ }
1086+ else if ( value == "->=" )
1087+ {
1088+ assign_to->op_type = eOpType::ASSIGN_ARROW;
1089+ }
10721090 else if ( value == "=" )
10731091 {
10741092 assign_to->op_type = eOpType::ASSIGN;
@@ -1166,7 +1184,7 @@
11661184 {
11671185 auto operation = lexer.MakeStep <decltype(lexer)::RuntimeEnv::StepProceduralSequence> ();
11681186
1169- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('=' | \"+=\" | \"-=\" | \"*=\" | \"/=\" | \"%=\" | \"^=\" | \"&=\" | \"|=\" | \".=\") spaces]" ) != nullptr );
1187+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('=' | \"+=\" | \"-=\" | \"*=\" | \"/=\" | \"%=\" | \"^=\" | \"&=\" | \"|=\" | \".=\" | \"->=\") spaces]" ) != nullptr );
11701188 {
11711189 struct assignment_dispatcher
11721190 {
@@ -1183,6 +1201,7 @@
11831201 ASSIGN_BIT_AND,
11841202 ASSIGN_BIT_OR,
11851203 ASSIGN_DOT,
1204+ ASSIGN_ARROW,
11861205 ASSIGN_BITSHIFT_LEFT,
11871206 ASSIGN_BITSHIFT_RIGHT
11881207 };
@@ -1232,6 +1251,10 @@
12321251 {
12331252 this->op_type = eOpType::ASSIGN_DOT;
12341253 }
1254+ else if ( value == "->=" )
1255+ {
1256+ this->op_type = eOpType::ASSIGN_ARROW;
1257+ }
12351258 else if ( value == "<<=" )
12361259 {
12371260 this->op_type = eOpType::ASSIGN_BITSHIFT_LEFT;
@@ -1286,6 +1309,10 @@
12861309 {
12871310 return new AssignDotOperation( left, right );
12881311 }
1312+ else if ( op_type == eOpType::ASSIGN_ARROW )
1313+ {
1314+ return new AssignArrowOperation( left, right );
1315+ }
12891316 else if ( op_type == eOpType::ASSIGN_BITSHIFT_LEFT )
12901317 {
12911318 return new AssignBitshiftLeftOperation( left, right );
@@ -1931,10 +1958,16 @@
19311958 };
19321959 operation.GetLastStep()->setSelector <arrayinit_selector> ();
19331960 }
1934- assert( lexer.CompileInto( compiler, operation, "[\"template\" spaces templop:operation spaces '<' spaces [<0> templarg:procgate type, spaces ',' spaces] spaces endtempl:'>' | dotitem:operation, spaces '.' spaces]" ) != nullptr );
1961+ assert( lexer.CompileInto( compiler, operation, "[\"template\" spaces templop:operation spaces '<' spaces [<0> templarg:procgate type, spaces ',' spaces] spaces endtempl:'>' | dotitem:operation, spaces optok:(\"->\"|'.') spaces]" ) != nullptr );
19351962 {
19361963 struct dot_with_templ_selector
19371964 {
1965+ enum class eOpType
1966+ {
1967+ DOT,
1968+ ARROW
1969+ };
1970+
19381971 inline void AddNodeAsRootDot( COSNode *node )
19391972 {
19401973 COSNode *prev_root = this->root;
@@ -1945,7 +1978,16 @@
19451978 return;
19461979 }
19471980
1948- this->root = new DotOperation( prev_root, node );
1981+ eOpType op_type = this->op_type;
1982+
1983+ if ( op_type == eOpType::ARROW )
1984+ {
1985+ this->root = new ArrowOperation( prev_root, node );
1986+ }
1987+ else if ( op_type == eOpType::DOT )
1988+ {
1989+ this->root = new DotOperation( prev_root, node );
1990+ }
19491991 }
19501992
19511993 inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
@@ -1956,8 +1998,18 @@
19561998 this->root = new TemplateInstantiationOperation( this->root, std::move( this->templargs ) );
19571999
19582000 this->templop = nullptr;
1959- return;
19602001 }
2002+ else if ( attrib == "optok" )
2003+ {
2004+ if ( value == "." )
2005+ {
2006+ this->op_type = eOpType::DOT;
2007+ }
2008+ else if ( value == "->" )
2009+ {
2010+ this->op_type = eOpType::ARROW;
2011+ }
2012+ }
19612013 }
19622014
19632015 inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
@@ -1993,6 +2045,7 @@
19932045 COSNode *root = nullptr;
19942046 COSNode *templop = nullptr;
19952047 depVector <COSNode*> templargs;
2048+ eOpType op_type = eOpType::DOT;
19962049 };
19972050 operation.GetLastStep()->setSelector <dot_with_templ_selector> ();
19982051 }
@@ -2354,11 +2407,11 @@
23542407 lexer.GetNamedProduction( "forloop" ).setSelector <direct_obj_build_selector <char, ForLoopStatement, COSNode, for_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
23552408 }
23562409 assert( lexer.CompileProduction( compiler, "loop", "whileloop | forloop" ) == true );
2357- assert( lexer.CompileProduction( compiler, "structdef", "\"struct\" spaces name:spec spaces ^!(body:nblock, <b> statement+typestatement) spaces ';'" ) == true );
2410+ assert( lexer.CompileProduction( compiler, "structdef", "\"struct\" spaces name:spec spaces ^!(body:block, <b> statement+typestatement) spaces ';'" ) == true );
23582411 {
23592412 struct struct_dispatcher
23602413 {
2361- static inline bool AssignNodeTo( StructStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2414+ static inline bool AssignNodeTo( StructDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
23622415 {
23632416 if ( attrib == "name" )
23642417 {
@@ -2373,15 +2426,15 @@
23732426 return false;
23742427 }
23752428 };
2376- lexer.GetNamedProduction( "structdef" ).setSelector <direct_obj_build_selector <char, StructStatement, COSNode, struct_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2429+ lexer.GetNamedProduction( "structdef" ).setSelector <direct_obj_build_selector <char, StructDefinition, COSNode, struct_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
23772430 }
23782431 assert( lexer.CompileProduction( compiler, "typedef", "dtypedef | structdef" ) == true );
23792432 assert( lexer.CompileProduction( compiler, "typestatement", "constructor | destructor" ) == true );
2380- assert( lexer.CompileProduction( compiler, "constructor", "\"constructor\" spaces '(' spaces paramlist_opt spaces ')' spaces body:extended funcbody" ) == true );
2433+ assert( lexer.CompileProduction( compiler, "constructor", "\"constructor\" spaces '(' spaces paramlist_opt spaces ')' spaces body:funcbody" ) == true );
23812434 {
23822435 struct constructor_dispatcher
23832436 {
2384- static inline bool AssignNodeTo( ConstructorStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2437+ static inline bool AssignNodeTo( ConstructorDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
23852438 {
23862439 if ( attrib == "param" )
23872440 {
@@ -2396,13 +2449,13 @@
23962449 return false;
23972450 }
23982451 };
2399- lexer.GetNamedProduction( "constructor" ).setSelector <direct_obj_build_selector <char, ConstructorStatement, COSNode, constructor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2452+ lexer.GetNamedProduction( "constructor" ).setSelector <direct_obj_build_selector <char, ConstructorDefinition, COSNode, constructor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
24002453 }
2401- assert( lexer.CompileProduction( compiler, "destructor", "\"destructor\" spaces body:extended funcbody" ) == true );
2454+ assert( lexer.CompileProduction( compiler, "destructor", "\"destructor\" spaces body:funcbody" ) == true );
24022455 {
24032456 struct destructor_dispatcher
24042457 {
2405- static inline bool AssignNodeTo( DestructorStatement *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
2458+ static inline bool AssignNodeTo( DestructorDefinition *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
24062459 {
24072460 if ( attrib == "body" )
24082461 {
@@ -2412,7 +2465,7 @@
24122465 return false;
24132466 }
24142467 };
2415- lexer.GetNamedProduction( "destructor" ).setSelector <direct_obj_build_selector <char, DestructorStatement, COSNode, destructor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
2468+ lexer.GetNamedProduction( "destructor" ).setSelector <direct_obj_build_selector <char, DestructorDefinition, COSNode, destructor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
24162469 }
24172470 assert( lexer.CompileProduction( compiler, "deleteop", "\"delete\" spaces op:operation spaces ';'" ) == true );
24182471 {
@@ -2468,7 +2521,7 @@
24682521 };
24692522 lexer.GetNamedProduction( "npath" ).setSelector <left_associative_selector <char, COSNode, npath_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
24702523 }
2471- assert( lexer.CompileProduction( compiler, "curlypack", "'(' spaces [param:operation, spaces ',' spaces] spacecs ')'" ) == true );
2524+ assert( lexer.CompileProduction( compiler, "curlypack", "'(' spaces [<0> param:operation, spaces ',' spaces] spaces ')'" ) == true );
24722525 {
24732526 struct curlypack_dispatcher
24742527 {
@@ -6654,7 +6707,1009 @@
66546707
66556708 printf( "testing COS type system..." );
66566709 {
6657- // TODO.
6710+ // 1)
6711+ {
6712+ COSNode *_root = lexer.StartProduction( "struct mydata{int field;};" );
6713+
6714+ StructDefinition *root = dynamic_cast <StructDefinition*> ( _root );
6715+
6716+ assert( root != nullptr );
6717+
6718+ SpecifierString *name = dynamic_cast <SpecifierString*> ( root->name );
6719+
6720+ assert( name != nullptr );
6721+ assert( name->string == "mydata" );
6722+
6723+ name->Delete();
6724+
6725+ BlockStatement *body = dynamic_cast <BlockStatement*> ( root->body );
6726+
6727+ assert( body != nullptr );
6728+ assert( body->statements.GetCount() == 1 );
6729+
6730+ DeclarationStatement *body_1 = dynamic_cast <DeclarationStatement*> ( body->statements[0] );
6731+
6732+ assert( body_1 != nullptr );
6733+ assert( body_1->initializer == nullptr );
6734+
6735+ SpecifierString *body_1_type = dynamic_cast <SpecifierString*> ( body_1->type );
6736+
6737+ assert( body_1_type != nullptr );
6738+ assert( body_1_type->string == "int" );
6739+
6740+ body_1_type->Delete();
6741+
6742+ SpecifierString *body_1_name = dynamic_cast <SpecifierString*> ( body_1->name );
6743+
6744+ assert( body_1_name != nullptr );
6745+ assert( body_1_name->string == "field" );
6746+
6747+ body_1_name->Delete();
6748+ body_1->Delete();
6749+ body->Delete();
6750+ root->Delete();
6751+ }
6752+
6753+ // 2)
6754+ {
6755+ COSNode *_root = lexer.StartProduction( R"RAW(
6756+struct test {
6757+ constructor() {
6758+ value = 1;
6759+ active = true;
66586760 }
6761+ destructor {
6762+ report(value);
6763+ active = false;
6764+ }
6765+ int value = 0;
6766+ bool active = false;
6767+};
6768+)RAW" );
6769+ StructDefinition *root = dynamic_cast <StructDefinition*> ( _root );
6770+
6771+ assert( root != nullptr );
6772+
6773+ SpecifierString *name = dynamic_cast <SpecifierString*> ( root->name );
6774+
6775+ assert( name != nullptr );
6776+ assert( name->string == "test" );
6777+
6778+ name->Delete();
6779+
6780+ BlockStatement *body = dynamic_cast <BlockStatement*> ( root->body );
6781+
6782+ assert( body != nullptr );
6783+ assert( body->statements.GetCount() == 4 );
6784+
6785+ ConstructorDefinition *body_1 = dynamic_cast <ConstructorDefinition*> ( body->statements[0] );
6786+
6787+ assert( body_1 != nullptr );
6788+ assert( body_1->params.GetCount() == 0 );
6789+
6790+ BlockStatement *body_1_body = dynamic_cast <BlockStatement*> ( body_1->body );
6791+
6792+ assert( body_1_body != nullptr );
6793+ assert( body_1_body->statements.GetCount() == 2 );
6794+
6795+ AssignmentOperation *body_1_body_1 = dynamic_cast <AssignmentOperation*> ( body_1_body->statements[0] );
6796+
6797+ assert( body_1_body_1 != nullptr );
6798+
6799+ SpecifierString *body_1_body_1_left = dynamic_cast <SpecifierString*> ( body_1_body_1->left );
6800+
6801+ assert( body_1_body_1_left != nullptr );
6802+ assert( body_1_body_1_left->string == "value" );
6803+
6804+ body_1_body_1_left->Delete();
6805+
6806+ NumberString *body_1_body_1_right = dynamic_cast <NumberString*> ( body_1_body_1->right );
6807+
6808+ assert( body_1_body_1_right != nullptr );
6809+ assert( body_1_body_1_right->numeric_string == "1" );
6810+
6811+ body_1_body_1_right->Delete();
6812+ body_1_body_1->Delete();
6813+
6814+ AssignmentOperation *body_1_body_2 = dynamic_cast <AssignmentOperation*> ( body_1_body->statements[1] );
6815+
6816+ assert( body_1_body_2 != nullptr );
6817+
6818+ SpecifierString *body_1_body_2_left = dynamic_cast <SpecifierString*> ( body_1_body_2->left );
6819+
6820+ assert( body_1_body_2_left != nullptr );
6821+ assert( body_1_body_2_left->string == "active" );
6822+
6823+ body_1_body_2_left->Delete();
6824+
6825+ SpecifierString *body_1_body_2_right = dynamic_cast <SpecifierString*> ( body_1_body_2->right );
6826+
6827+ assert( body_1_body_2_right != nullptr );
6828+ assert( body_1_body_2_right->string == "true" );
6829+
6830+ body_1_body_2_right->Delete();
6831+ body_1_body_2->Delete();
6832+ body_1_body->Delete();
6833+ body_1->Delete();
6834+
6835+ DestructorDefinition *body_2 = dynamic_cast <DestructorDefinition*> ( body->statements[1] );
6836+
6837+ assert( body_2 != nullptr );
6838+
6839+ BlockStatement *body_2_body = dynamic_cast <BlockStatement*> ( body_2->body );
6840+
6841+ assert( body_2_body != nullptr );
6842+ assert( body_2_body->statements.GetCount() == 2 );
6843+
6844+ FunctionCallOperation *body_2_body_1 = dynamic_cast <FunctionCallOperation*> ( body_2_body->statements[0] );
6845+
6846+ assert( body_2_body_1 != nullptr );
6847+ assert( body_2_body_1->params.GetCount() == 1 );
6848+
6849+ SpecifierString *body_2_body_1_what = dynamic_cast <SpecifierString*> ( body_2_body_1->what );
6850+
6851+ assert( body_2_body_1_what != nullptr );
6852+ assert( body_2_body_1_what->string == "report" );
6853+
6854+ body_2_body_1_what->Delete();
6855+
6856+ SpecifierString *body_2_body_1_1 = dynamic_cast <SpecifierString*> ( body_2_body_1->params[0] );
6857+
6858+ assert( body_2_body_1_1 != nullptr );
6859+ assert( body_2_body_1_1->string == "value" );
6860+
6861+ body_2_body_1_1->Delete();
6862+ body_2_body_1->Delete();
6863+
6864+ AssignmentOperation *body_2_body_2 = dynamic_cast <AssignmentOperation*> ( body_2_body->statements[1] );
6865+
6866+ assert( body_2_body_2 != nullptr );
6867+
6868+ SpecifierString *body_2_body_2_left = dynamic_cast <SpecifierString*> ( body_2_body_2->left );
6869+
6870+ assert( body_2_body_2_left != nullptr );
6871+ assert( body_2_body_2_left->string == "active" );
6872+
6873+ body_2_body_2_left->Delete();
6874+
6875+ SpecifierString *body_2_body_2_right = dynamic_cast <SpecifierString*> ( body_2_body_2->right );
6876+
6877+ assert( body_2_body_2_right != nullptr );
6878+ assert( body_2_body_2_right->string == "false" );
6879+
6880+ body_2_body_2_right->Delete();
6881+ body_2_body_2->Delete();
6882+ body_2_body->Delete();
6883+ body_2->Delete();
6884+
6885+ DeclarationStatement *body_3 = dynamic_cast <DeclarationStatement*> ( body->statements[2] );
6886+
6887+ assert( body_3 != nullptr );
6888+
6889+ SpecifierString *body_3_type = dynamic_cast <SpecifierString*> ( body_3->type );
6890+
6891+ assert( body_3_type != nullptr );
6892+ assert( body_3_type->string == "int" );
6893+
6894+ body_3_type->Delete();
6895+
6896+ SpecifierString *body_3_name = dynamic_cast <SpecifierString*> ( body_3->name );
6897+
6898+ assert( body_3_name != nullptr );
6899+ assert( body_3_name->string == "value" );
6900+
6901+ body_3_name->Delete();
6902+
6903+ NumberString *body_3_init = dynamic_cast <NumberString*> ( body_3->initializer );
6904+
6905+ assert( body_3_init != nullptr );
6906+ assert( body_3_init->numeric_string == "0" );
6907+
6908+ body_3_init->Delete();
6909+ body_3->Delete();
6910+
6911+ DeclarationStatement *body_4 = dynamic_cast <DeclarationStatement*> ( body->statements[3] );
6912+
6913+ assert( body_4 != nullptr );
6914+
6915+ SpecifierString *body_4_type = dynamic_cast <SpecifierString*> ( body_4->type );
6916+
6917+ assert( body_4_type != nullptr );
6918+ assert( body_4_type->string == "bool" );
6919+
6920+ body_4_type->Delete();
6921+
6922+ SpecifierString *body_4_name = dynamic_cast <SpecifierString*> ( body_4->name );
6923+
6924+ assert( body_4_name != nullptr );
6925+ assert( body_4_name->string == "active" );
6926+
6927+ body_4_name->Delete();
6928+
6929+ SpecifierString *body_4_init = dynamic_cast <SpecifierString*> ( body_4->initializer );
6930+
6931+ assert( body_4_init != nullptr );
6932+ assert( body_4_init->string == "false" );
6933+
6934+ body_4_init->Delete();
6935+ body_4->Delete();
6936+ body->Delete();
6937+ root->Delete();
6938+ }
6939+
6940+ // 3)
6941+ {
6942+ // TODO: add the -> operator to COS.
6943+
6944+ COSNode *_root = lexer.StartProduction( R"RAW(
6945+struct logger {
6946+ void func print( string msg ) {
6947+ buffer.append(msg);
6948+ update();
6949+ }
6950+ void func update() {
6951+ globalScreenUpdate(&this->buffer);
6952+ }
6953+ string buffer;
6954+};
6955+)RAW" );
6956+
6957+ StructDefinition *root = dynamic_cast <StructDefinition*> ( _root );
6958+
6959+ assert( root != nullptr );
6960+
6961+ SpecifierString *name = dynamic_cast <SpecifierString*> ( root->name );
6962+
6963+ assert( name != nullptr );
6964+ assert( name->string == "logger" );
6965+
6966+ name->Delete();
6967+
6968+ BlockStatement *body = dynamic_cast <BlockStatement*> ( root->body );
6969+
6970+ assert( body != nullptr );
6971+ assert( body->statements.GetCount() == 3 );
6972+
6973+ DeclarationStatement *body_1 = dynamic_cast <DeclarationStatement*> ( body->statements[0] );
6974+
6975+ assert( body_1 != nullptr );
6976+
6977+ SpecifierString *body_1_name = dynamic_cast <SpecifierString*> ( body_1->name );
6978+
6979+ assert( body_1_name != nullptr );
6980+ assert( body_1_name->string == "print" );
6981+
6982+ body_1_name->Delete();
6983+
6984+ FuncsigDefinition *body_1_type = dynamic_cast <FuncsigDefinition*> ( body_1->type );
6985+
6986+ assert( body_1_type != nullptr );
6987+ assert( body_1_type->params.GetCount() == 1 );
6988+
6989+ SpecifierString *body_1_type_rtype = dynamic_cast <SpecifierString*> ( body_1_type->return_type );
6990+
6991+ assert( body_1_type_rtype != nullptr );
6992+ assert( body_1_type_rtype->string == "void" );
6993+
6994+ body_1_type_rtype->Delete();
6995+
6996+ DeclarationStatement *body_1_type_p1 = dynamic_cast <DeclarationStatement*> ( body_1_type->params[0] );
6997+
6998+ assert( body_1_type_p1 != nullptr );
6999+ assert( body_1_type_p1->initializer == nullptr );
7000+
7001+ SpecifierString *body_1_type_p1_type = dynamic_cast <SpecifierString*> ( body_1_type_p1->type );
7002+
7003+ assert( body_1_type_p1_type != nullptr );
7004+ assert( body_1_type_p1_type->string == "string" );
7005+
7006+ body_1_type_p1_type->Delete();
7007+
7008+ SpecifierString *body_1_type_p1_name = dynamic_cast <SpecifierString*> ( body_1_type_p1->name );
7009+
7010+ assert( body_1_type_p1_name != nullptr );
7011+ assert( body_1_type_p1_name->string == "msg" );
7012+
7013+ body_1_type_p1_name->Delete();
7014+ body_1_type_p1->Delete();
7015+ body_1_type->Delete();
7016+
7017+ BlockStatement *body_1_init = dynamic_cast <BlockStatement*> ( body_1->initializer );
7018+
7019+ assert( body_1_init != nullptr );
7020+ assert( body_1_init->statements.GetCount() == 2 );
7021+
7022+ FunctionCallOperation *body_1_init_1 = dynamic_cast <FunctionCallOperation*> ( body_1_init->statements[0] );
7023+
7024+ assert( body_1_init_1 != nullptr );
7025+
7026+ DotOperation *body_1_init_1_what = dynamic_cast <DotOperation*> ( body_1_init_1->what );
7027+
7028+ assert( body_1_init_1_what != nullptr );
7029+
7030+ SpecifierString *body_1_init_1_what_left = dynamic_cast <SpecifierString*> ( body_1_init_1_what->left );
7031+
7032+ assert( body_1_init_1_what_left != nullptr );
7033+ assert( body_1_init_1_what_left->string == "buffer" );
7034+
7035+ body_1_init_1_what_left->Delete();
7036+
7037+ SpecifierString *body_1_init_1_what_right = dynamic_cast <SpecifierString*> ( body_1_init_1_what->right );
7038+
7039+ assert( body_1_init_1_what_right != nullptr );
7040+ assert( body_1_init_1_what_right->string == "append" );
7041+
7042+ body_1_init_1_what_right->Delete();
7043+ body_1_init_1_what->Delete();
7044+
7045+ SpecifierString *body_1_init_1_p1 = dynamic_cast <SpecifierString*> ( body_1_init_1->params[0] );
7046+
7047+ assert( body_1_init_1_p1 != nullptr );
7048+ assert( body_1_init_1_p1->string == "msg" );
7049+
7050+ body_1_init_1_p1->Delete();
7051+ body_1_init_1->Delete();
7052+
7053+ FunctionCallOperation *body_1_init_2 = dynamic_cast <FunctionCallOperation*> ( body_1_init->statements[1] );
7054+
7055+ assert( body_1_init_2 != nullptr );
7056+ assert( body_1_init_2->params.GetCount() == 0 );
7057+
7058+ SpecifierString *body_1_init_2_what = dynamic_cast <SpecifierString*> ( body_1_init_2->what );
7059+
7060+ assert( body_1_init_2_what != nullptr );
7061+ assert( body_1_init_2_what->string == "update" );
7062+
7063+ body_1_init_2_what->Delete();
7064+ body_1_init_2->Delete();
7065+ body_1_init->Delete();
7066+ body_1->Delete();
7067+
7068+ DeclarationStatement *body_2 = dynamic_cast <DeclarationStatement*> ( body->statements[1] );
7069+
7070+ assert( body_2 != nullptr );
7071+
7072+ SpecifierString *body_2_name = dynamic_cast <SpecifierString*> ( body_2->name );
7073+
7074+ assert( body_2_name != nullptr );
7075+ assert( body_2_name->string == "update" );
7076+
7077+ FuncsigDefinition *body_2_type = dynamic_cast <FuncsigDefinition*> ( body_2->type );
7078+
7079+ assert( body_2_type != nullptr );
7080+ assert( body_2_type->params.GetCount() == 0 );
7081+
7082+ SpecifierString *body_2_type_rtype = dynamic_cast <SpecifierString*> ( body_2_type->return_type );
7083+
7084+ assert( body_2_type_rtype != nullptr );
7085+ assert( body_2_type_rtype->string == "void" );
7086+
7087+ body_2_type_rtype->Delete();
7088+ body_2_type->Delete();
7089+
7090+ BlockStatement *body_2_init = dynamic_cast <BlockStatement*> ( body_2->initializer );
7091+
7092+ assert( body_2_init != nullptr );
7093+ assert( body_2_init->statements.GetCount() == 1 );
7094+
7095+ FunctionCallOperation *body_2_init_1 = dynamic_cast <FunctionCallOperation*> ( body_2_init->statements[0] );
7096+
7097+ assert( body_2_init_1 != nullptr );
7098+ assert( body_2_init_1->params.GetCount() == 1 );
7099+
7100+ SpecifierString *body_2_init_1_what = dynamic_cast <SpecifierString*> ( body_2_init_1->what );
7101+
7102+ assert( body_2_init_1_what != nullptr );
7103+ assert( body_2_init_1_what->string == "globalScreenUpdate" );
7104+
7105+ body_2_init_1_what->Delete();
7106+
7107+ AddressOfOperation *body_2_init_1_1 = dynamic_cast <AddressOfOperation*> ( body_2_init_1->params[0] );
7108+
7109+ assert( body_2_init_1_1 != nullptr );
7110+
7111+ ArrowOperation *body_2_init_1_1_op = dynamic_cast <ArrowOperation*> ( body_2_init_1_1->op );
7112+
7113+ assert( body_2_init_1_1_op != nullptr );
7114+
7115+ SpecifierString *body_2_init_1_1_op_left = dynamic_cast <SpecifierString*> ( body_2_init_1_1_op->left );
7116+
7117+ assert( body_2_init_1_1_op_left != nullptr );
7118+ assert( body_2_init_1_1_op_left->string == "this" );
7119+
7120+ body_2_init_1_1_op_left->Delete();
7121+
7122+ SpecifierString *body_2_init_1_1_op_right = dynamic_cast <SpecifierString*> ( body_2_init_1_1_op->right );
7123+
7124+ assert( body_2_init_1_1_op_right != nullptr );
7125+ assert( body_2_init_1_1_op_right->string == "buffer" );
7126+
7127+ body_2_init_1_1_op_right->Delete();
7128+ body_2_init_1_1_op->Delete();
7129+ body_2_init_1_1->Delete();
7130+ body_2_init_1->Delete();
7131+ body_2_init->Delete();
7132+ body_2->Delete();
7133+
7134+ DeclarationStatement *body_3 = dynamic_cast <DeclarationStatement*> ( body->statements[2] );
7135+
7136+ assert( body_3 != nullptr );
7137+ assert( body_3->initializer == nullptr );
7138+
7139+ SpecifierString *body_3_type = dynamic_cast <SpecifierString*> ( body_3->type );
7140+
7141+ assert( body_3_type != nullptr );
7142+ assert( body_3_type->string == "string" );
7143+
7144+ body_3_type->Delete();
7145+
7146+ SpecifierString *body_3_name = dynamic_cast <SpecifierString*> ( body_3->name );
7147+
7148+ assert( body_3_name != nullptr );
7149+ assert( body_3_name->string == "buffer" );
7150+
7151+ body_3_name->Delete();
7152+ body_3->Delete();
7153+ body->Delete();
7154+ root->Delete();
7155+ }
7156+
7157+ // 4)
7158+ {
7159+ COSNode *_root = lexer.StartProduction( "typedef int number;" );
7160+
7161+ TypedefStatement *root = dynamic_cast <TypedefStatement*> ( _root );
7162+
7163+ assert( root != nullptr );
7164+
7165+ SpecifierString *dst = dynamic_cast <SpecifierString*> ( root->dsttype );
7166+
7167+ assert( dst != nullptr );
7168+ assert( dst->string == "number" );
7169+
7170+ dst->Delete();
7171+
7172+ SpecifierString *src = dynamic_cast <SpecifierString*> ( root->srctype );
7173+
7174+ assert( src != nullptr );
7175+ assert( src->string == "int" );
7176+
7177+ src->Delete();
7178+ root->Delete();
7179+ }
7180+
7181+ // 5)
7182+ {
7183+ COSNode *_root = lexer.StartProduction( "struct anyT;" );
7184+
7185+ DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
7186+
7187+ assert( root != nullptr );
7188+ assert( root->initializer == nullptr );
7189+
7190+ SpecifierString *type = dynamic_cast <SpecifierString*> ( root->type );
7191+
7192+ assert( type != nullptr );
7193+ assert( type->string == "struct" );
7194+
7195+ type->Delete();
7196+
7197+ SpecifierString *name = dynamic_cast <SpecifierString*> ( root->name );
7198+
7199+ assert( name != nullptr );
7200+ assert( name->string == "anyT" );
7201+
7202+ name->Delete();
7203+ root->Delete();
7204+ }
7205+
7206+ // 6)
7207+ {
7208+ COSNode *_root = lexer.StartProduction( "$[getnumbertype()] value = 0;" );
7209+
7210+ DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
7211+
7212+ assert( root != nullptr );
7213+
7214+ SpecifierString *name = dynamic_cast <SpecifierString*> ( root->name );
7215+
7216+ assert( name != nullptr );
7217+ assert( name->string == "value" );
7218+
7219+ name->Delete();
7220+
7221+ NumberString *init = dynamic_cast <NumberString*> ( root->initializer );
7222+
7223+ assert( init != nullptr );
7224+ assert( init->numeric_string == "0" );
7225+
7226+ init->Delete();
7227+
7228+ ResolveSpecifierOperation *type = dynamic_cast <ResolveSpecifierOperation*> ( root->type );
7229+
7230+ assert( type != nullptr );
7231+
7232+ FunctionCallOperation *type_op = dynamic_cast <FunctionCallOperation*> ( type->op );
7233+
7234+ assert( type_op != nullptr );
7235+ assert( type_op->params.GetCount() == 0 );
7236+
7237+ SpecifierString *type_op_what = dynamic_cast <SpecifierString*> ( type_op->what );
7238+
7239+ assert( type_op_what != nullptr );
7240+ assert( type_op_what->string == "getnumbertype" );
7241+
7242+ type_op_what->Delete();
7243+ type_op->Delete();
7244+ type->Delete();
7245+ root->Delete();
7246+ }
7247+
7248+ // 7)
7249+ {
7250+ COSNode *_root = lexer.StartProduction( "$[1]$[0] = int;" );
7251+
7252+ DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
7253+
7254+ assert( root != nullptr );
7255+
7256+ ResolveSpecifierOperation *name = dynamic_cast <ResolveSpecifierOperation*> ( root->name );
7257+
7258+ assert( name != nullptr );
7259+
7260+ NumberString *name_op = dynamic_cast <NumberString*> ( name->op );
7261+
7262+ assert( name_op != nullptr );
7263+ assert( name_op->numeric_string == "0" );
7264+
7265+ name_op->Delete();
7266+ name->Delete();
7267+
7268+ ResolveSpecifierOperation *type = dynamic_cast <ResolveSpecifierOperation*> ( root->type );
7269+
7270+ assert( type != nullptr );
7271+
7272+ NumberString *type_op = dynamic_cast <NumberString*> ( type->op );
7273+
7274+ assert( type_op != nullptr );
7275+ assert( type_op->numeric_string == "1" );
7276+
7277+ type_op->Delete();
7278+ type->Delete();
7279+
7280+ SpecifierString *init = dynamic_cast <SpecifierString*> ( root->initializer );
7281+
7282+ assert( init != nullptr );
7283+ assert( init->string == "int" );
7284+
7285+ init->Delete();
7286+ root->Delete();
7287+ }
7288+
7289+ // 8)
7290+ {
7291+ COSNode *_root = lexer.StartProduction( "test obj();" );
7292+
7293+ DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
7294+
7295+ assert( root != nullptr );
7296+
7297+ SpecifierString *type = dynamic_cast <SpecifierString*> ( root->type );
7298+
7299+ assert( type != nullptr );
7300+ assert( type->string == "test" );
7301+
7302+ type->Delete();
7303+
7304+ SpecifierString *name = dynamic_cast <SpecifierString*> ( root->name );
7305+
7306+ assert( name != nullptr );
7307+ assert( name->string == "obj" );
7308+
7309+ name->Delete();
7310+
7311+ CurlyPack *init = dynamic_cast <CurlyPack*> ( root->initializer );
7312+
7313+ assert( init != nullptr );
7314+ assert( init->params.GetCount() == 0 );
7315+
7316+ init->Delete();
7317+ root->Delete();
7318+ }
7319+
7320+ // 9)
7321+ {
7322+ COSNode *_root = lexer.StartProduction( "test[obj()]();" );
7323+
7324+ FunctionCallOperation *root = dynamic_cast <FunctionCallOperation*> ( _root );
7325+
7326+ assert( root != nullptr );
7327+ assert( root->params.GetCount() == 0 );
7328+
7329+ EdgeBracketsOperation *what = dynamic_cast <EdgeBracketsOperation*> ( root->what );
7330+
7331+ assert( what != nullptr );
7332+
7333+ SpecifierString *what_left = dynamic_cast <SpecifierString*> ( what->left );
7334+
7335+ assert( what_left != nullptr );
7336+ assert( what_left->string == "test" );
7337+
7338+ what_left->Delete();
7339+
7340+ FunctionCallOperation *what_right = dynamic_cast <FunctionCallOperation*> ( what->right );
7341+
7342+ assert( what_right != nullptr );
7343+ assert( what_right->params.GetCount() == 0 );
7344+
7345+ SpecifierString *what_right_what = dynamic_cast <SpecifierString*> ( what_right->what );
7346+
7347+ assert( what_right_what != nullptr );
7348+ assert( what_right_what->string == "obj" );
7349+
7350+ what_right_what->Delete();
7351+ what_right->Delete();
7352+ what->Delete();
7353+ root->Delete();
7354+ }
7355+
7356+ // 10)
7357+ {
7358+ COSNode *_root = lexer.StartProduction( "int mydata.newfield = 0;" );
7359+
7360+ DeclarationStatement *root = dynamic_cast <DeclarationStatement*> ( _root );
7361+
7362+ assert( root != nullptr );
7363+
7364+ SpecifierString *type = dynamic_cast <SpecifierString*> ( root->type );
7365+
7366+ assert( type != nullptr );
7367+ assert( type->string == "int" );
7368+
7369+ type->Delete();
7370+
7371+ DotOperation *name = dynamic_cast <DotOperation*> ( root->name );
7372+
7373+ assert( name != nullptr );
7374+
7375+ SpecifierString *name_left = dynamic_cast <SpecifierString*> ( name->left );
7376+
7377+ assert( name_left != nullptr );
7378+ assert( name_left->string == "mydata" );
7379+
7380+ name_left->Delete();
7381+
7382+ SpecifierString *name_right = dynamic_cast <SpecifierString*> ( name->right );
7383+
7384+ assert( name_right != nullptr );
7385+ assert( name_right->string == "newfield" );
7386+
7387+ name_right->Delete();
7388+ name->Delete();
7389+
7390+ NumberString *init = dynamic_cast <NumberString*> ( root->initializer );
7391+
7392+ assert( init != nullptr );
7393+ assert( init->numeric_string == "0" );
7394+
7395+ init->Delete();
7396+ root->Delete();
7397+ }
7398+
7399+ // 11)
7400+ {
7401+ COSNode *_root = lexer.StartProduction( "int a = 0; int& b = a;" );
7402+
7403+ Program *root = dynamic_cast <Program*> ( _root );
7404+
7405+ assert( root != nullptr );
7406+ assert( root->statements.GetCount() == 2 );
7407+
7408+ DeclarationStatement *first = dynamic_cast <DeclarationStatement*> ( root->statements[0] );
7409+
7410+ assert( first != nullptr );
7411+
7412+ SpecifierString *first_type = dynamic_cast <SpecifierString*> ( first->type );
7413+
7414+ assert( first_type != nullptr );
7415+ assert( first_type->string == "int" );
7416+
7417+ first_type->Delete();
7418+
7419+ SpecifierString *first_name = dynamic_cast <SpecifierString*> ( first->name );
7420+
7421+ assert( first_name != nullptr );
7422+ assert( first_name->string == "a" );
7423+
7424+ first_name->Delete();
7425+
7426+ NumberString *first_init = dynamic_cast <NumberString*> ( first->initializer );
7427+
7428+ assert( first_init != nullptr );
7429+ assert( first_init->numeric_string == "0" );
7430+
7431+ first_init->Delete();
7432+ first->Delete();
7433+
7434+ DeclarationStatement *second = dynamic_cast <DeclarationStatement*> ( root->statements[1] );
7435+
7436+ assert( second != nullptr );
7437+
7438+ RefTypeSpecifier *second_type = dynamic_cast <RefTypeSpecifier*> ( second->type );
7439+
7440+ assert( second_type != nullptr );
7441+
7442+ SpecifierString *second_type_spec = dynamic_cast <SpecifierString*> ( second_type->spec );
7443+
7444+ assert( second_type_spec != nullptr );
7445+ assert( second_type_spec->string == "int" );
7446+
7447+ second_type_spec->Delete();
7448+ second_type->Delete();
7449+
7450+ SpecifierString *second_name = dynamic_cast <SpecifierString*> ( second->name );
7451+
7452+ assert( second_name != nullptr );
7453+ assert( second_name->string == "b" );
7454+
7455+ second_name->Delete();
7456+
7457+ SpecifierString *second_init = dynamic_cast <SpecifierString*> ( second->initializer );
7458+
7459+ assert( second_init != nullptr );
7460+ assert( second_init->string == "a" );
7461+
7462+ second_init->Delete();
7463+ second->Delete();
7464+ root->Delete();
7465+ }
7466+
7467+ // 12)
7468+ {
7469+ COSNode *_root = lexer.StartProduction( "typedef int *a, b, &c;" );
7470+
7471+ MultiTypedefStatement *root = dynamic_cast <MultiTypedefStatement*> ( _root );
7472+
7473+ assert( root != nullptr );
7474+ assert( root->defs.GetCount() == 3 );
7475+
7476+ TypedefStatement *first = dynamic_cast <TypedefStatement*> ( root->defs[0] );
7477+
7478+ assert( first != nullptr );
7479+
7480+ SpecifierString *first_dst = dynamic_cast <SpecifierString*> ( first->dsttype );
7481+
7482+ assert( first_dst != nullptr );
7483+ assert( first_dst->string == "a" );
7484+
7485+ first_dst->Delete();
7486+
7487+ PointerTypeSpecifier *first_src = dynamic_cast <PointerTypeSpecifier*> ( first->srctype );
7488+
7489+ assert( first_src != nullptr );
7490+
7491+ SpecifierString *first_src_spec = dynamic_cast <SpecifierString*> ( first_src->spec );
7492+
7493+ assert( first_src_spec != nullptr );
7494+ assert( first_src_spec->string == "int" );
7495+
7496+ first_src_spec->Delete();
7497+
7498+ first_src->Delete();
7499+ first->Delete();
7500+
7501+ TypedefStatement *second = dynamic_cast <TypedefStatement*> ( root->defs[1] );
7502+
7503+ assert( second != nullptr );
7504+ assert( second->srctype == first_src_spec );
7505+
7506+ SpecifierString *second_dst = dynamic_cast <SpecifierString*> ( second->dsttype );
7507+
7508+ assert( second_dst != nullptr );
7509+ assert( second_dst->string == "b" );
7510+
7511+ second_dst->Delete();
7512+ second->Delete();
7513+
7514+ TypedefStatement *third = dynamic_cast <TypedefStatement*> ( root->defs[2] );
7515+
7516+ assert( third != nullptr );
7517+
7518+ SpecifierString *third_dst = dynamic_cast <SpecifierString*> ( third->dsttype );
7519+
7520+ assert( third_dst != nullptr );
7521+ assert( third_dst->string == "c" );
7522+
7523+ third_dst->Delete();
7524+
7525+ RefTypeSpecifier *third_src = dynamic_cast <RefTypeSpecifier*> ( third->srctype );
7526+
7527+ assert( third_src != nullptr );
7528+ assert( third_src->spec == first_src_spec );
7529+
7530+ third_src->Delete();
7531+ third->Delete();
7532+ root->Delete();
7533+ }
7534+
7535+ // 13)
7536+ {
7537+ COSNode *_root = lexer.StartProduction( "typedef void func (*myproto)(int);" );
7538+
7539+ TypedefStatement *root = dynamic_cast <TypedefStatement*> ( _root );
7540+
7541+ assert( root != nullptr );
7542+
7543+ SpecifierString *dst = dynamic_cast <SpecifierString*> ( root->dsttype );
7544+
7545+ assert( dst != nullptr );
7546+ assert( dst->string == "myproto" );
7547+
7548+ dst->Delete();
7549+
7550+ PointerTypeSpecifier *src = dynamic_cast <PointerTypeSpecifier*> ( root->srctype );
7551+
7552+ assert( src != nullptr );
7553+
7554+ FuncsigDefinition *src_spec = dynamic_cast <FuncsigDefinition*> ( src->spec );
7555+
7556+ assert( src_spec != nullptr );
7557+ assert( src_spec->params.GetCount() == 1 );
7558+
7559+ SpecifierString *src_spec_rtype = dynamic_cast <SpecifierString*> ( src_spec->return_type );
7560+
7561+ assert( src_spec_rtype != nullptr );
7562+ assert( src_spec_rtype->string == "void" );
7563+
7564+ src_spec_rtype->Delete();
7565+
7566+ DeclarationStatement *src_spec_p1 = dynamic_cast <DeclarationStatement*> ( src_spec->params[0] );
7567+
7568+ assert( src_spec_p1 != nullptr );
7569+ assert( src_spec_p1->name == nullptr );
7570+ assert( src_spec_p1->initializer == nullptr );
7571+
7572+ SpecifierString *src_spec_p1_type = dynamic_cast <SpecifierString*> ( src_spec_p1->type );
7573+
7574+ assert( src_spec_p1_type != nullptr );
7575+ assert( src_spec_p1_type->string == "int" );
7576+
7577+ src_spec_p1_type->Delete();
7578+ src_spec_p1->Delete();
7579+ src_spec->Delete();
7580+ src->Delete();
7581+ root->Delete();
7582+ }
7583+
7584+ // 14)
7585+ {
7586+ COSNode *_root = lexer.StartProduction( "typedef int func (&rcodef)(), *func (*pushcode)(int);" );
7587+
7588+ MultiTypedefStatement *root = dynamic_cast <MultiTypedefStatement*> ( _root );
7589+
7590+ assert( root != nullptr );
7591+
7592+ TypedefStatement *first = dynamic_cast <TypedefStatement*> ( root->defs[0] );
7593+
7594+ assert( first != nullptr );
7595+
7596+ SpecifierString *first_dst = dynamic_cast <SpecifierString*> ( first->dsttype );
7597+
7598+ assert( first_dst != nullptr );
7599+ assert( first_dst->string == "rcodef" );
7600+
7601+ first_dst->Delete();
7602+
7603+ RefTypeSpecifier *first_src = dynamic_cast <RefTypeSpecifier*> ( first->srctype );
7604+
7605+ assert( first_src != nullptr );
7606+
7607+ FuncsigDefinition *first_src_spec = dynamic_cast <FuncsigDefinition*> ( first_src->spec );
7608+
7609+ assert( first_src_spec != nullptr );
7610+ assert( first_src_spec->params.GetCount() == 0 );
7611+
7612+ SpecifierString *first_src_spec_rtype = dynamic_cast <SpecifierString*> ( first_src_spec->return_type );
7613+
7614+ assert( first_src_spec_rtype != nullptr );
7615+ assert( first_src_spec_rtype->string == "int" );
7616+
7617+ first_src_spec_rtype->Delete();
7618+ first_src_spec->Delete();
7619+ first_src->Delete();
7620+ first->Delete();
7621+
7622+ TypedefStatement *second = dynamic_cast <TypedefStatement*> ( root->defs[1] );
7623+
7624+ assert( second != nullptr );
7625+
7626+ SpecifierString *second_dst = dynamic_cast <SpecifierString*> ( second->dsttype );
7627+
7628+ assert( second_dst != nullptr );
7629+ assert( second_dst->string == "pushcode" );
7630+
7631+ second_dst->Delete();
7632+
7633+ PointerTypeSpecifier *second_src = dynamic_cast <PointerTypeSpecifier*> ( second->srctype );
7634+
7635+ assert( second_src != nullptr );
7636+
7637+ FuncsigDefinition *second_src_spec = dynamic_cast <FuncsigDefinition*> ( second_src->spec );
7638+
7639+ assert( second_src_spec != nullptr );
7640+ assert( second_src_spec->params.GetCount() == 1 );
7641+
7642+ DeclarationStatement *second_src_spec_p1 = dynamic_cast <DeclarationStatement*> ( second_src_spec->params[0] );
7643+
7644+ assert( second_src_spec_p1 != nullptr );
7645+ assert( second_src_spec_p1->initializer == nullptr );
7646+ assert( second_src_spec_p1->name == nullptr );
7647+
7648+ SpecifierString *second_src_spec_p1_type = dynamic_cast <SpecifierString*> ( second_src_spec_p1->type );
7649+
7650+ assert( second_src_spec_p1_type != nullptr );
7651+ assert( second_src_spec_p1_type->string == "int" );
7652+
7653+ second_src_spec_p1_type->Delete();
7654+ second_src_spec_p1->Delete();
7655+
7656+ PointerTypeSpecifier *second_src_spec_rtype = dynamic_cast <PointerTypeSpecifier*> ( second_src_spec->return_type );
7657+
7658+ assert( second_src_spec_rtype != nullptr );
7659+ assert( second_src_spec_rtype->spec == first_src_spec_rtype );
7660+
7661+ second_src_spec_rtype->Delete();
7662+ second_src_spec->Delete();
7663+ second_src->Delete();
7664+ second->Delete();
7665+ root->Delete();
7666+ }
7667+
7668+ // 15)
7669+ {
7670+ COSNode *_root = lexer.StartProduction( "typedef int func (*func (*getmethodf)())();" );
7671+
7672+ TypedefStatement *root = dynamic_cast <TypedefStatement*> ( _root );
7673+
7674+ assert( root != nullptr );
7675+
7676+ SpecifierString *dst = dynamic_cast <SpecifierString*> ( root->dsttype );
7677+
7678+ assert( dst != nullptr );
7679+ assert( dst->string == "getmethodf" );
7680+
7681+ dst->Delete();
7682+
7683+ PointerTypeSpecifier *src = dynamic_cast <PointerTypeSpecifier*> ( root->srctype );
7684+
7685+ assert( src != nullptr );
7686+
7687+ FuncsigDefinition *src_spec = dynamic_cast <FuncsigDefinition*> ( src->spec );
7688+
7689+ assert( src_spec != nullptr );
7690+ assert( src_spec->params.GetCount() == 0 );
7691+
7692+ PointerTypeSpecifier *src_spec_rtype = dynamic_cast <PointerTypeSpecifier*> ( src_spec->return_type );
7693+
7694+ assert( src_spec_rtype != nullptr );
7695+
7696+ FuncsigDefinition *src_spec_rtype_spec = dynamic_cast <FuncsigDefinition*> ( src_spec_rtype->spec );
7697+
7698+ assert( src_spec_rtype_spec != nullptr );
7699+ assert( src_spec_rtype_spec->params.GetCount() == 0 );
7700+
7701+ SpecifierString *src_spec_rtype_spec_rtype = dynamic_cast <SpecifierString*> ( src_spec_rtype_spec->return_type );
7702+
7703+ assert( src_spec_rtype_spec_rtype != nullptr );
7704+ assert( src_spec_rtype_spec_rtype->string == "int" );
7705+
7706+ src_spec_rtype_spec_rtype->Delete();
7707+ src_spec_rtype_spec->Delete();
7708+ src_spec_rtype->Delete();
7709+ src_spec->Delete();
7710+ src->Delete();
7711+ root->Delete();
7712+ }
7713+ }
66597714 printf( "ok.\n" );
66607715 }
\ No newline at end of file
Show on old repository browser