Skip to content

Commit 381bdeb

Browse files
committed
Lots of refactoring to make the code simpler and cleaner
1 parent 2dff85f commit 381bdeb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+1376
-2641
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
* `__ENV__` and `__CALLER__` are now supported
66
* Began writing some of the standard libraries in Elixir instead of JavaScript
77

8+
* Breaking
9+
* `compile`, `compile_path`, and `compile_quoted` opts parameter now expects a map
10+
811
# v0.14.1
912
* Enhancements
1013
* Removed .DS_Store and LICENSE from output

GettingStarted.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,16 @@ The intent of this guide is to get you started with ElixirScript. It will give y
4444
4545
```bash
4646
$ elixirscript ":atom" -ex
47-
Kernel.SpecialForms.atom('atom')
47+
Symbol.for('atom')
4848
```
4949
50-
The elixirscript escript changed the elixir code, `:atom` into the JavaScript code `Kernel.SpecialForms.atom('atom')`. The `-ex` parameter lets the script know that the input is an Elixir code string instead of a file.
50+
The elixirscript escript changed the elixir code, `:atom` into the JavaScript code `Symbol.for('atom')`. The `-ex` parameter lets the script know that the input is an Elixir code string instead of a file.
5151
5252
What if we wanted to give it a file? You would simply do the following:
5353
5454
```bash
5555
$ elixirscript "example.exjs"
56-
Kernel.SpecialForms.atom('atom')
56+
Symbol.for('atom')
5757
```
5858
5959
What you will have noticed by now is that it has output everything we've done so far to the terminal. What about if we want to place the output to a path? The next example takes a file as input and outputs the result in another directory.

lib/elixir_script.ex

Lines changed: 40 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule ElixirScript do
2-
alias ElixirScript.Translator.JSModule
32
alias ESTree.Tools.Builder
43
alias ESTree.Tools.Generator
4+
alias ElixirScript.Translator.Utils
55

66
@moduledoc """
77
Translates Elixir into JavaScript.
@@ -32,7 +32,7 @@ defmodule ElixirScript do
3232
end
3333
end
3434

35-
@external_resource libs_path = Path.join([__DIR__, "elixir_script", "universal", "**", "*.ex"])
35+
@external_resource libs_path = Path.join([__DIR__, "elixir_script", "prelude", "**", "*.ex"])
3636
@libs (for path <- Path.wildcard(libs_path) do
3737
path
3838
|> File.read!
@@ -42,8 +42,8 @@ defmodule ElixirScript do
4242
@doc """
4343
Compiles the given Elixir code string
4444
"""
45-
@spec compile(binary, Dict.t) :: [binary | {binary, binary}]
46-
def compile(elixir_code, opts \\ []) do
45+
@spec compile(binary, Map.t) :: [binary | {binary, binary}]
46+
def compile(elixir_code, opts \\ %{}) do
4747
elixir_code
4848
|> Code.string_to_quoted!
4949
|> compile_quoted(opts)
@@ -52,34 +52,27 @@ defmodule ElixirScript do
5252
@doc """
5353
Compiles the given Elixir code in quoted form
5454
"""
55-
@spec compile_quoted(Macro.t, Dict.t) :: [binary | {binary, binary}]
56-
def compile_quoted(quoted, opts \\ []) do
57-
include_path = Dict.get(opts, :include_path, false)
58-
root = Dict.get(opts, :root)
59-
env = Dict.get(opts, :env, custom_env)
60-
import_standard_libs? = Dict.get(opts, :import_standard_libs, true)
61-
stdlib_path = Dict.get(opts, :stdlib_path, "Elixir")
55+
@spec compile_quoted(Macro.t, Map.t) :: [binary | {binary, binary}]
56+
def compile_quoted(quoted, opts \\ %{}) do
6257

63-
ElixirScript.State.start_link(root, env)
58+
compiler_opts = build_compiler_options(opts)
59+
ElixirScript.Translator.State.start_link(compiler_opts)
6460

6561
libs = @libs
6662
|> updated_quoted
6763

6864
build_environment(libs ++ [updated_quoted(quoted)])
69-
create_code(include_path, import_standard_libs?, stdlib_path)
65+
create_code(compiler_opts)
7066
end
7167

7268
@doc """
7369
Compiles the elixir files found at the given path
7470
"""
75-
@spec compile_path(binary, Dict.t) :: [binary | {binary, binary}]
76-
def compile_path(path, opts \\ []) do
77-
include_path = Dict.get(opts, :include_path, false)
78-
root = Dict.get(opts, :root)
79-
env = Dict.get(opts, :env, custom_env)
80-
stdlib_path = Dict.get(opts, :stdlib_path, "Elixir")
71+
@spec compile_path(binary, Map.t) :: [binary | {binary, binary}]
72+
def compile_path(path, opts \\ %{}) do
8173

82-
ElixirScript.State.start_link(root, env)
74+
compiler_opts = build_compiler_options(opts)
75+
ElixirScript.Translator.State.start_link(compiler_opts)
8376

8477
libs = @libs
8578
|> updated_quoted
@@ -90,7 +83,18 @@ defmodule ElixirScript do
9083

9184
build_environment(libs ++ code)
9285

93-
create_code(include_path, true, stdlib_path)
86+
create_code(compiler_opts)
87+
end
88+
89+
defp build_compiler_options(opts) do
90+
default_options = Map.new
91+
|> Map.put(:include_path, false)
92+
|> Map.put(:root, nil)
93+
|> Map.put(:env, custom_env)
94+
|> Map.put(:import_standard_libs, true)
95+
|> Map.put(:stdlib_path, "Elixir")
96+
97+
Map.merge(default_options, opts)
9498
end
9599

96100
defp file_to_quoted(file) do
@@ -102,7 +106,7 @@ defmodule ElixirScript do
102106

103107
defp build_environment(code_list) do
104108
code_list
105-
|> ElixirScript.Preprocess.Modules.get_info
109+
|> ElixirScript.Preprocess.Modules.process_modules
106110
end
107111

108112
defp updated_quoted(quoted) do
@@ -123,35 +127,35 @@ defmodule ElixirScript do
123127
__ENV__
124128
end
125129

126-
defp create_code(include_path, import_standard_libs?, stdlib_path) do
130+
defp create_code(compiler_opts) do
127131

128-
standard_lib_modules = ElixirScript.Module.build_standard_lib_map()
129-
|> Map.values
132+
state = ElixirScript.Translator.State.get
130133

131-
state = ElixirScript.State.get
134+
standard_lib_modules = state.std_lib_map
135+
|> Map.values
132136

133137
result =
134138
Map.values(state.modules)
135139
|> Enum.reject(fn(ast) ->
136-
import_standard_libs? == false && ast.name in standard_lib_modules
140+
compiler_opts.import_standard_libs == false && ast.name in standard_lib_modules
137141
end)
138142
|> Enum.map(fn ast ->
139-
env = ElixirScript.Env.module_env(ast.name, "#{create_file_name(ast.name)}")
143+
env = ElixirScript.Translator.Env.module_env(ast.name, Utils.name_to_js_file_name(ast.name) <> ".js")
140144

141145
case ast.type do
142146
:module ->
143147
ElixirScript.Translator.Module.make_module(ast.name, ast.body, env)
144148
:protocol ->
145149
ElixirScript.Translator.Protocol.consolidate(ast, env)
146150
end
147-
|> convert_to_code(state.root, state.elixir_env, import_standard_libs?, stdlib_path)
151+
|> convert_to_code()
148152
end)
149153

150-
ElixirScript.State.stop
154+
ElixirScript.Translator.State.stop
151155

152156
result
153157
|> Enum.map(fn({path, code}) ->
154-
if(include_path) do
158+
if(compiler_opts.include_path) do
155159
{ path, code }
156160
else
157161
code
@@ -174,37 +178,15 @@ defmodule ElixirScript do
174178
File.read!(operating_path <> "/Elixir.js")
175179
end
176180

177-
defp convert_to_code(js_ast, root, env, import_standard_libs, stdlib_path) do
178-
js_ast
179-
|> process_module(root, env, import_standard_libs, stdlib_path)
181+
defp convert_to_code(js_ast) do
182+
process_module(js_ast)
180183
|> javascript_ast_to_code
181184
end
182185

183-
defp process_module(%JSModule{} = module, root, _, import_standard_libs, stdlib_path) do
184-
file_path = create_file_name(module)
185-
186-
standard_libs_import =
187-
if import_standard_libs do
188-
ElixirScript.Translator.Import.create_standard_lib_imports(root, stdlib_path)
189-
else
190-
[]
191-
end
192-
193-
program =
194-
standard_libs_import ++ module.body
195-
|> ESTree.Tools.Builder.program
196-
197-
{file_path, program}
198-
end
199-
200-
defp create_file_name(%JSModule{name: module}) do
201-
name = ElixirScript.Module.name_to_js_file_name(module)
202-
"#{name}.js"
203-
end
186+
defp process_module(module) do
187+
file_path = Utils.name_to_js_file_name(module.name) <> ".js"
204188

205-
defp create_file_name(name) do
206-
name = ElixirScript.Module.name_to_js_file_name(name)
207-
"#{name}.js"
189+
{ file_path, ESTree.Tools.Builder.program(module.body) }
208190
end
209191

210192
@doc false

lib/elixir_script/cli.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ defmodule ElixirScript.CLI do
5757
end
5858

5959
def do_process(input, options) do
60-
compile_opts = [
60+
compile_opts = %{
6161
root: options[:root],
6262
include_path: options[:output] != nil,
63-
stdlib_path: Dict.get(options, :stdlib_path, "Elixir")
64-
]
63+
stdlib_path: Keyword.get(options, :stdlib_path, "Elixir")
64+
}
6565

6666
compile_output = case options[:elixir] do
6767
true ->
@@ -82,7 +82,7 @@ defmodule ElixirScript.CLI do
8282
write_to_file(x, output_path)
8383
end)
8484

85-
if Dict.get(options, :stdlib_path) == nil do
85+
if options[:stdlib_path] == nil do
8686
ElixirScript.copy_standard_libs_to_destination(output_path)
8787
end
8888
end

lib/elixir_script/module.ex

Lines changed: 0 additions & 63 deletions
This file was deleted.

lib/elixir_script/pattern_matching/match.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ defmodule ElixirScript.PatternMatching.Match do
112112
{ param, env }
113113

114114
(%ESTree.Identifier{} = param, env) ->
115-
env = ElixirScript.Env.add_var(env, param.name)
116-
new_name = ElixirScript.Env.get_var(env, param.name)
115+
env = ElixirScript.Translator.Env.add_var(env, param.name)
116+
new_name = ElixirScript.Translator.Env.get_var(env, param.name)
117117

118118
{ %{ param | name: new_name }, env }
119119

lib/elixir_script/prelude/agent.ex

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
defmodule ElixirScript.Agent do
2+
3+
def start(fun) do
4+
pid = Elixir.Core.Functions.get_global().processes.spawn()
5+
Elixir.Core.Functions.get_global().processes.put(pid, "state", fun.());
6+
{ :ok, pid }
7+
end
8+
9+
def start(fun, options) do
10+
pid = Elixir.Core.Functions.get_global().processes.spawn()
11+
12+
if Elixir.Keyword.has_key?(options, :name) do
13+
pid = Elixir.Core.Functions.get_global().processes.register(Elixir.Keyword.get(options, :name), pid)
14+
end
15+
16+
Elixir.Core.Functions.get_global().processes.put(pid, "state", fun.())
17+
{ :ok, pid }
18+
end
19+
20+
def stop(view) do
21+
Elixir.Core.Functions.get_global().processes.exit(view)
22+
:ok
23+
end
24+
25+
def update(agent, fun) do
26+
current_state = Elixir.Core.Functions.get_global().processes.get(agent, "state")
27+
Elixir.Core.Functions.get_global().processes.put(agent, "state", fun.(current_state));
28+
:ok
29+
end
30+
31+
def get(agent, fun) do
32+
current_state = Elixir.Core.Functions.get_global().processes.get(agent, "state")
33+
fun.(current_state)
34+
end
35+
36+
def get_and_update(agent, fun) do
37+
current_state = Elixir.Core.Functions.get_global().processes.get(agent, "state")
38+
{val, new_state} = fun.(current_state)
39+
Elixir.Core.Functions.get_global().processes.put(agent, "state", new_state);
40+
val
41+
end
42+
43+
end

lib/elixir_script/prelude/base.ex

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
defmodule ElixirScript.Base do
2+
3+
def encode64(data) do
4+
Elixir.Core.b64EncodeUnicode(data)
5+
end
6+
7+
def decode64(data) do
8+
if Elixir.Core.can_decode64(data) do
9+
{:ok, decode64!(data) }
10+
else
11+
:error
12+
end
13+
end
14+
15+
def decode64!(data) do
16+
Elixir.Core.get_global().atob(data)
17+
end
18+
19+
end
File renamed without changes.

0 commit comments

Comments
 (0)