diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-10 21:43:25 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-10 21:43:25 +0800 |
commit | 7df9e0a4a4fb677303c7a71919226a660b30e29b (patch) | |
tree | 41b5616f69406580a8d6fbdd5bfab4cdba2f1882 | |
parent | 8cb134e7fbad5fb4b2c445fa51548d96f3a078d7 (diff) | |
download | mrust-7df9e0a4a4fb677303c7a71919226a660b30e29b.tar.gz |
MIR - Destructure patterns
-rw-r--r-- | src/mir/from_hir.cpp | 82 |
1 files changed, 73 insertions, 9 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 633caf8e..4b60640d 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -151,16 +151,80 @@ namespace { } - void destructure_from(const Span& sp, const ::HIR::Pattern& pat, ::MIR::LValue lval) + void destructure_from(const Span& sp, const ::HIR::Pattern& pat, ::MIR::LValue lval, int allow_refutable=0) // 1 : yes, 2 : disallow binding { if( pat.m_binding.is_valid() ) { - ASSERT_BUG(sp, pat.m_data.is_Any(), "Destructure patterns can't bind and match"); - - m_builder.push_stmt_assign( ::MIR::LValue::make_Variable(pat.m_binding.m_slot), mv$(lval) ); - return ; + if( allow_refutable == 2 ) { + BUG(sp, "Binding when not expected"); + } + else if( allow_refutable == 0 ) { + ASSERT_BUG(sp, pat.m_data.is_Any(), "Destructure patterns can't bind and match"); + + m_builder.push_stmt_assign( ::MIR::LValue::make_Variable(pat.m_binding.m_slot), mv$(lval) ); + return; + } + else { + // Refutable and binding allowed + m_builder.push_stmt_assign( ::MIR::LValue::make_Variable(pat.m_binding.m_slot), lval.clone() ); + } } - // TODO: Destructure - TODO(sp, "Destructure using " << pat); + + TU_MATCHA( (pat.m_data), (e), + (Any, + ), + (Box, + TODO(sp, "Destructure using " << pat); + ), + (Ref, + destructure_from(sp, *e.sub, ::MIR::LValue::make_Deref({ box$( mv$(lval) ) })); + ), + (Tuple, + for(unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) + { + destructure_from(sp, e.sub_patterns[i], ::MIR::LValue::make_Field({ box$( lval.clone() ), i})); + } + ), + (StructTuple, + for(unsigned int i = 0; i < e.sub_patterns.size(); i ++ ) + { + destructure_from(sp, e.sub_patterns[i], ::MIR::LValue::make_Field({ box$( lval.clone() ), i})); + } + ), + (StructTupleWildcard, + ), + (Struct, + TODO(sp, "Destructure using " << pat); + ), + // Refutable + (Value, + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected"); + ), + (Range, + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected"); + ), + (EnumValue, + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected"); + ), + (EnumTuple, + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected"); + TODO(sp, "Destructure using " << pat); + ), + (EnumTupleWildcard, + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected"); + ), + (EnumStruct, + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected"); + TODO(sp, "Destructure using " << pat); + ), + (Slice, + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected"); + TODO(sp, "Destructure using " << pat); + ), + (SplitSlice, + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected"); + TODO(sp, "Destructure using " << pat); + ) + ) } // -- ExprVisitor @@ -543,8 +607,8 @@ namespace { ASSERT_BUG(node.span(), arm.m_patterns.size() == 1, "TODO: Handle multiple patterns on one arm"); const auto& pat = arm.m_patterns[0 /*rule.first.second*/]; - // Assign bindings (drop registration happens in previous loop) - this->destructure_from( arm.m_code->span(), pat, match_val.clone() ); + // Assign bindings (drop registration happens in previous loop) - Allow refutable patterns + this->destructure_from( arm.m_code->span(), pat, match_val.clone(), 1 ); } // ## Create descision tree in-memory based off the ruleset |