|
|
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.