Make module compilation work with elixir expressions

This commit is contained in:
José Valim
2013-11-22 21:41:59 +01:00
parent ffcde49975
commit c2243e2c28
3 changed files with 39 additions and 18 deletions
+18
View File
@@ -36,6 +36,24 @@
functions %% a list with functions imported from module
}).
-record(elixir_env, {
module=nil,
file=nil,
line=nil,
function=nil,
context=nil,
requires,
aliases,
functions,
macros,
macro_aliases=[],
macro_functions=[],
macro_macros=[],
context_modules=[],
vars=[],
lexical_tracker=nil
}).
-record(elixir_quote, {
line=nil,
context=nil,
+2 -2
View File
@@ -95,8 +95,8 @@ translate({defmodule, Meta, [Ref, KV]}, S) when is_list(KV) ->
{ TRef, S }
end,
MS = FS#elixir_scope{local=nil},
{ elixir_module:translate(Meta, FRef, Block, MS), FS };
Env = elixir_scope:to_ex_env({ ?line(Meta), FS }),
translate_each(elixir_module:translate(Ref, Block, Env), FS);
translate({Kind, Meta, [Call]}, S) when ?defs(Kind) ->
translate({Kind, Meta, [Call, nil]}, S);
+19 -16
View File
@@ -1,5 +1,5 @@
-module(elixir_module).
-export([translate/4, compile/5, data_table/1, docs_table/1,
-export([translate/3, compile/4, data_table/1, docs_table/1,
eval_quoted/4, format_error/1, eval_callbacks/5]).
-include("elixir.hrl").
@@ -42,21 +42,29 @@ docs_table(Module) ->
%% The abstract form for extra arguments may be given and they
%% will be passed to the invoked function.
translate(Meta, Ref, Block, S) ->
Line = ?line(Meta),
LexS = case S#elixir_scope.function of
nil -> S;
_ -> S#elixir_scope{lexical_tracker=nil}
translate(Ref, Block, ExEnv) ->
Env = elixir_env:from_ex(ExEnv),
%% In case we are generating a module from inside a function,
%% we get rid of the lexical tracker information as, at this
%% point, the lexical tracker process is long gone.
LexEnv = case Env#elixir_env.function of
nil -> Env;
_ -> Env#elixir_env{lexical_tracker=nil}
end,
MetaBlock = elixir_utils:elixir_to_erl(Line, Block, LexS),
{ MetaS, Vars } = elixir_scope:serialize_with_vars(Line, LexS),
{ Escaped, _ } = elixir_quote:escape(Block, false),
{ QuotedEnv, QuotedVars } = elixir_env:to_quote_with_vars(LexEnv),
Args = [{integer, Line, Line}, Ref, MetaBlock, Vars, MetaS],
?wrap_call(Line, ?MODULE, compile, Args).
Args = [Ref, Escaped, QuotedVars, QuotedEnv],
{ { '.', [], [elixir_module, compile] }, [], Args }.
%% The compilation hook.
compile(Module, Block, Vars, #elixir_env{line=Line} = Env) ->
Dict = [{ { Name, Kind }, Value } || { Name, Kind, Value, _ } <- Vars],
compile(Line, Module, Block, Vars, elixir_env:to_scope_with_vars(Env, Dict)).
compile(Line, Module, Block, Vars, #elixir_scope{context_modules=FileModules} = RawS) when is_atom(Module) ->
C = elixir_compiler:get_opts(),
S = case lists:member(Module, FileModules) of
@@ -106,12 +114,7 @@ compile(Line, Module, Block, Vars, #elixir_scope{context_modules=FileModules} =
end;
compile(Line, Other, _Block, _Vars, #elixir_scope{file=File}) ->
elixir_errors:form_error(Line, File, ?MODULE, { invalid_module, Other });
compile(Line, Module, Block, Vars, RawS) ->
Dict = [{ { Name, Kind }, Value } || { Name, Kind, Value, _ } <- Vars],
S = elixir_scope:deserialize_with_vars(RawS, Dict),
compile(Line, Module, Block, Vars, S).
elixir_errors:form_error(Line, File, ?MODULE, { invalid_module, Other }).
%% Hook that builds both attribute and functions and set up common hooks.