REDUCE

12.4 Break Loop

On detecting an error, PSL normally enters a read/eval/print loop called a break loop. Here the user can examine the state of his computation, change the values of fluid and global variables, or define missing functions. He can then dismiss the error call to the normal error handling mechanism (errorset or errset above). If the error was of the continuable type, he may continue the computation. By setting the switch *break to nil, all break loops can be suppressed, and just an error message is displayed. Suppressing error messages also suppresses break loops.

*break = [Initially: t] switch
   
Controls whether the break package is called before unwinding the stack on error.

breaklevel* = [Initially: 0] global
   
The current number of nesting level of breaks.

maxbreaklevel* = [Initially: 5] global
   
The maximum number of nesting levels of breaks permitted. If an error occurs with at least this number of nested breaks already existing, no entry to an interactive break loop is made. Control aborts back to the innermost error handler instead.

The prompt "lisp break>" indicates that PSL has entered a break loop. A message of the form ”Retry form is ...” may also be printed, in which case the user is able to continue his computation by repairing the offending expression. By default, a break loop uses the functions read, eval, and print. This may be changed by setting breakreader⋆, breakevaluator⋆, or breakprinter⋆ to the appropriate function name.

errorform* = [Initially: nil] global
   
Contains an expression to reevaluate inside a break loop for continuable errors. Used as a tag for various Error functions.

Several ids, if typed at top-level, are special in a break loop. These are used as commands, and are currently M, R, T, Q, A, I, and C. They call functions stored on their property lists under the indicator breakfunction. These ids are special only at top-level, and do not cause any difficulty if used as variables inside expressions. However, they may not be simply typed at top-level to see their values. This is not expected to cause any difficulty.

The meanings of these commands are:

M

Display errorform*, this command calls the function breakerrmsg.

R

Retry. This tries to evaluate the retry form, and continue the computation. It evaluates the value of errorform*. This is often useful after defining a missing function or assigning a value to a variable. This command calls the function breakretry.

C

Continue. This causes the expression last printed by the break loop to be returned as the value of the call on continuableerror. This is often useful as an automatic stub. If an expression containing an undefined function is evaluated, a break loop is entered, and this may be used to return the value of the function call. This command calls the function breakcontinue.

Q

Quit. This exits the break loop by throwing to the closest surrounding error handler. It calls the function breakquit.

A

Abort. This aborts to the top level, i.e., restarts PSL. It calls the function reset.

T

Trace. This prints a backtrace of function calls on the stack except for those on the lists ignoredinbacktrace* and interpreterfunctions*. It calls the function backtrace.

I

Interpreter Trace. This prints a backtrace of only interpreted functions call on the stack except for those on the list interpreterfunctions*. It calls the function interpbacktrace.

An attempt to continue a non-continuable error with R or C prints a message and behaves as Q.

ignoredinbacktrace* = [Initially: string] global
   
A list of function names that will not be printed by the commands I and T given within a break loop (eval apply fastapply codeapply codeevalapply catch errorset evprogn toploop breakeval bindeval break main).

interpreterfunctions* = [Initially: string] global
   
A list of function names that will not be printed by the command I given within a break loop (cond prog and or progn setq).

The above two globals can be reset in an init file if the programmer desires to do so.

(de new-nth (seq index)  
    (cond ((onep index) (car x))  
          (t (new-nth (rest index) (sub1 index)))))  
 
1 lisp> (new-nth '(a b c) 2)  
⋆⋆⋆⋆⋆ ‘S' is an unbound ID  
⋆⋆⋆⋆⋆ Continuable error: retry form is ‘S'  
2 lisp break (1)> t  
Backtrace from top of stack:  
car new-nth new-nth  
NIL  
3 lisp break (1)> seq  
(b c)  
4 lisp break (1)> c  
b