Skip to content

Commit ce17aa9

Browse files
committed
Translate with/1 as a closure
1 parent 92db97e commit ce17aa9

File tree

1 file changed

+25
-33
lines changed

1 file changed

+25
-33
lines changed

lib/elixir/src/elixir_erl_pass.erl

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,15 @@ translate({for, Meta, [_ | _] = Args}, _Ann, S) ->
185185
elixir_erl_for:translate(Meta, Args, S);
186186

187187
translate({with, Meta, [_ | _] = Args}, _Ann, S) ->
188+
Ann = ?ann(Meta),
188189
{Exprs, [{do, Do} | Opts]} = elixir_utils:split_last(Args),
189-
{ElseClause, SE} = translate_with_else(Meta, Opts, S),
190-
translate_with_do(Exprs, ?ann(Meta), Do, ElseClause, SE);
190+
{ElseClause, MaybeFun, SE} = translate_with_else(Meta, Opts, S),
191+
{Case, SD} = translate_with_do(Exprs, Ann, Do, ElseClause, SE),
192+
193+
case MaybeFun of
194+
nil -> {Case, SD};
195+
FunAssign -> {{block, Ann, [FunAssign, Case]}, SD}
196+
end;
191197

192198
%% Variables
193199

@@ -400,47 +406,34 @@ returns_boolean(Condition, Body) ->
400406
%% with
401407

402408
translate_with_else(Meta, [], S) ->
403-
Generated = ?ann(?generated(Meta)),
409+
Ann = ?ann(Meta),
404410
{VarName, SC} = elixir_erl_var:build('_', S),
405-
Var = {var, Generated, VarName},
406-
{{clause, Generated, [Var], [], [Var]}, SC};
411+
Var = {var, Ann, VarName},
412+
{{clause, Ann, [Var], [], [Var]}, nil, SC};
407413
translate_with_else(Meta, [{'else', [{'->', _, [[{Var, VarMeta, Kind}], Clause]}]}], S) when is_atom(Var), is_atom(Kind) ->
408414
Ann = ?ann(Meta),
409-
Generated = erl_anno:set_generated(true, Ann),
410415
{ElseVarErl, SV} = elixir_erl_var:translate(VarMeta, Var, Kind, S#elixir_erl{context=match}),
411416
{TranslatedClause, SC} = translate(Clause, Ann, SV#elixir_erl{context=nil}),
412-
{{clause, Generated, [ElseVarErl], [], [TranslatedClause]}, SC};
417+
Clauses = [{clause, Ann, [ElseVarErl], [], [TranslatedClause]}],
418+
with_else_closure(Meta, Clauses, SC);
413419
translate_with_else(Meta, [{'else', Else}], S) ->
414420
Generated = ?generated(Meta),
415-
{ElseVarEx, ElseVarErl, SE} = elixir_erl_var:assign(Generated, S),
416-
{RaiseVar, _, SV} = elixir_erl_var:assign(Generated, SE),
421+
{RaiseVar, _, SV} = elixir_erl_var:assign(Generated, S),
417422

418423
RaiseExpr = {{'.', Generated, [erlang, error]}, Generated, [{else_clause, RaiseVar}]},
419424
RaiseClause = {'->', Generated, [[RaiseVar], RaiseExpr]},
420-
GeneratedElse = [build_generated_clause(Generated, ElseClause) || ElseClause <- Else],
421-
422-
Case = {'case', Generated, [ElseVarEx, [{do, GeneratedElse ++ [RaiseClause]}]]},
423-
{TranslatedCase, SC} = translate(Case, ?ann(Meta), SV),
424-
{{clause, ?ann(Generated), [ElseVarErl], [], [TranslatedCase]}, SC}.
425-
426-
build_generated_clause(Generated, {'->', _, [Args, Clause]}) ->
427-
NewArgs = [build_generated_clause_arg(Generated, Arg) || Arg <- Args],
428-
{'->', Generated, [NewArgs, Clause]}.
429425

430-
build_generated_clause_arg(Generated, Arg) ->
431-
{Expr, Guards} = elixir_utils:extract_guards(Arg),
432-
NewGuards = [build_generated_guard(Generated, Guard) || Guard <- Guards],
433-
concat_guards(Generated, Expr, NewGuards).
426+
Clauses = elixir_erl_clauses:get_clauses('else', [{'else', Else ++ [RaiseClause]}], match),
427+
{TranslatedClauses, SC} = elixir_erl_clauses:clauses(Clauses, SV),
428+
with_else_closure(Meta, TranslatedClauses, SC).
434429

435-
build_generated_guard(Generated, {{'.', _, _} = Call, _, Args}) ->
436-
{Call, Generated, [build_generated_guard(Generated, Arg) || Arg <- Args]};
437-
build_generated_guard(_, Expr) ->
438-
Expr.
439-
440-
concat_guards(_Meta, Expr, []) ->
441-
Expr;
442-
concat_guards(Meta, Expr, [Guard | Tail]) ->
443-
{'when', Meta, [Expr, concat_guards(Meta, Guard, Tail)]}.
430+
with_else_closure(Meta, TranslatedClauses, S) ->
431+
Ann = ?ann(Meta),
432+
{_, FunErlVar, SC} = elixir_erl_var:assign(Meta, S),
433+
{_, ArgErlVar, SA} = elixir_erl_var:assign(Meta, SC),
434+
FunAssign = {match, Ann, FunErlVar, {'fun', Ann, {clauses, TranslatedClauses}}},
435+
FunCall = {call, Ann, FunErlVar, [ArgErlVar]},
436+
{{clause, Ann, [ArgErlVar], [], [FunCall]}, FunAssign, SA}.
444437

445438
translate_with_do([{'<-', Meta, [Left, Expr]} | Rest], _Ann, Do, Else, S) ->
446439
Ann = ?ann(Meta),
@@ -449,9 +442,8 @@ translate_with_do([{'<-', Meta, [Left, Expr]} | Rest], _Ann, Do, Else, S) ->
449442
{TArgs, SA} = elixir_erl_clauses:match(Ann, fun translate/3, Args, SR),
450443
TGuards = elixir_erl_clauses:guards(Ann, Guards, SA#elixir_erl.extra_guards, SA),
451444
{TBody, SB} = translate_with_do(Rest, Ann, Do, Else, SA#elixir_erl{extra_guards=[]}),
452-
453445
Clause = {clause, Ann, [TArgs], TGuards, unblock(TBody)},
454-
{{'case', erl_anno:set_generated(true, Ann), TExpr, [Clause, Else]}, SB};
446+
{{'case', Ann, TExpr, [Clause, Else]}, SB};
455447
translate_with_do([Expr | Rest], Ann, Do, Else, S) ->
456448
{TExpr, TS} = translate(Expr, Ann, S),
457449
{TRest, RS} = translate_with_do(Rest, Ann, Do, Else, TS),

0 commit comments

Comments
 (0)