[m-rev.] Retry added in ssdb

Olivier Annet oan at missioncriticalit.com
Thu Nov 8 13:51:40 AEDT 2007


Hi,

could someone review my code before commiting please.

Olivier.

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


Estimated hours taken: 24
Branches: main

Modification of the source-to-source debugger to manage the retry command.

compiler/ssdebug.m:
	Create an output variable and modify each call to the handle_event 
	function at exit and fail port to support the retry command. Create 
	the switch at exit and fail port in the source-to-source code.

ssdb/ssdb.m:
	Somme modifications have been added to support the retry at exit and
	fail port.
	A new type ssdb_retry has been added. It is used to set the output 
	variable Retry used for the switch in the source-to-source code at
	exit and fail port.

Index: compiler/ssdebug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ssdebug.m,v
retrieving revision 1.9
diff -u -r1.9 ssdebug.m
--- compiler/ssdebug.m	1 Nov 2007 06:23:22 -0000	1.9
+++ compiler/ssdebug.m	8 Nov 2007 02:15:02 -0000
@@ -266,35 +256,41 @@
-        %
-        % Generate the call to handle_event_exit(ProcId, VarList).
-        %
-        make_handle_event("exit", [ProcIdVar, ExitArgListVar], 
-            HandleEventExitGoal, !ModuleInfo, !Varset, !Vartypes),
+        % Create DoRetry output variable
+        make_retry_var("", RetryVar, !Varset, !Vartypes),
 
+        % Generate the call to handle_event_exit(ProcId, VarList, DoRetry).
+        make_handle_event("exit", [ProcIdVar, ExitArgListVar, RetryVar], 
+            HandleEventExitGoal, !ModuleInfo, !Varset, !Vartypes),
 
-        %
+        % Generate the recursive call in the case of a retry
+        make_recursive_call(!.PredInfo, !.ModuleInfo, PredId, ProcId, HeadVars, 
+            HeadGoal),
+        
         % Organize the order of the generated code.
         % XXX Need optimization in list append.
         goal_to_conj_list(BodyGoal1, BodyGoalList),
-        ConjGoals = ProcIdGoals ++ CallArgListGoals ++ 
-            [HandleEventCallGoal] ++ BodyGoalList ++ ExitArgListGoals ++ 
-            [HandleEventExitGoal | RenamingGoals],
-
         % Set the determinism.
         Determinism = detism_det,
         goal_info_init(GoalInfo0),
         goal_info_set_determinism(Determinism, GoalInfo0, GoalInfo),
-        
+
+        conj_list_to_goal(RenamingGoals, GoalInfo, RenamingGoal),
+        % Create the switch on Retry at exit port.
+        make_switch_call(RetryVar, HeadGoal, RenamingGoal, GoalInfo, 
+            SwitchGoal),
+
+        ConjGoals = ProcIdGoals ++ CallArgListGoals ++ 
+            [HandleEventCallGoal | BodyGoalList] ++ ExitArgListGoals ++ 
+            [HandleEventExitGoal, SwitchGoal],
+ 
         conj_list_to_goal(ConjGoals, GoalInfo, GoalWithoutPurity),
 
         % Add the purity scope.
@@ -364,46 +348,61 @@
+        % Create DoRetryA output variable
+        make_retry_var("A", RetryAVar, !Varset, !Vartypes),
 
-        %
-        % Generate the call to handle_event_exit(ProcId, VarList).
-        %
-        make_handle_event("exit", [ProcIdVar, ExitArgListVar], 
+        % Generate the call to handle_event_exit(ProcId, VarList, DoRetryA).
+        make_handle_event("exit", [ProcIdVar, ExitArgListVar, RetryAVar], 
             HandleEventExitGoal, !ModuleInfo, !Varset, !Vartypes),
 
+        % Generate the recursive call in the case of a retry
+        make_recursive_call(!.PredInfo, !.ModuleInfo, PredId, ProcId, HeadVars, 
+            HeadGoal),
 
-        %
         % Generate the list of arguments at the fail port.
-        %
         make_arg_list(0, InitInstMap, [], Renaming, FailArgListVar, 
             FailArgListGoals, !ModuleInfo, !ProcInfo, !PredInfo, !Varset, 
             !Vartypes, BoundVarDescsAtCall, _BoundVarDescsAtFail),
 
-        %
-        % Generate the call to handle_event_fail(ProcId, VarList).
-        %
-        make_handle_event("fail", [ProcIdVar, FailArgListVar], 
+        % Create DoRetryA output variable
+        make_retry_var("B", RetryBVar, !Varset, !Vartypes),
+
+        % Generate the call to handle_event_fail(ProcId, VarList, DoRetryB).
+        make_handle_event("fail", [ProcIdVar, FailArgListVar, RetryBVar], 
             HandleEventFailGoal, !ModuleInfo, !Varset, !Vartypes),
 
         make_fail_call(FailGoal, !.ModuleInfo),
         
-        %
         % Organize the order of the generated code.
         % XXX Need optimization in list append.
 
         % Get a flattened goal to avoid nested conjuction.
         goal_to_conj_list(BodyGoal1, BodyGoalList),
         GoalsCond   = BodyGoalList,
-        GoalsThen   = ExitArgListGoals ++ [HandleEventExitGoal| RenamingGoals],
-        GoalsElse   = FailArgListGoals ++ [HandleEventFailGoal, FailGoal],
+        
+        % Create the switch on DoRetryA at exit port.
+        Determinism = detism_det,
+        goal_info_init(GoalInfo1),
+        goal_info_set_determinism(Determinism, GoalInfo1, GoalInfo),
+        conj_list_to_goal(RenamingGoals, GoalInfo, RenamingGoal),
+        make_switch_call(RetryAVar, HeadGoal, RenamingGoal, GoalInfo, 
+            SwitchExitPortGoal),
+        
+        % Create the switch on DoRetryB at fail port.
+        make_switch_call(RetryBVar, HeadGoal, FailGoal, GoalInfo, 
+            SwitchFailPortGoal),
+
+        GoalsThen   = ExitArgListGoals ++ 
+            [HandleEventExitGoal, SwitchExitPortGoal],
+        GoalsElse   = FailArgListGoals ++ 
+            [HandleEventFailGoal, SwitchFailPortGoal],
 
         goal_info_init(GoalInfo0),
         goal_list_determinism(GoalsCond, Detism),
@@ -426,10 +425,6 @@
         GoalWithoutPurity = hlds_goal(conj(plain_conj, ConjGoal), 
             GoalInfoCond),
         
-        Determinism = detism_det,
-        goal_info_init(GoalInfo1),
-        goal_info_set_determinism(Determinism, GoalInfo1, GoalInfo),
-
         % Add the purity scope.
         Purity = goal_info_get_purity(BodyGoalInfo0),        
         wrap_with_purity_scope(Purity, GoalInfo, GoalWithoutPurity, Goal),
@@ -497,43 +480,38 @@
+        
+        % Create DoRetryA output variable
+        make_retry_var("A", RetryAVar, !Varset, !Vartypes),
 
-        %
-        % Generate the call to handle_event_exit(ProcId, VarList).
-        %
-        make_handle_event("exit", [ProcIdVar, ExitArgListVar], 
+        % Generate the call to handle_event_exit(ProcId, VarList, DoRetryA).
+        make_handle_event("exit", [ProcIdVar, ExitArgListVar, RetryAVar], 
             HandleEventExitGoal, !ModuleInfo, !Varset, !Vartypes),
         
-        %
         % Generate the call to handle_event_redo(ProcId, VarList).
-        %
         make_handle_event("redo", [ProcIdVar, ExitArgListVar], 
             HandleEventRedoGoal, !ModuleInfo, !Varset, !Vartypes),
 
-        %
         % Generate the list of argument at the fail port.
-        %
         make_arg_list(0, InitInstMap, [], Renaming, FailArgListVar, 
             FailArgListGoals, !ModuleInfo, !ProcInfo, !PredInfo, !Varset, 
             !Vartypes, BoundVarDescsAtCall, _BoundVarDescsAtFail),
 
-        %
-        % Generate the call to handle_event_fail(ProcId, VarList).
-        %
-        make_handle_event("fail", [ProcIdVar, FailArgListVar], 
+        % Create DoRetryB output variable
+        make_retry_var("B", RetryBVar, !Varset, !Vartypes),
+
+        % Generate the call to handle_event_fail(ProcId, VarList, DoRetryB).
+        make_handle_event("fail", [ProcIdVar, FailArgListVar, RetryBVar], 
             HandleEventFailGoal, !ModuleInfo, !Varset, !Vartypes),
 
         make_fail_call(FailGoal, !.ModuleInfo),
 
@@ -541,29 +519,45 @@
         goal_to_conj_list(BodyGoal1, BodyGoalList1),
         CallVarGoal0 = CallArgListGoals ++ 
             [HandleEventCallGoal | BodyGoalList1] ++ ExitArgListGoals,
-        goal_info_init(GoalInfo),
-        conj_list_to_goal(CallVarGoal0, GoalInfo, CallVarGoal1),
+        goal_info_init(GoalInfo0),
+        conj_list_to_goal(CallVarGoal0, GoalInfo0, CallVarGoal1),
         goal_to_conj_list(CallVarGoal1, CallVarGoal),
         
+        % Generate the recursive call in the case of a retry
+        make_recursive_call(!.PredInfo, !.ModuleInfo, PredId, ProcId, HeadVars, 
+            HeadGoal),
+
+        % Create the switch on DoRetryA at exit port.
+        Determinism = detism_det,
+        goal_info_set_determinism(Determinism, GoalInfo0, GoalInfo),
+        conj_list_to_goal(RenamingGoals, GoalInfo, RenamingGoal),
+        make_switch_call(RetryAVar, HeadGoal, RenamingGoal, GoalInfo, 
+            SwitchExitPortGoal),
+        
+        % Create the switch on DoRetryB at fail port.
+        make_switch_call(RetryBVar, HeadGoal, FailGoal, GoalInfo, 
+            SwitchFailPortGoal),
+
         ConjGoal11 = hlds_goal(conj(plain_conj, 
-            [HandleEventExitGoal| RenamingGoals]), GoalInfo),
+            [HandleEventExitGoal, SwitchExitPortGoal]), GoalInfo0),
         ConjGoal120 = hlds_goal(conj(plain_conj, 
-            [HandleEventRedoGoal, FailGoal]), GoalInfo),
+            [HandleEventRedoGoal, FailGoal]), GoalInfo0),
         goal_add_feature(feature_preserve_backtrack_into, ConjGoal120, 
             ConjGoal12),
-        DisjGoal1 = hlds_goal(disj([ConjGoal11, ConjGoal12]), GoalInfo),
+        DisjGoal1 = hlds_goal(disj([ConjGoal11, ConjGoal12]), GoalInfo0),
 
         ConjGoal21 = hlds_goal(conj(plain_conj, 
-            CallVarGoal ++ [DisjGoal1]), GoalInfo),
+            CallVarGoal ++ [DisjGoal1]), GoalInfo0),
         ConjGoal220 = hlds_goal(conj(plain_conj, 
-            FailArgListGoals ++ [HandleEventFailGoal, FailGoal]), GoalInfo), 
+            FailArgListGoals ++ [HandleEventFailGoal, SwitchFailPortGoal]), 
+            GoalInfo0), 
         goal_add_feature(feature_preserve_backtrack_into, ConjGoal220, 
             ConjGoal22),
         DisjGoal2 = hlds_goal(disj([ConjGoal21, ConjGoal22]), 
-            GoalInfo),
+            GoalInfo0),
 
         GoalWithoutPurity = hlds_goal(conj(plain_conj, 
-            ProcIdGoals ++ [DisjGoal2]), GoalInfo),
+            ProcIdGoals ++ [DisjGoal2]), GoalInfo0),
 
         % Add the purity scope.
         Purity = goal_info_get_purity(BodyGoalInfo0),
@@ -572,9 +566,64 @@
         commit_goal_changes(Goal, PredId, ProcId, !.PredInfo, !ProcInfo,
             !ModuleInfo, !.Varset, !.Vartypes)
     ).
-        
 
+
+    %
+    % Create the output variable DoRetry.
     %
+:- pred make_retry_var(string::in, prog_var::out, 
+    prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
+
+make_retry_var(String, RetryVar, !VarSet, !VarTypes) :-
+    SSDBModule = mercury_ssdb_builtin_module,
+    TypeCtor = type_ctor(qualified(SSDBModule, "ssdb_retry"), 0),
+    construct_type(TypeCtor, [], RetryType),
+    Name = "DoRetry" ++ String,
+    svvarset.new_named_var(Name, RetryVar, !VarSet),
+    svmap.det_insert(RetryVar, RetryType, !VarTypes).
+
+
+    %
+    % Create the goal for recursive call in the case of a retry.
+    %
+:- pred make_recursive_call(pred_info::in, module_info::in, pred_id::in, 
+    proc_id::in, list(prog_var)::in, hlds_goal::out) is det.
+
+make_recursive_call(PredInfo, ModuleInfo, PredId, ProcId, HeadVars, 
+    Goal) :-
+    PredName = pred_info_name(PredInfo),
+    ModuleName = pred_info_module(PredInfo),
+    SymName = qualified(ModuleName, PredName),
+    BuiltIn = builtin_state(ModuleInfo, PredId, PredId, ProcId),
+    GoalExpr = plain_call(PredId, ProcId, HeadVars, BuiltIn, no, 
+        SymName),
+    goal_info_init(GoalInfoHG),
+    Goal = hlds_goal(GoalExpr, GoalInfoHG).
+
+
+    %
+    % make_switch_call(SwitchVar, SwitchCase1, SwitchCase2, GoalInfo, Goal).
+    %
+    % Create the switch Goal.
+    %
+:- pred make_switch_call(prog_var::in, hlds_goal::in, hlds_goal::in, 
+    hlds_goal_info::in, hlds_goal::out) is det.
+
+make_switch_call(SwitchVar, DoRetryGoal, DoNotRetryGoal, GoalInfo, 
+    SwitchGoal) :-
+    SSDBModule = mercury_ssdb_builtin_module,
+    ConsIdDoRetry = cons(qualified(SSDBModule, "do_retry"), 0),
+    ConsIdDoNotRetry = cons(qualified(SSDBModule, "do_not_retry"), 0),
+    CaseDoRetry = case(ConsIdDoRetry, DoRetryGoal),
+    CaseDoNotRetry = case(ConsIdDoNotRetry, DoNotRetryGoal),
+    SwitchGoal = hlds_goal(switch(SwitchVar, cannot_fail, 
+        [CaseDoRetry, CaseDoNotRetry]), GoalInfo).
+
+
+    %
+    % wrap_with_purity_scope(Purity, GoalInfo, Goal0, Goal)
+    %
+    % The Goal0 is wrap with the Purity to give Goal.
     % Not wrapping impure procedures with redundant promise_impure scopes.
     %
 :- pred wrap_with_purity_scope(purity::in, hlds_goal_info::in, hlds_goal::in,
@@ -595,6 +644,10 @@
     ).
 
 
+    %
+    % Commit all informations added during the source-to-source 
+    % transformations.
+    %
 :- pred commit_goal_changes(hlds_goal::in, pred_id::in, proc_id::in,
     pred_info::in, proc_info::in, proc_info::out, 
     module_info::in, module_info::out, prog_varset::in, vartypes::in) is det.
Index: ssdb/ssdb.m
===================================================================
RCS file: /home/mercury1/repository/mercury/ssdb/ssdb.m,v
retrieving revision 1.9
diff -u -r1.9 ssdb.m
--- ssdb/ssdb.m	1 Nov 2007 06:23:22 -0000	1.9
+++ ssdb/ssdb.m	8 Nov 2007 02:15:02 -0000
@@ -35,6 +35,13 @@
     ;       ssdb_fail
     .
 
+
+:- type ssdb_retry
+    --->    do_retry
+    ;       do_not_retry
+    .
+
+
     %
     % The list of all variables in use in a procedure.
     %
@@ -68,12 +75,14 @@
     %
     % This routine is called at each exit event that occurs.
     %
-:- impure pred handle_event_exit(ssdb_proc_id::in, list_var_value::in) is det.
+:- impure pred handle_event_exit(ssdb_proc_id::in, list_var_value::in, 
+    ssdb_retry::out) is det.
 
     %
     % This routine is called at each fail event that occurs.
     %
-:- impure pred handle_event_fail(ssdb_proc_id::in, list_var_value::in) is det.
+:- impure pred handle_event_fail(ssdb_proc_id::in, list_var_value::in, 
+    ssdb_retry::out) is det.
 
     %
     % This routine is called at each redo event that occurs.
@@ -136,7 +146,14 @@
     --->    wn_step
     ;       wn_next
     ;       wn_continue
-    ;       wn_finish(int).
+    ;       wn_finish(int)
+    ;       wn_retry(int).
+
+:- inst what_next_no_retry
+    --->    wn_step
+    ;       wn_next
+    ;       wn_continue
+    ;       wn_finish(ground).
 
 
     %
@@ -147,7 +164,7 @@
     --->    ns_step
     ;       ns_next(int)
     ;       ns_continue
-    ;       ns_final_port(int).
+    ;       ns_final_port(int, ssdb_retry).
 
 
 :- type breakpoint
@@ -206,7 +224,7 @@
 
     CSN = StackFrame ^ se_initial_state ^ ssdb_csn,
 
-    set_stop(Event, CSN, State0, ProcId, Stop),
+    set_stop(Event, CSN, State0, ProcId, Stop, _AutoRetry),
     (
         Stop = yes,
         some [!IO] 
@@ -220,7 +238,7 @@
 
             impure consume_io(!.IO),
 
-            set_next_stop(CSN, WhatNext, NextStop),
+            impure set_next_stop(CSN, WhatNext, ShadowStack, NextStop, _Retry),
 
             % We need to get a new state because breakpoint could have been 
             % added in the prompt.
@@ -234,9 +252,9 @@
 
 
     %
-    % Write the event out and call the prompt.
+    % Call at exit port. Write the event out and call the prompt.
     %
-handle_event_exit(ProcId, ListVarValue) :-
+handle_event_exit(ProcId, ListVarValue, Retry) :-
     Event = ssdb_exit,
     impure get_event_num_inc(EventNum),
     impure update_depth(Event, PrintDepth),
@@ -250,7 +268,7 @@
 
     CSN = StackFrame ^ se_initial_state ^ ssdb_csn,
 
-    set_stop(Event, CSN, State0, ProcId, Stop),
+    set_stop(Event, CSN, State0, ProcId, Stop, AutoRetry),
     (
         Stop = yes,
         some [!IO] 
@@ -260,11 +278,17 @@
             print_event_info(Event, EventNum, ProcId, PrintDepth, CSN, !IO),  
          
             semipure get_shadow_stack(ShadowStack),
-            impure prompt(Event, ShadowStack, 0, WhatNext, !IO),
+            (
+                AutoRetry = do_retry
+            ->
+                WhatNext = wn_retry(CSN)
+            ;
+                impure prompt(Event, ShadowStack, 0, WhatNext, !IO)
+            ),
 
             impure consume_io(!.IO),
 
-            set_next_stop(CSN, WhatNext, NextStop),
+            impure set_next_stop(CSN, WhatNext, ShadowStack, NextStop, Retry),
 
             % We need to get a new state because breakpoint could have been 
             % added in the prompt.
@@ -273,7 +297,8 @@
             impure set_debugger_state(State)
         )
     ;
-        Stop = no
+        Stop = no,
+        Retry = do_not_retry
     ),
     
     semipure get_debugger_state(PopState),
@@ -283,9 +308,9 @@
 
 
     %
-    % Write the event out and call the prompt.
+    % Call at fail port. Write the event out and call the prompt.
     %
-handle_event_fail(ProcId, _ListVarValue) :-
+handle_event_fail(ProcId, _ListVarValue, Retry) :-
     Event = ssdb_fail,
     impure get_event_num_inc(EventNum),
     impure update_depth(Event, PrintDepth),
@@ -295,7 +320,7 @@
  
     CSN = StackFrame ^ se_initial_state ^ ssdb_csn,
 
-    set_stop(Event, CSN, State0, ProcId, Stop),
+    set_stop(Event, CSN, State0, ProcId, Stop, AutoRetry),
     (
         Stop = yes,
         some [!IO] 
@@ -305,11 +330,17 @@
             print_event_info(Event, EventNum, ProcId, PrintDepth, CSN, !IO),  
          
             semipure get_shadow_stack(ShadowStack),
-            impure prompt(Event, ShadowStack, 0, WhatNext, !IO),
+            (
+                AutoRetry = do_retry
+            ->
+                WhatNext = wn_retry(CSN)
+            ;
+                impure prompt(Event, ShadowStack, 0, WhatNext, !IO)
+            ),
 
             impure consume_io(!.IO),
 
-            set_next_stop(CSN, WhatNext, NextStop),
+            impure set_next_stop(CSN, WhatNext, ShadowStack, NextStop, Retry),
 
             % We need to get a new state because breakpoint could have been 
             % added in the prompt.
@@ -318,7 +349,8 @@
             impure set_debugger_state(State)
         )
     ;
-        Stop = no
+        Stop = no,
+        Retry = do_not_retry
     ),
     
     semipure get_debugger_state(PopState),
@@ -328,8 +360,7 @@
 
 
     %
-    % Write the event out and call the prompt.
-    % XXX Need to be completed
+    % Call at redo port. Write the event out and call the prompt.
     %
 handle_event_redo(ProcId, ListVarValue) :-
     Event = ssdb_redo,
@@ -352,7 +383,7 @@
 
     CSN = StackFrame ^ se_initial_state ^ ssdb_csn,
 
-    set_stop(Event, CSN, State0, ProcId, Stop),
+    set_stop(Event, CSN, State0, ProcId, Stop, _AutoRetry),
     (
         Stop = yes,
         some [!IO] 
@@ -363,10 +394,10 @@
             impure consume_io(!.IO),
 
-            set_next_stop(CSN, WhatNext, NextStop),
+            impure set_next_stop(CSN, WhatNext, ShadowStack, NextStop, _Retry),
 
             % We need to get a new state because breakpoint could have been 
             % added in the prompt.
@@ -409,6 +443,18 @@
     State = State0 ^ ssdb_event_number := EventNum,
     impure set_debugger_state(State).
 
+
+    %
+    % Setter of the ssdb_event_number field.
+    %
+:- impure pred set_event_num(int::in) is det.
+
+set_event_num(EventNum) :-
+    semipure get_debugger_state(State0),
+    State = State0 ^ ssdb_event_number := EventNum,
+    impure set_debugger_state(State).
+
+
     %
     % For a given event type, update the depth in the debugger state,
     % returning the updated depth.
@@ -455,6 +502,18 @@
 get_csn(CSN) :-
     semipure get_debugger_state(State0),
     CSN = State0 ^ ssdb_csn.
+
+
+    %
+    % Setter of the ssdb_csn field.
+    %
+:- impure pred set_csn(int::in) is det.
+
+set_csn(CSN) :-
+    semipure get_debugger_state(State0),
+    State = State0 ^ ssdb_csn := CSN,
+    impure set_debugger_state(State).
+
     
     %
     % Return the current shadow stack.
@@ -465,6 +524,10 @@
     semipure get_debugger_state(State0),
     ShadowStack = State0 ^ ssdb_stack.
 
+
+    %
+    % Setter of the ssdb_list_var_value field in the debugger_state.
+    %
 :- impure pred set_list_var_value(list(var_value)::in) is det.
 
 set_list_var_value(ListVarValue) :-
@@ -472,6 +535,10 @@
     State = State0 ^ ssdb_list_var_value := ListVarValue,
     impure set_debugger_state(State).
 
+
+    %
+    % Setter of the ssdb_list_var_value in the first element of the ssdb_stack.
+    %
 :- impure pred set_list_var_value_in_stack(list(var_value)::in) is det.
 
 set_list_var_value_in_stack(ListVarValue) :-
@@ -490,17 +557,19 @@
     % Set Stop, if Stop equals yes, we will call the prompt.
     %
 :- pred set_stop(ssdb_event_type::in, int::in, debugger_state::in, 
-    ssdb_proc_id::in, bool::out) is det.
+    ssdb_proc_id::in, bool::out, ssdb_retry::out) is det.
 
-set_stop(Event, CSN, State, ProcId, ShouldStopAtEvent) :-
+set_stop(Event, CSN, State, ProcId, ShouldStopAtEvent, AutoRetry) :-
 
     NextStop = State ^ ssdb_next_stop,
     (
         NextStop = ns_step,
-        ShouldStopAtEvent = yes
+        ShouldStopAtEvent = yes,
+        AutoRetry = do_not_retry
     ;
         NextStop = ns_next(StopCSN),
-        is_same_csn(StopCSN, CSN, ShouldStopAtEvent)
+        is_same_csn(StopCSN, CSN, ShouldStopAtEvent),
+        AutoRetry = do_not_retry
     ;
         NextStop = ns_continue,
         ( 
@@ -510,9 +579,10 @@
             ShouldStopAtEvent = yes
         ;
             ShouldStopAtEvent = no
-        )
+        ),
+        AutoRetry = do_not_retry
     ;
-        NextStop = ns_final_port(StopCSN),
+        NextStop = ns_final_port(StopCSN, AutoRetry),
         (
             ( Event = ssdb_exit
             ; Event = ssdb_fail
@@ -527,6 +597,58 @@
     ).
 
 
+    %
+    % set_next_stop(CSN, WhatNext, ShadowStack, NextStop, Retry).
+    %
+    % Set the NextStop and the Retry variable according to the WhatNext value.
+    % In the case where the WathNext is set for a retry, it modify the 
+    % debugger_state at his old value which it had at the call point.
+    %
+:- impure pred set_next_stop(int::in, what_next::in, stack(stack_elem)::in, 
+    next_stop::out, ssdb_retry::out) is det.
+
+set_next_stop(CSN, WhatNext, ShadowStack, NextStop, Retry) :-
+    (
+        WhatNext = wn_step,
+        NextStop = ns_step,
+        Retry = do_not_retry
+    ;
+        WhatNext = wn_next,
+        NextStop = ns_next(CSN),
+        Retry = do_not_retry
+    ;
+        WhatNext = wn_continue,
+        NextStop = ns_continue,
+        Retry = do_not_retry
+    ;
+        WhatNext = wn_finish(EndCSN),
+        NextStop = ns_final_port(EndCSN, do_not_retry),
+        Retry = do_not_retry
+    ;
+        WhatNext = wn_retry(RetryCSN),
+        (
+            RetryCSN = CSN
+        ->
+            NextStop = ns_step,
+            Retry = do_retry,
+            % Set the debugger state for the retry
+            stack.top_det(ShadowStack, FrameStack),
+            SetCSN0 = FrameStack ^ se_initial_state ^ ssdb_csn,
+            SetEventNum0 = FrameStack ^ se_initial_state ^ ssdb_event_number,
+            SetCSN = SetCSN0 - 1,
+            SetEventNum = SetEventNum0 - 1,
+            impure set_csn(SetCSN),
+            impure set_event_num(SetEventNum)
+        ;
+            NextStop = ns_final_port(RetryCSN, do_retry),
+            Retry = do_not_retry
+        )
+    ).
+
+
+    %
+    % Print the current informations at this event point.
+    %
 :- pred print_event_info(ssdb_event_type::in, int::in, ssdb_proc_id::in, 
     int::in, int::in, io::di, io::uo) is det.
     
@@ -546,27 +668,10 @@
     io.nl(!IO).
 
 
-:- pred set_next_stop(int::in, what_next::in, next_stop::out) is det.
-
-set_next_stop(CSN, WhatNext, NextStop) :-
-    (
-        WhatNext = wn_step,
-        NextStop = ns_step
-    ;
-        WhatNext = wn_next,
-        NextStop = ns_next(CSN)
-    ;
-        WhatNext = wn_continue,
-        NextStop = ns_continue
-    ;
-        WhatNext = wn_finish(EndCSN),
-        NextStop = ns_final_port(EndCSN)
-    ).
-
 %----------------------------------------------------------------------------%
 
@@ -615,6 +720,8 @@
             io.nl(!IO),
             io.write_string("d      :: down", !IO),
             io.nl(!IO),
+            io.write_string("r      :: retry", !IO),
+            io.nl(!IO),
             io.nl(!IO),
             impure prompt(Event, ShadowStack, Depth, WhatNext, !IO)
 
@@ -697,6 +804,18 @@
                 impure prompt(Event, ShadowStack, Depth, WhatNext, !IO)
             )
 
+        ; Words = ["r"] ->
+            (
+                ( Event = ssdb_exit
+                ; Event = ssdb_fail
+                ) ->
+                stack.top_det(ShadowStack, FrameStack),
+                CSN = FrameStack ^ se_initial_state ^ ssdb_csn,
+                WhatNext = wn_retry(CSN)        
+            ;
+                io.write_string("Impossible at call or redo port\n", !IO),
+                impure prompt(Event, ShadowStack, Depth, WhatNext, !IO)
+            )
         ;
             io.write_string("huh?\n", !IO),
             impure prompt(Event, ShadowStack, Depth, WhatNext, !IO)
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list