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