document distributed with 4.3BSD
authorNick Cuccia <cuccia@ucbvax.Berkeley.EDU>
Wed, 30 Apr 1986 10:04:35 +0000 (02:04 -0800)
committerNick Cuccia <cuccia@ucbvax.Berkeley.EDU>
Wed, 30 Apr 1986 10:04:35 +0000 (02:04 -0800)
SCCS-vsn: old/lisp/PSD.doc/ch14.n 6.1

usr/src/old/lisp/PSD.doc/ch14.n

index 9a0b4fb..741626b 100644 (file)
@@ -2,5 +2,202 @@
 .\" All rights reserved.  The Berkeley software License Agreement
 .\" specifies the terms and conditions for redistribution.
 .\"
 .\" All rights reserved.  The Berkeley software License Agreement
 .\" specifies the terms and conditions for redistribution.
 .\"
-.\"    @(#)ch14.n      5.1 (Berkeley) %G%
+.\"    @(#)ch14.n      6.1 (Berkeley) %G%
 .\"
 .\"
+." $Header: /na/franz/doc/RCS/ch14.n,v 1.1 83/01/31 07:08:43 jkf Exp $
+.Lc The\ LISP\ Stepper 14
+.sh 2 Simple\ Use\ Of\ Stepping 14
+.Lf step "s_arg1..."
+.No
+The LISP "stepping" package is intended to give the LISP programmer
+a facility analogous to the Instruction Step mode of running a
+machine language program.  
+The user interface is through the function (fexpr) step, which sets
+switches to put the LISP interpreter in and out of "stepping" mode.
+The most common \fIstep\fP invocations follow.  These invocations are 
+usually typed at the top-level, and will take effect
+immediately (i.e. the next S-expression typed in will be evaluated in stepping
+mode).
+.Eb
+\fI(step t)\fP                         ; Turn on stepping mode.
+\fI(step nil)\fP                       ; Turn off stepping mode.
+.Ee
+.Se
+In stepping mode, the LISP evaluator will print out each S-exp to
+be evaluated before evaluation, and the returned value after evaluation,
+calling itself recursively to display the stepped evaluation of each
+argument, if the S-exp is a function call.  In stepping mode, the
+evaluator will wait after displaying each S-exp before evaluation
+for a command character from the console.
+.Eb
+\fISTEP COMMAND SUMMARY\fP
+
+<return>                       Continue stepping recursively.
+
+c                              Show returned value from this level
+                               only, and continue stepping upward.
+
+e                              Only step interpreted code.
+
+g                              Turn off stepping mode. (but continue
+                               evaluation without stepping).
+
+n <number>                     Step through <number> evaluations without 
+                               stopping
+
+p                              Redisplay current form in full
+                               (i.e. rebind prinlevel and prinlength to nil)
+
+b                              Get breakpoint
+
+q                              Quit
+
+d                              Call debug
+.Ee
+.sh 2 Advanced\ Features
+.sh 3 Selectively\ Turning\ On\ Stepping.
+
+If
+       \fI(step foo1 foo2 ...)\fP
+
+is typed at top level, stepping will not commence
+immediately, but rather when the evaluator first encounters an S-expression
+whose car is one of \fIfoo1, foo2\fP, etc.  This form will then display
+at the console, and the evaluator will be in stepping mode waiting
+for a command character.
+.pp
+Normally the stepper intercepts calls to \fIfuncall\fP and \fIeval\fP.
+When \fIfuncall\fP is intercepted, the arguments to the function
+have already been evaluated but when \fIeval\fP is intercepted, the
+arguments have not been evaluated.  To differentiate the two cases, 
+when printing the form in evaluation, the stepper preceded intercepted
+calls to 
+.i funcall
+with "f:".
+Calls to \fIfuncall\fP are normally caused by compiled lisp code calling
+other functions, whereas calls to \fIeval\fP 
+usually occur when lisp code is interpreted.
+To step only calls to eval use:
+       \fI(step e)\fP
+
+.sh 3 Stepping\ With\ Breakpoints.
+.pp
+For the moment, step is turned off inside of error breaks, but not by
+the break function.  Upon exiting the error, step is reenabled.
+However, executing \fI(step nil)\fP inside a error loop will turn off
+stepping globally, i.e. within the error loop, and after return has
+be made from the loop.
+.sh 2 Overhead\ of\ Stepping.
+.pp
+If stepping mode has been turned off by \fI(step nil)\fP, 
+the execution overhead
+of having the stepping packing in your LISP is identically nil.
+If one stops stepping by typing "g", every call to eval
+incurs a small overhead--several machine instructions, corresponding
+to the compiled code for a simple cond and one function pushdown.
+Running with \fI(step foo1 foo2 ...)\fP can be more expensive, since a
+member of the car of the current form into the list \fI(foo1 foo2 ...)\fP
+is required at each call to eval.
+.sh 2 Evalhook\ and\ Funcallhook
+.pp
+There are hooks in the
+.Fr
+interpreter to permit a user written function to gain control of the
+evaluation process.
+These hooks are used by the Step package just described.
+There are two hooks and they have been strategically placed in the
+two key functions in the interpreter:
+.i eval
+(which all interpreted code goes through)
+and  
+.i funcall
+(which all compiled code goes through if \fI(sstatus\ translink\ nil)\fP
+has been done).
+The hook in
+.i eval
+is compatible with Maclisp, but there is no
+Maclisp equivalent of the hook in 
+.i funcall .
+.pp
+To arm the hooks two forms must be evaluated: \fI(*rset\ t)\fP and
+\fI(sstatus\ evalhook\ t)\fP.
+Once that is done, 
+.i eval
+and
+.i funcall
+do a special check when they enter.
+.pp
+If 
+.i eval 
+is given a form to evaluate, say \fI(foo\ bar)\fP, 
+and the symbol `evalhook' is non nil, say its value is `ehook',
+then
+.i eval
+will lambda bind the symbols `evalhook' and `funcallhook'
+to nil and will call ehook passing \fI(foo\ bar)\fP as the argument.
+It is ehook's responsibility to evaluate \fI(foo\ bar)\fP and
+return its value.
+Typically ehook will call the function `evalhook' 
+to evaluate \fI(foo\ bar)\fP.
+Note that `evalhook' is a symbol whose function binding is a system function
+described in Chapter 4, and whose value binding, if non nil, is the
+name of a user written
+function (or a lambda expression, or a binary object) which
+will gain control whenever eval is called.
+`evalhook' is also the name of the 
+.i status 
+tag which must be set for
+all of this to work.
+.pp
+If 
+.i funcall
+is given a function, say foo, and a set of already evaluated 
+arguments, say barv and bazv, and if the symbol `funcallhook'
+has a non nil value, say `fhook', then
+.i funcall
+will lambda bind `evalhook' and `funcallhook' to nil
+and will call fhook with arguments barv, bazv and foo.
+Thus fhook must be a lexpr since it may be given any number
+of arguments.  
+The function to call, foo in this case, will be the
+.i last
+of the arguments given to fhook.
+It is fhooks responsibility to do the function call and return the
+value.
+Typically fhook will call the function
+.i funcallhook
+to do the funcall.
+This is an example of a funcallhook function which  just prints
+the arguments on each entry to funcall and the return value.
+.Eb
+-> \fI(defun fhook n (let ((form (cons (arg n) (listify (1- n))))
+                       (retval))
+                      (patom "calling ")(print form)(terpr)
+                      (setq retval (funcallhook form 'fhook))
+                      (patom "returns ")(print retval)(terpr)
+                      retval))\fP
+fhook
+-> \fI(*rset t) (sstatus evalhook t) (sstatus translink nil)\fP
+-> \fI(setq funcallhook 'fhook)\fP
+calling (print fhook)          ;; now all compiled code is traced
+fhookreturns nil
+calling (terpr)
+
+returns nil
+calling (patom "-> ")
+-> returns "-> "
+calling (read nil Q00000)
+\fI(array foo t 10)\fP         ;; to test it, we see what happens when
+returns (array foo t 10)       ;; we make an array
+calling (eval (array foo t 10))
+calling (append (10) nil)
+returns (10)
+calling (lessp 1 1)
+returns nil
+calling (apply times (10))
+returns 10
+calling (small-segment value 10)
+calling (boole 4 137 127)
+returns 128
+ ... there is plenty more ...
+.Ee