Permalink
Browse files

Experimental Elixir support

  • Loading branch information...
Yurii Rashkovskii
Yurii Rashkovskii committed Feb 8, 2012
1 parent 87560a9 commit 6860feee3cfb3cf3497f8509a93a92301b92b3c2
View
@@ -6,7 +6,8 @@
{getopt, ".*", {git, "https://github.com/jcomellas/getopt.git", {branch, "master"}}},
{dynamic_compile, ".*", {git, "https://github.com/spawngrid/dynamic_compile", {branch, "master"}}},
{erlydtl, ".*", {git, "https://github.com/evanmiller/erlydtl.git", {branch, "master"}}},
- {parse_trans, ".*", {git, "https://github.com/esl/parse_trans.git", {branch, "master"}}}
+ {parse_trans, ".*", {git, "https://github.com/esl/parse_trans.git", {branch, "master"}}},
+ {elixir, ".*", {git, "https://github.com/josevalim/elixir.git", {branch, "master"}}}
]
}.
{erl_opts, [nowarn_unused_record]}.
@@ -14,7 +14,8 @@
dynamic_compile,
erlydtl,
parse_trans,
- syntax_tools
+ syntax_tools,
+ elixir
]},
{mod, { htoad_app, []}},
{env, [
@@ -4,6 +4,8 @@
-include_lib("htoad/include/htoad.hrl").
-include_lib("htoad/include/stdlib.hrl").
+-include_lib("elixir/include/elixir.hrl").
+
%% API
-export([start_link/1]).
@@ -96,7 +98,6 @@ handle_cast(apply, #state{ file = File, toadie = Toadie, applied = false } = Sta
handle_cast(init, #state{ file = File } = State) ->
try load_file(File) of
{Toadie, Bin} ->
- load_file(File),
htoad:assert(#'htoad.toadie'{ filename = File, module = Toadie, server = self() }),
lager:debug("Loaded toadie ~s", [File]),
load_rules(File, Toadie, Bin),
@@ -159,6 +160,19 @@ code_change(_OldVsn, State, _Extra) ->
%% Private
load_file(File) ->
+ case filename:extension(File) of
+ ".htd" ->
+ load_erl_file(File);
+ ".erl" ->
+ load_erl_file(File);
+ ".ex" ->
+ load_elixir_file(File);
+ ".exs" ->
+ load_elixir_file(File)
+ end.
+
+
+load_erl_file(File) ->
{ok, B} = file:read_file(File),
S = binary_to_list(B),
Module = list_to_atom(re:replace(File,"\\.","_",[{return, list}, global])),
@@ -181,6 +195,22 @@ load_file(File) ->
code:load_binary(Module, htoad_utils:file(File ++ ".beam"), Binary),
{Module, Binary}.
+load_elixir_file(File) ->
+ ModuleName = lists:flatten(io_lib:format("Elixir_Toadie_~w",[erlang:phash2(now())])),
+ {ok, B} = file:read_file(File),
+ Src = "defmodule " ++ ModuleName ++ " do\n"
+ "import Erlang.htoad_utils\n"
+ "Module.add_attribute __MODULE__, :htoad_absname, '" ++ File ++ "'\n"
+ "@compile {:parse_transform, :htoad_transform}\n"
+ ++ binary_to_list(B) ++
+ "end\n",
+ Forms = elixir_translator:forms(Src, 1, File),
+ put(elixir_compiled, []),
+ elixir_compiler:eval_forms(Forms, 1, list_to_atom(ModuleName), #elixir_scope{ filename = File }),
+ [{Module, Binary}] = get(elixir_compiled),
+ erase(elixir_compiled),
+ {Module, Binary}.
+
load_rules(File, Toadie, Bin) ->
case proplists:get_value(rules, Toadie:module_info(attributes)) of
undefined ->
@@ -79,20 +79,19 @@ do_transform(clause, {clause, Line, Head, G, B}, Context,
{B1, Rec, State2} = transform(fun do_transform/4, State1, B, Context),
{{clause, Line, Head1, G, B1}, Rec, State2};
+do_transform(application,{call, Line, {remote, RL, {atom, RL1, htoad_utils},{atom, RL2, F}}, [File]}, _Context,
+ #state{ absname = AbsName } = State) when F == load; F == file ->
+ {{call, Line, {remote, RL, {atom, RL1, htoad_utils}, {atom, RL2, F}},
+ [
+ filename_join(Line, File, AbsName)
+ ]}, true, State};
+
+
do_transform(application,{call, Line, {atom, Line1, F}, [File]}, _Context,
#state{ absname = AbsName } = State) when F == load; F == file ->
{{call, Line, {atom, Line1, F}, [
- {call, Line, {remote, Line,
- {atom, Line, filename},
- {atom, Line, join}},
- [list_to_cons([
- {call, Line, {remote, Line,
- {atom, Line, filename},
- {atom, Line, dirname}},
- [{string, Line, AbsName}]},
- File
- ], Line)]}
- ]}, true, State};
+ filename_join(Line, File, AbsName)
+ ]}, true, State};
do_transform(_Type, Form, _Context, State) ->
@@ -111,6 +110,19 @@ clause_scanner(_Type, Form, _Context, State) ->
{Form, false, State}.
+filename_join(Line, File, AbsName) ->
+ {call, Line, {remote, Line,
+ {atom, Line, filename},
+ {atom, Line, join}},
+ [list_to_cons([
+ {call, Line, {remote, Line,
+ {atom, Line, filename},
+ {atom, Line, dirname}},
+ [{string, Line, AbsName}]},
+ File
+ ], Line)]}.
+
+
scan_file_record(Fields) ->
DefaultFile = #file{},
RFields = record_info(fields, file),
View
@@ -0,0 +1,17 @@
+def build_server do
+ file = {:file, dir, Erlang.filename.join('/tmp/srv','build_dir'), :undefined, :undefined, :undefined, ""},
+ [
+ ensure(:present, file),
+ on([ {:operating_system_name, :darwin},
+ {:package_manager, :brew} ],
+ ensure(:present, {:package, 'git', :undefined}))
+ ]
+end
+
+def main do
+ [
+ load('base.htd')
+ on({:host, 'spawn.local'}, {:role, :build_server}),
+ on({:role, :build_server}, build_server)
+ ]
+end
View
@@ -1 +1,2 @@
{sub_dirs, ["apps/htoad","rel"]}.
+{post_hooks, [{compile, "cp deps/elixir/exbin/*.beam deps/elixir/ebin/"}]}.
View
@@ -35,7 +35,8 @@
{app, dynamic_compile, [{incl_cond, include}]},
{app, erlydtl, [{incl_cond, include}]},
{app, parse_trans, [{incl_cond, include}]},
- {app, syntax_tools, [{incl_cond, include}]}
+ {app, syntax_tools, [{incl_cond, include}]},
+ {app, elixir, [{incl_cond, include}]}
]}.
{target_dir, "htoad"}.

0 comments on commit 6860fee

Please sign in to comment.