|
|
1.1 root 1:
2:
3:
4:
5:
6:
7:
8: CHAPTER 14
9:
10:
11: The LISP Stepper
12:
13:
14:
15:
16:
17:
18: 14.1. Simple Use Of Stepping
19:
20: (step s_arg1...)
21:
22: NOTE: The LISP "stepping" package is intended to give
23: the LISP programmer a facility analogous to the
24: Instruction Step mode of running a machine
25: language program. The user interface is through
26: the function (fexpr) step, which sets switches to
27: put the LISP interpreter in and out of "stepping"
28: mode. The most common _s_t_e_p invocations follow.
29: These invocations are usually typed at the top-
30: level, and will take effect immediately (i.e. the
31: next S-expression typed in will be evaluated in
32: stepping mode).
33:
34:
35: ____________________________________________________
36:
37: (_s_t_e_p _t) ; Turn on stepping mode.
38: (_s_t_e_p _n_i_l) ; Turn off stepping mode.
39: ____________________________________________________
40:
41:
42:
43:
44: SIDE EFFECT: In stepping mode, the LISP evaluator will
45: print out each S-exp to be evaluated
46: before evaluation, and the returned value
47: after evaluation, calling itself recur-
48: sively to display the stepped evaluation
49: of each argument, if the S-exp is a func-
50: tion call. In stepping mode, the evalua-
51: tor will wait after displaying each S-exp
52: before evaluation for a command character
53: from the console.
54:
55:
56:
57:
58:
59:
60: 9
61:
62: 9The LISP Stepper 14-1
63:
64:
65:
66:
67:
68:
69:
70: The LISP Stepper 14-2
71:
72:
73:
74: ____________________________________________________
75:
76: _S_T_E_P _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
77:
78: <return> Continue stepping recursively.
79:
80: c Show returned value from this level
81: only, and continue stepping upward.
82:
83: e Only step interpreted code.
84:
85: g Turn off stepping mode. (but continue
86: evaluation without stepping).
87:
88: n <number> Step through <number> evaluations without
89: stopping
90:
91: p Redisplay current form in full
92: (i.e. rebind prinlevel and prinlength to nil)
93:
94: b Get breakpoint
95:
96: q Quit
97:
98: d Call debug
99: ____________________________________________________
100:
101:
102:
103:
104:
105:
106: 14.2. Advanced Features
107:
108:
109:
110: 14.2.1. Selectively Turning On Stepping.
111:
112: If
113: (_s_t_e_p _f_o_o_1 _f_o_o_2 ...)
114:
115: is typed at top level, stepping will not commence
116: immediately, but rather when the evaluator first
117: encounters an S-expression whose car is one of
118: _f_o_o_1, _f_o_o_2, etc. This form will then display at
119: the console, and the evaluator will be in stepping
120: mode waiting for a command character.
121:
122: Normally the stepper intercepts calls to _f_u_n_-
123: _c_a_l_l and _e_v_a_l. When _f_u_n_c_a_l_l is intercepted, the
124: arguments to the function have already been
125: evaluated but when _e_v_a_l is intercepted, the
126:
127:
128: Printed: July 21, 1983
129:
130:
131:
132:
133:
134:
135:
136: The LISP Stepper 14-3
137:
138:
139: arguments have not been evaluated. To differen-
140: tiate the two cases, when printing the form in
141: evaluation, the stepper preceded intercepted calls
142: to _f_u_n_c_a_l_l with "f:". Calls to _f_u_n_c_a_l_l are nor-
143: mally caused by compiled lisp code calling other
144: functions, whereas calls to _e_v_a_l usually occur when
145: lisp code is interpreted. To step only calls to
146: eval use: (_s_t_e_p _e)
147:
148:
149:
150:
151: 14.2.2. Stepping With Breakpoints.
152:
153: For the moment, step is turned off inside of
154: error breaks, but not by the break function. Upon
155: exiting the error, step is reenabled. However,
156: executing (_s_t_e_p _n_i_l) inside a error loop will turn
157: off stepping globally, i.e. within the error loop,
158: and after return has be made from the loop.
159:
160:
161:
162: 14.3. Overhead of Stepping.
163:
164: If stepping mode has been turned off by (_s_t_e_p
165: _n_i_l), the execution overhead of having the stepping
166: packing in your LISP is identically nil. If one stops
167: stepping by typing "g", every call to eval incurs a
168: small overhead--several machine instructions,
169: corresponding to the compiled code for a simple cond
170: and one function pushdown. Running with (_s_t_e_p _f_o_o_1
171: _f_o_o_2 ...) can be more expensive, since a member of the
172: car of the current form into the list (_f_o_o_1 _f_o_o_2 ...)
173: is required at each call to eval.
174:
175:
176:
177: 14.4. Evalhook and Funcallhook
178:
179: There are hooks in the FRANZ LISP interpreter to
180: permit a user written function to gain control of the
181: evaluation process. These hooks are used by the Step
182: package just described. There are two hooks and they
183: have been strategically placed in the two key func-
184: tions in the interpreter: _e_v_a_l (which all interpreted
185: code goes through) and _f_u_n_c_a_l_l (which all compiled
186: code goes through if (_s_s_t_a_t_u_s _t_r_a_n_s_l_i_n_k _n_i_l) has been
187: done). The hook in _e_v_a_l is compatible with Maclisp,
188: but there is no Maclisp equivalent of the hook in _f_u_n_-
189: _c_a_l_l.
190:
191: 9
192:
193: 9 Printed: July 21, 1983
194:
195:
196:
197:
198:
199:
200:
201: The LISP Stepper 14-4
202:
203:
204: To arm the hooks two forms must be evaluated:
205: (*_r_s_e_t _t) and (_s_s_t_a_t_u_s _e_v_a_l_h_o_o_k _t). Once that is
206: done, _e_v_a_l and _f_u_n_c_a_l_l do a special check when they
207: enter.
208:
209: If _e_v_a_l is given a form to evaluate, say
210: (_f_o_o _b_a_r), and the symbol `evalhook' is non nil, say
211: its value is `ehook', then _e_v_a_l will lambda bind the
212: symbols `evalhook' and `funcallhook' to nil and will
213: call ehook passing (_f_o_o _b_a_r) as the argument. It is
214: ehook's responsibility to evaluate (_f_o_o _b_a_r) and
215: return its value. Typically ehook will call the func-
216: tion `evalhook' to evaluate (_f_o_o _b_a_r). Note that
217: `evalhook' is a symbol whose function binding is a
218: system function described in Chapter 4, and whose
219: value binding, if non nil, is the name of a user writ-
220: ten function (or a lambda expression, or a binary
221: object) which will gain control whenever eval is
222: called. `evalhook' is also the name of the _s_t_a_t_u_s tag
223: which must be set for all of this to work.
224:
225: If _f_u_n_c_a_l_l is given a function, say foo, and a
226: set of already evaluated arguments, say barv and bazv,
227: and if the symbol `funcallhook' has a non nil value,
228: say `fhook', then _f_u_n_c_a_l_l will lambda bind `evalhook'
229: and `funcallhook' to nil and will call fhook with
230: arguments barv, bazv and foo. Thus fhook must be a
231: lexpr since it may be given any number of arguments.
232: The function to call, foo in this case, will be the
233: _l_a_s_t of the arguments given to fhook. It is fhooks
234: responsibility to do the function call and return the
235: value. Typically fhook will call the function _f_u_n_-
236: _c_a_l_l_h_o_o_k to do the funcall. This is an example of a
237: funcallhook function which just prints the arguments
238: on each entry to funcall and the return value.
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256: 9
257:
258: 9 Printed: July 21, 1983
259:
260:
261:
262:
263:
264:
265:
266: The LISP Stepper 14-5
267:
268:
269:
270: ____________________________________________________
271:
272: -> (_d_e_f_u_n _f_h_o_o_k _n (_l_e_t ((_f_o_r_m (_c_o_n_s (_a_r_g _n) (_l_i_s_t_i_f_y (_1- _n))))
273: (_r_e_t_v_a_l))
274: (_p_a_t_o_m "_c_a_l_l_i_n_g ")(_p_r_i_n_t _f_o_r_m)(_t_e_r_p_r)
275: (_s_e_t_q _r_e_t_v_a_l (_f_u_n_c_a_l_l_h_o_o_k _f_o_r_m '_f_h_o_o_k))
276: (_p_a_t_o_m "_r_e_t_u_r_n_s ")(_p_r_i_n_t _r_e_t_v_a_l)(_t_e_r_p_r)
277: _r_e_t_v_a_l))
278: fhook
279: -> (*_r_s_e_t _t) (_s_s_t_a_t_u_s _e_v_a_l_h_o_o_k _t) (_s_s_t_a_t_u_s _t_r_a_n_s_l_i_n_k _n_i_l)
280: -> (_s_e_t_q _f_u_n_c_a_l_l_h_o_o_k '_f_h_o_o_k)
281: calling (print fhook) ;; now all compiled code is traced
282: fhookreturns nil
283: calling (terpr)
284:
285: returns nil
286: calling (patom "-> ")
287: -> returns "-> "
288: calling (read nil Q00000)
289: (_a_r_r_a_y _f_o_o _t _1_0) ;; to test it, we see what happens when
290: returns (array foo t 10) ;; we make an array
291: calling (eval (array foo t 10))
292: calling (append (10) nil)
293: returns (10)
294: calling (lessp 1 1)
295: returns nil
296: calling (apply times (10))
297: returns 10
298: calling (small-segment value 10)
299: calling (boole 4 137 127)
300: returns 128
301: ... there is plenty more ...
302: ____________________________________________________
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321: 9
322:
323: 9 Printed: July 21, 1983
324:
325:
326:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.