[m-rev.] for review: atoms in the debugger

Mark Brown dougl at cs.mu.OZ.AU
Wed Jan 9 01:39:53 AEDT 2002


On 31-Dec-2001, Zoltan Somogyi <zs at cs.mu.OZ.AU> wrote:
> For review by Mark. I would also like Ralph to look at the change to pprint.m.
> 
> Mark, you should start thinking about how to exploit this ability in the
> declarative debugger, but don't start coding yet. In another workspace,
> I have a diff that modifies I/O tabling to preserve enough information about
> I/O primitives to allow each I/O action's atom to be printed in full.
> I haven't tested it yet, since doing so requires the ability to print atoms,
> and I haven't merged the two changes yet.
> 
> The diffs to the .expN files are not final yet.
> 
> Estimated hours taken: 20
> Branches: main
> 
> Give the debugger the ability to print atoms.
> 
> NEWS:
> 	Mention the new ability.
> 
> browser/browser_info.m:
> 	Define a new type, browser_term, which represents either a plain term,
> 	or a "synthetic term", which is a string (predicate or function name),
> 	a list of argument values, and an indication of whether the synthetic
> 	term is a predicate atom (i.e. of the form p(a1, ..., an)) or a
> 	function atom (i.e. of the form f(a1, ..., an-1) = an).
> 
> 	Add utility predicates for processing browser_terms.
> 
> browser/browse.m:
> 	Add predicates for printing and browsing synthetic terms, and export
> 	them to C code.
> 
> browser/browse.m:
> browser/size_pretty.m:
> 	Generalize lots of predicates to handle browser_terms, not just plain
> 	terms.
> 
> browser/util.m:
> 	Add a new type, "unbound", for use by mercury_trace_vars.c.
> 
> library/pprint.m:
> 	Add functions for converting synthetic terms to docs.
> 
> 	Fix a potential efficiency problem: an unnecessary deconstruct.
> 
> runtime/mercury_type_info.h:
> 	Add macros for defining static type_infos in C code.
> 
> 	Add macros for computing the names of type_ctor_infos even in non-hlc
> 	grades.
> 
> 	Give C code access to the representation of bools and of values of
> 	the new type "unbound".
> 
> trace/mercury_trace_browse.[ch]:
> 	Add functions for printing atoms.
> 
> trace/mercury_trace_internal.c:
> 	Add code to recognize and handle the commands "print atom" and
> 	"browse atom".
> 
> trace/mercury_trace_vars.[ch]:
> 	Add a function to compute the components of synthetic terms.
> 
> tests/debugger/browse_pretty.{inp,exp,exp2}:
> 	Add new commands to the input to test the printing and browsing of
> 	predicate atoms, and update the expected outputs accordingly.
> 
> tests/debugger/polymorphic_output.{inp,exp,exp2}:
> 	Add new commands to the input to test the printing and browsing of
> 	function atoms, and update the expected outputs accordingly.
> 
> Zoltan.
> 
> cvs diff: Diffing .
> Index: NEWS
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/NEWS,v
> retrieving revision 1.234
> diff -u -b -r1.234 NEWS
> --- NEWS	2001/12/29 04:40:57	1.234
> +++ NEWS	2001/12/30 17:53:13
> @@ -155,6 +155,8 @@
>  * You can now navigate terms in the debugger by argument name as well as by
>    argument number.
>    
> +* You can now print atoms in the debugger.
> +  
>  * The Mercury compiler can now perform smart recompilation, enabled by the
>    `--smart-recompilation' option. With smart recompilation, when the
>    interface of a module changes, only modules which use the changed
> cvs diff: Diffing bindist
> cvs diff: Diffing boehm_gc
> cvs diff: Diffing boehm_gc/Mac_files
> cvs diff: Diffing boehm_gc/cord
> cvs diff: Diffing boehm_gc/cord/private
> cvs diff: Diffing boehm_gc/doc
> cvs diff: Diffing boehm_gc/include
> cvs diff: Diffing boehm_gc/include/private
> cvs diff: Diffing boehm_gc/tests
> cvs diff: Diffing browser
> Index: browser/browse.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/browser/browse.m,v
> retrieving revision 1.23
> diff -u -b -r1.23 browse.m
> --- browser/browse.m	2001/12/19 06:50:18	1.23
> +++ browser/browse.m	2001/12/30 18:01:19
> @@ -20,8 +20,8 @@
>  
>  :- interface.
>  
> -:- import_module io, std_util, list.
>  :- import_module mdb__browser_info.
> +:- import_module io, std_util, bool, list.
>  
>  	% The interactive term browser.  The caller type will be `browse', and
>  	% the default format for the `browse' caller type will be used.
> @@ -38,6 +38,16 @@
>  			browser_persistent_state, io__state, io__state).
>  :- mode browse__browse_format(in, in, in, in, in, out, di, uo) is det.
>  
> +:- pred browse__browse_synthetic(string::in, list(univ)::in, bool::in,
> +	io__input_stream::in, io__output_stream::in, maybe(list(dir))::out,
> +	browser_persistent_state::in, browser_persistent_state::out,
> +	io__state::di, io__state::uo) is det.

The new predicate should be documented here.  In particular, the meaning
of the first three arguments should be explained, since the existing
predicates don't have these.

> +
> +:- pred browse__browse_format_synthetic(string::in, list(univ)::in, bool::in,
> +	io__input_stream::in, io__output_stream::in, portray_format::in,
> +	browser_persistent_state::in, browser_persistent_state::out,
> +	io__state::di, io__state::uo) is det.
> +
>  	% The browser interface for the external debugger.  The caller type
>  	% will be `browse', and the default format will be used.
>  	%
> @@ -50,16 +60,22 @@
>  	% `print' or `print_all'.  The default portray format for that
>  	% caller type is used.
>  	%
> -:- pred browse__print(T, io__output_stream, browse_caller_type,
> -			browser_persistent_state, io__state, io__state).
> -:- mode browse__print(in, in, in, in, di, uo) is det.
> +:- pred browse__print(T::in, io__output_stream::in, browse_caller_type::in,
> +	browser_persistent_state::in, io__state::di, io__state::uo) is det.
>  
> +:- pred browse__print_synthetic(string::in, list(univ)::in, bool::in,
> +	io__output_stream::in, browse_caller_type::in,
> +	browser_persistent_state::in, io__state::di, io__state::uo) is det.
> +
>  	% As above, except that the supplied format will override the default.
>  	%
> -:- pred browse__print_format(T, io__output_stream, browse_caller_type,
> -			portray_format, browser_persistent_state,
> -			io__state, io__state).
> -:- mode browse__print_format(in, in, in, in, in, di, uo) is det.
> +:- pred browse__print_format(T::in, io__output_stream::in,
> +	browse_caller_type::in, portray_format::in,
> +	browser_persistent_state::in, io__state::di, io__state::uo) is det.
> +
> +:- pred browse__print_format_synthetic(string::in, list(univ)::in, bool::in,
> +	io__output_stream::in, browse_caller_type::in, portray_format::in,
> +	browser_persistent_state::in, io__state::di, io__state::uo) is det.
>  
>  	% Estimate the total term size, in characters,
>  	% We count the number of characters in the functor,
> @@ -79,12 +95,14 @@
>  	% by definition the caller is not interested in the accurate value.
>  :- pred term_size_left_from_max(univ::in, int::in, int::out) is det.
>  
> +:- pred browser_term_size_left_from_max(browser_term::in,
> +	int::in, int::out) is det.
> +
>  %---------------------------------------------------------------------------%
>  :- implementation.
>  
>  :- import_module mdb__parse, mdb__util, mdb__frame, mdb__sized_pretty.
>  :- import_module string, parser, require, std_util, int, char, pprint.
> -:- import_module bool.
>  
>  %---------------------------------------------------------------------------%
>  %
> @@ -96,12 +114,20 @@
>  	"ML_BROWSE_browse").
>  :- pragma export(browse__browse_format(in, in, in, in, in, out, di, uo),
>  	"ML_BROWSE_browse_format").
> +:- pragma export(browse__browse_synthetic(in, in, in, in, in, out,
> +	in, out, di, uo), "ML_BROWSE_browse_synthetic").
> +:- pragma export(browse__browse_format_synthetic(in, in, in, in, in, in,
> +	in, out, di, uo), "ML_BROWSE_browse_format_synthetic").
>  :- pragma export(browse__browse_external(in, in, in, in, out, di, uo),
>  	"ML_BROWSE_browse_external").
>  :- pragma export(browse__print(in, in, in, in, di, uo),
>  	"ML_BROWSE_print").
>  :- pragma export(browse__print_format(in, in, in, in, in, di, uo),
>  	"ML_BROWSE_print_format").
> +:- pragma export(browse__print_synthetic(in, in, in, in, in, in, di, uo),
> +	"ML_BROWSE_print_synthetic").
> +:- pragma export(browse__print_format_synthetic(in, in, in, in, in, in, in,
> +	di, uo), "ML_BROWSE_print_format_synthetic").
>  
>  %---------------------------------------------------------------------------%
>  % If the term browser is called from the internal debugger, input is
> @@ -129,31 +155,43 @@
>  %
>  
>  browse__print(Term, OutputStream, Caller, State) -->
> -	browse__print_common(Term, OutputStream, Caller, no, State).
> +	browse__print_common(plain_term(univ(Term)), OutputStream,
> +		Caller, no, State).
>  
>  browse__print_format(Term, OutputStream, Caller, Format, State) -->
> -	browse__print_common(Term, OutputStream, Caller, yes(Format), State).
> +	browse__print_common(plain_term(univ(Term)), OutputStream,
> +		Caller, yes(Format), State).
>  
> -:- pred browse__print_common(T, io__output_stream, browse_caller_type,
> -		maybe(portray_format), browser_persistent_state,
> -		io__state, io__state).
> -:- mode browse__print_common(in, in, in, in, in, di, uo) is det.
> +browse__print_synthetic(FunctorString, Args, IsFunc, OutputStream,
> +		Caller, State) -->
> +	browse__print_common(synthetic_term(FunctorString, Args, IsFunc),
> +		OutputStream, Caller, no, State).
> +
> +browse__print_format_synthetic(FunctorString, Args, IsFunc, OutputStream,
> +		Caller, Format, State) -->
> +	browse__print_common(synthetic_term(FunctorString, Args, IsFunc),
> +		OutputStream, Caller, yes(Format), State).
> +
> +:- pred browse__print_common(browser_term::in, io__output_stream::in,
> +	browse_caller_type::in, maybe(portray_format)::in,
> +	browser_persistent_state::in, io__state::di, io__state::uo) is det.
>  
> -browse__print_common(Term, OutputStream, Caller, MaybeFormat, State) -->
> -	{ browser_info__init(Term, MaybeFormat, State, Info) },
> +browse__print_common(BrowserTerm, OutputStream, Caller, MaybeFormat, State) -->
> +	{ Info = browser_info__init(BrowserTerm, MaybeFormat, State) },
>  	io__set_output_stream(OutputStream, OldStream),
>  	{ browser_info__get_format(Info, Caller, MaybeFormat, Format) },
>  	%
> -	% We assume that the variable name has been printed on the
> -	% first part of the line.  If the format is something other than
> +	% For plain terms, we assume that the variable name has been printed
> +	% on the first part of the line.  If the format is something other than
>  	% `flat', then we need to start on the next line.
>  	%
>  	(
> -		{ Format = flat }
> +		{ BrowserTerm = plain_term(_) },
> +		{ Format \= flat }
>  	->
> -		[]
> -	;
>  		io__nl
> +	;
> +		[]
>  	),
>  	portray(internal, Caller, no, Info),
>  	io__set_output_stream(OldStream, _).
> @@ -164,29 +202,36 @@
>  %
>  
>  browse__browse(Object, InputStream, OutputStream, MaybeMark, State0, State) -->
> -	browse_common(internal, Object, InputStream, OutputStream, 
> -		no, MaybeMark, State0, State).
> +	browse_common(internal, plain_term(univ(Object)),
> +		InputStream, OutputStream, no, MaybeMark, State0, State).
>  
>  browse__browse_format(Object, InputStream, OutputStream, Format,
>  		State0, State) -->
> +	browse_common(internal, plain_term(univ(Object)),
> +		InputStream, OutputStream, yes(Format), _, State0, State).
>  
> -	browse_common(internal, Object, InputStream, OutputStream,
> -		yes(Format), _, State0, State).
> +browse__browse_synthetic(FunctorString, Args, IsFunc,
> +		InputStream, OutputStream, MaybeMark, State0, State) -->
> +	browse_common(internal, synthetic_term(FunctorString, Args, IsFunc),
> +		InputStream, OutputStream, no, MaybeMark, State0, State).
> +
> +browse__browse_format_synthetic(FunctorString, Args, IsFunc,
> +		InputStream, OutputStream, Format, State0, State) -->
> +	browse_common(internal, synthetic_term(FunctorString, Args, IsFunc),
> +		InputStream, OutputStream, yes(Format), _, State0, State).
>  
>  browse__browse_external(Object, InputStream, OutputStream, State0, State) -->
> -	browse_common(external, Object, InputStream, OutputStream, 
> -		no, _, State0, State).
> +	browse_common(external, plain_term(univ(Object)),
> +		InputStream, OutputStream, no, _, State0, State).
>  
> -:- pred browse_common(debugger::in, T::in, io__input_stream::in,
> +:- pred browse_common(debugger::in, browser_term::in, io__input_stream::in,
>  		io__output_stream::in, maybe(portray_format)::in,
>  		maybe(list(dir))::out, browser_persistent_state::in,
> -		browser_persistent_state::out, io__state::di, io__state::uo)
> -		is det.
> +	browser_persistent_state::out, io__state::di, io__state::uo) is det.
>  
>  browse_common(Debugger, Object, InputStream, OutputStream, MaybeFormat,
>  		MaybeMark, State0, State) -->
> -	
> -	{ browser_info__init(Object, MaybeFormat, State0, Info0) },
> +	{ Info0 = browser_info__init(Object, MaybeFormat, State0) },
>  	io__set_input_stream(InputStream, OldInputStream),
>  	io__set_output_stream(OutputStream, OldOutputStream),
>  	% startup_message,
> @@ -403,10 +448,10 @@
>  	{ set_path(Path, Info0, Info) },
>  	portray(Debugger, Caller, MaybeFormat, Info).
>  
> -:- pred portray_flat(debugger, univ, format_params, io__state, io__state).
> -:- mode portray_flat(in, in, in, di, uo) is det.
> +:- pred portray_flat(debugger::in, browser_term::in, format_params::in,
> +	io__state::di, io__state::uo) is det.
>  
> -portray_flat(Debugger, Univ, Params) -->
> +portray_flat(Debugger, BrowserTerm, Params) -->
>  	%
>  	% io__write handles the special cases such as lists,
>  	% operators, etc. better, so we prefer to use it if we
> @@ -417,43 +462,65 @@
>  	%
>  	% XXX this ignores the maximum number of lines
>  	%
> -	{ max_print_size(MaxSize) },
> -	{ term_size_left_from_max(Univ, MaxSize, RemainingSize) },
> +	{ browser_term_size_left_from_max(BrowserTerm, max_print_size,
> +		RemainingSize) },
>  	( { RemainingSize >= 0 } ->
> -		io__write_univ(Univ)
> +		portray_flat_write_browser_term(BrowserTerm)
>  	;
> -		{ term_to_string(Univ, Params ^ size, Params ^ depth, Str) },
> +		{ browser_term_to_string(BrowserTerm, Params ^ size,
> +			Params ^ depth, Str) },
>  		write_string_debugger(Debugger, Str)
>  	).
>  
> -:- pred portray_verbose(debugger, univ, format_params, io__state, io__state).
> -:- mode portray_verbose(in, in, in, di, uo) is det.
> +:- pred portray_flat_write_browser_term(browser_term::in,
> +	io__state::di, io__state::uo) is det.
>  
> -portray_verbose(Debugger, Univ, Params) -->
> -	{ term_to_string_verbose(Univ, Params ^ size, Params ^ depth,
> -			Params ^ width, Params ^ lines, Str) },
> +portray_flat_write_browser_term(plain_term(Univ)) -->
> +	io__write_univ(Univ).
> +portray_flat_write_browser_term(synthetic_term(Functor, Args, IsFunc)) -->
> +	io__write_string(Functor),
> +	(
> +		{ IsFunc = yes },
> +		{ list__split_last_det(Args, PredArgs, FuncArg) },
> +		io__write_string("("),
> +		io__write_list(PredArgs, ", ", io__write_univ),
> +		io__write_string(") = "),
> +		io__write_univ(FuncArg)
> +	;
> +		{ IsFunc = no },
> +		io__write_string("("),
> +		io__write_list(Args, ", ", io__write_univ),
> +		io__write_string(")")
> +	).

You should check that the (pred-) args list is not empty.  If it is empty,
the parentheses shouldn't be printed.

> +
> +:- pred portray_verbose(debugger::in, browser_term::in, format_params::in,
> +	io__state::di, io__state::uo) is det.
> +
> +portray_verbose(Debugger, BrowserTerm, Params) -->
> +	{ browser_term_to_string_verbose(BrowserTerm, Params ^ size,
> +		Params ^ depth, Params ^ width, Params ^ lines, Str) },
>  	write_string_debugger(Debugger, Str).
>  
> -:- pred portray_raw_pretty(debugger, univ, format_params, io__state, io__state).
> -:- mode portray_raw_pretty(in, in, in, di, uo) is det.
> +:- pred portray_raw_pretty(debugger::in, browser_term::in, format_params::in,
> +	io__state::di, io__state::uo) is det.
>  
> -portray_raw_pretty(Debugger, Univ, Params) -->
> -	{ term_to_string_raw_pretty(Univ, Params ^ width, 
> +portray_raw_pretty(Debugger, BrowserTerm, Params) -->
> +	{ browser_term_to_string_raw_pretty(BrowserTerm, Params ^ width, 
>  			Params ^ depth, Str) },
>  	write_string_debugger(Debugger, Str).
> -
>  
> -:- pred portray_pretty(debugger, univ, format_params, io__state, io__state).
> -:- mode portray_pretty(in, in, in, di, uo) is det.
> +:- pred portray_pretty(debugger::in, browser_term::in, format_params::in,
> +	io__state::di, io__state::uo) is det.
>  
> -portray_pretty(Debugger, Univ, Params) -->
> -	{ sized_pretty__univ_to_string_line(Univ, Params ^ width, 
> -			Params ^ lines, Str) },
> +portray_pretty(Debugger, BrowserTerm, Params) -->
> +	{ sized_pretty__browser_term_to_string_line(BrowserTerm,
> +		Params ^ width, Params ^ lines, Str) },
>  	write_string_debugger(Debugger, Str).
>  
>  	% The maximum estimated size for which we use `io__write'.
> -:- pred max_print_size(int::out) is det.
> -max_print_size(60).
> +:- func max_print_size = int.
> +
> +max_print_size = 60.
>  
>  term_size_left_from_max(Univ, MaxSize, RemainingSize) :-
>  	(
> @@ -473,58 +540,97 @@
>  		RemainingSize = -1
>  	).
>  
> +browser_term_size_left_from_max(BrowserTerm, MaxSize, RemainingSize) :-
> +	(
> +		BrowserTerm = plain_term(Univ),
> +		term_size_left_from_max(Univ, MaxSize, RemainingSize)
> +	;
> +		BrowserTerm = synthetic_term(Functor, Args, IsFunc),
> +		string__length(Functor, FunctorSize),
> +		list__length(Args, Arity),
> +		(
> +			IsFunc = yes,
> +			PrincipalSize = FunctorSize + 1 + Arity * 2
> +		;
> +			IsFunc = no,
> +			PrincipalSize = FunctorSize + Arity * 2
> +		),

The variable Arity is mis-named; it should be something like NumArgs,
or PredArity as Fergus suggested.

> +		MaxArgsSize = MaxSize - PrincipalSize,
> +		list__foldl(term_size_left_from_max,
> +			Args, MaxArgsSize, RemainingSize)
> +	).
> +
>  %---------------------------------------------------------------------------%
>  %
>  % Single-line representation of a term.
>  %
> +
> +:- pred browser_term_to_string(browser_term::in, int::in, int::in,
> +	string::out) is det.
>  
> -:- pred term_to_string(univ, int, int, string).
> -:- mode term_to_string(in, in, in, out) is det.
> -term_to_string(Univ, MaxSize, MaxDepth, Str) :-
> +browser_term_to_string(BrowserTerm, MaxSize, MaxDepth, Str) :-
>  	CurSize = 0,
>  	CurDepth = 0,
> -	term_to_string_2(Univ, MaxSize, CurSize, _NewSize,
> +	browser_term_to_string_2(BrowserTerm, MaxSize, CurSize, _NewSize,
>  		MaxDepth, CurDepth, Str).
>  
>  	% Note: When the size limit is reached, we simply display
> -	% further subterms compressed. We don't just stopping printing.
> +	% further subterms compressed. We don't just stop printing.
>  	% XXX: Is this reasonable?
> -:- pred term_to_string_2(univ, int, int, int, int, int, string).
> -:- mode term_to_string_2(in, in, in, out, in, in, out) is det.
> -term_to_string_2(Univ, MaxSize, CurSize, NewSize, MaxDepth, CurDepth, Str) :-
> +:- pred browser_term_to_string_2(browser_term::in, int::in, int::in, int::out,
> +	int::in, int::in, string::out) is det.
> +
> +browser_term_to_string_2(BrowserTerm, MaxSize, CurSize, NewSize,
> +		MaxDepth, CurDepth, Str) :-
>  	(
>  		CurSize < MaxSize,
>  		CurDepth < MaxDepth,
> -		limited_deconstruct(univ_value(Univ), MaxSize, Functor,
> -			_Arity, Args)
> +		limited_deconstruct_browser_term(BrowserTerm, MaxSize, Functor,
> +			_Arity, Args, IsFunc)
>  	->
>  		CurSize1 is CurSize + 1,
>  		CurDepth1 is CurDepth + 1,
> -		term_to_string_list(Args, MaxSize, CurSize1, NewSize,
> -			MaxDepth, CurDepth1, ArgStrs),
> +		(
> +			IsFunc = yes,
> +			list__split_last_det(Args, PredArgs, FuncArg),
> +			browser_term_to_string_list(PredArgs, MaxSize,
> +				CurSize1, NewSize1, MaxDepth, CurDepth1,
> +				PredArgStrs),
> +			brack_args(PredArgStrs, BrackPredArgsStr),
> +			browser_term_to_string_2(plain_term(FuncArg), MaxSize,
> +				NewSize1, NewSize, MaxDepth, CurDepth1,
> +				FuncArgStr),
> +			string__append_list([Functor, BrackPredArgsStr,
> +				" = ", FuncArgStr], Str)
> +		;
> +			IsFunc = no,
> +			browser_term_to_string_list(Args, MaxSize,
> +				CurSize1, NewSize, MaxDepth, CurDepth1,
> +				ArgStrs),
>  		brack_args(ArgStrs, BrackArgsStr),
>  		string__append_list([Functor, BrackArgsStr], Str)
> +		)
>  	;
>  		% Str = "...",
> -		term_compress(Univ, Str),
> +		browser_term_compress(BrowserTerm, Str),
>  		NewSize = CurSize
>  	).
> +
> +:- pred browser_term_to_string_list(list(univ)::in, int::in, int::in, int::out,
> +	int::in, int::in, list(string)::out) is det.

This is a misnomer, since the predicate works on univs not browser_terms.
I don't see a need to change the name of this predicate.

>  
> -:- pred term_to_string_list(list(univ), int, int, int, int, int, list(string)).
> -:- mode term_to_string_list(in, in, in, out, in, in, out) is det.
> -term_to_string_list([], _MaxSize, CurSize, NewSize,
> +browser_term_to_string_list([], _MaxSize, CurSize, NewSize,
>  		_MaxDepth, _CurDepth, Strs) :-
>  	Strs = [],
>  	NewSize = CurSize.
> -term_to_string_list([Univ | Univs], MaxSize, CurSize, NewSize,
> +browser_term_to_string_list([Univ | Univs], MaxSize, CurSize, NewSize,
>  		MaxDepth, CurDepth, Strs) :-
> -	term_to_string_2(Univ, MaxSize, CurSize, NewSize1,
> +	browser_term_to_string_2(plain_term(Univ), MaxSize, CurSize, NewSize1,
>  		MaxDepth, CurDepth, Str),
> -	term_to_string_list(Univs, MaxSize, NewSize1, NewSize,
> +	browser_term_to_string_list(Univs, MaxSize, NewSize1, NewSize,
>  		MaxDepth, CurDepth, RestStrs),
>  	Strs = [Str | RestStrs].
>  
> -
>  :- pred brack_args(list(string), string).
>  :- mode brack_args(in, out) is det.
>  brack_args(Args, Str) :-
> @@ -549,16 +655,23 @@
>  		comma_args([S2 | Ss], Rest),
>  		string__append_list([S1, ", ", Rest], Str)
>  	).
> +
> +:- pred browser_term_compress(browser_term::in, string::out) is det.
>  
> -:- pred term_compress(univ, string).
> -:- mode term_compress(in, out) is det.
> -term_compress(Univ, Str) :-
> -	functor(univ_value(Univ), Functor, Arity),
> +browser_term_compress(BrowserTerm, Str) :-
> +	functor_browser_term(BrowserTerm, Functor, Arity, IsFunc),
>  	( Arity = 0 ->
>  		Str = Functor
>  	;
> +		(
> +			IsFunc = yes,
> +			int_to_string(Arity - 1, ArityS),
> +			append_list([Functor, "/", ArityS, "+1"], Str)
> +		;
> +			IsFunc = no,
>  		int_to_string(Arity, ArityS),
>  		append_list([Functor, "/", ArityS], Str)
> +		)
>  	).
>  	
>  %---------------------------------------------------------------------------%
> @@ -568,13 +681,17 @@
>  % provides no way of doing this.
>  %
>  
> -:- pred term_to_string_raw_pretty(univ, int, int, string).
> -:- mode term_to_string_raw_pretty(in, in, in, out) is det.
> +:- pred browser_term_to_string_raw_pretty(browser_term::in, int::in, int::in,
> +	string::out) is det.
>  
> -term_to_string_raw_pretty(Univ, Width, MaxDepth, Str) :-
> +browser_term_to_string_raw_pretty(plain_term(Univ), Width, MaxDepth, Str) :-
>  	Value = univ_value(Univ),
>  	Doc = to_doc(MaxDepth, Value),
>  	Str = to_string(Width, Doc).
> +browser_term_to_string_raw_pretty(synthetic_term(Functor, Args, IsFunc), Width,
> +		MaxDepth, Str) :-
> +	Doc = synthetic_term_to_doc(MaxDepth, Functor, Args, IsFunc),
> +	Str = to_string(Width, Doc).
>  
>  %---------------------------------------------------------------------------%
>  %
> @@ -582,62 +699,61 @@
>  % Numbering makes it easier to change to subterms.
>  %
>  
> -:- pred term_to_string_verbose(univ, int, int, int, int, string).
> -:- mode term_to_string_verbose(in, in, in, in, in, out) is det.
> -term_to_string_verbose(Univ, MaxSize, MaxDepth, X, Y, Str) :-
> +:- pred browser_term_to_string_verbose(browser_term::in, int::in, int::in,
> +	int::in, int::in, string::out) is det.
> +
> +browser_term_to_string_verbose(BrowserTerm, MaxSize, MaxDepth, X, Y, Str) :-
>  	CurSize = 0,
>  	CurDepth = 0,
> -	term_to_string_verbose_2(Univ, MaxSize, CurSize, _NewSize,
> -		MaxDepth, CurDepth, Frame),
> +	browser_term_to_string_verbose_2(BrowserTerm, MaxSize, CurSize,
> +		_NewSize, MaxDepth, CurDepth, Frame),
>  	frame__clip(X-Y, Frame, ClippedFrame),
>  	unlines(ClippedFrame, Str).
> +
> +:- pred browser_term_to_string_verbose_2(browser_term::in, int::in, int::in,
> +	int::out, int::in, int::in, frame::out) is det.
>  
> -:- pred term_to_string_verbose_2(univ, int, int, int, int, int, frame).
> -:- mode term_to_string_verbose_2(in, in, in, out, in, in, out) is det.
> -term_to_string_verbose_2(Univ, MaxSize, CurSize, NewSize,
> +browser_term_to_string_verbose_2(BrowserTerm, MaxSize, CurSize, NewSize,
>  		MaxDepth, CurDepth, Frame) :-
>  	(
>  		CurSize < MaxSize,
>  		CurDepth < MaxDepth,
> -		limited_deconstruct(univ_value(Univ), MaxSize, Functor,
> -			_Arity, Args)
> +		limited_deconstruct_browser_term(BrowserTerm, MaxSize, Functor,
> +			_Arity, Args, _IsFunc)
>  	->
>  		CurSize1 is CurSize + 1,
>  		CurDepth1 is CurDepth + 1,
>  		ArgNum = 1,
> -		term_to_string_verbose_list(Args, ArgNum,
> +		browser_term_to_string_verbose_list(Args, ArgNum,
>  			MaxSize, CurSize1, NewSize,
>  			MaxDepth, CurDepth1, ArgsFrame),
>  		frame__vglue([Functor], ArgsFrame, Frame)
>  	;
> -		term_compress(Univ, Line),
> +		browser_term_compress(BrowserTerm, Line),
>  		Frame = [Line],
>  		NewSize = CurSize
>  	).
>  
> -:- pred term_to_string_verbose_list(list(univ), int, int, int, int,
> -	int, int, frame).
> -:- mode term_to_string_verbose_list(in, in, in, in, out, in, in, out) is det.
> +:- pred browser_term_to_string_verbose_list(list(univ)::in, int::in, int::in,
> +	int::in, int::out, int::in, int::in, frame::out) is det.

See above comment for term_to_string_list.

>  
> -term_to_string_verbose_list([], _ArgNum, _MaxSize, CurSize, NewSize,
> +browser_term_to_string_verbose_list([], _ArgNum, _MaxSize, CurSize, NewSize,
>  		_MaxDepth, _CurDepth, []) :-
>  	NewSize = CurSize.
> -
> -term_to_string_verbose_list([Univ], ArgNum, MaxSize, CurSize, NewSize,
> +browser_term_to_string_verbose_list([Univ], ArgNum, MaxSize, CurSize, NewSize,
>  		MaxDepth, CurDepth, Frame) :-
> -	term_to_string_verbose_2(Univ, MaxSize, CurSize, NewSize,
> -		MaxDepth, CurDepth, TreeFrame),
> +	browser_term_to_string_verbose_2(plain_term(Univ), MaxSize,
> +		CurSize, NewSize, MaxDepth, CurDepth, TreeFrame),
>  	% XXX: ArgNumS must have fixed length 2.
>  	string__int_to_string(ArgNum, ArgNumS),
>  	string__append_list([ArgNumS, "-"], LastBranchS),
>  	frame__hglue([LastBranchS], TreeFrame, Frame).
> -
> -term_to_string_verbose_list([Univ1, Univ2 | Univs], ArgNum, MaxSize, CurSize,
> -		NewSize, MaxDepth, CurDepth, Frame) :-
> -	term_to_string_verbose_2(Univ1, MaxSize, CurSize, NewSize1,
> -		MaxDepth, CurDepth, TreeFrame),
> +browser_term_to_string_verbose_list([Univ1, Univ2 | Univs], ArgNum, MaxSize,
> +		CurSize, NewSize, MaxDepth, CurDepth, Frame) :-
> +	browser_term_to_string_verbose_2(plain_term(Univ1), MaxSize, CurSize,
> +		NewSize1, MaxDepth, CurDepth, TreeFrame),
>  	ArgNum1 is ArgNum + 1,
> -	term_to_string_verbose_list([Univ2 | Univs], ArgNum1, MaxSize,
> +	browser_term_to_string_verbose_list([Univ2 | Univs], ArgNum1, MaxSize,
>  		NewSize1, NewSize2, MaxDepth, CurDepth, RestTreesFrame),
>  	NewSize = NewSize2,
>  	% XXX: ArgNumS must have fixed length 2.
> @@ -651,6 +767,7 @@
>  	frame__vglue(TopFrame, RestTreesFrame, Frame).
>  
>  :- pred unlines(list(string)::in, string::out) is det.
> +
>  unlines([], "").
>  unlines([Line | Lines], Str) :-
>  	string__append(Line, "\n", NLine),
> @@ -719,14 +836,40 @@
>  
>  	% We assume a root-relative path. We assume Term is the entire term
>  	% passed into browse/3, not a subterm.
> -:- pred deref_subterm(univ, list(dir), univ) is semidet.
> -:- mode deref_subterm(in, in, out) is semidet.
> -deref_subterm(Univ, Path, SubUniv) :-
> +:- pred deref_subterm(browser_term::in, list(dir)::in, browser_term::out)
> +	is semidet.
> +
> +deref_subterm(BrowserTerm, Path, SubBrowserTerm) :-
>  	simplify_dirs(Path, SimplifiedPath),
> -	deref_subterm_2(Univ, SimplifiedPath, SubUniv).
> +	(
> +		BrowserTerm = plain_term(Univ),
> +		deref_subterm_2(Univ, SimplifiedPath, SubUniv),
> +		SubBrowserTerm = plain_term(SubUniv)
> +	;
> +		BrowserTerm = synthetic_term(_FunctorString, Args, _IsFunc),
> +		(
> +			Path = [],
> +			SubBrowserTerm = BrowserTerm
> +		;
> +			Path = [Dir | _Dirs],

Why is the rest of the path ignored?  There should be a call to
deref_subterm_2/3 somewhere in here which processes the rest of the path.

> +			(
> +				Dir = child_num(N),
> +				% The first argument of a non-array is numbered
> +				% argument 1.
> +				list__index1(Args, N, SubUniv),
> +				SubBrowserTerm = plain_term(SubUniv)
> +			;
> +				Dir = child_name(_),
> +				fail
> +			;
> +				Dir = parent,
> +				error("deref_subterm: found parent")
> +			)
> +		)
> +	).
>  
> -:- pred deref_subterm_2(univ, list(dir), univ) is semidet.
> -:- mode deref_subterm_2(in, in, out) is semidet.
> +:- pred deref_subterm_2(univ::in, list(dir)::in, univ::out) is semidet.
> +
>  deref_subterm_2(Univ, Path, SubUniv) :-
>  	(
>  		Path = [],
> @@ -782,19 +925,19 @@
>  		list__append(PwdDirs, Dirs, NewDirs)
>  	),
>  	simplify_dirs(NewDirs, RootRelDirs).
> +
> +:- pred set_term(univ::in, browser_info::in, browser_info::out) is det.
>  
> -:- pred set_term(T, browser_info, browser_info).
> -:- mode set_term(in, in, out) is det.
>  set_term(Term, Info0, Info) :-
> -	type_to_univ(Term, Univ),
> -	set_univ(Univ, Info0, Info1),
> +	set_browser_term(plain_term(Term), Info0, Info1),
>  	% Display from the root term.
>  	% This avoid errors due to dereferencing non-existent subterms.
>  	set_path(root_rel([]), Info1, Info).
> +
> +:- pred set_browser_term(browser_term::in, browser_info::in, browser_info::out)
> +	is det.
>  
> -:- pred set_univ(univ, browser_info, browser_info).
> -:- mode set_univ(in, in, out) is det.
> -set_univ(NewUniv, Info, Info ^ term := NewUniv).
> +set_browser_term(BrowserTerm, Info, Info ^ term := BrowserTerm).
>  
>  %---------------------------------------------------------------------------%
>  %
> Index: browser/browser_info.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/browser/browser_info.m,v
> retrieving revision 1.5
> diff -u -b -r1.5 browser_info.m
> --- browser/browser_info.m	2001/12/19 06:44:47	1.5
> +++ browser/browser_info.m	2001/12/29 01:04:00
> @@ -15,20 +15,34 @@
>  :- interface.
>  :- import_module bool, list, std_util.
>  
> +:- type browser_term
> +	--->	plain_term(
> +			univ		% We are browsing a plain term.
> +		)
> +	;	synthetic_term(
> +			string,		% We are browsing a synthetic term,
> +					% such as a predicate name applied to
> +					% a list of arguments. The string says
> +					% what we should print as the functor.
> +			list(univ),
> +			bool
> +		).
> +

These last two fields should also be documented.

Come to think of it, a better design might be to separate the return value
from the other arguments.  That is, have the second field be the list of
arguments (without any return value), and the third field would be of type
maybe(univ), which holds the return value iff there is one.  This would
abstract away the fact that we make the return value the _last_ argument
in the underlying predicate, which is an implementation detail that the
users shouldn't have to think about.  I realise this would involve a
fairly extensive change to the current diff, but it would make much of the
rest of the code significantly easier to understand and maintain, IMHO.

I don't mind if you don't follow this suggestion right now.  But I think
you should at least consider changing the type to something like what I
just described.

>  	% The non-persistent browser information.  A new one of these is
>  	% created every time the browser is called, based on the contents
>  	% of the persistent state, and lasts for the duration of the call.
>  	%
>  :- type browser_info
>  	--->	browser_info(
> -			term	:: univ,	% Term to browse.
> -			dirs	:: list(dir),	% The list of directories to
> -						% take, starting from the root,
> -						% to reach the current subterm.
> +			term		:: browser_term,
> +					% Term to browse.
> +			dirs		:: list(dir),
> +					% The list of directories to take,
> +					% starting from the root, to reach
> +					% the current subterm.
>  			format	:: maybe(portray_format),
> -						% Format specified as
> -						% an option to the mdb
> -						% command.
> +					% Format specified as an option to the
> +					% mdb command.
>  			state	:: browser_persistent_state,
>  						% Persistent settings.
>  			maybe_mark :: maybe(list(dir))
> @@ -84,9 +98,8 @@
>  	% Initialise a new browser_info.  The optional portray_format
>  	% overrides the default format.
>  	%
> -:- pred browser_info__init(T, maybe(portray_format), browser_persistent_state,
> -		browser_info).
> -:- mode browser_info__init(in, in, in, out) is det.
> +:- func browser_info__init(browser_term, maybe(portray_format),
> +	browser_persistent_state) = browser_info.
>  
>  	% Get the format to use for the given caller type.  The optional
>  	% portray_format overrides the current default.
> @@ -125,6 +138,17 @@
>  
>  %---------------------------------------------------------------------------%
>  
> +:- pred deconstruct_browser_term(browser_term::in,
> +	string::out, int::out, list(univ)::out, bool::out) is det.
> +
> +:- pred limited_deconstruct_browser_term(browser_term::in, int::in,
> +	string::out, int::out, list(univ)::out, bool::out) is semidet.
> +
> +:- pred functor_browser_term(browser_term::in, string::out, int::out,
> +	bool::out) is det.
> +
> +%---------------------------------------------------------------------------%
> +
>  :- implementation.
>  :- import_module require.
>  
> @@ -199,8 +223,8 @@
>  
>  %---------------------------------------------------------------------------%
>  
> -browser_info__init(Term, MaybeFormat, State, Info) :-
> -	Info = browser_info(univ(Term), [], MaybeFormat, State, no).
> +browser_info__init(BrowserTerm, MaybeFormat, State) =
> +	browser_info(BrowserTerm, [], MaybeFormat, State, no).
>  
>  browser_info__get_format(Info, Caller, MaybeFormat, Format) :-
>  	(
> @@ -413,3 +437,38 @@
>  browser_persistent_state_type(type_of(State)) :-
>  	browser_info__init_persistent_state(State).
>  
> +%---------------------------------------------------------------------------%
> +
> +deconstruct_browser_term(BrowserTerm, Functor, Arity, Args, IsFunc) :-
> +	(
> +		BrowserTerm = plain_term(Univ),
> +		deconstruct(univ_value(Univ), Functor, Arity, Args),
> +		IsFunc = no
> +	;
> +		BrowserTerm = synthetic_term(Functor, Args, IsFunc),
> +		list__length(Args, Arity)
> +	).
> +
> +limited_deconstruct_browser_term(BrowserTerm, Limit, Functor, Arity, Args,
> +		IsFunc) :-
> +	(
> +		BrowserTerm = plain_term(Univ),
> +		limited_deconstruct(univ_value(Univ), Limit,
> +			Functor, Arity, Args),
> +		IsFunc = no
> +	;
> +		BrowserTerm = synthetic_term(Functor, Args, IsFunc),
> +		list__length(Args, Arity)
> +	).
> +
> +functor_browser_term(BrowserTerm, Functor, Arity, IsFunc) :-
> +	(
> +		BrowserTerm = plain_term(Univ),
> +		functor(univ_value(Univ), Functor, Arity),
> +		IsFunc = no
> +	;
> +		BrowserTerm = synthetic_term(Functor, Args, IsFunc),
> +		list__length(Args, Arity)
> +	).

These predicates calculate the arity incorrectly for functions, unless
by "arity" you mean the arity of the underlying predicate, which I don't
think you should.

> +
> +%---------------------------------------------------------------------------%
> Index: browser/sized_pretty.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/browser/sized_pretty.m,v
> retrieving revision 1.4
> diff -u -b -r1.4 sized_pretty.m
> --- browser/sized_pretty.m	2001/06/26 06:16:22	1.4
> +++ browser/sized_pretty.m	2001/12/29 01:03:39
> @@ -161,13 +161,18 @@
>  
>  :- interface.
>  
> +:- import_module mdb__browser_info.
>  :- import_module std_util, int, string.
>  
>  	% This may throw an exception or cause a runtime abort if the term
>  	% in question has user-defined equality. 
>  	% The Limit is number of lines.
> -:- pred univ_to_string_line(univ::in, int::in, int::in, string::out) is det.
> +:- pred sized_pretty__univ_to_string_line(univ::in, int::in, int::in,
> +	string::out) is det.
>  
> +:- pred sized_pretty__browser_term_to_string_line(browser_term::in,
> +	int::in, int::in, string::out) is det.
> +
>  %---------------------------------------------------------------------------%
>  
>  :- implementation.
> @@ -192,16 +197,17 @@
>  	% upto the point where the specified limit was reached.
>  :- type size_annotated_term(T)
>  	--->	exact(
> -			univ,			% univ(Term)
> +			browser_term,		% univ(Term)
>  			T,			% size of the term
>  			string,			% Functor
>  			int,			% Arity
>  			size_annotated_args(T) 	% arguments
>  		)
>  	;	at_least(
> -			univ,		% univ(Term)
> -			T,		% size of the term upto the point
> -					% where it's deconstructed
> +			browser_term,		% univ(Term)
> +			T,			% size of the term up to the
> +						% point where it is
> +						% deconstructed
>  			maybe_deconstructed(T)
>  		).
>  
> @@ -238,24 +244,31 @@
>  		%	  each argument,
>  		%	- adjusted measurement of available space,
>  		%	- adjusted measure parameter(s).
> -	pred measured_split(univ::in, MeasureParams::in, T::in, int::in,
> -	     bool::in, T::out, maybe(T)::out, T::out, MeasureParams::out) is det
> -		
> +	pred measured_split(browser_term::in, MeasureParams::in, T::in,
> +		int::in, bool::in, T::out, maybe(T)::out, T::out,
> +		MeasureParams::out) is det
>  ].
>  
>  %---------------------------------------------------------------------------%
> +
>  	% When the space (to print the term) is given in number of lines there
> -	% is an inital check that has to be done. This is due to the fact that
> +	% is an initial check that has to be done. This is due to the fact that
>  	% size_count_split assumes that every term is part of a bigger term and
>  	% therefore assumes that a term will have a comma and a space after it.
>  	% This is not true for the biggest term (Head Term) therefore if the
>  	% Head Term is going to be printed on a single line then it should be
>  	% given a limit of character_count(LineWidth - 1) instead of
>  	% character_count(LineWidth - 3).
> -univ_to_string_line(Univ, LineWidth, Lines, String) :-
> +sized_pretty__univ_to_string_line(Univ, LineWidth, Lines, String) :-
> +	sized_pretty__browser_term_to_string_line(plain_term(Univ),
> +		LineWidth, Lines, String).
> +
> +sized_pretty__browser_term_to_string_line(BrowserTerm, LineWidth, Lines,
> +		String) :-
>  	Params = measure_params(LineWidth),
> -	functor(univ_value(Univ), _, Arity),
> -	( 	Arity \= 0,
> +	functor_browser_term(BrowserTerm, _Functor, Arity, _IsFunc),
> +	(
> +		Arity \= 0,
>  		Lines \= 0,
>  		(Lines - 1) // Arity = 0 
>  	->
> @@ -264,60 +277,63 @@
>  	;
>  		Limit = line_count(Lines)
>  	),
> -	annotate_with_size(Univ, Params, Limit, AnnotTerm),
> +	annotate_with_size(BrowserTerm, Params, Limit, AnnotTerm),
>  	Doc = to_doc_sized(AnnotTerm),
>  	String = pprint__to_string(LineWidth, Doc).
>  
>  %---------------------------------------------------------------------------%
> +
>  	% first_pass gives an idea of how much space each term takes
>  	% In this pass the space is unevenly distributed. First come first
>  	% served. And once the space runs out, the term is not deconstructed
>  	% further. 
> -	% In The Second pass the space is evenly distributed between
> +	% In the Second pass the space is evenly distributed between
>  	% the terms and therefore the subterms are deconstructed evenly.
> -:- pred annotate_with_size(univ::in, MeasureParams::in, T::in,
> +:- pred annotate_with_size(browser_term::in, MeasureParams::in, T::in,
>  	size_annotated_term(T)::out) is det
>  	<= measure_with_params(T, MeasureParams).
>  
> -annotate_with_size(Univ, Params, Limit, Size2) :-
> -	first_pass(Univ, Params, Limit, Size1),
> -	second_pass(Size1, Params, Limit, Size2).
> +annotate_with_size(BrowserTerm, Params, Limit, SizedTerm2) :-
> +	first_pass(BrowserTerm, Params, Limit, SizedTerm1),
> +	second_pass(SizedTerm1, Params, Limit, SizedTerm2).
>  
>  %---------------------------------------------------------------------------%
>  	
> -:- pred first_pass(univ::in, MeasureParams::in, T::in,
> +:- pred first_pass(browser_term::in, MeasureParams::in, T::in,
>  	size_annotated_term(T)::out) is det
>  	<= measure_with_params(T, MeasureParams).
>  
> -first_pass(Univ, Params, Limit, Size) :-
> +first_pass(BrowserTerm, Params, Limit, Size) :-
>  	MaxFunctors = maximum_functors(Limit, Params),
>  	(
> -		limited_deconstruct(univ_value(Univ), MaxFunctors,
> -				Functor, Arity, UnivArgs)
> +		limited_deconstruct_browser_term(BrowserTerm, MaxFunctors,
> +			Functor, Arity, Args, _IsFunc)
>  	->
> -		measured_split(Univ, Params, Limit, Arity, yes, FunctorSize, 
> -					MaybeInitArgLimit, NewLimit, NewParams),
> +		measured_split(BrowserTerm, Params, Limit, Arity, yes,
> +			FunctorSize, MaybeInitArgLimit, NewLimit, NewParams),
>  		( (Arity \= 0, MaybeInitArgLimit = no) ->
>  			Exact0 = no
>  		;
>  			Exact0 = yes
>  		),
> -		annotate_args_with_size(UnivArgs, MaybeInitArgLimit, NewParams,
> +		annotate_args_with_size(Args, MaybeInitArgLimit, NewParams,
>  			NewLimit, FunctorSize, SoFar, Exact0, Exact,
>  			MaybeArgSizes),
>  		(
>  			Exact = no,
> -			Size = at_least(Univ, SoFar,
> +			Size = at_least(BrowserTerm, SoFar,
>  				deconstructed(Functor, Arity, MaybeArgSizes))
>  		;
>  			Exact = yes,
> -			Size = exact(Univ, SoFar, Functor, Arity, MaybeArgSizes)
> +			Size = exact(BrowserTerm, SoFar, Functor, Arity,
> +				MaybeArgSizes)
>  		)
>  	;
> -		Size = at_least(Univ, zero_measure, not_deconstructed)
> +		Size = at_least(BrowserTerm, zero_measure, not_deconstructed)
>  	).
>  
>  %---------------------------------------------------------------------------%
> +
>  	% annotating the arguments.
>  :- pred annotate_args_with_size(list(univ)::in, maybe(T)::in,
>  	MeasureParams::in, T::in, T::in, T::out, bool::in, bool::out, 
> @@ -336,7 +352,7 @@
>  			AppliedArgLimit = max_measure(InitArgLimit,
>  				subtract_measures(Limit, SoFar0, Params))
>  		),
> -		first_pass(Arg, Params, AppliedArgLimit, Size),
> +		first_pass(plain_term(Arg), Params, AppliedArgLimit, Size),
>  		MaybeArgSize = yes(InitArgLimit - Size),
>  		extract_size_from_annotation(Size) = ArgSize,
>  		SoFar1 = add_measures(SoFar0, ArgSize, Params),
> @@ -370,15 +386,19 @@
>  
>  %---------------------------------------------------------------------------%
>  
> -:- func extract_univ_from_annotation(size_annotated_term(T)) = univ.
> +:- func extract_browser_term_from_annotation(size_annotated_term(T)) =
> +	browser_term.
>  
> -extract_univ_from_annotation(exact(Univ, _, _, _, _)) = Univ.
> -extract_univ_from_annotation(at_least(Univ, _, _)) = Univ.
> +extract_browser_term_from_annotation(exact(BrowserTerm, _, _, _, _)) =
> +	BrowserTerm.
> +extract_browser_term_from_annotation(at_least(BrowserTerm, _, _)) =
> +	BrowserTerm.
>  
>  %---------------------------------------------------------------------------%
> +
>  	% This predicate basically ensures that the arguments that
>  	% take up smaller "Space" than their fair share is fully
> -	% printed and the rest the Space is shared equally between
> +	% printed and the rest of Space is shared equally between
>  	% the other terms which could take up more than their share.
>  	% If a term can be fully printed within the given space,
>  	% ("exact" type) then the Term is not altered.
> @@ -388,24 +408,25 @@
>  
>  second_pass(OldSizeTerm, Params, Limit, NewSizeTerm) :-
>  	(
> -    		OldSizeTerm = exact(_Univ, _Size, _, _Arity, _MaybeArgs),
> +    		OldSizeTerm = exact(_BrowserTerm, _Size, _,
> +			_Arity, _MaybeArgs),
>  		NewSizeTerm = OldSizeTerm
>  	;
> -    		OldSizeTerm = at_least(_Univ, _Size, not_deconstructed),
> +    		OldSizeTerm = at_least(_BrowserTerm, _Size, not_deconstructed),
>  		NewSizeTerm = OldSizeTerm
>  	;
> -    		OldSizeTerm = at_least(Univ, _Size, deconstructed(Functor, 
> -			Arity,MaybeArgs)),
> -		measured_split(Univ, Params, Limit, Arity, yes, FSize,
> +    		OldSizeTerm = at_least(BrowserTerm, _Size,
> +			deconstructed(Functor, Arity,MaybeArgs)),
> +		measured_split(BrowserTerm, Params, Limit, Arity, yes, FSize,
>  			MaybeInitLimit, NewLimit, NewParams),
> -		( if MaybeInitLimit = yes(InitLimit) then
> +		( MaybeInitLimit = yes(InitLimit) ->
>  	    		check_args(NewParams, MaybeArgs, InitLimit, Passed, 
>  				FSize, Used),
>  			LeftOver = add_measures(subtract_measures(NewLimit, 
>  			  	Used, Params), FSize, Params),
> -	    		measured_split(Univ, Params, LeftOver, Arity - Passed, 
> -				no, _, MaybeSplitLimit, _, _),
> -	    		( if MaybeSplitLimit = yes(SplitLimit) then
> +	    		measured_split(BrowserTerm, Params, LeftOver,
> +				Arity - Passed, no, _, MaybeSplitLimit, _, _),
> +	    		( MaybeSplitLimit = yes(SplitLimit) ->
>  	        		process_args(NewParams, MaybeArgs, InitLimit,
>  					SplitLimit, NewArgs, NewSize0),
>  				NewSize = add_measures(FSize, NewSize0, 
> @@ -413,54 +434,60 @@
>  				Result0 = list__map(check_if_exact, NewArgs),
>      				list__remove_adjacent_dups(Result0, Result),
>  				( Result = [yes] ->
> -					NewSizeTerm = exact(Univ, NewSize, 
> -						Functor, Arity, NewArgs) 	
> +					NewSizeTerm = exact(BrowserTerm,
> +						NewSize, Functor, Arity,
> +						NewArgs) 	
>  	        		;
> -					NewSizeTerm = at_least(Univ, NewSize, 
> +					NewSizeTerm = at_least(BrowserTerm,
> +						NewSize, 
>  						deconstructed(Functor, Arity, 
>  						NewArgs))
>  				)
> -	    		else
> -	        		NewSizeTerm = at_least(Univ, FSize, 
> +	    		;
> +	        		NewSizeTerm = at_least(BrowserTerm, FSize, 
>  					not_deconstructed)
>  	    		)
> -		else
> -			NewSizeTerm = at_least(Univ, FSize, not_deconstructed)
> +		;
> +			NewSizeTerm = at_least(BrowserTerm, FSize,
> +				not_deconstructed)
>  		)
>  	).
>  	
>  %---------------------------------------------------------------------------%
> +
>  	% Given a list of size annotated terms(ie arguments) and a
>  	% Limit, this predicate returns the values "Passed" and 
>  	% "Used". Where "Passed" represents the number of terms that
>  	% obey the Limit and are fully represented("exact") and "Used"
>  	% represents the space that these terms take up.
>  :- pred check_args(MeasureParams::in, size_annotated_args(T)::in, T::in, 
> -	int::out, T::in, T::out) is det <= measure_with_params(T, 
> -	MeasureParams).
> +	int::out, T::in, T::out) is det
> +	<= measure_with_params(T, MeasureParams).
>  
>  check_args(_, [], _, 0, Used0, Used0).
>  check_args(Params, [HeadArg | Rest], ArgLimit, Passed, Used0, Used) :-
> -	if HeadArg = yes(X) then
> +	( HeadArg = yes(X) ->
>  		X = _ - STerm,
>  		Size = extract_size_from_annotation(STerm), 
> -		( if STerm = exact(_, _, _, _, _) then
> -	    		( if compare_measures(ArgLimit, Size) = (<) then
> +		( STerm = exact(_, _, _, _, _) ->
> +	    		( compare_measures(ArgLimit, Size) = (<) ->
>  	    			check_args(Params, Rest, ArgLimit, Passed, 
>  					Used0, Used)
> -	    		else
> +	    		;
>  	    			Passed = 1 + PassedRest,
>  				UsedSofar = add_measures(Used0, Size, Params),
>  	    			check_args(Params, Rest, ArgLimit, PassedRest, 
>  					UsedSofar, Used)
>  	    		)
> -		else
> +		;
>  	    		check_args(Params, Rest, ArgLimit, Passed, Used0, Used)
>  		)
> -    	else
> -		check_args(Params, Rest, ArgLimit, Passed, Used0, Used).
> +    	;
> +		check_args(Params, Rest, ArgLimit, Passed, Used0, Used)
> +	).
>  
>  %---------------------------------------------------------------------------%
> +
>  	% This predicate accepts a list of size annotated terms(paired
>  	% with a flag) and returns a list of the same type. This new
>  	% list would consist of the same number of terms as the other
> @@ -474,10 +501,10 @@
>  process_args(_, [], _, _, [], zero_measure).
>  process_args(Params, [HeadArg | Rest], ArgLimit, SplitLimit, 
>  		[NewHeadArg | NewRest], SizeOut) :-
> -    	( if HeadArg = yes(X) then
> +    	( HeadArg = yes(X) ->
>  		X = _ - STerm,
>  		Size = extract_size_from_annotation(STerm), 
> -        	Univ = extract_univ_from_annotation(STerm), 
> +        	BrowserTerm = extract_browser_term_from_annotation(STerm), 
>  		( 
>  			STerm = exact(_, _, _, _, _),
>  	    		(
> @@ -489,9 +516,10 @@
>  			NewHeadArg = HeadArg
>  		;
>  			NewHeadArg = yes(pair(SplitLimit, NewSTerm)),
> -			annotate_with_size(Univ, Params, SplitLimit, NewSTerm)
> +			annotate_with_size(BrowserTerm, Params, SplitLimit,
> +				NewSTerm)
>  		)
> -    	else
> +    	;
>  		NewHeadArg = no
>      	),
>      	( NewHeadArg = yes(_ - Term) ->
> @@ -503,6 +531,7 @@
>      	process_args(Params, Rest, ArgLimit, SplitLimit, NewRest, RestSize).
>  
>  %---------------------------------------------------------------------------%
> +
>  	% checking if an size-annotated arg is an exact type (fully represented)
>  :- func check_if_exact(maybe(pair(T, size_annotated_term(T)))) = bool.
>  
> @@ -517,13 +546,28 @@
>  	).	
>  
>  %---------------------------------------------------------------------------%
> +
>  	% A function to convert a size annotated term to a 'doc' type,
>  	% a type defined in pprint.m.
>  :- func to_doc_sized(size_annotated_term(T)) = doc.
>  
> -to_doc_sized(at_least(Univ, _, not_deconstructed)) = Doc :-
> +to_doc_sized(at_least(BrowserTerm, _, not_deconstructed)) = Doc :-
> +	(
> +		BrowserTerm = plain_term(Univ),
>  	functor(univ_value(Univ), Functor, Arity),
> -	Doc = text(Functor) `<>` text("/") `<>` poly(i(Arity)).
> +		Doc = text(Functor) `<>` text("/") `<>` poly(i(Arity))
> +	;
> +		BrowserTerm = synthetic_term(Functor, Args, IsFunc),
> +		list__length(Args, Arity),
> +		(
> +			IsFunc = yes,
> +			Doc = text(Functor) `<>` text("/") `<>`
> +				poly(i(Arity - 1)) `<>` text("+1")
> +		;
> +			IsFunc = no,
> +			Doc = text(Functor) `<>` text("/") `<>` poly(i(Arity))
> +		)
> +	).
>  
>  to_doc_sized(at_least(_, _, deconstructed(Functor, Arity, MaybeArgs))) = Doc :-
>  	Doc = to_doc_sized_2(Functor, Arity, MaybeArgs).
> @@ -532,6 +576,7 @@
>  	Doc = to_doc_sized_2(Functor, Arity, MaybeArgs).
>  
>  %---------------------------------------------------------------------------%
> +
>  	% Assumes that every argument must be on a different line
>  	% or all of them should be on the same line.
>  :- func to_doc_sized_2(string, int, size_annotated_args(T)) = doc.
> @@ -556,6 +601,7 @@
>  handle_arg(no) = nil.
>  
>  %---------------------------------------------------------------------------%
> +
>  	% functor_count is a representation where the size of a term
>  	% is measured by the number of function symbols.
>  
> @@ -591,12 +637,14 @@
>  
>  zero_functor_count = functor_count(0).
>  	
> -:- pred functor_count_split(univ::in, no_measure_params::in, functor_count::in,
> -	int::in, bool::in, functor_count::out, maybe(functor_count)::out,
> -	functor_count::out, no_measure_params::out) is det.
> +:- pred functor_count_split(browser_term::in, no_measure_params::in,
> +	functor_count::in, int::in, bool::in, functor_count::out,
> +	maybe(functor_count)::out, functor_count::out, no_measure_params::out)
> +	is det.
>  
> -functor_count_split(_, Params, functor_count(Limit), Arity, _, functor_count(1),
> -		MaybeArgLimit, functor_count(Limit), Params) :-
> +functor_count_split(_, Params, functor_count(Limit), Arity, _,
> +		functor_count(1), MaybeArgLimit, functor_count(Limit),
> +		Params) :-
>  	( Arity = 0 ->
>  		MaybeArgLimit = no
>  	;
> @@ -621,8 +669,8 @@
>  	pred(measured_split/9) is functor_count_split
>  ].
>  
> -
>  %---------------------------------------------------------------------------%
> +
>  	% char_count is a representation where the size of a term is
>  	% measured by the number of characters.
>  
> @@ -659,21 +707,29 @@
>  
>  zero_char_count = char_count(0).
>  
> -:- pred char_count_split(univ::in, no_measure_params::in, char_count::in,
> -	int::in, bool::in, char_count::out, maybe(char_count)::out,
> -	char_count::out, no_measure_params::out) is det.
> +:- pred char_count_split(browser_term::in, no_measure_params::in,
> +	char_count::in, int::in, bool::in, char_count::out,
> +	maybe(char_count)::out, char_count::out, no_measure_params::out)
> +	is det.
>  
> -char_count_split(Univ, Params, char_count(Limit), Arity, Check, 
> +char_count_split(BrowserTerm, Params, char_count(Limit), Arity, Check, 
>  		char_count(FunctorSize), MaybeArgLimit, char_count(Limit),
>  		Params) :-
> -
> -	deconstruct(univ_value(Univ), Functor, _, Args),
> +	deconstruct_browser_term(BrowserTerm, Functor, _, Args, IsFunc),
>  	( Check = yes ->
>  		get_arg_length(Args, TotalLength, _)
>  	;
>  		TotalLength = 0
> +	),
> +	(
> +		IsFunc = yes,
> +		% Arity-2 times the string ", ", once "()", and once " = "
> +		FunctorSize = string__length(Functor) + 1 + 2 * (Arity)
> +	;
> +		IsFunc = no,
> +		% Arity-1 times the string ", ", and once "()"
> +		FunctorSize = string__length(Functor) + 2 * (Arity)
>  	),
> -	FunctorSize = string__length(Functor) + 2*(Arity),
>  	( Arity = 0 ->
>  		MaybeArgLimit = no
>  	;
> @@ -699,6 +755,7 @@
>  ].
>  
>  %---------------------------------------------------------------------------%
> +
>  	% size_count is representation where the size of a term is
>  	% measured by number of lines or number of characters.
>  
> @@ -821,26 +878,26 @@
>  
>  	% We assume that all arguments have to be on separate lines, or 
>  	% the whole term should be printed on a single line.
> -:- pred size_count_split(univ::in, measure_params::in, size_count::in,
> +:- pred size_count_split(browser_term::in, measure_params::in, size_count::in,
>  	int::in, bool::in, size_count::out, maybe(size_count)::out,
>  	size_count::out, measure_params::out) is det.
>  
> -size_count_split(Univ, Params, Limit, Arity, Check, FunctorSize, 
> +size_count_split(BrowserTerm, Params, Limit, Arity, Check, FunctorSize, 
>  		MaybeArgLimit, NewLimit, NewParams) :-
>  	% LineWidth is length of the line in which the functor is printed.
>  	Params = measure_params(LineWidth),
> -    	deconstruct(univ_value(Univ), Functor, ActualArity, Args),
> +	deconstruct_browser_term(BrowserTerm, Functor, ActualArity, Args,
> +		IsFunc),
>      	FSize = string__length(Functor) + 2 * (ActualArity),
>      	( Check = yes ->
>      		get_arg_length(Args, TotalLength, MaxArgLength),
> -		int__max(MaxArgLength, (string__length(Functor) + 1), MaxLength)
> +		int__max(MaxArgLength, (string__length(Functor) + 1),
> +			MaxLength)
>      	;
>      		TotalLength = 0,
>  		MaxLength = 0
>      	), 
> -    	( 
> -		Arity = 0 
> -	->
> +	( Arity = 0 ->
>  		MaybeArgLimit = no,
>      		FunctorSize = character_count(FSize),
>  		NewLimit = Limit,
> @@ -851,8 +908,8 @@
>  			% we need one line for the functor and atleast 
>  			% one line for each argument
>  			LineLimit >= (Arity + 1),
> -			% linewidth is decreased by two characters to account 
> -			% for indentation
> +			% linewidth is decreased by two characters
> +			% to account  for indentation
>  			(LineWidth - 2) >= MaxLength
>  		->
>  			Line = (LineLimit - 1) // Arity,
> @@ -863,13 +920,15 @@
>  		;
>  			Limit = line_count(LineLimit),
>  			LineLimit > 0,
> -			% Since every term is part of a bigger term (in this 
> -			% context anyway) it will have a comma, space and a 
> -			% newline at the end of it (Hence the "- 3").
> +			% Since every term is part of a bigger term
> +			% (in this  context anyway) it will have a
> +			% comma, space and a  newline at the end of it
> +			% (Hence the "- 3").
>  			LineWidth - 3 >= (FSize + TotalLength) 
>  		->
>  	    		% "Arity - 1" is for rounding up.
> -			Char = (LineWidth - 3 - FSize + Arity - 1) // Arity ,
> +			Char = (LineWidth - 3 - FSize + Arity - 1)
> +				// Arity ,
>  	    		MaybeArgLimit = yes(character_count(Char)),
>  	    		FunctorSize = character_count(FSize),
>  	    		NewLimit = character_count(LineWidth - 3),
> @@ -878,17 +937,33 @@
>  			Limit = character_count(CharLimit),
>  			CharLimit >= (FSize + TotalLength)
>  		->
> -	   		Char = (CharLimit - FSize + Arity - 1) // Arity,
> +			Char = (CharLimit - FSize + Arity - 1)
> +				// Arity,
>  	   		MaybeArgLimit = yes(character_count(Char)),
>  	   		FunctorSize = character_count(FSize),
>  	   		NewLimit = Limit,
>  	   		NewParams = Params
>  		;
>  	   		MaybeArgLimit = no,
> -			% If a term is not deconstructed, it is printed as
> -			% "functor/Arity". The "+ 2" accounts for that.
> -	   		FunctorSize = 
> -				character_count(string__length(Functor) + 2),
> +			% If an ordinary term is not deconstructed, it is
> +			% printed as "functor/Arity". If a synthetic function
> +			% term is not deconstructed, it is printed as
> +			% "functor/n+1", where n is Arity-1.
> +			% XXX we should

The XXX is not complete.

> +			(
> +				IsFunc = no,
> +				FuncSuffixChars = 0,
> +				EffArity = Arity
> +			;
> +				IsFunc = yes,
> +				FuncSuffixChars = 2,
> +				EffArity = Arity - 1
> +			),
> +			FunctorLength = string__length(Functor),
> +			string__int_to_string(EffArity, ArityStr),
> +			string__length(ArityStr, ArityChars),
> +			FunctorSize = character_count(FunctorLength + 1
> +				+ ArityChars + FuncSuffixChars),
>  	   		NewLimit = Limit, 
>  	   		NewParams = Params
>  		)
> @@ -908,6 +983,7 @@
>  ].
>  
>  %---------------------------------------------------------------------------%
> +
>  	% This predicate determines how many characters it will take
>  	% to print the functors of the arguments. Also determines the
>  	% length of biggest functor.
> Index: browser/util.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/browser/util.m,v
> retrieving revision 1.13
> diff -u -b -r1.13 util.m
> --- browser/util.m	2001/06/22 15:20:23	1.13
> +++ browser/util.m	2001/12/30 17:00:26
> @@ -74,6 +74,10 @@
>  :- pred util__limit(pred(list(T), list(T)), list(T), list(T)).
>  :- mode util__limit(pred(in,out) is det, in, out) is det.
>  
> +	% For use in representing unbound head variables in the "print atom"
> +	% commands in the debugger.
> +:- type unbound ---> '_'.
> +
>  %---------------------------------------------------------------------------%
>  :- implementation.
>  
> cvs diff: Diffing bytecode
> cvs diff: Diffing compiler
> cvs diff: Diffing compiler/notes
> cvs diff: Diffing debian
> cvs diff: Diffing deep_profiler
> cvs diff: Diffing deep_profiler/notes
> cvs diff: Diffing doc
> cvs diff: Diffing extras
> cvs diff: Diffing extras/aditi
> cvs diff: Diffing extras/cgi
> cvs diff: Diffing extras/complex_numbers
> cvs diff: Diffing extras/complex_numbers/samples
> cvs diff: Diffing extras/complex_numbers/tests
> cvs diff: Diffing extras/concurrency
> cvs diff: Diffing extras/curs
> cvs diff: Diffing extras/curs/samples
> cvs diff: Diffing extras/curses
> cvs diff: Diffing extras/curses/sample
> cvs diff: Diffing extras/dynamic_linking
> cvs diff: Diffing extras/graphics
> cvs diff: Diffing extras/graphics/mercury_opengl
> cvs diff: Diffing extras/graphics/mercury_tcltk
> cvs diff: Diffing extras/graphics/samples
> cvs diff: Diffing extras/graphics/samples/calc
> cvs diff: Diffing extras/graphics/samples/maze
> cvs diff: Diffing extras/graphics/samples/pent
> cvs diff: Diffing extras/lazy_evaluation
> cvs diff: Diffing extras/lex
> cvs diff: Diffing extras/lex/samples
> cvs diff: Diffing extras/logged_output
> cvs diff: Diffing extras/moose
> cvs diff: Diffing extras/moose/samples
> cvs diff: Diffing extras/morphine
> cvs diff: Diffing extras/morphine/non-regression-tests
> cvs diff: Diffing extras/morphine/scripts
> cvs diff: Diffing extras/morphine/source
> cvs diff: Diffing extras/odbc
> cvs diff: Diffing extras/posix
> cvs diff: Diffing extras/quickcheck
> cvs diff: Diffing extras/quickcheck/tutes
> cvs diff: Diffing extras/references
> cvs diff: Diffing extras/references/samples
> cvs diff: Diffing extras/references/tests
> cvs diff: Diffing extras/stream
> cvs diff: Diffing extras/trailed_update
> cvs diff: Diffing extras/trailed_update/samples
> cvs diff: Diffing extras/trailed_update/tests
> cvs diff: Diffing extras/xml
> cvs diff: Diffing extras/xml/samples
> cvs diff: Diffing java
> cvs diff: Diffing library
> Index: library/pprint.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/pprint.m,v
> retrieving revision 1.6
> diff -u -b -r1.6 pprint.m
> --- library/pprint.m	2001/11/02 00:49:21	1.6
> +++ library/pprint.m	2001/12/29 00:41:38
> @@ -150,7 +150,7 @@
>  
>  :- interface.
>  
> -:- import_module int, string, list, io.
> +:- import_module std_util, bool, int, string, list, io.
>  
>      % Clients must translate data structures into docs for
>      % the pretty printer to display.
> @@ -293,6 +293,14 @@
>  :- func to_doc(T)           = doc.
>  :- func to_doc(int, T)      = doc.
>  
> +    % These two functions are just like like to_doc, except their input is not
> +    % a natural term, but a synthetic term defined by a functor, a list of
> +    % arguments, and a boolean that is true iff the synthetic term is a
> +    % function application, and thus should be printed not as f(a1, ... an)
> +    % but as f(a1, ... an-1) = an.
> +:- func synthetic_term_to_doc(string, list(univ), bool)           = doc.
> +:- func synthetic_term_to_doc(int, string, list(univ), bool)      = doc.
> +
>      % Convert docs to pretty printed strings.  The int
>      % argument specifies a line width in characters.
>      %
> @@ -312,7 +320,7 @@
>  
>  :- implementation.
>  
> -:- import_module std_util, char, array, map.
> +:- import_module char, array, map, require.
>  
>  :- type doc
>      --->    'NIL'
> @@ -568,6 +576,8 @@
>  %------------------------------------------------------------------------------%
>  
>  to_doc(X) = to_doc(int__max_int, X).
> +synthetic_term_to_doc(Functor, Args, IsFunc) =
> +    synthetic_term_to_doc(int__max_int, Functor, Args, IsFunc).
>  
>  %------------------------------------------------------------------------------%
>  
> @@ -597,6 +607,53 @@
>        else    generic_term_to_doc(Depth, X)
>      ).
>  
> +synthetic_term_to_doc(Depth, Functor, Args, IsFunc) = Doc :-
> +    list__length(Args, Arity),
> +    ( Depth =< 0 ->
> +        ( Arity = 0 ->
> +            Doc = text(Functor)
> +        ;
> +            IsFunc = yes,
> +            Doc = text(Functor) `<>` text("/") `<>` poly(i(Arity - 1))
> +                `<>` text("+1") 
> +        ;
> +            IsFunc = no,
> +            Doc = text(Functor) `<>` text("/") `<>` poly(i(Arity))
> +        )
> +    ;
> +        ( Arity = 0 ->
> +            Doc = text(Functor)
> +        ;
> +            (
> +                IsFunc = yes,
> +                list__length(Args, NumArgs),
> +                (
> +                    list__split_list(NumArgs - 1, Args, PredArgsPrime,
> +                        FuncArgs),
> +                    FuncArgs = [FuncArgPrime]
> +                ->
> +                    PredArgs = PredArgsPrime,
> +                    FuncArg = FuncArgPrime
> +                ;
> +                    error("synthetic_term_to_doc: length mismatch")
> +                ),
> +                Doc = group(
> +                        text(Functor) `<>` parentheses(
> +                            nest(2, packed_cs_univ_args(Depth - 1, PredArgs))
> +                        ) `<>`
> +                        nest(2, text(" = ") `<>` to_doc(Depth - 1, FuncArg))
> +                    )
> +            ;
> +                IsFunc = no,
> +                Doc = group(
> +                        text(Functor) `<>` parentheses(
> +                            nest(2, packed_cs_univ_args(Depth - 1, Args))
> +                        )
> +                    )
> +            )
> +        )
> +    ).
> +
>  %------------------------------------------------------------------------------%
>  
>  :- some [T2] pred dynamic_cast_to_array(T1, array(T2)).
> @@ -696,7 +753,7 @@
>  
>  out_of_depth_term_to_doc(X) = Doc :-
>  
> -    deconstruct(X, Name, Arity, _UnivArgs),
> +    functor(X, Name, Arity),
>  
>      Doc = ( if Arity = 0 then text(Name)
>                           else text(Name) `<>` text("/") `<>` poly(i(Arity))
> cvs diff: Diffing profiler
> cvs diff: Diffing robdd
> cvs diff: Diffing runtime
> Index: runtime/mercury_type_info.h
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/runtime/mercury_type_info.h,v
> retrieving revision 1.77
> diff -u -b -r1.77 mercury_type_info.h
> --- runtime/mercury_type_info.h	2001/12/31 04:26:52	1.77
> +++ runtime/mercury_type_info.h	2001/12/31 05:05:42
> @@ -301,6 +301,33 @@
>  #define MR_fill_in_tuple_type_info(arena, type_ctor_info, arity, vector) \
>      MR_fill_in_higher_order_type_info(arena, type_ctor_info, arity, vector)
>  
> +#define MR_static_type_info_arity_0(name, ctor)				\
> +	struct {							\
> +		MR_TypeCtorInfo field1;					\
> +	} name = {							\
> +		(MR_TypeCtorInfo) (ctor)				\
> +	};
> +
> +#define MR_static_type_info_arity_1(name, ctor, ti1)			\
> +	struct {							\
> +		MR_TypeCtorInfo field1;					\
> +		MR_TypeInfo 	field2;					\
> +	} name = {							\
> +		(MR_TypeCtorInfo) (ctor),				\
> +		(MR_TypeInfo)     (ti1)					\
> +	};
> +
> +#define MR_static_type_info_arity_2(name, ctor, ti1, t2)		\

s/t2/ti2/

> +	struct {							\
> +		MR_TypeCtorInfo field1;					\
> +		MR_TypeInfo 	field2;					\
> +		MR_TypeInfo 	field3;					\
> +	} name = {							\
> +		(MR_TypeCtorInfo) (ctor),				\
> +		(MR_TypeInfo)     (ti1),				\
> +		(MR_TypeInfo)     (ti2)					\
> +	};
> +
>  /*
>  ** Used to define MR_TypeCtorInfos for the builtin types in the hlc grades.
>  ** This needs to be exported for use by the array type in the library.
> @@ -308,6 +335,9 @@
>  
>  #ifdef MR_HIGHLEVEL_CODE
>  
> +#define MR_builtin_type_ctor_info_name(TYPE, ARITY)			      \
> +		MR_type_ctor_info_name(builtin, TYPE, ARITY)
> +
>    #define MR_type_ctor_info_name(MODULE, TYPE, ARITY)			      \
>  	MR_PASTE2(mercury__,						      \
>  	MR_PASTE2(MODULE,						      \
> @@ -384,6 +414,23 @@
>  
>    #endif /* MR_BOOTSTRAP_TYPE_CTOR_VERSION_NO */
>  
> +#else /* MR_HIGHLEVEL_CODE */
> +
> +  #define MR_builtin_type_ctor_info_name(TYPE, ARITY)			      \
> +	MR_PASTE2(mercury_data_,					      \
> +	MR_PASTE2(__type_ctor_info_,					      \
> +	MR_PASTE2(TYPE,							      \
> +	MR_PASTE2(_,							      \
> +		 ARITY))))
> +
> +  #define MR_type_ctor_info_name(MODULE, TYPE, ARITY)			      \
> +	MR_PASTE2(mercury_data_,					      \
> +	MR_PASTE2(MODULE,						      \
> +	MR_PASTE2(__type_ctor_info_,					      \
> +	MR_PASTE2(TYPE,							      \
> +	MR_PASTE2(_,							      \
> +		 ARITY)))))
> +
>  #endif /* MR_HIGHLEVEL_CODE */
>  
>  /*---------------------------------------------------------------------------*/
> @@ -400,15 +447,25 @@
>  	** the same primary tag (1), and are all allocated secondary tags
>  	** starting from 0.
>  	*/
> -    #define MR_COMPARE_TAG      MR_mktag(MR_FIRST_UNRESERVED_RAW_TAG)
> +  #define MR_ENUM_TAG         MR_mktag(MR_FIRST_UNRESERVED_RAW_TAG)
>   
> -    #define MR_COMPARE_EQUAL    MR_mkword(MR_COMPARE_TAG, MR_mkbody(0))
> -    #define MR_COMPARE_LESS     MR_mkword(MR_COMPARE_TAG, MR_mkbody(1))
> -    #define MR_COMPARE_GREATER  MR_mkword(MR_COMPARE_TAG, MR_mkbody(2))         
> +  #define MR_COMPARE_EQUAL    MR_mkword(MR_ENUM_TAG, MR_mkbody(0))
> +  #define MR_COMPARE_LESS     MR_mkword(MR_ENUM_TAG, MR_mkbody(1))
> +  #define MR_COMPARE_GREATER  MR_mkword(MR_ENUM_TAG, MR_mkbody(2))         
> +
> +  #define MR_BOOL_NO          MR_mkword(MR_ENUM_TAG, MR_mkbody(0))
> +  #define MR_BOOL_YES         MR_mkword(MR_ENUM_TAG, MR_mkbody(1))
> +
> +  #define MR_UNBOUND          MR_mkword(MR_ENUM_TAG, MR_mkbody(0))
>  #else
>      #define MR_COMPARE_EQUAL    0
>      #define MR_COMPARE_LESS     1
>      #define MR_COMPARE_GREATER  2
> +
> +  #define MR_BOOL_NO          0
> +  #define MR_BOOL_YES         1
> +
> +  #define MR_UNBOUND          0
>  #endif
>  
>  /*---------------------------------------------------------------------------*/
> cvs diff: Diffing runtime/GETOPT
> cvs diff: Diffing runtime/machdeps
> cvs diff: Diffing samples
> cvs diff: Diffing samples/c_interface
> cvs diff: Diffing samples/c_interface/c_calls_mercury
> cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
> cvs diff: Diffing samples/c_interface/mercury_calls_c
> cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
> cvs diff: Diffing samples/c_interface/mercury_calls_fortran
> cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
> cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
> cvs diff: Diffing samples/diff
> cvs diff: Diffing samples/muz
> cvs diff: Diffing samples/rot13
> cvs diff: Diffing samples/solutions
> cvs diff: Diffing samples/tests
> cvs diff: Diffing samples/tests/c_interface
> cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
> cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
> cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
> cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
> cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
> cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
> cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
> cvs diff: Diffing samples/tests/diff
> cvs diff: Diffing samples/tests/muz
> cvs diff: Diffing samples/tests/rot13
> cvs diff: Diffing samples/tests/solutions
> cvs diff: Diffing samples/tests/toplevel
> cvs diff: Diffing scripts
> cvs diff: Diffing tests
> cvs diff: Diffing tests/benchmarks
> cvs diff: Diffing tests/debugger
> Index: tests/debugger/browse_pretty.exp
> ===================================================================
> RCS file: /home/mercury1/repository/tests/debugger/browse_pretty.exp,v
> retrieving revision 1.7
> diff -u -b -r1.7 browse_pretty.exp
> --- tests/debugger/browse_pretty.exp	2001/11/07 06:43:08	1.7
> +++ tests/debugger/browse_pretty.exp	2001/12/30 17:16:07
> @@ -104,5 +104,23 @@
>    [|](1, [|](2, [|]/2)), 
>    small)
>  browser> quit
> +mdb> print atom
> +big_data(
> +  big(big/3, [|]/2, big/3))
> +mdb> browse atom
> +browser> ls
> +big_data(
> +  big(big/3, [|]/2, big/3))
> +browser> ^1
> +browser> ls
> +big(
> +  big(big/3, [|]/2, small), 
> +  [|](1, [|](2, [|]/2)), 
> +  big(big/3, [|]/2, small))
> +browser> ^..
> +browser> ls
> +big_data(
> +  big(big/3, [|]/2, big/3))
> +browser> quit

Could you also test changing directories by multiple levels, please?

>  mdb> continue
>  big(big(big(small, [1], small), [1, 2], small), [1, 2, 3], big(big(small, [1, 2, 3, 4], big(small, [1, 2, 3, 4, 5], small)), [1, 2, 3, 4, 5, 6], small)).


Provided you address the issues that others brought up, the rest of the
diff is fine.

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