BSD 4_2 development
[unix-history] / usr / lisp / ch14.n
CommitLineData
1c9c8e44
C
1." $Header: /na/franz/doc/RCS/ch14.n,v 1.1 83/01/31 07:08:43 jkf Exp $
2.Lc The\ LISP\ Stepper 14
3.sh 2 Simple\ Use\ Of\ Stepping 14
4.Lf step "s_arg1..."
5.No
6The LISP "stepping" package is intended to give the LISP programmer
7a facility analogous to the Instruction Step mode of running a
8machine language program.
9The user interface is through the function (fexpr) step, which sets
10switches to put the LISP interpreter in and out of "stepping" mode.
11The most common \fIstep\fP invocations follow. These invocations are
12usually typed at the top-level, and will take effect
13immediately (i.e. the next S-expression typed in will be evaluated in stepping
14mode).
15.Eb
16\fI(step t)\fP ; Turn on stepping mode.
17\fI(step nil)\fP ; Turn off stepping mode.
18.Ee
19.Se
20In stepping mode, the LISP evaluator will print out each S-exp to
21be evaluated before evaluation, and the returned value after evaluation,
22calling itself recursively to display the stepped evaluation of each
23argument, if the S-exp is a function call. In stepping mode, the
24evaluator will wait after displaying each S-exp before evaluation
25for a command character from the console.
26.Eb
27\fISTEP COMMAND SUMMARY\fP
28
29<return> Continue stepping recursively.
30
31c Show returned value from this level
32 only, and continue stepping upward.
33
34e Only step interpreted code.
35
36g Turn off stepping mode. (but continue
37 evaluation without stepping).
38
39n <number> Step through <number> evaluations without
40 stopping
41
42p Redisplay current form in full
43 (i.e. rebind prinlevel and prinlength to nil)
44
45b Get breakpoint
46
47q Quit
48
49d Call debug
50.Ee
51.sh 2 Advanced\ Features
52.sh 3 Selectively\ Turning\ On\ Stepping.
53
54If
55 \fI(step foo1 foo2 ...)\fP
56
57is typed at top level, stepping will not commence
58immediately, but rather when the evaluator first encounters an S-expression
59whose car is one of \fIfoo1, foo2\fP, etc. This form will then display
60at the console, and the evaluator will be in stepping mode waiting
61for a command character.
62.pp
63Normally the stepper intercepts calls to \fIfuncall\fP and \fIeval\fP.
64When \fIfuncall\fP is intercepted, the arguments to the function
65have already been evaluated but when \fIeval\fP is intercepted, the
66arguments have not been evaluated. To differentiate the two cases,
67when printing the form in evaluation, the stepper preceded intercepted
68calls to
69.i funcall
70with "f:".
71Calls to \fIfuncall\fP are normally caused by compiled lisp code calling
72other functions, whereas calls to \fIeval\fP
73usually occur when lisp code is interpreted.
74To step only calls to eval use:
75 \fI(step e)\fP
76
77.sh 3 Stepping\ With\ Breakpoints.
78.pp
79For the moment, step is turned off inside of error breaks, but not by
80the break function. Upon exiting the error, step is reenabled.
81However, executing \fI(step nil)\fP inside a error loop will turn off
82stepping globally, i.e. within the error loop, and after return has
83be made from the loop.
84.sh 2 Overhead\ of\ Stepping.
85.pp
86If stepping mode has been turned off by \fI(step nil)\fP,
87the execution overhead
88of having the stepping packing in your LISP is identically nil.
89If one stops stepping by typing "g", every call to eval
90incurs a small overhead--several machine instructions, corresponding
91to the compiled code for a simple cond and one function pushdown.
92Running with \fI(step foo1 foo2 ...)\fP can be more expensive, since a
93member of the car of the current form into the list \fI(foo1 foo2 ...)\fP
94is required at each call to eval.
95.sh 2 Evalhook\ and\ Funcallhook
96.pp
97There are hooks in the
98.Fr
99interpreter to permit a user written function to gain control of the
100evaluation process.
101These hooks are used by the Step package just described.
102There are two hooks and they have been strategically placed in the
103two key functions in the interpreter:
104.i eval
105(which all interpreted code goes through)
106and
107.i funcall
108(which all compiled code goes through if \fI(sstatus\ translink\ nil)\fP
109has been done).
110The hook in
111.i eval
112is compatible with Maclisp, but there is no
113Maclisp equivalent of the hook in
114.i funcall .
115.pp
116To arm the hooks two forms must be evaluated: \fI(*rset\ t)\fP and
117\fI(sstatus\ evalhook\ t)\fP.
118Once that is done,
119.i eval
120and
121.i funcall
122do a special check when they enter.
123.pp
124If
125.i eval
126is given a form to evaluate, say \fI(foo\ bar)\fP,
127and the symbol `evalhook' is non nil, say its value is `ehook',
128then
129.i eval
130will lambda bind the symbols `evalhook' and `funcallhook'
131to nil and will call ehook passing \fI(foo\ bar)\fP as the argument.
132It is ehook's responsibility to evaluate \fI(foo\ bar)\fP and
133return its value.
134Typically ehook will call the function `evalhook'
135to evaluate \fI(foo\ bar)\fP.
136Note that `evalhook' is a symbol whose function binding is a system function
137described in Chapter 4, and whose value binding, if non nil, is the
138name of a user written
139function (or a lambda expression, or a binary object) which
140will gain control whenever eval is called.
141`evalhook' is also the name of the
142.i status
143tag which must be set for
144all of this to work.
145.pp
146If
147.i funcall
148is given a function, say foo, and a set of already evaluated
149arguments, say barv and bazv, and if the symbol `funcallhook'
150has a non nil value, say `fhook', then
151.i funcall
152will lambda bind `evalhook' and `funcallhook' to nil
153and will call fhook with arguments barv, bazv and foo.
154Thus fhook must be a lexpr since it may be given any number
155of arguments.
156The function to call, foo in this case, will be the
157.i last
158of the arguments given to fhook.
159It is fhooks responsibility to do the function call and return the
160value.
161Typically fhook will call the function
162.i funcallhook
163to do the funcall.
164This is an example of a funcallhook function which just prints
165the arguments on each entry to funcall and the return value.
166.Eb
167-> \fI(defun fhook n (let ((form (cons (arg n) (listify (1- n))))
168 (retval))
169 (patom "calling ")(print form)(terpr)
170 (setq retval (funcallhook form 'fhook))
171 (patom "returns ")(print retval)(terpr)
172 retval))\fP
173fhook
174-> \fI(*rset t) (sstatus evalhook t) (sstatus translink nil)\fP
175-> \fI(setq funcallhook 'fhook)\fP
176calling (print fhook) ;; now all compiled code is traced
177fhookreturns nil
178calling (terpr)
179
180returns nil
181calling (patom "-> ")
182-> returns "-> "
183calling (read nil Q00000)
184\fI(array foo t 10)\fP ;; to test it, we see what happens when
185returns (array foo t 10) ;; we make an array
186calling (eval (array foo t 10))
187calling (append (10) nil)
188returns (10)
189calling (lessp 1 1)
190returns nil
191calling (apply times (10))
192returns 10
193calling (small-segment value 10)
194calling (boole 4 137 127)
195returns 128
196 ... there is plenty more ...
197.Ee