Files
mercury/samples/sort.m
Julien Fischer 41d2622092 Fix compilation of samples/sort.m.
samples/sort.m:
   Replace use of io.see and io.tell with explicit streams.

   Use state variable notation in more spots.

   Simplify some code.
2022-03-06 02:49:37 +11:00

140 lines
3.8 KiB
Mathematica

%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
%
% A simple sorting program.
%
% It works on text files, considering each line to be a record.
% The entire line is considered to be the sort key.
%
% The algorithm used is simple insertion sort.
%
% This source file is hereby placed in the public domain. -fjh (the author).
%
%-----------------------------------------------------------------------------%
:- module sort.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module char.
:- import_module list.
:- import_module maybe.
:- import_module require.
:- import_module string.
%-----------------------------------------------------------------------------%
main(!IO) :-
io.command_line_arguments(Args, !IO),
(
(
Args = [],
handle_args(no, InputFile, no, OutputFile, !IO)
;
Args = [Input],
handle_args(yes(Input), InputFile, no, OutputFile, !IO)
;
Args = [Input, Output],
handle_args(yes(Input), InputFile, yes(Output), OutputFile, !IO)
),
sort(InputFile, OutputFile, !IO)
;
Args = [_, _, _ | _],
io.write_string("Usage: sort [Input [Output]]\\n", !IO)
).
:- pred handle_args(maybe(string)::in, io.text_input_stream::out,
maybe(string)::in, io.text_output_stream::out, io::di, io::uo)
is det.
handle_args(InArg, InFile, OutArg, OutFile, !IO) :-
(
InArg = yes(InFilename),
io.open_input(InFilename, InResult, !IO),
(
InResult = ok(InFile)
;
InResult = error(InError),
io.error_message(InError, InMsg),
error(InMsg)
)
;
InArg = no,
io.stdin_stream(InFile, !IO)
),
(
OutArg = yes(OutFilename),
io.open_output(OutFilename, OutResult, !IO),
(
OutResult = ok(OutFile)
;
OutResult = error(OutError),
io.error_message(OutError, OutMsg),
error(OutMsg)
)
;
OutArg = no,
io.stdout_stream(OutFile, !IO)
).
:- pred sort(io.text_input_stream::in, io.text_output_stream::in,
io::di, io::uo) is det.
sort(InFile, OutFile, !IO) :-
sort_2(InFile, OutFile, [], !IO).
:- pred sort_2(io.text_input_stream::in, io.text_output_stream::in,
list(string)::in, io::di, io::uo) is det.
sort_2(InFile, OutFile, !.Lines, !IO) :-
io.read_line_as_string(InFile, Result, !IO),
(
Result = error(Error),
io.error_message(Error, Msg),
error(Msg)
;
Result = eof,
output_sorted_lines(OutFile, !.Lines, !IO)
;
Result = ok(Line),
insert_line(Line, !Lines),
sort_2(InFile, OutFile, !.Lines, !IO)
).
:- pred insert_line(string::in, list(string)::in, list(string)::out) is det.
insert_line(I, [], [I]).
insert_line(I, [H | T], L) :-
compare(R, I, H),
(
R = (<),
L = [I, H | T]
;
( R = (=)
; R = (>)
),
insert_line(I, T, NT),
L = [H | NT]
).
:- pred output_sorted_lines(io.text_output_stream::in, list(string)::in,
io::di, io::uo) is det.
output_sorted_lines(_, [], !IO).
output_sorted_lines(OutFile, [Line | Lines], !IO) :-
io.write_string(OutFile, Line, !IO),
output_sorted_lines(OutFile, Lines, !IO).
%-----------------------------------------------------------------------------%
:- end_module sort.
%-----------------------------------------------------------------------------%