@@ -166,55 +166,16 @@ build_into(Ann, Clauses, Expr, ?empty_map_set_pattern = _Into, Uniq, S) ->
166166 {ReduceExpr , SR } = build_reduce (Ann , Clauses , InnerFun , Expr , {nil , Ann }, Uniq , S ),
167167 {? remote (Ann , 'Elixir.MapSet' , new , [ReduceExpr ]), SR };
168168build_into (Ann , Clauses , Expr , Into , Uniq , S ) ->
169- {Fun , SF } = build_var (Ann , S ),
170- {Acc , SA } = build_var (Ann , SF ),
171- {Kind , SK } = build_var (Ann , SA ),
172- {Reason , SR } = build_var (Ann , SK ),
173- {Stack , ST } = build_var (Ann , SR ),
174- {Done , SD } = build_var (Ann , ST ),
175- {Ref , SRef } = build_var (Ann , SD ),
176- {Current , SC } = build_var (Ann , SRef ),
177-
178- InnerFun = fun (InnerExpr , InnerAcc ) ->
179- {block , Ann , [
180- {match , Ann , Current , {call , Ann , Fun , [InnerAcc , pair (Ann , cont , InnerExpr )]}},
181- ? remote (Ann , erlang , put , [Ref , Current ]),
182- Current
183- ]}
184- end ,
169+ {Fun , SF } = build_var (Ann , S ),
170+ {Acc , SA } = build_var (Ann , SF ),
185171
186172 MatchExpr = {match , Ann ,
187173 {tuple , Ann , [Acc , Fun ]},
188174 ? remote (Ann , 'Elixir.Collectable' , into , [Into ])
189175 },
190176
191- {IntoReduceExpr , SN } = build_reduce (Ann , Clauses , InnerFun , Expr , Acc , Uniq , SC ),
192- RefExpr = {match , Ann , Ref , ? remote (Ann , erlang , make_ref , [])},
193-
194- TryExpr =
195- {'try' , Ann ,
196- [IntoReduceExpr ],
197- [{clause , Ann ,
198- [Done ],
199- [],
200- [
201- ? remote (Ann , erlang , erase , [Ref ]),
202- {call , Ann , Fun , [Done , {atom , Ann , done }]}
203- ]}],
204- [stacktrace_clause (Ann , Fun , Ref , Kind , Reason , Stack )],
205- []},
206-
207- {{block , Ann , [RefExpr , MatchExpr , ? remote (Ann , erlang , put , [Ref , Acc ]), TryExpr ]}, SN }.
208-
209- stacktrace_clause (Ann , Fun , Ref , Kind , Reason , Stack ) ->
210- CurrentAcc = ? remote (Ann , erlang , get , [Ref ]),
211- {clause , Ann ,
212- [{tuple , Ann , [Kind , Reason , Stack ]}],
213- [],
214- [
215- {call , Ann , Fun , [CurrentAcc , {atom , Ann , halt }]},
216- ? remote (Ann , erlang , erase , [Ref ]),
217- ? remote (Ann , erlang , raise , [Kind , Reason , Stack ])]}.
177+ {IntoReduceExpr , SN } = build_into_reduce (Ann , Clauses , Expr , Acc , Fun , Uniq , SA ),
178+ {{block , Ann , [MatchExpr , {call , Ann , Fun , [IntoReduceExpr , {atom , Ann , done }]}]}, SN }.
218179
219180% % Helpers
220181
@@ -245,6 +206,53 @@ build_reduce(Ann, Clauses, InnerFun, Expr, Into, true, S) ->
245206 EnumReduceCall = build_reduce_each (Clauses , InnerExpr , NewInto , Acc , SU ),
246207 {? remote (Ann , erlang , element , [{integer , Ann , 1 }, EnumReduceCall ]), SU }.
247208
209+ build_into_reduce (Ann , Clauses , Expr , Into , Fun , false , S ) ->
210+ {Acc , SA } = build_var (Ann , S ),
211+ {ProtectedExpr , SP } = build_into_try (Ann , Expr , Fun , Acc , SA ),
212+ {build_reduce_each (Clauses , {call , Ann , Fun , [Acc , pair (Ann , cont , ProtectedExpr )]}, Into , Acc , SP ), SP };
213+ build_into_reduce (Ann , Clauses , Expr , Into , Fun , true , S ) ->
214+ % % Those variables are used only inside the anonymous function
215+ % % so we don't need to worry about returning the scope.
216+ {Acc , SA } = build_var (Ann , S ),
217+ {Value , SV } = build_var (Ann , SA ),
218+ {IntoAcc , SI } = build_var (Ann , SV ),
219+ {UniqAcc , SU } = build_var (Ann , SI ),
220+
221+ {ProtectedExpr , SP } = build_into_try (Ann , Expr , Fun , IntoAcc , SU ),
222+ NewInto = {tuple , Ann , [Into , {map , Ann , []}]},
223+ AccTuple = {tuple , Ann , [IntoAcc , UniqAcc ]},
224+ PutUniqExpr = {map , Ann , UniqAcc , [{map_field_assoc , Ann , Value , {atom , Ann , true }}]},
225+
226+ InnerExpr = {block , Ann , [
227+ {match , Ann , AccTuple , Acc },
228+ {match , Ann , Value , ProtectedExpr },
229+ {'case' , Ann , UniqAcc , [
230+ {clause , Ann , [{map , Ann , [{map_field_exact , Ann , Value , {atom , Ann , true }}]}], [], [AccTuple ]},
231+ {clause , Ann , [{map , Ann , []}], [], [{tuple , Ann , [{call , Ann , Fun , [IntoAcc , pair (Ann , cont , Value )]}, PutUniqExpr ]}]}
232+ ]}
233+ ]},
234+
235+ EnumReduceCall = build_reduce_each (Clauses , InnerExpr , NewInto , Acc , SP ),
236+ {? remote (Ann , erlang , element , [{integer , Ann , 1 }, EnumReduceCall ]), SP }.
237+
238+ build_into_try (Ann , Expr , Fun , Acc , S ) ->
239+ {Value , SV } = build_var (Ann , S ),
240+ {Kind , SK } = build_var (Ann , SV ),
241+ {Reason , SR } = build_var (Ann , SK ),
242+ {Stack , SS } = build_var (Ann , SR ),
243+
244+ {{'try' , Ann ,
245+ [Expr ],
246+ [{clause , Ann , [Value ], [], [Value ]}],
247+ [{clause , Ann ,
248+ [{tuple , Ann , [Kind , Reason , Stack ]}],
249+ [],
250+ [
251+ {call , Ann , Fun , [Acc , {atom , Ann , halt }]},
252+ ? remote (Ann , erlang , raise , [Kind , Reason , Stack ])
253+ ]}],
254+ []}, SS }.
255+
248256build_reduce_each ([{enum , Meta , Left , Right , Filters } | T ], Expr , Arg , Acc , S ) ->
249257 Ann = ? ann (Meta ),
250258 True = build_reduce_each (T , Expr , Acc , Acc , S ),
0 commit comments