<commit_before>%% -*- mode: Erlang; fill-column: 76; comment-column: 76; -*-
-module(jxa_compile).

-export([main/0, main/1, comp/1, format_exception/1]).

-include_lib("joxa/include/joxa.hrl").
%%=============================================================================
%% Types
%%=============================================================================

%%=============================================================================
%% Public API
%%=============================================================================
main() ->
    main(init:get_plain_arguments()).

main(Args) ->
    case getopt:parse(option_spec_list(), Args) of
        {ok, {Options, [Target]}} ->
            {Ctx0, Binary} = comp(Target),
            save_beam(Options, Binary, Ctx0);
        _ ->
            usage(option_spec_list()),
            ?JXA_THROW(invalid_options_passed_in)
    end.

-spec comp(string() | binary()) -> {jxa_ctx:ctx(), binary()}.
comp(FileName) when is_list(FileName) ->
    case file:read_file(FileName) of
        {ok, Binary} ->
            Result = {Ctx0, ModuleBinary} = comp(Binary),
            ModuleName = jxa_ctx:module_name(Ctx0),
            {module, ModuleName} =
                code:load_binary(ModuleName, FileName, ModuleBinary),
            Result;
        {error, Reason} ->
            ?JXA_THROW({file_access, Reason, FileName})
    end;
comp(BinaryData) when is_binary(BinaryData) ->
    {Annots, Ast0} = jxa_parser:parse(BinaryData),
    Ctx0 = jxa_ctx:new(Annots),
    {_, Ctx3, Binary} =
        lists:foldl(fun(DefAst, {Path, Ctx1, _Binary}) ->
                            {Ctx2, Binary1} = comp_forms(jxa_path:add(Path),
                                                         Ctx1, DefAst),
                            ModuleName = jxa_ctx:module_name(Ctx2),
                            {module, ModuleName} =
                                code:load_binary(ModuleName,
                                                 "", Binary1),
                            {jxa_path:incr(Path), jxa_ctx:update(Ctx2),
                             Binary1}
                    end, {jxa_path:new(), Ctx0, <<>>}, Ast0),
    {Ctx3, Binary}.

-spec format_exception(ExceptionBody::term()) -> IoList::[term()].
format_exception({file_access, enoent, FileName}) ->
    io_lib:format("File does not exist ~s", [FileName]);
format_exception({file_access, eacces, FileName}) ->
    io_lib:format("Missing  permission for reading the file: ~s",
                  [FileName]);
format_exception({file_access, eisdir, FileName}) ->
    io_lib:format("The named file is a directory: ~s",
                  [FileName]);
format_exception({file_access, enomem, FileName}) ->
    io_lib:format("There is not enough memory for the contents of the file: ~s",
                  [FileName]);
format_exception({file_access, Reason, FileName}) ->
    io_lib:format("Unexpected error (~p) attempting to read file: ~s",
                  [Reason, FileName]).

%%=============================================================================
%% Internal Functions<commit_msg>support bootstraping in the compiler<commit_after>%% -*- mode: Erlang; fill-column: 76; comment-column: 76; -*-
-module(jxa_compile).

-export([main/0, main/1, comp/1, format_exception/1]).

-include_lib("joxa/include/joxa.hrl").
%%=============================================================================
%% Types:
%%=============================================================================

%%=============================================================================
%% Public API
%%=============================================================================
main() ->
    main(init:get_plain_arguments()).

main(Args) ->
    case getopt:parse(option_spec_list(), Args) of
        {ok, {Options, [Target]}} ->
            {Ctx0, Binary} = bootstrap_comp(filename:absname(Target)),
            save_beam(Options, Binary, Ctx0);
        _ ->
            usage(option_spec_list()),
            ?JXA_THROW(invalid_options_passed_in)
    end.

-spec bootstrap_comp(string() | binary()) -> {jxa_ctx:ctx(), binary()}.
bootstrap_comp(FileName) when is_list(FileName) ->
    case file:read_file(FileName) of
        {ok, Binary} ->
            Result = {Ctx0, ModuleBinary} = bootstrap_comp(Binary),
            ModuleName = jxa_ctx:module_name(Ctx0),
            {module, ModuleName} =
                code:load_binary(ModuleName, "", ModuleBinary),
            Result;
        {error, Reason} ->
            ?JXA_THROW({file_access, Reason, FileName})
    end;
bootstrap_comp(BinaryData) when is_binary(BinaryData) ->
    {Annots, Ast0} = jxa_parser:parse(BinaryData),
    Ctx0 = jxa_ctx:new(Annots),
    {_, Ctx3, Binary} =
        lists:foldl(fun(DefAst, {Path, Ctx1, _Binary}) ->
                            {Ctx2, Binary1} = comp_forms(jxa_path:add(Path),
                                                         Ctx1, DefAst),
                            {jxa_path:incr(Path), jxa_ctx:update(Ctx2),
                             Binary1}
                    end, {jxa_path:new(), Ctx0, <<>>}, Ast0),
    {Ctx3, Binary}.

comp(BinaryData) when is_binary(BinaryData) ->
    {Annots, Ast0} = jxa_parser:parse(BinaryData),
    Ctx0 = jxa_ctx:new(Annots),
    {_, Ctx3, Binary} =
        lists:foldl(fun(DefAst, {Path, Ctx1, _Binary}) ->
                            {Ctx2, Binary1} = comp_forms(jxa_path:add(Path),
                                                         Ctx1, DefAst),
                            ModuleName = jxa_ctx:module_name(Ctx2),
                            {module, ModuleName} =
                                code:load_binary(ModuleName,
                                                 "", Binary1),
                            {jxa_path:incr(Path), jxa_ctx:update(Ctx2),
                             Binary1}
                    end, {jxa_path:new(), Ctx0, <<>>}, Ast0),
    {Ctx3, Binary}.
-spec format_exception(ExceptionBody::term()) -> IoList::[term()].
format_exception({file_access, enoent, FileName}) ->
    io_lib:format("File does not exist ~s", [FileName]);
format_exception({file_access, eacces, FileName}) ->
    io_lib:format("Missing  permission for reading the file: ~s",
                  [FileName]);
format_exception({file_access, eisdir, FileName}) ->
    io_lib:format("The named file is a directory: ~s",
                  [FileName]);
format_exception({file_access, enomem, FileName}) ->
    io_lib:format("There is not enough memory for the contents of the file: ~s",
                  [FileName]);
format_exception({file_access, Reason, FileName}) ->
    io_lib:format("Unexpected error (~p) attempting to read file: ~s",
                  [Reason, FileName]).

%%=============================================================================
%% Internal Functions
{'fraction_non_alphanumeric': 0.23983560839571408, 'fraction_numerical': 0.009393805959195655, 'mean_word_length': 2.537902388369678, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5283038', 'n_tokens_mistral': 1964, 'n_tokens_neox': 1873, 'n_words': 360}