- File:
-
- 1 edited
-
src/ResolvExpr/AlternativeFinder.cc (modified) (33 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
r83882e9 r62194cb 30 30 #include "Common/utility.h" // for deleteAll, printAll, CodeLocation 31 31 #include "Cost.h" // for Cost, Cost::zero, operator<<, Cost... 32 #include "ExplodedActual.h" // for ExplodedActual 32 33 #include "InitTweak/InitTweak.h" // for getFunctionName 33 34 #include "RenameVars.h" // for RenameVars, global_renamer … … 186 187 expr->accept( *this ); 187 188 if ( failFast && alternatives.empty() ) { 188 PRINT(189 std::cerr << "No reasonable alternatives for expression " << expr << std::endl;190 )191 189 throw SemanticError( "No reasonable alternatives for expression ", expr ); 192 190 } … … 581 579 /// State to iteratively build a match of parameter expressions to arguments 582 580 struct ArgPack { 583 std::size_t parent; ///< Index of parent pack 581 std::size_t parent; ///< Index of parent pack 584 582 std::unique_ptr<Expression> expr; ///< The argument stored here 585 583 Cost cost; ///< The cost of this argument … … 590 588 unsigned nextArg; ///< Index of next argument in arguments list 591 589 unsigned tupleStart; ///< Number of tuples that start at this index 592 // TODO fix this somehow593 std::vector<Alternative> expls; ///< Exploded actuals left over from last match594 590 unsigned nextExpl; ///< Index of next exploded element 591 unsigned explAlt; ///< Index of alternative for nextExpl > 0 592 595 593 ArgPack() 596 594 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 597 tupleStart(0), expls() {}598 599 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 595 tupleStart(0), nextExpl(0), explAlt(0) {} 596 597 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 600 598 const OpenVarSet& openVars) 601 : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 602 openVars(openVars), nextArg(0), tupleStart(0), expls() {}603 604 ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need, 605 AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg, 606 unsigned tupleStart = 0, Cost cost = Cost::zero, 607 std::vector<Alternative>&& expls = std::vector<Alternative>{})608 : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 599 : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 600 openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {} 601 602 ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need, 603 AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg, 604 unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0, 605 unsigned explAlt = 0 ) 606 : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 609 607 have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart), 610 expls(move(expls)) {}611 612 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 608 nextExpl(nextExpl), explAlt(explAlt) {} 609 610 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 613 611 OpenVarSet&& openVars, unsigned nextArg, Cost added ) 614 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 615 env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 616 nextArg(nextArg), tupleStart(o.tupleStart), expls() {}617 618 619 // ArgPack(const ArgPack& o)620 // : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), env(o.env), 621 // need(o.need), have(o.have), openVars(o.openVars), nextArg(o.nextArg),622 // tupleStart(o.tupleStart), expls(o.expls) {}623 624 // ArgPack(ArgPack&&) = default;625 612 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 613 env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 614 nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {} 615 616 /// true iff this pack is in the middle of an exploded argument 617 bool hasExpl() const { return nextExpl > 0; } 618 619 /// Gets the list of exploded alternatives for this pack 620 const ExplodedActual& getExpl( const ExplodedArgs& args ) const { 621 return args[nextArg-1][explAlt]; 622 } 623 626 624 /// Ends a tuple expression, consolidating the appropriate actuals 627 625 void endTuple( const std::vector<ArgPack>& packs ) { … … 643 641 644 642 /// Instantiates an argument to match a formal, returns false if no results left 645 bool instantiateArgument( Type* formalType, Initializer* initializer, 646 const std::vector< AlternativeFinder >& args, std::vector<ArgPack>& results,647 std::size_t& genStart,const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {643 bool instantiateArgument( Type* formalType, Initializer* initializer, 644 const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart, 645 const SymTab::Indexer& indexer, unsigned nTuples = 0 ) { 648 646 if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) { 649 647 // formalType is a TupleType - group actuals into a TupleExpr … … 651 649 for ( Type* type : *tupleType ) { 652 650 // xxx - dropping initializer changes behaviour from previous, but seems correct 653 if ( ! instantiateArgument( 654 type, nullptr, args, results, genStart, indexer, nTuples ) ) 651 if ( ! instantiateArgument( 652 type, nullptr, args, results, genStart, indexer, nTuples ) ) 655 653 return false; 656 654 nTuples = 0; … … 676 674 // add another argument to results 677 675 for ( std::size_t i = genStart; i < genEnd; ++i ) { 678 // use remainder of exploded tuple if present679 if ( ! results[i].expls.empty() ) { 680 const Alternative& actual = results[i].expls.front();681 682 TypeEnvironment env = results[i].env;683 OpenVarSet openVars = results[i].openVars;684 685 env.addActual( actual.env, openVars );686 687 std::vector<Alternative> newExpls(688 std::next( results[i].expls.begin() ), results[i].expls.end() ); 676 auto nextArg = results[i].nextArg; 677 678 // use next element of exploded tuple if present 679 if ( results[i].hasExpl() ) { 680 const ExplodedActual& expl = results[i].getExpl( args ); 681 682 unsigned nextExpl = results[i].nextExpl + 1; 683 if ( nextExpl == expl.exprs.size() ) { 684 nextExpl = 0; 685 } 686 689 687 results.emplace_back( 690 i, actual.expr, move(env), copy(results[i].need), 691 copy(results[i].have), move(openVars), results[i].nextArg, nTuples, 692 Cost::zero, move(newExpls) ); 693 688 i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env), 689 copy(results[i].need), copy(results[i].have), 690 copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl, 691 results[i].explAlt ); 692 694 693 continue; 695 694 } 696 695 697 696 // finish result when out of arguments 698 if ( results[i].nextArg >= args.size() ) {699 ArgPack newResult{ 700 results[i].env, results[i].need, results[i].have, 697 if ( nextArg >= args.size() ) { 698 ArgPack newResult{ 699 results[i].env, results[i].need, results[i].have, 701 700 results[i].openVars }; 702 newResult.nextArg = results[i].nextArg;701 newResult.nextArg = nextArg; 703 702 Type* argType; 704 703 … … 718 717 719 718 if ( results[i].tupleStart > 0 && Tuples::isTtype( argType ) ) { 720 // the case where a ttype value is passed directly is special, 719 // the case where a ttype value is passed directly is special, 721 720 // e.g. for argument forwarding purposes 722 // xxx - what if passing multiple arguments, last of which is 721 // xxx - what if passing multiple arguments, last of which is 723 722 // ttype? 724 // xxx - what would happen if unify was changed so that unifying 725 // tuple 726 // types flattened both before unifying lists? then pass in 723 // xxx - what would happen if unify was changed so that unifying 724 // tuple 725 // types flattened both before unifying lists? then pass in 727 726 // TupleType (ttype) below. 728 727 --newResult.tupleStart; … … 735 734 736 735 // check unification for ttype before adding to final 737 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have, 736 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have, 738 737 newResult.openVars, indexer ) ) { 739 738 finalResults.push_back( move(newResult) ); 740 739 } 741 740 742 741 continue; 743 742 } 744 743 745 744 // add each possible next argument 746 auto j = results[i].nextArg; 747 for ( const Alternative& actual : args[j] ) { 745 for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) { 746 const ExplodedActual& expl = args[nextArg][j]; 747 748 748 // fresh copies of parent parameters for this iteration 749 749 TypeEnvironment env = results[i].env; 750 750 OpenVarSet openVars = results[i].openVars; 751 751 752 env.addActual( actual.env, openVars ); 753 754 // explode argument 755 std::vector<Alternative> exploded; 756 Tuples::explode( actual, indexer, back_inserter( exploded ) ); 757 if ( exploded.empty() ) { 758 // skip empty tuple arguments by (near-)cloning parent into next gen 752 env.addActual( expl.env, openVars ); 753 754 // skip empty tuple arguments by (near-)cloning parent into next gen 755 if ( expl.exprs.empty() ) { 759 756 results.emplace_back( 760 results[i], move(env), copy(results[i].need), 761 copy(results[i].have), move(openVars), j + 1, actual.cost );762 757 results[i], move(env), copy(results[i].need), 758 copy(results[i].have), move(openVars), nextArg + 1, expl.cost ); 759 763 760 continue; 764 761 } 765 762 766 // trim first element from exploded767 std::vector<Alternative> newExpls;768 newExpls.reserve( exploded.size() - 1 );769 for ( std::size_t i = 1; i < exploded.size(); ++i ) {770 newExpls.push_back( move(exploded[i]) );771 }772 763 // add new result 773 764 results.emplace_back( 774 i, expl oded.front().expr, move(env), copy(results[i].need),775 copy(results[i].have), move(openVars), results[i].nextArg + 1,776 nTuples, actual.cost, move(newExpls));765 i, expl.exprs.front().get(), move(env), copy(results[i].need), 766 copy(results[i].have), move(openVars), nextArg + 1, 767 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 777 768 } 778 769 } … … 793 784 std::size_t genEnd = results.size(); 794 785 for ( std::size_t i = genStart; i < genEnd; ++i ) { 786 auto nextArg = results[i].nextArg; 787 795 788 // use remainder of exploded tuple if present 796 if ( ! results[i].expls.empty() ) { 797 const Alternative& actual = results[i].expls.front(); 798 789 if ( results[i].hasExpl() ) { 790 const ExplodedActual& expl = results[i].getExpl( args ); 791 Expression* expr = expl.exprs[results[i].nextExpl].get(); 792 799 793 TypeEnvironment env = results[i].env; 800 794 AssertionSet need = results[i].need, have = results[i].have; 801 795 OpenVarSet openVars = results[i].openVars; 802 796 803 env.addActual( actual.env, openVars ); 804 Type* actualType = actual.expr->get_result(); 797 Type* actualType = expr->get_result(); 805 798 806 799 PRINT( … … 811 804 std::cerr << std::endl; 812 805 ) 813 806 814 807 if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) { 815 std::vector<Alternative> newExpls( 816 std::next( results[i].expls.begin() ), results[i].expls.end() ); 817 results.emplace_back( 818 i, actual.expr, move(env), move(need), move(have), move(openVars), 819 results[i].nextArg, nTuples, Cost::zero, move(newExpls) );; 808 unsigned nextExpl = results[i].nextExpl + 1; 809 if ( nextExpl == expl.exprs.size() ) { 810 nextExpl = 0; 811 } 812 813 results.emplace_back( 814 i, expr, move(env), move(need), move(have), move(openVars), nextArg, 815 nTuples, Cost::zero, nextExpl, results[i].explAlt ); 820 816 } 821 817 822 818 continue; 823 819 } 824 820 825 821 // use default initializers if out of arguments 826 if ( results[i].nextArg >= args.size() ) {822 if ( nextArg >= args.size() ) { 827 823 if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) { 828 824 if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) { … … 831 827 OpenVarSet openVars = results[i].openVars; 832 828 833 if ( unify( formalType, cnst->get_type(), env, need, have, openVars, 829 if ( unify( formalType, cnst->get_type(), env, need, have, openVars, 834 830 indexer ) ) { 835 831 results.emplace_back( 836 i, cnstExpr, move(env), move(need), move(have), 837 move(openVars), results[i].nextArg, nTuples );832 i, cnstExpr, move(env), move(need), move(have), 833 move(openVars), nextArg, nTuples ); 838 834 } 839 835 } … … 844 840 845 841 // Check each possible next argument 846 auto j = results[i].nextArg; 847 for ( const Alternative& actual : args[j] ) { 842 for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) { 843 const ExplodedActual& expl = args[nextArg][j]; 844 848 845 // fresh copies of parent parameters for this iteration 849 846 TypeEnvironment env = results[i].env; … … 851 848 OpenVarSet openVars = results[i].openVars; 852 849 853 env.addActual( actual.env, openVars ); 854 855 // explode argument 856 std::vector<Alternative> exploded; 857 Tuples::explode( actual, indexer, back_inserter( exploded ) ); 858 if ( exploded.empty() ) { 859 // skip empty tuple arguments by (near-)cloning parent into next gen 850 env.addActual( expl.env, openVars ); 851 852 // skip empty tuple arguments by (near-)cloning parent into next gen 853 if ( expl.exprs.empty() ) { 860 854 results.emplace_back( 861 results[i], move(env), move(need), move(have), move(openVars), j + 1,862 actual.cost );855 results[i], move(env), move(need), move(have), move(openVars), 856 nextArg + 1, expl.cost ); 863 857 864 858 continue; … … 866 860 867 861 // consider only first exploded actual 868 const Alternative& aActual = exploded.front();869 Type* actualType = aActual.expr->get_result()->clone();862 Expression* expr = expl.exprs.front().get(); 863 Type* actualType = expr->get_result()->clone(); 870 864 871 865 PRINT( … … 879 873 // attempt to unify types 880 874 if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) { 881 // trim first element from exploded882 std::vector<Alternative> newExpls;883 newExpls.reserve( exploded.size() - 1 );884 for ( std::size_t i = 1; i < exploded.size(); ++i ) {885 newExpls.push_back( move(exploded[i]) );886 }887 875 // add new result 888 876 results.emplace_back( 889 i, aActual.expr, move(env), move(need), move(have), move(openVars),890 j + 1, nTuples, actual.cost, move(newExpls));877 i, expr, move(env), move(need), move(have), move(openVars), nextArg + 1, 878 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 891 879 } 892 880 } … … 895 883 // reset for next parameter 896 884 genStart = genEnd; 897 885 898 886 return genEnd != results.size(); 899 887 } 900 888 901 889 template<typename OutputIterator> 902 void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 890 void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 903 891 const std::vector<ArgPack>& results, OutputIterator out ) { 904 892 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); … … 924 912 template<typename OutputIterator> 925 913 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, 926 FunctionType *funcType, const std::vector< AlternativeFinder > &args, 927 OutputIterator out ) { 914 FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) { 928 915 OpenVarSet funcOpenVars; 929 916 AssertionSet funcNeed, funcHave; … … 951 938 for ( DeclarationWithType* formal : funcType->get_parameters() ) { 952 939 ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal ); 953 if ( ! instantiateArgument( 940 if ( ! instantiateArgument( 954 941 obj->get_type(), obj->get_init(), args, results, genStart, indexer ) ) 955 942 return; … … 964 951 // iterate results 965 952 for ( std::size_t i = genStart; i < genEnd; ++i ) { 953 auto nextArg = results[i].nextArg; 954 966 955 // use remainder of exploded tuple if present 967 if ( ! results[i].expls.empty() ) { 968 const Alternative& actual = results[i].expls.front(); 969 970 TypeEnvironment env = results[i].env; 971 OpenVarSet openVars = results[i].openVars; 972 973 env.addActual( actual.env, openVars ); 974 975 std::vector<Alternative> newExpls( 976 std::next( results[i].expls.begin() ), results[i].expls.end() ); 956 if ( results[i].hasExpl() ) { 957 const ExplodedActual& expl = results[i].getExpl( args ); 958 959 unsigned nextExpl = results[i].nextExpl + 1; 960 if ( nextExpl == expl.exprs.size() ) { 961 nextExpl = 0; 962 } 963 977 964 results.emplace_back( 978 i, actual.expr, move(env), copy(results[i].need), 979 copy(results[i].have), move(openVars), results[i].nextArg, 0, 980 Cost::zero, move(newExpls) ); 981 965 i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env), 966 copy(results[i].need), copy(results[i].have), 967 copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl, 968 results[i].explAlt ); 969 982 970 continue; 983 971 } 984 972 985 973 // finish result when out of arguments 986 if ( results[i].nextArg >= args.size() ) {974 if ( nextArg >= args.size() ) { 987 975 validateFunctionAlternative( func, results[i], results, out ); 988 976 … … 991 979 992 980 // add each possible next argument 993 auto j = results[i].nextArg; 994 for ( const Alternative& actual : args[j] ) { 981 for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) { 982 const ExplodedActual& expl = args[nextArg][j]; 983 995 984 // fresh copies of parent parameters for this iteration 996 985 TypeEnvironment env = results[i].env; 997 986 OpenVarSet openVars = results[i].openVars; 998 987 999 env.addActual( actual.env, openVars ); 1000 1001 // explode argument 1002 std::vector<Alternative> exploded; 1003 Tuples::explode( actual, indexer, back_inserter( exploded ) ); 1004 if ( exploded.empty() ) { 1005 // skip empty tuple arguments by (near-)cloning parent into next gen 1006 results.emplace_back( 1007 results[i], move(env), copy(results[i].need), 1008 copy(results[i].have), move(openVars), j + 1, actual.cost ); 988 env.addActual( expl.env, openVars ); 989 990 // skip empty tuple arguments by (near-)cloning parent into next gen 991 if ( expl.exprs.empty() ) { 992 results.emplace_back( 993 results[i], move(env), copy(results[i].need), 994 copy(results[i].have), move(openVars), nextArg + 1, expl.cost ); 995 1009 996 continue; 1010 997 } 1011 998 1012 // trim first element from exploded1013 std::vector<Alternative> newExpls;1014 newExpls.reserve( exploded.size() - 1 );1015 for ( std::size_t i = 1; i < exploded.size(); ++i ) {1016 newExpls.push_back( move(exploded[i]) );1017 }1018 999 // add new result 1019 1000 results.emplace_back( 1020 i, expl oded.front().expr, move(env), copy(results[i].need),1021 copy(results[i].have), move(openVars), j + 1, 0,1022 actual.cost, move(newExpls));1001 i, expl.exprs.front().get(), move(env), copy(results[i].need), 1002 copy(results[i].have), move(openVars), nextArg + 1, 0, 1003 expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 1023 1004 } 1024 1005 } … … 1030 1011 for ( std::size_t i = genStart; i < results.size(); ++i ) { 1031 1012 ArgPack& result = results[i]; 1032 if ( result.expls.empty() && result.nextArg >= args.size() ) {1013 if ( ! result.hasExpl() && result.nextArg >= args.size() ) { 1033 1014 validateFunctionAlternative( func, result, results, out ); 1034 1015 } … … 1060 1041 printAlts( funcOpFinder.alternatives, std::cerr, 1 ); 1061 1042 ) 1043 1044 // pre-explode arguments 1045 ExplodedArgs argExpansions; 1046 argExpansions.reserve( argAlternatives.size() ); 1047 1048 for ( const AlternativeFinder& arg : argAlternatives ) { 1049 argExpansions.emplace_back(); 1050 auto& argE = argExpansions.back(); 1051 argE.reserve( arg.alternatives.size() ); 1052 1053 for ( const Alternative& actual : arg ) { 1054 argE.emplace_back( actual, indexer ); 1055 } 1056 } 1062 1057 1063 1058 AltList candidates; … … 1074 1069 Alternative newFunc( *func ); 1075 1070 referenceToRvalueConversion( newFunc.expr ); 1076 makeFunctionAlternatives( newFunc, function, arg Alternatives,1071 makeFunctionAlternatives( newFunc, function, argExpansions, 1077 1072 std::back_inserter( candidates ) ); 1078 1073 } … … 1083 1078 Alternative newFunc( *func ); 1084 1079 referenceToRvalueConversion( newFunc.expr ); 1085 makeFunctionAlternatives( newFunc, function, arg Alternatives,1080 makeFunctionAlternatives( newFunc, function, argExpansions, 1086 1081 std::back_inserter( candidates ) ); 1087 1082 } // if … … 1095 1090 // try each function operator ?() with each function alternative 1096 1091 if ( ! funcOpFinder.alternatives.empty() ) { 1097 // add function alternatives to front of argument list 1098 argAlternatives.insert( argAlternatives.begin(), move(funcFinder) ); 1092 // add exploded function alternatives to front of argument list 1093 std::vector<ExplodedActual> funcE; 1094 funcE.reserve( funcFinder.alternatives.size() ); 1095 for ( const Alternative& actual : funcFinder ) { 1096 funcE.emplace_back( actual, indexer ); 1097 } 1098 argExpansions.insert( argExpansions.begin(), move(funcE) ); 1099 1099 1100 1100 for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); … … 1108 1108 Alternative newFunc( *funcOp ); 1109 1109 referenceToRvalueConversion( newFunc.expr ); 1110 makeFunctionAlternatives( newFunc, function, arg Alternatives,1110 makeFunctionAlternatives( newFunc, function, argExpansions, 1111 1111 std::back_inserter( candidates ) ); 1112 1112 } … … 1150 1150 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( winners ) ); 1151 1151 1152 // function may return struct or union value, in which case we need to add alternatives 1153 // for implicitconversions to each of the anonymous members, must happen after findMinCost 1152 // function may return struct or union value, in which case we need to add alternatives 1153 // for implicitconversions to each of the anonymous members, must happen after findMinCost 1154 1154 // since anon conversions are never the cheapest expression 1155 1155 for ( const Alternative & alt : winners ) { … … 1182 1182 for ( Alternative& alt : finder.alternatives ) { 1183 1183 if ( isLvalue( alt.expr ) ) { 1184 alternatives.push_back( 1184 alternatives.push_back( 1185 1185 Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } ); 1186 1186 } // if … … 1231 1231 1232 1232 AltList candidates; 1233 for ( Alternative & alt : finder.alternatives ) {1233 for ( Alternative& alt : finder.alternatives ) { 1234 1234 AssertionSet needAssertions, haveAssertions; 1235 1235 OpenVarSet openVars; … … 1244 1244 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1245 1245 // unification run for side-effects 1246 unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions, 1246 unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions, 1247 1247 haveAssertions, openVars, indexer ); 1248 Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer, 1248 Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer, 1249 1249 alt.env ); 1250 PRINT(1251 std::cerr << "working on cast with result: " << castExpr->result << std::endl;1252 std::cerr << "and expr type: " << alt.expr->result << std::endl;1253 std::cerr << "env: " << alt.env << std::endl;1254 )1255 1250 if ( thisCost != Cost::infinity ) { 1256 PRINT(1257 std::cerr << "has finite cost." << std::endl;1258 )1259 1251 // count one safe conversion for each value that is thrown away 1260 1252 thisCost.incSafe( discardedValues ); 1261 Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env, 1253 Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env, 1262 1254 alt.cost, thisCost ); 1263 inferParameters( needAssertions, haveAssertions, newAlt, openVars, 1255 inferParameters( needAssertions, haveAssertions, newAlt, openVars, 1264 1256 back_inserter( candidates ) ); 1265 1257 } // if … … 1550 1542 void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) { 1551 1543 std::vector< AlternativeFinder > subExprAlternatives; 1552 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 1544 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 1553 1545 back_inserter( subExprAlternatives ) ); 1554 1546 std::vector< AltList > possibilities; 1555 combos( subExprAlternatives.begin(), subExprAlternatives.end(), 1547 combos( subExprAlternatives.begin(), subExprAlternatives.end(), 1556 1548 back_inserter( possibilities ) ); 1557 1549 for ( const AltList& alts : possibilities ) { … … 1561 1553 TypeEnvironment compositeEnv; 1562 1554 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 1563 alternatives.push_back( 1555 alternatives.push_back( 1564 1556 Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } ); 1565 1557 } // for
Note:
See TracChangeset
for help on using the changeset viewer.