• R/O
  • SSH
  • HTTPS

eircompile: Commit


Commit MetaInfo

Revision64 (tree)
Time2021-12-23 02:15:02
Authorquiret

Log Message

- fixed the buggy implementation of the StepReplacementPoint::GetNextConnectionsToNode method; it does return each node that it connects to exactly once now
- fixed other various bugs in the StepReplacementPoint class due to it's complicated references-layout
- improved the COS language definition by removing redundancy and adding the "operator-specifier" for future operator overloading

Change Summary

Incremental Difference

--- eircompile/include/eircompile/lexing_compile.h (revision 63)
+++ eircompile/include/eircompile/lexing_compile.h (revision 64)
@@ -207,7 +207,7 @@
207207 {
208208 if ( auto *replpt = right.replpt )
209209 {
210- auto *newReplpt = (typename compileForEnvType::StepReplacementPoint*)replpt->Clone();
210+ auto *newReplpt = env->runtime_env->CloneStep <typename compileForEnvType::StepReplacementPoint> ( replpt );
211211
212212 this->replpt = newReplpt;
213213
--- eircompile/include/eircompile/lexing_env.h (revision 63)
+++ eircompile/include/eircompile/lexing_env.h (revision 64)
@@ -2368,9 +2368,21 @@
23682368 {
23692369 LexingEnvironment *env = this->env;
23702370
2371+ Step *exec = this->exec;
2372+
2373+ if ( exec )
2374+ {
2375+ env->gcReachSched.OnRemoveConnection( this, exec );
2376+ }
2377+
23712378 for ( auto *kvNode : this->replacements )
23722379 {
2373- env->gcReachSched.OnRemoveConnection( this, kvNode->GetKey() );
2380+ Step *keyStep = kvNode->GetKey();
2381+
2382+ if ( keyStep != exec )
2383+ {
2384+ env->gcReachSched.OnRemoveConnection( this, keyStep );
2385+ }
23742386 }
23752387
23762388 for ( const valinfo& vinfo : this->valrefs )
@@ -2377,7 +2389,7 @@
23772389 {
23782390 Step *valstep = vinfo.step;
23792391
2380- if ( this->replacements.Find( valstep ) == nullptr )
2392+ if ( valstep != exec && this->replacements.Find( valstep ) == nullptr )
23812393 {
23822394 env->gcReachSched.OnRemoveConnection( this, valstep );
23832395 }
@@ -2394,6 +2406,62 @@
23942406 // First we iterate through all keys.
23952407 // Then we iterate through all values which are not - at the same time - keys.
23962408
2409+ auto isInternalNode = [&]( Step *node )
2410+ {
2411+ if ( this->exec == node )
2412+ return true;
2413+
2414+ return false;
2415+ };
2416+
2417+ auto isKeyNode = [&]( Step *node )
2418+ {
2419+ return ( this->replacements.Find( node ) != nullptr );
2420+ };
2421+
2422+ auto isValueNode = [&]( Step *node )
2423+ {
2424+ return ( this->valrefs.Find( node ) != nullptr );
2425+ };
2426+
2427+ auto findNextInternalNode = [&]( Step *intern_prev ) -> Step*
2428+ {
2429+ Step *exec = this->exec;
2430+
2431+ if ( intern_prev == nullptr )
2432+ {
2433+ return exec;
2434+ }
2435+ else
2436+ {
2437+ return nullptr;
2438+ }
2439+ };
2440+
2441+ auto findNextKeyNode = [&]( Step *key_prev ) -> Step*
2442+ {
2443+ auto *findNode = this->replacements.FindJustAbove( key_prev );
2444+
2445+ if ( findNode == nullptr )
2446+ return nullptr;
2447+
2448+ typename decltype(this->replacements)::iterator iter( findNode );
2449+
2450+ while ( iter.IsEnd() == false )
2451+ {
2452+ Step *attempt_return = iter.Resolve()->GetKey();
2453+
2454+ if ( this->exec != attempt_return )
2455+ {
2456+ return attempt_return;
2457+ }
2458+
2459+ iter.Increment();
2460+ }
2461+
2462+ return nullptr;
2463+ };
2464+
23972465 auto findNextValNode = [&]( Step *val_prev ) -> Step*
23982466 {
23992467 auto *findNode = this->valrefs.FindJustAbove( val_prev );
@@ -2407,7 +2475,7 @@
24072475 {
24082476 Step *attempt_return = iter.Resolve()->GetValue().step;
24092477
2410- if ( this->replacements.Find( attempt_return ) == nullptr )
2478+ if ( this->exec != attempt_return && this->replacements.Find( attempt_return ) == nullptr )
24112479 {
24122480 return attempt_return;
24132481 }
@@ -2418,52 +2486,87 @@
24182486 return nullptr;
24192487 };
24202488
2421- Step *first = this->exec;
2489+ enum class eListPresence
2490+ {
2491+ INTERN,
2492+ KEYS,
2493+ VALUES
2494+ };
24222495
2423- if ( prev == nullptr || first != nullptr && prev == first )
2496+ eListPresence list_presence;
2497+ Step *iter = prev;
2498+
2499+ // Find the starting iter step.
2500+ if ( prev == nullptr )
24242501 {
2425- if ( prev == nullptr && first != nullptr )
2502+ list_presence = eListPresence::INTERN;
2503+ }
2504+ else
2505+ {
2506+ if ( isInternalNode( prev ) )
24262507 {
2427- return first;
2508+ list_presence = eListPresence::INTERN;
24282509 }
2429-
2430- auto *keyMinNode = this->replacements.GetMinimumByKey();
2431-
2432- if ( keyMinNode )
2510+ else if ( isKeyNode( prev ) )
24332511 {
2434- return keyMinNode->GetKey();
2512+ list_presence = eListPresence::KEYS;
24352513 }
2514+ else if ( isValueNode( prev ) )
2515+ {
2516+ list_presence = eListPresence::VALUES;
2517+ }
2518+ else
2519+ {
2520+ // ???
2521+ return nullptr;
2522+ }
2523+ }
24362524
2437- return findNextValNode( nullptr );
2438- }
2439-
2440- // If the previous node is inside the keys, then return the next key.
2441- // If there is no more next key then we return the first value.
2442- if ( this->replacements.Find( prev ) != nullptr )
2525+ while ( true )
24432526 {
2444- auto *nextByKeys = this->replacements.FindMinimumByCriteria(
2445- [&]( auto *leftNode )
2446- {
2447- eir::eCompResult cmpRes = eir::DefaultValueCompare( leftNode->GetKey(), prev );
2527+ // Increment until we find a valid next step.
2528+ if ( list_presence == eListPresence::INTERN )
2529+ {
2530+ iter = findNextInternalNode( iter );
2531+ }
2532+ else if ( list_presence == eListPresence::KEYS )
2533+ {
2534+ iter = findNextKeyNode( iter );
2535+ }
2536+ else if ( list_presence == eListPresence::VALUES )
2537+ {
2538+ iter = findNextValNode( iter );
2539+ }
24482540
2449- if ( cmpRes == eir::eCompResult::LEFT_LESS || cmpRes == eir::eCompResult::EQUAL )
2450- {
2451- return eir::eCompResult::LEFT_LESS;
2452- }
2541+ // Check for validity.
2542+ if ( iter != nullptr )
2543+ break;
24532544
2454- return eir::eCompResult::EQUAL;
2455- }
2456- );
2457-
2458- if ( nextByKeys == nullptr )
2545+ if ( list_presence == eListPresence::INTERN )
24592546 {
2460- return findNextValNode( nullptr );
2547+ list_presence = eListPresence::KEYS;
2548+ iter = nullptr;
24612549 }
2462-
2463- return nextByKeys->GetValue();
2550+ else if ( list_presence == eListPresence::KEYS )
2551+ {
2552+ list_presence = eListPresence::VALUES;
2553+ iter = nullptr;
2554+ }
2555+ else if ( list_presence == eListPresence::VALUES )
2556+ {
2557+ break;
2558+ }
2559+ else
2560+ {
2561+ // ???
2562+#ifdef _DEBUG
2563+ assert( 0 );
2564+#endif //_DEBUG
2565+ return nullptr;
2566+ }
24642567 }
2465-
2466- return findNextValNode( prev );
2568+
2569+ return iter;
24672570 }
24682571
24692572 bool IsUnambiguousCall( void ) const noexcept override
@@ -2545,18 +2648,23 @@
25452648 if ( old_exec == exec )
25462649 return;
25472650
2548- bool prev_is_new_exec_referenced = _is_step_referenced( exec );
2651+ bool prev_is_new_exec_referenced;
25492652
2653+ if ( exec != nullptr )
2654+ {
2655+ prev_is_new_exec_referenced = _is_step_referenced( exec );
2656+ }
2657+
25502658 this->exec = exec;
25512659
25522660 LexingEnvironment *env = this->env;
25532661
2554- if ( _is_step_referenced( old_exec ) == false )
2662+ if ( old_exec != nullptr && _is_step_referenced( old_exec ) == false )
25552663 {
25562664 env->gcReachSched.OnRemoveConnection( this, old_exec );
25572665 }
25582666
2559- if ( prev_is_new_exec_referenced == false )
2667+ if ( exec != nullptr && prev_is_new_exec_referenced == false )
25602668 {
25612669 env->gcReachSched.OnAddedConnection( this, exec );
25622670 }
@@ -2621,6 +2729,16 @@
26212729 this->replacements.RemoveNode( findNode );
26222730
26232731 on_value_remove( old_value );
2732+
2733+ if ( old_value != to_replace )
2734+ {
2735+ bool is_val_ref = _is_step_referenced( old_value );
2736+
2737+ if ( is_val_ref == false )
2738+ {
2739+ env->gcReachSched.OnRemoveConnection( this, old_value );
2740+ }
2741+ }
26242742 }
26252743 }
26262744 else
@@ -2632,6 +2750,16 @@
26322750 if ( old_step && old_step != replace_with )
26332751 {
26342752 on_value_remove( old_step );
2753+
2754+ if ( old_step != to_replace )
2755+ {
2756+ bool is_val_ref = _is_step_referenced( old_step );
2757+
2758+ if ( is_val_ref == false )
2759+ {
2760+ env->gcReachSched.OnRemoveConnection( this, old_step );
2761+ }
2762+ }
26352763 }
26362764
26372765 this->valrefs[ replace_with ].refcnt++;
@@ -2678,7 +2806,7 @@
26782806 return ( find_node ? find_node->GetValue() : nullptr );
26792807 }
26802808
2681- void ClearReplacements( void )
2809+ inline void ClearReplacements( void )
26822810 {
26832811 LexingEnvironment *env = this->env;
26842812
@@ -4304,9 +4432,9 @@
43044432
43054433 if ( altsNode == nullptr )
43064434 {
4307- // Optimization: an empty alternatives results in a failure.
4435+ // Optimization: an empty alternatives results in a success.
43084436 has_op_finished = true;
4309- is_op_successful = false;
4437+ is_op_successful = true;
43104438 }
43114439 else
43124440 {
@@ -4371,10 +4499,12 @@
43714499 {
43724500 auto& alts = altsteps->alts;
43734501
4374- if ( alts.GetCount() == entry.process_idx )
4502+ size_t alts_count = ( alts.GetCount() );
4503+
4504+ if ( alts_count == entry.process_idx )
43754505 {
43764506 has_op_finished = true;
4377- is_op_successful = false;
4507+ is_op_successful = ( alts_count == 0 );
43784508 }
43794509 else
43804510 {
@@ -4447,6 +4577,7 @@
44474577
44484578 if ( idx == 2 )
44494579 {
4580+ // We assume that the extend-step is never structurally empty.
44504581 has_op_finished = true;
44514582 is_op_successful = false;
44524583 }
@@ -4510,10 +4641,12 @@
45104641 // The crux is in what process_idx it starts from.
45114642 auto& alts = procaltstep->alts;
45124643
4513- if ( alts.GetCount() == entry.process_idx )
4644+ size_t alts_count = alts.GetCount();
4645+
4646+ if ( alts_count == entry.process_idx )
45144647 {
45154648 has_op_finished = true;
4516- is_op_successful = false;
4649+ is_op_successful = ( alts_count == 0 );
45174650 }
45184651 else
45194652 {
--- testcompiler/src/cos_tests.cpp (revision 63)
+++ testcompiler/src/cos_tests.cpp (revision 64)
@@ -88,6 +88,10 @@
8888 {
8989 using UnaryOperation::UnaryOperation;
9090 };
91+struct AddressOfOperation : public UnaryOperation
92+{
93+ using UnaryOperation::UnaryOperation;
94+};
9195
9296 struct BinaryOperation : public Operation
9397 {
@@ -134,6 +138,14 @@
134138 {
135139 using BinaryOperation::BinaryOperation;
136140 };
141+struct BitshiftLeftOperation : public BinaryOperation
142+{
143+ using BinaryOperation::BinaryOperation;
144+};
145+struct BitshiftRightOperation : public BinaryOperation
146+{
147+ using BinaryOperation::BinaryOperation;
148+};
137149 struct CompareEqualityOperation : public BinaryOperation
138150 {
139151 using BinaryOperation::BinaryOperation;
@@ -198,7 +210,24 @@
198210 COSNode *what;
199211 depVector <COSNode*> params;
200212 };
213+struct ArrayInitOperation : public Operation
214+{
215+ inline ArrayInitOperation( COSNode *what = nullptr, depVector <COSNode*> items = {} ) noexcept : what( what ), items( std::move( items ) )
216+ {
217+ return;
218+ }
219+ inline ArrayInitOperation( const ArrayInitOperation& ) = default;
220+ inline ArrayInitOperation( ArrayInitOperation&& right ) noexcept : items( std::move( right.items ) )
221+ {
222+ this->what = right.what;
223+
224+ right.what = nullptr;
225+ }
201226
227+ COSNode *what;
228+ depVector <COSNode*> items;
229+};
230+
202231 struct NewOperation : public Operation
203232 {
204233 inline NewOperation( COSNode *type = nullptr, depVector <COSNode*> params = {} ) noexcept : type( type ), params( std::move( params ) )
@@ -569,7 +598,58 @@
569598
570599 depMultiString numeric_string;
571600 };
601+struct SpecifierOperator : public COSNode
602+{
603+ enum class eOpType
604+ {
605+ UNDEFINED,
572606
607+ ADD,
608+ SUBTRACT,
609+ MULTIPLY,
610+ DIVIDE,
611+ MODULUS,
612+ BIT_XOR,
613+ BIT_AND,
614+ BIT_OR,
615+ LOGICAL_NEGATE,
616+ DOT,
617+ ASSIGN,
618+ BIT_NEGATE,
619+
620+ ASSIGN_ADD,
621+ ASSIGN_SUBTRACT,
622+ ASSIGN_MULTIPLY,
623+ ASSIGN_DIVIDE,
624+ ASSIGN_MODULUS,
625+ ASSIGN_BIT_XOR,
626+ ASSIGN_BIT_AND,
627+ ASSIGN_BIT_OR,
628+ ASSIGN_DOT,
629+
630+ COMPARE_EQUALITY,
631+ COMPARE_GREATER_THAN,
632+ COMPARE_LESS_THAN,
633+ COMPARE_GREATER_THAN_EQUAL,
634+ COMPARE_LESS_THAN_EQUAL,
635+ COMPARE_INEQUALITY,
636+
637+ LOGICAL_AND,
638+ LOGICAL_OR,
639+ BITSHIFT_LEFT,
640+ BITSHIFT_RIGHT
641+ };
642+
643+ inline SpecifierOperator( eOpType op_type = eOpType::UNDEFINED ) noexcept : op_type( op_type )
644+ {
645+ return;
646+ }
647+ inline SpecifierOperator( const SpecifierOperator& ) = default;
648+ inline SpecifierOperator( SpecifierOperator&& ) = default;
649+
650+ eOpType op_type = eOpType::UNDEFINED;
651+};
652+
573653 struct PointerTypeSpecifier : public COSNode
574654 {
575655 inline PointerTypeSpecifier( COSNode *spec = nullptr ) noexcept : spec( spec )
@@ -805,6 +885,148 @@
805885 };
806886 lexer.GetNamedProduction( "spec" ).GetLastStep()->setSelector <direct_obj_build_selector <char, ResolveSpecifierOperation, COSNode, dynspec_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
807887 }
888+ assert( lexer.CompileProduction( compiler, "optoksingle_epostfix", "'+-*/%^&|!.=<>'" ) == true );
889+ assert( lexer.CompileProduction( compiler, "optoksingle", "'~' | optoksingle_epostfix" ) == true );
890+ assert( lexer.CompileProduction( compiler, "optoks", "\"&&\" | \"||\" | \"<<\" | \">>\" | optoksingle_epostfix '=' | optoksingle" ) == true );
891+ assert( lexer.CompileProduction( compiler, "spec", "\"operator\" spaces optok:optoks" ) == true );
892+ {
893+ struct specifier_op_dispatcher
894+ {
895+ static inline void AssignAttributeTo( SpecifierOperator *assign_to, const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
896+ {
897+ if ( attrib != "optok" )
898+ return;
899+
900+ typedef SpecifierOperator::eOpType eOpType;
901+
902+ if ( value == "+" )
903+ {
904+ assign_to->op_type = eOpType::ADD;
905+ }
906+ else if ( value == "+=" )
907+ {
908+ assign_to->op_type = eOpType::ASSIGN_ADD;
909+ }
910+ else if ( value == "-" )
911+ {
912+ assign_to->op_type = eOpType::SUBTRACT;
913+ }
914+ else if ( value == "-=" )
915+ {
916+ assign_to->op_type = eOpType::ASSIGN_SUBTRACT;
917+ }
918+ else if ( value == "*" )
919+ {
920+ assign_to->op_type = eOpType::MULTIPLY;
921+ }
922+ else if ( value == "*=" )
923+ {
924+ assign_to->op_type = eOpType::ASSIGN_MULTIPLY;
925+ }
926+ else if ( value == "/" )
927+ {
928+ assign_to->op_type = eOpType::DIVIDE;
929+ }
930+ else if ( value == "/=" )
931+ {
932+ assign_to->op_type = eOpType::ASSIGN_DIVIDE;
933+ }
934+ else if ( value == "%" )
935+ {
936+ assign_to->op_type = eOpType::MODULUS;
937+ }
938+ else if ( value == "%=" )
939+ {
940+ assign_to->op_type = eOpType::ASSIGN_MODULUS;
941+ }
942+ else if ( value == "^" )
943+ {
944+ assign_to->op_type = eOpType::BIT_XOR;
945+ }
946+ else if ( value == "^=" )
947+ {
948+ assign_to->op_type = eOpType::ASSIGN_BIT_XOR;
949+ }
950+ else if ( value == "&" )
951+ {
952+ assign_to->op_type = eOpType::BIT_AND;
953+ }
954+ else if ( value == "&=" )
955+ {
956+ assign_to->op_type = eOpType::ASSIGN_BIT_AND;
957+ }
958+ else if ( value == "|" )
959+ {
960+ assign_to->op_type = eOpType::BIT_OR;
961+ }
962+ else if ( value == "|=" )
963+ {
964+ assign_to->op_type = eOpType::ASSIGN_BIT_OR;
965+ }
966+ else if ( value == "!" )
967+ {
968+ assign_to->op_type = eOpType::LOGICAL_NEGATE;
969+ }
970+ else if ( value == "!=" )
971+ {
972+ assign_to->op_type = eOpType::COMPARE_INEQUALITY;
973+ }
974+ else if ( value == "." )
975+ {
976+ assign_to->op_type = eOpType::DOT;
977+ }
978+ else if ( value == ".=" )
979+ {
980+ assign_to->op_type = eOpType::ASSIGN_DOT;
981+ }
982+ else if ( value == "=" )
983+ {
984+ assign_to->op_type = eOpType::ASSIGN;
985+ }
986+ else if ( value == "==" )
987+ {
988+ assign_to->op_type = eOpType::COMPARE_EQUALITY;
989+ }
990+ else if ( value == "~" )
991+ {
992+ assign_to->op_type = eOpType::BIT_NEGATE;
993+ }
994+ else if ( value == "<" )
995+ {
996+ assign_to->op_type = eOpType::COMPARE_LESS_THAN;
997+ }
998+ else if ( value == "<=" )
999+ {
1000+ assign_to->op_type = eOpType::COMPARE_LESS_THAN_EQUAL;
1001+ }
1002+ else if ( value == ">" )
1003+ {
1004+ assign_to->op_type = eOpType::COMPARE_GREATER_THAN;
1005+ }
1006+ else if ( value == ">=" )
1007+ {
1008+ assign_to->op_type = eOpType::COMPARE_GREATER_THAN_EQUAL;
1009+ }
1010+ else if ( value == "&&" )
1011+ {
1012+ assign_to->op_type = eOpType::BIT_AND;
1013+ }
1014+ else if ( value == "||" )
1015+ {
1016+ assign_to->op_type = eOpType::BIT_OR;
1017+ }
1018+ else if ( value == "<<" )
1019+ {
1020+ assign_to->op_type = eOpType::BITSHIFT_LEFT;
1021+ }
1022+ else if ( value == ">>" )
1023+ {
1024+ assign_to->op_type = eOpType::BITSHIFT_RIGHT;
1025+ }
1026+ }
1027+ };
1028+ lexer.GetNamedProduction( "spec" ).GetLastStep()->setSelector <direct_obj_build_selector <char, SpecifierOperator, COSNode, specifier_op_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1029+ }
8081030 assert( lexer.CompileProduction( compiler, "dtypedef", "\"typedef\" spaces tmultdecl spaces ';'" ) == true );
8091031 assert( lexer.CompileProduction( compiler, "block", "'{' spaces [<0>statement:extended statement, spaces] spaces '}'" ) == true );
8101032 {
@@ -843,6 +1065,54 @@
8431065 };
8441066 operation.GetLastStep()->setSelector <right_associative_selector <char, COSNode, assignment_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
8451067 }
1068+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'|' spaces]" ) != nullptr );
1069+ {
1070+ struct bor_dispatcher
1071+ {
1072+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1073+ {
1074+ return;
1075+ }
1076+
1077+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1078+ {
1079+ return new BitwiseOrOperation( left, right );
1080+ }
1081+ };
1082+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1083+ }
1084+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'^' spaces]" ) != nullptr );
1085+ {
1086+ struct bxor_dispatcher
1087+ {
1088+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1089+ {
1090+ return;
1091+ }
1092+
1093+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1094+ {
1095+ return new BitwiseXorOperation( left, right );
1096+ }
1097+ };
1098+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bxor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1099+ }
1100+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'&' spaces]" ) != nullptr );
1101+ {
1102+ struct band_dispatcher
1103+ {
1104+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1105+ {
1106+ return;
1107+ }
1108+
1109+ inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1110+ {
1111+ return new BitwiseAndOperation( left, right );
1112+ }
1113+ };
1114+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, band_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1115+ }
8461116 assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:\"||\" spaces]" ) != nullptr );
8471117 {
8481118 struct logical_or_dispatcher
@@ -959,53 +1229,51 @@
9591229 };
9601230 operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, logical_comparison_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
9611231 }
962- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'|' spaces]" ) != nullptr );
1232+ assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:(\"<<\"|\">>\") spaces]" ) != nullptr );
9631233 {
964- struct bor_dispatcher
1234+ struct bitwise_shift_dispatcher
9651235 {
966- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1236+ enum class eOpType
9671237 {
968- return;
969- }
1238+ UNDEFINED,
1239+ LEFT_SHIFT,
1240+ RIGHT_SHIFT
1241+ };
9701242
971- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
972- {
973- return new BitwiseOrOperation( left, right );
974- }
975- };
976- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
977- }
978- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'^' spaces]" ) != nullptr );
979- {
980- struct bxor_dispatcher
981- {
9821243 inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
9831244 {
984- return;
1245+ if ( attrib == "optype" )
1246+ {
1247+ if ( value == "<<" )
1248+ {
1249+ this->op_type = eOpType::LEFT_SHIFT;
1250+ }
1251+ else if ( value == ">>" )
1252+ {
1253+ this->op_type = eOpType::RIGHT_SHIFT;
1254+ }
1255+ }
9851256 }
9861257
9871258 inline COSNode* CreateOperation( COSNode *left, COSNode *right )
9881259 {
989- return new BitwiseXorOperation( left, right );
1260+ eOpType op_type = this->op_type;
1261+
1262+ if ( op_type == eOpType::LEFT_SHIFT )
1263+ {
1264+ return new BitshiftLeftOperation( left, right );
1265+ }
1266+ else if ( op_type == eOpType::RIGHT_SHIFT )
1267+ {
1268+ return new BitshiftRightOperation( left, right );
1269+ }
1270+
1271+ throw lexing_invalid_parameter_exception();
9901272 }
991- };
992- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bxor_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
993- }
994- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:'&' spaces]" ) != nullptr );
995- {
996- struct band_dispatcher
997- {
998- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
999- {
1000- return;
1001- }
10021273
1003- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1004- {
1005- return new BitwiseAndOperation( left, right );
1006- }
1274+ eOpType op_type = eOpType::UNDEFINED;
10071275 };
1008- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, band_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1276+ operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, bitwise_shift_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
10091277 }
10101278 assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces optype:('-'|'+') spaces]" ) != nullptr );
10111279 {
@@ -1175,7 +1443,7 @@
11751443 };
11761444 operation.GetLastStep()->setSelector <unary_operation_selector <char, COSNode, quickunamod_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
11771445 }
1178- assert( lexer.CompileInto( compiler, operation, "[<0,e>optype:'-~!*', spaces] opitem:operation" ) != nullptr );
1446+ assert( lexer.CompileInto( compiler, operation, "[<0,e>optype:'-~!*&', spaces] opitem:operation" ) != nullptr );
11791447 {
11801448 struct unary_negation_dispatcher
11811449 {
@@ -1185,7 +1453,8 @@
11851453 NUMERIC_NEGATION,
11861454 BITWISE_NEGATION,
11871455 LOGICAL_NEGATION,
1188- PTR_RESOLVE
1456+ PTR_RESOLVE,
1457+ ADDRESS_OF
11891458 };
11901459
11911460 inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
@@ -1208,6 +1477,10 @@
12081477 {
12091478 this->op_type = eOpType::PTR_RESOLVE;
12101479 }
1480+ else if ( value == "&" )
1481+ {
1482+ this->op_type = eOpType::ADDRESS_OF;
1483+ }
12111484 }
12121485 }
12131486
@@ -1231,6 +1504,10 @@
12311504 {
12321505 return new PointerResolveOperation( op );
12331506 }
1507+ else if ( op_type == eOpType::ADDRESS_OF )
1508+ {
1509+ return new AddressOfOperation( op );
1510+ }
12341511
12351512 throw lexing_invalid_parameter_exception();
12361513 }
@@ -1368,31 +1645,113 @@
13681645 };
13691646 operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, key_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
13701647 }
1371- assert( lexer.CompileInto( compiler, operation, "[istempl_inst:\"template\" spaces op:operation spaces '<' spaces [<0> procgate type, spaces ',' spaces] spaces '>' | op:operation, spaces '.' spaces]" ) != nullptr );
1648+ assert( lexer.CompileInto( compiler, operation, "op:operation (spaces '{' spaces [<0> item:procgate operation, spaces ',' spaces] spaces endarrtok:'}')^0:1" ) != nullptr );
13721649 {
1373- struct dot_with_templ_dispatcher
1650+ struct arrayinit_selector
13741651 {
1652+ inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
1653+ {
1654+ if ( attrib == "endarrtok" )
1655+ {
1656+ this->root = new ArrayInitOperation( this->root, std::move( this->items ) );
1657+ }
1658+ }
13751659
1660+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
1661+ {
1662+ if ( attrib == "op" )
1663+ {
1664+ this->root = node;
1665+ return true;
1666+ }
1667+ if ( attrib == "item" )
1668+ {
1669+ this->items.AddToBack( node );
1670+ return true;
1671+ }
1672+
1673+ return false;
1674+ }
1675+
1676+ inline COSNode* DetachFinishedNode( void )
1677+ {
1678+ COSNode *result = this->root;
1679+
1680+ this->root = nullptr;
1681+
1682+ return result;
1683+ }
1684+
1685+ COSNode *root = nullptr;
1686+ depVector <COSNode*> items;
13761687 };
1688+ operation.GetLastStep()->setSelector <arrayinit_selector> ();
13771689 }
1378-#if 0
1379- assert( lexer.CompileInto( compiler, operation, "[opitem:operation, spaces '.' spaces]" ) != nullptr );
1690+ assert( lexer.CompileInto( compiler, operation, "[\"template\" spaces templop:operation spaces '<' spaces [<0> templarg:procgate type, spaces ',' spaces] spaces endtempl:'>' | dotitem:operation, spaces '.' spaces]" ) != nullptr );
13801691 {
1381- struct dot_dispatcher
1692+ struct dot_with_templ_selector
13821693 {
1694+ inline void AddNodeAsRootDot( COSNode *node )
1695+ {
1696+ COSNode *prev_root = this->root;
1697+
1698+ if ( prev_root == nullptr )
1699+ {
1700+ this->root = node;
1701+ return;
1702+ }
1703+
1704+ this->root = new DotOperation( prev_root, node );
1705+ }
1706+
13831707 inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
13841708 {
1385- return;
1709+ if ( attrib == "endtempl" )
1710+ {
1711+ this->AddNodeAsRootDot( templop );
1712+ this->root = new TemplateInstantiationOperation( this->root, std::move( this->templargs ) );
1713+
1714+ this->templop = nullptr;
1715+ return;
1716+ }
13861717 }
13871718
1388- inline COSNode* CreateOperation( COSNode *left, COSNode *right )
1719+ inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
13891720 {
1390- return new DotOperation( left, right );
1721+ if ( attrib == "dotitem" )
1722+ {
1723+ this->AddNodeAsRootDot( node );
1724+ return true;
1725+ }
1726+ else if ( attrib == "templop" )
1727+ {
1728+ this->templop = node;
1729+ return true;
1730+ }
1731+ else if ( attrib == "templarg" )
1732+ {
1733+ this->templargs.AddToBack( node );
1734+ return true;
1735+ }
1736+
1737+ return false;
13911738 }
1739+
1740+ inline COSNode* DetachFinishedNode( void ) noexcept
1741+ {
1742+ COSNode *result = this->root;
1743+
1744+ this->root = nullptr;
1745+
1746+ return result;
1747+ }
1748+
1749+ COSNode *root = nullptr;
1750+ COSNode *templop = nullptr;
1751+ depVector <COSNode*> templargs;
13921752 };
1393- operation.GetLastStep()->setSelector <left_associative_selector <char, COSNode, dot_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1753+ operation.GetLastStep()->setSelector <dot_with_templ_selector> ();
13941754 }
1395-#endif //0
13961755
13971756 auto tailop = lexer.MakeStep <decltype(lexer)::RuntimeEnv::StepAlternatives> ();
13981757
@@ -1418,6 +1777,28 @@
14181777 };
14191778 tailop.GetLastStep()->setSelector <direct_obj_build_selector <char, NewOperation, COSNode, new_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
14201779 }
1780+ assert( lexer.CompileInto( compiler, tailop, "\"cast\" spaces '<' spaces totype:type spaces '>' spaces '(' spaces castobj:procgate operation spaces ')'" ) != nullptr );
1781+ {
1782+ struct cast_dispatcher
1783+ {
1784+ static inline bool AssignNodeTo( CastOperation *assign_to, const eir::FixedString <char>& attrib, COSNode *node )
1785+ {
1786+ if ( attrib == "totype" )
1787+ {
1788+ assign_to->totype = node;
1789+ return true;
1790+ }
1791+ if ( attrib == "castobj" )
1792+ {
1793+ assign_to->castobj = node;
1794+ return true;
1795+ }
1796+
1797+ return false;
1798+ }
1799+ };
1800+ tailop.GetLastStep()->setSelector <direct_obj_build_selector <char, CastOperation, COSNode, cast_dispatcher, decltype(lexer)::RuntimeEnv>> ( &lexer.GetRuntimeEnvironment() );
1801+ }
14211802 assert( lexer.CompileInto( compiler, tailop, "name" ) != nullptr );
14221803 assert( lexer.CompileInto( compiler, tailop, "number" ) != nullptr );
14231804 assert( lexer.CompileInto( compiler, tailop, "'{' spaces [item:procgate operation, spaces ',' spaces] spaces '}'" ) != nullptr );
@@ -2055,8 +2436,8 @@
20552436 };
20562437 lexer.GetNamedProduction( "tmultdecl" ).setSelector <tmultdecl_selector> ();
20572438 }
2058- assert( lexer.CompileProduction( compiler, "funcsigdecl", "functag spaces ( '(' spaces locator spaces (subfunc:funcsigdecl|locatedname) spaces ')' | name:spec ) spaces '(' spaces paramlist_opt spaces ')'" ) == true );
2059- assert( lexer.CompileProduction( compiler, "funcsigdecl_opt", "functag spaces ('(' spaces locator spaces (subfunc:funcsigdecl_opt|locatedname_opt) spaces ')' | (name:spec)^0:1) spaces '(' spaces paramlist_opt spaces ')'" ) == true );
2439+ assert( lexer.CompileProduction( compiler, "funcsigtempl", "functag spaces ( '(' spaces locator spaces (subfunc:funcsigtempl|locnametempl) spaces ')' | name:replaceable nameplacehold ) spaces '(' spaces paramlist_opt spaces ')'" ) == true ); // helper
2440+ assert( lexer.CompileProduction( compiler, "funcsigdecl", "&(funcsigtempl, nameplacehold=spec)" ) == true );
20602441 {
20612442 struct funcsig_selector
20622443 {
@@ -2115,15 +2496,15 @@
21152496 FuncsigDefinition *subfunc = nullptr;
21162497 };
21172498 lexer.GetNamedProduction( "funcsigdecl" ).setSelector <funcsig_selector> ();
2118- lexer.GetNamedProduction( "funcsigdecl_opt" ).setSelector <funcsig_selector> ();
21192499 }
2120- assert( lexer.CompileProduction( compiler, "locatedname", "name:spec (spaces [arrspec:arrayspec, spaces])^0:1" ) == true ); // helper
2121- assert( lexer.CompileProduction( compiler, "locatedname_opt", "(name:spec)^0:1 (spaces [arrspec:arrayspec, spaces])^0:1" ) == true ); // helper.
2500+ assert( lexer.CompileProduction( compiler, "locnametempl", "name:replaceable nameplacehold (spaces [arrspec:arrayspec, spaces])^0:1" ) == true ); // helper
2501+ assert( lexer.CompileProduction( compiler, "locatedname", "&(locnametempl, nameplacehold=spec)" ) == true );
21222502 assert( lexer.CompileProduction( compiler, "arrayspec", "'[' spaces (idx:operation spaces)^0:1 endtok:']'" ) == true ); // helper
21232503 // Set-up both of the following productions in one block.
2124- assert( lexer.CompileProduction( compiler, "declaration", "utype:spec spaces locator spaces (func:funcsigdecl|locatedname) declinit" ) == true );
2125- assert( lexer.CompileProduction( compiler, "decl_optnoinit", "utype:spec spaces locator spaces (func:funcsigdecl_opt|locatedname_opt)" ) == true );
2126- assert( lexer.CompileProduction( compiler, "decl_opt", "inline decl_optnoinit declinit" ) == true );
2504+ assert( lexer.CompileProduction( compiler, "decltemplate", "utype:spec spaces locator spaces (func:funcsigtempl|locnametempl) replaceable initplacehold" ) == true ); // helper
2505+ assert( lexer.CompileProduction( compiler, "declaration", "&(decltemplate, nameplacehold=spec, initplacehold=declinit)" ) == true );
2506+ assert( lexer.CompileProduction( compiler, "decl_optnoinit", "&(decltemplate, nameplacehold=(spec)^0:1, initplacehold=empty)" ) == true );
2507+ assert( lexer.CompileProduction( compiler, "decl_opt", "&(decltemplate, nameplacehold=(spec)^0:1, initplacehold=declinit)" ) == true );
21272508 assert( lexer.CompileProduction( compiler, "multdecl", "utype:spec spaces [locator spaces (func:funcsigdecl|locatedname) declinit, spaces nextdecl:',' spaces]" ) == true );
21282509 {
21292510 struct declaration_selector
@@ -2383,64 +2764,8 @@
23832764 lexer.AddStep( "initexpr", std::move( special_declinit ) );
23842765 }
23852766 assert( lexer.CompileProduction( compiler, "declinit", "( spaces init:initexpr | spaces '=' spaces init:operation | spaces init:curlypack )^0:1" ) == true );
2386- assert( lexer.CompileProduction( compiler, "typelocator", "[<0>arrspec:arrayspec, spaces]" ) == true ); // helper
2387- assert( lexer.CompileProduction( compiler, "typefuncsig", "functag spaces ( '(' spaces locator spaces (subfunc:typefuncsig|typelocator) spaces ')' spaces )^0:1 '(' spaces paramlist_opt spaces ')'" ) == true );
2388- {
2389- struct typefuncsig_selector
2390- {
2391- inline void AssignAttribute( const eir::FixedString <char>& attrib, const eir::FixedString <char>& value )
2392- {
2393- locbuild.AssignAttribute( attrib, value );
2394- }
2395-
2396- inline bool AssignNode( const eir::FixedString <char>& attrib, COSNode *node )
2397- {
2398- if ( attrib == "param" )
2399- {
2400- this->funcsig.params.AddToBack( node );
2401- return true;
2402- }
2403- else if ( attrib == "subfunc" )
2404- {
2405- this->subfunc = dynamic_cast <FuncsigDefinition*> ( node );
2406- return true;
2407- }
2408- else
2409- {
2410- return locbuild.AssignNode( attrib, node );
2411- }
2412- }
2413-
2414- inline COSNode* DetachFinishedNode( void )
2415- {
2416- COSNode *type;
2417-
2418- COSNode *detached_func = this->locbuild.EncapsulateByTypeLocators( new FuncsigDefinition( std::move( this->funcsig ) ) );
2419-
2420- if ( FuncsigDefinition *subfunc = this->subfunc )
2421- {
2422- FuncsigDefinition *left_most_func = subfunc->GetDeepestReturnValueFunctionSignatureType();
2423-
2424- left_most_func->return_type = detached_func;
2425-
2426- type = subfunc;
2427- }
2428- else
2429- {
2430- type = detached_func;
2431- }
2432-
2433- return type;
2434- }
2435-
2436- declaratory_locator_builder locbuild;
2437- FuncsigDefinition *subfunc = nullptr;
2438- FuncsigDefinition funcsig;
2439- };
2440- lexer.GetNamedProduction( "typefuncsig" ).setSelector <typefuncsig_selector> ();
2441- }
24422767 assert( lexer.CompileProduction( compiler, "functag", "\"func\" | \"operator\" | \"proc\"" ) == true );
2443- assert( lexer.CompileProduction( compiler, "type", "utype:spec spaces locator spaces (func:typefuncsig|typelocator)" ) == true );
2768+ assert( lexer.CompileProduction( compiler, "type", "&(decltemplate, nameplacehold=spec, initplacehold=empty)" ) == true );
24442769 {
24452770 struct type_selector
24462771 {
@@ -4722,7 +5047,35 @@
47225047
47235048 printf( "testing COS functions..." );
47245049 {
4725- // TODO.
5050+ // 1)
5051+ {
5052+
5053+ }
5054+
5055+ // 2)
5056+ {
5057+
5058+ }
5059+
5060+ // 3)
5061+ {
5062+
5063+ }
5064+
5065+ // 4)
5066+ {
5067+
5068+ }
5069+
5070+ // 5)
5071+ {
5072+
5073+ }
5074+
5075+ // 6)
5076+ {
5077+
5078+ }
47265079 }
47275080 printf( "ok.\n" );
47285081
Show on old repository browser