Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    rab780e6 r7a780ad  
    284284                const CodeLocation & location,
    285285                const ast::Type * paramType, const ast::Init * init, const ExplodedArgs & args,
    286                 std::vector< ArgPack > & results, std::size_t & genStart, const ast::SymbolTable & symtab,
     286                std::vector< ArgPack > & results, std::size_t & genStart, const ResolveContext & context,
    287287                unsigned nTuples = 0
    288288        ) {
     
    294294                                // ^^^ need to handle the case where a tuple has a default argument
    295295                                if ( ! instantiateArgument( location,
    296                                         type, nullptr, args, results, genStart, symtab, nTuples ) ) return false;
     296                                        type, nullptr, args, results, genStart, context, nTuples ) ) return false;
    297297                                nTuples = 0;
    298298                        }
     
    509509
    510510                                // attempt to unify types
    511                                 if ( unify( paramType, argType, env, need, have, open ) ) {
     511                                ast::ptr<ast::Type> common;
     512                                if ( unify( paramType, argType, env, need, have, open, common ) ) {
    512513                                        // add new result
    513                                         results.emplace_back(
    514                                                 i, expr, std::move( env ), std::move( need ), std::move( have ), std::move( open ),
    515                                                 nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     514                                        assert( common );
     515                                        // auto attrType = common.as<ast::EnumAttrType>();
     516                                        // if ( attrType && ( attrType->attr == ast::EnumAttribute::Value ) ) {
     517                                        //      auto callExpr = new ast::UntypedExpr(
     518                                        //              expr->location, new ast::NameExpr( expr->location, "valueE"), {expr} );
     519                                        //      CandidateFinder finder( context, env );
     520                                        //      finder.find( callExpr );
     521                                        //      CandidateList winners = findMinCost( finder.candidates );
     522                                        //      if (winners.size() != 1) {
     523                                        //              SemanticError( callExpr, "Ambiguous expression in valueE" );
     524                                        //      }
     525                                        //      CandidateRef & choice = winners.front();
     526                                        //      choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
     527
     528                                        //      results.emplace_back(
     529                                        //              i, choice->expr,
     530                                        //              std::move( env ), std::move( need ), std::move( have ), std::move( open ),
     531                                        //              nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     532                                        // } else {
     533                                                results.emplace_back(
     534                                                        i, expr, std::move( env ), std::move( need ), std::move( have ), std::move( open ),
     535                                                        nextArg + 1, nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
     536                                        //}
    516537                                }
    517538                        }
     
    785806                                        auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>();
    786807                                        if ( !instantiateArgument( location,
    787                                                 funcType->params[i], obj->init, args, results, genStart, symtab)) return;
     808                                                funcType->params[i], obj->init, args, results, genStart, context)) return;
    788809                                }
    789810                                goto endMatch;
     
    795816                        // no default args for indirect calls
    796817                        if ( !instantiateArgument( location,
    797                                 param, nullptr, args, results, genStart, symtab ) ) return;
     818                                param, nullptr, args, results, genStart, context ) ) return;
    798819                }
    799820
     
    890911                } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) {
    891912                        addAggMembers( unionInst, aggrExpr, *cand, Cost::unsafe, "" );
    892                 }
    893                 else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
    894                         if (enumInst->base && enumInst->base->base) {
    895             const CodeLocation &location = cand->expr->location;
    896 
    897             CandidateFinder funcFinder(context, tenv);
    898             auto nameExpr = new ast::NameExpr(location, "valueE");
    899             ResolveMode mode = {true, false, selfFinder.candidates.empty()};
    900             funcFinder.find( nameExpr, mode );
    901 
    902             // make variableExpr itself the candidate for the value Call
    903             ExplodedArgs argExpansions;
    904             argExpansions.emplace_back();
    905             auto &argE = argExpansions.back();
    906 
    907             argE.emplace_back(*cand, symtab); // Use the typed name expr as param for value
    908 
    909             CandidateList found;
    910             SemanticErrorException errors;
    911 
    912             for (CandidateRef &func : funcFinder) {
    913                 try {
    914                     const ast::Type *funcResult =
    915                         func->expr->result->stripReferences();
    916                     if (auto pointer = dynamic_cast<const ast::PointerType *>(
    917                             funcResult)) {
    918                         if (auto function =
    919                                 pointer->base.as<ast::FunctionType>()) {
    920                             CandidateRef newFunc{new Candidate{*func}};
    921                             newFunc->expr = referenceToRvalueConversion(
    922                                 newFunc->expr, newFunc->cost);
    923                             makeFunctionCandidates( location,
    924                                                    newFunc, function,
    925                                                    argExpansions, found );
    926                         }
    927                     }
    928                 } catch (SemanticErrorException &e) {
    929                     std::cerr
    930                         << "Resolving value function should cause an error"
    931                         << std::endl;
    932                     errors.append(e);
    933                 }
    934             }
    935 
    936             if (found.empty()) {
    937                 std::cerr << "Resolve value function should always success"
    938                           << std::endl;
    939             }
    940 
    941             for (CandidateRef &withFunc : found) {
    942                 withFunc->cost.incSafe();
    943                 Cost cvtCost =
    944                     computeApplicationConversionCost(withFunc, symtab);
    945                 assert(cvtCost != Cost::infinity);
    946 
    947                 candidates.emplace_back(std::move(withFunc));
    948             }
    949         }
     913                } else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
     914                        if ( enumInst->base->base ) {
     915                                CandidateFinder finder( context, tenv );
     916                                auto location = aggrExpr->location;
     917                                auto callExpr = new ast::UntypedExpr(
     918                                        location, new ast::NameExpr( location, "valueE" ), {aggrExpr}
     919                                );
     920                                finder.find( callExpr );
     921                                CandidateList winners = findMinCost( finder.candidates );
     922                                if (winners.size() != 1) {
     923                                        SemanticError( callExpr, "Ambiguous expression in valueE" );
     924                                }
     925                                CandidateRef & choice = winners.front();
     926                                // choice->cost.incSafe();
     927                                candidates.emplace_back( std::move(choice) );
     928                        }
     929
    950930                }
    951931        }
     
    14141394                        ast::Expr * newExpr = data.combine( nameExpr->location, cost );
    14151395
     1396                        bool bentConversion = false;
     1397                        if ( auto inst = newExpr->result.as<ast::EnumInstType>() ) {
     1398                                if ( inst->base && inst->base->base ) {
     1399                                        bentConversion = true;
     1400                                }
     1401                        }
     1402
    14161403                        CandidateRef newCand = std::make_shared<Candidate>(
    1417                                 newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero,
     1404                                newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, bentConversion? Cost::safe: Cost::zero,
    14181405                                cost );
    14191406
     
    14481435        auto cand = new Candidate(variableExpr, tenv);
    14491436        candidates.emplace_back(cand);
    1450 
    1451         if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(
    1452                 variableExpr->var->get_type())) {
    1453             if (enumInst->base && enumInst->base->base) {
    1454                 const CodeLocation &location = cand->expr->location;
    1455 
    1456                 CandidateFinder funcFinder(context, tenv);
    1457                 auto nameExpr = new ast::NameExpr(location, "valueE");
    1458                 ResolveMode mode = {true, false, selfFinder.candidates.empty()};
    1459                 funcFinder.find( nameExpr, mode );
    1460 
    1461                 // make variableExpr itself the candidate for the value Call
    1462                 ExplodedArgs argExpansions;
    1463                 argExpansions.emplace_back();
    1464                 auto &argE = argExpansions.back();
    1465 
    1466                 argE.emplace_back(*cand, symtab);
    1467 
    1468                 CandidateList found;
    1469                 SemanticErrorException errors;
    1470 
    1471                 for (CandidateRef &func : funcFinder) {
    1472                     try {
    1473                     const ast::Type *funcResult =
    1474                         func->expr->result->stripReferences();
    1475                     if (auto pointer = dynamic_cast<const ast::PointerType *>(
    1476                             funcResult)) {
    1477                         if (auto function =
    1478                                 pointer->base.as<ast::FunctionType>()) {
    1479                             CandidateRef newFunc{new Candidate{*func}};
    1480                             newFunc->expr = referenceToRvalueConversion(
    1481                                 newFunc->expr, newFunc->cost);
    1482                             makeFunctionCandidates(variableExpr->location,
    1483                                                    newFunc, function,
    1484                                                    argExpansions, found);
    1485                         }
    1486                     }
    1487                     } catch (SemanticErrorException &e) {
    1488                         std::cerr
    1489                             << "Resolving value function should cause an error"
    1490                             << std::endl;
    1491                         errors.append(e);
    1492                     }
    1493                 }
    1494 
    1495                 if (found.empty()) {
    1496                     std::cerr << "Resolve value function should always success"
    1497                             << std::endl;
    1498                 }
    1499 
    1500                 for (CandidateRef &withFunc : found) {
    1501                     withFunc->cost.incSafe();
    1502                     Cost cvtCost =
    1503                         computeApplicationConversionCost(withFunc, symtab);
    1504                     assert(cvtCost != Cost::infinity);
    1505 
    1506                     candidates.emplace_back(std::move(withFunc));
    1507                 }
    1508             }
    1509         }
    15101437    }
    15111438
     
    18391766
    18401767                                // unification run for side-effects
    1841                                 bool canUnify = unify( toType, cand->expr->result, env, need, have, open );
     1768                                ast::ptr<ast::Type> common;
     1769                                bool canUnify = unify( toType, cand->expr->result, env, need, have, open, common );
    18421770                                (void) canUnify;
    18431771                                Cost thisCost = computeConversionCost( cand->expr->result, toType, cand->expr->get_lvalue(),
     
    18641792                                        // ambiguous case, still output candidates to print in error message
    18651793                                        if ( cand->cost == minExprCost && thisCost == minCastCost ) {
    1866                                                 CandidateRef newCand = std::make_shared<Candidate>(
    1867                                                         new ast::InitExpr{
    1868                                                                 initExpr->location,
    1869                                                                 restructureCast( cand->expr, toType ),
    1870                                                                 initAlt.designation },
    1871                                                         std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
    1872                                                 // currently assertions are always resolved immediately so this should have no effect.
    1873                                                 // if this somehow changes in the future (e.g. delayed by indeterminate return type)
    1874                                                 // we may need to revisit the logic.
    1875                                                 inferParameters( newCand, matches );
     1794                                                auto commonAsEnumAttr = common.as<ast::EnumAttrType>();
     1795                                                if ( commonAsEnumAttr && commonAsEnumAttr->attr == ast::EnumAttribute::Value ) {
     1796                                                        auto callExpr = new ast::UntypedExpr(
     1797                                                                cand->expr->location, new ast::NameExpr( cand->expr->location, "valueE"), {cand->expr} );
     1798                                                        CandidateFinder finder( context, env );
     1799                                                        finder.find( callExpr );
     1800                                                        CandidateList winners = findMinCost( finder.candidates );
     1801                                                        if (winners.size() != 1) {
     1802                                                                SemanticError( callExpr, "Ambiguous expression in valueE" );
     1803                                                        }
     1804                                                        CandidateRef & choice = winners.front();
     1805                                                        // assert( valueCall->result );
     1806                                                        CandidateRef newCand = std::make_shared<Candidate>(
     1807                                                                new ast::InitExpr{
     1808                                                                        initExpr->location,
     1809                                                                        // restructureCast( cand->expr, toType ),
     1810                                                                        choice->expr,
     1811                                                                        initAlt.designation },
     1812                                                                std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
     1813                                                                inferParameters( newCand, matches );
     1814                                                } else {
     1815                                                        CandidateRef newCand = std::make_shared<Candidate>(
     1816                                                                new ast::InitExpr{
     1817                                                                        initExpr->location,
     1818                                                                        restructureCast( cand->expr, toType ),
     1819                                                                        initAlt.designation },
     1820                                                                std::move(env), std::move( open ), std::move( need ), cand->cost + thisCost );
     1821                                                        // currently assertions are always resolved immediately so this should have no effect.
     1822                                                        // if this somehow changes in the future (e.g. delayed by indeterminate return type)
     1823                                                        // we may need to revisit the logic.
     1824                                                        inferParameters( newCand, matches );
     1825                                                }
    18761826                                        }
    18771827                                }
     
    19001850                                                std::make_shared<Candidate>(
    19011851                                                        newExpr, copy( tenv ), ast::OpenVarSet{},
    1902                                                         ast::AssertionSet{}, Cost::zero, cost
     1852                                                        ast::AssertionSet{}, Cost::safe, cost
    19031853                                                );
    19041854
     
    22002150}
    22012151
     2152const ast::Expr * getValueEnumCall( const ast::Expr * expr,
     2153                const ResolveContext & context, const ast::TypeEnvironment & env ) {
     2154        auto callExpr = new ast::UntypedExpr(
     2155                expr->location, new ast::NameExpr( expr->location, "valueE"), {expr} );
     2156        CandidateFinder finder( context, env );
     2157        finder.find( callExpr );
     2158        CandidateList winners = findMinCost( finder.candidates );
     2159        if (winners.size() != 1) {
     2160                SemanticError( callExpr, "Ambiguous expression in valueE" );
     2161        }
     2162        CandidateRef & choice = winners.front();
     2163        return choice->expr;
     2164}
     2165
    22022166const ast::Expr * createCondExpr( const ast::Expr * expr ) {
    22032167        assert( expr );
     
    22122176                        }
    22132177                ),
    2214                 new ast::BasicType( ast::BasicType::SignedInt )
     2178                new ast::BasicType( ast::BasicKind::SignedInt )
    22152179        );
    22162180}
Note: See TracChangeset for help on using the changeset viewer.