66 lines
2.5 KiB
Erlang
66 lines
2.5 KiB
Erlang
-module(elixir_env).
|
|
-include("elixir.hrl").
|
|
-export([new/0, linify/1, env_to_scope/1, env_to_scope_with_vars/2]).
|
|
-export([mergea/2, mergev/2, merge_vars/2, merge_opt_vars/2]).
|
|
|
|
new() ->
|
|
#{'__struct__' => 'Elixir.Macro.Env',
|
|
module => nil, %% the current module
|
|
file => <<"nofile">>, %% the current filename
|
|
line => 1, %% the current line
|
|
function => nil, %% the current function
|
|
context => nil, %% can be match, guard or nil
|
|
requires => [], %% a set with modules required
|
|
aliases => [], %% a list of aliases by new -> old names
|
|
functions => [], %% a list with functions imported from module
|
|
macros => [], %% a list with macros imported from module
|
|
macro_aliases => [], %% keep aliases defined inside a macro
|
|
context_modules => [], %% modules defined in the current context
|
|
lexical_tracker => nil, %% holds the lexical tracker PID
|
|
vars => [], %% a set of defined variables
|
|
export_vars => nil, %% a set of variables to be exported in some constructs
|
|
prematch_vars => nil, %% a set of variables defined before the current match
|
|
match_vars => warn}. %% handling of new variables
|
|
|
|
linify({Line, Env}) ->
|
|
Env#{line := Line};
|
|
linify(#{} = Env) ->
|
|
Env.
|
|
|
|
env_to_scope(#{file := File, context := Context}) ->
|
|
#elixir_erl{file=File, context=Context}.
|
|
|
|
env_to_scope_with_vars(Env, Vars) ->
|
|
Map = maps:from_list(Vars),
|
|
(env_to_scope(Env))#elixir_erl{
|
|
vars=Map, counter=#{'_' => map_size(Map)}
|
|
}.
|
|
|
|
%% SCOPE MERGING
|
|
|
|
%% Receives two scopes and return a new scope based on the second
|
|
%% with their variables merged.
|
|
mergev(E1, E2) when is_list(E1) ->
|
|
E2#{
|
|
vars := merge_vars(E1, ?key(E2, vars)),
|
|
export_vars := merge_opt_vars(E1, ?key(E2, export_vars))
|
|
};
|
|
mergev(E1, E2) ->
|
|
E2#{
|
|
vars := merge_vars(?key(E1, vars), ?key(E2, vars)),
|
|
export_vars := merge_opt_vars(?key(E1, export_vars), ?key(E2, export_vars))
|
|
}.
|
|
|
|
%% Receives two scopes and return the later scope
|
|
%% keeping the variables from the first (imports
|
|
%% and everything else are passed forward).
|
|
|
|
mergea(E1, E2) ->
|
|
E2#{vars := ?key(E1, vars)}.
|
|
|
|
merge_vars(V1, V2) -> ordsets:union(V1, V2).
|
|
|
|
merge_opt_vars(_V1, nil) -> nil;
|
|
merge_opt_vars(nil, _V2) -> nil;
|
|
merge_opt_vars(V1, V2) -> ordsets:union(V1, V2).
|