This commit is contained in:
rhiannon morris 2022-12-01 08:56:19 +01:00
commit ea6fb40895
4 changed files with 88 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
Mercury/
*.mh
*.err
aoc

42
aoc.m Normal file
View file

@ -0,0 +1,42 @@
:- module aoc.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is cc_multi.
:- implementation.
:- import_module basics.
:- import_module die.
:- import_module string.
:- import_module list.
:- import_module exception.
main(!IO) :- wrap_main(main2, !IO).
:- pred main2(io::di, io::uo) is cc_multi.
:- pragma no_determinism_warning(main2/2).
main2(!IO) :-
command_line_arguments(Args, !IO),
(if (Args = [DayS, PartS | Rest],
to_int(DayS, Day),
part(PartS, Part))
then
run(Day, Part, Rest, !IO)
else if Args = [D, P | _] then
die("expected a day and a part, got ""%s"" ""%s""", [s(D), s(P)])
else
die("expected at least two args")).
:- type solution == (pred(part, list(string), io, io)).
:- inst solution == (pred(in, in, di, uo) is det).
:- pred solution(int::in, solution::out(solution)) is semidet.
solution(_, _) :- fail.
:- pred run(int::in, part::in, list(string)::in, io::di, io::uo) is det.
run(Day, Part, Args, !IO) :-
if solution(Day, P) then
P(Part, Args, !IO)
else
die("no solution for day %d", [i(Day)]).

13
basics.m Normal file
View file

@ -0,0 +1,13 @@
:- module basics.
:- interface.
:- type part ---> one; two.
:- pred part(string, part).
:- mode part(in, out) is semidet.
:- mode part(out, in) is semidet.
:- implementation.
part("1", one).
part("2", two).

29
die.m Normal file
View file

@ -0,0 +1,29 @@
:- module die.
:- interface.
:- import_module io.
:- import_module list.
:- import_module string.
:- pred die(string::in) is erroneous.
:- pred die(string::in, list(poly_type)::in) is erroneous.
:- type main == (pred(io, io)).
:- inst main == (pred(di, uo) is cc_multi).
:- pred wrap_main(main::in(main), io::di, io::uo) is cc_multi.
:- implementation.
:- import_module exception.
:- type die ---> death(string).
die(Str) :- throw(death(Str)).
die(Fmt, Args) :- die(format(Fmt, Args)).
wrap_main(Main, !IO) :-
try [io(!IO)] Main(!IO)
then true
catch death(Err) -> (
format("%s\n", [s(Err)], !IO),
set_exit_status(1, !IO)
).