[m-rev.] for review: allow paths with field names for subterm tracking

Ian MacLarty maclarty at cs.mu.OZ.AU
Mon Feb 6 01:59:33 AEDT 2006


For reeview by anyone.

Estimated hours taken: 5
Branches: main

Allow field names to be used in the paths used with subterm dependency
tracking.

Allow the user to cd to the return value of a function by giving the
number of arguments plus one as an argument to the `cd' command.

browser/browse.m:
	Export the predicate that removed ".." from paths.
	Make the return value of this predicate a subtype, so we can be
	sure the simplification has been applied to the path.

	Allow the user to do `cd N', where N is the number of arguments of
	a function plus one.  This will cd to the return value of the function.

	Add some more aliases for the directory name of the return value of a
	function.

browser/browser_info.m:
	Use the new simplified_dirs inst.
	When converting a list of directories to a term path, look at the
	value the path applies to to resolve field names in the path.

browser/declarative_user.m:
	Report an error if the user tries to track an I/O action.
	Call the new version of convert_dirs_to_term_path which handles
	field names in the path.

browser/term_rep.m:
	Add predicates to lookup a subterm in a term representation and
	also to look up a named field in a term representation.

tests/debugger/declarative/Mercury.options:
tests/debugger/declarative/Mmakefile:
tests/debugger/declarative/named_fields.exp:
tests/debugger/declarative/named_fields.inp:
tests/debugger/declarative/named_fields.m:
	Test tracking of subterms using a path with a field name.

tests/debugger/polymorphic_output.exp*
	The output of this test has changed, because cd's to the return value
	of a function, using a number, are now allowed.

Index: browser/browse.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/browse.m,v
retrieving revision 1.54
diff -u -r1.54 browse.m
--- browser/browse.m	2 Nov 2005 14:02:05 -0000	1.54
+++ browser/browse.m	5 Feb 2006 10:01:53 -0000
@@ -145,6 +145,18 @@
 :- pred save_term_to_file_xml(string::in, browser_term::in,
     io__output_stream::in, io::di, io::uo) is cc_multi.
 
+    % Remove "/dir/../" sequences from a list of directories to yield
+    % a form that lacks ".." entries.
+    % If there are more ".." entries than normal entries then the
+    % empty list is returned.
+    %
+:- pred simplify_dirs(list(dir)::in, list(dir)::out(simplified_dirs)) is det.
+
+    % True if the given string can be used to cd to the return value of a
+    % function.
+    %
+:- pred string_is_return_value_alias(string::in) is semidet.
+
 %---------------------------------------------------------------------------%
 
 :- implementation.
@@ -1390,19 +1402,20 @@
             (
                 (
                     Step = child_num(N),
-                    % The first argument of a non-array
-                    % is numbered argument 1.
-                    list__index1(Args, N, ArgUniv)
-                ;
-                    Step = child_name(Name),
-                    MaybeReturn = yes(ArgUniv),
-                    ( Name = "r"
-                    ; Name = "res"
-                    ; Name = "result"
+                    (
+                        N = list.length(Args) + 1,
+                        MaybeReturn = yes(ReturnValue)
+                    ->
+                        ArgUniv = ReturnValue
+                    ;
+                        % The first argument of a non-array
+                        % is numbered argument 1.
+                        list__index1(Args, N, ArgUniv)
                     )
                 ;
-                    Step = parent,
-                    error("deref_subterm: found parent")
+                    Step = child_name(Name),
+                    string_is_return_value_alias(Name),
+                    MaybeReturn = yes(ArgUniv)
                 )
             ->
                 deref_subterm_2(ArgUniv, SimplifiedPathTail,
@@ -1414,6 +1427,13 @@
         )
     ).
 
+string_is_return_value_alias("r").
+string_is_return_value_alias("res").
+string_is_return_value_alias("rv").
+string_is_return_value_alias("result").
+string_is_return_value_alias("return").
+string_is_return_value_alias("ret").
+
 :- pred deref_result_univ_to_browser_term(deref_result(univ)::in,
     deref_result(browser_term)::out) is det.
 
@@ -1649,11 +1669,6 @@
 not_slash(C) :-
     C \= ('/').
 
-    % Remove "/dir/../" sequences from a list of directories to yield
-    % a form that lacks ".." entries.
-    %
-:- pred simplify_dirs(list(dir)::in, list(dir)::out) is det.
-
 simplify_dirs(Dirs, SimpleDirs) :-
     list.reverse(Dirs, RevDirs),
     simplify_rev_dirs(RevDirs, 0, [], SimpleDirs).
@@ -1666,14 +1681,16 @@
     % SoFar accumulates the simplified dirs processed so far so we can be
     % tail recursive.
     %
-:- pred simplify_rev_dirs(list(dir)::in, int::in, list(dir)::in,
-    list(dir)::out) is det.
+:- pred simplify_rev_dirs(list(dir)::in, int::in,
+    list(dir)::in(simplified_dirs), list(dir)::out(simplified_dirs)) is det.
 
 simplify_rev_dirs([], _, SimpleDirs, SimpleDirs).
 simplify_rev_dirs([Dir | Dirs], N, SoFar, SimpleDirs) :-
-    ( Dir = parent ->
+    (
+        Dir = parent,
         simplify_rev_dirs(Dirs, N+1, SoFar, SimpleDirs)
     ;
+        ( Dir = child_num(_) ; Dir = child_name(_) ),
         ( N > 0 ->
             simplify_rev_dirs(Dirs, N-1, SoFar, SimpleDirs)
         ;
Index: browser/browser_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/browser_info.m,v
retrieving revision 1.21
diff -u -r1.21 browser_info.m
--- browser/browser_info.m	2 Nov 2005 14:02:05 -0000	1.21
+++ browser/browser_info.m	5 Feb 2006 00:08:12 -0000
@@ -16,6 +16,7 @@
 
 :- import_module mdb.browser_term.
 :- import_module mdb.parse.
+:- import_module mdb.term_rep.
 :- import_module mdbcomp.program_representation.
 
 :- import_module bool.
@@ -95,6 +96,12 @@
 	;	child_num(int)
 	;	child_name(string).
 
+:- inst dir_no_parent
+	---> 	child_num(ground)
+	;	child_name(ground).
+
+:- inst simplified_dirs == list_skel(dir_no_parent).
+
 	% The browser is required to behave differently for different
 	% caller circumstances.  The following type enumerates the
 	% various possibilities.
@@ -160,7 +167,8 @@
 :- func browser_info__get_num_printed_io_actions(browser_persistent_state)
 	= int.
 
-:- pred convert_dirs_to_term_path(list(dir)::in, term_path::out) is det.
+:- pred convert_dirs_to_term_path(term_rep::in,
+	list(dir)::in(simplified_dirs), term_path::out) is det.
 
 %---------------------------------------------------------------------------%
 
@@ -243,8 +251,12 @@
 :- implementation.
 
 :- import_module deconstruct.
+:- import_module int.
 :- import_module io.
 :- import_module require.
+:- import_module string.
+
+:- import_module mdb.term_rep.
 
 :- pragma export(browser_info__init_persistent_state(out),
 		"ML_BROWSE_init_persistent_state").
@@ -711,12 +723,26 @@
 
 %---------------------------------------------------------------------------%
 
-convert_dirs_to_term_path([], []).
-convert_dirs_to_term_path([child_num(N) | Dirs], [N | TermPath]) :-
-	convert_dirs_to_term_path(Dirs, TermPath).
-convert_dirs_to_term_path([child_name(_) | _], _) :-
-	error("convert_dirs_to_term_path: not in canonical form").
-convert_dirs_to_term_path([parent | _], _) :-
-	error("convert_dirs_to_term_path: not in canonical form").
+convert_dirs_to_term_path(_, [], []).
+convert_dirs_to_term_path(Term, [child_num(N) | Dirs], [N | TermPath]) :-
+	(
+		term_rep.argument(Term, N, Subterm)
+	->
+		convert_dirs_to_term_path(Subterm, Dirs, TermPath)
+	;
+		error("convert_dirs_to_term_path:" ++
+			"invalid argument")
+	).
+convert_dirs_to_term_path(Term, [child_name(Name) | Dirs], [N | TermPath]) :-
+	(
+		term_rep.field_pos(Name, Term, Pos),
+		term_rep.argument(Term, Pos, Subterm)
+	->
+		convert_dirs_to_term_path(Subterm, Dirs, TermPath),
+		N = Pos
+	;
+		error("convert_dirs_to_term_path:" ++
+			"invalid field name")
+	).
 
 %---------------------------------------------------------------------------%
Index: browser/declarative_user.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_user.m,v
retrieving revision 1.55
diff -u -r1.55 declarative_user.m
--- browser/declarative_user.m	4 Nov 2005 07:27:24 -0000	1.55
+++ browser/declarative_user.m	5 Feb 2006 13:26:16 -0000
@@ -525,12 +525,19 @@
 :- pred browse_io_action(io_action::in, maybe_track_subterm(term_path)::out,
 	user_state::in, user_state::out, io::di, io::uo) is cc_multi.
 
-browse_io_action(IoAction, MaybeTrack, !User, !IO) :-
+browse_io_action(IoAction, no_track, !User, !IO) :-
 	Term = io_action_to_browser_term(IoAction),
 	browse_browser_term(Term, !.User ^ instr, !.User ^ outstr, no,
 		MaybeTrackDirs, !.User ^ browser, Browser, !IO),
-	convert_maybe_track_dirs_to_term_path(MaybeTrackDirs, 
-		MaybeTrack),
+	(
+		MaybeTrackDirs = track(_, _, _),
+		io.write_string(!.User ^ outstr,
+			"Sorry, tracking of I/O actions is not yet " ++
+			"supported.\n", !IO),
+		browse_io_action(IoAction, _, !User, !IO)
+	;
+		MaybeTrackDirs = no_track
+	),
 	!:User = !.User ^ browser := Browser.
 
 :- pred browse_decl_bug(decl_bug::in, maybe(int)::in, user_state::in,
@@ -578,7 +585,7 @@
 			yes(get_subterm_mode_from_atoms_for_arg(ArgNum, 
 				InitAtom, FinalAtom)),
 			MaybeTrackDirs, !.User ^ browser, Browser, !IO),
-		convert_maybe_track_dirs_to_term_path(
+		convert_maybe_track_dirs_to_term_path_from_arg(ArgRep,
 			MaybeTrackDirs, MaybeTrack),
 		!:User = !.User ^ browser := Browser
 	;
@@ -622,7 +629,7 @@
 	browse_browser_term(BrowserTerm, !.User ^ instr, !.User ^ outstr,
 		yes(get_subterm_mode_from_atoms(InitAtom, FinalAtom)),
 		MaybeTrackDirs, !.User ^ browser, Browser, !IO),
-	convert_maybe_track_dirs_to_term_path(
+	convert_maybe_track_dirs_to_term_path_from_atom(FinalAtom,
 		MaybeTrackDirs, MaybeTrack),
 	!:User = !.User ^ browser := Browser.
 
@@ -641,11 +648,11 @@
 	save_and_browse_browser_term_xml(BrowserTerm, User ^ outstr, 
 		User ^ outstr, User ^ browser, !IO).
 
-:- func get_subterm_mode_from_atoms(trace_atom, trace_atom, list(dir)) 
-	= browser_term_mode.
+:- func get_subterm_mode_from_atoms(trace_atom::in, trace_atom::in,
+	list(dir)::in(simplified_dirs)) = (browser_term_mode::out) is det.
 
 get_subterm_mode_from_atoms(InitAtom, FinalAtom, Dirs) = Mode :-
-	convert_dirs_to_term_path(Dirs, Path),
+	convert_dirs_to_term_path_from_atom(FinalAtom, Dirs, Path),
 	(
 		Path = [ArgNum | TermPath],
 		ArgPos = arg_num_to_arg_pos(ArgNum),
@@ -669,12 +676,13 @@
 		Mode = unbound
 	).
 
-:- func get_subterm_mode_from_atoms_for_arg(int, trace_atom, trace_atom, 
-	list(dir)) = browser_term_mode.
+:- func get_subterm_mode_from_atoms_for_arg(int::in, trace_atom::in,
+	trace_atom::in, list(dir)::in(simplified_dirs)) =
+	(browser_term_mode::out) is det.
 
 get_subterm_mode_from_atoms_for_arg(ArgNum, InitAtom, FinalAtom, Dirs) 
 		= Mode :-
-	convert_dirs_to_term_path(Dirs, TermPath),
+	convert_dirs_to_term_path_from_atom(FinalAtom, Dirs, TermPath),
 	ArgPos = arg_num_to_arg_pos(ArgNum),
 	Mode = get_subterm_mode_from_atoms_and_term_path(InitAtom, FinalAtom,
 		ArgPos, TermPath).
@@ -734,14 +742,29 @@
 		OK = no
 	).
 
-:- pred convert_maybe_track_dirs_to_term_path(
-	maybe_track_subterm(list(dir))::in, 
+:- pred convert_maybe_track_dirs_to_term_path_from_atom(
+	trace_atom::in,
+	maybe_track_subterm(list(dir))::in,
+	maybe_track_subterm(term_path)::out) is det.
+
+convert_maybe_track_dirs_to_term_path_from_atom(_, no_track, no_track).
+convert_maybe_track_dirs_to_term_path_from_atom(Atom,
+		track(HowTrack, ShouldAssertInvalid, Dirs),
+		track(HowTrack, ShouldAssertInvalid, TermPath)) :-
+	simplify_dirs(Dirs, SimplifiedDirs),
+	convert_dirs_to_term_path_from_atom(Atom, SimplifiedDirs, TermPath).
+
+:- pred convert_maybe_track_dirs_to_term_path_from_arg(
+	term_rep::in,
+	maybe_track_subterm(list(dir))::in,
 	maybe_track_subterm(term_path)::out) is det.
 
-convert_maybe_track_dirs_to_term_path(no_track, no_track).
-convert_maybe_track_dirs_to_term_path(track(HowTrack, ShouldAssertInvalid,
-		Dirs), track(HowTrack, ShouldAssertInvalid, TermPath)) :-
-	convert_dirs_to_term_path(Dirs, TermPath).
+convert_maybe_track_dirs_to_term_path_from_arg(_, no_track, no_track).
+convert_maybe_track_dirs_to_term_path_from_arg(Term,
+		track(HowTrack, ShouldAssertInvalid, Dirs),
+		track(HowTrack, ShouldAssertInvalid, TermPath)) :-
+	simplify_dirs(Dirs, SimplifiedDirs),
+	convert_dirs_to_term_path(Term, SimplifiedDirs, TermPath).
 
 	% Reverse the first argument and append the second to it.
 	%
@@ -1274,3 +1297,52 @@
 set_user_testing_flag(Testing, User, User ^ testing := Testing).
 
 %-----------------------------------------------------------------------------%
+
+:- pred convert_dirs_to_term_path_from_atom(trace_atom::in,
+	list(dir)::in(simplified_dirs), term_path::out) is det.
+
+convert_dirs_to_term_path_from_atom(_, [], []).
+convert_dirs_to_term_path_from_atom(atom(_, Args), [Dir | Dirs], TermPath) :-
+	(
+		Dir = child_num(Pos),
+		Arg = list.det_index1(Args, Pos),
+		Arg = arg_info(_, _, MaybeValue)
+	;
+		Dir = child_name(Name),
+		( string_is_return_value_alias(Name) ->
+			( list.last(Args, LastArg) ->
+				LastArg = arg_info(_, _, MaybeValue),
+				Pos = list.length(Args)
+			;
+				throw(internal_error(
+					"convert_dirs_to_term_path_from_atom",
+					"argument list empty"))
+			)
+		;
+			throw(internal_error(
+				"convert_dirs_to_term_path_from_atom",
+				"argument of atom cannot be named"))
+		)
+	),
+	(
+		MaybeValue = yes(TermRep),
+		convert_dirs_to_term_path(TermRep, Dirs, TermPath0),
+		TermPath = [Pos | TermPath0]
+	;
+		MaybeValue = no,
+		(
+			% The user can cd to an unbound argument, but they
+			% can't cd into subterms of an unbound argument.
+			(
+				Dirs = [],
+				TermPath = [Pos]
+			;
+				Dirs = [_ | _],
+				throw(internal_error(
+					"convert_dirs_to_term_path_from_atom",
+					"no value for first position in path"))
+			)
+		)
+	).
+
+%-----------------------------------------------------------------------------%
Index: browser/term_rep.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/term_rep.m,v
retrieving revision 1.5
diff -u -r1.5 term_rep.m
--- browser/term_rep.m	2 Nov 2005 14:02:07 -0000	1.5
+++ browser/term_rep.m	5 Feb 2006 09:35:46 -0000
@@ -30,14 +30,28 @@
 
 :- pred rep_to_univ(term_rep::in, univ::out) is det.
 
+	% argumnet(Term, N, Subterm).
+	% True iff Subterm is the Nth argument of Term.
+	%
+:- pred argument(term_rep::in, int::in, term_rep::out) is semidet.
+
 :- pred deref_path(term_rep::in, term_path::in, term_rep::out) is semidet.
 
+	% field_pos(FieldName, Term, N).
+	% True iff argument N of Term has the name FieldName.
+	%
+:- pred field_pos(string::in, term_rep::in, int::out) is semidet.
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
 
+:- import_module exception.
 :- import_module int.
 :- import_module list.
+:- import_module string.
+
+:- import_module mdb.declarative_debugger.
 
 :- type term_rep
 	---> term_rep(univ)
@@ -75,17 +89,84 @@
 		SubTerm = Term
 	;
 		Path = [Head | Tail],
-		%
-		% There is only one representation of a subterm, given
-		% the representation of the containing term and a term path.
-		%
-		promise_equivalent_solutions [NextSubTerm] (
-			rep_to_univ(Term, Univ),
-			% Argument indexes in the term path start from one, but
-			% the argument function wants argument indexes to
-			% start from zero.
-			SubUniv = argument(univ_value(Univ), Head - 1),
-			univ_to_rep(SubUniv, NextSubTerm)
-		),
+		argument(Term, Head, NextSubTerm),
 		deref_path(NextSubTerm, Tail, SubTerm)
 	).
+
+argument(Term, N, Arg) :-
+	%
+	% There is only one representation of a subterm, given
+	% the representation of the containing term and a term path.
+	%
+	promise_equivalent_solutions [MaybeArg] (
+		rep_to_univ(Term, Univ),
+		% Argument indexes in the term path start from one, but
+		% the argument function wants argument indexes to
+		% start from zero.
+		argument_cc(univ_value(Univ), N - 1, MaybeSubUniv),
+		(
+			MaybeSubUniv = yes(SubUniv),
+			univ_to_rep(SubUniv, Arg0),
+			MaybeArg = yes(Arg0)
+		;
+			MaybeSubUniv = no,
+			MaybeArg = no
+		)
+	),
+	MaybeArg = yes(Arg).
+
+field_pos(FieldName, Term, Pos) :-
+	%
+	% There is only one or zero positions of a field
+	% given a representation of a term and the field name.
+	%
+	promise_equivalent_solutions [MaybePos] (
+		rep_to_univ(Term, Univ),
+		Value = univ_value(Univ),
+		deconstruct_cc(Value, Functor, Arity, _Args),
+		Type = type_of(Value),
+		find_functor(1, num_functors(Type), Type, Functor, Arity,
+			MaybeFunctorNum),
+		(
+			MaybeFunctorNum = yes(FunctorNum),
+			(
+				get_functor_with_names(Type, FunctorNum - 1, 
+					_FunctorName, _Arity, _ArgTypes,
+					ArgNames)
+			->
+				(
+					nth_member_search(ArgNames,
+						yes(FieldName), Pos0)
+				->
+					MaybePos = yes(Pos0)
+				;
+					MaybePos = no
+				)
+			;
+				throw(internal_error("field_pos",
+					"get_functor_with_names " ++
+					"couldn't find functor"))
+			)
+		;
+			MaybeFunctorNum = no,
+			throw(internal_error("field_pos",
+				"find_functor couldn't find functor"))
+		)
+	),
+	MaybePos = yes(Pos).
+
+:- pred find_functor(int::in, int::in, type_desc::in, string::in, int::in,
+	maybe(int)::out) is det.
+
+find_functor(Current, NumFunctors, Type, FunctorName, Arity, MaybeFunctorNum)
+		:-
+	( if Current =< NumFunctors then
+		( get_functor(Type, Current - 1, FunctorName, Arity, _) ->
+			MaybeFunctorNum = yes(Current)
+		;
+			find_functor(Current + 1, NumFunctors, Type,
+				FunctorName, Arity, MaybeFunctorNum)
+		)
+	else
+		MaybeFunctorNum = no
+	).
Index: tests/debugger/polymorphic_output.exp3
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/polymorphic_output.exp3,v
retrieving revision 1.10
diff -u -r1.10 polymorphic_output.exp3
--- tests/debugger/polymorphic_output.exp3	16 Nov 2004 00:16:39 -0000	1.10
+++ tests/debugger/polymorphic_output.exp3	5 Feb 2006 13:54:10 -0000
@@ -40,13 +40,12 @@
 browser> p
 two("three", 3, three("four", 4, "one", 1, empty, empty, empty), two("two", 2, empty, empty))
 browser> ^..^2
-error: there is no subterm 2
 browser> p
-two("three", 3, three("four", 4, "one", 1, empty, empty, empty), two("two", 2, empty, empty))
+'_'
 browser> ^..^3
 error: there is no subterm 3
 browser> p
-two("three", 3, three("four", 4, "one", 1, empty, empty, empty), two("two", 2, empty, empty))
+'_'
 browser> ^..^r
 browser> p
 '_'
Index: tests/debugger/declarative/Mercury.options
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/Mercury.options,v
retrieving revision 1.13
diff -u -r1.13 Mercury.options
--- tests/debugger/declarative/Mercury.options	2 Nov 2005 14:17:37 -0000	1.13
+++ tests/debugger/declarative/Mercury.options	5 Feb 2006 09:36:22 -0000
@@ -1,5 +1,6 @@
 MCFLAGS-deep_sub=--trace rep --suppress-trace context
 MCFLAGS-io_tab_impure=--trace rep --trace-table-io-all
+MCFLAGS-named_fields=--trace rep --trace-table-io-all
 MCFLAGS-nodescend_tracking=--trace rep --trace-table-io-all
 MCFLAGS-shallow_2=--trace shallow
 MCFLAGS-tabled_read_decl=--trace rep --trace-table-io-all
Index: tests/debugger/declarative/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/Mmakefile,v
retrieving revision 1.88
diff -u -r1.88 Mmakefile
--- tests/debugger/declarative/Mmakefile	8 Dec 2005 20:38:45 -0000	1.88
+++ tests/debugger/declarative/Mmakefile	5 Feb 2006 10:24:56 -0000
@@ -49,6 +49,7 @@
 	lpe_example		\
 	mapinit			\
 	mismatch_on_call	\
+	named_fields		\
 	negation		\
 	neg_conj		\
 	nodescend_tracking	\
@@ -408,6 +409,11 @@
 		> nodescend_tracking.out 2>&1 \
 	|| { grep . $@ /dev/null; exit 1; }
 
+named_fields.out: named_fields named_fields.inp
+	$(MDB_STD) ./named_fields < named_fields.inp \
+		> named_fields.out 2>&1 \
+	|| { grep . $@ /dev/null; exit 1; }
+
 negation.out: negation negation.inp
 	$(MDB) ./negation < negation.inp > negation.out 2>&1 \
 	|| { grep . $@ /dev/null; exit 1; }
Index: tests/debugger/declarative/named_fields.exp
===================================================================
RCS file: tests/debugger/declarative/named_fields.exp
diff -N tests/debugger/declarative/named_fields.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/declarative/named_fields.exp	5 Feb 2006 13:38:32 -0000
@@ -0,0 +1,101 @@
+      E1:     C1 CALL pred named_fields.main/2-0 (det) named_fields.m:11
+mdb> mdb> mdb> I/O tabling started.
+mdb> echo on
+Command echo enabled.
+mdb> break swap
+ 0: + stop  interface func named_fields.swap/1-0 (det)
+mdb> c
+      E2:     C2 CALL func named_fields.swap/1-0 (det) named_fields.m:27 (named_fields.m:13)
+mdb> f
+      E3:     C2 EXIT func named_fields.swap/1-0 (det) named_fields.m:27 (named_fields.m:13)
+mdb> dd -a
+swap(t(1, 2)) = t(2, 1)
+Valid? browse
+browser> cd 1/field1
+browser> ls
+1
+browser> track
+gen_t(t(1, 2))
+Valid? info
+Context of current question : named_fields.m:23 (named_fields.m:12)
+Search mode                 : top down                             
+The current question was chosen because the marked subterm was bound by
+the unification inside the predicate named_fields.gen_t/1
+(named_fields.m:23). The path to the subterm in the atom is 1/1.
+dd> undo
+swap(t(1, 2)) = t(2, 1)
+Valid? browse 1
+browser> cd field1
+browser> ls
+1
+browser> track
+gen_t(t(1, 2))
+Valid? info
+Context of current question : named_fields.m:23 (named_fields.m:12)
+Search mode                 : top down                             
+The current question was chosen because the marked subterm was bound by
+the unification inside the predicate named_fields.gen_t/1
+(named_fields.m:23). The path to the subterm in the atom is 1/1.
+dd> undo
+swap(t(1, 2)) = t(2, 1)
+Valid? browse
+browser> cd 2/field2
+browser> ls
+1
+browser> track
+gen_t(t(1, 2))
+Valid? info
+Context of current question : named_fields.m:23 (named_fields.m:12)
+Search mode                 : top down                             
+The current question was chosen because the marked subterm was bound by
+the unification inside the predicate named_fields.gen_t/1
+(named_fields.m:23). The path to the subterm in the atom is 1/1.
+dd> undo
+swap(t(1, 2)) = t(2, 1)
+Valid? browse
+browser> cd result/field2
+browser> ls
+1
+browser> track
+gen_t(t(1, 2))
+Valid? info
+Context of current question : named_fields.m:23 (named_fields.m:12)
+Search mode                 : top down                             
+The current question was chosen because the marked subterm was bound by
+the unification inside the predicate named_fields.gen_t/1
+(named_fields.m:23). The path to the subterm in the atom is 1/1.
+dd> undo
+swap(t(1, 2)) = t(2, 1)
+Valid? browse 2
+browser> cd field2
+browser> ls
+1
+browser> track
+gen_t(t(1, 2))
+Valid? info
+Context of current question : named_fields.m:23 (named_fields.m:12)
+Search mode                 : top down                             
+The current question was chosen because the marked subterm was bound by
+the unification inside the predicate named_fields.gen_t/1
+(named_fields.m:23). The path to the subterm in the atom is 1/1.
+dd> undo
+swap(t(1, 2)) = t(2, 1)
+Valid? browse 2
+browser> track field2
+gen_t(t(1, 2))
+Valid? info
+Context of current question : named_fields.m:23 (named_fields.m:12)
+Search mode                 : top down                             
+The current question was chosen because the marked subterm was bound by
+the unification inside the predicate named_fields.gen_t/1
+(named_fields.m:23). The path to the subterm in the atom is 1/1.
+dd> undo
+swap(t(1, 2)) = t(2, 1)
+Valid? browse 2
+browser> track field3
+error: cannot track subterm
+browser> quit
+dd> quit
+Diagnosis aborted.
+      E3:     C2 EXIT func named_fields.swap/1-0 (det) named_fields.m:27 (named_fields.m:13)
+mdb> quit -y
Index: tests/debugger/declarative/named_fields.inp
===================================================================
RCS file: tests/debugger/declarative/named_fields.inp
diff -N tests/debugger/declarative/named_fields.inp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/declarative/named_fields.inp	5 Feb 2006 13:38:16 -0000
@@ -0,0 +1,47 @@
+register --quiet
+table_io allow
+table_io start
+echo on
+break swap
+c
+f
+dd -a
+browse
+cd 1/field1
+ls
+track
+info
+undo
+browse 1
+cd field1
+ls
+track
+info
+undo
+browse
+cd 2/field2
+ls
+track
+info
+undo
+browse
+cd result/field2
+ls
+track
+info
+undo
+browse 2
+cd field2
+ls
+track
+info
+undo
+browse 2
+track field2
+info
+undo
+browse 2
+track field3
+quit
+quit
+quit -y
Index: tests/debugger/declarative/named_fields.m
===================================================================
RCS file: tests/debugger/declarative/named_fields.m
diff -N tests/debugger/declarative/named_fields.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/declarative/named_fields.m	5 Feb 2006 13:35:37 -0000
@@ -0,0 +1,27 @@
+:- module named_fields.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+main(!IO) :-
+	gen_t(T),
+	_ = swap(T).
+
+:- type t --->
+	t(
+		field1 :: int,
+		field2 :: int
+	).
+
+:- pred gen_t(t :: out) is det.
+
+gen_t(t(1, 2)).
+
+:- func swap(t) = t.
+
+swap(t(X, Y)) = t(Y, X).
--------------------------------------------------------------------------
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