diff options
-rw-r--r-- | src/mir/from_hir_match.cpp | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index 227c46f3..f5e083bf 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -2292,15 +2292,40 @@ namespace // Common code for numerics (Int, Uint, and Float) template<typename T> + static void from_rule_value( + const Span& sp, + ::std::vector< ::std::pair< DecisionTreeNode::Range<T>, DecisionTreeNode::Branch> >& be, T ve, + const char* name, const field_path_t& field_path, ::std::function<void(DecisionTreeNode::Branch&)> and_then + ) + { + 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( DecisionTreeNode::Range<T> { ve,ve }, new_branch_subtree(field_path) ) ); + } + else if( it->first.start == ve && it->first.end == ve ) { + // Equal, continue and add sub-pat + } + else { + // Collide or overlap! + TODO(sp, "Value patterns - " << name << " - Overlapping - " << it->first.start << " <= " << ve << " <= " << it->first.end); + } + and_then( it->second ); + } + + template<typename T> static void from_rule_valuerange( const Span& sp, ::std::vector< ::std::pair< DecisionTreeNode::Range<T>, DecisionTreeNode::Branch> >& be, T ve_start, T ve_end, const char* name, const field_path_t& field_path, ::std::function<void(DecisionTreeNode::Branch&)> and_then ) { + TRACE_FUNCTION_F("be=[" << FMT_CB(os, for(const auto& i:be) os << i.first <<" , ";) << "], new=" << ve_start << "..." << ve_end); ASSERT_BUG(sp, ve_start <= ve_end, "Range pattern with a start after the end - " << ve_start << "..." << ve_end); - TRACE_FUNCTION_F("[" << FMT_CB(os, for(const auto& i:be) os << i.first <<" , ";) << "]"); + if( ve_start == ve_end ) { + from_rule_value(sp, be, ve_start, name, field_path, and_then); + return ; + } // - Find the first entry that ends after the new one starts. auto it = ::std::find_if(be.begin(), be.end(), [&](const auto& v){ return v.first.end >= ve_start; }); while(ve_start < ve_end) @@ -2355,27 +2380,6 @@ namespace } } } - - template<typename T> - static void from_rule_value( - const Span& sp, - ::std::vector< ::std::pair< DecisionTreeNode::Range<T>, DecisionTreeNode::Branch> >& be, T ve, - const char* name, const field_path_t& field_path, ::std::function<void(DecisionTreeNode::Branch&)> and_then - ) - { - 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( DecisionTreeNode::Range<T> { ve,ve }, new_branch_subtree(field_path) ) ); - } - else if( it->first.start == ve && it->first.end == ve ) { - // Equal, continue and add sub-pat - } - else { - // Collide or overlap! - TODO(sp, "Value patterns - " << name << " - Overlapping - " << it->first.start << " <= " << ve << " <= " << it->first.end); - } - and_then( it->second ); - } } void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule* first_rule, unsigned int rule_count, ::std::function<void(Branch&)> and_then) { |