Compile maps

This commit is contained in:
Ulf Norell 2019-04-30 13:27:55 +02:00
parent cd454fb538
commit 4a8fb5ba05
2 changed files with 49 additions and 0 deletions

View File

@ -41,6 +41,10 @@
| {tuple, [fexpr()]} | {tuple, [fexpr()]}
| {proj, fexpr(), integer()} | {proj, fexpr(), integer()}
| {set_proj, fexpr(), integer(), fexpr()} %% tuple, field, new_value | {set_proj, fexpr(), integer(), fexpr()} %% tuple, field, new_value
| map_empty
| {map_set, fexpr(), fexpr(), fexpr()} % map, key, val
| {map_get, fexpr(), fexpr()} % map, key
| {map_get, fexpr(), fexpr(), fexpr()} % map, key, default
| {op, binop(), fexpr(), fexpr()} | {op, binop(), fexpr(), fexpr()}
| {op, unop(), fexpr()} | {op, unop(), fexpr()}
| {'let', var_name(), fexpr(), fexpr()} | {'let', var_name(), fexpr(), fexpr()}
@ -376,6 +380,33 @@ expr_to_fcode(Env, _Type, {app, _Ann, {Op, _}, [A]}) when is_atom(Op) ->
expr_to_fcode(Env, _Type, {app, _Ann, Fun, Args}) -> expr_to_fcode(Env, _Type, {app, _Ann, Fun, Args}) ->
{funcall, expr_to_fcode(Env, Fun), [expr_to_fcode(Env, Arg) || Arg <- Args]}; {funcall, expr_to_fcode(Env, Fun), [expr_to_fcode(Env, Arg) || Arg <- Args]};
%% Maps
expr_to_fcode(_Env, _Type, {map, _, []}) ->
map_empty;
expr_to_fcode(Env, Type, {map, Ann, KVs}) ->
%% Cheaper to do incremental map_update than building the list and doing
%% map_from_list (I think).
Fields = [{field, Ann, [{map_get, Ann, K}], V} || {K, V} <- KVs],
expr_to_fcode(Env, Type, {map, Ann, {map, Ann, []}, Fields});
expr_to_fcode(Env, _Type, {map, _, Map, KVs}) ->
X = fresh_name(),
Map1 = {var, [X]},
{'let', X, expr_to_fcode(Env, Map),
lists:foldr(fun(Fld, M) ->
case Fld of
{field, _, [{map_get, _, K}], V} ->
{map_set, M, expr_to_fcode(Env, K), expr_to_fcode(Env, V)};
{field_upd, _, [{map_get, _, K}], {typed, _, {lam, _, [{arg, _, {id, _, Z}, _}], V}, _}} ->
Y = fresh_name(),
{'let', Y, expr_to_fcode(Env, K),
{'let', Z, {map_get, Map1, {var, [Y]}},
{map_set, M, {var, [Y]}, expr_to_fcode(Env, V)}}}
end end, Map1, KVs)};
expr_to_fcode(Env, _Type, {map_get, _, Map, Key}) ->
{map_get, expr_to_fcode(Env, Map), expr_to_fcode(Env, Key)};
expr_to_fcode(Env, _Type, {map_get, _, Map, Key, Def}) ->
{map_get, expr_to_fcode(Env, Map), expr_to_fcode(Env, Key), expr_to_fcode(Env, Def)};
expr_to_fcode(_Env, Type, Expr) -> expr_to_fcode(_Env, Type, Expr) ->
error({todo, {Expr, ':', Type}}). error({todo, {Expr, ':', Type}}).

View File

@ -249,6 +249,24 @@ to_scode(Env, {op, Op, A}) ->
[ to_scode(notail(Env), A), [ to_scode(notail(Env), A),
unop_to_scode(Op) ]; unop_to_scode(Op) ];
%% Maps
to_scode(_Env, map_empty) ->
[aeb_fate_code:map_empty(?a)];
to_scode(Env, {map_set, Map, Key, Val}) ->
[to_scode(notail(Env), Val),
to_scode(notail(Env), Key),
to_scode(notail(Env), Map),
aeb_fate_code:map_update(?a, ?a, ?a, ?a)];
to_scode(Env, {map_get, Map, Key}) ->
[to_scode(notail(Env), Key),
to_scode(notail(Env), Map),
aeb_fate_code:map_lookup(?a, ?a, ?a)];
to_scode(Env, {map_get, Map, Key, Default}) ->
[to_scode(notail(Env), Default),
to_scode(notail(Env), Key),
to_scode(notail(Env), Map),
aeb_fate_code:map_lookup(?a, ?a, ?a, ?a)];
to_scode(Env, {'let', X, {var, Y}, Body}) -> to_scode(Env, {'let', X, {var, Y}, Body}) ->
Env1 = bind_var(X, lookup_var(Env, Y), Env), Env1 = bind_var(X, lookup_var(Env, Y), Env),
to_scode(Env1, Body); to_scode(Env1, Body);