Changes in / [4432b52:1f9a4d0]


Ignore:
Files:
1 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/andrew_beach_MMath/Makefile

    r4432b52 r1f9a4d0  
    3131        ${GLOSSARY} ${BUILD}/${BASE}
    3232        ${LATEX} ${BASE}
     33        ${LATEX} ${BASE}
    3334
    3435${DOC}: ${BUILD}/${DOC}
  • doc/theses/andrew_beach_MMath/cfalab.sty

    r4432b52 r1f9a4d0  
    2727% Cforall with the forall symbol.
    2828\newsymbolcmd\CFA{\textsf{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}}
    29 % C++ with kerning. (No standard number support.)
    30 \newsymbolcmd\CPP{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}}
    31 
    32 % This is executed very early in the \begin{document} code.
    33 \AtEndPreamble{
    34   \@ifpackageloaded{hyperref}{
    35     % Convert symbols to pdf compatable forms when required.
    36     \pdfstringdefDisableCommands{
    37       \def\CFA{CFA}
    38       \def\CPP{C++}
    39     }
    40   }{}
    41 }
    4229
    4330% The CFA listings language. Based off of ANCI C and including GCC extensions.
     
    8572    \renewcommand\textunderscore{\csuse{cfalab@textunderscore@#1}}}
    8673
     74% This is executed very early in the \begin{document} code.
     75\AtEndPreamble{
     76  \@ifpackageloaded{hyperref}{
     77    % Convert symbols to pdf compatable forms when required.
     78    \pdfstringdefDisableCommands{
     79      \def\CFA{CFA}
     80    }
     81  }{}
     82}
     83
    8784\endinput
  • doc/theses/andrew_beach_MMath/thesis.tex

    r4432b52 r1f9a4d0  
    5050% MAIN BODY
    5151%----------------------------------------------------------------------
    52 \input{existing}
    53 \input{features}
    5452\input{unwinding}
    55 \input{future}
    5653
    5754%======================================================================
  • src/ResolvExpr/AlternativeFinder.cc

    r4432b52 r1f9a4d0  
    251251                        SemanticError( expr, "No reasonable alternatives for expression " );
    252252                }
    253                 if ( mode.prune ) {
     253                if ( mode.satisfyAssns || mode.prune ) {
    254254                        // trim candidates just to those where the assertions resolve
    255255                        // - necessary pre-requisite to pruning
  • src/ResolvExpr/CandidateFinder.cpp

    r4432b52 r1f9a4d0  
    16451645        /// Prunes a list of candidates down to those that have the minimum conversion cost for a given
    16461646        /// return type. Skips ambiguous candidates.
    1647 
    1648 } // anonymous namespace
    1649 
    1650 bool CandidateFinder::pruneCandidates( CandidateList & candidates, CandidateList & out, std::vector<std::string> & errors ) {
    1651         struct PruneStruct {
    1652                 CandidateRef candidate;
    1653                 bool ambiguous;
    1654 
    1655                 PruneStruct() = default;
    1656                 PruneStruct( const CandidateRef & c ) : candidate( c ), ambiguous( false ) {}
    1657         };
    1658 
    1659         // find lowest-cost candidate for each type
    1660         std::unordered_map< std::string, PruneStruct > selected;
    1661         // attempt to skip satisfyAssertions on more expensive alternatives if better options have been found
    1662         std::sort(candidates.begin(), candidates.end(), [](const CandidateRef & x, const CandidateRef & y){return x->cost < y->cost;});
    1663         for ( CandidateRef & candidate : candidates ) {
    1664                 std::string mangleName;
    1665                 {
    1666                         ast::ptr< ast::Type > newType = candidate->expr->result;
    1667                         assertf(candidate->expr->result, "Result of expression %p for candidate is null", candidate->expr.get());
    1668                         candidate->env.apply( newType );
    1669                         mangleName = Mangle::mangle( newType );
    1670                 }
    1671 
    1672                 auto found = selected.find( mangleName );
    1673                 if (found != selected.end() && found->second.candidate->cost < candidate->cost) {
    1674                         PRINT(
    1675                                 std::cerr << "cost " << candidate->cost << " loses to "
    1676                                         << found->second.candidate->cost << std::endl;
    1677                         )
    1678                         continue;
    1679                 }
    1680 
    1681                 // xxx - when do satisfyAssertions produce more than 1 result?
    1682                 // this should only happen when initial result type contains
    1683                 // unbound type parameters, then it should never be pruned by
    1684                 // the previous step, since renameTyVars guarantees the mangled name
    1685                 // is unique.
    1686                 CandidateList satisfied;
    1687                 bool needRecomputeKey = false;
    1688                 if (candidate->need.empty()) {
    1689                         satisfied.emplace_back(candidate);
    1690                 }
    1691                 else {
    1692                         satisfyAssertions(candidate, localSyms, satisfied, errors);
    1693                         needRecomputeKey = true;
    1694                 }
    1695 
    1696                 for (auto & newCand : satisfied) {
    1697                         // recomputes type key, if satisfyAssertions changed it
    1698                         if (needRecomputeKey)
     1647        CandidateList pruneCandidates( CandidateList & candidates ) {
     1648                struct PruneStruct {
     1649                        CandidateRef candidate;
     1650                        bool ambiguous;
     1651
     1652                        PruneStruct() = default;
     1653                        PruneStruct( const CandidateRef & c ) : candidate( c ), ambiguous( false ) {}
     1654                };
     1655
     1656                // find lowest-cost candidate for each type
     1657                std::unordered_map< std::string, PruneStruct > selected;
     1658                for ( CandidateRef & candidate : candidates ) {
     1659                        std::string mangleName;
    16991660                        {
    1700                                 ast::ptr< ast::Type > newType = newCand->expr->result;
    1701                                 assertf(newCand->expr->result, "Result of expression %p for candidate is null", newCand->expr.get());
    1702                                 newCand->env.apply( newType );
     1661                                ast::ptr< ast::Type > newType = candidate->expr->result;
     1662                                assertf(candidate->expr->result, "Result of expression %p for candidate is null", candidate->expr.get());
     1663                                candidate->env.apply( newType );
    17031664                                mangleName = Mangle::mangle( newType );
    17041665                        }
     1666
    17051667                        auto found = selected.find( mangleName );
    17061668                        if ( found != selected.end() ) {
    1707                                 if ( newCand->cost < found->second.candidate->cost ) {
     1669                                if ( candidate->cost < found->second.candidate->cost ) {
    17081670                                        PRINT(
    1709                                                 std::cerr << "cost " << newCand->cost << " beats "
     1671                                                std::cerr << "cost " << candidate->cost << " beats "
    17101672                                                        << found->second.candidate->cost << std::endl;
    17111673                                        )
    17121674
    1713                                         found->second = PruneStruct{ newCand };
    1714                                 } else if ( newCand->cost == found->second.candidate->cost ) {
     1675                                        found->second = PruneStruct{ candidate };
     1676                                } else if ( candidate->cost == found->second.candidate->cost ) {
    17151677                                        // if one of the candidates contains a deleted identifier, can pick the other,
    17161678                                        // since deleted expressions should not be ambiguous if there is another option
    17171679                                        // that is at least as good
    1718                                         if ( findDeletedExpr( newCand->expr ) ) {
     1680                                        if ( findDeletedExpr( candidate->expr ) ) {
    17191681                                                // do nothing
    17201682                                                PRINT( std::cerr << "candidate is deleted" << std::endl; )
    17211683                                        } else if ( findDeletedExpr( found->second.candidate->expr ) ) {
    17221684                                                PRINT( std::cerr << "current is deleted" << std::endl; )
    1723                                                 found->second = PruneStruct{ newCand };
     1685                                                found->second = PruneStruct{ candidate };
    17241686                                        } else {
    17251687                                                PRINT( std::cerr << "marking ambiguous" << std::endl; )
    17261688                                                found->second.ambiguous = true;
    17271689                                        }
    1728                                 } else {
    1729                                         // xxx - can satisfyAssertions increase the cost?
     1690                                } else {
    17301691                                        PRINT(
    1731                                                 std::cerr << "cost " << newCand->cost << " loses to "
     1692                                                std::cerr << "cost " << candidate->cost << " loses to "
    17321693                                                        << found->second.candidate->cost << std::endl;
    1733                                         )       
     1694                                        )
    17341695                                }
    17351696                        } else {
    1736                                 selected.emplace_hint( found, mangleName, newCand );
    1737                         }
    1738                 }
     1697                                selected.emplace_hint( found, mangleName, candidate );
     1698                        }
     1699                }
     1700
     1701                // report unambiguous min-cost candidates
     1702                CandidateList out;
     1703                for ( auto & target : selected ) {
     1704                        if ( target.second.ambiguous ) continue;
     1705
     1706                        CandidateRef cand = target.second.candidate;
     1707
     1708                        ast::ptr< ast::Type > newResult = cand->expr->result;
     1709                        cand->env.applyFree( newResult );
     1710                        cand->expr = ast::mutate_field(
     1711                                cand->expr.get(), &ast::Expr::result, move( newResult ) );
     1712
     1713                        out.emplace_back( cand );
     1714                }
     1715                return out;
    17391716        }
    17401717
    1741         // report unambiguous min-cost candidates
    1742         // CandidateList out;
    1743         for ( auto & target : selected ) {
    1744                 if ( target.second.ambiguous ) continue;
    1745 
    1746                 CandidateRef cand = target.second.candidate;
    1747 
    1748                 ast::ptr< ast::Type > newResult = cand->expr->result;
    1749                 cand->env.applyFree( newResult );
    1750                 cand->expr = ast::mutate_field(
    1751                         cand->expr.get(), &ast::Expr::result, move( newResult ) );
    1752 
    1753                 out.emplace_back( cand );
    1754         }
    1755         // if everything is lost in satisfyAssertions, report the error
    1756         return !selected.empty();
    1757 }
     1718} // anonymous namespace
    17581719
    17591720void CandidateFinder::find( const ast::Expr * expr, ResolvMode mode ) {
     
    17781739        }
    17791740
    1780         /*
    17811741        if ( mode.satisfyAssns || mode.prune ) {
    17821742                // trim candidates to just those where the assertions are satisfiable
     
    18011761                candidates = move( satisfied );
    18021762        }
    1803         */
    18041763
    18051764        if ( mode.prune ) {
     
    18101769                )
    18111770
    1812                 CandidateList pruned;
    1813                 std::vector<std::string> errors;
    1814                 bool found = pruneCandidates( candidates, pruned, errors );
     1771                CandidateList pruned = pruneCandidates( candidates );
    18151772
    18161773                if ( mode.failFast && pruned.empty() ) {
    18171774                        std::ostringstream stream;
    1818                         if (found) {           
    1819                                 CandidateList winners = findMinCost( candidates );
    1820                                 stream << "Cannot choose between " << winners.size() << " alternatives for "
    1821                                         "expression\n";
    1822                                 ast::print( stream, expr );
    1823                                 stream << " Alternatives are:\n";
    1824                                 print( stream, winners, 1 );
    1825                                 SemanticError( expr->location, stream.str() );
    1826                         }
    1827                         else {
    1828                                 stream << "No alternatives with satisfiable assertions for " << expr << "\n";
    1829                                 for ( const auto& err : errors ) {
    1830                                         stream << err;
    1831                                 }
    1832                                 SemanticError( expr->location, stream.str() );
    1833                         }
     1775                        CandidateList winners = findMinCost( candidates );
     1776                        stream << "Cannot choose between " << winners.size() << " alternatives for "
     1777                                "expression\n";
     1778                        ast::print( stream, expr );
     1779                        stream << " Alternatives are:\n";
     1780                        print( stream, winners, 1 );
     1781                        SemanticError( expr->location, stream.str() );
    18341782                }
    18351783
  • src/ResolvExpr/CandidateFinder.hpp

    r4432b52 r1f9a4d0  
    4040        /// Fill candidates with feasible resolutions for `expr`
    4141        void find( const ast::Expr * expr, ResolvMode mode = {} );
    42         bool pruneCandidates( CandidateList & candidates, CandidateList & out, std::vector<std::string> & errors );
    4342
    4443        /// Runs new candidate finder on each element in xs, returning the list of finders
  • src/ResolvExpr/ResolvMode.h

    r4432b52 r1f9a4d0  
    2222                const bool prune;            ///< Prune alternatives to min-cost per return type? [true]
    2323                const bool failFast;         ///< Fail on no resulting alternatives? [true]
     24                const bool satisfyAssns;     ///< Satisfy assertions? [false]
    2425
    2526        private:
    26                 constexpr ResolvMode(bool a, bool p, bool ff)
    27                 : adjust(a), prune(p), failFast(ff) {}
     27                constexpr ResolvMode(bool a, bool p, bool ff, bool sa)
     28                : adjust(a), prune(p), failFast(ff), satisfyAssns(sa) {}
    2829
    2930        public:
    3031                /// Default settings
    31                 constexpr ResolvMode() : adjust(false), prune(true), failFast(true) {}
     32                constexpr ResolvMode() : adjust(false), prune(true), failFast(true), satisfyAssns(false) {}
    3233               
    3334                /// With adjust flag set; turns array and function types into equivalent pointers
    34                 static constexpr ResolvMode withAdjustment() { return { true, true, true }; }
     35                static constexpr ResolvMode withAdjustment() { return { true, true, true, false }; }
    3536
    3637                /// With adjust flag set but prune unset; pruning ensures there is at least one alternative
    3738                /// per result type
    38                 static constexpr ResolvMode withoutPrune() { return { true, false, true }; }
     39                static constexpr ResolvMode withoutPrune() { return { true, false, true, false }; }
    3940
    4041                /// With adjust and prune flags set but failFast unset; failFast ensures there is at least
    4142                /// one resulting alternative
    42                 static constexpr ResolvMode withoutFailFast() { return { true, true, false }; }
     43                static constexpr ResolvMode withoutFailFast() { return { true, true, false, false }; }
    4344
    4445                /// The same mode, but with satisfyAssns turned on; for top-level calls
    45                 ResolvMode atTopLevel() const { return { adjust, true, failFast }; }
     46                ResolvMode atTopLevel() const { return { adjust, prune, failFast, true }; }
    4647        };
    4748} // namespace ResolvExpr
  • src/ResolvExpr/SatisfyAssertions.hpp

    r4432b52 r1f9a4d0  
    2727namespace ResolvExpr {
    2828
    29 /// Recursively satisfies all assertions provided in a candidate
    30 /// returns true if it has been run (candidate has any assertions)
     29/// Recursively satisfies all assertions provided in a candidate; returns true if succeeds
    3130void satisfyAssertions(
    3231        CandidateRef & cand, const ast::SymbolTable & symtab, CandidateList & out,
Note: See TracChangeset for help on using the changeset viewer.