[m-rev.] Performance, layout and code improvements to pprint.m

Mark Brown dougl at cs.mu.OZ.AU
Thu Nov 1 05:56:09 AEDT 2001


Apart from the comments below, this looks good.

On 29-Oct-2001, Ralph Becket <rafe at cs.mu.OZ.AU> wrote:
> 
> Estimated hours taken: 24
> Branches: main
> 
> I've fixed a performance bug, tidied up the code somewhat, fixed a bug
> in the `group' doc semantics, added some improved list formatting
> functions and used them to improve the default formatting for lists,
> arrays, tuples and maps.
> 
> library/pprint.m:
> 	- Tidied up the code somewhat, including the removal of several
> 	  now-useless functions.
> 	- Fixed a performance bug in be//3 where what looked tail recursion

s.be//3.be/3.

> 	  actually wasn't.
> 	- Added a suite of packed_xxx functions to support placing as many
> 	  items as possible on a line.
> 	- Used those functions to improve the default formatting of lists,
> 	  tuples, maps, arrays, etc.
> 
> tests/hard_coded/pretty_printing.m:
> 	Added.
> 
> tests/hard_coded/pretty_printing.exp:
> 	Added (expected output of the above).
> 
> tests/hard_coded/Mmakefile:
> 	Added `pretty_printing' to list of ORDINARY_PROGS.
> 
> Index: pprint.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/pprint.m,v
> retrieving revision 1.5
> diff -u -r1.5 pprint.m
> --- pprint.m	26 Apr 2001 14:55:13 -0000	1.5
> +++ pprint.m	29 Oct 2001 05:47:00 -0000
> @@ -188,6 +188,9 @@
>      %
>  :- func label(string, doc)  = doc.
>  
> +    % A group doc gives the pretty printer a choice: if
> +    % the doc can be printed without line wrapping then
> +

This comment is unfinished.

>      % A group doc may be flattened out in the sense
>      % described for line, above, at the discretion of the
>      % pretty printer.  A group doc, therefore, defines a
> @@ -216,14 +219,40 @@
>  :- func brackets(doc)                   = doc.
>  :- func braces(doc)                     = doc.
>  
> -    % separated(PP, Sep, [X1,...,Xn]) =
> -    %   PP(X1) `<>` (Sep `<>` ... (Sep `<>` PP(Xn)) ... )
> +    % packed(Sep, [X1, X2, .., Xn]) = G1 `<>` G2 `<>` .. `<>` Gn where
> +    % Gi = group(line `<>` Xi `<>` Sep), except for Gn where
> +    % Gn = group(line `<>` Xn).
> +    %
> +    % For the singleton list case, packed(Sep, [X]) = group(line `<>` X).
> +    %
> +    % The resulting doc tries to pack as many items on a line as
> +    % possible.
>      %
> -    % Note that if you want to pack as many things on one
> -    % line as possible with some sort of separator, the
> -    % following example illustrates a suitable idiom:
> +:- func packed(doc, list(doc)) = doc.
> +
> +    % A variant of the above whereby only the first N elements of
> +    % the list are formatted and the rest are replaced by a single
> +    % ellipsis.
> +    %
> +:- func packed(int, doc, list(doc)) = doc.
> +
> +    % packed_cs(Xs) = packed(comma_space, Xs).

I'm not sure this abbreviation is a good idea, even though I'd expect
this variant to be used fairly often.  It doesn't achive the aim of
making code more readble, IMHO.  Can you think of a non-abbreviated
name which concisely describes the resulting document?  I'm thinking
of something like packed_list, although that could be slightly
misleading, since it might suggest a list in Mercury syntax.

>      %
> -    %   separated(PP, group(comma_space_line), Xs)
> +    % For example, to pretty print a Mercury list of docs
> +    % one might use
> +    %
> +    %   brackets(nest(2, packed_cs(Xs)))
> +    % 
> +:- func packed_cs(list(doc)) = doc.
> +
> +    % A variant of the above whereby only the first N elements of
> +    % the list are formatted and the rest are replaced by a single
> +    % ellipsis.
> +    %
> +:- func packed_cs(int, list(doc)) = doc.
> +
> +    % separated(PP, Sep, [X1,...,Xn]) =
> +    %   PP(X1) `<>` Sep `<>` ... Sep `<>` PP(Xn)
>      %
>  :- func separated(func(T) = doc, doc, list(T)) = doc.
>  
> 

...

> pretty_printing.m
> ===================================================================

If you 'cvs add' new files before creating the diff, then recent
versions of cvs will create a diff of these new files against /dev/null.
This saves you having to manually include all the added files.

Cheers,
Mark.

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