Changeset 7ed7b4a
- Timestamp:
- Nov 3, 2022, 4:11:16 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- a805100
- Parents:
- f6aa89c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rf6aa89c r7ed7b4a 99 99 void passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 100 100 /// wraps a function application with a new temporary for the out-parameter return value 101 Expression *addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg);101 Expression *addRetParam( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, Type *retType ); 102 102 /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value 103 Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType, std::list< Expression *>::iterator &arg ); 104 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 105 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars ); 106 void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 107 void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ); 103 Expression *addDynRetParam( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, Type *polyType ); 104 /// Converts a function call into a call of the adapter with the 105 /// original function as the first argument (all other arguments 106 /// are pushed back). May adjust return value. 107 Expression *applyAdapter( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ); 108 /// Modifies the `arg`, replacing it with a boxed expression 109 /// that matches `formal` under the current TyVarMap. 110 void boxParam( Expression *&arg, Type *formal, const TyVarMap &exprTyVars ); 111 /// Box an argument of `appExpr` for each parameter in `function` 112 /// starting at `arg`. 113 /// `exprTyVars` is the function's type variables. 114 void boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ); 115 /// Boxes each assertion and inserts them into `appExpr` at 116 /// `arg`. `exprTyVars` is the function's type variables. 117 void addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ); 108 118 /// Stores assignment operators from assertion list in local map of assignment operations 109 119 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 120 /// Creates an adapter definition from `adaptee` to `realType`, using 121 /// `mangleName` as the base name for the adapter. `tyVars` is the map of 122 /// type variables for the function type of the adapted expression. 110 123 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 111 124 /// Replaces intrinsic operator functions with their arithmetic desugaring … … 590 603 } 591 604 592 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg) {605 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, Type *retType ) { 593 606 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 594 607 // using a comma expression. … … 630 643 // See forward definition. 631 644 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone ) { 645 assert( env ); 632 646 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 633 647 Type *concrete = env->lookup( typeInst->get_name() ); … … 652 666 } 653 667 654 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) { 655 assert( env ); 668 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, Type *dynType ) { 656 669 Type *concrete = replaceWithConcrete( dynType, env ); 657 670 // add out-parameter for return value 658 return addRetParam( appExpr, concrete, arg);659 } 660 661 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {671 return addRetParam( appExpr, arg, concrete ); 672 } 673 674 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &tyVars ) { 662 675 Expression *ret = appExpr; 663 676 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 664 677 if ( isDynRet( function, tyVars ) ) { 665 ret = addRetParam( appExpr, function->returnVals.front()->get_type(), arg);678 ret = addRetParam( appExpr, arg, function->returnVals.front()->get_type() ); 666 679 } // if 667 680 std::string mangleName = mangleAdapterName( function, tyVars ); … … 709 722 } 710 723 711 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {724 void Pass1::boxParam( Expression *&arg, Type *param, const TyVarMap &exprTyVars ) { 712 725 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 713 726 addCast( arg, param, exprTyVars ); … … 722 735 // } 723 736 // } 724 arg = 737 arg = generalizedLvalue( new AddressExpr( arg ) ); 725 738 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 726 739 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. … … 731 744 Type * newType = param->clone(); 732 745 if ( env ) env->apply( newType ); 733 ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr ); 734 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 735 stmtsToAddBefore.push_back( new DeclStmt( newObj ) ); 736 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 746 ObjectDecl *newObj = makeTemporary( newType ); 747 // TODO: is this right??? (Why wouldn't it be?) 748 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); 749 // TODO: why doesn't this just use initialization syntax? 750 // (Possibly to ensure code is run at the right time.) 751 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 737 752 assign->get_args().push_back( new VariableExpr( newObj ) ); 738 753 assign->get_args().push_back( arg ); … … 742 757 } 743 758 744 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {759 void Pass1::boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ) { 745 760 for ( DeclarationWithType * param : function->parameters ) { 746 761 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() ); 747 boxParam( param->get_type(), *arg, exprTyVars );762 boxParam( *arg, param->get_type(), exprTyVars ); 748 763 ++arg; 749 764 } // for 750 765 } 751 766 752 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {767 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) { 753 768 std::list< Expression *>::iterator cur = arg; 754 769 for ( TypeDecl * const tyVar : functionType->forall ) { … … 757 772 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( assert ).c_str(), toString( appExpr ).c_str() ); 758 773 Expression *newExpr = inferParam->second.expr->clone(); 759 boxParam( assert->get_type(), newExpr, tyVars );774 boxParam( newExpr, assert->get_type(), tyVars ); 760 775 appExpr->get_args().insert( cur, newExpr ); 761 776 } // for … … 1104 1119 // std::cerr << "dynRetType: " << dynRetType << std::endl; 1105 1120 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result(); 1106 ret = addDynRetParam( appExpr, concRetType, arg); // xxx - used to use dynRetType instead of concRetType1121 ret = addDynRetParam( appExpr, arg, concRetType ); // xxx - used to use dynRetType instead of concRetType 1107 1122 } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...? 1108 1123 // xxx - the ! needsAdapter check may be incorrect. It seems there is some situation where an adapter is applied where it shouldn't be, and this fixes it for some cases. More investigation is needed. … … 1112 1127 // std::cerr << *env << std::endl; 1113 1128 // change the application so it calls the adapter rather than the passed function 1114 ret = applyAdapter( appExpr, function, arg, scopeTyVars );1129 ret = applyAdapter( appExpr, arg, function, scopeTyVars ); 1115 1130 } // if 1116 1131 arg = appExpr->get_args().begin(); … … 1118 1133 Type *concRetType = replaceWithConcrete( dynRetType, env ); 1119 1134 passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's) 1120 addInferredParams( appExpr, function, arg, exprTyVars );1135 addInferredParams( appExpr, arg, function, exprTyVars ); 1121 1136 1122 1137 arg = paramBegin; 1123 1138 1124 boxParams( appExpr, function, arg, exprTyVars );1139 boxParams( appExpr, arg, function, exprTyVars ); 1125 1140 passAdapters( appExpr, function, exprTyVars ); 1126 1141
Note: See TracChangeset
for help on using the changeset viewer.