anchor.diff: +%% @doc Clojerl compilation environment.
  +%%
  +%% `clj_env:env()' holds the information for the current compilation
  +%% environment. It is used by all the compilation stages: the
  +%% `clj_reader', the `clj_analyzer' and the `clj_emitter'.
  +%%
  +%% Some examples of the information it keeps are:
  +%% <ul>
  +%%   <li>Local variables available in the current scope.</li>
  +%%   <li>Current location in the file or string being processed.</li>
  +%%   <li>Stack of expressions added by the `clj_analyzer'.</li>
  +%%   <li>... and more.</li>
  +%% </ul>
   -module(clj_env).
   
   -include("clojerl.hrl").
  
positive.code:   Times1 = Times0#{Key => T + Delta},
    put(times, Times1, Env).
  
  -spec push_expr(expr(), env()) -> env().
  push_expr(Expr, Env = #{exprs := Exprs}) ->
    Env#{exprs => [Expr | Exprs]}.
  
  -spec pop_expr(env()) -> {expr(), env()}.
  pop_expr(Env = #{exprs := [H | Exprs]}) ->
    {H, Env#{exprs => Exprs}}.
  
  -spec last_exprs(integer(), env()) -> {[any()], env()}.
  last_exprs(N, Env = #{exprs := AllExprs}) when N >= 0 ->
    Exprs = lists:sublist(AllExprs, N),
    RestExprs = lists:sublist(AllExprs, N + 1, length(AllExprs)),
    {lists:reverse(Exprs),
     Env#{exprs => RestExprs}}.
  
  -spec exprs(env()) -> [any()].
  exprs(#{exprs := AllExprs}) -> lists:reverse(AllExprs).
  
  -spec add_locals_scope(env()) -> env().
  add_locals_scope(Env = #{locals := ParentLocals}) ->
    Env#{locals => clj_scope:new(ParentLocals)}.
  
  -spec remove_locals_scope(env()) -> env().
  remove_locals_scope(Env = #{locals := Locals}) ->
    Env#{locals => clj_scope:parent(Locals)}.
  
  -spec save_locals_scope(env()) -> clj_scope:scope().
  save_locals_scope(#{locals := Locals} = Env) ->
    Env#{locals := clj_scope:new(), saved_locals := Locals}.
  
  -spec restore_locals_scope(env()) -> env().
  restore_locals_scope(#{saved_locals := LocalsCache} = Env) ->
    Env#{locals := LocalsCache, saved_locals := ?NIL}.
  
  -spec get_local('clojerl.Symbol':type(), env()) -> any().
  get_local(Sym, _Env = #{locals := Locals}) ->
    clj_scope:get(clj_rt:str(Sym), Locals).
  
  -spec get_locals(env()) -> [any()].
  get_locals(#{locals := Locals}) ->
    clj_scope:values(Locals).
  
  -spec put_local('clojerl.Symbol':type(), any(), env()) -> env().
  put_local(Sym, Local, Env = #{locals := Locals}) ->
    Env#{locals => clj_scope:put(clj_rt:str(Sym), Local, Locals)}.
  
  -spec put_locals([map()], env()) -> env().
  put_locals(Locals, Env) ->
    PutLocalFun = fun(Local, EnvAcc) ->
                      Name = maps:get(name, Local),
  
negative.code:    , mapping      => clj_scope:new()
     }.
  
  %% @doc Returns the current type of context.
  -spec context(env()) -> context().
  context(Env) -> get(context, expr, Env).
  
  %% @doc Returns the current location in the file or string.
  %%
  %% When the location is not available it returns `undefined'.
  -spec location(env()) -> ?NIL | clj_reader:location().
  location(Env) -> get(location, Env).
  
  %% @doc Returns the timing information stored by the compiler.
  %%
  %% Timing information is only stored and kept in the environment by
  %% the compiler when the user asks for a timed compilation.
  -spec time(env()) -> map().
  time(Env) ->
    get(times, #{}, Env).
  
  %% @doc Increase the time for `Key' by `Delta'.
  -spec time(any(), number(), env()) -> env().
  time(Key, Delta, Env) ->
    Times0 = get(times, #{}, Env),
  