From ea6fb40895f06d5c9b3ba72e55f918fd22c48dcd Mon Sep 17 00:00:00 2001 From: rhiannon morris Date: Thu, 1 Dec 2022 08:56:19 +0100 Subject: [PATCH] first --- .gitignore | 4 ++++ aoc.m | 42 ++++++++++++++++++++++++++++++++++++++++++ basics.m | 13 +++++++++++++ die.m | 29 +++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 .gitignore create mode 100644 aoc.m create mode 100644 basics.m create mode 100644 die.m diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a2a2f6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +Mercury/ +*.mh +*.err +aoc diff --git a/aoc.m b/aoc.m new file mode 100644 index 0000000..956b953 --- /dev/null +++ b/aoc.m @@ -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)]). diff --git a/basics.m b/basics.m new file mode 100644 index 0000000..cb70428 --- /dev/null +++ b/basics.m @@ -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). diff --git a/die.m b/die.m new file mode 100644 index 0000000..3149536 --- /dev/null +++ b/die.m @@ -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) + ).