Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    r7a780ad rab780e6  
    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 ResolveContext & context,
     286                std::vector< ArgPack > & results, std::size_t & genStart, const ast::SymbolTable & symtab,
    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, context, nTuples ) ) return false;
     296                                        type, nullptr, args, results, genStart, symtab, nTuples ) ) return false;
    297297                                nTuples = 0;
    298298                        }
     
    509509
    510510                                // attempt to unify types
    511                                 ast::ptr<ast::Type> common;
    512                                 if ( unify( paramType, argType, env, need, have, open, common ) ) {
     511                                if ( unify( paramType, argType, env, need, have, open ) ) {
    513512                                        // add new result
    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                                         //}
     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 );
    537516                                }
    538517                        }
     
    806785                                        auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>();
    807786                                        if ( !instantiateArgument( location,
    808                                                 funcType->params[i], obj->init, args, results, genStart, context)) return;
     787                                                funcType->params[i], obj->init, args, results, genStart, symtab)) return;
    809788                                }
    810789                                goto endMatch;
     
    816795                        // no default args for indirect calls
    817796                        if ( !instantiateArgument( location,
    818                                 param, nullptr, args, results, genStart, context ) ) return;
     797                                param, nullptr, args, results, genStart, symtab ) ) return;
    819798                }
    820799
     
    911890                } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) {
    912891                        addAggMembers( unionInst, aggrExpr, *cand, Cost::unsafe, "" );
    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 
     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        }
    930950                }
    931951        }
     
    13941414                        ast::Expr * newExpr = data.combine( nameExpr->location, cost );
    13951415
    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 
    14031416                        CandidateRef newCand = std::make_shared<Candidate>(
    1404                                 newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, bentConversion? Cost::safe: Cost::zero,
     1417                                newExpr, copy( tenv ), ast::OpenVarSet{}, ast::AssertionSet{}, Cost::zero,
    14051418                                cost );
    14061419
     
    14351448        auto cand = new Candidate(variableExpr, tenv);
    14361449        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        }
    14371510    }
    14381511
     
    17661839
    17671840                                // unification run for side-effects
    1768                                 ast::ptr<ast::Type> common;
    1769                                 bool canUnify = unify( toType, cand->expr->result, env, need, have, open, common );
     1841                                bool canUnify = unify( toType, cand->expr->result, env, need, have, open );
    17701842                                (void) canUnify;
    17711843                                Cost thisCost = computeConversionCost( cand->expr->result, toType, cand->expr->get_lvalue(),
     
    17921864                                        // ambiguous case, still output candidates to print in error message
    17931865                                        if ( cand->cost == minExprCost && thisCost == minCastCost ) {
    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                                                 }
     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 );
    18261876                                        }
    18271877                                }
     
    18501900                                                std::make_shared<Candidate>(
    18511901                                                        newExpr, copy( tenv ), ast::OpenVarSet{},
    1852                                                         ast::AssertionSet{}, Cost::safe, cost
     1902                                                        ast::AssertionSet{}, Cost::zero, cost
    18531903                                                );
    18541904
     
    21502200}
    21512201
    2152 const 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 
    21662202const ast::Expr * createCondExpr( const ast::Expr * expr ) {
    21672203        assert( expr );
     
    21762212                        }
    21772213                ),
    2178                 new ast::BasicType( ast::BasicKind::SignedInt )
     2214                new ast::BasicType( ast::BasicType::SignedInt )
    21792215        );
    21802216}
Note: See TracChangeset for help on using the changeset viewer.