[m-rev.] for review: add string builder stream to extras

Julien Fischer juliensf at csse.unimelb.edu.au
Mon Nov 27 16:17:24 AEDT 2006


On Mon, 27 Nov 2006, Ian MacLarty wrote:

> Estimated hours taken: 2
> Branches: main
>
> Add a string_builder stream to extras.  This stream can be used to build a
> string using predicates that write to string or character streams.

The emphasis should be more on the fact that it can be used to
_efficiently_ construct such strings.

> extras/README:
> extras/stream/README:
> 	Document the new contents of the stream directory.
>
> extras/stream/Mmakefile:
> 	Change the mmake rules to build libstream_util instead of the
> 	now deprecated stream library.
>
> extras/stream/stream.m:
> extras/stream/stream_old.m:
> 	Rename stream.m to stream_old.m.
>
> extras/stream/stream_util.m:
> 	The new stream_util library.

For the benefit of everyone else I should point out that the intention
here is to add bits and pieces to this new library and then migrate the
parts that turn out to be useful into the standard library.

> extras/stream/stream_util.string_builder.m:
> 	The new string builder module.
>
> stream/tests/Makefile:
> stream/tests/stream_util_test.exp:
> stream/tests/stream_util_test.m:
> 	Add a test case for  string builder streams.
>
> Index: README
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/extras/README,v
> retrieving revision 1.22
> diff -u -r1.22 README
> --- README	16 Nov 2006 04:04:24 -0000	1.22
> +++ README	27 Nov 2006 02:56:24 -0000
> @@ -82,9 +82,8 @@
> 		adapted to make them suitable for use with solver
> 		types.
>
> -stream		Generic IO interface using typeclasses.
> -		Note this interface has been superceded by the one
> -		in standard library.
> +stream		Utility streams that use the stream interface in the
> +		standard library.


 	This directory also contains ... <stuff about the old streams>

>
> trailed_update	Some library modules that make use of backtrackable
> 		destructive update, including a module which provides
> Index: stream/Mmakefile
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/extras/stream/Mmakefile,v
> retrieving revision 1.2
> diff -u -r1.2 Mmakefile
> --- stream/Mmakefile	22 Nov 2001 11:04:40 -0000	1.2
> +++ stream/Mmakefile	27 Nov 2006 03:15:03 -0000
> @@ -6,19 +6,6 @@
>
> -include ../Mmake.params
>
> -MAIN_TARGET=libstream
> +MAIN_TARGET=libstream_util
>
> -depend: stream.depend
> -
> -stream stream.depend: mvar.m semaphore.m
> -
> -mvar.m: ../concurrency/mvar.m
> -	cp ../concurrency/mvar.m .
> -semaphore.m: ../concurrency/semaphore.m
> -	cp ../concurrency/semaphore.m .
> -
> -realclean:
> -	rm -f mvar.m semaphore.m
> -
> -check: libstream
> -	true

Don't delete the old sutff in the Mmakefile, the old_stream library
should still be buildable - feel free to disable it for no though, I'll
fix it up when I get a chance to look at it.

> +depend: stream_util.depend
> +This directory contains various instances of the stream typeclass defined
> +in the Mercury standard library.  The instances implement various utility
> +streams.
>
> -To build this library you need mvar.m and semaphore.m from the
> -extras/concurrency directory.  (The Mmakefile rules should copy these
> -here automatically.)
> +stream_util.m:
> +	The top-level package.
>
> -The following files implement the stream interfaces at various levels
> +stream_util.string_builder.m:
> +	A stream that can be used to build up strings from predicates that
> +	write to any string or character streams.

s/A stream/An output stream/

...

> +lowlevel.m:
> +impure.m:
> +stream_old.m:
> +	These files are part of the old stream interface, which has now been
> +	deprecated.

To which it is probably worth adding:

 	Similar functionality is available in the standard library's
 	stream module.
...

> Index: stream/stream_util.m
> ===================================================================
> RCS file: stream/stream_util.m
> diff -N stream/stream_util.m
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ stream/stream_util.m	27 Nov 2006 04:55:22 -0000
> @@ -0,0 +1,20 @@
> +%-----------------------------------------------------------------------------%
> +% vim: ft=mercury ts=4 sw=4 et
> +%-----------------------------------------------------------------------------%
> +% Copyright (C) 2006 The University of Melbourne.
> +% This file may only be copied under the terms of the GNU Library General
> +% Public License - see the file COPYING.LIB in the Mercury distribution.
> +%-----------------------------------------------------------------------------%
> +%
> +% File: stream_util.m.
> +% Main authors: maclarty.
> +%
> +% This library contains a set of utility streams that conform to the interface
> +% defined in the stream module in the Mercury standard library.
> +%

The library may contain more than utility streams; it may also contain
generic predicates that operate on stream etc.

> +
> +:- module stream_util.
> +
> +:- interface.
> +
> +:- include_module string_builder.
> Index: stream/stream_util.string_builder.m
> ===================================================================
> RCS file: stream/stream_util.string_builder.m
> diff -N stream/stream_util.string_builder.m
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ stream/stream_util.string_builder.m	27 Nov 2006 04:53:30 -0000
> @@ -0,0 +1,88 @@
> +%-----------------------------------------------------------------------------%
> +% vim: ft=mercury ts=4 sw=4 et
> +%-----------------------------------------------------------------------------%
> +% Copyright (C) 2006 The University of Melbourne.
> +% This file may only be copied under the terms of the GNU Library General
> +% Public License - see the file COPYING.LIB in the Mercury distribution.
> +%-----------------------------------------------------------------------------%
> +%
> +% File: stream_util.string_builder.m.
> +% Main authors: maclarty.

s/authors/author/ (unless you have a clone)

> +%
> +% This module implements a string builder stream, that can be used to
> +% build a string by calling predicates that write to string or character
> +% writer streams.
> +%

A suggested rewording:

 	This module implements a string build stream.  It can be used
 	build up a string using string or character writers.

> +:- module stream_util.string_builder.
> +
> +:- interface.
> +
> +:- import_module char.
> +:- import_module stream.
> +:- import_module string.
> +
> +:- type string_builder_stream.
> +
> +:- type string_builder_state.
> +
> +:- pred init(string_builder_stream::out, string_builder_state::uo) is det.
> +
> +:- instance stream.stream(string_builder_stream, string_builder_state).
> +:- instance stream.output(string_builder_stream, string_builder_state).
> +
> +:- instance stream.writer(string_builder_stream, string, string_builder_state).
> +:- instance stream.writer(string_builder_stream, char, string_builder_state).
> +
> +:- func string_builder_state_to_string(string_builder_state::di) = (string::uo)
> +    is det.
> +
> +%----------------------------------------------------------------------------%
> +
> +:- implementation.
> +
> +:- import_module list.
> +
> +:- type string_builder_state
> +    --->    string_builder_state(list(string)).
> +
> +:- type string_builder_stream
> +    --->    string_builder_stream.
> +
> +init(string_builder_stream, string_builder_state([])).
> +
> +:- instance stream.stream(string_builder_stream, string_builder_state)
> +        where [
> +    name(_, "<<string builder stream>>", !State)
> +].
> +
> +:- instance stream.output(string_builder_stream, string_builder_state)
> +        where [
> +    flush(_, !State)
> +].
> +
> +:- instance stream.writer(string_builder_stream, string, string_builder_state)
> +        where [
> +    ( put(_, String, !State) :-
> +        !.State = string_builder_state(StringList0),
> +        %
> +        % The string builder will never clobber the string.  Also we
> +        % know that nothing else can clobber the string since it isn't unique.

s/since/although/?

> +        % Therefore the inst cast below is okay, even though it is a lie.
> +        %
> +        StringList = [unsafe_promise_unique(String) | StringList0],
> +        !:State = string_builder_state(StringList)
> +    )
> +].
> +
> +:- instance stream.writer(string_builder_stream, char, string_builder_state)
> +        where [
> +    ( put(_, Char, !State) :-
> +        !.State = string_builder_state(StringList0),
> +        StringList = [string.from_char(Char) | StringList0],
> +        !:State = string_builder_state(StringList)
> +    )
> +].
> +
> +string_builder_state_to_string(State) = String :-
> +    State = string_builder_state(StringList),
> +    String = string.join_list("", list.reverse(StringList)).


...

> +%-----------------------------------------------------------------------------%
> +% vim: ft=mercury ts=4 sw=4 et
> +%-----------------------------------------------------------------------------%
> +:- module stream_util_test.
> +
> +:- interface.
> +
> +:- import_module io.
> +
> +:- pred main(io::di, io::uo) is det.
> +
> +:- implementation.
> +
> +:- import_module list.
> +:- import_module stream.
> +:- import_module stream_util.
> +:- import_module stream_util.string_builder.
> +:- import_module term_to_xml.
> +
> +main(!IO) :-
> +    some [StringBuilderStream, !StringBuilderState, String] (
> +        string_builder.init(StringBuilderStream, !:StringBuilderState),
> +        put(StringBuilderStream, "Hello", !StringBuilderState),
> +        put(StringBuilderStream, ',', !StringBuilderState),
> +        put(StringBuilderStream, " world!", !StringBuilderState),
> +        String = string_builder_state_to_string(!.StringBuilderState),
> +        io.write_string(String, !IO),
> +        io.nl(!IO)
> +    ),
> +    some [StringBuilderStream, !StringBuilderState, String] (
> +        string_builder.init(StringBuilderStream, !:StringBuilderState),
> +        write_xml_doc_general(StringBuilderStream, [1, 2, 3],
> +            simple, no_stylesheet, no_dtd, _, !StringBuilderState),
> +        String = string_builder_state_to_string(!.StringBuilderState),
> +        io.write_string(String, !IO),
> +        io.nl(!IO)
> +    ).

You may also want to include a few calls to stream.format and the
pprint.write_to_stream in there.

Julien.
--------------------------------------------------------------------------
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