BSD 4_4 release
[unix-history] / usr / src / old / lisp / PSD.doc / ch14.n
index f2f30b7..17b28fb 100644 (file)
@@ -1,11 +1,39 @@
-.\" Copyright (c) 1980 Regents of the University of California.
-.\" All rights reserved.  The Berkeley software License Agreement
-.\" specifies the terms and conditions for redistribution.
+.\" Copyright (c) 1980 The Regents of the University of California.
+.\" All rights reserved.
 .\"
 .\"
-.\"    @(#)ch14.n      4.1 (Berkeley) %G%
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
 .\"
 .\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"    @(#)ch14.n      6.3 (Berkeley) 4/17/91
+.\"
+." $Header: /na/franz/doc/RCS/ch14.n,v 1.1 83/01/31 07:08:43 jkf Exp $
 .Lc The\ LISP\ Stepper 14
 .Lc The\ LISP\ Stepper 14
-.sh 2 Simple\ Use\ Of\ Stepping 14
+.sh 2 Simple\ Use\ Of\ Stepping \n(ch 1
 .Lf step "s_arg1..."
 .No
 The LISP "stepping" package is intended to give the LISP programmer
 .Lf step "s_arg1..."
 .No
 The LISP "stepping" package is intended to give the LISP programmer
@@ -69,7 +97,7 @@ 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 \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 preceeded intercepted
+when printing the form in evaluation, the stepper preceded intercepted
 calls to 
 .i funcall
 with "f:".
 calls to 
 .i funcall
 with "f:".
@@ -97,3 +125,106 @@ 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.
 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