|
|
1.1 ! root 1: (setq rcs-step- ! 2: "$Header: /usr/lib/lisp/step.l,v 1.1 83/01/29 18:39:46 jkf Exp $") ! 3: ! 4: ; vi: set lisp : ! 5: ! 6: ;;; LISP Stepping Package ! 7: ;;; ! 8: ;;; Adapted by Mitch Marcus for Franz Lisp from Chuck Rich's MACLISP ! 9: ;;; package. ! 10: ;;; ! 11: ;;; ! 12: ;;; Adapted 2/80 from the Maclisp version of 11/03/76 ! 13: ;;; Further modified 5/80 by Don Cohen (DNC) ! 14: ;;; ! 15: ;;; modified by jkf 6/81 to handle funcallhook. ! 16: ;;; ! 17: ;;; User Interface Function ! 18: ;;; ! 19: ;;; Valid Forms: ! 20: ;;; (step) or (step nil) :: turn off stepping ! 21: ;;; (step t) :: turn on stepping right away. ! 22: ;;; (step e) :: turn on stepping of eval only ! 23: ;;; (step foo1 foo2 ...) :: turn on stepping when one of fooi is ! 24: ;;; :: called ! 25: ;;; ! 26: ;------ implementation: ! 27: ; evalhook* is nil meaning no stepping, or t meaning always step ! 28: ; or is a list of forms which will start continuous stepping. ! 29: ; ! 30: ; The hook functions are evalhook* and funcallhook*. ! 31: ; ! 32: ! 33: (declare (special ! 34: evalhook-switch piport ! 35: hookautolfcount funcallhook ! 36: evalhook evalhook* |evalhook#| prinlevel prinlength ! 37: fcn-evalhook fcn-funcallhook ! 38: Standard-Input) ! 39: (macros nil)) ! 40: ! 41: ;; First Some Macros ! 42: ! 43: (defun 7bit macro (s) ! 44: ;; (7BIT n c) tests if n is ascii for c ! 45: (list '= (list 'boole 1 127. (cadr s)) (caddr s))) ! 46: ! 47: ;--- print* ! 48: ; indent based on current evalhook recursion level then print the ! 49: ; arg in form ! 50: ; ! 51: (defun print* macro (s) ! 52: ;; print with indentation ! 53: '(do ((i 1 (1+ i)) ! 54: (indent (* 2 |evalhook#|)) ! 55: (prinlevel 3) ! 56: (prinlength 5)) ! 57: ((> i indent) ! 58: (cond ((eq type 'funcall) (patom "f:"))) ! 59: (print form)) ! 60: (tyo 32.))) ! 61: ! 62: (defun step fexpr (arg) ! 63: (cond ((or (null arg) (car arg)) ! 64: (setq evalhook-switch t) ; for fixit package ! 65: (setq |evalhook#| 0.) ;initialize depth count ! 66: (setq hookautolfcount 0) ; count if auto lfs at break ! 67: (setq evalhook nil) ;for safety ! 68: (setq funcallhook nil) ! 69: ; (step e) means just step eval things, else step eval and funcal ! 70: (cond ((eq (car arg) 'e) ! 71: (setq fcn-evalhook 'evalhook* fcn-funcallhook nil)) ! 72: (t (setq fcn-evalhook 'evalhook* fcn-funcallhook 'funcallhook*))) ! 73: (setq evalhook* ! 74: (cond ((null arg) nil) ! 75: ((or (eq (car arg) t) (eq (car arg) 'e))) ! 76: (arg))) ! 77: (setq evalhook fcn-evalhook) ;turn system hook to my function ! 78: (setq funcallhook fcn-funcallhook) ! 79: (sstatus translink nil) ! 80: (*rset t) ;must be on for hook to work ! 81: (sstatus evalhook t)) ;arm it ! 82: (t (setq evalhook* nil) ! 83: (setq evalhook nil) ! 84: (setq hookautolfcount 0) ; count if auto lfs at break ! 85: (setq evalhook-switch nil) ! 86: (sstatus evalhook nil)))) ! 87: ! 88: ! 89: ;---- funcall-evalhook* ! 90: ; ! 91: ; common function to handle evalhook's and funcallhook's. ! 92: ; the form to be evaluated is given as form and the type (eval or funcall) ! 93: ; is given as type. ! 94: ; ! 95: ! 96: (defun funcall-evalhook* (form type) ! 97: (cond (evalhook* ! 98: ;; see if selective feature kicks in here ! 99: (and (not (atom form)) ! 100: (not (eq evalhook* t)) ! 101: (memq (car form) evalhook*) ! 102: (setq evalhook* t)) ; yes, begin stepping always ! 103: ! 104: (cond ((eq evalhook* t) ! 105: ;; print out form before evaluation ! 106: (print*) ! 107: ! 108: (cond ((atom form) ! 109: ;; since form is atom, we just eval it and print ! 110: ;; out its value, no need to ask user what to do ! 111: (cond ((not (or (numberp form)(null form)(eq form t))) ! 112: (princ '" = ") ! 113: ((lambda (prinlevel prinlength) ! 114: (setq form (evalhook form nil nil)) ! 115: (print form)) ! 116: 3 5))) ! 117: (terpri)) ! 118: (t ; s-expression ! 119: (prog (cmd ehookfn fhookfcn) ! 120: ! 121: cmdlp (cond ((greaterp hookautolfcount 0) ! 122: (setq hookautolfcount (sub1 hookautolfcount)) ! 123: (terpr) ! 124: (setq cmd #\lf)) ! 125: (t (setq cmd (let ((piport ! 126: Standard-Input)) ! 127: (drain piport) ! 128: (tyi piport))))) ! 129: ! 130: ;; uppercase alphabetics ! 131: ;; dispatch on command character ! 132: (cond ((eq cmd #\lf) ! 133: ; \n so continue ! 134: (setq ehookfn fcn-evalhook ! 135: fhookfcn fcn-funcallhook)) ! 136: ! 137: ((memq cmd '(#/p #/P)) ! 138: ; "P" print in full ! 139: (print form) ! 140: (go cmdlp)) ! 141: ! 142: ; "G" ! 143: ((memq cmd '(#/g #/G)) ! 144: (setq evalhook* nil ;stop everything ! 145: ehookfn nil ! 146: fhookfcn nil)) ! 147: ! 148: ((memq cmd '(#/c #/C)) ! 149: ;"C" no deeper ! 150: (setq ehookfn nil ! 151: fhookfcn nil)) ! 152: ! 153: ((memq cmd '(#/d #/D)) ! 154: ;"D" call debug ! 155: (setq evalhook-switch nil) ! 156: (sstatus evalhook nil) ! 157: (debug) ! 158: (setq evalhook-switch t) ! 159: (sstatus evalhook t) ! 160: (go cmdlp)) ! 161: ! 162: ! 163: ((memq cmd '(#/b #/B)) ! 164: ; "B" give breakpoint ! 165: (break step) ! 166: (print*) ! 167: (go cmdlp)) ! 168: ! 169: ((memq cmd '(#/q #/Q)) ! 170: ; "Q" stop stepping ! 171: (step nil) ! 172: (reset)) ! 173: ! 174: ((memq cmd '(#/n #/N)) ! 175: (setq hookautolfcount ! 176: (let ((piport Standard-Input)) ! 177: (read))) ! 178: (cond ((not (numberp hookautolfcount)) ! 179: (patom "arg to n should be number") ! 180: (terpr) ! 181: (setq hookautolfcount 0)))) ! 182: ! 183: ; "s" eval form ! 184: ((memq cmd '(#/s #/S)) ! 185: (let ((piport Standard-Input) ! 186: (fcns nil)) ! 187: (setq fcns (read)) ! 188: (cond ((dtpr fcns) ! 189: (setq evalhook* fcns)) ! 190: ((symbolp fcns) ! 191: (setq evalhook* (list fcns)))))) ! 192: ! 193: ; "e" step eval only ! 194: ((memq cmd '(#/e #/E)) ! 195: (setq fcn-funcallhook nil)) ! 196: ! 197: ; "?", "H" show the options ! 198: ((memq cmd '(72 104 63.)) ! 199: #+cmu (ty /usr/lisp/doc/step\.ref) ! 200: #-cmu(stephelpform) ! 201: (terpri) ! 202: (go cmdlp)) ! 203: ((eq cmd #\eof) ! 204: (patom "EOF typed") ! 205: (terpr)) ! 206: ! 207: (t (princ '"Try one of ?BCDGMPQ or <cr>") ! 208: (go cmdlp))) ! 209: ! 210: ;; evaluate form ! 211: (clear-input-buffer) ! 212: ((lambda (|evalhook#|) ! 213: (setq form (continue-evaluation ! 214: form ! 215: type ! 216: ehookfn ! 217: fhookfcn))) ! 218: (1+ |evalhook#|)) ! 219: ! 220: ;; print out evaluated form ! 221: (cond ((and evalhook* ! 222: (or (eq type 'funcall) ! 223: (not (zerop |evalhook#|)))) ! 224: (let ((type nil)) ! 225: (print*)) ! 226: (terpri) ! 227: ))))) ! 228: ;;return evaluated form ! 229: form) ! 230: (t ; why was this here? (clear-input-buffer) ! 231: (continue-evaluation form type fcn-evalhook fcn-funcallhook)))) ! 232: (t ; why was this here? (clear-input-buffer) ! 233: (continue-evaluation form type fcn-evalhook fcn-funcallhook)))) ! 234: ! 235: ;--- stephelpform ! 236: ; ! 237: ; print a summary of the functions of step ! 238: ; ! 239: (defun stephelpform nil ! 240: (patom "<cr> - single step; n <number> - step <number> times")(terpr) ! 241: (patom "b - break; q - quit stepping; d - call debug;") (terpri) ! 242: (patom "c - turn off step for deeper levels; e - stop at eval forms only") ! 243: (terpri) ! 244: (patom "h,? - print this") (terpr)) ! 245: ! 246: ;--- funcallhook* ! 247: ; ! 248: ; automatically called when a funcall is done and funcallhook*'s ! 249: ; value is the name of this function (funcallhook*). When this is ! 250: ; called, a function with n-1 args is being funcalled, the args ! 251: ; to the function are (arg 1) through (arg (sub1 n)), the name of ! 252: ; the function is (arg n) ! 253: ; ! 254: (defun funcallhook* n ! 255: (let ((name (arg n)) ! 256: (args (listify (sub1 n)))) ! 257: (funcall-evalhook* (cons name args) 'funcall))) ! 258: ! 259: ;--- evalhook* ! 260: ; ! 261: ; called whenever an eval is done and evalhook*'s value is the ! 262: ; name of this function (evalhook*). arg is the thing being ! 263: ; evaluated. ! 264: ; ! 265: (defun evalhook* (arg) ! 266: (funcall-evalhook* arg 'eval)) ! 267: ! 268: (defun continue-evaluation (form type evalhookfcn funcallhookfcn) ! 269: (cond ((eq type 'eval) (evalhook form evalhookfcn funcallhookfcn)) ! 270: (t (funcallhook form funcallhookfcn evalhookfcn)))) ! 271: ! 272: ! 273: (or (boundp 'prinlength) (setq prinlength nil)) ! 274: ! 275: (or (boundp 'prinlevel) (setq prinlevel nil)) ! 276: ! 277: ; Standard-Input is a variable bound to the initial stdin port. It is ! 278: ; bound in the auxfns0 package, but older lisps may not have that new ! 279: ; package, so in case they don't we approximate Standard-Input with nil ! 280: ; which works in many cases, but drain's do not work. ! 281: (or (boundp 'Standard-Input) (setq Standard-Input nil)) ! 282: (defun clear-input-buffer nil (drain Standard-Input))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.