Files
mercury/tests/declarative_debugger/sort.m
Zoltan Somogyi ecb5e4a9e6 Update the style of many test cases.
tests/declarative_debugger/*.m:
tests/exceptions/*.m:
tests/general/*.m:
tests/grade_subdirs/*.m:
tests/purity/*.m:
tests/submodules/*.m:
tests/typeclasses/*.m:
    Update programming style.

tests/declarative_debugger/*.inp:
    Update line numbers in breakpoint commands.
tests/declarative_debugger/*.exp:
    Update expected line numbers.

tests/exceptions/Mercury.options:
tests/general/Mercury.options:
    Disable some warnings that are irrelevant to the test.
2021-07-25 23:26:17 +10:00

146 lines
3.9 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module sort.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
%---------------------------------------------------------------------------%
:- implementation.
:- import_module exception.
:- import_module int.
:- import_module list.
:- import_module maybe.
:- import_module string.
%---------------------------------------------------------------------------%
:- type line == string.
:- type lines == list(string).
main(!IO) :-
io.command_line_arguments(Args, !IO),
open_stream(Args, MaybeStream, !IO),
(
MaybeStream = ok(InputStream),
some [!Words] (
read_lines(InputStream, !:Words, !IO),
sort_lines(!Words),
print_lines(!.Words, !IO)
)
;
MaybeStream = error(ErrorMessage),
io.stderr_stream(StdErr, !IO),
io.format(StdErr, "%s\n", [s(ErrorMessage)], !IO),
io.set_exit_status(1, !IO)
).
%---------------------------------------------------------------------------%
:- pred open_stream(list(string)::in, maybe_error(io.input_stream)::out,
io::di, io::uo) is det.
open_stream([], MaybeStream, !IO) :-
io.stdin_stream(Stdin, !IO),
MaybeStream = ok(Stdin).
open_stream([Arg], MaybeStream, !IO) :-
io.open_input(Arg, MaybeStream0, !IO),
(
MaybeStream0 = ok(Stream),
MaybeStream = ok(Stream)
;
MaybeStream0 = error(Error),
io.error_message(Error, ErrorMessage),
MaybeStream = error(ErrorMessage)
).
open_stream([_, _ | _], error(ErrorMessage), !IO) :-
ErrorMessage = "usage: sort [Input]".
%---------------------------------------------------------------------------%
:- pred read_lines(io.input_stream::in, lines::out, io::di, io::uo) is det.
read_lines(Stream, Lines, !IO) :-
read_lines_2(Stream, [], Lines, !IO).
:- pred read_lines_2(io.input_stream::in, lines::in,
lines::out, io::di, io::uo) is det.
read_lines_2(Stream, !Lines, !IO) :-
io.read_line_as_string(Stream, Result, !IO),
(
Result = ok(Line),
list.cons(Line, !Lines),
read_lines_2(Stream, !Lines, !IO)
;
Result = eof
;
Result = error(Error),
io.error_message(Error, ErrorMessage),
throw(ErrorMessage)
).
%---------------------------------------------------------------------------%
:- pred sort_lines(lines::in, lines::out) is det.
sort_lines(Us, Ss) :-
N = list.length(Us),
msort_n(N, Us, Ss, _).
:- pred msort_n(int::in, lines::in, lines::out, lines::out) is det.
msort_n(N, Unsorted, SortedPart, Rest) :-
( if N =< 0 then
SortedPart = [],
Rest = Unsorted
else if N = 1 then
(
Unsorted = [U | Us],
SortedPart = [U],
Rest = Us
;
Unsorted = [],
throw("Unsorted = [] and N = 0")
)
else
N1 = N // 2,
sort.msort_n(N1, Unsorted, Ss1, Us2),
N2 = N - N1,
msort_n(N2, Us2, Ss2, Rest),
sort.merge(Ss1, Ss2, SortedPart)
).
:- pred merge(lines::in, lines::in, lines::out) is det.
merge([], [], []).
merge([S | Ss], [], [S | Ss]).
merge([], [S | Ss], [S | Ss]).
merge([A | As], [B | Bs], [C | Cs]) :-
compare(Cmp, A, B),
( if ( Cmp = (<) ; Cmp = (=) ) then
sort.merge(As, [B | Bs], Cs),
C = A
else
sort.merge(As, [B | Bs], Cs), % BUG
C = B
).
%---------------------------------------------------------------------------%
:- pred print_lines(lines::in, io::di, io::uo) is det.
print_lines(Lines, !IO) :-
io.write_list(Lines, "", io.write_string, !IO).
%---------------------------------------------------------------------------%
:- end_module sort.
%---------------------------------------------------------------------------%