Permalink
Browse files

bootstrapped joxa compiler, initial support for module compilation

  • Loading branch information...
1 parent bb99ff8 commit ebede4a7439a01796a0c538940c8c855f9f6de2b @ericbmerritt ericbmerritt committed Jan 13, 2012
View
Oops, something went wrong.
View
@@ -101,9 +101,9 @@ comp_pattern(Path0, Acc0={Ctx0, _}, [quote, Args]) ->
comp_pattern(Path0, Acc0, Expr=[binary | _]) ->
jxa_binary:comp_pattern(Path0, Acc0, Expr);
comp_pattern(Path0, Acc0, [Arg1, '.', Arg2]) ->
- {Acc1, Cerl1} = comp_pattern(Path0,
+ {Acc1, Cerl1} = comp_pattern(jxa_path:add(Path0),
Acc0, Arg1),
- {Acc2={Ctx1, _}, Cerl2} = comp_pattern(jxa_path:incr(2, Path0),
+ {Acc2={Ctx1, _}, Cerl2} = comp_pattern(jxa_path:add(jxa_path:incr(2, Path0)),
Acc1, Arg2),
Annots = jxa_annot:get_line(jxa_path:add_path(Path0),
jxa_ctx:annots(Ctx1)),
@@ -39,9 +39,11 @@ comp(Path0, Ctx0, _) ->
?JXA_THROW({invalid_definition, Idx}).
-compile_function(Path0, Ctx0, Body = [_, _, _]) ->
+compile_function(Path0, Ctx0, Body = [Name, Args, _])
+ when is_list(Args), is_atom(Name) ->
compile_function1(Path0, Ctx0, [default_type() | Body]);
-compile_function(Path0, Ctx0, Body = [_, _, _, _]) ->
+compile_function(Path0, Ctx0, Body = [_, Name, Args, _])
+ when is_list(Args), is_atom(Name) ->
compile_function1(jxa_path:incr(Path0), Ctx0, Body);
compile_function(Path0, Ctx0, _) ->
Idx = jxa_annot:get_idx(jxa_path:path(Path0),
@@ -121,9 +121,9 @@ comp(Path0, Ctx0, [values | Args0]) ->
comp(Path0, Ctx0, Expr = [binary | _]) ->
jxa_binary:comp(Path0, Ctx0, Expr);
comp(Path0, Ctx0, [Arg1, '.', Arg2]) ->
- {Ctx1, Cerl1} = comp(Path0,
+ {Ctx1, Cerl1} = comp(jxa_path:add(Path0),
Ctx0, Arg1),
- {Ctx2, Cerl2} = comp(jxa_path:incr(2, Path0),
+ {Ctx2, Cerl2} = comp(jxa_path:add(jxa_path:incr(2, Path0)),
Ctx1, Arg2),
Annots = jxa_annot:get_line(jxa_path:add_path(Path0),
jxa_ctx:annots(Ctx2)),
View
@@ -31,7 +31,13 @@ compile_bindings(Path0, Path1, Ctx0, [[Var, Expr] | Rest], Body) ->
compile_bindings(Path0a,
jxa_path:incr(Path1a),
Ctx1, Rest, Body)
- end).
+ end);
+compile_bindings(_Path0, Path1, Ctx0, _, _Body) ->
+ Idx =
+ jxa_annot:get_idx(jxa_path:add_path(Path1),
+ jxa_ctx:annots(Ctx0)),
+ ?JXA_THROW({invalid_let_binding, Idx}).
+
compile_binding(Path0, Path1, Ctx0, Var, Expr=[fn, Args, _],
Continuation) when not is_list(Var) ->
%% For letrecs the variable has to be available in the scope so
View
@@ -34,7 +34,7 @@
%% for testing purposes
-export([intermediate_parse/1, p_charclass/1, string/2, setup_memo/0,
- release_memo/0]).
+ release_memo/0]).
-include_lib("joxa/include/joxa.hrl").
@@ -262,8 +262,29 @@ float(Input, Index) ->
char(Input, Index) ->
p(Input, Index, char,
p_seq([p_string(<<"\\">>),
- p_anything()]),
- fun([_, Char], Idx) ->
+ p_choose([p_string(<<"\\\"">>),
+ p_string(<<"\\\\">>),
+ p_string(<<"\\b">>),
+ p_string(<<"\\f">>),
+ p_string(<<"\\n">>),
+ p_string(<<"\\r">>),
+ p_string(<<"\\t">>),
+ p_anything()])]),
+ fun([_, <<"\\\"">>], Idx) ->
+ {char, $", Idx};
+ ([_, <<"\\\\">>], Idx) ->
+ {char, $\\, Idx};
+ ([_, <<"\\b">>], Idx) ->
+ {char, $\b, Idx};
+ ([_, <<"\\f">>], Idx) ->
+ {char, $\f, Idx};
+ ([_, <<"\\n">>], Idx) ->
+ {char, $\n, Idx};
+ ([_, <<"\\r">>], Idx) ->
+ {char, $\r, Idx};
+ ([_, <<"\\t">>], Idx) ->
+ {char, $\t, Idx};
+ ([_, Char], Idx) ->
{char, hd(binary_to_list(Char)), Idx}
end).
@@ -305,7 +326,7 @@ digit(Input, Index) ->
fun(I,D) ->
(p_charclass(<<"[0-9]">>))(I,D)
end).
-%% done
+
-spec binary(binary(), index()) -> intermediate_ast().
binary(Input, Index) ->
p(Input, Index, binary,
@@ -338,7 +359,6 @@ binary(Input, Index) ->
{binary, [], Idx}
end).
-%% done
-spec tuple(binary(), index()) -> intermediate_ast().
tuple(Input, Index) ->
p(Input, Index, tuple,
@@ -358,7 +378,6 @@ tuple(Input, Index) ->
{tuple, [], Idx}
end).
-%% done
-spec list(binary(), index()) -> intermediate_ast().
list(Input, Index) ->
p(Input, Index, list,
@@ -392,7 +411,6 @@ list(Input, Index) ->
{list, [], Idx}
end).
-%% Done
-spec string(binary(), index()) -> intermediate_ast().
string(Input, Index) ->
p(Input, Index, string,
@@ -461,7 +479,6 @@ ignorable(Input, Index) ->
[]
end).
-%% done
fun_reference(Input, Index) ->
p(Input, Index, fun_reference,
p_choose([p_seq([fun ident/2,
@@ -512,7 +529,6 @@ ident(Input, Index) ->
{ident, Result, Idx}
end).
-%% done
-spec quote(binary(), index()) -> intermediate_ast().
quote(Input, Index) ->
p(Input, Index, quote,
@@ -523,7 +539,6 @@ quote(Input, Index) ->
{quote, Item, Idx}
end).
-%% done
-spec value(binary(), index()) -> intermediate_ast().
value(Input, Index) ->
p(Input, Index, value,
@@ -13,6 +13,7 @@ given([a,module,that,has,an,anonymous,function], _State, _) ->
(defn+ do-test ()
(let ((z (internal-test))
+ (c '(one two three))
(x (fn (arg1 arg2)
{:hello arg1 arg2}))
(a erlang/phash2/1)
@@ -10,7 +10,7 @@ given([a,bare,module], _State, _) ->
{ok, Module}.
'when'([joxa,is,called,on,this,module], State, _) ->
- Result = jxa_compile:comp("", State),
+ Result = joxa.compiler:forms("", State, []),
{ok, Result}.
then([a,beam,binary,is,produced], State={_Ctx, Binary}, _) ->
View
@@ -0,0 +1,83 @@
+%%%-------------------------------------------------------------------
+%%% @author Eric B Merritt <ericbmerritt@gmail.com>
+%%% @copyright (C) 2011, Eric B Merritt
+%%% @doc
+%%%
+%%% @end
+%%% Created : 29 Dec 2011 by Eric B Merritt <ericbmerritt@gmail.com>
+%%%-------------------------------------------------------------------
+-module(jxat_ctx).
+
+%% API
+-include_lib("eunit/include/eunit.hrl").
+
+%%%===================================================================
+%%% Tests
+%%%===================================================================
+test1_test() ->
+ Ctx0 = joxa.compiler:'new-context'([{attrs, [{foo, bar}]}]),
+ ?assertMatch([{foo, bar}],
+ joxa.compiler:'get-context'(attrs, Ctx0)),
+ Ctx1 = joxa.compiler:'add-export-ctx'(10, super, 3, Ctx0),
+ ?assertMatch([{super, 3, 10}],
+ sets:to_list(joxa.compiler:'get-context'(exports, Ctx1))),
+ Ctx2 = joxa.compiler:'add-require-ctx'(filelib, Ctx1),
+ ?assertMatch([{filelib, _}],
+ ec_dictionary:to_list(joxa.compiler:'get-context'(requires,
+ Ctx2))),
+ Ctx3 = joxa.compiler:'add-use-ctx'(print, 2, format, io, Ctx2),
+
+ ?assertMatch([{{print, 2}, {format, io}}],
+ ec_dictionary:to_list(joxa.compiler:'get-context'(uses,
+ Ctx3))),
+ Ctx4 = joxa.compiler:'add-def-ctx'([], foo, [], none,
+ joxa.compiler:'push-scope-ctx'(Ctx3)),
+ Ctx5 = joxa.compiler:'add-def-ctx'([], foo, [one, two], none, Ctx4),
+ Ctx6 = joxa.compiler:'add-require-ctx'(lists,
+ joxa.compiler:'add-alias-ctx'(bar, lists, Ctx5)),
+ Ctx7 = joxa.compiler:'add-reference-to-scope-ctx'(foo, -1, Ctx6),
+
+ ?assertMatch({reference, {c_var, [], foo}},
+ joxa.compiler:'resolve-reference-ctx'(foo, -1, Ctx7)),
+
+ ?assertMatch({apply, foo, 2},
+ joxa.compiler:'resolve-reference-ctx'(foo, 2, Ctx7)),
+
+ ?assertMatch('not-a-reference',
+ joxa.compiler:'resolve-reference-ctx'(foo, 3, Ctx7)),
+
+ ?assertMatch('not-a-reference',
+ joxa.compiler:'resolve-reference-ctx'(foo, 1, Ctx7)),
+
+ ?assertMatch({apply, foo, 0},
+ joxa.compiler:'resolve-reference-ctx'(foo, 0, Ctx7)),
+
+ ?assertMatch({remote, io, format, 2},
+ joxa.compiler:'resolve-reference-ctx'(print, 2, Ctx7)),
+
+ ?assertMatch({remote, lists, zipwith3, 4},
+ joxa.compiler:'resolve-reference-ctx'({'__fun__', lists,
+ zipwith3, 4}, 4, Ctx7)),
+
+ ?assertMatch({remote, lists, zipwith3, 4},
+ joxa.compiler:'resolve-reference-ctx'({'__fun__', bar,
+ zipwith3, 4}, 4, Ctx7)),
+
+ ?assertThrow({'mismatched-arity',bar,zipwith3,4,3},
+ joxa.compiler:'resolve-reference-ctx'({'__fun__', bar,
+ zipwith3, 3}, 4, Ctx7)).
+
+
+
+
+
+
+
+
+
+
+%%%===================================================================
+%%% Support Functions
+%%%===================================================================
+
+
@@ -21,7 +21,7 @@ given([a,featureful,module], _State, _) ->
{ok, Source}.
'when'([joxa,is,called,on,this,module], State, _) ->
- Result = jxa_compile:comp("", State),
+ Result = joxa.compiler:forms("", State, []),
{ok, Result}.
then([a,beam,binary,is,produced], State={_, Binary}, _) ->
@@ -33,9 +33,9 @@ then([the,joxa,context,for,a,featureful,module,is,correctly,formed], State={Ctx0
validate_lists(Ctx0),
validate_file(Ctx0),
validate_filename(Ctx0),
- Required = jxa_ctx:require(Ctx0),
- Alias = jxa_ctx:alias(Ctx0),
- _Attrs = jxa_ctx:attrs(Ctx0),
+ Required = joxa.compiler:'get-context'(requires, Ctx0),
+ Alias = joxa.compiler:'get-context'(aliases, Ctx0),
+ _Attrs = joxa.compiler:'get-context'(attrs, Ctx0),
?assertMatch(true, ec_dictionary:has_key(proplists, Required)),
?assertMatch(true, ec_dictionary:has_key(erlang, Required)),
?assertMatch(true, ec_dictionary:has_key(code, Required)),
@@ -53,9 +53,9 @@ then([the,joxa,context,for,a,featureful,module,is,correctly,formed], State={Ctx0
validate_module(Module, Ctx0) ->
%% module_info causes problems and is mostly ignored
Exports = [El || El={Fun, _}
- <- proplists:get_value(exports, Module:module_info()),
+ <- Module:module_info(exports),
Fun =/= module_info],
- Used = jxa_ctx:use(Ctx0),
+ Used = joxa.compiler:'get-context'(uses, Ctx0),
lists:foreach(fun(Export={Fun, _}) ->
?assertMatch({Fun, Module},
ec_dictionary:get(Export, Used))
@@ -64,11 +64,11 @@ validate_module(Module, Ctx0) ->
validate_lists(Ctx0) ->
Required = [{append, 2}],
Exports = [El || El={Fun, _}
- <- proplists:get_value(exports, lists:module_info()),
+ <- lists:module_info(exports),
Fun =/= module_info],
FilteredExports = [FunArity || FunArity <- Exports,
not lists:member(FunArity, Required)],
- Used = jxa_ctx:use(Ctx0),
+ Used = joxa.compiler:'get-context'(uses, Ctx0),
lists:foreach(fun(Export={Fun, _}) ->
?assertMatch({Fun, lists},
ec_dictionary:get(Export, Used))
@@ -86,14 +86,14 @@ validate_file(Ctx0) ->
DescUsed = [{{chgrp, 2}, change_group},
{{chmod, 2}, change_mode}],
Exports = [El || El={Fun, _}
- <- proplists:get_value(exports, file:module_info()),
+ <- file:module_info(exports),
Fun =/= module_info],
FilteredExports = [FunArity || FunArity <- Exports,
not lists:member(FunArity,
[{delete, 1},
{change_group, 2},
{change_mode, 2}])],
- Used = jxa_ctx:use(Ctx0),
+ Used = joxa.compiler:'get-context'(uses, Ctx0),
lists:foreach(fun({Export, Target}) ->
?assertMatch({Target, file},
ec_dictionary:get(Export, Used))
@@ -105,7 +105,7 @@ validate_file(Ctx0) ->
validate_filename(Ctx0) ->
Exports = [El || El={Fun, _}
- <- proplists:get_value(exports, filename:module_info()),
+ <- filename:module_info(exports),
Fun =/= module_info],
DescExclude = [{absname, 1},
{join, 2},
@@ -115,7 +115,7 @@ validate_filename(Ctx0) ->
FilteredExports = [FunArity || FunArity <- Exports,
not lists:member(FunArity,
DescExclude)],
- Used = jxa_ctx:use(Ctx0),
+ Used = joxa.compiler:'get-context'(uses, Ctx0),
lists:foreach(fun(Export={Target, _}) ->
?assertMatch({Target, filename},
ec_dictionary:get(Export, Used))
Oops, something went wrong.

0 comments on commit ebede4a

Please sign in to comment.