diff --git a/src/aeso_ast_to_fcode.erl b/src/aeso_ast_to_fcode.erl index 20d08b1..b80e481 100644 --- a/src/aeso_ast_to_fcode.erl +++ b/src/aeso_ast_to_fcode.erl @@ -87,7 +87,7 @@ | {lam, fann(), [var_name()], fexpr()}. -type fsplit() :: {split, ftype(), var_name(), [fcase()]} - | {nosplit, fexpr()}. + | {nosplit, [rename()], fexpr()}. %% Renames are needed to add DBG_DEF for switch pattern vars -type fcase() :: {'case', fsplit_pat(), fsplit()}. @@ -821,8 +821,8 @@ expr_to_fcode(_Env, Type, Expr) -> -spec make_if(fexpr(), fexpr(), fexpr()) -> fexpr(). make_if({var, FAnn, X}, Then, Else) -> {switch, FAnn, {split, boolean, X, - [{'case', {bool, false}, {nosplit, Else}}, - {'case', {bool, true}, {nosplit, Then}}]}}; + [{'case', {bool, false}, {nosplit, [], Else}}, + {'case', {bool, true}, {nosplit, [], Then}}]}}; make_if(Cond, Then, Else) -> X = fresh_name(), FAnn = get_fann(Cond), @@ -831,7 +831,7 @@ make_if(Cond, Then, Else) -> -spec make_if_no_else(fexpr(), fexpr()) -> fexpr(). make_if_no_else({var, FAnn, X}, Then) -> {switch, FAnn, {split, boolean, X, - [{'case', {bool, true}, {nosplit, Then}}]}}; + [{'case', {bool, true}, {nosplit, [], Then}}]}}; make_if_no_else(Cond, Then) -> X = fresh_name(), FAnn = get_fann(Cond), @@ -927,7 +927,7 @@ split_tree(Env, Vars, Alts = [{'case', Pats, Body} | _]) -> Ys = [ Y || {var, Y} <- Pats ], Ren = [ {Y, X} || {Y, X} <- lists:zip(Ys, Xs), X /= Y, Y /= "_" ], %% TODO: Unreachable clauses error - {nosplit, rename(Ren, Body)}; + {nosplit, Ren, rename(Ren, Body)}; I when is_integer(I) -> {Vars0, [{X, Type} | Vars1]} = lists:split(I - 1, Vars), Type1 = strip_singleton_tuples(Type), @@ -1123,8 +1123,8 @@ decision_tree_to_fcode({atom, B}) -> B; decision_tree_to_fcode({'if', A, Then, Else}) -> X = fresh_name(), {'let', get_fann(A), X, A, - {switch, get_fann(A), {split, boolean, X, [{'case', {bool, false}, {nosplit, decision_tree_to_fcode(Else)}}, - {'case', {bool, true}, {nosplit, decision_tree_to_fcode(Then)}}]}}}. + {switch, get_fann(A), {split, boolean, X, [{'case', {bool, false}, {nosplit, [], decision_tree_to_fcode(Else)}}, + {'case', {bool, true}, {nosplit, [], decision_tree_to_fcode(Then)}}]}}}. %% -- Statements -- @@ -1262,7 +1262,7 @@ event_function(_Env = #{event_type := {variant_t, EventCons}}, EventType = {vari end, Indices = [ {var, [], V} || {indexed, V} <- IVars ], Body = {builtin, [], chain_event, [Payload, Hash | Indices]}, - {'case', {con, [], Arities, Tag, Vars}, {nosplit, Body}} + {'case', {con, [], Arities, Tag, Vars}, {nosplit, [], Body}} end, #{ attrs => [private], args => [{"e", EventType}], @@ -1369,7 +1369,7 @@ lambda_lift_expr(Layout, Expr) -> {get_state, _, _} -> Expr; {switch, FAnn, S} -> {switch, FAnn, lambda_lift_expr(Layout, S)}; {split, Type, X, Alts} -> {split, Type, X, lambda_lift_exprs(Layout, Alts)}; - {nosplit, A} -> {nosplit, lambda_lift_expr(Layout, A)}; + {nosplit, Rens, A} -> {nosplit, Rens, lambda_lift_expr(Layout, A)}; {'case', P, S} -> {'case', P, lambda_lift_expr(Layout, S)} end. @@ -1601,12 +1601,12 @@ add_catchalls(Alts, Catchalls) -> end. -spec nest_catchalls([fcase()]) -> fcase(). -nest_catchalls([C = {'case', {var, _}, {nosplit, _}} | _]) -> C; +nest_catchalls([C = {'case', {var, _}, {nosplit, _, _}} | _]) -> C; nest_catchalls([{'case', P = {var, _}, {split, Type, X, Alts}} | Catchalls]) -> {'case', P, {split, Type, X, add_catchalls(Alts, Catchalls)}}. -spec simpl_switch(expr_env(), fann(), [fcase()], fsplit()) -> fexpr() | nomatch. -simpl_switch(_Env, _FAnn, _, {nosplit, E}) -> E; +simpl_switch(_Env, _FAnn, _, {nosplit, _, E}) -> E; simpl_switch(Env, FAnn, Catchalls, {split, Type, X, Alts}) -> Alts1 = add_catchalls(Alts, Catchalls), Stuck = {switch, FAnn, {split, Type, X, Alts1}}, @@ -1708,7 +1708,7 @@ read_only({remote, _, _, _, _, _, _}) -> false; read_only({builtin, _, _, _}) -> false; %% TODO: some builtins are read_only({switch, _, Split}) -> read_only(Split); read_only({split, _, _, Cases}) -> read_only(Cases); -read_only({nosplit, E}) -> read_only(E); +read_only({nosplit, _, E}) -> read_only(E); read_only({'case', _, Split}) -> read_only(Split); read_only({'let', _, _, A, B}) -> read_only([A, B]); read_only({funcall, _, _, _}) -> false; @@ -1960,7 +1960,7 @@ free_vars(Expr) -> {closure, _, _, A} -> free_vars(A); {switch, _, A} -> free_vars(A); {split, _, X, As} -> free_vars([{var, [], X} | As]); - {nosplit, A} -> free_vars(A); + {nosplit, _, A} -> free_vars(A); {'case', P, A} -> free_vars(A) -- lists:sort(fsplit_pat_vars(P)) end. @@ -1992,7 +1992,7 @@ used_defs(Expr) -> {closure, _, F, A} -> lists:umerge([F], used_defs(A)); {switch, _, A} -> used_defs(A); {split, _, _, As} -> used_defs(As); - {nosplit, A} -> used_defs(A); + {nosplit, _, A} -> used_defs(A); {'case', _, A} -> used_defs(A) end. @@ -2040,7 +2040,7 @@ bottom_up(F, Env, Expr) -> {'let', FAnn, X, E1, bottom_up(F, Env1, Body)} end; {split, Type, X, Cases} -> {split, Type, X, [bottom_up(F, Env, Case) || Case <- Cases]}; - {nosplit, E} -> {nosplit, bottom_up(F, Env, E)}; + {nosplit, Rens, E} -> {nosplit, Rens, bottom_up(F, Env, E)}; {'case', Pat, Split} -> {'case', Pat, bottom_up(F, Env, Split)} end). @@ -2164,7 +2164,7 @@ rename_spat(Ren, {assign, X, P}) -> -spec rename_split(rename(), fsplit()) -> fsplit(). rename_split(Ren, {split, Type, X, Cases}) -> {split, Type, rename_var(Ren, X), [rename_case(Ren, C) || C <- Cases]}; -rename_split(Ren, {nosplit, E}) -> {nosplit, rename(Ren, E)}. +rename_split(Ren, {nosplit, Rens, E}) -> {nosplit, Rens, rename(Ren, E)}. -spec rename_case(rename(), fcase()) -> fcase(). rename_case(Ren, {'case', Pat, Split}) -> @@ -2406,7 +2406,7 @@ pp_ftype({variant, Cons}) -> end || {I, Args} <- indexed(Cons)])). -spec pp_split(fsplit()) -> prettypr:document(). -pp_split({nosplit, E}) -> pp_fexpr(E); +pp_split({nosplit, _, E}) -> pp_fexpr(E); pp_split({split, Type, X, Alts}) -> pp_above([pp_beside([pp_text("switch("), pp_text(X), pp_text(" : "), pp_ftype(Type), pp_text(")")])] ++ [prettypr:nest(2, pp_case(Alt)) || Alt <- Alts]). diff --git a/src/aeso_fcode_to_fate.erl b/src/aeso_fcode_to_fate.erl index 843ea39..0767446 100644 --- a/src/aeso_fcode_to_fate.erl +++ b/src/aeso_fcode_to_fate.erl @@ -334,13 +334,13 @@ to_scode1(Env, {op, Ann, Op, Args}) -> to_scode1(Env, {'let', Ann, X, {var, _, Y}, Body}) -> Env1 = bind_var(X, lookup_var(Env, Y), Env), - [ dbg_loc(Env, Ann) | dbg_scoped_var(Env1, X, to_scode(Env1, Body)) ]; + [ dbg_loc(Env, Ann) | dbg_scoped_vars(Env1, [X], to_scode(Env1, Body)) ]; to_scode1(Env, {'let', Ann, X, Expr, Body}) -> {I, Env1} = bind_local(X, Env), SCode = [ to_scode(notail(Env), Expr), aeb_fate_ops:store({var, I}, {stack, 0}), to_scode(Env1, Body) ], - [ dbg_loc(Env, Ann) | dbg_scoped_var(Env1, X, SCode) ]; + [ dbg_loc(Env, Ann) | dbg_scoped_vars(Env1, [X], SCode) ]; to_scode1(Env = #env{ current_function = Fun, tailpos = true, debug_info = false }, {def, Ann, Fun, Args}) -> %% Tail-call to current function, f(e0..en). Compile to @@ -409,8 +409,8 @@ to_scode1(Env, {switch, Ann, Case}) -> local_call( Env = #env{debug_info = false}, Fun) when Env#env.tailpos -> aeb_fate_ops:call_t(Fun); local_call(_Env, Fun) -> aeb_fate_ops:call(Fun). -split_to_scode(Env, {nosplit, Expr}) -> - [switch_body, to_scode(Env, Expr)]; +split_to_scode(Env, {nosplit, Renames, Expr}) -> + [switch_body, dbg_scoped_vars(Env, Renames, to_scode(Env, Expr))]; split_to_scode(Env, {split, {tuple, _}, X, Alts}) -> {Def, Alts1} = catchall_to_scode(Env, X, Alts), Arg = lookup_var(Env, X), @@ -760,20 +760,20 @@ dbg_scoped_vars(#env{debug_info = false}, _, SCode) -> SCode; dbg_scoped_vars(_Env, [], SCode) -> SCode; -dbg_scoped_vars(Env, [Var | Rest], SCode) -> - dbg_scoped_vars(Env, Rest, dbg_scoped_var(Env, Var, SCode)). +dbg_scoped_vars(Env, [{SavedVarName, Var} | Rest], SCode) -> + dbg_scoped_vars(Env, Rest, dbg_scoped_var(Env, SavedVarName, Var, SCode)); +dbg_scoped_vars(Env = #env{saved_fresh_names = SavedFreshNames}, [Var | Rest], SCode) -> + SavedVarName = maps:get(Var, SavedFreshNames, Var), + dbg_scoped_vars(Env, Rest, dbg_scoped_var(Env, SavedVarName, Var, SCode)). -dbg_scoped_var(#env{debug_info = false}, _, SCode) -> - SCode; -dbg_scoped_var(Env = #env{saved_fresh_names = SavedFreshNames}, Var, SCode) -> - VarName = maps:get(Var, SavedFreshNames, Var), - case VarName == "_" orelse is_fresh_name(VarName) of +dbg_scoped_var(Env, SavedVarName, Var, SCode) -> + case SavedVarName == "_" orelse is_fresh_name(SavedVarName) of true -> SCode; false -> Register = lookup_var(Env, Var), - Def = [{'DBG_DEF', {immediate, VarName}, Register}], - Undef = [{'DBG_UNDEF', {immediate, VarName}, Register}], + Def = [{'DBG_DEF', {immediate, SavedVarName}, Register}], + Undef = [{'DBG_UNDEF', {immediate, SavedVarName}, Register}], Def ++ dbg_undef(Undef, SCode) end.