The SIGNAL packageHenry ThompsonFile:{ivy}lisp>rpc>signal.bravo, .pressRevised:January 22, 1983 2:13 PMThe file SIGNAL.DCOM implements a first pass at the CEDAR/MESA signal mechanism. It allowssignals to be raised, caught, examined, and resumed or exited. Catch phrases are introduced withthe clisp-word enable; signals are raised with the function Signal.(Signal type arg)Raises a signal of type type. If the signal is resumed, will return with the argument tosresume, - see below. Otherwise will not return.(enable s1 => a1 a2 a3 ... . . . sn => n1 n2 n3 ... form l1 -> la1 la2 ... . . . ln -> ln1 ln2 ...)The double arrow lines above are called catch phrases, the single arrow lines are calledfinish phrases. Evaluates form so as to catch signals s1, ... sn if they are raised during itsevaluation. If e.g. s1 is raised, the forms a1 ... an(the catch phrase for s1) will be evaluated in the context of the call to Signal which raiseds1, with the addition of the fact that the variables type and arg will be locally bound to typeand arg. For a catch phrase to be well formed, all control paths through it must end withone of the following four quit forms:(exit)Causes the stack to unwind back through the enclosing enable form, which is exitedwith value NIL.(sresume form)Returns from the call to Signal with the value of form as the value of that call.(goto label)Causes the stack to unwind back to the enclosing enable form, where the finishphrase for label is evaluated. The value of the last form in the phrase is the valueof the enable. The variables $SignalType$, $SignalArg$, and $Exit$ will be boundto type and arg of the original call to Signal and label respectively, but otherwisethe environment of the call to Signal is lost.(reject)Causes the signal handling process to act as if the catch phrase had not been thereat all.#apXqp $^r [sF- ZC Wr s r!sr UL Tpr. QMtr<LXpr* Gp Fr2D} B Au ? >m <9(t r"89t r trt r6tr51t r83tr7tr t2)rtr E0t r-zpr*N?(%pr"s<HprHtrKQtrtrtr .pr92N =UM2When a signal is raised the stack is scanned upwards for a catch phrase for that signal. Ifnone is found (or if all those found are rejected) an Uncaught Signal break will occur.Otherwise the one of the three other options listed above will occur.There is one signal name which receives special interpretation. A catch phrase with thename any will catch any signal not explicitly caught elsewhere in the enable.There is a special label whose name is unwind, which cannot be gone to and has a specialmeaning. The finish clause for the unwind label will be evaluated as the stack unwindsupwards from a call to Signal to the enable clause which caught it (or to the UserExec ifERROR! is envoked).At the moment the package does use ERROR! and NLSETQ itself to implement the stackunwinding. This means the package interacts correctly with RESETSAVE, but has the unfortunateconsequence that interleaving on the stack of calls to ERRORSET in any of its forms and enableclauses has consequences which are confusing at best.As there are many ways in which the semantics of signals and catchers are much cleaner than thoseof errors and errorsets, it is hoped that at some point a more sophisticated implementation of thesignal mechanism undoing the resetsaves directly and redefining ERRORSET in terms of enablewill be made available.As an interim measure however, a mechanism for turning errors into signals has been provided.The function (MakeErrorsSignals) will arrange that all errors will be converted into a signal withname LispError and argument an instance of the following record:(RECORD LispError (eMess eFn eType . ePos))where eMess is the standard error message pair (for printing with ERRORMESS), eFn the name ofthe function which the old package would have broken, eType its type, and ePos a stack pointer toits frame. If you catch this signal, you should free the stack pointer. If you don't catch it (or catchand reject it), a break will happen, regardless of HELPDEPTH, ERRORSETs, etc. That is,BREAKCHECK is not called or paid attention to. This is the interim price of having the otherbenefits of the signal package, and in practice seems to work quite well. Things from the oldpackage that do still work are ERRORTYPELST, user interrupts, and the various other funnies todo with hash arrays and EOFs which the error code handles.To go back to the old way of life, use (MakeErrorsErrorsAgain).There follows on the next page an toy example of the use of the package, which is in fact includedin the file itself - enjoy!Nfrb:"`)pr_E[EZfprEW;'pr! U$pr%T3M R M4 LXN JA IP5 F$V D U CK A >m? <T ;e@89+ 53* 3(9 2 _ 0t r4 . tr8 -z5) + tr D *r: 'F? $;' " "P>E3(ST [LAMBDA NIL (* ht: "20-JAN-83 21:40") (enable s1 => (PRINT "s1 caught" T) (goto s1) s2 => (PRINT "s2 caught") (sresume 37) s3 => (PRINT "s3 caught") (reject) s4 => (PRINT "s4 caught") (exit) any => (printout T type " caught by any" T) (exit) (TestSignals) s1 -> (PRINT "s1 unwound") unwind -> (PRINT "unwinding"))])(TestSignals [LAMBDA NIL (* ht: "18-JAN-83 16:39") (printout T T(SELECTQ (PROGN (printout T T ">") (READ)) (1 (Signal 's1 1)) (2 (Signal 's2 2)) (3 (Signal 's3 3)) (4 (Signal 's4 4)) (5 (Signal 'foo 5)) 6) '_])Nfr b `> _p ]rurpr2\pr Zurpr2Ypr Wurpr2Upr Tyurpr2Rpr Qquprpr2Opr Ni Lurpr Kaurpr HY F> EQprCprBI" (@(?A(=(<8(:(9027 7e<0 TIMESROMAN  TIMESROMAN  TIMESROMAN  TIMESROMAN TIMESROMAN  TIMESROMAN  Qj/Y6re HTHOMPSONJanuary 22, 1983 2:22 PM