-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f9dc79d
Showing
12 changed files
with
393 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Used by "mix format" | ||
[ | ||
inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# The directory Mix will write compiled artifacts to. | ||
/_build/ | ||
|
||
# If you run "mix test --cover", coverage assets end up here. | ||
/cover/ | ||
|
||
# The directory Mix downloads your dependencies sources to. | ||
/deps/ | ||
|
||
# Where 3rd-party dependencies like ExDoc output generated docs. | ||
/doc/ | ||
|
||
# Ignore .fetch files in case you like to edit your project deps locally. | ||
/.fetch | ||
|
||
# If the VM crashes, it generates a dump, let's ignore it too. | ||
erl_crash.dump | ||
|
||
# Also ignore archive artifacts (built via "mix archive.build"). | ||
*.ez | ||
|
||
# Ignore package tarball (built via "mix hex.build"). | ||
elixir_lfe-*.tar | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Mix LFE Compiler | ||
|
||
A very simple Mix task that compiles LFE (lisp (flavoured (erlang))). | ||
|
||
It is a Mix compiler which uses the Erlang Mix compiler. | ||
|
||
Lisp is a great language to get into the functional way of thinking and LFE is Lisp 2+ which runs on the greatest platform (personal opinion). | ||
Elixir's Mix is a great (or the greatest) configuration/package/build manager, so why not use it to compile LFE? | ||
Also Elixir developers should try LFE! This little project has the purpose to make that an easier. | ||
|
||
## Installation | ||
|
||
You can create a Mix project with `mix new <project_name>` and add this as dependency: | ||
|
||
```elixir | ||
def deps do | ||
[ | ||
{:mix_lfe, "~> 0.1.0"} | ||
] | ||
end | ||
``` | ||
|
||
The project uses the rebar3 `lfe` package to compile LFE source files, so the following will be necessary: | ||
|
||
1. Navigate to the new project root. | ||
2. Run `mix deps.get`. | ||
3. Run `mix local.rebar` (if you don't have rebar3 installed). | ||
4. Compile LFE : `(cd deps/lfe && ~/.mix/rebar3 compile)`. You can replace `~/.mix/rebar3` here with the location it is installed on your machine. | ||
5. Create a `src` folder and add your `*.lfe` sources there. | ||
6. Run `mix compile.lfe` to compile them. Now you'll be able to use the compiled modules with `iex -S mix`. | ||
|
||
To use the compiled modules with the LFE REPL, you can run: | ||
|
||
```bash | ||
./deps/lfe/bin/lfe -pa _build/dev/lib/*/ebin | ||
``` | ||
|
||
Also if you want to just run `mix compile` add `compilers: Mix.compilers() ++ [:lfe]` to the list returned by `project/0` which is defined in your `mix.exs`. | ||
|
||
## Example projects | ||
|
||
TODO | ||
|
||
## TODO | ||
|
||
The tests of this project mirror the ones for the Erlang Mix compiler. | ||
For now the source is very simple and uses an [idea](https://github.com/elixir-lang/elixir/blob/e1c903a5956e4cb9075f0aac00638145788b0da4/lib/mix/lib/mix/compilers/erlang.ex#L20) from the Erlang Mix compiler. | ||
All works well, but requires some manual work and doesn't support LFE compiler fine tunning, so that's what we'll be after next. | ||
|
||
1. Add task for running LFE tests. What kind of tests? Will see... | ||
2. Automate the installation & setup process in a way. Maybe by using something similar to the Phoenix generator tasks. | ||
3. Pass more options to the LFE compiler, using mix configuration. | ||
4. Use LFE syntax for configuration (not sure this is needed, really). | ||
5. More and more examples. | ||
6. A mix task or binary running the LFE REPL in the context of the compiled artifacts. | ||
7. Add CI to this project. | ||
|
||
## License | ||
|
||
Same as Elixir. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use Mix.Config | ||
|
||
# This configuration is loaded before any dependency and is restricted | ||
# to this project. If another project depends on this project, this | ||
# file won't be loaded nor affect the parent project. For this reason, | ||
# if you want to provide default values for your application for | ||
# 3rd-party users, it should be done in your "mix.exs" file. | ||
|
||
# You can configure your application as: | ||
# | ||
# config :elixir_lfe, key: :value | ||
# | ||
# and access this configuration in your application as: | ||
# | ||
# Application.get_env(:elixir_lfe, :key) | ||
# | ||
# You can also configure a 3rd-party app: | ||
# | ||
# config :logger, level: :info | ||
# | ||
|
||
# It is also possible to import configuration files, relative to this | ||
# directory. For example, you can emulate configuration per environment | ||
# by uncommenting the line below and defining dev.exs, test.exs and such. | ||
# Configuration from the imported file will override the ones defined | ||
# here (which is why it is important to import them last). | ||
# | ||
# import_config "#{Mix.env}.exs" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
defmodule Mix.Tasks.Compile.Lfe do | ||
use Mix.Task.Compiler | ||
import Mix.Compilers.Erlang | ||
|
||
@recursive true | ||
@manifest "compile.lfe" | ||
@switches [force: :boolean, all_warnings: :boolean] | ||
|
||
@moduledoc """ | ||
Compiles LFE source files. | ||
Uses an [idea](https://github.com/elixir-lang/elixir/blob/e1c903a5956e4cb9075f0aac00638145788b0da4/lib/mix/lib/mix/compilers/erlang.ex#L20) from the Erlang Mix compiler to do so. | ||
It supports the options of the Erlang Mix compiler under the covers at it is used. | ||
This means that these options are supported: | ||
## Command line options | ||
* `--force` - forces compilation regardless of modification times | ||
* `--all-warnings` - prints warnings even from files that do not need to be recompiled | ||
## Configuration | ||
The [Erlang compiler configuration](https://github.com/elixir-lang/elixir/blob/master/lib/mix/lib/mix/tasks/compile.erlang.ex#L31) is supported. | ||
Specific configuration options for the LFE compiler will be supported in future. | ||
""" | ||
|
||
@doc """ | ||
Runs this task. | ||
""" | ||
def run(args) do | ||
{opts, _, _} = OptionParser.parse(args, switches: @switches) | ||
do_run(opts) | ||
end | ||
|
||
defp do_run(opts) do | ||
dest = Mix.Project.compile_path() | ||
|
||
callback = fn input, output -> | ||
module = input |> Path.basename(".lfe") |> String.to_atom() | ||
:code.purge(module) | ||
:code.delete(module) | ||
|
||
outdir = output |> Path.dirname() |> to_erl_file() | ||
|
||
compile_result(:lfe_comp.file(to_erl_file(input), [{:outdir, outdir}, :return, :report])) | ||
end | ||
|
||
compile(manifest(), [{"src", dest}], :lfe, :beam, opts, callback) | ||
end | ||
|
||
@doc """ | ||
Returns LFE manifests. | ||
""" | ||
def manifests, do: [manifest()] | ||
|
||
@doc """ | ||
Cleans up compilation artifacts. | ||
""" | ||
def clean, do: clean(manifest()) | ||
|
||
defp manifest, do: Path.join(Mix.Project.manifest_path(), @manifest) | ||
|
||
defp compile_result({:error, [{:error, [{file, [error | _]}], []}], [], []}) do | ||
{:error, [{file, [error]}], []} | ||
end | ||
|
||
defp compile_result(result), do: result | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
defmodule MixLfe.MixProject do | ||
use Mix.Project | ||
|
||
def project do | ||
[ | ||
app: :mix_lfe, | ||
version: "0.1.0", | ||
elixir: "~> 1.6", | ||
start_permanent: Mix.env() == :prod, | ||
description: "A LFE compiler for Mix", | ||
package: package(), | ||
deps: deps() | ||
] | ||
end | ||
|
||
def application do | ||
[extra_applications: [:logger]] | ||
end | ||
|
||
def package do | ||
%{ | ||
licenses: ["Apache 2"], | ||
links: %{"GitHub" => "https://github.com/meddle0x53/mix_lfe"}, | ||
maintainers: ["Nikolay Tsvetinov (Meddle)"] | ||
} | ||
end | ||
|
||
def deps do | ||
[ | ||
{:lfe, "~> 1.2", override: true, manager: :rebar} | ||
] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
%{ | ||
"lfe": {:hex, :lfe, "1.2.0", "257708859c0a6949f174cecee6f08bb5d6f08c0f97ec7b75c07072014723ecbc", [:rebar3], [], "hexpm"}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
defmodule Sample.Mixfile do | ||
use Mix.Project | ||
|
||
def project do | ||
[app: :sample, version: "1.0.0"] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(defmodule tut4 | ||
(export (convert 2))) | ||
|
||
(defun convert | ||
((m 'inch) (/ m 2.54)) | ||
((n 'centimeter) (* n 2.54))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(defmodule tut5 | ||
(export (convert-length 1))) | ||
|
||
(defun convert-length | ||
(((tuple 'centimeter x)) (tuple 'inch (/ x 2.54))) | ||
(((tuple 'inch y)) (tuple 'centimeter (* y 2.54)))) |
Oops, something went wrong.