aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/build/dev/erlang/snag/_gleam_artefacts
diff options
context:
space:
mode:
authorJ.J <thechairman@thechairman.info>2024-05-30 21:50:02 -0400
committerJ.J <thechairman@thechairman.info>2024-05-30 21:50:02 -0400
commit612fd986ab1e00b6d34dc1937136250e08e89325 (patch)
treea3c93952040c6afdf348b5831619a45db7ba0a2e /aoc2023/build/dev/erlang/snag/_gleam_artefacts
parent231c2b688d1e6cf0846d46e883da30e042a9c6cf (diff)
downloadgleam_aoc-612fd986ab1e00b6d34dc1937136250e08e89325.tar.gz
gleam_aoc-612fd986ab1e00b6d34dc1937136250e08e89325.zip
cleanup
Diffstat (limited to 'aoc2023/build/dev/erlang/snag/_gleam_artefacts')
-rw-r--r--aoc2023/build/dev/erlang/snag/_gleam_artefacts/gleam@@compile.erl157
-rw-r--r--aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.cachebin0 -> 3788 bytes
-rw-r--r--aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.cache_metabin0 -> 125 bytes
-rw-r--r--aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.erl74
4 files changed, 231 insertions, 0 deletions
diff --git a/aoc2023/build/dev/erlang/snag/_gleam_artefacts/gleam@@compile.erl b/aoc2023/build/dev/erlang/snag/_gleam_artefacts/gleam@@compile.erl
new file mode 100644
index 0000000..543db88
--- /dev/null
+++ b/aoc2023/build/dev/erlang/snag/_gleam_artefacts/gleam@@compile.erl
@@ -0,0 +1,157 @@
+#!/usr/bin/env escript
+
+% TODO: Don't concurrently print warnings and errors
+% TODO: Some tests
+
+-record(arguments, {lib = "./", out = "./", modules = []}).
+
+main(Args) ->
+ #arguments{out = Out, lib = Lib, modules = Modules} = parse(Args),
+ IsElixirModule = fun(Module) ->
+ filename:extension(Module) =:= ".ex"
+ end,
+ {ElixirModules, ErlangModules} = lists:partition(IsElixirModule, Modules),
+ ok = configure_logging(),
+ ok = add_lib_to_erlang_path(Lib),
+ ok = filelib:ensure_dir([Out, $/]),
+ {ErlangOk, _ErlangBeams} = compile_erlang(ErlangModules, Out),
+ {ElixirOk, _ElixirBeams} = case ErlangOk of
+ true -> compile_elixir(ElixirModules, Out);
+ false -> {false, []}
+ end,
+ case ErlangOk and ElixirOk of
+ true -> ok;
+ false -> erlang:halt(1)
+ end.
+
+compile_erlang(Modules, Out) ->
+ Workers = start_compiler_workers(Out),
+ ok = producer_loop(Modules, Workers),
+ collect_results({true, []}).
+
+collect_results(Acc = {Result, Beams}) ->
+ receive
+ {compiled, Beam} -> collect_results({Result, [Beam | Beams]});
+ failed -> collect_results({false, Beams})
+ after 0 -> Acc
+ end.
+
+producer_loop([], 0) ->
+ ok;
+producer_loop([], Workers) ->
+ receive
+ {work_please, _} -> producer_loop([], Workers - 1)
+ end;
+producer_loop([Module | Modules], Workers) ->
+ receive
+ {work_please, Worker} ->
+ erlang:send(Worker, {module, Module}),
+ producer_loop(Modules, Workers)
+ end.
+
+start_compiler_workers(Out) ->
+ Parent = self(),
+ NumSchedulers = erlang:system_info(schedulers),
+ SpawnWorker = fun(_) ->
+ erlang:spawn_link(fun() -> worker_loop(Parent, Out) end)
+ end,
+ lists:foreach(SpawnWorker, lists:seq(1, NumSchedulers)),
+ NumSchedulers.
+
+worker_loop(Parent, Out) ->
+ Options = [report_errors, report_warnings, debug_info, {outdir, Out}],
+ erlang:send(Parent, {work_please, self()}),
+ receive
+ {module, Module} ->
+ log({compiling, Module}),
+ case compile:file(Module, Options) of
+ {ok, ModuleName} ->
+ Beam = filename:join(Out, ModuleName) ++ ".beam",
+ Message = {compiled, Beam},
+ log(Message),
+ erlang:send(Parent, Message);
+ error ->
+ log({failed, Module}),
+ erlang:send(Parent, failed)
+ end,
+ worker_loop(Parent, Out)
+ end.
+
+compile_elixir(Modules, Out) ->
+ Error = [
+ "The program elixir was not found. Is it installed?",
+ $\n,
+ "Documentation for installing Elixir can be viewed here:",
+ $\n,
+ "https://elixir-lang.org/install.html"
+ ],
+ case Modules of
+ [] -> {true, []};
+ _ ->
+ log({starting, "compiler.app"}),
+ ok = application:start(compiler),
+ log({starting, "elixir.app"}),
+ case application:start(elixir) of
+ ok -> do_compile_elixir(Modules, Out);
+ _ ->
+ io:put_chars(standard_error, [Error, $\n]),
+ {false, []}
+ end
+ end.
+
+do_compile_elixir(Modules, Out) ->
+ ModuleBins = lists:map(fun(Module) ->
+ log({compiling, Module}),
+ list_to_binary(Module)
+ end, Modules),
+ OutBin = list_to_binary(Out),
+ Options = [{dest, OutBin}],
+ % Silence "redefining module" warnings.
+ % Compiled modules in the build directory are added to the code path.
+ % These warnings result from recompiling loaded modules.
+ % TODO: This line can likely be removed if/when the build directory is cleaned before every compilation.
+ 'Elixir.Code':compiler_options([{ignore_module_conflict, true}]),
+ case 'Elixir.Kernel.ParallelCompiler':compile_to_path(ModuleBins, OutBin, Options) of
+ {ok, ModuleAtoms, _} ->
+ ToBeam = fun(ModuleAtom) ->
+ Beam = filename:join(Out, atom_to_list(ModuleAtom)) ++ ".beam",
+ log({compiled, Beam}),
+ Beam
+ end,
+ {true, lists:map(ToBeam, ModuleAtoms)};
+ {error, Errors, _} ->
+ % Log all filenames associated with modules that failed to compile.
+ % Note: The compiler prints compilation errors upon encountering them.
+ ErrorFiles = lists:usort([File || {File, _, _} <- Errors]),
+ Log = fun(File) ->
+ log({failed, binary_to_list(File)})
+ end,
+ lists:foreach(Log, ErrorFiles),
+ {false, []};
+ _ -> {false, []}
+ end.
+
+add_lib_to_erlang_path(Lib) ->
+ code:add_paths(filelib:wildcard([Lib, "/*/ebin"])).
+
+parse(Args) ->
+ parse(Args, #arguments{}).
+
+parse([], Arguments) ->
+ Arguments;
+parse(["--lib", Lib | Rest], Arguments) ->
+ parse(Rest, Arguments#arguments{lib = Lib});
+parse(["--out", Out | Rest], Arguments) ->
+ parse(Rest, Arguments#arguments{out = Out});
+parse([Module | Rest], Arguments = #arguments{modules = Modules}) ->
+ parse(Rest, Arguments#arguments{modules = [Module | Modules]}).
+
+configure_logging() ->
+ Enabled = os:getenv("GLEAM_LOG") /= false,
+ persistent_term:put(gleam_logging_enabled, Enabled).
+
+log(Term) ->
+ case persistent_term:get(gleam_logging_enabled) of
+ true -> erlang:display(Term), ok;
+ false -> ok
+ end.
diff --git a/aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.cache b/aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.cache
new file mode 100644
index 0000000..bc9c27c
--- /dev/null
+++ b/aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.cache
Binary files differ
diff --git a/aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.cache_meta b/aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.cache_meta
new file mode 100644
index 0000000..daef1e9
--- /dev/null
+++ b/aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.cache_meta
Binary files differ
diff --git a/aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.erl b/aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.erl
new file mode 100644
index 0000000..92d4f80
--- /dev/null
+++ b/aoc2023/build/dev/erlang/snag/_gleam_artefacts/snag.erl
@@ -0,0 +1,74 @@
+-module(snag).
+-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
+
+-export([new/1, error/1, layer/2, context/2, pretty_print/1, line_print/1]).
+-export_type([snag/0]).
+
+-type snag() :: {snag, binary(), list(binary())}.
+
+-spec new(binary()) -> snag().
+new(Issue) ->
+ {snag, Issue, []}.
+
+-spec error(binary()) -> {ok, any()} | {error, snag()}.
+error(Issue) ->
+ {error, new(Issue)}.
+
+-spec layer(snag(), binary()) -> snag().
+layer(Snag, Issue) ->
+ {snag, Issue, [erlang:element(2, Snag) | erlang:element(3, Snag)]}.
+
+-spec context({ok, KFH} | {error, snag()}, binary()) -> {ok, KFH} |
+ {error, snag()}.
+context(Result, Issue) ->
+ case Result of
+ {ok, _} ->
+ Result;
+
+ {error, Snag} ->
+ {error, layer(Snag, Issue)}
+ end.
+
+-spec pretty_print_cause(list(binary())) -> gleam@string_builder:string_builder().
+pretty_print_cause(Cause) ->
+ _pipe = Cause,
+ _pipe@1 = gleam@list:index_map(
+ _pipe,
+ fun(Index, Line) ->
+ gleam@string:concat(
+ [<<" "/utf8>>,
+ gleam@int:to_string(Index),
+ <<": "/utf8>>,
+ Line,
+ <<"\n"/utf8>>]
+ )
+ end
+ ),
+ gleam@string_builder:from_strings(_pipe@1).
+
+-spec pretty_print(snag()) -> binary().
+pretty_print(Snag) ->
+ Builder = gleam@string_builder:from_strings(
+ [<<"error: "/utf8>>, erlang:element(2, Snag), <<"\n"/utf8>>]
+ ),
+ gleam@string_builder:to_string(case erlang:element(3, Snag) of
+ [] ->
+ Builder;
+
+ Cause ->
+ _pipe = Builder,
+ _pipe@1 = gleam@string_builder:append(
+ _pipe,
+ <<"\ncause:\n"/utf8>>
+ ),
+ gleam@string_builder:append_builder(
+ _pipe@1,
+ pretty_print_cause(Cause)
+ )
+ end).
+
+-spec line_print(snag()) -> binary().
+line_print(Snag) ->
+ _pipe = [gleam@string:append(<<"error: "/utf8>>, erlang:element(2, Snag)) |
+ erlang:element(3, Snag)],
+ gleam@string:join(_pipe, <<" <- "/utf8>>).