[m-rev.] for review: move string builder stream to standard library
Ian MacLarty
maclarty at csse.unimelb.edu.au
Fri Apr 20 11:10:37 AEST 2007
On Thu, Apr 19, 2007 at 05:50:22PM +1000, Julien Fischer wrote:
>
> On Thu, 19 Apr 2007, Ian MacLarty wrote:
>
> >For review by anyone.
> >
> >Estimated hours taken: 0.5
> >Branches: main.
> >
> >Move the string builder stream from extras to the standard library.
> >
> >library/string.builder.m:
> > Move stream_util.string_builder to string.builder.
> >
> > Use builtin.copy instead of unsafe_promise_unique in the
> > implementation
> > of put/4 for the string builder stream.
> >
> >library/string.m:
> > Include string.builder.
>
> You also need to update the predicate mercury_std_library_module/1
> in library/library.m.
>
Done.
> >tests/hard_coded/Mmakefile:
> >tests/hard_coded/string_builder_test.exp:
> >tests/hard_coded/string_builder_test.m:
> > Add a test case.
> >
> >extras/Mmakefile:
> >extras/README:
> >extras/stream/Mmakefile:
> >extras/stream/README:
> >extras/stream/impure.m:
> >extras/stream/lowlevel.m:
> >extras/stream/stream_old.m:
> >extras/stream/stream_util.m:
> >extras/stream/stream_util.string_builder.m:
> >extras/stream/tests/Makefile:
> >extras/stream/tests/stream_util_test.exp:
> >extras/stream/tests/stream_util_test.m:
> > Completely remove the streams modules from extras. These modules
> > are all deprecated now.
>
> (For the record, Ian and I discussed this and decided that it was simpler
> to just delete the stream package from extras, rather than expend the
> any effort maintaining it; the stream support in the stdlib offers
> significantly more functionality than this ever did.)
>
> >Index: library/string.builder.m
> >===================================================================
> >RCS file: library/string.builder.m
> >diff -N library/string.builder.m
> >--- /dev/null 1 Jan 1970 00:00:00 -0000
> >+++ library/string.builder.m 19 Apr 2007 05:14:15 -0000
> >@@ -0,0 +1,92 @@
> >+%-----------------------------------------------------------------------------%
> >+% 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: string.builder.m.
> >+% Main author: maclarty.
> >+%
> >+% This module implements a string builder stream. It can be used to
> >+% build up a string using string or character writers.
> >+%
> >+%-----------------------------------------------------------------------------%
> >+%-----------------------------------------------------------------------------%
> >+
> >+:- module string.builder.
> >+:- interface.
> >+
> >+:- import_module char.
> >+:- import_module stream.
> >+
> >+%-----------------------------------------------------------------------------%
> >+
> >+:- type string_builder_stream.
>
> I suggest calling that string_builder_handle. The "stream" is really
> the combination of both that and the state.
>
I've renamed it to just string.builder.handle.
> >+:- type string_builder_state.
> >+
> >+:- pred init(string_builder_stream::out, string_builder_state::uo) is det.
>
> It may be worth having a TODO list somewhere in the implementation
> section that mentions that if the restriction on repeated variables
> in typeclass instances is lifted then this should actually be:
>
> :- type string_builder_stream(T).
> :- type string_builder_state(T).
>
> :- some [T] pred init(string_build_stream(T)::out,
> string_builder_state(T)::uo) is det.
>
I think a better idea might be to just expose the implementation of the
handle type to make it clear that it's a constant. This avoids the problem
of using the correct handle with the correct state altogether, because you
always use the same handle and it's only the state that varies. Have a
look at the interdiff at the end of this email and see what you think.
> >+:- 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.
>
> I would also provide to_string/1 as a synonym since that convention is
> followed throughout much of the library.
>
I've added to_string and deleted string_builder_state_to_string.
Ian.
diff -u library/string.builder.m library/string.builder.m
--- library/string.builder.m 19 Apr 2007 05:14:15 -0000
+++ library/string.builder.m 20 Apr 2007 01:00:00 -0000
@@ -12,7 +12,19 @@
% This module implements a string builder stream. It can be used to
% build up a string using string or character writers.
%
-%-----------------------------------------------------------------------------%
+% To build up a string using this module, you first construct an initial
+% string builder state by calling the init function. You can then use
+% any instances of stream.writer that write strings or characters to update the
+% string builder state, using string.builder.handle as the stream argument.
+% Once you've finished writing to the string builder you can get the final
+% string by calling string.builder.to_string/1.
+%
+% For example:
+%
+% State0 = string.builder.init,
+% stream.string_writer.put_int(string.builder.handle, 5, State0, State),
+% Str = string.builder.to_string(State), % Str = "5".
+%
%-----------------------------------------------------------------------------%
:- module string.builder.
@@ -23,21 +35,21 @@
%-----------------------------------------------------------------------------%
-:- type string_builder_stream.
+:- type handle
+ ---> handle.
-:- type string_builder_state.
+:- type state.
-:- pred init(string_builder_stream::out, string_builder_state::uo) is det.
+:- func init = (string.builder.state::uo) is det.
-:- instance stream.stream(string_builder_stream, string_builder_state).
+:- instance stream.stream(string.builder.handle, string.builder.state).
-:- instance stream.output(string_builder_stream, string_builder_state).
+:- instance stream.output(string.builder.handle, string.builder.state).
-:- instance stream.writer(string_builder_stream, string, string_builder_state).
-:- instance stream.writer(string_builder_stream, char, string_builder_state).
+:- instance stream.writer(string.builder.handle, string, string.builder.state).
+:- instance stream.writer(string.builder.handle, char, string.builder.state).
-:- func string_builder_state_to_string(string_builder_state::di) = (string::uo)
- is det.
+:- func to_string(string.builder.state::di) = (string::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -46,46 +58,43 @@
:- import_module list.
-:- type string_builder_state
- ---> string_builder_state(list(string)).
-
-:- type string_builder_stream
- ---> string_builder_stream.
+:- type state
+ ---> state(list(string)).
-init(string_builder_stream, string_builder_state([])).
+init = state([]).
-:- instance stream.stream(string_builder_stream, string_builder_state)
+:- instance stream.stream(string.builder.handle, string.builder.state)
where [
name(_, "<<string builder stream>>", !State)
].
-:- instance stream.output(string_builder_stream, string_builder_state)
+:- instance stream.output(string.builder.handle, string.builder.state)
where [
flush(_, !State)
].
-:- instance stream.writer(string_builder_stream, string, string_builder_state)
+:- instance stream.writer(string.builder.handle, string, string.builder.state)
where [
( put(_, String, !State) :-
- !.State = string_builder_state(StringList0),
+ !.State = state(StringList0),
copy(String, UniqueString),
StringList = [UniqueString | StringList0],
- !:State = string_builder_state(StringList)
+ !:State = state(StringList)
)
].
-:- instance stream.writer(string_builder_stream, char, string_builder_state)
+:- instance stream.writer(string.builder.handle, char, string.builder.state)
where [
( put(_, Char, !State) :-
- !.State = string_builder_state(StringList0),
+ !.State = state(StringList0),
StringList = [string.from_char(Char) | StringList0],
- !:State = string_builder_state(StringList)
+ !:State = state(StringList)
)
].
-string_builder_state_to_string(State) = String :-
- State = string_builder_state(StringList),
- String = string.join_list("", list.reverse(StringList)).
+to_string(State) = String :-
+ State = state(StringList),
+ String = string.append_list(list.reverse(StringList)).
%-----------------------------------------------------------------------------%
:- end_module string.builder.
diff -u tests/hard_coded/string_builder_test.m tests/hard_coded/string_builder_test.m
--- tests/hard_coded/string_builder_test.m 19 Apr 2007 04:17:19 -0000
+++ tests/hard_coded/string_builder_test.m 20 Apr 2007 01:02:01 -0000
@@ -15,12 +15,14 @@
:- import_module pprint.
:- import_module stream.
:- import_module stream.string_writer.
+:- import_module string.
:- import_module string.builder.
:- import_module term_to_xml.
main(!IO) :-
some [!State] (
- string.builder.init(Stream, !:State),
+ !:State = string.builder.init,
+ Stream = string.builder.handle,
put(Stream, "Hello", !State),
put(Stream, ',', !State),
put(Stream, " world!", !State),
@@ -34,5 +36,5 @@
string_writer.format(Stream, "%.2f", [f(3.14)], !State),
put(Stream, "\n", !State),
- String = string_builder_state_to_string(!.State),
+ String = string.builder.to_string(!.State),
io.write_string(String, !IO)
).
only in patch2:
unchanged:
--- NEWS 12 Apr 2007 04:31:09 -0000 1.453
+++ NEWS 20 Apr 2007 00:37:11 -0000
@@ -137,6 +137,10 @@
* We have added a function construct.get_functor_lex/2 which converts
an ordinal functor number into a lexicographic functor number.
+* A new module string.builder has been added to the standard library.
+ The new module provides instances of the stream typeclasses that can
+ be used to build up a string using char and string writers.
+
Changes to the Mercury compiler:
* The compiler now issues a warning when an inst declaration is not
only in patch2:
unchanged:
--- library/library.m 16 Mar 2007 21:00:24 -0000 1.103
+++ library/library.m 20 Apr 2007 00:38:49 -0000
@@ -254,6 +254,7 @@
mercury_std_library_module("stream").
mercury_std_library_module("stream.string_writer").
mercury_std_library_module("string").
+mercury_std_library_module("string.builder").
mercury_std_library_module("svarray").
mercury_std_library_module("svbag").
mercury_std_library_module("svbimap").
--------------------------------------------------------------------------
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