summaryrefslogtreecommitdiff
path: root/src/expand/mod.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-05-20 09:52:57 +0800
committerJohn Hodge <tpg@mutabah.net>2016-05-20 09:52:57 +0800
commite0d932dbc21555ef47e33b0d13aeb3dde8e42c7e (patch)
tree1ea75a429d676026efc54b3920f5159563debf6f /src/expand/mod.cpp
parent692cef0353fc891756d4137e8007e0f822c684a5 (diff)
downloadmrust-e0d932dbc21555ef47e33b0d13aeb3dde8e42c7e.tar.gz
Expand - For loop desugar
Diffstat (limited to 'src/expand/mod.cpp')
-rw-r--r--src/expand/mod.cpp46
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);