Basic tuple patterns

This commit is contained in:
Ulf Norell 2019-04-01 16:04:59 +02:00
parent 216fbc6144
commit d37ef8cec2
2 changed files with 35 additions and 6 deletions

View File

@ -33,9 +33,10 @@
| {'if', fexpr(), fexpr(), fexpr()} | {'if', fexpr(), fexpr(), fexpr()}
| {switch, fexpr(), [falt()]}. | {switch, fexpr(), [falt()]}.
-type fpat() :: {var, var_name()}. -type fpat() :: {var, var_name()}
| {tuple, [fpat()]}.
-type falt() :: {fpat(), fexpr()}. -type falt() :: {'case', fpat(), fexpr()}.
-type ftype() :: aeb_fate_data:fate_type_type(). -type ftype() :: aeb_fate_data:fate_type_type().
@ -151,6 +152,8 @@ type_to_fcode(Env, {app_t, T = {Id, _, _}, Types}) when Id == id; Id == qid ->
lookup_type(Env, T, [type_to_fcode(Env, Type) || Type <- Types]); lookup_type(Env, T, [type_to_fcode(Env, Type) || Type <- Types]);
type_to_fcode(Env, T = {Id, _, _}) when Id == id; Id == qid -> type_to_fcode(Env, T = {Id, _, _}) when Id == id; Id == qid ->
lookup_type(Env, T, []); lookup_type(Env, T, []);
type_to_fcode(Env, {tuple_t, _, Types}) ->
{tuple, [type_to_fcode(Env, T) || T <- Types]};
type_to_fcode(_Env, Type) -> type_to_fcode(_Env, Type) ->
{todo, Type}. {todo, Type}.
@ -179,6 +182,11 @@ expr_to_fcode(Env, _Type, {'if', _, Cond, Then, Else}) ->
expr_to_fcode(Env, Then), expr_to_fcode(Env, Then),
expr_to_fcode(Env, Else)}; expr_to_fcode(Env, Else)};
%% Switch
expr_to_fcode(Env, _Type, {switch, _, Expr, Alts}) ->
{switch, expr_to_fcode(Env, Expr),
[ alt_to_fcode(Env, Alt) || Alt <- Alts ]};
%% Blocks %% Blocks
expr_to_fcode(Env, _Type, {block, _, Stmts}) -> expr_to_fcode(Env, _Type, {block, _, Stmts}) ->
stmts_to_fcode(Env, Stmts); stmts_to_fcode(Env, Stmts);
@ -193,6 +201,10 @@ expr_to_fcode(_Env, Type, Expr) ->
binop_to_fcode(Op) when Op == '+'; Op == '-'; Op == '==' -> Op. binop_to_fcode(Op) when Op == '+'; Op == '-'; Op == '==' -> Op.
-spec alt_to_fcode(env(), aeso_syntax:alt()) -> falt().
alt_to_fcode(Env, {'case', _, Pat, Expr}) ->
{'case', pat_to_fcode(Env, Pat), expr_to_fcode(Env, Expr)}.
-spec pat_to_fcode(env(), aeso_syntax:pattern()) -> fpat(). -spec pat_to_fcode(env(), aeso_syntax:pattern()) -> fpat().
pat_to_fcode(Env, {typed, _, Pat, Type}) -> pat_to_fcode(Env, {typed, _, Pat, Type}) ->
pat_to_fcode(Env, type_to_fcode(Env, Type), Pat); pat_to_fcode(Env, type_to_fcode(Env, Type), Pat);
@ -201,6 +213,8 @@ pat_to_fcode(Env, Pat) ->
-spec pat_to_fcode(env(), ftype() | no_type, aeso_syntax:pattern()) -> fpat(). -spec pat_to_fcode(env(), ftype() | no_type, aeso_syntax:pattern()) -> fpat().
pat_to_fcode(_Env, _Type, {id, _, X}) -> {var, X}; pat_to_fcode(_Env, _Type, {id, _, X}) -> {var, X};
pat_to_fcode(Env, _Type, {tuple, _, Pats}) ->
{tuple, [ pat_to_fcode(Env, Pat) || Pat <- Pats ]};
pat_to_fcode(_Env, Type, Pat) -> {todo, Pat, ':', Type}. pat_to_fcode(_Env, Type, Pat) -> {todo, Pat, ':', Type}.
-spec stmts_to_fcode(env(), [aeso_syntax:stmt()]) -> fexpr(). -spec stmts_to_fcode(env(), [aeso_syntax:stmt()]) -> fexpr().

View File

@ -56,7 +56,11 @@ compile(ICode, Options) ->
SFuns = functions_to_scode(Functions, Options), SFuns = functions_to_scode(Functions, Options),
SFuns1 = optimize_scode(SFuns, Options), SFuns1 = optimize_scode(SFuns, Options),
BBFuns = to_basic_blocks(SFuns1, Options), BBFuns = to_basic_blocks(SFuns1, Options),
#{ functions => BBFuns }. FateCode = #{ functions => BBFuns,
symbols => #{},
annotations => #{} },
debug(Options, "~s\n", [aeb_fate_asm:pp(FateCode)]),
FateCode.
make_function_name(init) -> <<"init">>; make_function_name(init) -> <<"init">>;
make_function_name({entrypoint, Name}) -> Name; make_function_name({entrypoint, Name}) -> Name;
@ -123,10 +127,22 @@ to_scode(Env, {switch, Expr, Alts}) ->
to_scode(_Env, Icode) -> ?TODO(Icode). to_scode(_Env, Icode) -> ?TODO(Icode).
alts_to_scode(Env, [{{var, X}, Body}]) -> alts_to_scode(Env, [{'case', {var, X}, Body}]) ->
{I, Env1} = bind_local(X, Env), {I, Env1} = bind_local(X, Env),
[ aeb_fate_code:store({var, I}, {stack, 0}), [ aeb_fate_code:store({var, I}, {stack, 0}),
to_scode(Env1, Body) ]; to_scode(Env1, Body) ];
alts_to_scode(Env, Alts = [{'case', {tuple, Pats}, Body}]) ->
Xs = lists:flatmap(fun({var, X}) -> [X]; (_) -> [] end, Pats),
case length(Xs) == length(Pats) of
false -> ?TODO(Alts);
true ->
{Is, Env1} = lists:foldl(fun(X, {Is, E}) -> {I, E1} = bind_local(X, E), {[I|Is], E1} end,
{[], Env}, Xs),
[ [[aeb_fate_code:dup(),
aeb_fate_code:element_op({var, X}, ?i(J), ?a)]
|| {J, X} <- with_ixs(lists:reverse(Is))],
to_scode(Env1, Body) ]
end;
alts_to_scode(_Env, Alts) -> alts_to_scode(_Env, Alts) ->
?TODO(Alts). ?TODO(Alts).
@ -201,12 +217,11 @@ to_basic_blocks(Funs, Options) ->
bb(Name, Code ++ [aeb_fate_code:return()], Options)}} bb(Name, Code ++ [aeb_fate_code:return()], 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) ->
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) ]),
BBs = [ set_labels(Labels, B) || B <- Blocks ], BBs = [ set_labels(Labels, B) || B <- Blocks ],
debug(Options, "Final code for ~s:\n ~p\n", [Name, BBs]),
maps:from_list(BBs). maps:from_list(BBs).
%% -- Break up scode into basic blocks -- %% -- Break up scode into basic blocks --