[m-rev.] for review: start integrating stream typeclasses into stdlib
Julien Fischer
juliensf at csse.unimelb.edu.au
Thu Oct 26 16:12:13 AEST 2006
For review by anyone.
Estimated hours taken: 2
Branches: main
Start integrating the new stream typeclasses into the rest of the
standard library.
library/io.m:
Make the standard text and binary files streams from the io
modules instances of the new stream typeclasses.
(Note: I've only made instances of the obvious types, we
will probably want to define a few more, e.g.
:- type line ---> line(string)
).
Unrelated change: move the implementation of the function
version of io.error_message next to its predicate version.
library/pprint.m:
Generalise pprint.write so that it can write docs to any
arbitrary string writer. (This is backwards compatible with
existing uses of this prediate.)
tests/hard_coded/Mmakefile:
tests/hard_coded/stream_tests.{m,exp,data}:
A short test of the new stream typeclasses.
Julien.
Index: library/io.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.361
diff -u -r1.361 io.m
--- library/io.m 24 Oct 2006 02:59:46 -0000 1.361
+++ library/io.m 26 Oct 2006 05:28:29 -0000
@@ -34,6 +34,7 @@
:- import_module list.
:- import_module map.
:- import_module maybe.
+:- import_module stream.
:- import_module string.
:- import_module time.
:- import_module univ.
@@ -1356,6 +1357,41 @@
:- pred io.error_message(io.error::in, string::out) is det.
%-----------------------------------------------------------------------------%
+%
+% Instances of the stream typeclass
+%
+
+:- instance stream.error(io.error).
+
+:- instance stream.stream(io.output_stream, io.state).
+:- instance stream.output(io.output_stream, io.state).
+:- instance stream.writer(io.output_stream, char, io.state).
+:- instance stream.writer(io.output_stream, float, io.state).
+:- instance stream.writer(io.output_stream, int, io.state).
+:- instance stream.writer(io.output_stream, string, io.state).
+:- instance stream.writer(io.output_stream, univ, io.state).
+:- instance stream.line_oriented(io.output_stream, io.state).
+
+:- instance stream.stream(io.input_stream, io.state).
+:- instance stream.input(io.input_stream, io.state, io.error).
+:- instance stream.reader(io.input_stream, char, io.state, io.error).
+
+:- instance stream.line_oriented(io.input_stream, io.state).
+:- instance stream.putback(io.input_stream, char, io.state, io.error).
+
+:- instance stream.stream(io.binary_output_stream, io.state).
+:- instance stream.output(io.binary_output_stream, io.state).
+:- instance stream.writer(io.binary_output_stream, int, io.state).
+:- instance stream.writer(io.binary_output_stream, string, io.state).
+:- instance stream.seekable(io.binary_output_stream, io.state).
+
+:- instance stream.stream(io.binary_input_stream, io.state).
+:- instance stream.input(io.binary_input_stream, io.state, io.error).
+:- instance stream.reader(io.binary_input_stream, int, io.state, io.error).
+:- instance stream.putback(io.binary_input_stream, int, io.state, io.error).
+:- instance stream.seekable(io.binary_input_stream, io.state).
+
+%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
@@ -5097,6 +5133,9 @@
io.make_io_error(Error) = io_error(Error).
+io.error_message(Error) = Msg :-
+ io.error_message(Error, Msg).
+
io.error_message(io_error(Error), Error).
%-----------------------------------------------------------------------------%
@@ -8964,12 +9003,189 @@
}
").
-/*---------------------------------------------------------------------------*/
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+%
+% Instances of the stream typeclass
+%
+
+:- instance stream.error(io.error) where [
+ func(stream.error_message/1) is io.error_message
+].
%-----------------------------------------------------------------------------%
+%
+% Text input streams
+%
+
+:- instance stream.stream(io.input_stream, io.state) where [
+ pred(name/4) is io.input_stream_name
+].
+
+:- instance stream.input(io.input_stream, io.state, io.error) where [].
+
+:- instance stream.reader(io.input_stream, char, io.state, io.error)
+ where
+[
+ ( get(Stream, Result, !IO) :-
+ io.read_char(Stream, Result0, !IO),
+ Result = io.result_to_stream_result(Result0)
+ )
+].
+
+:- instance stream.reader(io.input_stream, string, io.state, io.error)
+ where
+[
+ ( get(Stream, Result, !IO) :-
+ io.read_line_as_string(Stream, Result0, !IO),
+ Result = io.result_to_stream_result(Result0)
+ )
+].
+
+:- instance stream.putback(io.input_stream, char, io.state, io.error) where
+[
+ pred(unget/4) is io.putback_char
+].
+
+:- func io.result_to_stream_result(io.result(T)) = stream.result(T, io.error).
+
+io.result_to_stream_result(ok(T)) = ok(T).
+io.result_to_stream_result(eof) = eof.
+io.result_to_stream_result(error(Error)) = error(Error).
+
+
+:- instance stream.line_oriented(io.input_stream, io.state) where
+[
+ pred(get_line/4) is io.get_line_number,
+ pred(set_line/4) is io.set_line_number
+].
+
%-----------------------------------------------------------------------------%
-% Ralph Becket <rwab1 at cl.cam.ac.uk> 27/04/99
-% Functional forms added.
+%
+% Text output streams
+%
-io.error_message(Error) = Msg :-
- io.error_message(Error, Msg).
+:- instance stream.stream(io.output_stream, io.state) where [
+ pred(name/4) is io.output_stream_name
+].
+
+:- instance stream.output(io.output_stream, io.state) where [
+ pred(flush/3) is io.flush_output
+].
+
+:- instance stream.writer(io.output_stream, char, io.state)
+ where
+[
+ pred(put/4) is io.write_char
+].
+
+:- instance stream.writer(io.output_stream, float, io.state)
+ where
+[
+ pred(put/4) is io.write_float
+].
+
+:- instance stream.writer(io.output_stream, int, io.state)
+ where
+[
+ pred(put/4) is io.write_int
+].
+
+:- instance stream.writer(io.output_stream, string, io.state)
+ where
+[
+ pred(put/4) is io.write_string
+].
+
+:- instance stream.writer(io.output_stream, univ, io.state)
+ where
+[
+ pred(put/4) is io.write_univ
+].
+
+:- instance stream.line_oriented(io.output_stream, io.state) where
+[
+ pred(get_line/4) is io.get_output_line_number,
+ pred(set_line/4) is io.set_output_line_number
+].
+
+%-----------------------------------------------------------------------------%
+%
+% Binary input streams
+%
+
+:- instance stream.stream(io.binary_input_stream, io.state)
+ where
+[
+ pred(name/4) is io.binary_input_stream_name
+].
+
+:- instance stream.input(io.binary_input_stream, io.state, io.error)
+ where [].
+
+:- instance stream.reader(io.binary_input_stream, int, io.state, io.error)
+ where
+[
+ ( get(Stream, Result, !IO) :-
+ io.read_byte(Stream, Result0, !IO),
+ Result = io.result_to_stream_result(Result0)
+ )
+].
+
+:- instance stream.putback(io.binary_input_stream, int, io.state, io.error)
+ where
+[
+ pred(unget/4) is io.putback_byte
+].
+
+:- instance stream.seekable(io.binary_input_stream, io.state)
+ where
+[
+ ( seek(Stream, Whence0, OffSet, !IO) :-
+ Whence = stream_whence_to_io_whence(Whence0),
+ io.seek_binary_input(Stream, Whence, OffSet, !IO)
+ )
+].
+
+:- func stream_whence_to_io_whence(stream.whence) = io.whence.
+
+stream_whence_to_io_whence(set) = set.
+stream_whence_to_io_whence(cur) = cur.
+stream_whence_to_io_whence(end) = end.
+
+%-----------------------------------------------------------------------------%
+%
+% Binary output streams
+%
+
+:- instance stream.stream(io.binary_output_stream, io.state) where [
+ pred(name/4) is io.binary_output_stream_name
+].
+
+:- instance stream.output(io.binary_output_stream, io.state) where [
+ pred(flush/3) is io.flush_binary_output
+].
+
+:- instance stream.writer(io.binary_output_stream, int, io.state)
+ where
+[
+ pred(put/4) is io.write_byte
+].
+
+:- instance stream.writer(io.binary_output_stream, string, io.state)
+ where
+[
+ pred(put/4) is io.write_bytes
+].
+
+:- instance stream.seekable(io.binary_output_stream, io.state)
+ where
+[
+ ( seek(Stream, Whence0, OffSet, !IO) :-
+ Whence = stream_whence_to_io_whence(Whence0),
+ io.seek_binary_output(Stream, Whence, OffSet, !IO)
+ )
+].
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
Index: library/pprint.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/pprint.m,v
retrieving revision 1.26
diff -u -r1.26 pprint.m
--- library/pprint.m 27 Sep 2006 06:16:41 -0000 1.26
+++ library/pprint.m 26 Oct 2006 05:43:47 -0000
@@ -156,6 +156,7 @@
:- import_module char.
:- import_module io.
:- import_module list.
+:- import_module stream.
:- import_module string.
:- import_module univ.
@@ -366,8 +367,11 @@
%
:- pred write(int::in, T::in, io::di, io::uo) is det <= doc(T).
-:- pred write(io.output_stream::in, int::in, T::in, io::di, io::uo) is det
- <= doc(T).
+ % Write docs to the specified string writer stream in pretty printed
+ % format. The int argument specifies a page width in characters.
+ %
+:- pred write(Stream::in, int::in, T::in, State::di, State::uo) is det
+ <= ( doc(T), stream.writer(Stream, string, State) ).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -453,8 +457,8 @@
write(W, X, !IO) :-
layout_best(io.write_string, W, doc(X), !IO).
-write(Stream, W, X, !IO) :-
- layout_best(io.write_string(Stream), W, doc(X), !IO).
+write(Stream, W, X, !State) :-
+ layout_best(put(Stream), W, doc(X), !State).
%-----------------------------------------------------------------------------%
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.298
diff -u -r1.298 Mmakefile
--- tests/hard_coded/Mmakefile 9 Oct 2006 06:40:26 -0000 1.298
+++ tests/hard_coded/Mmakefile 26 Oct 2006 06:01:30 -0000
@@ -185,6 +185,7 @@
solver_ite_inits \
space \
stable_sort \
+ stream_test \
string_alignment \
string_alignment_bug \
string_loop \
@@ -573,6 +574,9 @@
nonascii_gen: nonascii_gen.c
$(CC) nonascii_gen.c -o nonascii_gen
+stream_test.out: stream_test
+ ./stream_test < stream_test.data > stream_test.out
+
# The trace_goal_env_1 and trace_goal_env_2 test cases differ from each other
# only in that the latter is executed with the TRACE_ABC environment variable
# set.
Index: tests/hard_coded/stream_test.data
===================================================================
RCS file: tests/hard_coded/stream_test.data
diff -N tests/hard_coded/stream_test.data
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/stream_test.data 26 Oct 2006 05:58:51 -0000
@@ -0,0 +1,3 @@
+abcdefghijklmnopqrstuvwxyz
+0123456789
+~!@#$%^&*()_+
Index: tests/hard_coded/stream_test.exp
===================================================================
RCS file: tests/hard_coded/stream_test.exp
diff -N tests/hard_coded/stream_test.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/stream_test.exp 26 Oct 2006 05:58:51 -0000
@@ -0,0 +1,16 @@
+561
+Hello World!
+a
+[foo, bar, baz]
+[
+ foo,
+ foo,
+ foo,
+ foo,
+ foo,
+ foo,
+ foo,
+ foo,
+ foo,
+ foo]
+['\n', '+', '_', ')', '(', '*', '&', '^', '%', '$', '#', '@', '!', '~', '\n', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0', '\n', 'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']
Index: tests/hard_coded/stream_test.m
===================================================================
RCS file: tests/hard_coded/stream_test.m
diff -N tests/hard_coded/stream_test.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/stream_test.m 26 Oct 2006 05:58:51 -0000
@@ -0,0 +1,42 @@
+:- module stream_test.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module char.
+:- import_module list.
+:- import_module pprint.
+:- import_module stream.
+:- import_module univ.
+
+:- type foo ---> foo ; bar ; baz.
+
+main(!IO) :-
+ io.stdout_stream(Stdout, !IO),
+ put(Stdout, 561, !IO),
+ put(Stdout, "\nHello World!\n", !IO),
+ put(Stdout, 'a', !IO),
+ put(Stdout, "\n", !IO),
+ put(Stdout, univ([foo, bar, baz]), !IO),
+ put(Stdout, "\n", !IO),
+ list.duplicate(10, foo, ListFoo),
+ pprint.write(Stdout, 4, to_doc(ListFoo), !IO),
+ io.nl(Stdout, !IO),
+ io.stdin_stream(Stdin, !IO),
+ input_stream_fold(Stdin, char_list_cons, [], PartialResult, !IO),
+ (
+ PartialResult = ok(Result),
+ io.write(Result, !IO),
+ io.nl(!IO)
+ ;
+ PartialResult = error(_, _),
+ io.write_string("TEST FAILED\n", !IO)
+ ).
+
+:- pred char_list_cons(char::in, list(char)::in, list(char)::out) is det.
+
+char_list_cons(X, Xs, [ X | Xs ]).
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list