Simplify variables bindings in environment
This commit is contained in:
parent
66413ae7fe
commit
961af8ba93
@ -43,7 +43,7 @@
|
|||||||
Op =:= 'OR' orelse
|
Op =:= 'OR' orelse
|
||||||
Op =:= 'ELEMENT')).
|
Op =:= 'ELEMENT')).
|
||||||
|
|
||||||
-record(env, { args = [], stack = [], locals = [], tailpos = true }).
|
-record(env, { vars = [], locals = [], tailpos = true }).
|
||||||
|
|
||||||
%% -- Debugging --------------------------------------------------------------
|
%% -- Debugging --------------------------------------------------------------
|
||||||
|
|
||||||
@ -95,22 +95,25 @@ function_to_scode(Name, Args, Body, ResType, Options) ->
|
|||||||
%% -- Environment functions --
|
%% -- Environment functions --
|
||||||
|
|
||||||
init_env(Args) ->
|
init_env(Args) ->
|
||||||
#env{ args = Args, stack = [], tailpos = true }.
|
#env{ vars = [ {X, {arg, I}} || {I, {X, _}} <- with_ixs(Args) ],
|
||||||
|
tailpos = true }.
|
||||||
|
|
||||||
push_env(Type, Env) ->
|
next_var(#env{ vars = Vars }) ->
|
||||||
Env#env{ stack = [Type | Env#env.stack] }.
|
1 + lists:max([-1 | [J || {_, {var, J}} <- Vars]]).
|
||||||
|
|
||||||
bind_local(Name, Env = #env{ locals = Locals }) ->
|
bind_var(Name, Var, Env = #env{ vars = Vars }) ->
|
||||||
I = length(Locals),
|
Env#env{ vars = [{Name, Var} | Vars] }.
|
||||||
{I, Env#env{ locals = [{Name, I} | Locals] }}.
|
|
||||||
|
bind_local(Name, Env) ->
|
||||||
|
I = next_var(Env),
|
||||||
|
{I, bind_var(Name, {var, I}, Env)}.
|
||||||
|
|
||||||
notail(Env) -> Env#env{ tailpos = false }.
|
notail(Env) -> Env#env{ tailpos = false }.
|
||||||
|
|
||||||
lookup_var(Env = #env{ args = Args, locals = Locals }, X) ->
|
lookup_var(Env = #env{ vars = Vars }, X) ->
|
||||||
case {lists:keyfind(X, 1, Locals), keyfind_index(X, 1, Args)} of
|
case lists:keyfind(X, 1, Vars) of
|
||||||
{false, false} -> error({unbound_variable, X, Env});
|
false -> error({unbound_variable, X, Env});
|
||||||
{false, Arg} -> {arg, Arg};
|
{_, Var} -> Var
|
||||||
{{_, Local}, _} -> {var, Local}
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% -- The compiler --
|
%% -- The compiler --
|
||||||
@ -129,9 +132,9 @@ to_scode(Env, {tuple, As}) ->
|
|||||||
[[ to_scode(Env, A) || A <- As ],
|
[[ to_scode(Env, A) || A <- As ],
|
||||||
aeb_fate_code:tuple(N)];
|
aeb_fate_code:tuple(N)];
|
||||||
|
|
||||||
to_scode(Env, {binop, Type, Op, A, B}) ->
|
to_scode(Env, {binop, _Type, Op, A, B}) ->
|
||||||
[ to_scode(notail(Env), B),
|
[ to_scode(notail(Env), B),
|
||||||
to_scode(push_env(Type, Env), A),
|
to_scode(Env, A),
|
||||||
binop_to_scode(Op) ];
|
binop_to_scode(Op) ];
|
||||||
|
|
||||||
to_scode(Env, {'if', Dec, Then, Else}) ->
|
to_scode(Env, {'if', Dec, Then, Else}) ->
|
||||||
@ -181,10 +184,8 @@ split_to_scode(_, Split = {split, _, _, _}) ->
|
|||||||
catchall_to_scode(Env, X, Alts) -> catchall_to_scode(Env, X, Alts, []).
|
catchall_to_scode(Env, X, Alts) -> catchall_to_scode(Env, X, Alts, []).
|
||||||
|
|
||||||
catchall_to_scode(Env, X, [{'case', {var, Y}, Split} | _], Acc) ->
|
catchall_to_scode(Env, X, [{'case', {var, Y}, Split} | _], Acc) ->
|
||||||
I = lookup_var(Env, X),
|
Env1 = bind_var(Y, lookup_var(Env, X), Env),
|
||||||
{J, Env1} = bind_local(Y, Env),
|
{split_to_scode(Env1, Split), lists:reverse(Acc)};
|
||||||
{[aeb_fate_code:store({var, J}, I),
|
|
||||||
split_to_scode(Env1, Split)], lists:reverse(Acc)};
|
|
||||||
catchall_to_scode(Env, X, [Alt | Alts], Acc) ->
|
catchall_to_scode(Env, X, [Alt | Alts], Acc) ->
|
||||||
catchall_to_scode(Env, X, Alts, [Alt | Acc]);
|
catchall_to_scode(Env, X, Alts, [Alt | Acc]);
|
||||||
catchall_to_scode(_, _, [], Acc) -> {missing, lists:reverse(Acc)}.
|
catchall_to_scode(_, _, [], Acc) -> {missing, lists:reverse(Acc)}.
|
||||||
@ -658,6 +659,8 @@ r_write_to_dead_var({Ann, {'STORE', R = {var, _}, A}}, Code) when A /= ?a ->
|
|||||||
false ->
|
false ->
|
||||||
case Code of
|
case Code of
|
||||||
[] -> {[], []};
|
[] -> {[], []};
|
||||||
|
[switch_body, {Ann1, I} | Code1] ->
|
||||||
|
{[], [switch_body, {merge_ann(Ann, Ann1), I} | Code1]};
|
||||||
[{Ann1, I} | Code1] ->
|
[{Ann1, I} | Code1] ->
|
||||||
{[], [{merge_ann(Ann, Ann1), I} | Code1]}
|
{[], [{merge_ann(Ann, Ann1), I} | Code1]}
|
||||||
end;
|
end;
|
||||||
@ -710,7 +713,6 @@ to_basic_blocks(Funs, Options) ->
|
|||||||
|| {Name, {{Args, Res}, Code}} <- maps:to_list(Funs) ]).
|
|| {Name, {{Args, Res}, Code}} <- maps:to_list(Funs) ]).
|
||||||
|
|
||||||
bb(_Name, Code, _Options) ->
|
bb(_Name, Code, _Options) ->
|
||||||
io:format("Code = ~p\n", [Code]),
|
|
||||||
Blocks0 = blocks(Code),
|
Blocks0 = blocks(Code),
|
||||||
Blocks = optimize_blocks(Blocks0),
|
Blocks = optimize_blocks(Blocks0),
|
||||||
Labels = maps:from_list([ {Ref, I} || {I, {Ref, _}} <- with_ixs(Blocks) ]),
|
Labels = maps:from_list([ {Ref, I} || {I, {Ref, _}} <- with_ixs(Blocks) ]),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user