|
|
1.1 root 1: (setq rcs-tpl-
2: "$Header: tpl.l,v 1.6 84/02/29 19:31:09 jkf Exp $")
3:
4: ; -[Thu Feb 16 07:49:26 1984 by jkf]-
5: ;
6:
7: ; to do
8: ; ?state : display status translink, *rset, displace-macros.
9: ; current error, prinlevel and prinlength
10: ; add a way of modifying the values
11: ; ?bk [n] : do a baktrace (default 10 frames from bottom)
12: ; ?zo [n] : add an optional number of frames to zoom
13: ; ?retf : return value from 'current' frame
14: ; ?retry : retry expr in 'current' frame (required mod to lisp).
15: ;
16: ; the frame re-eval question is not asked when it should.
17: ; interact with tracebreaks correctly
18: ;
19: ; add stepper.
20: ; get 'debugging' to work ok.
21:
22: ;--- state
23: ;
24: (declare (special tpl-debug-on tpl-step-on
25: tpl-top-framelist tpl-bot-framelist
26: tpl-eval-flush tpl-trace-flush
27: tpl-prinlength tpl-prinlevel
28: prinlevel prinlength top-level-print
29: tpl-commands tpl-break-level
30: tpl-spec-char
31: tpl-last-loaded
32: tpl-level
33: tpl-fcn-in-eval
34: tpl-contuab
35: ER%tpl ER%all given-history res-history
36: tpl-stack-bad tpl-stack-ok
37: tpl-history-count
38: tpl-history-show
39: tpl-dontshow-tpl
40: tpl-step-enable ;; if stepping is on
41: tpl-step-print ;; if should print step forms
42: tpl-step-triggers ;; list of fcns to enable step
43: tpl-step-countdown ;; if positive, then don't break
44: tpl-step-reclevel ;; recursion level
45: evalhook funcallhook
46: *rset % piport ^w
47: debug-error-handler
48: displace-macros
49: ))
50:
51: (putd 'tpl-eval (getd 'eval))
52: (putd 'tpl-funcall (getd 'funcall))
53: (putd 'tpl-evalhook (getd 'evalhook))
54: (putd 'tpl-funcallhook (getd 'funcallhook))
55:
56:
57: ;--- macros which should be in the system
58: ;
59: (defmacro evalframe-type (evf) `(car ,evf))
60: (defmacro evalframe-pdl (evf) `(cadr ,evf))
61: (defmacro evalframe-expr (evf) `(caddr ,evf))
62: (defmacro evalframe-bind (evf) `(cadddr ,evf))
63: (defmacro evalframe-np (evf) `(caddddr ,evf))
64: (defmacro evalframe-lbot (evf) `(cadddddr ,evf))
65:
66:
67: ;; messages are passed between break levels by means of catch and
68: ;; throw:
69: (defmacro tpl-throw (value) `(*throw 'tpl-break-catch ,value))
70: (defmacro tpl-catch (form) `(*catch 'tpl-break-catch ,form))
71:
72: ; A tpl-catch is placed around the prompting and evaluation of forms.
73: ; if something abnormal happens in the evaluation, a tpl-throw is done
74: ; which then tells the break look that something special should be
75: ; done.
76: ;
77: ; messages:
78: ; contbreak - this tells the break level to print out the message
79: ; it prints when it is entered (such as the error message).
80: ; [see poplevel message].
81: ; poplevel - tells the break level to jump up to the next higher
82: ; break level and continue there. It sends contbreak
83: ; message to that break level so that it will remind the
84: ; user what the state is. [see cmd: ?pop ]
85: ; reset - This tells the break level to send a reset to the next
86: ; higher break level. Thus a reset is done by successive
87: ; small pops. This isn't totally necessary, but it is
88: ; clean.
89: ; (retbreak v) - return from the break level, returning the value v.
90: ; If this an error break, then we return (list v) since
91: ; that is required to indicate that an error has been
92: ; handled.
93: ; (retry v) - instead of asking for a new value, retry the given one.
94: ; popretry - take the expression that caused the current break and
95: ; send a (retry expr) message to the break level above us
96: ; so that it can be tried again.
97:
98: (setq tpl-eval-flush nil tpl-trace-flush nil
99: tpl-prinlevel 3 tpl-prinlength 4
100: tpl-spec-char #/?)
101:
102: (or (boundp 'tpl-last-loaded) (setq tpl-last-loaded nil))
103:
104: (defun tpl nil
105: (let ((debug-error-handler 'tpl-err-all-fcn))
106: (setq ER%tpl 'tpl-err-tpl-fcn)
107: (putd '*break (getd 'tpl-*break))
108: (setq given-history nil
109: res-history nil
110: tpl-debug-on nil
111: tpl-step-on nil
112: tpl-top-framelist nil
113: tpl-bot-framelist nil
114: tpl-stack-bad t
115: tpl-stack-ok nil
116: tpl-fcn-in-eval nil
117: tpl-level nil
118: tpl-history-count 0
119: tpl-break-level -1
120: tpl-dontshow-tpl t
121: tpl-history-show 10
122: tpl-step-enable nil
123: tpl-step-countdown 0
124: tpl-step-reclevel 0)
125: (do ((retv))
126: (nil)
127: (setq retv
128: (tpl-catch
129: (tpl-break-function nil))))))
130:
131:
132: ;--- do-one-transaction
133: ; do a single read-eval-print transaction
134: ; If eof-form is given, then we provide a prompt and read the input,
135: ; otherwise given is what we use, but we print the prompt and the
136: ; given input before evaling it again.
137: ; (given must be in the form (sys|user ..)
138: ;
139: (defun do-one-transaction (given prompt eof-form)
140: (let (retv)
141: (patom prompt)
142: (If eof-form
143: then (setq given
144: (car (errset (ntpl-read nil eof-form))))
145: (If (eq eof-form given)
146: then (If (status isatty)
147: then (msg "EOF" N)
148: (setq given '(sys <eof>))
149: else (exit)))
150: else (tpl-history-form-print given)
151: (terpr))
152: (add-to-given-history given)
153: (If (eq 'user (car given))
154: then (setq tpl-stack-bad t)
155: (setq retv
156: (if tpl-step-enable
157: then (tpl-evalhook (cdr given)
158: 'tpl-do-evalhook
159: 'tpl-do-funcallhook)
160: else (tpl-eval (cdr given))))
161: (setq tpl-stack-bad t)
162: else (setq retv (process-fcn (cdr given)))
163: (setq tpl-stack-bad (not tpl-stack-ok)))
164: (add-to-res-history retv)
165: (ntpl-print retv)
166: (terpr)
167: ))
168:
169:
170: ;; reader
171: ; if sees a rpar as the first non space char, it just reads all chars
172: ; return (sys . form) where form is a list, e.g
173: ; )foo bar baz rets (sys foo bar baz)
174: ; or
175: ; (user . form)
176: ; note: if nothing is typed, (sys) is returned
177: ;
178: (defun ntpl-read (port eof-form)
179: (let (ch)
180: ; skip all spaces
181: (do ()
182: ((and (not (eq (setq ch (tyipeek port)) #\space))
183: (not (eq ch #\newline))))
184: (setq ch (tyi)))
185: (If (eq ch #\eof)
186: then eof-form
187: else (setq ch (tyi port))
188: (If (eq ch tpl-spec-char)
189: then (do ((xx (list #\lpar) (cons (tyi) xx)))
190: ((or (eq #\eof (car xx))
191: (eq #\newline (car xx)))
192: (cons 'sys
193: (car (errset
194: (readlist
195: (nreverse
196: (cons #\rpar (cdr xx)))))))))
197: else (untyi ch)
198: (cons 'user (read port eof-form))))))
199:
200: ;--- tpl-history-form-print :: the inverse of tpl-read
201: ; this takes the history form of an expression and prints it out
202: ; just as the user would have typed it.
203: ;
204: (defun tpl-history-form-print (form)
205: (If (eq 'user (car form))
206: then (print (cdr form))
207: else (patom "?")
208: (mapc '(lambda (x) (print x) (patom " ")) (cdr form))))
209:
210: (defun ntpl-print (form)
211: (cond ((and top-level-print
212: (getd top-level-print))
213: (funcall top-level-print form))
214: (t (print form))))
215:
216: (setq tpl-commands
217: '( ((help h) tpl-command-help
218: " [cmd] - print general or specific info "
219: " '?help' - print a short description of all commands "
220: " '?help cmd' - print extended information on the given command ")
221: ( ? tpl-command-redo
222: " [args] - redo last or previous command "
223: " '??' - redo last user command "
224: " '?? n' - (for n>0) redo command #n (as printed by ?history)"
225: " '?? -n' - (for n>0) redo n'th previous command (?? -1 == ??)"
226: " '?? symb' - redo last with car == symb"
227: " '?? symb *' - redo last with car == symb*")
228: ( (his history) tpl-command-history
229: " [r] - print history list "
230: " ?history, ?his - print list of commands previously executed"
231: " '?his r' - print results too")
232: ( (re reset) tpl-command-reset
233: " - pop up to the top level"
234: " '?re, ?reset', pop up to the top level ")
235: ( tr tpl-command-trace
236: " [fn ..] - trace"
237: " '?tr' - print list of traced functions"
238: " '?tr fn ...' - trace given functions, can be fn or (fn cmd ...)"
239: " where cmds are trace commands")
240: ( step tpl-command-step
241: " [t] [funa funb ...] step always or when specific function hit"
242: " '?step t' - step starting right away "
243: " '?step funa funb' - step when either funa or funb to be called ")
244: ( soff tpl-command-stepoff
245: " - turn off stepping "
246: " '?soff' - turn off stepping ")
247: ( sc tpl-command-sc
248: " [n] - continue stepping [don't break for n steps] "
249: " '?sc' - do one step then break "
250: " '?sc n' - step for n steps before breaking "
251: " if n is a non integer (e.g. inf) then "
252: " step forever without breaking ")
253: ( state tpl-command-state
254: " [vals] - print or change state "
255: " 'state' - print current state in short form "
256: " 'state l' - print state in long form"
257: " 'state sym val ... ...' - set values of state "
258: " symbols are those given in 'state l' list")
259: ( prt tpl-command-prt
260: " - pop up a level and retry the command which caused this break"
261: " ?prt - do a ?pop followed by a retry of the command which"
262: " caused this break to be entered")
263: ( ld tpl-command-load
264: " [file ...] - load given or last files"
265: " 'ld' - loads the last files loaded with ?ld"
266: " 'ld file ...' - loads the given files")
267: ( debug tpl-command-debug
268: " [off] - toggle debug state "
269: " 'debug' Turns on debugging. When debug is on then"
270: " enough information is kept around for viewing"
271: " and quering evaluation stack"
272: " 'debug off' - Turns off debuging" )
273: ( fast tpl-command-fast
274: " - set switches for fastest execution "
275: " '?fast - turn off ?debug mode (i.e. (*rset nil)), set the "
276: " translink table to 'on', and set displace-macros to t."
277: " This will cause franz to run as fast as possible "
278: " (but will result in loss of debugging information ")
279: ( pop tpl-command-pop
280: " - pop up to previous break level"
281: " 'pop' - if not at top level, pop up to the break level"
282: " above this one")
283: ( ret tpl-command-ret
284: " [val] - return value from this break loop "
285: " 'ret [val]' if this is a break look due to a break command "
286: " or a continuable error, evaluate val (default nil)"
287: " and return it to the function that found an error,"
288: " allowing it to continue")
289:
290: ( zo tpl-command-zoom
291: " - view a portion of evaluation stack"
292: " 'zo' - show a portion above and below the 'current' stack"
293: " frame. Use )up and )dn or alter current stack frame")
294: ( dn tpl-command-down
295: " [n] - go down stack frames "
296: " 'dn' - move the current stack frame down one. Down refers to"
297: " older stack frames"
298: " 'dn n' - n is a fixnum telling how many stack frames to go down"
299: " 'dn n z' - after going down, do a zoom"
300: " After dn is done, a limited zoom will be done")
301: ( up tpl-command-up
302: " [n] - go up stack frames "
303: " 'up' - move the current stack frame up one. Up refers to"
304: " younger stack frames"
305: " 'up n' - n is a fixnum telling how many stack frames to go up")
306: ( ev tpl-command-ev
307: " symbol - eval the given symbol wrt the current frame "
308: " 'ev symbol' - determine the value of the given symbol"
309: " after restoring the bindings to the way they were"
310: " when the current frame was current. see ?zo,?up,?dn")
311: ( pp tpl-command-pp
312: " - pretty print the current frame "
313: " 'pp' - pretty print the current frame (see ?zo, ?up, ?dn)")
314: ( <eof> tpl-command-pop
315: " - pop one break level up "
316: " '^D' - if connect to tty, pops up one break level,"
317: " otherwise, exits doesn't exit unless "))
318: )
319:
320: ;--- process-fcn :: do a user command
321: ;
322: (defun process-fcn (form)
323: (let ((sel (car form)))
324: (setq tpl-stack-ok nil)
325: (do ((xx tpl-commands (cdr xx))
326: (this))
327: ((null xx)
328: (msg "Illegal command, type ?help for list of commands" N))
329: (If (or (and (symbolp (setq this (caar xx)))
330: (eq sel this))
331: (and (dtpr this)
332: (memq sel this)))
333: then (return (tpl-funcall (cadar xx) form))))))
334:
335:
336:
337: ;--- tpl commands
338: ;
339:
340: ;--- tpl-command-help
341: (defun tpl-command-help (x)
342: (setq tpl-stack-ok t)
343: (If (cdr x)
344: then (do ((xx tpl-commands (cdr xx))
345: (sel (cadr x))
346: (this))
347: ((null xx)
348: (msg "I don't know that command" N))
349: ; look for command in tpl-commands list
350: (If (or (and (symbolp (setq this (caar xx)))
351: (eq sel this))
352: (and (dtpr this)
353: (memq sel this)))
354: then (return (do ((yy (cdddar xx) (cdr yy)))
355: ((null yy))
356: ; print all extended documentation
357: (patom (car yy))
358: (terpr)))))
359: else ; print short info on all commands
360: (mapc #'(lambda (x)
361: (let ((sel (car x)))
362: ; first print selector or selectors
363: (If (dtpr sel)
364: then (patom (car sel))
365: (mapc #'(lambda (y) (patom ",") (patom y))
366: (cdr sel))
367: else (patom sel))
368: ; next print documentation
369: (patom (caddr x))
370: (terpr)))
371: tpl-commands))
372: nil)
373:
374: (defun tpl-command-load (args)
375: (setq args (cdr args))
376: (If args
377: then (setq tpl-last-loaded args)
378: (mapc 'load args)
379: elseif tpl-last-loaded
380: then (mapc 'load tpl-last-loaded)
381: else (msg "Nothing to load" N)))
382:
383:
384: (defun tpl-command-trace (args)
385: (setq args (cdr args))
386: (apply 'trace args))
387:
388:
389:
390: ;--- tpl-command-state
391: ;
392: (defun tpl-command-state (x)
393: (msg " State: debug " tpl-debug-on ", step " tpl-step-enable N)
394: (msg " *rset " *rset ", (status translink) " (status translink) N)
395: (msg " variables: tpl-prinlength " tpl-prinlength N)
396: (msg " tpl-prinlevel " tpl-prinlevel N))
397:
398: ;--- tpl-command-debug
399: ;
400: (defun tpl-command-debug (x)
401: (If (memq 'off (cdr x))
402: then (*rset nil)
403: (msg "Debug is off" N)
404: (setq tpl-debug-on nil)
405: else (*rset t)
406: (sstatus translink nil)
407: (msg "Debug is on" N)
408: (setq tpl-debug-on t)))
409:
410: ;--- tpl-command-fast
411: ;
412: (defun tpl-command-fast (x)
413: (*rset nil)
414: (setq tpl-debug-on nil)
415: (sstatus translink on)
416: (setq displace-macros t))
417:
418: ;--- tpl-command-zoom
419: ;
420: (defun tpl-command-zoom (x)
421: (tpl-update-stack)
422: (setq tpl-stack-ok t)
423: (tpl-zoom))
424:
425: (defun tpl-command-down (args)
426: ;; go down the evaluation stack and zoom
427: ;; down means towards older frames
428: (setq tpl-stack-ok t)
429: (let ((count 1))
430: (If (and (fixp (cadr args)) (> (cadr args) 0))
431: then (setq count (cadr args)))
432: (do ((xx count (1- xx)))
433: ((= 0 xx))
434: (If tpl-bot-framelist
435: then (setq tpl-top-framelist (cons (car tpl-bot-framelist)
436: tpl-top-framelist)
437: tpl-bot-framelist (cdr tpl-bot-framelist))))
438: (tpl-command-zoom nil)))
439:
440: (defun tpl-command-up (args)
441: ;; go up the stack and zoom
442: ;; up is towards more recent stuff
443: ;;
444: (setq tpl-stack-ok t)
445: (let ((count 1))
446: (If (and (fixp (cadr args)) (> (cadr args) 0))
447: then (setq count (cadr args)))
448: (do ((xx count (1- xx)))
449: ((= 0 xx))
450: (If tpl-top-framelist
451: then (setq tpl-bot-framelist (cons (car tpl-top-framelist)
452: tpl-bot-framelist)
453: tpl-top-framelist (cdr tpl-top-framelist))))
454: (tpl-command-zoom nil)))
455:
456: (defun tpl-command-ev (args)
457: ;; ?ev foo
458: ;; determine the value of variable foo with respect to the current
459: ;; evaluation frame.
460: ;;
461: (let ((sym (cadr args)))
462: (If (not (symbolp sym))
463: then (msg "ev must be given a symbol" N)
464: elseif (null tpl-bot-framelist)
465: then (msg "there is no evaluation stack, is debug on?")
466: else (prog1 (car
467: (errset
468: (eval sym
469: (evalframe-bind (car tpl-bot-framelist)))))
470: (setq tpl-stack-ok t)))))
471:
472:
473: (defun tpl-command-pp (args)
474: (pp-form (evalframe-expr (car tpl-bot-framelist)))
475: (terpr)
476: nil)
477:
478: ;;-- history list maintainers
479: ;
480: ; history lists are just lists of forms
481: ; one for the given, and one for the returned
482: ;
483: (defun most-recent-given () (car given-history))
484:
485: (defun add-to-given-history (form)
486: (setq given-history (cons form given-history))
487: (setq res-history (cons nil res-history))
488: (If (not (eq (car form) 'history))
489: then (setq tpl-history-count (1+ tpl-history-count))))
490:
491: (defun add-to-res-history (form)
492: (setq res-history (cons form (cdr res-history)))
493: (setq % form))
494:
495:
496: ;--- evalframe generation
497: ;
498:
499: (defun tpl-update-stack nil
500: (If tpl-stack-bad
501: then (If (tpl-yorn "Should I re-calc the stack(y/n):")
502: then (tpl-gentrace)
503: else (msg "[not re-calc'ed]" N)
504: (setq tpl-stack-bad nil))))
505:
506: ;--- tpl-gentrace
507: ; this is called before an function which references the
508: ; frame list. it needn't be called unless one knows that
509: ; the frame status has changed
510: ;
511: (defun tpl-gentrace ()
512: (let ((templist (tpl-getframelist)))
513: ; templist contains the frame from bottom (oldest) to top
514:
515: (setq templist (nreverse templist)) ; now youngest to oldest
516:
517:
518: ; determine a new framelist and put it on the bottom list
519: ; the top list is empty. the first thing in the
520: ; bottom framelist is the 'current' frame.
521:
522: ; go though frames, based on flags, flush trace calls
523: ; or eval calls
524: (do ((xx templist (cdr xx))
525: (remember (If tpl-dontshow-tpl then nil else t))
526: (forget-this nil nil)
527: (res)
528: (exp)
529: (flushpoint))
530: ((null xx) (setq tpl-bot-framelist (nreverse res)))
531: (setq exp (evalframe-expr (car xx)))
532: (If (dtpr exp)
533: then (If (and tpl-dontshow-tpl
534: (memq (car exp) '(tpl-eval tpl-funcall
535: tpl-evalhook
536: tpl-funcallhook)))
537: then (setq remember nil)))
538: (If (dtpr exp)
539: then (If (and tpl-dontshow-tpl (memq (car exp)
540: '(tpl-err-tpl-fcn
541: tpl-funcall-evalhook
542: tpl-do-funcallhook)))
543: then (setq forget-this t)))
544: (If (and remember (not forget-this))
545: then (setq res (cons (car xx) res)))
546: (If (dtpr exp)
547: then (If (and tpl-dontshow-tpl
548: (eq (car exp) 'tpl-break-function))
549: then (setq remember t))))
550:
551: (setq tpl-top-framelist nil)))
552:
553: (defun tpl-getframelist nil
554: (let ((frames)
555: temp)
556: (If *rset
557: then ; Getting the first few frames is tricky because
558: ; the frames disappear quickly.
559: (setq temp (evalframe nil)) ; call to setq
560: (setq temp (evalframe (evalframe-pdl temp)))
561: (do ((xx (list (evalframe (evalframe-pdl temp)))
562: (cons (evalframe (evalframe-pdl (car xx))) xx)))
563: ((null (car xx))
564: (cdr xx))))))
565:
566:
567: (defun tpl-printframelist (printdown vals count)
568: (If (null vals)
569: then (If printdown
570: then (msg "*** bottom ***" N)
571: else (msg "*** top ***" N))
572: elseif (= 0 count)
573: then (msg "... " (length vals) " more ..." N)
574: else (If (not printdown)
575: then (tpl-printframelist printdown (cdr vals) (1- count)))
576: (let ((prinlevel tpl-prinlevel)
577: (prinlength tpl-prinlength))
578: ; tag apply type forms with 'a:'
579: (if (eq 'apply (evalframe-type (car vals)))
580: then (msg "a:"))
581: (print (evalframe-expr (car vals)))
582: (terpr))
583: (If printdown
584: then (tpl-printframelist printdown (cdr vals) (1- count)))))
585:
586:
587: (defun tpl-zoom nil
588: (tpl-printframelist nil tpl-top-framelist 4)
589: (msg "// current \\\\" N)
590: (tpl-printframelist t tpl-bot-framelist 4))
591:
592:
593:
594: (defmacro errdesc-class (err) `(car ,err))
595: (defmacro errdesc-id (err) `(cadr ,err))
596: (defmacro errdesc-contp (err) `(caddr ,err))
597: (defmacro errdesc-descr (err) `(cdddr ,err))
598:
599: ;--- error handler
600: ;
601:
602: (defun tpl-break-function (reason)
603: (do ((tpl-fcn-in-eval (most-recent-given))
604: (tpl-level reason)
605: (tpl-continuab)
606: (tpl-break-level (1+ tpl-break-level))
607: ;(tpl-step-enable)
608: (prompt)
609: (do-retry nil nil)
610: (retry-value)
611: (retv 'contbreak)
612: (piport nil)
613: (eof-form (ncons nil)))
614: (nil)
615: (If (eq retv 'contbreak)
616: then
617: (If (memq (car reason) '(error derror))
618: then (if (eq (car reason) 'error)
619: then (msg "Error: ")
620: else (msg "DError: "))
621: (patom (car (errdesc-descr (cdr reason))))
622: (mapc #'(lambda (x) (patom " ") (print x))
623: (cdr (errdesc-descr (cdr reason))))
624: (terpr)
625: (msg "Form: " (cdr tpl-fcn-in-eval))
626: elseif (eq 'break (car reason))
627: then (msg "Break: ")
628: (patom (cadr reason))
629: (mapc #'(lambda (x) (patom " ") (print x))
630: (cddr reason)))
631: (terpr)
632: (setq tpl-contuab (or (memq (car reason) '(break derror step))
633: (errdesc-contp (cdr reason))))
634: (setq prompt (If reason
635: then (concat (if (eq (car reason) 'derror)
636: then "d"
637: elseif (eq (car reason) 'step)
638: then "s"
639: else "")
640: (If tpl-contuab then "c" else "")
641: "{"
642: tpl-break-level
643: "} ")
644: else "=> "))
645: elseif (eq retv 'reset)
646: then (tpl-throw 'reset)
647: elseif (eq retv 'poplevel)
648: then (tpl-throw 'contbreak)
649: elseif (eq retv 'popretry)
650: then (tpl-throw `(retry ,tpl-fcn-in-eval))
651: elseif (dtpr retv)
652: then (If (eq 'retbreak (car retv))
653: then (If (eq 'error (car reason))
654: then (return (cdr retv)) ; return from error
655: else (return (cadr retv)))
656: else (If (eq 'retry (car retv))
657: then (setq do-retry t
658: retry-value (cadr retv)))))
659: (setq retv
660: (tpl-catch
661: (do ()
662: (nil)
663: (If (null do-retry)
664: then (do-one-transaction nil prompt eof-form)
665: else (do-one-transaction retry-value prompt nil))
666: (setq do-retry nil)
667: nil)))))
668:
669: ;--- tpl-err-tpl-fcn
670: ; attached to ER%tpl, the error will return to top level
671: ; generic error handler
672: ;
673: (defun tpl-err-tpl-fcn (err)
674: (let ((^w nil))
675: (tpl-break-function (cons 'error err))))
676:
677: ;--- tpl-err-all-fcn
678: ; attached to ER%all if (debugging t) is done.
679: ;
680: (defun tpl-err-all-fcn (err)
681: (let ((^w nil))
682: (setq ER%all 'tpl-err-all-fcn)
683: (tpl-break-function (cons 'derror err))))
684:
685: ;-- tpl-command-pop
686: ; pop a break level
687: ;
688: (defun tpl-command-pop (x)
689: (If (= 0 tpl-break-level)
690: then (msg "Already at top level " N)
691: else (tpl-throw 'poplevel)))
692:
693:
694:
695: (defun tpl-command-ret (x)
696: (If tpl-contuab
697: then (tpl-throw (list 'retbreak (eval (cadr x))))
698: else (msg "Can't return at this point" N)))
699:
700: ;--- tpl-command-redo
701: ; see documentatio above for a list of the various things this accepts
702: ;
703: (defun tpl-command-redo (x)
704: (setq x (cdr x))
705: (If (null x)
706: then (tpl-redo-by-count 1)
707: elseif (fixp (car x))
708: then (If (< (car x) 0)
709: then (tpl-redo-by-count (- (car x)))
710: else (If (not (< (car x) tpl-history-count))
711: then (msg "There aren't that many commands " N)
712: else (tpl-redo-by-count (- tpl-history-count (car x)))))
713: else (tpl-redo-by-car x)))
714:
715:
716: ;--- tpl-redo-by-car :: locate command to do by the car of the command
717: ;
718: (defun tpl-redo-by-car (x)
719: (let ((command (car x))
720: (substringp (If (eq (cadr x) '*) thenret)))
721: (If substringp
722: then (If (not (symbolp command))
723: then (msg "must give a symbol before *" N)
724: else (let* ((string (get_pname command))
725: (len (pntlen string)))
726: (do ((xx (tpl-next-user-in-history given-history)
727: (tpl-next-user-in-history (cdr xx)))
728: (pos))
729: ((null xx)
730: (msg "Can't find a match" N))
731: (If (and (dtpr (cdar xx))
732: (symbolp (setq pos (cadar xx))))
733: then (If (equal (substring pos 1 len)
734: string)
735: then (tpl-throw
736: `(retry ,(car xx))))))))
737: else (do ((xx (tpl-next-user-in-history given-history)
738: (tpl-next-user-in-history (cdr xx)))
739: (pos))
740: ((null xx)
741: (msg "Can't find a match" N))
742: (If (and (dtpr (cdar xx))
743: (symbolp (setq pos (cadar xx))))
744: then (If (eq pos command)
745: then (tpl-throw
746: `(retry ,(car xx)))))))))
747:
748: ;--- tpl-redo-by-count :: redo n'th previous input
749: ; n>=0. if n=0, then redo last.
750: ;
751: (defun tpl-redo-by-count (n)
752: (do ((xx n (1- xx))
753: (list (tpl-next-user-in-history given-history)
754: (tpl-next-user-in-history (cdr list))))
755: ((or (not (> xx 0)) (null list))
756: (If (null list)
757: then (msg "There aren't that many commands " N)
758: else (tpl-throw `(retry ,(car list)))))))
759:
760:
761: '(defun tpl-next-user-in-history (hlist)
762: (do ((histlist hlist (cdr histlist)))
763: ((or (null histlist)
764: (eq 'user (caar histlist)))
765: histlist)))
766:
767: (defun tpl-next-user-in-history (hlist)
768: hlist)
769:
770: ;--- tpl-command-prt
771: ; pop and retry command which failed this time
772: ;
773: (defun tpl-command-prt (x)
774: (tpl-throw 'popretry))
775:
776:
777: ;--- tpl-command-history
778: ;
779: (defun tpl-command-history (x)
780: (let (show-res)
781: (If (memq 'r (cdr x))
782: then (setq show-res t))
783: (tpl-command-his-rec tpl-history-show tpl-history-count show-res
784: given-history res-history)))
785:
786: (defun tpl-command-his-rec (count current show-res hlist rhlist)
787: (If (and hlist (> count 0))
788: then (tpl-command-his-rec (1- count) (1- current) show-res
789: (cdr hlist) (cdr rhlist)))
790: (If hlist
791: then
792: (let ((prinlevel tpl-prinlevel)
793: (prinlength tpl-prinlength))
794: (msg current ": ") (tpl-history-form-print (car hlist))
795: (terpr)
796: (If show-res
797: then (msg "% " current ": " (car rhlist) N)))))
798:
799:
800: (defun tpl-command-reset (x)
801: (tpl-throw 'reset))
802:
803: (defun tpl-yorn (message)
804: (drain piport)
805: (msg message)
806: (let ((ch (tyi)))
807: (drain piport)
808: (eq #/y ch)))
809:
810:
811: ;--- tpl-*break :: handle breaks
812: ; when tpl starts, this is put on *break's function cell
813: ;
814: (defun tpl-*break (pred message)
815: (let ((^w nil))
816: (cond (pred (tpl-break-function (list 'break message))))))
817:
818:
819:
820: ;; stepping code
821: (defun tpl-command-step (args)
822: (setq tpl-step-enable t
823: tpl-step-print nil
824: tpl-step-triggers nil
825: tpl-step-countdown 0)
826: (if (memq t args)
827: then (setq tpl-step-print t)
828: else (setq tpl-step-triggers args))
829: (*rset t)
830: (setq evalhook nil funcallhook nil)
831: (sstatus translink nil)
832: (sstatus evalhook t))
833:
834:
835: (defun tpl-command-stepoff (args)
836: ;; we don't turn off status evalhook because then an
837: ;; evalhook would cause an error (this probably should be fixed)
838: (sstatus evalhook nil)
839: (setq tpl-step-enable nil
840: tpl-step-print nil))
841:
842: (defun tpl-command-sc (args)
843: ;; continue after step
844: (if (cdr args)
845: then (if (fixp (cadr args))
846: then (setq tpl-step-countdown (cadr args))
847: else (setq tpl-step-countdown 100000)))
848: (tpl-throw `(retbreak ,tpl-step-enable)))
849:
850: (defun tpl-do-evalhook (arg)
851: ;; arg is the form to eval
852: (tpl-funcall-evalhook arg 'eval))
853:
854: (defun tpl-do-funcallhook (&rest args)
855: ;; this is called with n args.
856: ;; args 0 to n-2 are the actual arguments.
857: ;; arg n-1 is the function to call (notice that it comes at the end)
858: ; the list in 'args' is a fresh list, we can clobber it
859: (let (name)
860: ; strip the last cons cells from the args list
861: ; there will be at least one element in the list,
862: ; namely the function being called
863: (if (cdr args)
864: then ; case of at least one argument
865: (do ((xx args (cdr xx)))
866: ((null (cddr xx))
867: (setq name (cadr xx))
868: (setf (cdr xx) nil)))
869: else ; case of zero arguments
870: (setq name (car args) args nil))
871:
872: (tpl-funcall-evalhook (cons name args) 'funcall)))
873:
874:
875: (defun tpl-funcall-evalhook (fform type)
876: ;; function called after an evalhook or funclalhook is triggered
877: ;; The form is an s-expression to be evaluated
878: ;; The type is either 'eval' or 'funcall',
879: ;; eval meaning that the form is something to be eval'ed
880: ;; funcall meaning that the car of the form is the function to
881: ;; be applied to the list which is the cdr [actually the cdr
882: ;; is spread out on the stack and a 'funcall' is done, but this
883: ;; is what apply does anyway.
884: ;; Upon entry we optionally print, optionally break, optionally continue
885: ;; stepping, and then optionally print the value
886: ;; We print if tpl-step-print is t
887: ;; We break if tpl-step-print is t and tpl-step-countdown is <= 0
888: ;; We continue stepping if tpl-step-enable is t
889: ;; We print the result if we continued stepping.
890: ;;
891: ;; note: if it were possible to call evalhook and funcallhook if
892: ;; (status evalhook) were nil, then we could make ?soff turn off
893: ;; (status evalhook), making things run faster [as it is now, stepping
894: ;; continues until we reach top-level again. We just don't print
895: ;; things out]
896: ;;
897: (let ((tpl-step-reclevel (1+ tpl-step-reclevel)))
898: (if (and (not tpl-step-print)
899: (dtpr fform)
900: (memq (car fform) tpl-step-triggers))
901: then (setq tpl-step-print t))
902: (if tpl-step-print
903: then (tpl-step-printform tpl-step-reclevel type fform)
904: (if (<& tpl-step-countdown 1)
905: then (setq tpl-step-enable (tpl-break-function '(step)))
906: else (setq tpl-step-countdown (1- tpl-step-countdown))))
907: (if tpl-step-enable
908: then (let ((newval))
909: (setq newval (if (eq type 'eval)
910: then (tpl-evalhook fform
911: 'tpl-do-evalhook
912: 'tpl-do-funcallhook)
913: else (tpl-funcallhook fform
914: 'tpl-do-funcallhook
915: 'tpl-do-evalhook)))
916: (if tpl-step-print
917: then (tpl-step-printform tpl-step-reclevel 'r newval))
918: newval)
919: else (if (eq type 'eval)
920: then (tpl-evalhook fform nil nil)
921: else (tpl-funcallhook fform nil nil)))))
922:
923:
924: (defun tpl-step-printform (indent key form)
925: (printblanks indent nil)
926: (let ((prinlevel 4) (prinlength 4))
927: (msg (if (eq key 'r)
928: then '"=="
929: elseif (eq key 'funcall)
930: then 'f:
931: elseif (eq key 'eval)
932: then 'e:
933: else key)
934: form N)))
935:
936: ; in order to use this: (setq user-top-level 'tpl)
937:
938:
939: (putprop 'tpl t 'version)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.