for review: term browser (version one) (revised diff -u!)

Bert THOMPSON aet at cs.mu.OZ.AU
Fri Oct 23 18:03:30 AEST 1998


David Glen JEFFERY <dgj at cs.mu.OZ.AU> writes:

|I think you should also add all the things that you haven't thought of. :)

|Just a small nit: we usually post unified diffs. (diff -u)

I was on autopilot when creating the diff. Here it is again.

===================================================================

People,

This is a relative diff showing changes to the browser after review.

Bert

===================================================================
Estimated hours taken: 50

Add a simple term browser for use by the trace-based debugger.

This is minimal but useful browser. Not included in this version
are a scripting language, Windows Explorer-style tree expansion,
and other features not yet thought of.

N.B. This still needs to be hooked into the debugger.

browser/Mmakefile:
	Added target browse_test.

browser/browser_library.m:
	Added modules required for the browser.

browser/browse_test.m:
	A simple driver for the browser with an example
	data structure to browse. (new file)

browser/browse.m:
	The browser proper. (new file)

browser/parse.m:
	Parser for browser's command language. (new file)

browser/util.m:
	Miscellaneous utilities used in the browser code. (new file)

browser/frame.m:
	Bare minimal ASCII graphics frames. (new file)

== browse.m =================================================
--- 1.11	1998/10/16 04:36:56
+++ browse.m	1998/10/23 06:05:29
@@ -20,20 +20,16 @@
 
 :- interface.
 
-:- import_module io, std_util.
+:- import_module parse.
+:- import_module io, std_util, list.
 
 	% The interactive term browser.
-:- pred browse__browser(univ, io__state, io__state).
-:- mode browse__browser(in, di, uo) is det.
+:- pred browse__browse(univ, io__state, io__state).
+:- mode browse__browse(in, di, uo) is det.
 
-%---------------------------------------------------------------------------%
-:- implementation.
-
-:- import_module parse, util, frame, string, list, parser, require,
-	std_util, int, char.
+:- pred browse__portray_root(browser_state, string).
+:- mode browse__portray_root(in, out) is det.
 
-:- pragma export(browse__browser(in, di, uo), "ML_browser").
-
 :- type browser_state
 	--->	browser_state(
 			univ,	% term to browse (as univ)
@@ -45,21 +41,31 @@
 			int	% Y clipping for verbose display
 		).
 
-browse__browser(Univ) -->
+%---------------------------------------------------------------------------%
+:- implementation.
+
+:- import_module parse, util, frame, string, list, parser, require,
+	std_util, int, char.
+
+:- pragma export(browse__browse(in, di, uo), "ML_browse").
+
+
+browse__browse(Univ) -->
 	{ default_state(Univ, State) },
-	startup_message,
-	browser2(State).
+	% startup_message,
+	browse_2(State).
 
-:- pred browser2(browser_state, io__state, io__state).
-:- mode browser2(in, di, uo) is det.
-browser2(State) -->
+:- pred browse_2(browser_state, io__state, io__state).
+:- mode browse_2(in, di, uo) is det.
+browse_2(State) -->
 	prompt,
 	parse__read_command(Command),
 	( { Command = quit } ->
-		io__write_string("quitting...\n")
+		% io__write_string("quitting...\n")
+		{ true }
 	;
 		run_command(Command, State, NewState),
-		browser2(NewState)
+		browse_2(NewState)
 	).
 
 :- pred startup_message(io__state::di, io__state::uo) is det.
@@ -77,7 +83,7 @@
 :- mode run_command(in, in, out, di, uo) is det.
 run_command(Command, State, NewState) -->
 	( { Command = unknown } ->
-		io__write_string("error: unknown command. try \"help\"\n"),
+		io__write_string("error: Try \"help\".\n"),
 		{ NewState = State }
 	; { Command = help } ->
 		help,
@@ -103,8 +109,11 @@
 	; { Command = ls } ->
 		portray(State),
 		{ NewState = State }
+	; { Command = ls(Path) } ->
+		portray_path(State, Path),
+		{ NewState = State }
 	; { Command = cd } ->
-		{ set_path(root_rel([]),State, NewState) }
+		{ set_path(root_rel([]), State, NewState) }
 	; { Command = cd(Path) } ->
 		{ get_dirs(State, Pwd) },
 		{ get_term(State, Univ) },
@@ -128,7 +137,6 @@
 		{ NewState = State }
 	).
 
-	% XXX: hardwired constant 10 in help.
 :- pred help(io__state::di, io__state::uo) is det.
 help -->
 	io__write_string(
@@ -139,21 +147,17 @@
 \tset var value  -- set a setting\n\
 \tset            -- show settings\n\
 \tprint          -- show single line representation of current term\n\
-\tdisplay        -- not implemented\n\
-\twrite          -- not implemented\n\
 \tquit           -- quit browser\n\
 SICStus Prolog style commands are:\n\
-\td              -- display\n\
 \tp              -- print\n\
-\tw              -- write\n\
 \t< [n]          -- set depth (default is 10)\n\
-\t^ [path]       -- cd\n\
+\t^ [path]       -- cd [path]\n\
 \t?              -- help\n\
 \th              -- help\n\
 \n\
 -- settings:\n\
 --    size; depth; path; format (flat pretty verbose); clipx; clipy\n\
---    example paths: /1/2/2 1/2\n\
+--    Paths can be Unix-style or SICStus-style: /2/3/1 or ^2^3^1\n\
 \n"
 	).
 
@@ -163,28 +167,36 @@
 :- mode portray(in, di, uo) is det.
 portray(State) -->
 	{ get_fmt(State, Fmt) },
-	( { Fmt = flat } ->
+	(
+		{ Fmt = flat },
 		portray_flat(State)
-	; { Fmt = pretty } ->
+	;
+		{ Fmt = pretty },
 		portray_pretty(State)
-	; { Fmt = verbose } ->
-		portray_verbose(State)
 	;
-		{ error("portray: unknown format") }
+		{ Fmt = verbose },
+		portray_verbose(State)
 	).
-	
+
+
+:- pred portray_path(browser_state, path, io__state, io__state).
+:- mode portray_path(in, in, di, uo) is det.
+portray_path(State, Path) -->
+	{ set_path(Path, State, NewState) },
+	portray(NewState).
 
 :- pred portray_fmt(browser_state, portray_format, io__state, io__state).
 :- mode portray_fmt(in, in, di, uo) is det.
 portray_fmt(State, Format) -->
-	( { Format = flat } ->
+	(
+		{ Format = flat },
 		portray_flat(State)
-	; { Format = pretty } ->
+	;
+		{ Format = pretty },
 		portray_pretty(State)
-	; { Format = verbose } ->
-		portray_verbose(State)
 	;
-		{ error("portray_fmt: unknown format") }
+		{ Format = verbose },
+		portray_verbose(State)
 	).
 
 	% XXX: could abstract out the code common to the following preds.
@@ -230,7 +242,7 @@
 	{ get_term(State, Univ) },
 	{ get_dirs(State, Dir) },
 	( { deref_subterm(Univ, Dir, SubUniv) } ->
-		{ term_to_string_indented(SubUniv, MaxSize, MaxDepth, Str) },
+		{ term_to_string_pretty(SubUniv, MaxSize, MaxDepth, Str) },
 		io__write_string(Str)
 	;
 		io__write_string("error: no such subterm")
@@ -238,6 +250,85 @@
 	io__nl.
 
 %---------------------------------------------------------------------------%
+	% Non-interactive display
+
+	% Display from the root term.
+	% This avoid errors due to dereferencing non-existent subterms.
+browse__portray_root(State, Str) :-
+	get_fmt(State, Fmt),
+	set_path(root_rel([]), State, NewState),
+	(
+		Fmt = flat,
+		portray_flat_string(NewState, Str)
+	;
+		Fmt = pretty,
+		portray_pretty_string(NewState, Str)
+	;
+		Fmt = verbose,
+		portray_verbose_string(NewState, Str)
+	).
+
+:- pred portray_string(browser_state, string).
+:- mode portray_string(in, out) is det.
+portray_string(State, Str) :-
+	get_fmt(State, Fmt),
+	(
+		Fmt = flat,
+		portray_flat_string(State, Str)
+	;
+		Fmt = pretty,
+		portray_pretty_string(State, Str)
+	;
+		Fmt = verbose,
+		portray_verbose_string(State, Str)
+	).
+
+
+:- pred portray_flat_string(browser_state, string).
+:- mode portray_flat_string(in, out) is det.
+portray_flat_string(State, Str) :-
+	get_term(State, Univ),
+	get_size(State, MaxSize),
+	get_depth(State, MaxDepth),
+	get_dirs(State, Dir),
+	( deref_subterm(Univ, Dir, SubUniv) ->
+		term_to_string(SubUniv, MaxSize, MaxDepth, Str)
+	;
+		error("error: no such subterm")
+	).
+	
+	% XXX: return maybe(string) instead?
+:- pred portray_pretty_string(browser_state, string).
+:- mode portray_pretty_string(in, out) is det.
+portray_pretty_string(State, Str) :-
+	get_term(State, Univ),
+	get_size(State, MaxSize),
+	get_depth(State, MaxDepth),
+	get_dirs(State, Dir),
+	( deref_subterm(Univ, Dir, SubUniv) ->
+		term_to_string_pretty(SubUniv, MaxSize, MaxDepth, Str)
+	;
+		error("error: no such subterm")
+	).
+	
+:- pred portray_verbose_string(browser_state, string).
+:- mode portray_verbose_string(in, out) is det.
+portray_verbose_string(State, Str) :-
+	get_term(State, Univ),
+	get_size(State, MaxSize),
+	get_depth(State, MaxDepth),
+	get_dirs(State, Dir),
+	get_clipx(State, X),
+	get_clipy(State, Y),
+	( deref_subterm(Univ, Dir, SubUniv) ->
+		term_to_string_verbose(SubUniv, MaxSize, MaxDepth,
+			X, Y, Str)
+	;
+		error("error: no such subterm")
+	).
+	
+
+%---------------------------------------------------------------------------%
 	% Single-line representation of a term.
 
 :- pred term_to_string(univ, int, int, string).
@@ -245,22 +336,21 @@
 term_to_string(Univ, MaxSize, MaxDepth, Str) :-
 	CurSize = 0,
 	CurDepth = 0,
-	term_to_string2(Univ, MaxSize, CurSize, _NewSize,
+	term_to_string_2(Univ, 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.
 	% XXX: Is this reasonable?
-:- pred term_to_string2(univ, int, int, int, int, int, string).
-:- mode term_to_string2(in, in, in, out, in, in, out) is det.
-term_to_string2(Univ, MaxSize, CurSize, NewSize, MaxDepth, CurDepth, Str) :-
+:- 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) :-
 	( ( (CurSize >= MaxSize) ; (CurDepth >= MaxDepth) ) ->
 		% Str = "...",
 		term_compress(Univ, Str),
 		NewSize = CurSize
 	;
-		util__functor(Univ, Functor),
-		util__args(Univ, Args),
+		deconstruct(Univ, Functor, _Arity, Args),
 		CurSize1 is CurSize + 1,
 		CurDepth1 is CurDepth + 1,
 		term_to_string_list(Args, MaxSize, CurSize1, NewSize,
@@ -275,13 +365,13 @@
 		_MaxDepth, _CurDepth, Strs) :-
 	Strs = [],
 	NewSize = CurSize.
-term_to_string_list([Univ|Univs], MaxSize, CurSize, NewSize,
+term_to_string_list([Univ | Univs], MaxSize, CurSize, NewSize,
 		MaxDepth, CurDepth, Strs) :-
-	term_to_string2(Univ, MaxSize, CurSize, NewSize1,
+	term_to_string_2(Univ, MaxSize, CurSize, NewSize1,
 		MaxDepth, CurDepth, Str),
 	term_to_string_list(Univs, MaxSize, NewSize1, NewSize,
 		MaxDepth, CurDepth, RestStrs),
-	Strs = [Str|RestStrs].
+	Strs = [Str | RestStrs].
 
 
 :- pred brack_args(list(string), string).
@@ -297,22 +387,22 @@
 :- pred comma_args(list(string), string).
 :- mode comma_args(in, out) is det.
 comma_args(Args, Str) :-
-	( Args = [] ->
+	(
+		Args = [],
 		Str = ""
-	; Args = [S] ->
+	;
+		Args = [S],
 		Str = S
-	; Args = [S1,S2|Ss] ->
-		comma_args([S2|Ss], Rest),
-		string__append_list([S1, ", ", Rest], Str)
 	;
-		error("comma_args: software error")
+		Args = [S1, S2 | Ss],
+		comma_args([S2 | Ss], Rest),
+		string__append_list([S1, ", ", Rest], Str)
 	).
 
 :- pred term_compress(univ, string).
 :- mode term_compress(in, out) is det.
 term_compress(Univ, Str) :-
-	util__functor(Univ, Functor),
-	util__arity(Univ, Arity),
+	deconstruct(Univ, Functor, Arity, _Args),
 	( Arity = 0 ->
 		Str = Functor
 	;
@@ -326,20 +416,18 @@
 	% pretty printing since parentheses and commas are omitted.
 	% XXX: Should do proper pretty printing?
 
-:- pred term_to_string_indented(univ, int, int, string).
-:- mode term_to_string_indented(in, in, in, out) is det.
-term_to_string_indented(Univ, MaxSize, MaxDepth, Str) :-
+:- pred term_to_string_pretty(univ, int, int, string).
+:- mode term_to_string_pretty(in, in, in, out) is det.
+term_to_string_pretty(Univ, MaxSize, MaxDepth, Str) :-
 	CurSize = 0,
 	CurDepth = 0,
-	term_to_string_indented2(Univ, MaxSize, CurSize, _NewSize,
+	term_to_string_pretty_2(Univ, MaxSize, CurSize, _NewSize,
 		MaxDepth, CurDepth, Lines),
 	unlines(Lines, Str).
 
-:- pred term_to_string_indented2(univ, int, int, int, int, int, list(string)).
-
-:- mode term_to_string_indented2(in, in, in, out, in, in, out) is det.
-
-term_to_string_indented2(Univ, MaxSize, CurSize, NewSize,
+:- pred term_to_string_pretty_2(univ, int, int, int, int, int, list(string)).
+:- mode term_to_string_pretty_2(in, in, in, out, in, in, out) is det.
+term_to_string_pretty_2(Univ, MaxSize, CurSize, NewSize,
 		MaxDepth, CurDepth, Lines) :-
 	( ((CurSize >= MaxSize) ; (CurDepth >= MaxDepth)) ->
 		term_compress(Univ, Line),
@@ -347,31 +435,56 @@
 		% Lines = ["..."],
 		NewSize = CurSize
 	;
-		util__functor(Univ, Functor),
-		util__args(Univ, Args),
+		deconstruct(Univ, Functor, Arity, Args),
 		CurSize1 is CurSize + 1,
 		CurDepth1 is CurDepth + 1,
-		term_to_string_indented_list(Args, MaxSize, CurSize1,
+		( Arity >= 1 ->
+			string__append(Functor, "(", Functor1)
+		;
+			Functor1 = Functor
+		),
+		term_to_string_pretty_list(Args, MaxSize, CurSize1,
 			NewSize, MaxDepth, CurDepth1, ArgsLines),
 		list__condense(ArgsLines, ArgsLineses),
 		map(indent, ArgsLineses, IndentedArgLines),
-		list__append([Functor], IndentedArgLines, Lines)
+		list__append([Functor1], IndentedArgLines, Lines1),
+		( Arity >= 1 ->
+			list__append(Lines1, [")"], Lines)
+		;
+			Lines = Lines1
+		)
 	).
 
-:- pred term_to_string_indented_list(list(univ), int, int, int, int, int,
+
+:- pred term_to_string_pretty_list(list(univ), int, int, int, int, int,
 	list(list(string))).
-:- mode term_to_string_indented_list(in, in, in, out, in, in, out) is det.
-term_to_string_indented_list([], _MaxSize, CurSize, NewSize,
+:- mode term_to_string_pretty_list(in, in, in, out, in, in, out) is det.
+term_to_string_pretty_list([], _MaxSize, CurSize, NewSize,
 		_MaxDepth, _CurDepth, Lines) :-
 	Lines = [],
 	NewSize = CurSize.
-term_to_string_indented_list([Univ|Univs], MaxSize, CurSize, NewSize,
+term_to_string_pretty_list([Univ], MaxSize, CurSize, NewSize,
 		MaxDepth, CurDepth, Lineses) :-
-	term_to_string_indented2(Univ, MaxSize, CurSize, NewSize1,
+	term_to_string_pretty_2(Univ, MaxSize, CurSize, NewSize,
 		MaxDepth, CurDepth, Lines),
-	term_to_string_indented_list(Univs, MaxSize, NewSize1, NewSize,
+	Lineses = [Lines].
+term_to_string_pretty_list([Univ1, Univ2 | Univs], MaxSize, CurSize, NewSize,
+		MaxDepth, CurDepth, Lineses) :-
+	term_to_string_pretty_2(Univ1, MaxSize, CurSize, NewSize1,
+		MaxDepth, CurDepth, Lines1),
+	comma_last(Lines1, Lines),
+	term_to_string_pretty_list([Univ2 | Univs], MaxSize, NewSize1, NewSize,
 		MaxDepth, CurDepth, RestLineses),
-	Lineses = [Lines|RestLineses].
+	Lineses = [Lines | RestLineses].
+
+:- pred comma_last(list(string), list(string)).
+:- mode comma_last(in, out) is det.
+comma_last([], []).
+comma_last([S], [Sc]) :-
+	string__append(S, ",", Sc).
+comma_last([S1, S2 | Ss], [S1 | Rest]) :-
+	comma_last([S2 | Ss], Rest).
+
 	
 :- pred indent(string::in, string::out) is det.
 indent(Str, IndentedStr) :-
@@ -379,7 +492,7 @@
 
 :- pred unlines(list(string)::in, string::out) is det.
 unlines([], "").
-unlines([Line|Lines], Str) :-
+unlines([Line | Lines], Str) :-
 	string__append(Line, "\n", NLine),
 	unlines(Lines, Strs),
 	string__append(NLine, Strs, Str).
@@ -394,14 +507,14 @@
 term_to_string_verbose(Univ, MaxSize, MaxDepth, X, Y, Str) :-
 	CurSize = 0,
 	CurDepth = 0,
-	term_to_string_verbose2(Univ, MaxSize, CurSize, _NewSize,
+	term_to_string_verbose_2(Univ, MaxSize, CurSize, _NewSize,
 		MaxDepth, CurDepth, Frame),
 	frame__clip(X-Y, Frame, ClippedFrame),
 	unlines(ClippedFrame, Str).
 
-:- pred term_to_string_verbose2(univ, int, int, int, int, int, frame).
-:- mode term_to_string_verbose2(in, in, in, out, in, in, out) is det.
-term_to_string_verbose2(Univ, MaxSize, CurSize, NewSize,
+:- 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,
 		MaxDepth, CurDepth, Frame) :-
 	( ((CurSize >= MaxSize) ; (CurDepth >= MaxDepth)) ->
 		term_compress(Univ, Line),
@@ -408,8 +521,7 @@
 		Frame = [Line],
 		NewSize = CurSize
 	;
-		util__functor(Univ, Functor),
-		util__args(Univ, Args),
+		deconstruct(Univ, Functor, _Arity, Args),
 		CurSize1 is CurSize + 1,
 		CurDepth1 is CurDepth + 1,
 		ArgNum = 1,
@@ -429,7 +541,7 @@
 
 term_to_string_verbose_list([Univ], ArgNum, MaxSize, CurSize, NewSize,
 		MaxDepth, CurDepth, Frame) :-
-	term_to_string_verbose2(Univ, MaxSize, CurSize, NewSize,
+	term_to_string_verbose_2(Univ, MaxSize, CurSize, NewSize,
 		MaxDepth, CurDepth, TreeFrame),
 	% XXX: ArgNumS must have fixed length 2.
 	string__int_to_string(ArgNum, ArgNumS),
@@ -436,12 +548,12 @@
 	string__append_list([ArgNumS, "-"], LastBranchS),
 	frame__hglue([LastBranchS], TreeFrame, Frame).
 
-term_to_string_verbose_list([Univ1,Univ2|Univs], ArgNum, MaxSize, CurSize,
+term_to_string_verbose_list([Univ1, Univ2 | Univs], ArgNum, MaxSize, CurSize,
 		NewSize, MaxDepth, CurDepth, Frame) :-
-	term_to_string_verbose2(Univ1, MaxSize, CurSize, NewSize1,
+	term_to_string_verbose_2(Univ1, MaxSize, CurSize, NewSize1,
 		MaxDepth, CurDepth, TreeFrame),
 	ArgNum1 is ArgNum + 1,
-	term_to_string_verbose_list([Univ2|Univs], ArgNum1, MaxSize,
+	term_to_string_verbose_list([Univ2 | Univs], ArgNum1, MaxSize,
 		NewSize1, NewSize2, MaxDepth, CurDepth, RestTreesFrame),
 	NewSize = NewSize2,
 	% XXX: ArgNumS must have fixed length 2.
@@ -449,7 +561,7 @@
 	string__append_list([ArgNumS, "-"], BranchFrameS),
 	frame__vsize(TreeFrame, Height),
 	Height1 is Height - 1,
-	util__copy(Height1, "|", VBranchFrame),
+	list__duplicate(Height1, "|", VBranchFrame),
 	frame__vglue([BranchFrameS], VBranchFrame, LeftFrame),
 	frame__hglue(LeftFrame, TreeFrame, TopFrame),
 	frame__vglue(TopFrame, RestTreesFrame, Frame).
@@ -462,38 +574,38 @@
 write_path([]) -->
 	io__write_string("/").
 write_path([Dir]) -->
-	( { Dir = parent } ->
+	(
+		{ Dir = parent },
 		io__write_string("/")
-	; { Dir = child(N) } ->
-		io__write_string("/"), io__write_int(N)
 	;
-		{ error("write_path: software error") }
+		{ Dir = child(N) },
+		io__write_string("/"), io__write_int(N)
 	).
-write_path([Dir,Dir2|Dirs]) -->
-	write_path2([Dir,Dir2|Dirs]).
+write_path([Dir, Dir2 | Dirs]) -->
+	write_path_2([Dir, Dir2 | Dirs]).
 
 
-:- pred write_path2(list(dir), io__state, io__state).
-:- mode write_path2(in, di, uo) is det.
-write_path2([]) -->
+:- pred write_path_2(list(dir), io__state, io__state).
+:- mode write_path_2(in, di, uo) is det.
+write_path_2([]) -->
 	io__write_string("/").
-write_path2([Dir]) -->
-	( { Dir = parent } ->
+write_path_2([Dir]) -->
+	(
+		{ Dir = parent },
 		io__write_string("/..")
-	; { Dir = child(N) } ->
-		io__write_string("/"), io__write_int(N)
 	;
-		{ error("write_path2: software error") }
+		{ Dir = child(N) },
+		io__write_string("/"), io__write_int(N)
 	).
-write_path2([Dir,Dir2|Dirs]) -->
-	( { Dir = parent } ->
+write_path_2([Dir, Dir2 | Dirs]) -->
+	(
+		{ Dir = parent },
 		io__write_string("/.."),
-		write_path2([Dir2|Dirs])
-	; { Dir = child(N) } ->
-		io__write_string("/"), io__write_int(N),
-		write_path2([Dir2|Dirs])
+		write_path_2([Dir2 | Dirs])
 	;
-		{ error("write_path2: software error") }
+		{ Dir = child(N) },
+		io__write_string("/"), io__write_int(N),
+		write_path_2([Dir2 | Dirs])
 	).
 
 	% We assume a root-relative path. We assume Term is the entire term
@@ -502,7 +614,7 @@
 :- mode deref_subterm(in, in, out) is semidet.
 deref_subterm(Univ, Path, SubUniv) :-
 	path_to_int_list(Path, PathN),
-	deref_subterm2(Univ, PathN, SubUniv).
+	deref_subterm_2(Univ, PathN, SubUniv).
 
 :- pred path_to_int_list(list(dir), list(int)).
 :- mode path_to_int_list(in, out) is semidet.
@@ -513,21 +625,21 @@
 :- pred dirs_to_ints(list(dir), list(int)).
 :- mode dirs_to_ints(in, out) is semidet.
 dirs_to_ints([], []).
-dirs_to_ints([child(N)|Dirs], [N|Ns]) :-
+dirs_to_ints([child(N) | Dirs], [N | Ns]) :-
 	dirs_to_ints(Dirs, Ns).
-dirs_to_ints([parent|_], _) :-
+dirs_to_ints([parent | _], _) :-
  	error("dirs_to_ints: software error").
 
-:- pred deref_subterm2(univ, list(int), univ) is semidet.
-:- mode deref_subterm2(in, in, out) is semidet.
-deref_subterm2(Univ, Path, SubUniv) :-
+:- pred deref_subterm_2(univ, list(int), univ) is semidet.
+:- mode deref_subterm_2(in, in, out) is semidet.
+deref_subterm_2(Univ, Path, SubUniv) :-
 	( Path = [] ->
 		Univ = SubUniv
 	; 
-		Path = [N|Ns],
-		util__args(Univ, Args),
+		Path = [N | Ns],
+		deconstruct(Univ, _Functor, _Arity, Args),
 		list__index1(Args, N, ArgN),
-		deref_subterm2(ArgN, Ns, SubUniv)
+		deref_subterm_2(ArgN, Ns, SubUniv)
 	).
 
 %---------------------------------------------------------------------------%
@@ -536,7 +648,8 @@
 :- pred default_state(univ, browser_state).
 :- mode default_state(in, out) is det.
 default_state(Univ, State) :-
-	State = browser_state(Univ,3,10,[],verbose, 79, 25).
+	State = browser_state(Univ, 3, DefaultDepth, [], verbose, 79, 25),
+	default_depth(DefaultDepth).
 
 :- pred get_term(browser_state, univ).
 :- mode get_term(in, out) is det.
@@ -605,12 +718,12 @@
 :- pred change_dir(list(dir), path, list(dir)).
 :- mode change_dir(in, in, out) is det.
 change_dir(PwdDirs, Path, RootRelDirs) :-
-	( Path = root_rel(Dirs) ->
+	(
+		Path = root_rel(Dirs),
 		NewDirs = Dirs
-	; Path = dot_rel(Dirs) ->
-		list__append(PwdDirs, Dirs, NewDirs)
 	;
-		error("change_dir: software error")
+		Path = dot_rel(Dirs),
+		list__append(PwdDirs, Dirs, NewDirs)
 	),
 	simplify_dirs(NewDirs, RootRelDirs).
 
@@ -621,8 +734,8 @@
 
 :- pred set_term(univ, browser_state, browser_state).
 :- mode set_term(in, in, out) is det.
-set_term(NewUniv, browser_state(_OldUniv,Dep,Siz,Path,Fmt,X,Y),
-	browser_state(NewUniv,Dep,Siz,Path,Fmt,X,Y)).
+set_term(NewUniv, browser_state(_OldUniv, Dep, Siz, Path, Fmt, X, Y),
+	browser_state(NewUniv, Dep, Siz, Path, Fmt, X, Y)).
 
 %---------------------------------------------------------------------------%
 	% display predicates.
@@ -639,16 +752,8 @@
 	io__write_string("Current path is: "),
 		write_path(CurPath), io__nl,
 	io__write_string("Print format is "),
-		io__write_string(FmtStr), io__nl,
-	( { Fmt = flat } ->
-		{ FmtStr = "flat" }
-	; { Fmt = pretty } ->
-		{ FmtStr = "pretty" }
-	; { Fmt = verbose } ->
-		{ FmtStr = "verbose" }
-	;
-		{ error("show_settings: unknown format") }
-	).
+	io__print(Fmt),
+	io__nl.
 
 :- pred string_to_path(string, path).
 :- mode string_to_path(in, out) is semidet.
@@ -658,13 +763,13 @@
 
 :- pred chars_to_path(list(char), path).
 :- mode chars_to_path(in, out) is semidet.
-chars_to_path([C|Cs], Path) :-
+chars_to_path([C | Cs], Path) :-
 	( C = ('/') ->
 		Path = root_rel(Dirs),
 		chars_to_dirs(Cs, Dirs)
 	;
 		Path = dot_rel(Dirs),
-		chars_to_dirs([C|Cs], Dirs)
+		chars_to_dirs([C | Cs], Dirs)
 	).
 
 :- pred chars_to_dirs(list(char), list(dir)).
@@ -676,15 +781,15 @@
 :- pred names_to_dirs(list(string), list(dir)).
 :- mode names_to_dirs(in, out) is semidet.
 names_to_dirs([], []).
-names_to_dirs([Name|Names], Dirs) :-
+names_to_dirs([Name | Names], Dirs) :-
 	( Name = ".." ->
-		Dirs = [parent|RestDirs],
+		Dirs = [parent | RestDirs],
 		names_to_dirs(Names, RestDirs)
 	; Name = "." ->
 		names_to_dirs(Names, Dirs)
 	;
 		string__to_int(Name, Num),
-		Dirs = [child(Num)| RestDirs],
+		Dirs = [child(Num) | RestDirs],
 		names_to_dirs(Names, RestDirs)
 	).
 
@@ -698,9 +803,9 @@
 		Names = []
 	; Rest = [] ->
 		Names = [Name]
-	; Rest = [_Slash|RestCs] ->
+	; Rest = [_Slash | RestCs] ->
 		split_dirs(RestCs, RestNames),
-		Names = [Name|RestNames]
+		Names = [Name | RestNames]
 	;
 		error("split_dirs: software error")
 	).
@@ -711,18 +816,28 @@
 not_slash(C) :-
 	C \= ('/').
 
+	% Remove "/dir/../" sequences from a list of directories to yield
+	% a form that lacks ".." entries.
+	% NB: This can be done more efficiently than simple iteration
+	% to a limit.
 :- pred simplify_dirs(list(dir), list(dir)).
 :- mode simplify_dirs(in, out) is det.
 simplify_dirs(Dirs, SimpleDirs) :-
 	util__limit(simplify, Dirs, SimpleDirs).
 
+	% If possible, remove a single occurence of
+	% either:
+	%	- "dir/../"
+	% or:
+	%	- "/.." (parent of root is root)
+	%
 :- pred simplify(list(dir), list(dir)).
 :- mode simplify(in, out) is det.
 simplify([], []).
-simplify([parent|Dirs], Dirs).
+simplify([parent | Dirs], Dirs).
 simplify([child(Dir)], [child(Dir)]).
-simplify([child(_Dir), parent |Dirs], Dirs).
-simplify([child(Dir1), child(Dir2) |Dirs], [child(Dir1) | Rest]) :-
-	simplify([child(Dir2)|Dirs], Rest).
+simplify([child(_Dir), parent | Dirs], Dirs).
+simplify([child(Dir1), child(Dir2) | Dirs], [child(Dir1) | Rest]) :-
+	simplify([child(Dir2) | Dirs], Rest).
 
 %---------------------------------------------------------------------------%
== browse_test.m =================================================
--- 1.7	1998/10/16 04:27:37
+++ browse_test.m	1998/10/16 04:29:43
@@ -37,7 +37,7 @@
 			AssocList) },
 		{ tree234__assoc_list_to_tree234(AssocList, Tree) },
 		{ type_to_univ(Tree, Univ) },
-		browse__browser(Univ),
+		browse__browse(Univ),
 		io__set_exit_status(EXIT_SUCCESS)
 	).
 
== frame.m =================================================
--- 1.6	1998/10/16 04:25:30
+++ frame.m	1998/10/23 04:08:50
@@ -21,7 +21,6 @@
 :- import_module list, std_util.
 
 	% XXX: Make frame type abstract instead?
-	% XXX: I'd rather not fully module-qualify the frame type.
 % :- type frame.
 :- type frame == list(string).
 
@@ -29,21 +28,27 @@
 	% coordinates is needed.
 :- type frame__clip_rect == pair(int, int).
 
+	% Width of a frame (horizontal size).
 :- pred frame__hsize(frame, int).
 :- mode frame__hsize(in, out) is det.
 
+	% Height of a frame (vertical size).
 :- pred frame__vsize(frame, int).
 :- mode frame__vsize(in, out) is det.
 
+	% Create a frame from a string.
 :- pred frame__from_string(string, frame).
 :- mode frame__from_string(in, out) is det.
 
+	% Stack (vertically glue) two frames, left-aligned.
 :- pred frame__vglue(frame, frame, frame).
 :- mode frame__vglue(in, in, out) is det.
 
+	% Juxtapose (horizontally glue) two frames, top-aligned.
 :- pred frame__hglue(frame, frame, frame).
 :- mode frame__hglue(in, in, out) is det.
 
+	% clip a frame, where cliprect originates in top-left corner of frame.
 :- pred frame__clip(frame__clip_rect, frame, frame).
 :- mode frame__clip(in, in, out) is det.
 
@@ -101,7 +106,7 @@
 	( (Strs = [], Lens = []) ->
 		PaddedFrame = []
 	; (Strs = [S|Ss], Lens = [L|Ls]) ->
-		util__copy(L, ' ', PadChars),
+		list__duplicate(L, ' ', PadChars),
 		string__from_char_list(PadChars, Padding),
 		string__append(S, Padding, SP),
 		add_right_padding(Ss, Ls, Rest),
@@ -121,7 +126,7 @@
 :- pred frame_lower_pad(frame, int, frame).
 :- mode frame_lower_pad(in, in, out) is det.
 frame_lower_pad(Frame, PadLines, PaddedFrame) :-
-	util__copy(PadLines, "", Padding),
+	list__duplicate(PadLines, "", Padding),
 	list__append(Frame, Padding, PaddedFrame).
 
 
@@ -137,7 +142,6 @@
 
 	% Clip a frame to the rectangle ((0,0),(X,Y)) where
 	% origin is on the top-left. Coordinate axes go down and right.
-	% XXX: Any reasons to implement a general clip?
 frame__clip(X-Y, Frame, ClippedFrame) :-
 	list__take_upto(Y, Frame, YClippedFrame),
 	list__map(left(X), YClippedFrame, ClippedFrame).
== parse.m =================================================
--- 1.5	1998/10/16 04:26:20
+++ parse.m	1998/10/23 04:11:46
@@ -37,10 +37,14 @@
 %		"verbose"
 %
 %	path:
-%		["/"] dir ["/" path]
+%		["/"] [dirs]
 %
+%	dirs:
+%		dir ["/" dirs]
+%
 %	dir:
 %		num
+%		".."
 %
 
 :- module parse.
@@ -49,7 +53,6 @@
 
 :- import_module io, list.
 
-	% XXX: could nuke zero-arity "ls" and "cd".
 :- type command
 	--->	ls(path)
 	;	ls
@@ -90,6 +93,9 @@
 :- pred parse__read_command(command, io__state, io__state).
 :- mode parse__read_command(out, di, uo) is det.
 
+:- pred default_depth(int).
+:- mode default_depth(out) is det.
+
 %---------------------------------------------------------------------------%
 :- implementation.
 
@@ -125,24 +131,24 @@
 
 :- pred lexer(list(char), list(token)).
 :- mode lexer(in, out) is det.
-lexer([],[]).
-lexer([C|Cs], Toks) :-
+lexer([], []).
+lexer([C | Cs], Toks) :-
 	( C = ('.') ->
 		lexer_dots(Cs, Toks)
 	; C = ('/') ->
-		Toks = [(/)|Toks2],
+		Toks = [(/) | Toks2],
 		lexer(Cs, Toks2)
 	; C = ('?') ->
-		Toks = [(?)|Toks2],
+		Toks = [(?) | Toks2],
 		lexer(Cs, Toks2)
 	; C = ('^') ->
-		Toks = [(^)|Toks2],
+		Toks = [(^) | Toks2],
 		lexer(Cs, Toks2)
 	; C = ('<') ->
-		Toks = [(<)|Toks2],
+		Toks = [(<) | Toks2],
 		lexer(Cs, Toks2)
 	; char__is_digit(C) ->
-		dig_to_int(C,N),
+		dig_to_int(C, N),
 		lexer_num(N, Cs, Toks)
 	; char__is_alpha(C) ->
 		lexer_name(C, Cs, Toks)
@@ -149,22 +155,22 @@
 	; char__is_whitespace(C) ->
 		lexer(Cs, Toks)
 	;
-		Toks = [unknown(C) |Toks2],
+		Toks = [unknown(C) | Toks2],
 		lexer(Cs, Toks2)
 	).
 
 :- pred lexer_dots(list(char), list(token)).
 :- mode lexer_dots(in, out) is det.
-lexer_dots([],[]).
-lexer_dots([C|Cs], Toks) :-
+lexer_dots([], []).
+lexer_dots([C | Cs], Toks) :-
 	( C = ('.') ->
 		Tok = (..),
 		lexer(Cs, Toks2),
-		Toks = [Tok|Toks2]
+		Toks = [Tok | Toks2]
 	;
 		Tok = (.),
-		lexer([C|Cs], Toks2),
-		Toks = [Tok|Toks2]
+		lexer([C | Cs], Toks2),
+		Toks = [Tok | Toks2]
 	).
 
 :- pred dig_to_int(char, int).
@@ -179,7 +185,7 @@
 lexer_num(N, Cs, Toks) :-
 	list__takewhile(char__is_digit, Cs, Digits, Rest),
 	digits_to_int_acc(N, Digits, Num),
-	Toks = [num(Num)|Toks2],
+	Toks = [num(Num) | Toks2],
 	lexer(Rest, Toks2).
 	
 			
@@ -186,7 +192,7 @@
 :- pred digits_to_int_acc(int, list(char), int).
 :- mode digits_to_int_acc(in, in, out) is det.
 digits_to_int_acc(Acc, [], Acc).
-digits_to_int_acc(Acc, [C|Cs], Num) :-
+digits_to_int_acc(Acc, [C | Cs], Num) :-
 	dig_to_int(C, D),
 	Acc2 is 10 * Acc + D,
 	digits_to_int_acc(Acc2, Cs, Num).
@@ -196,9 +202,9 @@
 :- mode lexer_name(in, in, out) is det.
 lexer_name(C, Cs, Toks) :-
 	list__takewhile(char__is_alpha, Cs, Letters, Rest),
-	string__from_char_list([C|Letters], Name),
+	string__from_char_list([C | Letters], Name),
 	lexer(Rest, Toks2),
-	Toks = [name(Name)|Toks2].
+	Toks = [name(Name) | Toks2].
 	
 
 :- pred parse(list(token), command).
@@ -208,7 +214,7 @@
 
 :- pred start(list(token), command).
 :- mode start(in, out) is semidet.
-start([Tok|Toks], Comm) :-
+start([Tok | Toks], Comm) :-
 	( (Tok = name("help") ; Tok = (?) ; Tok = name("h")) ->
 		Toks = [],
 		Comm = help
@@ -259,9 +265,6 @@
 		)
 	).
 
-	% XXX: default depth also in browse.m
-:- pred default_depth(int).
-:- mode default_depth(out) is det.
 default_depth(10).
 
 :- pred parse_path(list(token), path).
@@ -268,33 +271,41 @@
 :- mode parse_path(in, out) is semidet.
 	% SICStus is forgiving in the syntax of paths, hence so are we.
 	% XXX: Be less forgiving?
-parse_path([Tok|Toks], Path) :-
+parse_path([Tok | Toks], Path) :-
 	( Tok = (/) ->
 		Path = root_rel(Dirs),
 		parse_dirs(Toks, Dirs)
 	;
 		Path = dot_rel(Dirs),
-		parse_dirs([Tok|Toks], Dirs)
+		parse_dirs([Tok | Toks], Dirs)
 	).
 
 :- pred parse_dirs(list(token), list(dir)).
 :- mode parse_dirs(in, out) is semidet.
 parse_dirs([], []).
-parse_dirs([Tok|Toks], Dirs) :-
-	( Tok = num(Subdir) ->
-		Dirs = [child(Subdir)|RestDirs],
+parse_dirs([Tok | Toks], Dirs) :-
+	(
+		Tok = num(Subdir),
+		Dirs = [child(Subdir) | RestDirs],
 		parse_dirs(Toks, RestDirs)
-	; Tok = (..) ->
-		Dirs = [parent|RestDirs],
+	;
+		Tok = (..),
+		Dirs = [parent | RestDirs],
 		parse_dirs(Toks, RestDirs)
 	;
-		% Forgive almost anything else
+		% We can effectively ignore slashes (for Unix-style
+		% pathnames) and carets (for SICStus-style pathnames),
+		% but anything else is not allowed.
+		Tok = (/),
+		parse_dirs(Toks, Dirs)
+	;
+		Tok = (^),
 		parse_dirs(Toks, Dirs)
 	).
 
 :- pred parse_setting(list(token), setting).
 :- mode parse_setting(in, out) is semidet.
-parse_setting([Tok|Toks], Setting) :-
+parse_setting([Tok | Toks], Setting) :-
 	( Tok = name("depth") ->
 		Toks = [num(Depth)],
 		Setting = depth(Depth)
@@ -371,11 +382,11 @@
 :- mode show_dirs(in, di, uo) is det.
 show_dirs([]) -->
 	io__nl.
-show_dirs([child(Num)|Dirs]) -->
+show_dirs([child(Num) | Dirs]) -->
 	io__write_int(Num),
 	io__write_string("/"),
 	show_dirs(Dirs).
-show_dirs([parent|Dirs]) -->
+show_dirs([parent | Dirs]) -->
 	io__write_string("../"),
 	show_dirs(Dirs).
 
== util.m =================================================
--- 1.7	1998/10/16 04:23:50
+++ util.m	1998/10/16 07:44:50
@@ -8,26 +8,13 @@
 
 :- interface.
 
-:- import_module std_util, string, list.
+:- import_module list.
 
-:- pred util__typename(univ, string).
-:- mode util__typename(in, out) is det.
-
-:- pred util__functor(univ, string).
-:- mode util__functor(in, out) is det.
-
-:- pred util__args(univ, list(univ)).
-:- mode util__args(in, out) is det.
-
-:- pred util__arity(univ, int).
-:- mode util__arity(in, out) is det.
-
-:- pred util__copy(int, T, list(T)).
-:- mode util__copy(in, in, out) is det.
-
 :- pred util__zip_with(pred(T1, T2, T3), list(T1), list(T2), list(T3)).
 :- mode util__zip_with(pred(in, in, out) is det, in, in, out) is det.
 
+	% Apply predicate to argument repeatedly until the result
+	% remains the same.
 :- pred util__limit(pred(list(T), list(T)), list(T), list(T)).
 :- mode util__limit(pred(in,out) is det, in, out) is det.
 
@@ -34,31 +21,8 @@
 %---------------------------------------------------------------------------%
 :- implementation.
 
-:- import_module std_util, list, string, int, require.
+:- import_module list, int, require.
 
-
-util__functor(Univ, Functor) :-
-	deconstruct(Univ, Functor, _Arity, _Args).
-	
-util__args(Univ, Args) :-
-	deconstruct(Univ, _Functor, _Arity, Args).
-
-util__arity(Univ, Arity) :-
-	deconstruct(Univ, _Functor, Arity, _Args).
-	
-util__typename(Univ, TypeName) :-
-	TypeInfo = univ_type(Univ),
-	TypeName = type_name(TypeInfo).
-
-util__copy(N, X, Xs) :-
-	( N =< 0 ->
-		Xs = []
-	;
-		util__copy(N1, X, Xs2),
-		Xs = [X|Xs2],
-		N1 is N - 1
-	).
-
 util__zip_with(Pred, XXs, YYs, Zipped) :-
 	( (XXs = [], YYs = []) ->
 		Zipped = []
@@ -70,7 +34,6 @@
 		error("zip_with: list arguments are of unequal length")
 	).
 
-
 util__limit(Pred, Xs, Ys) :-
 	Pred(Xs, Zs),
 	( Xs = Zs ->



More information about the developers mailing list