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