[m-rev.] for review: io__foldl

Simon Taylor stayl at cs.mu.OZ.AU
Tue Jan 15 19:46:12 AEDT 2002


Estimated hours taken: 1

NEWS:
library/io.m:
	Add `io__input_stream_foldl', `io__input_stream_foldl_io'
	and `io__input_stream_foldl2_io', which apply a predicate
	to each character of an input stream in turn.

	Add a new result type `io__maybe_partial_res' which is
	used for operations which can return a partial result
	like io__input_stream_foldl* and io__read_file.

tests/general/Mmakefile:
tests/general/io_foldl.{m,exp}:
	Test case.

Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.237
diff -u -u -r1.237 NEWS
--- NEWS	15 Jan 2002 07:19:04 -0000	1.237
+++ NEWS	15 Jan 2002 07:34:17 -0000
@@ -65,6 +65,14 @@
 
 Changes to the Mercury standard library:
 
+* `io__read_file' and `io__read_file_as_string' now have better error
+  handling. The result types have changed, so code using these predicates
+  will need minor modifications.
+
+* We've added predicates `io__input_stream_foldl', `io__input_stream_foldl_io'
+  and `io__input_stream_foldl2_io', which apply a predicate to each character
+  of an input stream in turn.
+
 * We've added four functions to list.m for mapping functions over
   corresponding members of lists: list__map_corresponding/3,
   list__map_corresponding3/4, list__filter_map_corresponding/3
Index: library/io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.237
diff -u -u -r1.237 io.m
--- library/io.m	14 Dec 2001 16:05:40 -0000	1.237
+++ library/io.m	15 Jan 2002 08:09:09 -0000
@@ -69,6 +69,12 @@
 :- type io__res(T)	--->	ok(T)
 			;	error(io__error).
 
+	% io__maybe_partial_res is used where it is possible to return
+	% a partial result when an error occurs,
+:- type io__maybe_partial_res(T)
+			--->	ok(T)
+			;	error(T, io__error).
+
 :- type io__result	--->	ok
 			;	eof
 			;	error(io__error).
@@ -128,17 +134,45 @@
 %		Reads a line from the current input stream, returns the
 %		result as a string.
 
-:- pred io__read_file(io__result(list(char)), io__state, io__state).
+:- pred io__read_file(io__maybe_partial_res(list(char)), io__state, io__state).
 :- mode io__read_file(out, di, uo) is det.
 %		Reads all the characters from the current input stream until
 %		eof or error.
 
-:- pred io__read_file_as_string(io__res, string, io__state, io__state).
-:- mode io__read_file_as_string(out, out, di, uo) is det.
+:- pred io__read_file_as_string(io__maybe_partial_res(string),
+			io__state, io__state).
+:- mode io__read_file_as_string(out, di, uo) is det.
 %		Reads all the characters from the current input stream until
 %		eof or error.  Returns the result as a string rather than
 %		as a list of char.
 
+:- pred io__input_stream_foldl(pred(char, T, T),
+			T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__input_stream_foldl((pred(in, in, out) is det),
+			in, out, di, uo) is det.
+:- mode io__input_stream_foldl((pred(in, in, out) is cc_multi),
+			in, out, di, uo) is cc_multi.
+%		Applies the given closure to each character read from
+%		the input stream in turn, until eof or error.
+
+:- pred io__input_stream_foldl_io(pred(char, io__state, io__state),
+			io__res, io__state, io__state).
+:- mode io__input_stream_foldl_io((pred(in, di, uo) is det),
+			out, di, uo) is det.
+:- mode io__input_stream_foldl_io((pred(in, di, uo) is cc_multi),
+			out, di, uo) is cc_multi.
+%		Applies the given closure to each character read from
+%		the input stream in turn, until eof or error.
+
+:- pred io__input_stream_foldl2_io(pred(char, T, T, io__state, io__state),
+			T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__input_stream_foldl2_io((pred(in, in, out, di, uo) is det),
+			in, out, di, uo) is det.
+:- mode io__input_stream_foldl2_io((pred(in, in, out, di, uo) is cc_multi),
+			in, out, di, uo) is cc_multi.
+%		Applies the given closure to each character read from
+%		the input stream in turn, until eof or error.
+
 :- pred io__putback_char(char, io__state, io__state).
 :- mode io__putback_char(in, di, uo) is det.
 %		Un-reads a character from the current input stream.
@@ -166,24 +200,53 @@
 %		as a list of chars.
 
 :- pred io__read_line_as_string(io__input_stream, io__result(string),
-		io__state, io__state).
+			io__state, io__state).
 :- mode io__read_line_as_string(in, out, di, uo) is det.
 %		Reads a line from specified stream, returning the
 %		result as a string.
 
-:- pred io__read_file(io__input_stream, io__result(list(char)),
-							io__state, io__state).
+:- pred io__read_file(io__input_stream, io__maybe_partial_res(list(char)),
+			io__state, io__state).
 :- mode io__read_file(in, out, di, uo) is det.
 %		Reads all the characters from the given input stream until
 %		eof or error.
 
-:- pred io__read_file_as_string(io__input_stream, io__res, string,
-							io__state, io__state).
-:- mode io__read_file_as_string(in, out, out, di, uo) is det.
+:- pred io__read_file_as_string(io__input_stream,
+			io__maybe_partial_res(string), io__state, io__state).
+:- mode io__read_file_as_string(in, out, di, uo) is det.
 %		Reads all the characters from the given input stream until
 %		eof or error.  Returns the result as a string rather than
 %		as a list of char.
 
+:- pred io__input_stream_foldl(io__input_stream, pred(char, T, T),
+			T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__input_stream_foldl(in, (pred(in, in, out) is det),
+			in, out, di, uo) is det.
+:- mode io__input_stream_foldl(in, (pred(in, in, out) is cc_multi),
+			in, out, di, uo) is cc_multi.
+%		Applies the given closure to each character read from
+%		the input stream in turn, until eof or error.
+
+:- pred io__input_stream_foldl_io(io__input_stream,
+			pred(char, io__state, io__state), io__res,
+			io__state, io__state).
+:- mode io__input_stream_foldl_io(in, (pred(in, di, uo) is det),
+			out, di, uo) is det.
+:- mode io__input_stream_foldl_io(in, (pred(in, di, uo) is cc_multi),
+			out, di, uo) is cc_multi.
+%		Applies the given closure to each character read from
+%		the input stream in turn, until eof or error.
+
+:- pred io__input_stream_foldl2_io(io__input_stream,
+			pred(char, T, T, io__state, io__state),
+			T, io__maybe_partial_res(T), io__state, io__state).
+:- mode io__input_stream_foldl2_io(in, (pred(in, in, out, di, uo) is det),
+			in, out, di, uo) is det.
+:- mode io__input_stream_foldl2_io(in, (pred(in, in, out, di, uo) is cc_multi),
+			in, out, di, uo) is cc_multi.
+%		Applies the given closure to each character read from
+%		the input stream in turn, until eof or error.
+
 :- pred io__putback_char(io__input_stream, char, io__state, io__state).
 :- mode io__putback_char(in, in, di, uo) is det.
 %		Un-reads a character from specified stream.
@@ -1460,19 +1523,18 @@
 io__read_file(Stream, Result) -->
 	io__read_file_2(Stream, [], Result).
 
-:- pred io__read_file_2(io__input_stream, list(char), io__result(list(char)),
-		io__state, io__state).
+:- pred io__read_file_2(io__input_stream, list(char),
+		io__maybe_partial_res(list(char)), io__state, io__state).
 :- mode io__read_file_2(in, in, out, di, uo) is det.
 
 io__read_file_2(Stream, Chars0, Result) -->
 	io__read_char(Stream, Result0),
 	(
 		{ Result0 = eof },
-		{ list__reverse(Chars0, Chars) },
-		{ Result = ok(Chars) }
+		{ Result = ok(list__reverse(Chars0)) }
 	;
 		{ Result0 = error(Err) },
-		{ Result = error(Err) }
+		{ Result = error(list__reverse(Chars0), Err) }
 	;
 		{ Result0 = ok(Char) },
 		io__read_file_2(Stream, [Char|Chars0], Result)
@@ -1480,11 +1542,11 @@
 
 %-----------------------------------------------------------------------------%
 
-io__read_file_as_string(Result, String) -->
+io__read_file_as_string(Result) -->
 	io__input_stream(Stream),
-	io__read_file_as_string(Stream, Result, String).
+	io__read_file_as_string(Stream, Result).
 
-io__read_file_as_string(Stream, Result, String) -->
+io__read_file_as_string(Stream, Result) -->
 	%
 	% check if the stream is a regular file;
 	% if so, allocate a buffer according to the
@@ -1510,7 +1572,14 @@
 		Buffer, Pos, BufferSize),
 	{ require(Pos < BufferSize, "io__read_file_as_string: overflow") },
 	{ io__buffer_to_string(Buffer, Pos, String) },
-	io__check_err(Stream, Result).
+	io__check_err(Stream, Result0),
+	{
+		Result0 = ok,
+		Result = ok(String)
+	;
+		Result0 = error(Error),
+		Result = error(String, Error)
+	}.
 
 :- pred io__read_file_as_string_2(io__input_stream, buffer, int, int,
 		buffer, int, int, io__state, io__state).
@@ -1536,6 +1605,62 @@
 			Buffer, Pos, Size)
 	).
 	
+%-----------------------------------------------------------------------------%
+
+io__input_stream_foldl(Pred, T0, Res) -->
+	io__input_stream(Stream),
+	io__input_stream_foldl(Stream, Pred, T0, Res).
+
+io__input_stream_foldl(Stream, Pred, T0, Res) -->
+	io__read_char(Stream, CharResult),
+	(
+		{ CharResult = ok(Char) },
+		{ Pred(Char, T0, T1) },
+		io__input_stream_foldl(Stream, Pred, T1, Res)
+	;
+		{ CharResult = eof },
+		{ Res = ok(T0) }
+	;
+		{ CharResult = error(Error) },
+		{ Res = error(T0, Error) }
+	).
+
+io__input_stream_foldl_io(Pred, Res) -->
+	io__input_stream(Stream),
+	io__input_stream_foldl_io(Stream, Pred, Res).
+
+io__input_stream_foldl_io(Stream, Pred, Res) -->
+	io__read_char(Stream, CharResult),
+	(
+		{ CharResult = ok(Char) },
+		Pred(Char),
+		io__input_stream_foldl_io(Stream, Pred, Res)
+	;
+		{ CharResult = eof },
+		{ Res = ok }
+	;
+		{ CharResult = error(Error) },
+		{ Res = error(Error) }
+	).
+
+io__input_stream_foldl2_io(Pred, T0, Res) -->
+	io__input_stream(Stream),
+	io__input_stream_foldl2_io(Stream, Pred, T0, Res).
+
+io__input_stream_foldl2_io(Stream, Pred, T0, Res) -->
+	io__read_char(Stream, CharResult),
+	(
+		{ CharResult = ok(Char) },
+		Pred(Char, T0, T1),
+		io__input_stream_foldl2_io(Stream, Pred, T1, Res)
+	;
+		{ CharResult = eof },
+		{ Res = ok(T0) }
+	;
+		{ CharResult = error(Error) },
+		{ Res = error(T0, Error) }
+	).
+
 %-----------------------------------------------------------------------------%
 
 :- pred io__clear_err(stream, io__state, io__state).
Index: tests/general/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/general/Mmakefile,v
retrieving revision 1.35
diff -u -u -r1.35 Mmakefile
--- tests/general/Mmakefile	19 Dec 2001 02:53:47 -0000	1.35
+++ tests/general/Mmakefile	14 Jan 2002 08:08:20 -0000
@@ -37,6 +37,7 @@
 		higher_order \
 		intermod_type \
 		interpreter \
+		io_foldl \
 		io_regression \
 		liveness \
 		liveness2 \
@@ -119,6 +120,10 @@
 		    -e 's/require.m:[0-9]*/require.m:NNNN/g' \
 		    -e 's/exception.m:[0-9]*/exception.m:NNNN/g' \
 		| tr -d '\r' > string_format_test_3.out
+
+	# io_foldl `cat's its input to its output.
+io_foldl.out: io_foldl io_foldl.exp
+	./io_foldl < io_foldl.exp > io_foldl.out 2>&1
 
 #-----------------------------------------------------------------------------#
 
Index: tests/general/io_foldl.exp
===================================================================
RCS file: tests/general/io_foldl.exp
diff -N tests/general/io_foldl.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/general/io_foldl.exp	14 Jan 2002 05:43:37 -0000
@@ -0,0 +1,24 @@
+First 0x20 characters of fig 1.4 in MG are
+`In the beginning there was the t'.
+First 0x1b characters of fig 1.4 in MG are
+`In the beginning there was '.
+First 0x25 characters of fig 1.4 in MG are
+`In the beginning there was the text, '.
+
+Following line should have 3, 4, 1 significant figures.
+Strangly, 1.00e+01+  10.000=  2E+01
+
+
+!%0 10.5i!%0+10.5i!%0 -10.5i!%0+-10.5i!
+!% 10.5i!%+10.5i!% -10.5i!%+-10.5i!
+!% 10.5x!%+10.5x!% -10.5x!%+-10.5x!
+!%#10.x!%#+10.x!%#-10.x!%#+-10.x!
+
+!    -00031!    -00031!-00031    !-00031    !
+!     00031!    +00031! 00031    !+00031    !
+!    -00031!    -00031!-00031    !-00031    !
+!     00031!    +00031! 00031    !+00031    !
+!  ffffffe1!  ffffffe1!ffffffe1  !ffffffe1  !
+!     0001f!     0001f!0001f     !0001f     !
+!0xffffffe1!0xffffffe1!0xffffffe1!0xffffffe1!
+!      0x1f!      0x1f!0x1f      !0x1f      !
Index: tests/general/io_foldl.m
===================================================================
RCS file: tests/general/io_foldl.m
diff -N tests/general/io_foldl.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/general/io_foldl.m	14 Jan 2002 08:00:40 -0000
@@ -0,0 +1,15 @@
+:- module io_foldl.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module require.
+
+main --> 
+	io__input_stream_foldl_io(io__write_char, Res),
+	{ require(unify(Res, ok), "Error reading file.") }.
Index: tests/general/io_regression.m
===================================================================
RCS file: /home/mercury1/repository/tests/general/io_regression.m,v
retrieving revision 1.1
diff -u -u -r1.1 io_regression.m
--- tests/general/io_regression.m	11 Sep 2000 04:28:22 -0000	1.1
+++ tests/general/io_regression.m	14 Jan 2002 07:44:06 -0000
@@ -13,8 +13,8 @@
 :- implementation.
 
 main --> 
-	io__read_file_as_string(Res, Str),
-	( { Res = ok } ->
+	io__read_file_as_string(Res),
+	( { Res = ok(Str) } ->
 		io__write_string(Str)
 	;
 		io__write_string("Error reading file.\n")
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list