;;; FRIDAY NOV 19,1976 10:51:28 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; STACK DEBUGGING TOOLS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; These routines are for crawling around in the LISP stack. For ;;;any meaningful stack information to be available *RSET must be set to ;;;T. Further, only minimal information will be present for compiled ;;;calls unless NOUUO is T. This package takes up 376. decimal words. ;;; The variable *FRAME*-*POINTER* (hereafter called the CURSOR) is ;;;always bound to a "stack frame 4-tuple". Each tuple is the value of ;;;an EVALFRAME function call. All the functions described below, ;;;unless otherwise noted, have as their value the current CURSOR. ;;; The CURSOR is either of the form: ;;; (EVAL
) or ;;; (APPLY ( ) ) ;;;The first atom is a keyword identifier indicating the format of the ;;;third entry. EVAL means that the form is an entity that is being ;;;EVAL'ed and the user could EVAL to see the effect. APPLY means that ;;;the third element is the list of the operator and its argument list. ;;;The argument list has been evaluated and is ready for the operator to ;;;be APPLY'ed to it. The user can do the latter by hand to see the ;;;effect. ;;; The and print as FIXNUM's. They are ;;;pointers that are meaningful for EVALFRAME, FRETURN, EVAL, APPLY and ;;;a few other commands. The reader is refered to the MACLISP manual ;;;for a more detailed discussion. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; COMMANDS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;TOP (no args) ;;; Set the CURSOR to the "top" of the stack. The "top" is closest ;;;to the break. Like a plant the growing point of a stack is at its ;;;top. ;;;BOT (no args) ;;; Set the CURSOR to the "bottom" of the stack. The "bottom" is ;;;the frame of the last call from "command line". ;;;UP (fexpr) ;;; Move the CURSOR another frame towards the top. Falling off the ;;;top of the stack causes an error message to be printed. The CURSOR ;;;is not changed. (Thus the value of UP will be EQ to its previous ;;;value). ;;;DN (fexpr) ;;; Move the CURSOR another frame towards the bottom. Falling off ;;;the bottom of the stack causes an error message to be printed. The ;;;CURSOR is not changed. (Thus the value of DN will be EQ to its ;;;previous value). ;;;both UP and DN ;;;take the following arguments: ;;; do the operation that many times ;;; go to the frame where that function was invoked ;;; the letter F move the CURSOR until the first user function ;;; call is encountered ;;; the letter I move the CURSOR until the first non-compiled ;;; user function call is encountered ;;; the letter C move the CURSOR until the first compiled user ;;; function call is encountered ;;; the letter M move the CURSOR until the first user macro call ;;;FR (lexpr) ;;; Given no argument, its value is simply the CURSOR. ;;; Given an argument, it will reset the CURSOR to the argument. ;;;FM (no args) ;;; Return only the FORM of the stack frame. This is the third ;;;element of the CURSOR structure. ;;;RET (lexpr) ;;; no arg - reexecute the form at the cursor and unwind the stack ;;; Only this type execution of RET evaluates in the ;;; original (CURSOR) lambda variable binding environment ;;; one arg - return the arg in place of computing the value of the ;;; form at the CURSOR. ;;; two arg - as above, but use (arg 2) in place of the CURSOR. ;;;EV (lexpr) ;;; one arg - evaluate the arg in the binding environment of the ;;; CURSOR frame. ;;; two arg - as above, but use (arg 2) in place of the CURSOR. ;;;EVQ (fexpr) ;;; The evalquote version of the above function. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; HINTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; When the CURSOR 4-tuple is of the EVAL type (the first element ;;;of the tuple is EVAL), the form component is EQ to the piece of code ;;;that is in the actual function being executed. Thus RPLAC operators ;;;on this form wil make patches to the function. ;;; RET is most useful to return the correct value for some ;;;evaluation sequence that has gone amuck and proceed with the overall ;;;processing. It eliminates the necessity of starting again from the ;;;beginning because of some "simple" bug. ;;; To evaluate a number of variables and forms in some frame ;;;context it is often easier to do a (EVQ (BREAK FOO)) rather than ;;;repetitive EVQ's. The former expression places a BREAK "at an ;;;earlier place in the evaluation". Obviously this BREAK should be ;;;$P'ed, when it is no longer needed.