33-include (" elixir.hrl" ).
44
55translate (Meta , Args , Return , S ) ->
6- {AccName , _ , SA } = elixir_erl_var :build ('_' , S ),
7- {VarName , _ , SV } = elixir_erl_var :build ('_' , SA ),
8-
96 Ann = ? ann (Meta ),
10- Acc = {var , Ann , AccName },
11- Var = {var , Ann , VarName },
12-
137 {Cases , [{do , Expr } | Opts ]} = elixir_utils :split_last (Args ),
148
159 {TInto , SI } =
1610 case lists :keyfind (into , 1 , Opts ) of
17- {into , Into } -> elixir_erl_pass :translate (Into , SV );
18- false when Return -> {{nil , Ann }, SV };
19- false -> {false , SV }
11+ {into , Into } -> elixir_erl_pass :translate (Into , S );
12+ false when Return -> {{nil , Ann }, S };
13+ false -> {false , S }
2014 end ,
2115
2216 TUniq = lists :keyfind (uniq , 1 , Opts ) == {uniq , true },
@@ -27,9 +21,9 @@ translate(Meta, Args, Return, S) ->
2721
2822 case comprehension_expr (TInto , TExpr ) of
2923 {inline , TIntoExpr } ->
30- {build_inline (Ann , TCases , TIntoExpr , TInto , TUniq , Var , Acc , SF ), SF };
24+ {build_inline (Ann , TCases , TIntoExpr , TInto , TUniq , SF ), SF };
3125 {into , TIntoExpr } ->
32- build_into (Ann , TCases , TIntoExpr , TInto , TUniq , Var , Acc , SF )
26+ build_into (Ann , TCases , TIntoExpr , TInto , TUniq , SF )
3327 end .
3428
3529% % In case we have no return, we wrap the expression
@@ -95,30 +89,61 @@ collect_filters([], Acc) ->
9589 {Acc , []}.
9690
9791
98- build_inline (Ann , Clauses , Expr , Into , Uniq , _Var , Acc , S ) ->
92+ build_inline (Ann , Clauses , Expr , Into , Uniq , S ) ->
9993 case not Uniq and lists :all (fun (Clause ) -> element (1 , Clause ) == bin end , Clauses ) of
10094 true -> build_comprehension (Ann , Clauses , Expr , Into );
101- false -> build_inline (Ann , Clauses , Expr , Into , Uniq , Acc , S )
95+ false -> build_inline_each (Ann , Clauses , Expr , Into , Uniq , S )
10296 end .
10397
104- build_inline (Ann , Clauses , Expr , false , Uniq , Acc , S ) ->
98+ build_inline_each (Ann , Clauses , Expr , false , Uniq , S ) ->
10599 InnerFun = fun (InnerExpr , _InnerAcc ) -> InnerExpr end ,
106- build_reduce (Ann , Clauses , InnerFun , Expr , {nil , Ann }, Uniq , Acc , S );
107- build_inline (Ann , Clauses , Expr , {nil , _ } = Into , Uniq , Acc , S ) ->
100+ build_reduce (Ann , Clauses , InnerFun , Expr , {nil , Ann }, Uniq , S );
101+ build_inline_each (Ann , Clauses , Expr , {nil , _ } = Into , Uniq , S ) ->
108102 InnerFun = fun (InnerExpr , InnerAcc ) -> {cons , Ann , InnerExpr , InnerAcc } end ,
109- ReduceExpr = build_reduce (Ann , Clauses , InnerFun , Expr , Into , Uniq , Acc , S ),
103+ ReduceExpr = build_reduce (Ann , Clauses , InnerFun , Expr , Into , Uniq , S ),
110104 elixir_erl :remote (Ann , lists , reverse , [ReduceExpr ]);
111- build_inline (Ann , Clauses , Expr , {bin , _ , _ } = Into , Uniq , Acc , S ) ->
112- InnerFun = fun (InnerExpr , InnerAcc ) -> {cons , Ann , InnerAcc , InnerExpr } end ,
113- ReduceExpr = build_reduce (Ann , Clauses , InnerFun , Expr , Into , Uniq , Acc , S ),
105+ build_inline_each (Ann , Clauses , Expr , {bin , _ , []}, Uniq , S ) ->
106+ {InnerValue , SV } = build_var (Ann , S ),
107+
108+ InnerFun = fun (InnerExpr , InnerAcc ) ->
109+ {'case' , Ann , InnerExpr , [
110+ {clause , Ann ,
111+ [InnerValue ],
112+ [[elixir_erl :remote (Ann , erlang , is_binary , [InnerValue ]),
113+ elixir_erl :remote (Ann , erlang , is_list , [InnerAcc ])]],
114+ [{cons , Ann , InnerAcc , InnerValue }]},
115+ {clause , Ann ,
116+ [InnerValue ],
117+ [[elixir_erl :remote (Ann , erlang , is_bitstring , [InnerValue ]),
118+ elixir_erl :remote (Ann , erlang , is_bitstring , [InnerAcc ])]],
119+ [{bin , Ann , [
120+ {bin_element , Ann , InnerAcc , default , [bitstring ]},
121+ {bin_element , Ann , InnerValue , default , [bitstring ]}
122+ ]}]},
123+ {clause , Ann ,
124+ [InnerValue ],
125+ [[elixir_erl :remote (Ann , erlang , is_bitstring , [InnerValue ])]],
126+ [{bin , Ann , [
127+ {bin_element , Ann , elixir_erl :remote (Ann , erlang , iolist_to_binary , [InnerAcc ]), default , [bitstring ]},
128+ {bin_element , Ann , InnerValue , default , [bitstring ]}
129+ ]}]},
130+ {clause , Ann ,
131+ [InnerValue ],
132+ [],
133+ [elixir_erl :remote (Ann , erlang , error , [{tuple , Ann , [{atom , Ann , badarg }, InnerValue ]}])]}
134+ ]}
135+ end ,
136+
137+ ReduceExpr = build_reduce (Ann , Clauses , InnerFun , Expr , {nil , Ann }, Uniq , SV ),
114138 elixir_erl :remote (Ann , erlang , iolist_to_binary , [ReduceExpr ]).
115139
116- build_into (Ann , Clauses , Expr , {map , _ , []}, Uniq , _Var , Acc , S ) ->
117- ReduceExpr = build_inline (Ann , Clauses , Expr , {nil , Ann }, Uniq , Acc , S ),
140+ build_into (Ann , Clauses , Expr , {map , _ , []}, Uniq , S ) ->
141+ ReduceExpr = build_inline_each (Ann , Clauses , Expr , {nil , Ann }, Uniq , S ),
118142 {elixir_erl :remote (Ann , maps , from_list , [ReduceExpr ]), S };
119-
120- build_into (Ann , Clauses , Expr , Into , Uniq , Fun , Acc , S ) ->
121- {Kind , SK } = build_var (Ann , S ),
143+ build_into (Ann , Clauses , Expr , Into , Uniq , S ) ->
144+ {Fun , SF } = build_var (Ann , S ),
145+ {Acc , SA } = build_var (Ann , SF ),
146+ {Kind , SK } = build_var (Ann , SA ),
122147 {Reason , SR } = build_var (Ann , SK ),
123148 {Stack , ST } = build_var (Ann , SR ),
124149 {Done , SD } = build_var (Ann , ST ),
@@ -132,7 +157,7 @@ build_into(Ann, Clauses, Expr, Into, Uniq, Fun, Acc, S) ->
132157 elixir_erl :remote (Ann , 'Elixir.Collectable' , into , [Into ])
133158 },
134159
135- IntoReduceExpr = build_reduce (Ann , Clauses , InnerFun , Expr , Acc , Uniq , Acc , SD ),
160+ IntoReduceExpr = build_reduce (Ann , Clauses , InnerFun , Expr , Acc , Uniq , SD ),
136161
137162 TryExpr =
138163 {'try' , Ann ,
@@ -153,12 +178,14 @@ build_into(Ann, Clauses, Expr, Into, Uniq, Fun, Acc, S) ->
153178
154179% % Helpers
155180
156- build_reduce (_Ann , Clauses , InnerFun , Expr , Into , false , Acc , S ) ->
157- build_reduce_each (Clauses , InnerFun (Expr , Acc ), Into , Acc , S );
158- build_reduce (Ann , Clauses , InnerFun , Expr , Into , true , Acc , S ) ->
181+ build_reduce (Ann , Clauses , InnerFun , Expr , Into , false , S ) ->
182+ {Acc , SA } = build_var (Ann , S ),
183+ build_reduce_each (Clauses , InnerFun (Expr , Acc ), Into , Acc , SA );
184+ build_reduce (Ann , Clauses , InnerFun , Expr , Into , true , S ) ->
159185 % % Those variables are used only inside the anonymous function
160186 % % so we don't need to worry about returning the scope.
161- {Value , SV } = build_var (Ann , S ),
187+ {Acc , SA } = build_var (Ann , S ),
188+ {Value , SV } = build_var (Ann , SA ),
162189 {IntoAcc , SI } = build_var (Ann , SV ),
163190 {UniqAcc , SU } = build_var (Ann , SI ),
164191
@@ -302,12 +329,12 @@ join_filter(Ann, {nil, Filter}, True, False) ->
302329 {clause , Ann , [{atom , Ann , false }], [], [False ]}
303330 ]};
304331join_filter (Ann , {Var , Filter }, True , False ) ->
305- Guard =
306- {op , Ann , 'orelse' ,
307- {op , Ann , '==' , Var , {atom , Ann , false }},
308- { op , Ann , '==' , Var , { atom , Ann , nil }}} ,
332+ Guards = [
333+ [ {op , Ann , '==' , Var , { atom , Ann , false }}] ,
334+ [ {op , Ann , '==' , Var , {atom , Ann , nil }}]
335+ ] ,
309336
310337 {'case' , Ann , Filter , [
311- {clause , Ann , [Var ], [[ Guard ]] , [False ]},
338+ {clause , Ann , [Var ], Guards , [False ]},
312339 {clause , Ann , [{var , Ann , '_' }], [], [True ]}
313340 ]}.
0 commit comments