(setq SCCS-step "@(#)step.l 1.3 7/9/81")
;;; LISP Stepping Package
;;; Adapted by Mitch Marcus for Franz Lisp from Chuck Rich's MACLISP
;;; Adapted 2/80 from the Maclisp version of 11/03/76
;;; Further modified 5/80 by Don Cohen (DNC)
;;; modified by jkf 6/81 to handle funcallhook.
;;; User Interface Function
;;; (step) or (step nil) :: turn off stepping
;;; (step t) :: turn on stepping right away.
;;; (step e) :: turn on stepping of eval only
;;; (step foo1 foo2 ...) :: turn on stepping when one of fooi is
; evalhook* is nil meaning no stepping, or t meaning always step
; or is a list of forms which will start continuous stepping.
; The hook functions are evalhook* and funcallhook*.
hookautolfcount funcallhook
evalhook evalhook* |evalhook#| prinlevel prinlength
fcn-evalhook fcn-funcallhook)
;; (7BIT n c) tests if n is ascii for c
(list '= (list 'boole 1 127. (cadr s)) (caddr s)))
; indent based on current evalhook recursion level then print the
;; print with indentation
(indent (* 2 |evalhook#|))
(cond ((eq type 'funcall) (patom "f:")))
(cond ((or (null arg) (car arg))
(setq evalhook-switch t) ; for fixit package
(setq |evalhook#| 0.) ;initialize depth count
(setq hookautolfcount 0) ; count if auto lfs at break
(setq evalhook nil) ;for safety
; (step e) means just step eval things, else step eval and funcal
(setq fcn-evalhook 'evalhook* fcn-funcallhook nil))
(t (setq fcn-evalhook 'evalhook* fcn-funcallhook 'funcallhook*)))
((or (eq (car arg) t) (eq (car arg) 'e)))
(setq evalhook fcn-evalhook) ;turn system hook to my function
(setq funcallhook fcn-funcallhook)
(*rset t) ;must be on for hook to work
(sstatus evalhook t)) ;arm it
(setq hookautolfcount 0) ; count if auto lfs at break
(setq evalhook-switch nil)
(sstatus evalhook nil))))
; common function to handle evalhook's and funcallhook's.
; the form to be evaluated is given as form and the type (eval or funcall)
(defun funcall-evalhook* (form type)
;; see if selective feature kicks in here
(memq (car form) evalhook*)
(setq evalhook* t)) ; yes, begin stepping always
;; print out form before evaluation
;; since form is atom, we just eval it and print
;; out its value, no need to ask user what to do
(cond ((not (or (numberp form)(null form)(eq form t)))
((lambda (prinlevel prinlength)
(setq form (evalhook form nil nil))
(prog (cmd ehookfn fhookfcn)
cmdlp (cond ((greaterp hookautolfcount 0)
(setq hookautolfcount (sub1 hookautolfcount))
(t (setq cmd(let ((piport nil))
;; dispatch on command character
(setq ehookfn fcn-evalhook
fhookfcn fcn-funcallhook))
(setq evalhook* nil ;stop everything
(setq evalhook-switch nil)
(cond ((not (numberp hookautolfcount))
(patom "arg to n should be number")
(setq hookautolfcount 0))))
(setq fcn-funcallhook nil))
; "?", "H" show the options
((memq cmd '(72 104 63.))
#+cmu (ty /usr/lisp/doc/step\.ref)
(t (princ '"Try one of ?BCDGMPQ or <cr>")
(setq form (continue-evaluation
;; print out evaluated form
(not (zerop |evalhook#|))))
(t (continue-evaluation form type fcn-evalhook fcn-funcallhook))))
(t (continue-evaluation form type fcn-evalhook fcn-funcallhook))))
; print a summary of the functions of step
(patom "<cr> - single step; n <number> - step <number> times")(terpr)
(patom "b - break; q - quit stepping; d - call debug;") (terpri)
(patom "c - turn off step for deeper levels; e - stop at eval forms only")
(patom "h,? - print this") (terpr))
; automatically called when a funcall is done and funcallhook*'s
; value is the name of this function (funcallhook*). When this is
; called, a function with n-1 args is being funcalled, the args
; to the function are (arg 1) through (arg (sub1 n)), the name of
; the function is (arg n)
(args (listify (sub1 n))))
(funcall-evalhook* (cons name args) 'funcall)))
; called whenever an eval is done and evalhook*'s value is the
; name of this function (evalhook*). arg is the thing being
(funcall-evalhook* arg 'eval))
(defun continue-evaluation (form type evalhookfcn funcallhookfcn)
(cond ((eq type 'eval) (evalhook form evalhookfcn funcallhookfcn))
(t (funcallhook form funcallhookfcn evalhookfcn))))
(or (boundp 'prinlength) (setq prinlength nil))
(or (boundp 'prinlevel) (setq prinlevel nil))