Skip to content

Commit a94e490

Browse files
committed
Got protocols translating
1 parent 3b37cc1 commit a94e490

14 files changed

Lines changed: 411 additions & 62 deletions

File tree

lib/elixir_script.ex

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,16 @@ defmodule ElixirScript do
4343
root = Dict.get(opts, :root)
4444
env = Dict.get(opts, :env, custom_env)
4545
import_standard_libs? = Dict.get(opts, :import_standard_libs, true)
46+
use_default_protocols? = Dict.get(opts, :use_default_protocols, true)
4647

4748

4849
ElixirScript.State.start_link(root, env)
4950
build_environment([quoted])
5051

51-
if Set.size(ElixirScript.State.get().modules) > 0 do
52-
create_code(include_path, import_standard_libs?)
52+
state = ElixirScript.State.get()
53+
54+
if Set.size(state.modules) > 0 || Dict.size(state.protocols) > 0 do
55+
create_code(include_path, import_standard_libs?, use_default_protocols?)
5356
else
5457
result = case Translator.translate(quoted, env) do
5558
modules when is_list(modules) ->
@@ -97,12 +100,12 @@ defmodule ElixirScript do
97100
|> build_environment
98101

99102

100-
create_code(include_path, true)
103+
create_code(include_path, true, true)
101104
end
102105

103106
defp build_environment(code_list) do
104107
code_list
105-
|> ElixirScript.Preprocess.Modules.get_info
108+
|> ElixirScript.Preprocess.Modules.get_info
106109
end
107110

108111
defp custom_env() do
@@ -111,7 +114,12 @@ defmodule ElixirScript do
111114
__ENV__
112115
end
113116

114-
defp create_code(include_path, import_standard_libs?) do
117+
defp create_code(include_path, import_standard_libs?, use_default_protocols?) do
118+
119+
if use_default_protocols? do
120+
ElixirScript.Translator.Protocol.add_default_protocols()
121+
end
122+
115123
state = ElixirScript.State.get()
116124

117125
current = self
@@ -130,9 +138,16 @@ defmodule ElixirScript do
130138
end)
131139
|> List.flatten
132140

141+
protocol_result = state.protocols |> Dict.to_list
142+
|> ElixirScript.Translator.Protocol.consolidate(state.env)
143+
|> Enum.map(fn(x) ->
144+
convert_to_code(x, state.root, include_path, state.env, import_standard_libs?)
145+
end)
146+
|> List.flatten
147+
133148
ElixirScript.State.stop
134149

135-
result
150+
result ++ protocol_result
136151
end
137152

138153
@doc """

lib/elixir_script/preprocess/modules.ex

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@ defmodule ElixirScript.Preprocess.Modules do
1111
end)
1212
end
1313

14-
defp do_get_info({:defprotocol, _, [name, [do: {:__block__, _, spec}]]}) do
15-
State.add_protocol(name, spec)
14+
def do_get_info({:defprotocol, _, [name, [do: {:__block__, context, spec}]]}) do
15+
ElixirScript.State.add_protocol(name, {:__block__, context, spec})
1616
end
1717

18-
defp do_get_info({:defprotocol, _, [name, [do: spec]]}) do
19-
State.add_protocol(name, [spec])
18+
def do_get_info({:defprotocol, _, [name, [do: spec]]}) do
19+
ElixirScript.State.add_protocol(name, {:__block__, [], [spec]})
2020
end
2121

22-
defp do_get_info({:defimpl, _, protocol, [ [for: type], [do: {:__block__, _, spec}] ]}) do
23-
State.add_protocol_impl(protocol, type, spec)
22+
def do_get_info({:defimpl, _, [ protocol, [for: type], [do: {:__block__, context, spec}] ]}) do
23+
ElixirScript.State.add_protocol_impl(protocol, type, {:__block__, context, spec})
2424
end
2525

26-
defp do_get_info({:defimpl, _, protocol, [ [for: type], [do: spec] ]}) do
27-
State.add_protocol_impl(protocol, type, [spec])
26+
def do_get_info({:defimpl, _, [ protocol, [for: type], [do: spec] ]}) do
27+
ElixirScript.State.add_protocol_impl(protocol, type, {:__block__, [], [spec]})
2828
end
2929

30-
defp do_get_info({:defmodule, _, [{:__aliases__, meta, module_name_list}, [do: body]]} = ast) do
30+
def do_get_info({:defmodule, _, [{:__aliases__, meta, module_name_list}, [do: body]]} = ast) do
3131
body = make_inner_module_aliases(module_name_list, body)
3232

3333
functions = get_functions_from_module(body)
@@ -47,7 +47,7 @@ defmodule ElixirScript.Preprocess.Modules do
4747
ast
4848
end
4949

50-
defp do_get_info(ast) do
50+
def do_get_info(ast) do
5151
ast
5252
end
5353

lib/elixir_script/state.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ defmodule ElixirScript.State do
2525

2626
def module_listed?(module_name) do
2727
Agent.get(__MODULE__, fn(state) ->
28-
Enum.any?(state.modules, fn(x) -> x.name == module_name end)
28+
Enum.any?(state.modules, fn(x) -> x.name == module_name end) ||
29+
Enum.any?(state.protocols, fn({key, value}) -> key == module_name end)
2930
end)
3031
end
3132

lib/elixir_script/translator.ex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,14 @@ defmodule ElixirScript.Translator do
285285
Module.make_module(module_name_list, body, env)
286286
end
287287

288+
defp do_translate({:defprotocol, _, _}) do
289+
%ElixirScript.Translator.Group{}
290+
end
291+
292+
defp do_translate({:defimpl, _, _}) do
293+
%ElixirScript.Translator.Group{}
294+
end
295+
288296
defp do_translate({name, metadata, params} = ast, env) when is_list(params) do
289297
if KernelLib.is_defined_in_kernel(name, length(params)) do
290298
KernelLib.translate_kernel_function(name, params, env)

lib/elixir_script/translator/function.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ defmodule ElixirScript.Translator.Function do
7575
body = make_function_body(body, env)
7676
do_make_function_clause(patterns, params, body)
7777

78+
({_, _, [{_, _, params}]}) ->
79+
{ patterns, params } = Match.build_match(params, env)
80+
params = make_params(params)
81+
body = make_function_body([], env)
82+
do_make_function_clause(patterns, params, body)
7883
end)
7984
|> Enum.to_list
8085

lib/elixir_script/translator/module.ex

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ defmodule ElixirScript.Translator.Module do
77
alias ElixirScript.Preprocess.Aliases
88
alias ElixirScript.Preprocess.Using
99
alias ElixirScript.Translator.Function
10+
alias ElixirScript.Translator.Primitive
1011

1112
def make_module(module_name_list, nil, env) do
1213
[%JSModule{ name: module_name_list, body: List.wrap(create__module__(module_name_list, env)) }]
@@ -82,7 +83,7 @@ defmodule ElixirScript.Translator.Module do
8283
result
8384
end
8485

85-
defp extract_functions_from_module({:__block__, meta, body_list}) do
86+
def extract_functions_from_module({:__block__, meta, body_list}) do
8687
{ body_list, functions } = Enum.map_reduce(body_list,
8788
%{exported: HashDict.new(), private: HashDict.new()}, fn
8889
({:def, _, [{:when, _, [{name, _, _} | _guards] }, _] } = function, state) ->
@@ -104,7 +105,7 @@ defmodule ElixirScript.Translator.Module do
104105
{
105106
nil,
106107
%{ state | private: HashDict.put(state.private, name, HashDict.get(state.private, name, []) ++ [function]) }
107-
}
108+
}
108109
(x, state) ->
109110
{ x, state }
110111
end)
@@ -115,11 +116,11 @@ defmodule ElixirScript.Translator.Module do
115116
{ body, functions }
116117
end
117118

118-
defp extract_functions_from_module(body) do
119+
def extract_functions_from_module(body) do
119120
extract_functions_from_module({:__block__, [], List.wrap(body)})
120121
end
121122

122-
defp extract_imports_from_body(body) do
123+
def extract_imports_from_body(body) do
123124
Enum.partition(body, fn(x) ->
124125
case x do
125126
%ESTree.ImportDeclaration{} ->
@@ -130,7 +131,7 @@ defmodule ElixirScript.Translator.Module do
130131
end)
131132
end
132133

133-
defp extract_structs_from_body(body) do
134+
def extract_structs_from_body(body) do
134135
Enum.partition(body, fn(x) ->
135136
case x do
136137
%ESTree.FunctionDeclaration{} ->
@@ -154,7 +155,7 @@ defmodule ElixirScript.Translator.Module do
154155
end
155156
end
156157

157-
defp process_imports(imports, aliases) do
158+
def process_imports(imports, aliases) do
158159
imports ++ make_imports(aliases)
159160
|> Enum.reduce(HashSet.new, fn(x, acc)->
160161
HashSet.put(acc, x)
@@ -180,7 +181,7 @@ defmodule ElixirScript.Translator.Module do
180181
end)
181182
end
182183

183-
defp process_functions(%{ exported: exported, private: private }, env) do
184+
def process_functions(%{ exported: exported, private: private }, env) do
184185
exported_functions = Enum.map(Dict.keys(exported), fn(key) ->
185186
functions = Dict.get(exported, key)
186187
{ key, Function.process_function(key, functions, env) }
@@ -203,10 +204,14 @@ defmodule ElixirScript.Translator.Module do
203204
JS.variable_declaration([declarator], :const)
204205
end
205206

206-
defp create__module__(module_name_list, env) do
207+
def create__module__(module_name_list, env) do
208+
module_name = Enum.map(module_name_list, &Atom.to_string(&1))
209+
|> Enum.join(".")
210+
|> String.to_atom
211+
207212
declarator = JS.variable_declarator(
208213
JS.identifier(:__MODULE__),
209-
ElixirScript.Translator.translate(List.last(module_name_list), env)
214+
Primitive.make_atom(module_name)
210215
)
211216

212217
JS.variable_declaration([declarator], :const)

0 commit comments

Comments
 (0)