diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-13 11:30:12 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-13 11:30:12 +0800 |
commit | 0a55a95701042e76fa244e4954cca20fcf6654f2 (patch) | |
tree | 10fd85c24672825d96b0eae70ff6e00d4c96edf6 /src | |
parent | 7b55e470e275f2182a5bb41413cded0fe9446d3a (diff) | |
download | mrust-0a55a95701042e76fa244e4954cca20fcf6654f2.tar.gz |
MIR Gen Match - Initial population for &str support
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/from_hir_match.cpp | 112 |
1 files changed, 98 insertions, 14 deletions
diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index 52c53310..6bb37b01 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -429,8 +429,8 @@ struct DecisionTreeNode (Bool, struct { Branch false_branch, true_branch; }), (Variant, ::std::vector< ::std::pair<unsigned int, Branch> >), (Unsigned, ::std::vector< ::std::pair< Range<uint64_t>, Branch> >), - (Signed, ::std::vector< ::std::pair< Range<int64_t>, Branch> >) - //(String, struct { branchset_t< ::std::string> branches; }) + (Signed, ::std::vector< ::std::pair< Range<int64_t>, Branch> >), + (String, ::std::vector< ::std::pair< ::std::string, Branch> >) ); bool is_specialisation; @@ -869,6 +869,15 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa ), (Ref, this->append_from( sp, *pe.sub, *e.inner ); + ), + (Value, + if( pe.val.is_String() ) { + const auto& s = pe.val.as_String(); + m_rules.push_back( PatternRule::make_Value(s) ); + } + else { + BUG(sp, "Matching borrow invalid pattern - " << pat); + } ) ) ), @@ -934,6 +943,13 @@ DecisionTreeNode::Values DecisionTreeNode::clone(const DecisionTreeNode::Values& for(const auto& v : e) rv.push_back( ::std::make_pair(v.first, clone(v.second)) ); return Values( mv$(rv) ); + ), + (String, + Values::Data_String rv; + rv.reserve(e.size()); + for(const auto& v : e) + rv.push_back( ::std::make_pair(v.first, clone(v.second)) ); + return Values( mv$(rv) ); ) ) throw ""; @@ -1059,13 +1075,16 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule BUG(sp, "Mismatched rules"); } auto& be = m_branches.as_Unsigned(); - auto it = ::std::find_if(be.begin(), be.end(), [&](const auto& v){ return v.first.start <= ve; }); - if( it == be.end() || it->first.end < ve ) { + auto it = ::std::find_if(be.begin(), be.end(), [&](const auto& v){ return v.first.end >= ve; }); + if( it == be.end() || it->first.start > ve ) { it = be.insert( it, ::std::make_pair( Range<uint64_t> { ve,ve }, Branch( box$(DecisionTreeNode()) ) ) ); } + else if( it->first.start == ve && it->first.end == ve ) { + // Equal, continue and add sub-pat + } else { // Collide or overlap! - TODO(sp, "Value patterns - Uint - Overlapping"); + TODO(sp, "Value patterns - Uint - Overlapping - " << it->first.start << " <= " << ve << " <= " << it->first.end); } auto& branch = it->second; if( rule_count > 1 ) @@ -1089,7 +1108,29 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule TODO(sp, "Value patterns - Bytes"); ), (StaticString, - TODO(sp, "Value patterns - StaticString"); + if( m_branches.is_Unset() ) { + m_branches = Values::make_String({}); + } + else if( !m_branches.is_String() ) { + BUG(sp, "Mismatched rules"); + } + auto& be = m_branches.as_String(); + + auto it = ::std::find_if(be.begin(), be.end(), [&](const auto& v){ return v.first >= ve; }); + if( it == be.end() || it->first != ve ) { + it = be.insert( it, ::std::make_pair(ve, Branch( box$(DecisionTreeNode()) ) ) ); + } + auto& branch = it->second; + if( rule_count > 1 ) + { + assert( branch.as_Subtree() ); + auto& subtree = *branch.as_Subtree(); + subtree.populate_tree_from_rule(sp, first_rule+1, rule_count-1, and_then); + } + else + { + and_then(branch); + } ), (ItemAddr, throw ""; @@ -1110,10 +1151,13 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule BUG(sp, "Mismatched rules"); } auto& be = m_branches.as_Unsigned(); - auto it = ::std::find_if(be.begin(), be.end(), [&](const auto& v){ return v.first.start <= ve_end; }); + auto it = ::std::find_if(be.begin(), be.end(), [&](const auto& v){ return v.first.start >= ve_end; }); if( it == be.end() || it->first.end < ve_start ) { it = be.insert( it, ::std::make_pair( Range<uint64_t> { ve_start,ve_end }, Branch( box$(DecisionTreeNode()) ) ) ); } + else if( it->first.start == ve_start && it->first.end == ve_end ) { + // Equal, add sub-pattern + } else { // Collide or overlap! TODO(sp, "ValueRange patterns - Uint - Overlapping"); @@ -1131,16 +1175,16 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule } ), (Float, - TODO(sp, "Value patterns - Float"); + TODO(sp, "ValueRange patterns - Float"); ), (Bool, throw ""; ), (Bytes, - TODO(sp, "Value patterns - Bytes"); + TODO(sp, "ValueRange patterns - Bytes"); ), (StaticString, - TODO(sp, "Value patterns - StaticString"); + ERROR(sp, E0000, "Use of string in value range patter"); ), (ItemAddr, throw ""; @@ -1186,6 +1230,11 @@ void DecisionTreeNode::simplify() for(auto& branch : e) { H::simplify_branch(branch.second); } + ), + (String, + for(auto& branch : e) { + H::simplify_branch(branch.second); + } ) ) @@ -1226,6 +1275,11 @@ void DecisionTreeNode::propagate_default() for(auto& branch : e) { H::handle_branch(branch.second, m_default); } + ), + (String, + for(auto& branch : e) { + H::handle_branch(branch.second, m_default); + } ) ) TU_IFLET(Branch, m_default, Subtree, be, @@ -1254,6 +1308,11 @@ void DecisionTreeNode::propagate_default() for(auto& branch : e) { be->unify_from(branch.second); } + ), + (String, + for(auto& branch : e) { + be->unify_from(branch.second); + } ) ) } @@ -1328,6 +1387,18 @@ void DecisionTreeNode::unify_from(const Branch& b) // NOTE: Overlapping doesn't get handled here } } + ), + (String, + for(const auto& srcv : src) + { + auto it = ::std::find_if( dst.begin(), dst.end(), [&](const auto& x){ return x.first >= srcv.first; }); + // Not found? Insert a new branch + if( it == dst.end() ) { + it = dst.insert(it, ::std::make_pair( srcv.first, clone(srcv.second) )); + } + else { + } + } ) ) if( m_default.is_Unset() ) { @@ -1388,6 +1459,11 @@ void DecisionTreeNode::unify_from(const Branch& b) } os << " = " << branch.second << ", "; } + ), + (String, + for(const auto& branch : e) { + os << "\"" << branch.first << "\"" << " = " << branch.second << ", "; + } ) ) @@ -1507,10 +1583,18 @@ void DecisionTreeGen::populate_tree_vals( BUG(sp, "Hit match over `[T]` - must be `&[T]`"); ), (Borrow, - populate_tree_vals( sp, node, - *e.inner, 0, ::MIR::LValue::make_Deref({ box$(val.clone()) }), - and_then - ); + if( *e.inner == ::HIR::TypeRef(::HIR::CoreType::Str) ) { + TODO(sp, "Match over &str"); + } + else if( e.inner->m_data.is_Slice() ) { + TODO(sp, "Match over &[T]"); + } + else { + populate_tree_vals( sp, node, + *e.inner, 0, ::MIR::LValue::make_Deref({ box$(val.clone()) }), + and_then + ); + } ), (Pointer, ERROR(sp, E0000, "Attempting to match over a pointer"); |