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