; STORED ON: DEBUG.VLI AUTHOR: Unknown (comments by P. Mennen - unreliable) The routines in this file can be loaded by: (INPUT DEBUG) The resources used when this file is loaded are: Atoms = 157 Lists = 355 when this file has been loaded, you may type: (DEBUG) to hook the debugger to the evaluator. when this is done the execution of the next expression can be traced by the use of these debugging commands: "A" ADVANCE advance step by step thru the evaluation of the current expression " " SKIP skip the tracing of the current expression "P" PRINT print the current expression "B" BREAK read a break-point expression from the terminal. continue the evaluation of the expression until the break-point function is encountered "L" LEVEL read a break-point level from the terminal. continue the evaluation of the expression until the given level is reached. "H" HISTORY print the history of the pending evaluations. "E" EVALUATE read and evaluate an expression (this is a toplevel loop, which has no effect on the current debugging session. ; (DE -CMD- () ; this function accepts one of the 7 debugging commands from the user and performs the requested action ; (SETQ CHR (TYI)) ; read a character from the keyboard ; (IF (AND (GE CHR 65) (LE CHR 90)) (SETQ CHR (+ CHR 32))) ; if it is upper case convert it to lower case ; ; !...?:::::::::::::::::::::::::::?.?:::::::::::::::::::?! ; (SELECTQ ; d ; (ASCII CHR) ("e" (TERPRI) (TPRINT '= (EVAL (READ))) (SELF)) ; (EVALUATE) toplevel loop ; ; e !..........?:::::::::::?! e ; ("a" (TERPRI) -CMD-) ; (ADVANCE) advance step by step ; (" " (TERPRI) '(EVAL -E-)) ; (SKIP) dont step thru this expression ; ("p" (TERPRI) (TPRINT -E-) (SELF)) ; (PRINT) print the current expression ; ; !................................! ; ("b" (TPRINT) (SETQ EV* (READ) STEP ()) -CMD-) ; (BREAK) read a breakpoint function, set STEP ; ; !.............?:::::::::::::::::::::::?......! to free-run mode ; ("l" (TPRINT) (SETQ -LVL- (READ) STEP ()) -CMD-) ; (LEVEL) read a breakpoint level, set STEP to ; ; !.............?:::::::::::::::::::::::::?......! free-run mode ; ("h" ; p ; (LET ; (HISTORY) print the history of the pending ; ; q evaluations ; ((-E- (REVERSE (CONS -E- -H-))) (-N- 1) (PRINTLENGTH 10)) ; r!....?::::::::::::::::::::::?! r ; (WHILE -E- ; x ; (TERPRI) (-LVL-) (PRIN -N- '> (NEXTL -E-)) (INCR -N-))) ; xq ; (TPRINT) (SELF)) ; p ; (T (PRINT "what?") (SELF)))) ; if illegal command, ask for another one ; ; !........................!d ; (DE TPRINT X ; print the expressions in the argument list, and prompt the user for a command ; (MAPC (LAMBDA (X) (PRIN X)) X) (PRIN '":") (TERPRI -1)) ; !.....?:::::::::::::::::::?..! ; (DE EV* (-E-) ; the hook function. if STEP is nil, we deepen to search for break-points (i.e. free run mode). if STEP is true, we step once and read another command (i.e. single-step mode). -H- contains the list of pending evaluations EV* contains the break-point function -LVL- contains the break-point level ; (IF (AND ; a b ; (NULL STEP) ; if we are in free run mode ; (OR (EQ (1+ -N-) -LVL-) (AND (LISTP -E-) (EQ (CAR -E-) EV*)))) ; and the breakpoint is satisfied ; ; c !.................! !................?::::::::::::::::?!cb ; (PROGN (SETQ STEP T -LVL- 0 EV* ()) (SELF -E-)) ; then switch to single-step mode ; ; !.............................................! ; (INCR -N-) ; advance the current level number ; (IFN STEP ; if we are in free-run, do one evaluation in ; ; k the user program ; (SETQ -V- (EVAL -CMD-)) (-LVL-) ; if we are in single step, first set line ; ; position, ; (LET (PRINTLENGTH 10) (TPRINT -N- '> -E-)) ; and print current level and expression ; ; !........................................! ; (SETQ -V- (EVAL (-CMD-))) ; then read and execute a command ; ; !.........?::::::::::::?! ; (OR STEP (NEQ -N- -LVL-) (SETQ STEP T -LVL- 0)) ; if we are in free-run, and the current level ; ; !.............................................! is equal to the breakpoint level, then switch ; ; to single-step mode ; (IFN STEP () (-LVL-) (TPRINT -N- '< -V-) (-CMD-))) ; if we are in single-step, print the result of ; ; !...............................................!k the evaluation and ask for the next command ; (NEXTL -H-) ; remove the expression from the history list ; (DECR -N-) ; decrement the current level ; -V-)) ; and return the result of the user evaluation ; ; a ; (DE -LVL- () ; the formater. positions the output according to the current level ; (OUTPOS (IF (< -N- 30) -N- 30))) ; dont indent beyond column 30 ; ; !.......?::::::::::::::::::::?! ; (DE DEBUG () ; the spear. once this function is executed, you are hooked. you can use a control-c to get unhooked. ; (SETQ STEP T ; a ; EV* () -H- () -N- 0 -LVL- 0 -CMD- '(EVALHOOK (CAR (NEWL -H- -E-)) 'EV*) ; !.........?::::::::::::::::::?.....! ; EVALHOOK 'EV*)) ; a ; (DM LET (LS) ; this macro allows you to use the temporary binding characteristics of the lambda function, without the awkwardness of the lambda functon for this purpose. the form of the let function is: (LET ((A1 B1) (A2 B2) ... (An Bn)) (S1 S2 ... Sj) which is expended by the macro into: ((LAMBDA (A1 A2 ... An) S1 S2 ... Sj) (B1 B2 ... Bn)) thus the effect of the let function is: temporarily bind B1 to A1, ... Bn to An then evaluate (PROGN S1 S2 ... Sj), then return A1,... An to their previous bindings ; (RPLACB ; a ; LS (CONS ; b ; (MCONS LAMBDA (MAPCAR 'CAR (CADR LS)) (CDDR LS)) ; !.............?:::::::::::::::::::::?..........! ; (MAPCAR 'CADR (CADR LS))))) ; !......................!ba ; (DE SVDEBUG () ; save all the functions of the debugger ; (SETQ CPOS 77) (SAVE -CMD- TPRINT EV* -LVL- DEBUG LET SVDEBUG))