diff options
author | John Hodge <tpg@mutabah.net> | 2016-05-20 09:52:57 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-05-20 09:52:57 +0800 |
commit | e0d932dbc21555ef47e33b0d13aeb3dde8e42c7e (patch) | |
tree | 1ea75a429d676026efc54b3920f5159563debf6f /src/expand/mod.cpp | |
parent | 692cef0353fc891756d4137e8007e0f822c684a5 (diff) | |
download | mrust-e0d932dbc21555ef47e33b0d13aeb3dde8e42c7e.tar.gz |
Expand - For loop desugar
Diffstat (limited to 'src/expand/mod.cpp')
-rw-r--r-- | src/expand/mod.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 2f4fe0be..3d4f431e 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -343,6 +343,52 @@ struct CExpandExpr: void visit(::AST::ExprNode_Loop& node) override { this->visit_nodelete(node, node.m_cond); this->visit_nodelete(node, node.m_code); + Expand_Pattern(is_early, crate, modstack, this->cur_mod(), node.m_pattern); + if(node.m_type == ::AST::ExprNode_Loop::FOR) + { + // TODO: Desugar into: + // { + // let mut it = <_ as IntoIterator>::into_iter(`m_cond`); + // `m_label`: loop { + // match it.next() { + // Some(`m_pattern`) => `m_code`, + // None => break `m_label`, + // } + // } + // } + ::std::vector< ::AST::ExprNode_Match_Arm> arms; + arms.push_back( ::AST::ExprNode_Match_Arm( + ::make_vec1( ::AST::Pattern(::AST::Pattern::TagEnumVariant(), ::AST::Path(::AST::Path::TagRelative(), {::AST::PathNode("Some")}), ::make_vec1( mv$(node.m_pattern) ) ) ), + nullptr, + mv$(node.m_code) + ) ); + arms.push_back( ::AST::ExprNode_Match_Arm( + ::make_vec1( ::AST::Pattern(::AST::Pattern::TagValue(), ::AST::Pattern::Value::make_Named(::AST::Path(::AST::Path::TagRelative(), {::AST::PathNode("None")})) ) ), + nullptr, + ::AST::ExprNodeP(new ::AST::ExprNode_Flow(::AST::ExprNode_Flow::BREAK, node.m_label, nullptr)) + ) ); + ::std::vector< ::AST::ExprNodeP> block_nodes; + block_nodes.push_back( ::AST::ExprNodeP(new ::AST::ExprNode_LetBinding( + ::AST::Pattern(::AST::Pattern::TagBind(), "it"), + TypeRef(), + ::AST::ExprNodeP(new ::AST::ExprNode_CallPath( + ::AST::Path(::AST::Path::TagUfcs(), ::TypeRef(), ::AST::Path(::AST::Path::TagRelative(), {::AST::PathNode("IntoIterator")}), { ::AST::PathNode("into_iter") } ), + ::make_vec1( mv$(node.m_cond) ) + )) + )) ); + block_nodes.push_back( ::AST::ExprNodeP(new ::AST::ExprNode_Loop( + node.m_label, + ::AST::ExprNodeP(new ::AST::ExprNode_Match( + ::AST::ExprNodeP(new ::AST::ExprNode_CallMethod( + ::AST::ExprNodeP(new ::AST::ExprNode_NamedValue( ::AST::Path("it") )), + ::AST::PathNode("next"), + {} + )), + mv$(arms) + )) + )) ); + replacement.reset(new ::AST::ExprNode_Block( mv$(block_nodes), nullptr )); + } } void visit(::AST::ExprNode_Match& node) override { this->visit_nodelete(node, node.m_val); |