+ case step of
+ RunAndLogSteps ->
+ traceRunStatus expr ref bindings final_ids
+ breakMVar statusMVar status emptyHistory
+ _other ->
+ handleRunStatus expr ref bindings final_ids
+ breakMVar statusMVar status emptyHistory
+
+
+back :: Session -> IO ([Name], Int, SrcSpan)
+back = moveHist (+1)
+
+forward :: Session -> IO ([Name], Int, SrcSpan)
+forward = moveHist (subtract 1)
+
+moveHist fn (Session ref) = do
+ hsc_env <- readIORef ref
+ case ic_resume (hsc_IC hsc_env) of
+ [] -> throwDyn (ProgramError "not stopped at a breakpoint")
+ (r:rs) -> do
+ let ix = resumeHistoryIx r
+ history = resumeHistory r
+ new_ix = fn ix
+ --
+ when (new_ix > length history) $
+ throwDyn (ProgramError "no more logged breakpoints")
+ when (new_ix < 0) $
+ throwDyn (ProgramError "already at the beginning of the history")
+
+ let
+ update_ic apStack mb_info = do
+ (hsc_env1, names, span) <- bindLocalsAtBreakpoint hsc_env
+ apStack mb_info
+ let ic = hsc_IC hsc_env1
+ r' = r { resumeHistoryIx = new_ix }
+ ic' = ic { ic_resume = r':rs }
+
+ writeIORef ref hsc_env1{ hsc_IC = ic' }
+
+ return (names, new_ix, span)
+
+ -- careful: we want apStack to be the AP_STACK itself, not a thunk
+ -- around it, hence the cases are carefully constructed below to
+ -- make this the case. ToDo: this is v. fragile, do something better.
+ if new_ix == 0
+ then case r of
+ Resume { resumeApStack = apStack,
+ resumeBreakInfo = mb_info } ->
+ update_ic apStack mb_info
+ else case history !! (new_ix - 1) of
+ History apStack info ->
+ update_ic apStack (Just info)