Changes in / [4432b52:1f9a4d0]
- Files:
-
- 1 deleted
- 8 edited
-
doc/theses/andrew_beach_MMath/Makefile (modified) (1 diff)
-
doc/theses/andrew_beach_MMath/cfalab.sty (modified) (2 diffs)
-
doc/theses/andrew_beach_MMath/existing.tex (deleted)
-
doc/theses/andrew_beach_MMath/thesis.tex (modified) (1 diff)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (1 diff)
-
src/ResolvExpr/CandidateFinder.cpp (modified) (4 diffs)
-
src/ResolvExpr/CandidateFinder.hpp (modified) (1 diff)
-
src/ResolvExpr/ResolvMode.h (modified) (1 diff)
-
src/ResolvExpr/SatisfyAssertions.hpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/andrew_beach_MMath/Makefile
r4432b52 r1f9a4d0 31 31 ${GLOSSARY} ${BUILD}/${BASE} 32 32 ${LATEX} ${BASE} 33 ${LATEX} ${BASE} 33 34 34 35 ${DOC}: ${BUILD}/${DOC} -
doc/theses/andrew_beach_MMath/cfalab.sty
r4432b52 r1f9a4d0 27 27 % Cforall with the forall symbol. 28 28 \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 }42 29 43 30 % The CFA listings language. Based off of ANCI C and including GCC extensions. … … 85 72 \renewcommand\textunderscore{\csuse{cfalab@textunderscore@#1}}} 86 73 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 87 84 \endinput -
doc/theses/andrew_beach_MMath/thesis.tex
r4432b52 r1f9a4d0 50 50 % MAIN BODY 51 51 %---------------------------------------------------------------------- 52 \input{existing}53 \input{features}54 52 \input{unwinding} 55 \input{future}56 53 57 54 %====================================================================== -
src/ResolvExpr/AlternativeFinder.cc
r4432b52 r1f9a4d0 251 251 SemanticError( expr, "No reasonable alternatives for expression " ); 252 252 } 253 if ( mode. prune ) {253 if ( mode.satisfyAssns || mode.prune ) { 254 254 // trim candidates just to those where the assertions resolve 255 255 // - necessary pre-requisite to pruning -
src/ResolvExpr/CandidateFinder.cpp
r4432b52 r1f9a4d0 1645 1645 /// Prunes a list of candidates down to those that have the minimum conversion cost for a given 1646 1646 /// 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; 1699 1660 { 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 ); 1703 1664 mangleName = Mangle::mangle( newType ); 1704 1665 } 1666 1705 1667 auto found = selected.find( mangleName ); 1706 1668 if ( found != selected.end() ) { 1707 if ( newCand->cost < found->second.candidate->cost ) {1669 if ( candidate->cost < found->second.candidate->cost ) { 1708 1670 PRINT( 1709 std::cerr << "cost " << newCand->cost << " beats "1671 std::cerr << "cost " << candidate->cost << " beats " 1710 1672 << found->second.candidate->cost << std::endl; 1711 1673 ) 1712 1674 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 ) { 1715 1677 // if one of the candidates contains a deleted identifier, can pick the other, 1716 1678 // since deleted expressions should not be ambiguous if there is another option 1717 1679 // that is at least as good 1718 if ( findDeletedExpr( newCand->expr ) ) {1680 if ( findDeletedExpr( candidate->expr ) ) { 1719 1681 // do nothing 1720 1682 PRINT( std::cerr << "candidate is deleted" << std::endl; ) 1721 1683 } else if ( findDeletedExpr( found->second.candidate->expr ) ) { 1722 1684 PRINT( std::cerr << "current is deleted" << std::endl; ) 1723 found->second = PruneStruct{ newCand};1685 found->second = PruneStruct{ candidate }; 1724 1686 } else { 1725 1687 PRINT( std::cerr << "marking ambiguous" << std::endl; ) 1726 1688 found->second.ambiguous = true; 1727 1689 } 1728 } else { 1729 // xxx - can satisfyAssertions increase the cost? 1690 } else { 1730 1691 PRINT( 1731 std::cerr << "cost " << newCand->cost << " loses to "1692 std::cerr << "cost " << candidate->cost << " loses to " 1732 1693 << found->second.candidate->cost << std::endl; 1733 ) 1694 ) 1734 1695 } 1735 1696 } 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; 1739 1716 } 1740 1717 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 1758 1719 1759 1720 void CandidateFinder::find( const ast::Expr * expr, ResolvMode mode ) { … … 1778 1739 } 1779 1740 1780 /*1781 1741 if ( mode.satisfyAssns || mode.prune ) { 1782 1742 // trim candidates to just those where the assertions are satisfiable … … 1801 1761 candidates = move( satisfied ); 1802 1762 } 1803 */1804 1763 1805 1764 if ( mode.prune ) { … … 1810 1769 ) 1811 1770 1812 CandidateList pruned; 1813 std::vector<std::string> errors; 1814 bool found = pruneCandidates( candidates, pruned, errors ); 1771 CandidateList pruned = pruneCandidates( candidates ); 1815 1772 1816 1773 if ( mode.failFast && pruned.empty() ) { 1817 1774 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() ); 1834 1782 } 1835 1783 -
src/ResolvExpr/CandidateFinder.hpp
r4432b52 r1f9a4d0 40 40 /// Fill candidates with feasible resolutions for `expr` 41 41 void find( const ast::Expr * expr, ResolvMode mode = {} ); 42 bool pruneCandidates( CandidateList & candidates, CandidateList & out, std::vector<std::string> & errors );43 42 44 43 /// Runs new candidate finder on each element in xs, returning the list of finders -
src/ResolvExpr/ResolvMode.h
r4432b52 r1f9a4d0 22 22 const bool prune; ///< Prune alternatives to min-cost per return type? [true] 23 23 const bool failFast; ///< Fail on no resulting alternatives? [true] 24 const bool satisfyAssns; ///< Satisfy assertions? [false] 24 25 25 26 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) {} 28 29 29 30 public: 30 31 /// Default settings 31 constexpr ResolvMode() : adjust(false), prune(true), failFast(true) {}32 constexpr ResolvMode() : adjust(false), prune(true), failFast(true), satisfyAssns(false) {} 32 33 33 34 /// 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 }; } 35 36 36 37 /// With adjust flag set but prune unset; pruning ensures there is at least one alternative 37 38 /// per result type 38 static constexpr ResolvMode withoutPrune() { return { true, false, true }; }39 static constexpr ResolvMode withoutPrune() { return { true, false, true, false }; } 39 40 40 41 /// With adjust and prune flags set but failFast unset; failFast ensures there is at least 41 42 /// one resulting alternative 42 static constexpr ResolvMode withoutFailFast() { return { true, true, false }; }43 static constexpr ResolvMode withoutFailFast() { return { true, true, false, false }; } 43 44 44 45 /// 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 }; } 46 47 }; 47 48 } // namespace ResolvExpr -
src/ResolvExpr/SatisfyAssertions.hpp
r4432b52 r1f9a4d0 27 27 namespace ResolvExpr { 28 28 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 31 30 void satisfyAssertions( 32 31 CandidateRef & cand, const ast::SymbolTable & symtab, CandidateList & out,
Note:
See TracChangeset
for help on using the changeset viewer.