(FILECREATED "31-Dec-85 14:18:56" {IVY}<HTHOMPSON>LISP>SIGNALS>SIGNAL.;28 16427 changes to: (FNS Signal) previous date: " 1-Aug-85 22:17:59" {IVY}<HTHOMPSON>LISP>SIGNALS>SIGNAL.;27) (* Copyright (c) 1984, 1985 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT SIGNALCOMS) (RPAQQ SIGNALCOMS ((FNS \EnableTran \EnableQuitTran Signal \EnablePPMacro) (PROP CLISPWORD ENABLE EXIT GOTO REJECT SRESUME enable exit goto reject sresume) (FNS ST TestSignals) (FNS \NewErrorx2 \NewOldFault1 MakeErrorsSignals MakeErrorsErrorsAgain) (P (MOVD? '\HELPDLBLOCK/ERRORX2 '\OldErrorx2) (MOVD? 'OLDFAULT1 '\OldOldFault1)) (RECORDS LispError) (E (SETQ $PF PRETTYFLG) (SETQ PRETTYFLG NIL)) (ALISTS (PRETTYPRINTMACROS ENABLE enable)) (E (SETQ PRETTYFLG $PF)))) (DEFINEQ (\EnableTran [LAMBDA (form) (* ht: "25-Sep-84 23:10") (PROG (catches finals (p (form::1)) sig tran it unwind any) (catches←(while p::1 until p:3= '-> collect (if p:2~= '=> then (HELP "Missing 'sig =>" form)) (if (U-CASE p:1)= 'ANY then (pop p) (pop p) (any←(while p::1 until (OR p:2= '=> p:3= '->) collect (pop p))) (GO $$LP)) (<sig←(if (LITATOM p:1) then (pop p) else (HELP "Expected atom before =>")) !(first (pop p) while p::1 until (OR p:2= '=> p:3= '->) collect (pop p)) >))) (it←(pop p)) (finals←(while p::2 collect (if p:2~= '-> then (HELP "Missing 'label ->'" form)) (if (U-CASE p:1)= 'UNWIND then (pop p) (pop p) (unwind←(while p until p:2= '-> collect (pop p))) (GO $$LP)) (<(if (LITATOM p:1) then (pop p) else (HELP "Expected atom before ->")) !(first (pop p) while p until p:2= '-> collect (pop p)) >))) (CLISPTRAN form tran←(DWIMIFY [BQUOTE (PROG ($SignalType$ $SignalArg$ result [$SignalCatcher$ (FUNCTION (LAMBDA (type arg) (PROG NIL (SELECTQ type ,. catches , (if any then (if (CDR any) then (CONS 'PROGN any) else (CAR any] $Exit$) (DECLARE (SPECVARS $SignalType$ $SignalArg$ $SignalCatcher$ $Exit$)) (RETURN (COND ((SETQ result (NLSETQ , it)) (CAR result)) (T (SELECTQ $Exit$ ,. finals (NIL ,. unwind (ERROR!)) (T) (SHOULDNT] T)) (RETURN tran]) (\EnableQuitTran [LAMBDA (form) (* ht: "22-JAN-83 11:11") (PROG (tran) (CLISPTRAN form tran←(DWIMIFY (SELECTQ (U-CASE form:1) (GOTO (if ~(AND form:2 (LITATOM form:2)) then (HELP "Must have non-NIL atomic exit label" form:2) else <(QUOTE RETURN) (KWOTE form:2) >)) (EXIT (if form::1 then (printout T "exit should not have args - args ignored" T)) (QUOTE (RETURN T))) [SRESUME (if ~(form::1) then (HELP "sresume must have a value")) (BQUOTE (RETURN (LIST , (IF (CDDR form) THEN (CONS (QUOTE PROGN) (CDR form)) ELSE (CADR form] (REJECT (if form::1 then (printout T "reject should not have args - args ignored" T)) (QUOTE (RETURN))) (SHOULDNT)) T)) (RETURN tran]) (Signal [LAMBDA (type arg) (* ht: "31-Dec-85 14:18") (PROG (frame val) LP (if frame←(STKSCAN '$SignalCatcher$ (STKNTH 1 frame frame) frame) then (SELECTQ (val←(APPLY* (STKARG '$SignalCatcher$ frame) type arg)) (NIL (* reject or uncaught at that frame, try higher) (GO LP)) (if (LISTP val) then (* resume up above) (RELSTK frame) (RETURN val:1) else (* exit up top) (SETSTKARG '$SignalType$ frame type) (SETSTKARG '$SignalArg$ frame arg) (SETSTKARG '$Exit$ frame val) (RELSTK frame) (ERROR!))) else (RELSTK frame) (if type= 'LispError then (if arg:ePntMsg then (ERRORMESS arg:eMess)) (if arg:eBkChk then (RETEVAL 'Signal (LIST 'RETFROM arg:ePos (if arg:eType then (* from an ordinary error) (\HELPDLBLOCK/ERRORX3 arg:eFn arg:eType arg:ePos) else (* from FAULTEVAL/APPLY) (CONS 'BREAK1 arg:eFn)) T)) else (RELSTK arg:ePos) (ERROR!)) else (RETURN (HELP "Uncaught signal" (CONS type arg]) (\EnablePPMacro [LAMBDA (form) (* ht: "18-JAN-83 15:28") (PROG ((pos (POSITION)) npos) (printout NIL "(" .FONT CLISPFONT (pop form) .FONT DEFAULTFONT) [while (AND form::1 form:2=(QUOTE =>)) do (printout NIL .TAB (pos+5) .FONT FONT5 (pop form) .FONT CLISPFONT " => " # (npos←(POSITION)) .FONT DEFAULTFONT .PPFTL (first (pop form) while form::1 until (OR form:2=(QUOTE =>) form:3=(QUOTE ->)) collect (pop form] (printout NIL .TAB (pos+3) .PPF (pop form)) [while form do (printout NIL .TAB (pos+5) .FONT FONT5 (pop form) .FONT CLISPFONT " -> " # (npos←(POSITION)) .FONT DEFAULTFONT .PPFTL (first (pop form) while form until form:2=(QUOTE ->) collect (pop form] (printout NIL ")"]) ) (PUTPROPS ENABLE CLISPWORD (\EnableTran . enable)) (PUTPROPS EXIT CLISPWORD (\EnableQuitTran . exit)) (PUTPROPS GOTO CLISPWORD (\EnableQuitTran . goto)) (PUTPROPS REJECT CLISPWORD (\EnableQuitTran . reject)) (PUTPROPS SRESUME CLISPWORD (\EnableQuitTran . sresume)) (PUTPROPS enable CLISPWORD (\EnableTran . enable)) (PUTPROPS exit CLISPWORD (\EnableQuitTran . exit)) (PUTPROPS goto CLISPWORD (\EnableQuitTran . goto)) (PUTPROPS reject CLISPWORD (\EnableQuitTran . reject)) (PUTPROPS sresume CLISPWORD (\EnableQuitTran . sresume)) (DEFINEQ (ST [LAMBDA NIL (* ht: " 8-JUN-83 14:15") (enable s1 => (PRINT "s1 caught" T) (goto s1) s2 => (PRINT "s2 caught") (sresume 37) s3 => (PRINT "s3 caught") (reject) s4 => (PRINT "s4 caught") (exit) LispError => (printout T "lisp error " # (ERRORMESS arg:eMess) T) (exit) any => (printout T type " caught by any" T) (exit) (TestSignals) s1 -> (PRINT "s1 unwound") unwind -> (PRINT "unwinding"))]) (TestSignals [LAMBDA NIL (* ht: " 1-Aug-85 22:17") (printout T T (SELECTQ (PROGN (printout T T ">") (READ)) (1 (Signal 's1 1)) (2 (Signal 's2 2)) (3 (Signal 's3 3)) (4 (Signal 's4)) (5 (Signal 'foo 5)) (6 (LET ((A)) X←1+A) 6) (7 X← (CONS 'A BBAABB) 7) (8 (UNDEFINEDITRUST) 8) (9 (APPLY* 'AlsoUndefined 3 2) 9) (10 (NLSETQ (UNDEFINEDITRUST)) 8) (11 (NLSETQ (APPLY* 'AlsoUndefined 3 2)) 9) 12) '←]) ) (DEFINEQ (\NewErrorx2 [LAMBDA (ERRORMESS ERRORPOS) (* ht: " 1-Aug-85 21:37") (* ERRORMESS is the error message, ERRORPOS is the stack position of the last function before any error function) (* Henry%'s kludged up version for Signal world correct as of Intermezzo release) (SELECTQ (SYSTEMTYPE) ((TENEX TOPS20) (* It is hard for the 10 SKIPSEPRS subr to return NIL on EOF, so we handle it here prior to any other processing, since this is technically not an error.) (AND 16=ERRORMESS:1 (STKNAME ERRORPOS)= 'SKIPSEPRS (RETFROM ERRORPOS NIL T))) NIL) (PROG (EX2X EX2Y EX2FN (PRINTMSG T) BREAKCHK) (* PRINTMSG is initially T because if no errorset is found, i.e. error occurs in typein a top level, the message is to be printed) (BREAKCHK←(BREAKCHECK ERRORPOS ERRORMESS:1)) (if (AND EX2X←(FASSOC ERRORMESS:1 ERRORTYPELST) EX2X←(EVAL EX2X:2)) then (* This is an attempt at providing the user with a way of specifying treatment of certain error conditions. The error number is looked up on ERRORTYPELST and if found, CADR is evaluated. If this produces a non-nil value, the function causing the error is reevaluated with the result of the evaluation substituted for the offender, a la the alt-mode command. (If Alice fixes the call to ERRORX2 so that they all continue, e.g. INFILE, RPLACA, etc. then we can take out the RETEVAL.) Note of course that the user can always (QUOTE take) over%' by simply having the form on ERRORMESS, ERRORPOS, to a RETEVAL. In order to make this feature more convenient to user, ERRORMESS and BREAKCHK are SPECVARS) (RETAPPLY ERRORPOS (STKNAME ERRORPOS) (SUBST EX2X ERRORMESS:2 (STKARGS ERRORPOS)) T)) (SELECTQ ERRORMESS:1 (16 (* END OF FILE) (if (OPENP ERRORMESS:2) then (EOFCLOSEF ERRORMESS:2))) [26 (* Hash array full. When PUTHASH is fixed in all implementations so that it calls HASHOVERFLOW directly, then special treatment here can be removed.) (if (LISTP ERRORMESS:2) then (RETURN (PROG1 (HASHOVERFLOW ERRORMESS:2) (RELSTK ERRORPOS] (43 (* User break) (if EX2X←(FASSOC ERRORMESS:2 USERINTERRUPTS) then [RETEVAL 'ERRORX (SUBPAIR '(ERRORPOS EXP) <ERRORPOS EX2X:2> '(OR (ERSETQ (RETFROM ERRORPOS EXP T)) (PROGN (RELSTK ERRORPOS) (ERROR!)))] (* causes a return to the functi at errorpos, with (CADR EX2X) evaluated as of ERRORX) else (ERROR '"undefined user interrupt" ERRORMESS:2))) NIL) (EX2FN←(STKNAME ERRORPOS)) (if EX2X←(FNTYP EX2FN) then EX2X←[BQUOTE (Signal 'LispError , (KWOTE (create LispError eMess ← ERRORMESS eFn ← EX2FN eType ← EX2X ePos ← ERRORPOS eBkChk ← BREAKCHK ePntMsg ← PRINTMSG] else (* the realstknth in errorx should take care of skipping over *PROG*LAM and BLOCK frames) (SHOULDNT)) (RETEVAL 'ERRORX < 'RETFROM ERRORPOS EX2X T>) (* the reson for calling reteval to do the retfrom, rather than doing it in one operaton is that we want the evaluation of the break expression to take place just below where the error occurs, so thatthe arguments are on the stack, but we want the value returned to be returned as the value of the function causing the error.) ]) (\NewOldFault1 [LAMBDA (FAULTX FAULTARGS FAULTAPPLYFLG FAULTZ) (* ht: " 1-Aug-85 21:37") (* Henry%'s buggered version for SIGNAL - (correct as of Intermezzo release)) (* When DWIM is enabled, and an eror is to occur, DWIM calls FAULT1 speicyfing FAULTZ so that FAULT1 can print out the superexpression and function name.) (PROG ([FAULTPOS (STKNTH -1 (if FAULTAPPLYFLG then 'FAULTAPPLY else 'FAULTEVAL] (FAULTFN FAULTX) ERRORMESS FXF BREAKCHK (PRINTMSG T)) (AND DWIMFLG (ATOM FAULTX) FAULTAPPLYFLG=NIL LASTWORD←FAULTX) (* So user can simply set it by typing $← form. Not much use to reset lastword for functions, and user might want to type editf "()" using his earlier context.) (SETERRORN (if FAULTAPPLYFLG then 46 elseif (ATOM FAULTX) then 44 else 45) FAULTFN) (ERRORMESS←(if (AND (FAULTZ (NOT FAULTAPPLYFLG))) then (* FAULTZ is being passed down as extra arg tacked onto ERRORN until the spec for ERRORN can be changed to allow for it) (APPEND (ERRORN) (CONS FAULTZ)) else (ERRORN))) (if FAULTAPPLYFLG then FAULTX←(MAKEAPPLY FAULTFN FAULTARGS)) (AND LISPXHISTORY (LISPXPUT '*ERROR* FAULTFN)) (BREAKCHK←(BREAKCHECK FAULTPOS)) [FXF←(BQUOTE (Signal 'LispError , (KWOTE (create LispError eMess ← ERRORMESS eFn ←(LIST FAULTX T FAULTFN NIL (LIST (BLIPVAL '*FORM* FAULTPOS))) ePos ← FAULTPOS eBkChk ← BREAKCHK ePntMsg ← PRINTMSG] (RETEVAL (if FAULTAPPLYFLG then 'FAULTAPPLY else 'FAULTEVAL) < 'RETFROM FAULTPOS FXF T>]) (MakeErrorsSignals [LAMBDA NIL (* ht: " 8-JUN-83 14:46") (MOVD? (QUOTE \HELPDLBLOCK/ERRORX2) (QUOTE \OldErrorx2)) (MOVD (QUOTE \NewErrorx2) (QUOTE \HELPDLBLOCK/ERRORX2)) (if (GETD (QUOTE OLDFAULT1)) then (MOVD? (QUOTE OLDFAULT1) (QUOTE \OldOldFault1)) (MOVD (QUOTE \NewOldFault1) (QUOTE OLDFAULT1)) else (PROMPTPRINT "WARNING - FAULT1 no longer lives as OLDFAULT1, can't fix u.b.a and u.d.f.")) "Errors are now signals"]) (MakeErrorsErrorsAgain [LAMBDA NIL (* ht: " 8-JUN-83 14:48") (if (GETD (QUOTE \OldErrorx2)) then (MOVD (QUOTE \OldErrorx2) (QUOTE \HELPDLBLOCK/ERRORX2)) (if (GETD (QUOTE \OldOldFault1)) then (MOVD (QUOTE \OldOldFault1) (QUOTE OLDFAULT1))) else (PROMPTPRINT "Errors were still errors anyway")) "Errors are now errors"]) ) (MOVD? '\HELPDLBLOCK/ERRORX2 '\OldErrorx2) (MOVD? 'OLDFAULT1 '\OldOldFault1) [DECLARE: EVAL@COMPILE (RECORD LispError ((eMess eFn . eType) ePos eBkChk . ePntMsg)) ] (ADDTOVAR PRETTYPRINTMACROS (ENABLE . \EnablePPMacro) (enable . \EnablePPMacro)) (PUTPROPS SIGNAL COPYRIGHT ("Xerox Corporation" 1984 1985)) (DECLARE: DONTCOPY (FILEMAP (NIL (861 6722 (\EnableTran 871 . 3020) (\EnableQuitTran 3022 . 4001) (Signal 4003 . 5651) ( \EnablePPMacro 5653 . 6720)) (7303 8714 (ST 7313 . 7975) (TestSignals 7977 . 8712)) (8715 16067 ( \NewErrorx2 8725 . 12981) (\NewOldFault1 12983 . 15093) (MakeErrorsSignals 15095 . 15632) ( MakeErrorsErrorsAgain 15634 . 16065))))) STOP