diff options
Diffstat (limited to 'aoc2023/build/dev/erlang/simplifile')
-rw-r--r-- | aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/gleam@@compile.erl | 157 | ||||
-rw-r--r-- | aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.cache | bin | 0 -> 20593 bytes | |||
-rw-r--r-- | aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.cache_meta | bin | 0 -> 110 bytes | |||
-rw-r--r-- | aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.erl | 287 | ||||
-rw-r--r-- | aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile_erl.erl | 70 | ||||
-rw-r--r-- | aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile_js.mjs | 102 | ||||
-rw-r--r-- | aoc2023/build/dev/erlang/simplifile/ebin/simplifile.app | 7 | ||||
-rw-r--r-- | aoc2023/build/dev/erlang/simplifile/ebin/simplifile.beam | bin | 0 -> 10372 bytes | |||
-rw-r--r-- | aoc2023/build/dev/erlang/simplifile/ebin/simplifile_erl.beam | bin | 0 -> 4484 bytes |
9 files changed, 623 insertions, 0 deletions
diff --git a/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/gleam@@compile.erl b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/gleam@@compile.erl new file mode 100644 index 0000000..543db88 --- /dev/null +++ b/aoc2023/build/dev/erlang/simplifile/_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/simplifile/_gleam_artefacts/simplifile.cache b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.cache Binary files differnew file mode 100644 index 0000000..bf0b1d7 --- /dev/null +++ b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.cache diff --git a/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.cache_meta b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.cache_meta Binary files differnew file mode 100644 index 0000000..90aa893 --- /dev/null +++ b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.cache_meta diff --git a/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.erl b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.erl new file mode 100644 index 0000000..2dbeac9 --- /dev/null +++ b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile.erl @@ -0,0 +1,287 @@ +-module(simplifile). +-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). + +-export([read/1, write/2, delete/1, delete_all/1, append/2, read_bits/1, write_bits/2, append_bits/2, is_directory/1, create_directory/1, read_directory/1, is_file/1, create_file/1, get_files/1, create_directory_all/1, copy_directory/2, rename_directory/2, copy_file/2, rename_file/2]). +-export_type([file_error/0]). + +-type file_error() :: eacces | + eagain | + ebadf | + ebadmsg | + ebusy | + edeadlk | + edeadlock | + edquot | + eexist | + efault | + efbig | + eftype | + eintr | + einval | + eio | + eisdir | + eloop | + emfile | + emlink | + emultihop | + enametoolong | + enfile | + enobufs | + enodev | + enolck | + enolink | + enoent | + enomem | + enospc | + enosr | + enostr | + enosys | + enotblk | + enotdir | + enotsup | + enxio | + eopnotsupp | + eoverflow | + eperm | + epipe | + erange | + erofs | + espipe | + esrch | + estale | + etxtbsy | + exdev | + not_utf8 | + unknown. + +-spec do_append(binary(), binary()) -> {ok, nil} | {error, file_error()}. +do_append(Content, Filepath) -> + _pipe = Content, + _pipe@1 = gleam_stdlib:identity(_pipe), + simplifile_erl:append_file(_pipe@1, Filepath). + +-spec do_write(binary(), binary()) -> {ok, nil} | {error, file_error()}. +do_write(Content, Filepath) -> + _pipe = Content, + _pipe@1 = gleam_stdlib:identity(_pipe), + simplifile_erl:write_file(_pipe@1, Filepath). + +-spec do_read(binary()) -> {ok, binary()} | {error, file_error()}. +do_read(Filepath) -> + case simplifile_erl:read_file(Filepath) of + {ok, Bits} -> + case gleam@bit_array:to_string(Bits) of + {ok, Str} -> + {ok, Str}; + + _ -> + {error, not_utf8} + end; + + {error, E} -> + {error, E} + end. + +-spec cast_error({ok, FJY} | {error, file_error()}) -> {ok, FJY} | + {error, file_error()}. +cast_error(Input) -> + Input. + +-spec read(binary()) -> {ok, binary()} | {error, file_error()}. +read(Filepath) -> + _pipe = do_read(Filepath), + cast_error(_pipe). + +-spec write(binary(), binary()) -> {ok, nil} | {error, file_error()}. +write(Filepath, Contents) -> + _pipe = do_write(Contents, Filepath), + cast_error(_pipe). + +-spec delete(binary()) -> {ok, nil} | {error, file_error()}. +delete(Path) -> + _pipe = simplifile_erl:recursive_delete(Path), + cast_error(_pipe). + +-spec delete_all(list(binary())) -> {ok, nil} | {error, file_error()}. +delete_all(Paths) -> + case Paths of + [] -> + {ok, nil}; + + [Path | Rest] -> + case delete(Path) of + {ok, nil} -> + delete_all(Rest); + + {error, enoent} -> + delete_all(Rest); + + E -> + E + end + end. + +-spec append(binary(), binary()) -> {ok, nil} | {error, file_error()}. +append(Filepath, Contents) -> + _pipe = do_append(Contents, Filepath), + cast_error(_pipe). + +-spec read_bits(binary()) -> {ok, bitstring()} | {error, file_error()}. +read_bits(Filepath) -> + _pipe = simplifile_erl:read_file(Filepath), + cast_error(_pipe). + +-spec write_bits(binary(), bitstring()) -> {ok, nil} | {error, file_error()}. +write_bits(Filepath, Bits) -> + _pipe = simplifile_erl:write_file(Bits, Filepath), + cast_error(_pipe). + +-spec append_bits(binary(), bitstring()) -> {ok, nil} | {error, file_error()}. +append_bits(Filepath, Bits) -> + _pipe = simplifile_erl:append_file(Bits, Filepath), + cast_error(_pipe). + +-spec is_directory(binary()) -> boolean(). +is_directory(Filepath) -> + filelib:is_dir(Filepath). + +-spec create_directory(binary()) -> {ok, nil} | {error, file_error()}. +create_directory(Filepath) -> + _pipe = simplifile_erl:make_directory(Filepath), + cast_error(_pipe). + +-spec read_directory(binary()) -> {ok, list(binary())} | {error, file_error()}. +read_directory(Path) -> + _pipe = simplifile_erl:list_directory(Path), + cast_error(_pipe). + +-spec is_file(binary()) -> boolean(). +is_file(Filepath) -> + simplifile_erl:is_file(Filepath). + +-spec create_file(binary()) -> {ok, nil} | {error, file_error()}. +create_file(Filepath) -> + case begin + _pipe = Filepath, + is_file(_pipe) + end + orelse begin + _pipe@1 = Filepath, + is_directory(_pipe@1) + end of + true -> + {error, eexist}; + + false -> + write_bits(Filepath, <<>>) + end. + +-spec do_copy_directory(binary(), binary()) -> {ok, nil} | {error, file_error()}. +do_copy_directory(Src, Dest) -> + gleam@result:'try'( + read_directory(Src), + fun(Segments) -> + _pipe = Segments, + gleam@list:each( + _pipe, + fun(Segment) -> + Src_path = <<<<Src/binary, "/"/utf8>>/binary, + Segment/binary>>, + Dest_path = <<<<Dest/binary, "/"/utf8>>/binary, + Segment/binary>>, + case {is_file(Src_path), is_directory(Src_path)} of + {true, false} -> + gleam@result:'try'( + read_bits(Src_path), + fun(Content) -> _pipe@1 = Content, + write_bits(Dest_path, _pipe@1) end + ); + + {false, true} -> + gleam@result:'try'( + create_directory(Dest_path), + fun(_) -> + do_copy_directory(Src_path, Dest_path) + end + ); + + {_, _} -> + erlang:error(#{gleam_error => panic, + message => <<"unreachable"/utf8>>, + module => <<"simplifile"/utf8>>, + function => <<"do_copy_directory"/utf8>>, + line => 341}) + end + end + ), + {ok, nil} + end + ). + +-spec get_files(binary()) -> {ok, list(binary())} | {error, file_error()}. +get_files(Directory) -> + gleam@result:'try'( + read_directory(Directory), + fun(Contents) -> + Paths = gleam@list:map( + Contents, + fun(Segment) -> + <<<<Directory/binary, "/"/utf8>>/binary, Segment/binary>> + end + ), + Files = gleam@list:filter(Paths, fun is_file/1), + case gleam@list:filter(Paths, fun is_directory/1) of + [] -> + {ok, Files}; + + Directories -> + gleam@result:'try'( + gleam@list:try_map(Directories, fun get_files/1), + fun(Nested_files) -> + {ok, + gleam@list:append( + Files, + gleam@list:flatten(Nested_files) + )} + end + ) + end + end + ). + +-spec create_directory_all(binary()) -> {ok, nil} | {error, file_error()}. +create_directory_all(Dirpath) -> + Path = case begin + _pipe = Dirpath, + gleam@string:ends_with(_pipe, <<"/"/utf8>>) + end of + true -> + Dirpath; + + false -> + <<Dirpath/binary, "/"/utf8>> + end, + _pipe@1 = simplifile_erl:create_dir_all(Path), + cast_error(_pipe@1). + +-spec copy_directory(binary(), binary()) -> {ok, nil} | {error, file_error()}. +copy_directory(Src, Dest) -> + gleam@result:'try'( + create_directory_all(Dest), + fun(_) -> do_copy_directory(Src, Dest) end + ). + +-spec rename_directory(binary(), binary()) -> {ok, nil} | {error, file_error()}. +rename_directory(Src, Dest) -> + gleam@result:'try'(copy_directory(Src, Dest), fun(_) -> delete(Src) end). + +-spec copy_file(binary(), binary()) -> {ok, nil} | {error, file_error()}. +copy_file(Src, Dest) -> + _pipe = file:copy(Src, Dest), + _pipe@1 = gleam@result:replace(_pipe, nil), + cast_error(_pipe@1). + +-spec rename_file(binary(), binary()) -> {ok, nil} | {error, file_error()}. +rename_file(Src, Dest) -> + _pipe = simplifile_erl:rename_file(Src, Dest), + cast_error(_pipe). diff --git a/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile_erl.erl b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile_erl.erl new file mode 100644 index 0000000..dac135a --- /dev/null +++ b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile_erl.erl @@ -0,0 +1,70 @@ +-module(simplifile_erl). +-export([ + read_file/1, + append_file/2, write_file/2, delete_file/1, delete_directory/1, recursive_delete/1, + list_directory/1, make_directory/1, is_file/1, create_dir_all/1, rename_file/2 +]). + +-define(is_posix_error(Error), + Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse + Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse + Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse + Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse + Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse + Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse + Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse + Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse + Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse + Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse + Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse + Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse + Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse + Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse + Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse + Error =:= etxtbsy orelse Error =:= exdev +). + +posix_result(Result) -> + case Result of + ok -> {ok, nil}; + {ok, Value} -> {ok, Value}; + {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} + end. + +read_file(Filename) -> + posix_result(file:read_file(Filename)). + +write_file(Contents, Filename) -> + posix_result(file:write_file(Filename, Contents)). + +append_file(Contents, Filename) -> + posix_result(file:write_file(Filename, Contents, [append])). + +delete_file(Filename) -> + posix_result(file:delete(Filename)). + +make_directory(Dir) -> + posix_result(file:make_dir(Dir)). + +list_directory(Dir) -> + case file:list_dir(Dir) of + {ok, Filenames} -> + {ok, [list_to_binary(Filename) || Filename <- Filenames]}; + {error, Reason} when ?is_posix_error(Reason) -> + {error, Reason} + end. + +delete_directory(Dir) -> + posix_result(file:del_dir(Dir)). + +recursive_delete(Dir) -> + posix_result(file:del_dir_r(Dir)). + +is_file(Filename) -> + not (file:read_file_info(Filename) == {error, enoent}) and not filelib: is_dir(Filename). + +create_dir_all(Filename) -> + posix_result(filelib:ensure_dir(Filename)). + +rename_file(Source, Destination) -> + posix_result(file:rename(Source, Destination)). diff --git a/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile_js.mjs b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile_js.mjs new file mode 100644 index 0000000..faf4109 --- /dev/null +++ b/aoc2023/build/dev/erlang/simplifile/_gleam_artefacts/simplifile_js.mjs @@ -0,0 +1,102 @@ +import fs from "node:fs" +import path from "node:path" +import { BitArray, Ok, Error as GError, toList} from "./gleam.mjs"; + +export function readBits(filepath) { + try { + const contents = fs.readFileSync(path.normalize(filepath)) + return new Ok(new BitArray(new Uint8Array(contents))) + } catch(e) { + return new GError(stringifyError(e)) + } +} + +export function writeBits(contents, filepath) { + try { + fs.writeFileSync(path.normalize(filepath), contents.buffer) + return new Ok(undefined) + } catch (e) { + return new GError(stringifyError(e)) + } +} + +export function appendBits(contents, filepath) { + try { + fs.appendFileSync(path.normalize(filepath), contents.buffer) + return new Ok(undefined) + } catch (e) { + return new GError(stringifyError(e)) + } +} + +function stringifyError(e) { + return e.code +} + +export function isFile(filepath) { + let fp = path.normalize(filepath) + return fs.existsSync(fp) && fs.lstatSync(fp).isFile(); +} + +export function isDirectory(filepath) { + let fp = path.normalize(filepath) + return fs.existsSync(fp) && fs.lstatSync(fp).isDirectory(); +} + +export function makeDirectory(filepath) { + try { + fs.mkdirSync(path.normalize(filepath)) + return new Ok(undefined) + } catch (e) { + return new GError(stringifyError(e)) + } +} + +export function createDirAll(filepath) { + try { + fs.mkdirSync(filepath, { recursive: true }) + return new Ok(undefined) + } catch (e) { + return new GError(stringifyError(e)) + } +} + +export function deleteFileOrDirRecursive(fileOrDirPath) { + try { + if (isDirectory(fileOrDirPath)) { + fs.rmSync(path.normalize(fileOrDirPath), { recursive: true }) + } else { + fs.unlinkSync(path.normalize(fileOrDirPath)) + } + return new Ok(undefined) + } catch (e) { + return new GError(stringifyError(e)) + } +} + +export function listContents(filepath) { + try { + const stuff = toList(fs.readdirSync(path.normalize(filepath))) + return new Ok(stuff) + } catch(e) { + return new GError(stringifyError(e)) + } +} + +export function copyFile(srcpath, destpath) { + try { + fs.copyFileSync(path.normalize(srcpath), path.normalize(destpath)) + return new Ok(undefined) + } catch (e) { + return new GError(stringifyError(e)) + } +} + +export function renameFile(srcpath, destpath) { + try { + fs.renameSync(path.normalize(srcpath), path.normalize(destpath)) + return new Ok(undefined) + } catch (e) { + return new GError(stringifyError(e)) + } +}
\ No newline at end of file diff --git a/aoc2023/build/dev/erlang/simplifile/ebin/simplifile.app b/aoc2023/build/dev/erlang/simplifile/ebin/simplifile.app new file mode 100644 index 0000000..3bb63fa --- /dev/null +++ b/aoc2023/build/dev/erlang/simplifile/ebin/simplifile.app @@ -0,0 +1,7 @@ +{application, simplifile, [ + {vsn, "1.0.0"}, + {applications, [gleam_stdlib]}, + {description, "Basic file operations that work on all targets"}, + {modules, []}, + {registered, []} +]}. diff --git a/aoc2023/build/dev/erlang/simplifile/ebin/simplifile.beam b/aoc2023/build/dev/erlang/simplifile/ebin/simplifile.beam Binary files differnew file mode 100644 index 0000000..6631cad --- /dev/null +++ b/aoc2023/build/dev/erlang/simplifile/ebin/simplifile.beam diff --git a/aoc2023/build/dev/erlang/simplifile/ebin/simplifile_erl.beam b/aoc2023/build/dev/erlang/simplifile/ebin/simplifile_erl.beam Binary files differnew file mode 100644 index 0000000..2abefda --- /dev/null +++ b/aoc2023/build/dev/erlang/simplifile/ebin/simplifile_erl.beam |