anchor.diff:        end
     end.
   
  --spec add_location_field(any(), any(), map()) -> map().
  -add_location_field(Meta, Name, Location) ->
  -  case clj_rt:get(Meta, Name) of
  -    ?NIL -> Location;
  -    Value -> maps:put(Name, Value, Location)
  -  end.
  -
  +%% @doc Removes the location information from `Meta'.
   -spec remove_location(any()) -> any().
   remove_location(?NIL) ->
     ?NIL;
  
positive.code: -module(clj_reader).
  
  -include("clojerl.hrl").
  -include("clojerl_int.hrl").
  
  -export([ read_fold/4
          , read/1, read/2
          , location_meta/1
          , remove_location/1
          ]).
  
negative.code:     throw:{eof, Value, _} -> Value
    end.
  
  %% @private
  %% @doc Folds over the forms read using `Env' as the accumulator.
  %%
  %% Used by {@link clj_compiler} to process all forms from the input.
  -spec read_fold(read_fold_fun(), binary(), opts(), clj_env:env()) ->
    clj_env:env().
  read_fold(Fun, Src, Opts0, Env) ->
    %% Since we want to consume all of the source, we don't want to
    %% throw when eof is reached.
    Opts    = Opts0#{?OPT_EOF => ok},
    State   = new_state(Src, Env, Opts),
    ReadFun = read_fun(Opts),
    ok = clj_rt:reset_id(),
    read_fold_loop(Fun, ReadFun, State).
  
  %%------------------------------------------------------------------------------
  %% Internal functions
  %%------------------------------------------------------------------------------
  
  -spec add_location_field(any(), any(), map()) -> map().
  add_location_field(Meta, Name, Location) ->
    case clj_rt:get(Meta, Name) of
      ?NIL -> Location;
      Value -> maps:put(Name, Value, Location)
    end.
  
  -spec read_fun(opts()) -> function().
  read_fun(#{time := true}) ->
    fun time_read_one_fold/1;
  read_fun(_) ->
    fun read_one_fold/1.
  
  -spec time_read_one_fold(state()) -> state().
  time_read_one_fold(State0) ->
    {Delta, State1} = timer:tc(fun () -> read_one_fold(State0) end),
    #{env := Env0} = State1,
    Env1 = clj_env:time("Reader", Delta, Env0),
    State1#{env => Env1}.
  
  -spec read_one_fold(state()) -> state().
  read_one_fold(State) ->
    try read_one(State)
    catch throw:{eof, ok, State_} -> State_
    end.
  
  -spec read_fold_loop(read_fold_fun(), fun(), state()) -> clj_env:env().
  read_fold_loop(Fun, ReadFun, State0) ->
    case ReadFun(State0) of
      %% Only finish when there is no more source to consume
      #{src := <<>>, forms := [], env := Env0} ->
        Env0;
      State1 = #{forms := []} ->
        read_fold_loop(Fun, ReadFun, State1);
      State1 = #{forms := [Form], env := Env0} ->
        Env1 = Fun(Form, Env0),
        read_fold_loop(Fun, ReadFun, State1#{env => Env1, forms => []})
    end.
  
  -spec platform_features(opts() | ?NIL) -> opts().
  platform_features(#{?OPT_FEATURES := Features} = Opts) ->
  