[m-dev.] Minimal streams diff

Michael Day mikeday at yeslogic.com
Wed Oct 2 12:00:19 AEST 2002


Seeing as how Fergus has just announced a feature freeze, it seems like a
good time to post a minimal streams diff for the day after the next
release staggers out the door.

I've tried to keep it to the minimum level of changes necessary to
introduce stream type classes into the standard library, so it doesn't
include putback streams or line number counting or anything like that. 

Interestingly enough, I ended up implementing socket streams on top of the
posix code for the ICFP contest and they worked pretty well, but the lack
of integration with regular io streams and the incredible irritation of
having to manipulate separate io__result and stream__result types is a
killer for any real usage.

Anyway, anyone not busy frantically squashing bugs for the release, please 
feel free to criticise the diff below.

Michael

--- ../mercury-compiler-rotd-2002-09-07/library/io.m	Thu Jul 25 02:05:11 2002
+++ io.m	Wed Oct  2 11:47:33 2002
@@ -112,6 +112,43 @@
 	;	end
 	.
 
+% Type classes
+
+:- typeclass input(S) where
+    [
+	pred input_stream_name(S, string, io, io),
+	mode input_stream_name(in, out, di, uo) is det,
+%		Retrieves the human-readable name associated with the
+%		specified input stream.
+%		For file streams, this is the filename.
+%		For stdin this is the string "<standard input>".
+
+	pred read_char(S, io__result(char), io, io),
+	mode read_char(in, out, di, uo) is det
+%		Reads a character from specified stream.
+    ].
+
+:- instance input(input_stream).
+
+:- typeclass output(S) where
+    [
+	pred output_stream_name(S, string, io, io),
+	mode output_stream_name(in, out, di, uo) is det,
+%		Retrieves the human-readable name associated with the
+%		specified stream.
+%		For file streams, this is the filename.
+%		For stdout this is the string "<standard output>".
+%		For stderr this is the string "<standard error>".
+
+	pred write_char(S, char, io, io),
+	mode write_char(in, in, di, uo) is det
+%		Writes a character to the specified output stream.
+    ].
+
+:- instance output(output_stream).
+
+:- typeclass duplex(S) <= (input(S), output(S)) where [].
+
 %-----------------------------------------------------------------------------%
 
 % Text input predicates.
@@ -183,11 +220,6 @@
 %		`io__putback_char' will throw an io__error exception
 %		if ungetc() fails.
 
-:- pred io__read_char(io__input_stream, io__result(char),
-				io__state, io__state).
-:- mode io__read_char(in, out, di, uo) is det.
-%		Reads a character from specified stream.
-
 :- pred io__read_word(io__input_stream, io__result(list(char)),
 							io__state, io__state).
 :- mode io__read_word(in, out, di, uo) is det.
@@ -441,10 +473,6 @@
 :- mode io__write_char(in, di, uo) is det.
 %		Writes a character to the current output stream.
 
-:- pred io__write_char(io__output_stream, char, io__state, io__state).
-:- mode io__write_char(in, in, di, uo) is det.
-%		Writes a character to the specified output stream.
-
 :- pred io__write_int(int, io__state, io__state).
 :- mode io__write_int(in, di, uo) is det.
 %		Writes an integer to the current output stream.
@@ -579,13 +607,6 @@
 %	For file streams, this is the filename.
 %	For stdin this is the string "<standard input>".
 
-:- pred io__input_stream_name(io__input_stream, string, io__state, io__state).
-:- mode io__input_stream_name(in, out, di, uo) is det.
-%	Retrieves the human-readable name associated with the specified input
-%	stream.
-%	For file streams, this is the filename.
-%	For stdin this is the string "<standard input>".
-
 :- pred io__get_line_number(int, io__state, io__state).
 :- mode io__get_line_number(out, di, uo) is det.
 %	Return the line number of the current input stream.
@@ -683,14 +704,6 @@
 %	For stdout this is the string "<standard output>".
 %	For stderr this is the string "<standard error>".
 
-:- pred io__output_stream_name(io__output_stream, string,
-				io__state, io__state).
-:- mode io__output_stream_name(in, out, di, uo) is det.
-%	Retrieves the human-readable name associated with the specified stream.
-%	For file streams, this is the filename.
-%	For stdout this is the string "<standard output>".
-%	For stderr this is the string "<standard error>".
-
 :- pred io__get_output_line_number(int, io__state, io__state).
 :- mode io__get_output_line_number(out, di, uo) is det.
 %	Return the line number of the current output stream.
@@ -1211,6 +1224,11 @@
 %		The `ExitStatus' will be 0 if the command completed
 %		successfully or the return value of the command otherwise.
 
+:- func io__make_io_error(string) = io__error.
+%	io__make_io_error(ErrorMessage) = ErrorCode.
+%		Construct an error code including the specified error message.
+%		(This is necessary for stream implementations).
+
 :- func io__error_message(io__error) = string.
 :- pred io__error_message(io__error, string).
 :- mode io__error_message(in, out) is det.
@@ -1382,6 +1400,12 @@
 
 % input predicates
 
+:- instance input(input_stream) where
+    [
+	pred(input_stream_name/4) is io__stream_name,
+	pred(read_char/4) is io__read_char0
+    ].
+
 % we want to inline these, to allow deforestation
 :- pragma inline(io__read_char/3).
 :- pragma inline(io__read_char/4).
@@ -1390,7 +1414,12 @@
 	io__input_stream(Stream),
 	io__read_char(Stream, Result).
 
-io__read_char(Stream, Result) -->
+:- pred io__read_char0(io__input_stream, io__result(char),
+				io__state, io__state).
+:- mode io__read_char0(in, out, di, uo) is det.
+%		Reads a character from specified stream.
+
+io__read_char0(Stream, Result) -->
 	io__read_char_code(Stream, Code),
 	(
 		{ Code = -1 }
@@ -2225,6 +2254,12 @@
 
 % output predicates
 
+:- instance output(output_stream) where
+    [
+	pred(output_stream_name/4) is io__stream_name,
+	pred(write_char/4) is io__write_char0
+    ].
+
 io__nl -->
 	io__write_char('\n').
 
@@ -2925,16 +2960,10 @@
 	io__input_stream(Stream),
 	io__stream_name(Stream, Name).
 
-io__input_stream_name(Stream, Name) -->
-	io__stream_name(Stream, Name).
-
 io__output_stream_name(Name) -->
 	io__output_stream(Stream),
 	io__stream_name(Stream, Name).
 
-io__output_stream_name(Stream, Name) -->
-	io__stream_name(Stream, Name).
-
 io__binary_input_stream_name(Name) -->
 	io__binary_input_stream(Stream),
 	io__stream_name(Stream, Name).
@@ -3283,6 +3312,8 @@
 	% exception if there is no exception hander, does not print out
 	% the module name.
 
+io__make_io_error(Error) = io_error(Error).
+
 io__error_message(io_error(Error), Error).
 
 %-----------------------------------------------------------------------------%
@@ -4281,8 +4312,12 @@
 	update_io(IO0, IO);
 }").
 
+:- pred io__write_char0(io__output_stream, char, io__state, io__state).
+:- mode io__write_char0(in, in, di, uo) is det.
+%		Writes a character to the specified output stream.
+
 :- pragma foreign_proc("C",
-	io__write_char(Stream::in, Character::in, IO0::di, IO::uo),
+	io__write_char0(Stream::in, Character::in, IO0::di, IO::uo),
 		[may_call_mercury, promise_pure, tabled_for_io, thread_safe], 
 "{
 	MercuryFile *stream = (MercuryFile *) Stream;

--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list