[m-rev.] for review: add io.{write,print}_line
Julien Fischer
jfischer at opturion.com
Wed Feb 12 17:10:15 AEDT 2014
For review by anyone.
Add io.{write,print}_line to the standard library.
Add the predicates io.write_line and io.print_line to the standard library.
These are versions of io.write and io.print respectively, that in addition to
printing their argument also print a final newline. While this is no different
to calling io.{write,print} and then calling io.nl, it is a little more concise
which can be convenient in some circumstances.
library/io.m:
Add the above predicates.
compiler/error_util.m:
Avoid ambiguity with the write_line/3 predicate defined
in this module.
NEWS:
Announce the new predicates.
tests/hard_coded/write.m:
Use up-to-date syntax in this module.
Call write_line in a few spots.
Julien.
diff --git a/NEWS b/NEWS
index a08d669..f35b152 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+NEWS since Mercury 14.01
+------------------------
+
+Changes to the Mercury standard library:
+
+* We have added the print_line and write_line family of predicates to the
+ io module. These behave like the print and write predicates, but also
+ write a terminating newline character.
+
+
NEWS for Mercury 14.01
----------------------
diff --git a/compiler/error_util.m b/compiler/error_util.m
index 5c24267..d5f7298 100644
--- a/compiler/error_util.m
+++ b/compiler/error_util.m
@@ -990,7 +990,7 @@ write_lines([Line | Lines], MaybeContext, FixedIndent, !IO) :-
Indent = FixedIndent + LineIndent * indent_increment,
string.pad_left("", ' ', Indent, IndentStr),
io.write_string(IndentStr, !IO),
- write_line(LineWords, !IO),
+ error_util.write_line(LineWords, !IO),
write_lines(Lines, MaybeContext, FixedIndent, !IO).
:- pred write_line(list(string)::in, io::di, io::uo) is det.
diff --git a/library/io.m b/library/io.m
index 8b39037..135afae 100644
--- a/library/io.m
+++ b/library/io.m
@@ -376,7 +376,7 @@
%-----------------------------------------------------------------------------%
%
-% Text output predicates
+% Text output predicates.
%
% These will all throw an io.error exception if an I/O error occurs.
@@ -420,6 +420,20 @@
:- pred io.print_cc(T::in, io::di, io::uo) is cc_multi.
+ % io.print_line calls io.print and then writes a newline character.
+ %
+:- pred io.print_line(T::in, io::di, io::uo) is det.
+
+:- pred io.print_line(io.output_stream::in, T::in, io::di, io::uo) is det.
+
+:- pred io.print_line(io.output_stream, deconstruct.noncanon_handling, T, io, io).
+:- mode io.print_line(in, in(do_not_allow), in, di, uo) is det.
+:- mode io.print_line(in, in(canonicalize), in, di, uo) is det.
+:- mode io.print_line(in, in(include_details_cc), in, di, uo) is cc_multi.
+:- mode io.print_line(in, in, in, di, uo) is cc_multi.
+
+:- pred io.print_line_cc(T::in, io::di, io::uo) is cc_multi.
+
% io.write/3 writes its argument to the current output stream.
% io.write/4 writes its second argument to the output stream specified
% in its first argument. In all cases, the argument to output may be
@@ -454,6 +468,20 @@
:- pred io.write_cc(T::in, io::di, io::uo) is cc_multi.
+ % io.write_line calls io.write and then writes a newline character.
+ %
+:- pred io.write_line(T::in, io::di, io::uo) is det.
+
+:- pred io.write_line(io.output_stream::in, T::in, io::di, io::uo) is det.
+
+:- pred io.write_line(io.output_stream, deconstruct.noncanon_handling, T, io, io).
+:- mode io.write_line(in, in(do_not_allow), in, di, uo) is det.
+:- mode io.write_line(in, in(canonicalize), in, di, uo) is det.
+:- mode io.write_line(in, in(include_details_cc), in, di, uo) is cc_multi.
+:- mode io.write_line(in, in, in, di, uo) is cc_multi.
+
+:- pred io.write_line_cc(T::in, io::di, io::uo) is cc_multi.
+
% Writes a newline character to the current output stream.
%
:- pred io.nl(io::di, io::uo) is det.
@@ -4683,6 +4711,22 @@ io.print_cc(Term, !IO) :-
io.print_to_stream(Stream, Term, !IO) :-
io.print(output_stream(Stream), canonicalize, Term, !IO).
+io.print_line(Term, !IO) :-
+ io.print(Term, !IO),
+ io.nl(!IO).
+
+io.print_line(Stream, Term, !IO) :-
+ io.print(Stream, Term, !IO),
+ io.nl(!IO).
+
+io.print_line(Stream, NonCanon, Term, !IO) :-
+ io.print(Stream, NonCanon, Term, !IO),
+ io.nl(!IO).
+
+io.print_line_cc(Term, !IO) :-
+ io.print_cc(Term, !IO),
+ io.nl(!IO).
+
%-----------------------------------------------------------------------------%
%
% Various different versions of io.write
@@ -4702,6 +4746,22 @@ io.write_cc(X, !IO) :-
io.output_stream(Stream, !IO),
stream.string_writer.write(Stream, include_details_cc, X, !IO).
+io.write_line(X, !IO) :-
+ io.write(X, !IO),
+ io.nl(!IO).
+
+io.write_line(Stream, X, !IO) :-
+ io.write(Stream, X, !IO),
+ io.nl(!IO).
+
+io.write_line(Stream, NonCanon, X, !IO) :-
+ io.write(Stream, NonCanon, X, !IO),
+ io.nl(!IO).
+
+io.write_line_cc(X, !IO) :-
+ io.write_cc(X, !IO),
+ io.nl(!IO).
+
%-----------------------------------------------------------------------------%
io.write_list([], _Separator, _OutputPred, !IO).
diff --git a/tests/hard_coded/write.m b/tests/hard_coded/write.m
index faf13a4..564e374 100644
--- a/tests/hard_coded/write.m
+++ b/tests/hard_coded/write.m
@@ -1,4 +1,5 @@
-% Test case for io__write
+% vim: ft=mercury ts=4 sw=4 et
+% Test case for io.write (and io.write_line).
%
% Author: trd
@@ -6,161 +7,169 @@
:- interface.
:- import_module io.
-:- pred main(io__state::di, io__state::uo) is det.
+:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module list, int, term, map, array, univ.
:- import_module version_array.
-:- pred test_ops(io__state::di, io__state::uo) is det.
-:- pred test_builtins(io__state::di, io__state::uo) is det.
-:- pred test_discriminated(io__state::di, io__state::uo) is det.
-:- pred test_polymorphism(io__state::di, io__state::uo) is det.
-:- pred test_other(io__state::di, io__state::uo) is det.
-:- pred newline(io__state::di, io__state::uo) is det.
-
-
-:- type enum ---> one ; two ; three.
-
-:- type fruit ---> apple(list(int))
- ; banana(list(enum)).
-
-:- type thingie ---> foo ; bar(int) ; bar(int, int) ; qux(int) ;
- quux(int) ; quuux(int, int) ; wombat ;
- zoom(int) ; zap(int, float) ; zip(int, int) ;
- zop(float, float).
-
-:- type poly(A, B) ---> poly_one(A) ; poly_two(B) ;
- poly_three(B, A, poly(B, A)).
-
-:- type no_tag ---> qwerty(int).
-
-:- type expr ---> var(string)
- ; int(int)
- ; expr + expr
- ; expr - expr
- ; expr * expr
- ; (expr, expr)
- ; {expr; expr}
- ; {{expr}}
- ; (type)
- ; blah
- ; (:-)
- .
-
-main -->
- test_ops,
- test_discriminated,
- test_polymorphism,
- test_builtins,
- test_other.
-
-
-test_ops -->
- io__write(var("X") + int(3) * var("X^2") ; (type)), newline,
- io__write(write.{type}), newline,
- io__write(write.{:-}), newline,
- io__write((:-)), newline,
- io__write(write.{blah}), newline,
- io__write((blah ; (type), (type) * blah ; (type))), newline,
- io__write(((blah ; blah), blah) * blah ; blah), newline,
- io__write((type) * blah ; (type)), newline.
-
-test_discriminated -->
- io__write_string("TESTING DISCRIMINATED UNIONS\n"),
-
- % test enumerations
- io__write(one), newline,
- io__write(two), newline,
- io__write(three), newline,
-
- % test simple tags
- io__write(apple([9,5,1])), newline,
- io__write(banana([three, one, two])), newline,
-
- % test complicated tags
- io__write(zop(3.3, 2.03)), newline,
- io__write(zip(3, 2)), newline,
- io__write(zap(3, -2.111)), newline,
-
- % test complicated constant
- io__write(wombat), newline,
- io__write(foo), newline,
-
- newline.
-
-test_polymorphism -->
- io__write_string("TESTING POLYMORPHISM\n"),
- io__write(poly_one([2399.3])), newline,
- io__write(poly_two(3)), newline,
- io__write(poly_three(3.33, 4, poly_one(9.11))), newline,
-
- newline.
-
-
-test_builtins -->
- io__write_string("TESTING BUILTINS\n"),
-
- % test strings
- io__write(""), newline,
- io__write("Hello, world\n"), newline,
- io__write("Foo%sFoo"), newline,
- io__write(""""), newline, % interesting - prints """ of course
-
- % test characters
- io__write('a'), newline,
- io__write('&'), newline,
-
- % test floats
- io__write(3.14159), newline,
- io__write(11.28324983E-22), newline,
- io__write(22.3954899E22), newline,
-
- % test integers
- io__write(-65), newline,
- io__write(4), newline,
-
- % test univ.
- { type_to_univ(["hi! I'm a univ!"], Univ) },
- io__write(Univ), newline,
-
- % test predicates
- io__write(newline), newline,
-
- newline.
-
-
-
- % Note: testing abstract types is always going to have results
- % that are dependent on the implementation. If someone changes
- % the implementation, the results of this test can change.
-
-test_other -->
- io__write_string("TESTING OTHER TYPES\n"),
- { term__init_var_supply(VarSupply) },
- { term__create_var(Var, VarSupply, NewVarSupply) },
- io__write(Var), newline,
- io__write(VarSupply), newline,
- io__write(NewVarSupply), newline,
-
- % presently, at least, map is an equivalence and
- % an abstract type.
- { map__init(Map) },
- io__write(Map), newline,
-
- % a no tag type
- io__write(qwerty(4)), newline,
-
- { array__from_list([1,2,3,4], Array) },
- io__write(Array), newline,
-
- { VersionArray = version_array.from_list([1,2,3,4]) },
- io.write(VersionArray), newline,
-
- newline.
-
-newline -->
- io__write_char('\n').
-
-
+:- pred test_ops(io::di, io::uo) is det.
+:- pred test_builtins(io::di, io::uo) is det.
+:- pred test_discriminated(io::di, io::uo) is det.
+:- pred test_polymorphism(io::di, io::uo) is det.
+:- pred test_other(io::di, io::uo) is det.
+:- pred newline(io::di, io::uo) is det.
+
+:- type enum
+ ---> one
+ ; two
+ ; three.
+
+:- type fruit
+ ---> apple(list(int))
+ ; banana(list(enum)).
+
+:- type thingie
+ ---> foo
+ ; bar(int)
+ ; bar(int, int)
+ ; qux(int)
+ ; quux(int)
+ ; quuux(int, int)
+ ; wombat
+ ; zoom(int)
+ ; zap(int, float)
+ ; zip(int, int)
+ ; zop(float, float).
+
+:- type poly(A, B)
+ ---> poly_one(A)
+ ; poly_two(B)
+ ; poly_three(B, A, poly(B, A)).
+
+:- type no_tag
+ ---> qwerty(int).
+
+:- type expr
+ ---> var(string)
+ ; int(int)
+ ; expr + expr
+ ; expr - expr
+ ; expr * expr
+ ; (expr, expr)
+ ; {expr; expr}
+ ; {{expr}}
+ ; (type)
+ ; blah
+ ; (:-).
+
+main(!IO) :-
+ test_ops(!IO),
+ test_discriminated(!IO),
+ test_polymorphism(!IO),
+ test_builtins(!IO),
+ test_other(!IO).
+
+test_ops(!IO) :-
+ io.write(var("X") + int(3) * var("X^2") ; (type), !IO), newline(!IO),
+ io.write(write.{type}, !IO), newline(!IO),
+ io.write(write.{:-}, !IO), newline(!IO),
+ io.write((:-), !IO), newline(!IO),
+ io.write(write.{blah}, !IO), newline(!IO),
+ io.write((blah ; (type), (type) * blah ; (type)), !IO), newline(!IO),
+ io.write(((blah ; blah), blah) * blah ; blah, !IO), newline(!IO),
+ io.write((type) * blah ; (type), !IO), newline(!IO).
+
+test_discriminated(!IO) :-
+ io.write_string("TESTING DISCRIMINATED UNIONS\n", !IO),
+
+ % Test enumerations.
+ io.write_line(one, !IO),
+ io.write_line(two, !IO),
+ io.write_line(three, !IO),
+
+ % Test simple tags.
+ io.write(apple([9,5,1]), !IO), newline(!IO),
+ io.write(banana([three, one, two]), !IO), newline(!IO),
+
+ % Test complicated tags.
+ io.write(zop(3.3, 2.03), !IO), newline(!IO),
+ io.write(zip(3, 2), !IO), newline(!IO),
+ io.write(zap(3, -2.111), !IO), newline(!IO),
+
+ % Test complicated constant.
+ io.write(wombat, !IO), newline(!IO),
+ io.write(foo, !IO), newline(!IO),
+
+ newline(!IO).
+
+test_polymorphism(!IO) :-
+ io.write_string("TESTING POLYMORPHISM\n", !IO),
+ io.write(poly_one([2399.3]), !IO), newline(!IO),
+ io.write(poly_two(3), !IO), newline(!IO),
+ io.write(poly_three(3.33, 4, poly_one(9.11)), !IO), newline(!IO),
+
+ newline(!IO).
+
+test_builtins(!IO) :-
+ io.write_string("TESTING BUILTINS\n", !IO),
+
+ % Test strings.
+ io.write("", !IO), newline(!IO),
+ io.write("Hello, world\n", !IO), newline(!IO),
+ io.write("Foo%sFoo", !IO), newline(!IO),
+ io.write("""", !IO), newline(!IO), % interesting - prints """ of course
+
+ % Test characters.
+ io.write('a', !IO), newline(!IO),
+ io.write('&', !IO), newline(!IO),
+
+ % Test floats.
+ io.write(3.14159, !IO), newline(!IO),
+ io.write(11.28324983E-22, !IO), newline(!IO),
+ io.write(22.3954899E22, !IO), newline(!IO),
+
+ % Test integers.
+ io.write(-65, !IO), newline(!IO),
+ io.write(4, !IO), newline(!IO),
+
+ % Test univ.
+ type_to_univ(["hi! I'm a univ!"], Univ),
+ io.write(Univ, !IO), newline(!IO),
+
+ % Test predicates.
+ io.write(newline, !IO), newline(!IO),
+
+ newline(!IO).
+
+ % Note: testing abstract types is always going to have results
+ % that are dependent on the implementation. If someone changes
+ % the implementation, the results of this test can change.
+ %
+test_other(!IO) :-
+ io.write_string("TESTING OTHER TYPES\n", !IO),
+ term.init_var_supply(VarSupply),
+ term.create_var(Var, VarSupply, NewVarSupply),
+ io.write(Var, !IO), newline(!IO),
+ io.write(VarSupply, !IO), newline(!IO),
+ io.write(NewVarSupply, !IO), newline(!IO),
+
+ % Presently, at least, map is an equivalence and
+ % an abstract type.
+ map.init(Map),
+ io.write(Map, !IO), newline(!IO),
+
+ % A no tag type.
+ io.write(qwerty(4), !IO), newline(!IO),
+
+ array.from_list([1,2,3,4], Array),
+ io.write(Array, !IO), newline(!IO),
+
+ VersionArray = version_array.from_list([1,2,3,4]),
+ io.write(VersionArray, !IO), newline(!IO),
+
+ newline(!IO).
+
+newline(!IO) :-
+ io.write_char('\n', !IO).
More information about the reviews
mailing list