Changeset 24d6572 for src/ResolvExpr/Unify.cc
- Timestamp:
- Jun 12, 2023, 2:45:32 PM (13 months ago)
- Branches:
- ast-experimental, master
- Children:
- 62d62db
- Parents:
- 34b4268 (diff), 251ce80 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r34b4268 r24d6572 33 33 #include "AST/TypeEnvironment.hpp" 34 34 #include "Common/PassVisitor.h" // for PassVisitor 35 #include "CommonType.hpp" // for commonType 35 36 #include "FindOpenVars.h" // for findOpenVars 37 #include "SpecCost.hpp" // for SpecCost 36 38 #include "SynTree/LinkageSpec.h" // for C 37 39 #include "SynTree/Constant.h" // for Constant … … 43 45 #include "Tuples/Tuples.h" // for isTtype 44 46 #include "TypeEnvironment.h" // for EqvClass, AssertionSet, OpenVarSet 45 #include "typeops.h" // for flatten, occurs , commonType47 #include "typeops.h" // for flatten, occurs 46 48 47 49 namespace ast { … … 50 52 51 53 namespace SymTab { 52 class Indexer;54 class Indexer; 53 55 } // namespace SymTab 54 56 … … 56 58 57 59 namespace ResolvExpr { 60 61 // Template Helpers: 62 template< typename Iterator1, typename Iterator2 > 63 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) { 64 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 65 Type *commonType = 0; 66 if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 67 return false; 68 } // if 69 commonTypes.push_back( commonType ); 70 } // for 71 return ( list1Begin == list1End && list2Begin == list2End ); 72 } 73 74 template< typename Iterator1, typename Iterator2 > 75 bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 76 std::list< Type* > commonTypes; 77 if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) { 78 deleteAll( commonTypes ); 79 return true; 80 } else { 81 return false; 82 } // if 83 } 58 84 59 85 struct Unify_old : public WithShortCircuiting { … … 102 128 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 103 129 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 104 WidenMode widen , const ast::SymbolTable & symtab);130 WidenMode widen ); 105 131 106 132 bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) { … … 124 150 125 151 bool typesCompatible( 126 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,152 const ast::Type * first, const ast::Type * second, 127 153 const ast::TypeEnvironment & env ) { 128 154 ast::TypeEnvironment newEnv; … … 137 163 findOpenVars( newSecond, open, closed, need, have, newEnv, FirstOpen ); 138 164 139 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden() , symtab);165 return unifyExact(newFirst, newSecond, newEnv, need, have, open, noWiden() ); 140 166 } 141 167 … … 157 183 158 184 bool typesCompatibleIgnoreQualifiers( 159 const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,185 const ast::Type * first, const ast::Type * second, 160 186 const ast::TypeEnvironment & env ) { 161 187 ast::TypeEnvironment newEnv; … … 190 216 subFirst, 191 217 subSecond, 192 newEnv, need, have, open, noWiden() , symtab);218 newEnv, need, have, open, noWiden() ); 193 219 } 194 220 … … 760 786 const ast::OpenVarSet & open; 761 787 WidenMode widen; 762 const ast::SymbolTable & symtab;763 788 public: 764 789 static size_t traceId; … … 767 792 Unify_new( 768 793 const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 769 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 770 const ast::SymbolTable & symtab ) 794 ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen ) 771 795 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 772 symtab(symtab),result(false) {}796 result(false) {} 773 797 774 798 void previsit( const ast::Node * ) { visit_children = false; } … … 788 812 result = unifyExact( 789 813 pointer->base, pointer2->base, tenv, need, have, open, 790 noWiden() , symtab);814 noWiden()); 791 815 } 792 816 } … … 811 835 812 836 result = unifyExact( 813 array->base, array2->base, tenv, need, have, open, noWiden(), 814 symtab ); 837 array->base, array2->base, tenv, need, have, open, noWiden()); 815 838 } 816 839 … … 818 841 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 819 842 result = unifyExact( 820 ref->base, ref2->base, tenv, need, have, open, noWiden(), 821 symtab ); 843 ref->base, ref2->base, tenv, need, have, open, noWiden()); 822 844 } 823 845 } … … 828 850 static bool unifyTypeList( 829 851 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 830 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 831 const ast::SymbolTable & symtab 852 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open 832 853 ) { 833 854 while ( crnt1 != end1 && crnt2 != end2 ) { … … 842 863 return unifyExact( 843 864 t1, tupleFromTypes( crnt2, end2 ), env, need, have, open, 844 noWiden() , symtab);865 noWiden() ); 845 866 } else if ( ! isTuple1 && isTuple2 ) { 846 867 // combine remainder of list1, then unify 847 868 return unifyExact( 848 869 tupleFromTypes( crnt1, end1 ), t2, env, need, have, open, 849 noWiden() , symtab);870 noWiden() ); 850 871 } 851 872 852 873 if ( ! unifyExact( 853 t1, t2, env, need, have, open, noWiden() , symtab)874 t1, t2, env, need, have, open, noWiden() ) 854 875 ) return false; 855 876 … … 865 886 return unifyExact( 866 887 t1, tupleFromTypes( crnt2, end2 ), env, need, have, open, 867 noWiden() , symtab);888 noWiden() ); 868 889 } else if ( crnt2 != end2 ) { 869 890 // try unifying empty tuple with ttype … … 872 893 return unifyExact( 873 894 tupleFromTypes( crnt1, end1 ), t2, env, need, have, open, 874 noWiden() , symtab);895 noWiden() ); 875 896 } 876 897 … … 882 903 const std::vector< ast::ptr< ast::Type > > & list2, 883 904 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 884 const ast::OpenVarSet & open , const ast::SymbolTable & symtab905 const ast::OpenVarSet & open 885 906 ) { 886 907 return unifyTypeList( 887 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 888 symtab ); 908 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open); 889 909 } 890 910 … … 927 947 ) return; 928 948 929 if ( ! unifyTypeList( params, params2, tenv, need, have, open , symtab) ) return;949 if ( ! unifyTypeList( params, params2, tenv, need, have, open ) ) return; 930 950 if ( ! unifyTypeList( 931 func->returns, func2->returns, tenv, need, have, open , symtab) ) return;951 func->returns, func2->returns, tenv, need, have, open ) ) return; 932 952 933 953 markAssertions( have, need, func ); … … 944 964 // check that the other type is compatible and named the same 945 965 auto otherInst = dynamic_cast< const XInstType * >( other ); 946 if (otherInst && inst->name == otherInst->name) this->result = otherInst; 966 if (otherInst && inst->name == otherInst->name) 967 this->result = otherInst; 947 968 return otherInst; 948 969 } … … 1000 1021 1001 1022 if ( ! unifyExact( 1002 pty, pty2, tenv, need, have, open, noWiden() , symtab) ) {1023 pty, pty2, tenv, need, have, open, noWiden() ) ) { 1003 1024 result = false; 1004 1025 return; … … 1030 1051 void postvisit( const ast::TypeInstType * typeInst ) { 1031 1052 // assert( open.find( *typeInst ) == open.end() ); 1032 handleRefType( typeInst, type2 ); 1053 auto otherInst = dynamic_cast< const ast::TypeInstType * >( type2 ); 1054 if (otherInst && typeInst->name == otherInst->name) 1055 this->result = otherInst; 1056 // return otherInst; 1033 1057 } 1034 1058 … … 1039 1063 const std::vector< ast::ptr< ast::Type > > & list1, 1040 1064 const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 1041 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1042 const ast::SymbolTable & symtab 1065 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open 1043 1066 ) { 1044 1067 auto crnt1 = list1.begin(); … … 1055 1078 return unifyExact( 1056 1079 t1, tupleFromTypes( list2 ), env, need, have, open, 1057 noWiden() , symtab);1080 noWiden() ); 1058 1081 } else if ( ! isTuple1 && isTuple2 ) { 1059 1082 // combine entirety of list1, then unify 1060 1083 return unifyExact( 1061 1084 tupleFromTypes( list1 ), t2, env, need, have, open, 1062 noWiden() , symtab);1085 noWiden() ); 1063 1086 } 1064 1087 1065 1088 if ( ! unifyExact( 1066 t1, t2, env, need, have, open, noWiden() , symtab)1089 t1, t2, env, need, have, open, noWiden() ) 1067 1090 ) return false; 1068 1091 … … 1078 1101 return unifyExact( 1079 1102 t1, tupleFromTypes( list2 ), env, need, have, open, 1080 noWiden() , symtab);1103 noWiden() ); 1081 1104 } else if ( crnt2 != list2.end() ) { 1082 1105 // try unifying empty tuple with ttype … … 1087 1110 return unifyExact( 1088 1111 tupleFromTypes( list1 ), t2, env, need, have, open, 1089 noWiden() , symtab);1112 noWiden() ); 1090 1113 } 1091 1114 … … 1106 1129 auto types2 = flatten( flat2 ); 1107 1130 1108 result = unifyList( types, types2, tenv, need, have, open , symtab);1131 result = unifyList( types, types2, tenv, need, have, open ); 1109 1132 } 1110 1133 … … 1130 1153 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1131 1154 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1132 ast::OpenVarSet & open , const ast::SymbolTable & symtab1155 ast::OpenVarSet & open 1133 1156 ) { 1134 1157 ast::ptr<ast::Type> common; 1135 return unify( type1, type2, env, need, have, open, symtab,common );1158 return unify( type1, type2, env, need, have, open, common ); 1136 1159 } 1137 1160 … … 1139 1162 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1140 1163 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1141 ast::OpenVarSet & open, const ast::SymbolTable & symtab,ast::ptr<ast::Type> & common1164 ast::OpenVarSet & open, ast::ptr<ast::Type> & common 1142 1165 ) { 1143 1166 ast::OpenVarSet closed; … … 1145 1168 findOpenVars( type2, open, closed, need, have, env, FirstOpen ); 1146 1169 return unifyInexact( 1147 type1, type2, env, need, have, open, WidenMode{ true, true }, symtab,common );1170 type1, type2, env, need, have, open, WidenMode{ true, true }, common ); 1148 1171 } 1149 1172 … … 1151 1174 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 1152 1175 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 1153 WidenMode widen , const ast::SymbolTable & symtab1176 WidenMode widen 1154 1177 ) { 1155 1178 if ( type1->qualifiers != type2->qualifiers ) return false; … … 1170 1193 return env.bindVarToVar( 1171 1194 var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have, 1172 open, widen , symtab);1195 open, widen ); 1173 1196 } else if ( isopen1 ) { 1174 return env.bindVar( var1, type2, entry1->second, need, have, open, widen , symtab);1197 return env.bindVar( var1, type2, entry1->second, need, have, open, widen ); 1175 1198 } else if ( isopen2 ) { 1176 1199 return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab ); … … 1180 1203 return env.bindVarToVar( 1181 1204 var1, var2, ast::TypeData{ var1->base->kind, var1->base->sized||var2->base->sized }, need, have, 1182 open, widen , symtab);1205 open, widen ); 1183 1206 } else if ( isopen1 ) { 1184 return env.bindVar( var1, type2, ast::TypeData{var1->base}, need, have, open, widen , symtab);1207 return env.bindVar( var1, type2, ast::TypeData{var1->base}, need, have, open, widen ); 1185 1208 } else if ( isopen2 ) { 1186 return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen , symtab);1209 return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen ); 1187 1210 }else { 1188 1211 return ast::Pass<Unify_new>::read( 1189 type1, type2, env, need, have, open, widen , symtab);1212 type1, type2, env, need, have, open, widen ); 1190 1213 } 1191 1214 … … 1195 1218 const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 1196 1219 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 1197 const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,1220 const ast::OpenVarSet & open, WidenMode widen, 1198 1221 ast::ptr<ast::Type> & common 1199 1222 ) { … … 1209 1232 ast::ptr< ast::Type > t2_(t2); 1210 1233 1211 if ( unifyExact( t1, t2, env, need, have, open, widen , symtab) ) {1234 if ( unifyExact( t1, t2, env, need, have, open, widen ) ) { 1212 1235 // if exact unification on unqualified types, try to merge qualifiers 1213 1236 if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) { … … 1219 1242 } 1220 1243 1221 } else if (( common = commonType( t1, t2, env, need, have, open, widen , symtab))) {1244 } else if (( common = commonType( t1, t2, env, need, have, open, widen ))) { 1222 1245 // no exact unification, but common type 1223 1246 auto c = shallowCopy(common.get());
Note: See TracChangeset
for help on using the changeset viewer.