Changes in / [1f9a4d0:4432b52]


Ignore:
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/andrew_beach_MMath/Makefile

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

    r1f9a4d0 r4432b52  
    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}
    2942
    3043% The CFA listings language. Based off of ANCI C and including GCC extensions.
     
    7285    \renewcommand\textunderscore{\csuse{cfalab@textunderscore@#1}}}
    7386
    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 
    8487\endinput
  • doc/theses/andrew_beach_MMath/thesis.tex

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

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

    r1f9a4d0 r4432b52  
    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         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;
     1647
     1648} // anonymous namespace
     1649
     1650bool 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)
    16601699                        {
    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 );
     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 );
    16641703                                mangleName = Mangle::mangle( newType );
    16651704                        }
    1666 
    16671705                        auto found = selected.find( mangleName );
    16681706                        if ( found != selected.end() ) {
    1669                                 if ( candidate->cost < found->second.candidate->cost ) {
     1707                                if ( newCand->cost < found->second.candidate->cost ) {
    16701708                                        PRINT(
    1671                                                 std::cerr << "cost " << candidate->cost << " beats "
     1709                                                std::cerr << "cost " << newCand->cost << " beats "
    16721710                                                        << found->second.candidate->cost << std::endl;
    16731711                                        )
    16741712
    1675                                         found->second = PruneStruct{ candidate };
    1676                                 } else if ( candidate->cost == found->second.candidate->cost ) {
     1713                                        found->second = PruneStruct{ newCand };
     1714                                } else if ( newCand->cost == found->second.candidate->cost ) {
    16771715                                        // if one of the candidates contains a deleted identifier, can pick the other,
    16781716                                        // since deleted expressions should not be ambiguous if there is another option
    16791717                                        // that is at least as good
    1680                                         if ( findDeletedExpr( candidate->expr ) ) {
     1718                                        if ( findDeletedExpr( newCand->expr ) ) {
    16811719                                                // do nothing
    16821720                                                PRINT( std::cerr << "candidate is deleted" << std::endl; )
    16831721                                        } else if ( findDeletedExpr( found->second.candidate->expr ) ) {
    16841722                                                PRINT( std::cerr << "current is deleted" << std::endl; )
    1685                                                 found->second = PruneStruct{ candidate };
     1723                                                found->second = PruneStruct{ newCand };
    16861724                                        } else {
    16871725                                                PRINT( std::cerr << "marking ambiguous" << std::endl; )
    16881726                                                found->second.ambiguous = true;
    16891727                                        }
    1690                                 } else {
     1728                                } else {
     1729                                        // xxx - can satisfyAssertions increase the cost?
    16911730                                        PRINT(
    1692                                                 std::cerr << "cost " << candidate->cost << " loses to "
     1731                                                std::cerr << "cost " << newCand->cost << " loses to "
    16931732                                                        << found->second.candidate->cost << std::endl;
    1694                                         )
     1733                                        )       
    16951734                                }
    16961735                        } else {
    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;
     1736                                selected.emplace_hint( found, mangleName, newCand );
     1737                        }
     1738                }
    17161739        }
    17171740
    1718 } // anonymous namespace
     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}
    17191758
    17201759void CandidateFinder::find( const ast::Expr * expr, ResolvMode mode ) {
     
    17391778        }
    17401779
     1780        /*
    17411781        if ( mode.satisfyAssns || mode.prune ) {
    17421782                // trim candidates to just those where the assertions are satisfiable
     
    17611801                candidates = move( satisfied );
    17621802        }
     1803        */
    17631804
    17641805        if ( mode.prune ) {
     
    17691810                )
    17701811
    1771                 CandidateList pruned = pruneCandidates( candidates );
     1812                CandidateList pruned;
     1813                std::vector<std::string> errors;
     1814                bool found = pruneCandidates( candidates, pruned, errors );
    17721815
    17731816                if ( mode.failFast && pruned.empty() ) {
    17741817                        std::ostringstream stream;
    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() );
     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                        }
    17821834                }
    17831835
  • src/ResolvExpr/CandidateFinder.hpp

    r1f9a4d0 r4432b52  
    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 );
    4243
    4344        /// Runs new candidate finder on each element in xs, returning the list of finders
  • src/ResolvExpr/ResolvMode.h

    r1f9a4d0 r4432b52  
    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]
    2524
    2625        private:
    27                 constexpr ResolvMode(bool a, bool p, bool ff, bool sa)
    28                 : adjust(a), prune(p), failFast(ff), satisfyAssns(sa) {}
     26                constexpr ResolvMode(bool a, bool p, bool ff)
     27                : adjust(a), prune(p), failFast(ff) {}
    2928
    3029        public:
    3130                /// Default settings
    32                 constexpr ResolvMode() : adjust(false), prune(true), failFast(true), satisfyAssns(false) {}
     31                constexpr ResolvMode() : adjust(false), prune(true), failFast(true) {}
    3332               
    3433                /// With adjust flag set; turns array and function types into equivalent pointers
    35                 static constexpr ResolvMode withAdjustment() { return { true, true, true, false }; }
     34                static constexpr ResolvMode withAdjustment() { return { true, true, true }; }
    3635
    3736                /// With adjust flag set but prune unset; pruning ensures there is at least one alternative
    3837                /// per result type
    39                 static constexpr ResolvMode withoutPrune() { return { true, false, true, false }; }
     38                static constexpr ResolvMode withoutPrune() { return { true, false, true }; }
    4039
    4140                /// With adjust and prune flags set but failFast unset; failFast ensures there is at least
    4241                /// one resulting alternative
    43                 static constexpr ResolvMode withoutFailFast() { return { true, true, false, false }; }
     42                static constexpr ResolvMode withoutFailFast() { return { true, true, false }; }
    4443
    4544                /// The same mode, but with satisfyAssns turned on; for top-level calls
    46                 ResolvMode atTopLevel() const { return { adjust, prune, failFast, true }; }
     45                ResolvMode atTopLevel() const { return { adjust, true, failFast }; }
    4746        };
    4847} // namespace ResolvExpr
  • src/ResolvExpr/SatisfyAssertions.hpp

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