@@ -136,6 +136,28 @@ void RewriteStep::dump(llvm::raw_ostream &out,
136136 out << difference.LHS << " : " << difference.RHS << " )" ;
137137 break ;
138138 }
139+ case LeftConcreteProjection: {
140+ evaluator.applyLeftConcreteProjection (*this , system);
141+
142+ out << " LeftConcrete" << (Inverse ? " In" : " Pro" ) << " jection(" ;
143+
144+ const auto &difference = system.getTypeDifference (
145+ getTypeDifferenceID ());
146+
147+ out << difference.LHS << " : " << difference.RHS << " )" ;
148+ break ;
149+ }
150+ case RightConcreteProjection: {
151+ evaluator.applyRightConcreteProjection (*this , system);
152+
153+ out << " RightConcrete" << (Inverse ? " In" : " Pro" ) << " jection(" ;
154+
155+ const auto &difference = system.getTypeDifference (
156+ getTypeDifferenceID ());
157+
158+ out << difference.LHS << " : " << difference.RHS << " )" ;
159+ break ;
160+ }
139161 }
140162}
141163
@@ -542,6 +564,139 @@ void RewritePathEvaluator::applyDecomposeConcrete(const RewriteStep &step,
542564 }
543565}
544566
567+ void
568+ RewritePathEvaluator::applyLeftConcreteProjection (const RewriteStep &step,
569+ const RewriteSystem &system) {
570+ assert (step.Kind == RewriteStep::LeftConcreteProjection);
571+
572+ const auto &difference = system.getTypeDifference (step.getTypeDifferenceID ());
573+ unsigned index = step.getSubstitutionIndex ();
574+
575+ MutableTerm leftProjection (difference.LHS .getSubstitutions ()[index]);
576+
577+ MutableTerm leftBaseTerm (difference.BaseTerm );
578+ leftBaseTerm.add (difference.LHS );
579+
580+ auto bug = [&](StringRef msg) {
581+ llvm::errs () << msg << " \n " ;
582+ llvm::errs () << " - StartOffset: " << step.StartOffset << " \n " ;
583+ llvm::errs () << " - EndOffset: " << step.EndOffset << " \n " ;
584+ llvm::errs () << " - SubstitutionIndex: " << index << " \n " ;
585+ llvm::errs () << " - LeftProjection: " << leftProjection << " \n " ;
586+ llvm::errs () << " - LeftBaseTerm: " << leftBaseTerm << " \n " ;
587+ llvm::errs () << " - DifferenceID: " << step.getTypeDifferenceID () << " \n " ;
588+ llvm::errs () << " \n Type difference:\n " ;
589+ difference.dump (llvm::errs ());
590+ llvm::errs () << " :\n " ;
591+ difference.dump (llvm::errs ());
592+ llvm::errs () << " \n Evaluator state:\n " ;
593+ dump (llvm::errs ());
594+ abort ();
595+ };
596+
597+ if (!step.Inverse ) {
598+ const auto &term = getCurrentTerm ();
599+
600+ MutableTerm subTerm (term.begin () + step.StartOffset ,
601+ term.end () - step.EndOffset );
602+ if (subTerm != MutableTerm (leftProjection))
603+ bug (" Incorrect left projection term" );
604+
605+ Primary.push_back (leftBaseTerm);
606+ } else {
607+ if (Primary.size () < 2 )
608+ bug (" Too few elements on the primary stack" );
609+
610+ if (Primary.back () != leftBaseTerm)
611+ bug (" Incorrect left base term" );
612+
613+ Primary.pop_back ();
614+
615+ const auto &term = getCurrentTerm ();
616+
617+ MutableTerm subTerm (term.begin () + step.StartOffset ,
618+ term.end () - step.EndOffset );
619+ if (subTerm != leftProjection)
620+ bug (" Incorrect left projection term" );
621+ }
622+ }
623+
624+ void
625+ RewritePathEvaluator::applyRightConcreteProjection (const RewriteStep &step,
626+ const RewriteSystem &system) {
627+ assert (step.Kind == RewriteStep::RightConcreteProjection);
628+
629+ const auto &difference = system.getTypeDifference (step.getTypeDifferenceID ());
630+ unsigned index = step.getSubstitutionIndex ();
631+
632+ MutableTerm leftProjection (difference.LHS .getSubstitutions ()[index]);
633+ auto rightProjection = difference.getReplacementSubstitution (index);
634+
635+ MutableTerm leftBaseTerm (difference.BaseTerm );
636+ leftBaseTerm.add (difference.LHS );
637+
638+ MutableTerm rightBaseTerm (difference.BaseTerm );
639+ rightBaseTerm.add (difference.RHS );
640+
641+ auto bug = [&](StringRef msg) {
642+ llvm::errs () << msg << " \n " ;
643+ llvm::errs () << " - StartOffset: " << step.StartOffset << " \n " ;
644+ llvm::errs () << " - EndOffset: " << step.EndOffset << " \n " ;
645+ llvm::errs () << " - SubstitutionIndex: " << index << " \n " ;
646+ llvm::errs () << " - LeftProjection: " << leftProjection << " \n " ;
647+ llvm::errs () << " - RightProjection: " << rightProjection << " \n " ;
648+ llvm::errs () << " - LeftBaseTerm: " << leftBaseTerm << " \n " ;
649+ llvm::errs () << " - RightBaseTerm: " << rightBaseTerm << " \n " ;
650+ llvm::errs () << " - DifferenceID: " << step.getTypeDifferenceID () << " \n " ;
651+ llvm::errs () << " \n Type difference:\n " ;
652+ difference.dump (llvm::errs ());
653+ llvm::errs () << " :\n " ;
654+ difference.dump (llvm::errs ());
655+ llvm::errs () << " \n Evaluator state:\n " ;
656+ dump (llvm::errs ());
657+ abort ();
658+ };
659+
660+ if (!step.Inverse ) {
661+ auto &term = getCurrentTerm ();
662+
663+ MutableTerm subTerm (term.begin () + step.StartOffset ,
664+ term.end () - step.EndOffset );
665+
666+ if (subTerm != rightProjection)
667+ bug (" Incorrect right projection term" );
668+
669+ MutableTerm newTerm (term.begin (), term.begin () + step.StartOffset );
670+ newTerm.append (leftProjection);
671+ newTerm.append (term.end () - step.EndOffset , term.end ());
672+
673+ term = newTerm;
674+
675+ Primary.push_back (rightBaseTerm);
676+ } else {
677+ if (Primary.size () < 2 )
678+ bug (" Too few elements on the primary stack" );
679+
680+ if (Primary.back () != rightBaseTerm)
681+ bug (" Incorrect right base term" );
682+
683+ Primary.pop_back ();
684+
685+ auto &term = getCurrentTerm ();
686+
687+ MutableTerm subTerm (term.begin () + step.StartOffset ,
688+ term.end () - step.EndOffset );
689+ if (subTerm != leftProjection)
690+ bug (" Incorrect left projection term" );
691+
692+ MutableTerm newTerm (term.begin (), term.begin () + step.StartOffset );
693+ newTerm.append (rightProjection);
694+ newTerm.append (term.end () - step.EndOffset , term.end ());
695+
696+ term = newTerm;
697+ }
698+ }
699+
545700void RewritePathEvaluator::apply (const RewriteStep &step,
546701 const RewriteSystem &system) {
547702 switch (step.Kind ) {
@@ -568,5 +723,13 @@ void RewritePathEvaluator::apply(const RewriteStep &step,
568723 case RewriteStep::DecomposeConcrete:
569724 applyDecomposeConcrete (step, system);
570725 break ;
726+
727+ case RewriteStep::LeftConcreteProjection:
728+ applyLeftConcreteProjection (step, system);
729+ break ;
730+
731+ case RewriteStep::RightConcreteProjection:
732+ applyRightConcreteProjection (step, system);
733+ break ;
571734 }
572735}
0 commit comments