Add fann() to def and def_u
This commit is contained in:
parent
74f0b3a2db
commit
44ec5db132
@ -63,7 +63,7 @@
|
|||||||
-type fexpr() :: {lit, flit()}
|
-type fexpr() :: {lit, flit()}
|
||||||
| nil
|
| nil
|
||||||
| {var, var_name()}
|
| {var, var_name()}
|
||||||
| {def, fun_name(), [fexpr()]}
|
| {def, fann(), fun_name(), [fexpr()]}
|
||||||
| {remote, fann(), [ftype()], ftype(), fexpr(), fun_name(), [fexpr()]}
|
| {remote, fann(), [ftype()], ftype(), fexpr(), fun_name(), [fexpr()]}
|
||||||
| {builtin, builtin(), [fexpr()]}
|
| {builtin, builtin(), [fexpr()]}
|
||||||
| {con, arities(), tag(), [fexpr()]}
|
| {con, arities(), tag(), [fexpr()]}
|
||||||
@ -80,7 +80,7 @@
|
|||||||
%% The following (unapplied top-level functions/builtins and
|
%% The following (unapplied top-level functions/builtins and
|
||||||
%% lambdas) are generated by the fcode compiler, but translated
|
%% lambdas) are generated by the fcode compiler, but translated
|
||||||
%% to closures by the lambda lifter.
|
%% to closures by the lambda lifter.
|
||||||
| {def_u, fun_name(), arity()}
|
| {def_u, fann(), fun_name(), arity()}
|
||||||
| {remote_u, fann(), [ftype()], ftype(), fexpr(), fun_name()}
|
| {remote_u, fann(), [ftype()], ftype(), fexpr(), fun_name()}
|
||||||
| {builtin_u, builtin(), arity()}
|
| {builtin_u, builtin(), arity()}
|
||||||
| {builtin_u, builtin(), arity(), [fexpr()]} %% Typerep arguments to be added after normal args.
|
| {builtin_u, builtin(), arity(), [fexpr()]} %% Typerep arguments to be added after normal args.
|
||||||
@ -652,8 +652,8 @@ expr_to_fcode(Env, _Type, {list, _, Es}) ->
|
|||||||
nil, Es);
|
nil, Es);
|
||||||
|
|
||||||
expr_to_fcode(Env, _Type, {app, _, {'..', _}, [A, B]}) ->
|
expr_to_fcode(Env, _Type, {app, _, {'..', _}, [A, B]}) ->
|
||||||
{def_u, FromTo, _} = resolve_fun(Env, ["ListInternal", "from_to"]),
|
{def_u, Ann, FromTo, _} = resolve_fun(Env, ["ListInternal", "from_to"]),
|
||||||
{def, FromTo, [expr_to_fcode(Env, A), expr_to_fcode(Env, B)]};
|
{def, Ann, FromTo, [expr_to_fcode(Env, A), expr_to_fcode(Env, B)]};
|
||||||
|
|
||||||
expr_to_fcode(Env, _Type, {list_comp, _, Yield, []}) ->
|
expr_to_fcode(Env, _Type, {list_comp, _, Yield, []}) ->
|
||||||
{op, '::', [expr_to_fcode(Env, Yield), nil]};
|
{op, '::', [expr_to_fcode(Env, Yield), nil]};
|
||||||
@ -663,8 +663,8 @@ expr_to_fcode(Env, _Type, {list_comp, As, Yield, [{comprehension_bind, Pat = {ty
|
|||||||
Bind = {lam, [Arg], expr_to_fcode(Env1, {switch, As, {typed, As, {id, As, Arg}, PatType},
|
Bind = {lam, [Arg], expr_to_fcode(Env1, {switch, As, {typed, As, {id, As, Arg}, PatType},
|
||||||
[{'case', As, Pat, [{guarded, As, [], {list_comp, As, Yield, Rest}}]},
|
[{'case', As, Pat, [{guarded, As, [], {list_comp, As, Yield, Rest}}]},
|
||||||
{'case', As, {id, As, "_"}, [{guarded, As, [], {list, As, []}}]}]})},
|
{'case', As, {id, As, "_"}, [{guarded, As, [], {list, As, []}}]}]})},
|
||||||
{def_u, FlatMap, _} = resolve_fun(Env, ["ListInternal", "flat_map"]),
|
{def_u, Ann, FlatMap, _} = resolve_fun(Env, ["ListInternal", "flat_map"]),
|
||||||
{def, FlatMap, [Bind, expr_to_fcode(Env, BindExpr)]};
|
{def, Ann, FlatMap, [Bind, expr_to_fcode(Env, BindExpr)]};
|
||||||
expr_to_fcode(Env, Type, {list_comp, As, Yield, [{comprehension_if, _, Cond}|Rest]}) ->
|
expr_to_fcode(Env, Type, {list_comp, As, Yield, [{comprehension_if, _, Cond}|Rest]}) ->
|
||||||
make_if(expr_to_fcode(Env, Cond),
|
make_if(expr_to_fcode(Env, Cond),
|
||||||
expr_to_fcode(Env, Type, {list_comp, As, Yield, Rest}),
|
expr_to_fcode(Env, Type, {list_comp, As, Yield, Rest}),
|
||||||
@ -737,7 +737,7 @@ expr_to_fcode(Env, _, {app, _, Fun = {typed, Ann, FunE, {fun_t, _, NamedArgsT, A
|
|||||||
{_, _} -> fcode_error({not_a_contract_type, Type})
|
{_, _} -> fcode_error({not_a_contract_type, Type})
|
||||||
end;
|
end;
|
||||||
{builtin_u, B, _Ar} -> builtin_to_fcode(state_layout(Env), B, FArgs);
|
{builtin_u, B, _Ar} -> builtin_to_fcode(state_layout(Env), B, FArgs);
|
||||||
{def_u, F, _Ar} -> {def, F, FArgs};
|
{def_u, Ann, F, _Ar} -> {def, Ann, F, FArgs};
|
||||||
{remote_u, Ann, RArgsT, RRetT, Ct, RFun} -> {remote, Ann, RArgsT, RRetT, Ct, RFun, FArgs};
|
{remote_u, Ann, RArgsT, RRetT, Ct, RFun} -> {remote, Ann, RArgsT, RRetT, Ct, RFun, FArgs};
|
||||||
FFun ->
|
FFun ->
|
||||||
%% FFun is a closure, with first component the function name and
|
%% FFun is a closure, with first component the function name and
|
||||||
@ -1135,7 +1135,7 @@ builtin_to_fcode(Layout, get_state, []) ->
|
|||||||
builtin_to_fcode(_Layout, require, [Cond, Msg]) ->
|
builtin_to_fcode(_Layout, require, [Cond, Msg]) ->
|
||||||
make_if(Cond, {tuple, []}, {builtin, abort, [Msg]});
|
make_if(Cond, {tuple, []}, {builtin, abort, [Msg]});
|
||||||
builtin_to_fcode(_Layout, chain_event, [Event]) ->
|
builtin_to_fcode(_Layout, chain_event, [Event]) ->
|
||||||
{def, event, [Event]};
|
{def, [], event, [Event]};
|
||||||
builtin_to_fcode(_Layout, map_delete, [Key, Map]) ->
|
builtin_to_fcode(_Layout, map_delete, [Key, Map]) ->
|
||||||
{op, map_delete, [Map, Key]};
|
{op, map_delete, [Map, Key]};
|
||||||
builtin_to_fcode(_Layout, map_member, [Key, Map]) ->
|
builtin_to_fcode(_Layout, map_member, [Key, Map]) ->
|
||||||
@ -1256,7 +1256,7 @@ lambda_lift_expr(Layout, {lam, Xs, Body}) ->
|
|||||||
FVs = free_vars({lam, Xs, Body}),
|
FVs = free_vars({lam, Xs, Body}),
|
||||||
make_closure(FVs, Xs, lambda_lift_expr(Layout, Body));
|
make_closure(FVs, Xs, lambda_lift_expr(Layout, Body));
|
||||||
lambda_lift_expr(Layout, UExpr) when element(1, UExpr) == def_u; element(1, UExpr) == builtin_u ->
|
lambda_lift_expr(Layout, UExpr) when element(1, UExpr) == def_u; element(1, UExpr) == builtin_u ->
|
||||||
[Tag, F, Ar | _] = tuple_to_list(UExpr),
|
[Tag, _, F, Ar | _] = tuple_to_list(UExpr),
|
||||||
ExtraArgs = case UExpr of
|
ExtraArgs = case UExpr of
|
||||||
{builtin_u, _, _, TypeArgs} -> TypeArgs;
|
{builtin_u, _, _, TypeArgs} -> TypeArgs;
|
||||||
_ -> []
|
_ -> []
|
||||||
@ -1265,7 +1265,7 @@ lambda_lift_expr(Layout, UExpr) when element(1, UExpr) == def_u; element(1, UExp
|
|||||||
Args = [{var, X} || X <- Xs] ++ ExtraArgs,
|
Args = [{var, X} || X <- Xs] ++ ExtraArgs,
|
||||||
Body = case Tag of
|
Body = case Tag of
|
||||||
builtin_u -> builtin_to_fcode(Layout, F, Args);
|
builtin_u -> builtin_to_fcode(Layout, F, Args);
|
||||||
def_u -> {def, F, Args}
|
def_u -> {def, [], F, Args}
|
||||||
end,
|
end,
|
||||||
make_closure([], Xs, Body);
|
make_closure([], Xs, Body);
|
||||||
lambda_lift_expr(Layout, {remote_u, Ann, ArgsT, RetT, Ct, F}) ->
|
lambda_lift_expr(Layout, {remote_u, Ann, ArgsT, RetT, Ct, F}) ->
|
||||||
@ -1281,7 +1281,7 @@ lambda_lift_expr(Layout, Expr) ->
|
|||||||
nil -> Expr;
|
nil -> Expr;
|
||||||
{var, _} -> Expr;
|
{var, _} -> Expr;
|
||||||
{closure, _, _, _} -> Expr;
|
{closure, _, _, _} -> Expr;
|
||||||
{def, D, As} -> {def, D, lambda_lift_exprs(Layout, As)};
|
{def, Ann, D, As} -> {def, Ann, D, lambda_lift_exprs(Layout, As)};
|
||||||
{builtin, B, As} -> {builtin, B, lambda_lift_exprs(Layout, As)};
|
{builtin, B, As} -> {builtin, B, lambda_lift_exprs(Layout, As)};
|
||||||
{remote, Ann, ArgsT, RetT, Ct, F, As} -> {remote, Ann, ArgsT, RetT, lambda_lift_expr(Layout, Ct), F, lambda_lift_exprs(Layout, As)};
|
{remote, Ann, ArgsT, RetT, Ct, F, As} -> {remote, Ann, ArgsT, RetT, lambda_lift_expr(Layout, Ct), F, lambda_lift_exprs(Layout, As)};
|
||||||
{con, Ar, C, As} -> {con, Ar, C, lambda_lift_exprs(Layout, As)};
|
{con, Ar, C, As} -> {con, Ar, C, lambda_lift_exprs(Layout, As)};
|
||||||
@ -1335,7 +1335,7 @@ optimize_fun(Fcode, Fun, Def = #{ body := Body0 }, Options) ->
|
|||||||
%% --- Inlining ---
|
%% --- Inlining ---
|
||||||
|
|
||||||
-spec inliner(fcode(), fun_name(), fexpr()) -> fexpr().
|
-spec inliner(fcode(), fun_name(), fexpr()) -> fexpr().
|
||||||
inliner(Fcode, Fun, {def, Fun1, Args} = E) when Fun1 /= Fun ->
|
inliner(Fcode, Fun, {def, _, Fun1, Args} = E) when Fun1 /= Fun ->
|
||||||
case should_inline(Fcode, Fun1) of
|
case should_inline(Fcode, Fun1) of
|
||||||
false -> E;
|
false -> E;
|
||||||
true -> inline(Fcode, Fun1, Args)
|
true -> inline(Fcode, Fun1, Args)
|
||||||
@ -1344,7 +1344,7 @@ inliner(_Fcode, _Fun, E) -> E.
|
|||||||
|
|
||||||
should_inline(_Fcode, _Fun1) -> false == list_to_atom("true"). %% Dialyzer
|
should_inline(_Fcode, _Fun1) -> false == list_to_atom("true"). %% Dialyzer
|
||||||
|
|
||||||
inline(_Fcode, Fun, Args) -> {def, Fun, Args}. %% TODO
|
inline(_Fcode, Fun, Args) -> {def, [], Fun, Args}. %% TODO
|
||||||
|
|
||||||
%% --- Bind subexpressions ---
|
%% --- Bind subexpressions ---
|
||||||
|
|
||||||
@ -1600,12 +1600,12 @@ read_only({set_proj, _, A, _, B}) -> read_only([A, B]);
|
|||||||
read_only({op, _, Es}) -> read_only(Es);
|
read_only({op, _, Es}) -> read_only(Es);
|
||||||
read_only({get_state, _}) -> true;
|
read_only({get_state, _}) -> true;
|
||||||
read_only({set_state, _, _, _}) -> false;
|
read_only({set_state, _, _, _}) -> false;
|
||||||
read_only({def_u, _, _}) -> true;
|
read_only({def_u, _, _, _}) -> true;
|
||||||
read_only({remote_u, _, _, _, _, _}) -> true;
|
read_only({remote_u, _, _, _, _, _}) -> true;
|
||||||
read_only({builtin_u, _, _}) -> true;
|
read_only({builtin_u, _, _}) -> true;
|
||||||
read_only({builtin_u, _, _, _}) -> true;
|
read_only({builtin_u, _, _, _}) -> true;
|
||||||
read_only({lam, _, _}) -> true;
|
read_only({lam, _, _}) -> true;
|
||||||
read_only({def, _, _}) -> false; %% TODO: purity analysis
|
read_only({def, _, _, _}) -> false; %% TODO: purity analysis
|
||||||
read_only({remote, _, _, _, _, _, _}) -> false;
|
read_only({remote, _, _, _, _, _, _}) -> false;
|
||||||
read_only({builtin, _, _}) -> false; %% TODO: some builtins are
|
read_only({builtin, _, _}) -> false; %% TODO: some builtins are
|
||||||
read_only({switch, Split}) -> read_only(Split);
|
read_only({switch, Split}) -> read_only(Split);
|
||||||
@ -1761,7 +1761,7 @@ resolve_fun(#{ fun_env := Funs, builtins := Builtin } = Env, Q) ->
|
|||||||
{not_found, not_found} -> internal_error({unbound_variable, Q});
|
{not_found, not_found} -> internal_error({unbound_variable, Q});
|
||||||
{_, {B, none}} -> builtin_to_fcode(state_layout(Env), B, []);
|
{_, {B, none}} -> builtin_to_fcode(state_layout(Env), B, []);
|
||||||
{_, {B, Ar}} -> {builtin_u, B, Ar};
|
{_, {B, Ar}} -> {builtin_u, B, Ar};
|
||||||
{{Fun, Ar}, _} -> {def_u, Fun, Ar}
|
{{Fun, Ar}, _} -> {def_u, [], Fun, Ar}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
init_fresh_names(Options) ->
|
init_fresh_names(Options) ->
|
||||||
@ -1828,8 +1828,8 @@ free_vars(Expr) ->
|
|||||||
{var, X} -> [X];
|
{var, X} -> [X];
|
||||||
{lit, _} -> [];
|
{lit, _} -> [];
|
||||||
nil -> [];
|
nil -> [];
|
||||||
{def, _, As} -> free_vars(As);
|
{def, _, _, As} -> free_vars(As);
|
||||||
{def_u, _, _} -> [];
|
{def_u, _, _, _} -> [];
|
||||||
{remote, _, _, _, Ct, _, As} -> free_vars([Ct | As]);
|
{remote, _, _, _, Ct, _, As} -> free_vars([Ct | As]);
|
||||||
{remote_u, _, _, _, Ct, _} -> free_vars(Ct);
|
{remote_u, _, _, _, Ct, _} -> free_vars(Ct);
|
||||||
{builtin, _, As} -> free_vars(As);
|
{builtin, _, As} -> free_vars(As);
|
||||||
@ -1859,8 +1859,8 @@ used_defs(Expr) ->
|
|||||||
{var, _} -> [];
|
{var, _} -> [];
|
||||||
{lit, _} -> [];
|
{lit, _} -> [];
|
||||||
nil -> [];
|
nil -> [];
|
||||||
{def, F, As} -> lists:umerge([F], used_defs(As));
|
{def, _, F, As} -> lists:umerge([F], used_defs(As));
|
||||||
{def_u, F, _} -> [F];
|
{def_u, _, F, _} -> [F];
|
||||||
{remote, _, _, _, Ct, _, As} -> used_defs([Ct | As]);
|
{remote, _, _, _, Ct, _, As} -> used_defs([Ct | As]);
|
||||||
{remote_u, _, _, _, Ct, _} -> used_defs(Ct);
|
{remote_u, _, _, _, Ct, _} -> used_defs(Ct);
|
||||||
{builtin, _, As} -> used_defs(As);
|
{builtin, _, As} -> used_defs(As);
|
||||||
@ -1890,8 +1890,8 @@ bottom_up(F, Env, Expr) ->
|
|||||||
{lit, _} -> Expr;
|
{lit, _} -> Expr;
|
||||||
nil -> Expr;
|
nil -> Expr;
|
||||||
{var, _} -> Expr;
|
{var, _} -> Expr;
|
||||||
{def, D, Es} -> {def, D, [bottom_up(F, Env, E) || E <- Es]};
|
{def, Ann, D, Es} -> {def, Ann, D, [bottom_up(F, Env, E) || E <- Es]};
|
||||||
{def_u, _, _} -> Expr;
|
{def_u, _, _, _} -> Expr;
|
||||||
{builtin, B, Es} -> {builtin, B, [bottom_up(F, Env, E) || E <- Es]};
|
{builtin, B, Es} -> {builtin, B, [bottom_up(F, Env, E) || E <- Es]};
|
||||||
{builtin_u, _, _} -> Expr;
|
{builtin_u, _, _} -> Expr;
|
||||||
{builtin_u, _, _, _} -> Expr;
|
{builtin_u, _, _, _} -> Expr;
|
||||||
@ -1948,8 +1948,8 @@ rename(Ren, Expr) ->
|
|||||||
{lit, _} -> Expr;
|
{lit, _} -> Expr;
|
||||||
nil -> nil;
|
nil -> nil;
|
||||||
{var, X} -> {var, rename_var(Ren, X)};
|
{var, X} -> {var, rename_var(Ren, X)};
|
||||||
{def, D, Es} -> {def, D, [rename(Ren, E) || E <- Es]};
|
{def, Ann, D, Es} -> {def, Ann, D, [rename(Ren, E) || E <- Es]};
|
||||||
{def_u, _, _} -> Expr;
|
{def_u, _, _, _} -> Expr;
|
||||||
{builtin, B, Es} -> {builtin, B, [rename(Ren, E) || E <- Es]};
|
{builtin, B, Es} -> {builtin, B, [rename(Ren, E) || E <- Es]};
|
||||||
{builtin_u, _, _} -> Expr;
|
{builtin_u, _, _} -> Expr;
|
||||||
{builtin_u, _, _, _} -> Expr;
|
{builtin_u, _, _, _} -> Expr;
|
||||||
@ -2148,9 +2148,9 @@ pp_fexpr(nil) ->
|
|||||||
pp_text("[]");
|
pp_text("[]");
|
||||||
pp_fexpr({var, X}) -> pp_text(X);
|
pp_fexpr({var, X}) -> pp_text(X);
|
||||||
pp_fexpr({def, Fun}) -> pp_fun_name(Fun);
|
pp_fexpr({def, Fun}) -> pp_fun_name(Fun);
|
||||||
pp_fexpr({def_u, Fun, Ar}) ->
|
pp_fexpr({def_u, _, Fun, Ar}) ->
|
||||||
pp_beside([pp_fun_name(Fun), pp_text("/"), pp_int(Ar)]);
|
pp_beside([pp_fun_name(Fun), pp_text("/"), pp_int(Ar)]);
|
||||||
pp_fexpr({def, Fun, Args}) ->
|
pp_fexpr({def, _, Fun, Args}) ->
|
||||||
pp_call(pp_fun_name(Fun), Args);
|
pp_call(pp_fun_name(Fun), Args);
|
||||||
pp_fexpr({con, _, I, []}) ->
|
pp_fexpr({con, _, I, []}) ->
|
||||||
pp_beside(pp_text("C"), pp_int(I));
|
pp_beside(pp_text("C"), pp_int(I));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user