Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CandidateFinder.cpp

    rd57e349 r396037d  
    1717
    1818#include <sstream>
    19 #include <string>
    20 #include <unordered_map>
    2119
    2220#include "Candidate.hpp"
    2321#include "CompilationState.h"
    24 #include "Cost.h"
    25 #include "Resolver.h"
    2622#include "SatisfyAssertions.hpp"
    27 #include "typeops.h"              // for adjustExprType
    2823#include "AST/Expr.hpp"
    2924#include "AST/Node.hpp"
    3025#include "AST/Pass.hpp"
    31 #include "AST/Print.hpp"
    32 #include "SymTab/Mangler.h"
    3326
    3427#define PRINT( text ) if ( resolvep ) { text }
     
    5649        /// return type. Skips ambiguous candidates.
    5750        CandidateList pruneCandidates( CandidateList & candidates ) {
    58                 struct PruneStruct {
    59                         CandidateRef candidate;
    60                         bool ambiguous;
    61 
    62                         PruneStruct() = default;
    63                         PruneStruct( const CandidateRef & c ) : candidate( c ), ambiguous( false ) {}
    64                 };
    65 
    66                 // find lowest-cost candidate for each type
    67                 std::unordered_map< std::string, PruneStruct > selected;
    68                 for ( CandidateRef & candidate : candidates ) {
    69                         std::string mangleName;
    70                         {
    71                                 ast::ptr< ast::Type > newType = candidate->expr->result;
    72                                 candidate->env.apply( newType );
    73                                 mangleName = Mangle::mangle( newType );
    74                         }
    75 
    76                         auto found = selected.find( mangleName );
    77                         if ( found != selected.end() ) {
    78                                 if ( candidate->cost < found->second.candidate->cost ) {
    79                                         PRINT(
    80                                                 std::cerr << "cost " << candidate->cost << " beats "
    81                                                         << found->second.candidate->cost << std::endl;
    82                                         )
    83 
    84                                         found->second = PruneStruct{ candidate };
    85                                 } else if ( candidate->cost == found->second.candidate->cost ) {
    86                                         // if one of the candidates contains a deleted identifier, can pick the other,
    87                                         // since deleted expressions should not be ambiguous if there is another option
    88                                         // that is at least as good
    89                                         if ( findDeletedExpr( candidate->expr ) ) {
    90                                                 // do nothing
    91                                                 PRINT( std::cerr << "candidate is deleted" << std::endl; )
    92                                         } else if ( findDeletedExpr( found->second.candidate->expr ) ) {
    93                                                 PRINT( std::cerr << "current is deleted" << std::endl; )
    94                                                 found->second = PruneStruct{ candidate };
    95                                         } else {
    96                                                 PRINT( std::cerr << "marking ambiguous" << std::endl; )
    97                                                 found->second.ambiguous = true;
    98                                         }
    99                                 } else {
    100                                         PRINT(
    101                                                 std::cerr << "cost " << candidate->cost << " loses to "
    102                                                         << found->second.candidate->cost << std::endl;
    103                                         )
    104                                 }
    105                         } else {
    106                                 selected.emplace_hint( found, mangleName, candidate );
    107                         }
    108                 }
    109 
    110                 // report unambiguous min-cost candidates
    111                 CandidateList out;
    112                 for ( auto & target : selected ) {
    113                         if ( target.second.ambiguous ) continue;
    114 
    115                         CandidateRef cand = target.second.candidate;
    116                        
    117                         ast::ptr< ast::Type > newResult = cand->expr->result;
    118                         cand->env.applyFree( newResult );
    119                         cand->expr = ast::mutate_field(
    120                                 cand->expr.get(), &ast::Expr::result, std::move( newResult ) );
    121                        
    122                         out.emplace_back( cand );
    123                 }
    124                 return out;
    125         }
    126 
    127         /// Returns a list of alternatives with the minimum cost in the given list
    128         CandidateList findMinCost( const CandidateList & candidates ) {
    129                 CandidateList out;
    130                 Cost minCost = Cost::infinity;
    131                 for ( const CandidateRef & r : candidates ) {
    132                         if ( r->cost < minCost ) {
    133                                 minCost = r->cost;
    134                                 out.clear();
    135                                 out.emplace_back( r );
    136                         } else if ( r->cost == minCost ) {
    137                                 out.emplace_back( r );
    138                         }
    139                 }
    140                 return out;
     51                #warning unimplemented
     52                (void)candidates;
     53                assert(false);
     54                return {};
    14155        }
    14256
     
    17791        if ( mode.prune ) {
    17892                // trim candidates to single best one
     93                auto oldsize = candidates.size();
    17994                PRINT(
    18095                        std::cerr << "alternatives before prune:" << std::endl;
     
    18398
    18499                CandidateList pruned = pruneCandidates( candidates );
    185                
    186100                if ( mode.failFast && pruned.empty() ) {
    187101                        std::ostringstream stream;
    188                         CandidateList winners = findMinCost( candidates );
    189                         stream << "Cannot choose between " << winners.size() << " alternatives for "
    190                                 "expression\n";
    191                         ast::print( stream, expr );
    192                         stream << " Alternatives are:\n";
    193                         print( stream, winners, 1 );
    194                         SemanticError( expr->location, stream.str() );
    195                 }
    196 
    197                 auto oldsize = candidates.size();
    198                 candidates = std::move( pruned );
    199 
    200                 PRINT(
    201                         std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl;
    202                 )
    203                 PRINT(
    204                         std::cerr << "there are " << candidates.size() << " alternatives after elimination"
    205                                 << std::endl;
    206                 )
    207         }
    208 
    209         // adjust types after pruning so that types substituted by pruneAlternatives are correctly
    210         // adjusted
    211         if ( mode.adjust ) {
    212                 for ( CandidateRef & r : candidates ) {
    213                         r->expr = ast::mutate_field(
    214                                 r->expr.get(), &ast::Expr::result,
    215                                 adjustExprType( r->expr->result, r->env, symtab ) );
     102                        CandidateList winners;
     103                       
     104                        #warning unimplemented
     105                        assert(false);
    216106                }
    217107        }
    218108
    219         // Central location to handle gcc extension keyword, etc. for all expressions
    220         for ( CandidateRef & r : candidates ) {
    221                 if ( r->expr->extension != expr->extension ) {
    222                         r->expr.get_and_mutate()->extension = expr->extension;
    223                 }
    224         }
     109        #warning unimplemented
     110        assert(false);
    225111}
    226112
Note: See TracChangeset for help on using the changeset viewer.