1: #ifndef lint
   2: static char *rcsid =
   3:    "$Header: frame.c,v 1.2 83/05/07 23:46:38 jkf Exp $";
   4: #endif
   5: 
   6: /*					-[Sat May  7 22:27:57 1983 by jkf]-
   7:  * 	frame.c				$Locker: sklower $
   8:  * non local goto handlers
   9:  *
  10:  * (c) copyright 1982, Regents of the University of California
  11:  */
  12: 
  13: 
  14: #include "global.h"
  15: #include "frame.h"
  16: 
  17: /*
  18:  * This is a collection of routines for manipulating evaluation frames.
  19:  * Such frames are generated to mark the state of execution at a certain
  20:  * spot.  They are created upon entry to prog, do, catch, errset and
  21:  * other misc. functions (such as eval when in *rset mode).
  22:  *
  23:  * As described in h/frame.h, each frame is identified by a class, which
  24:  * says who created the frame.  The global variable errp points to the
  25:  * first (newest) frame on the stack.
  26:  * The standard way to create a frame is to say
  27:  *
  28:  *   errp = Pushframe(class,arg1,arg2);	 /* create and link in new
  29:  *   					    frame of give class * /
  30:  *
  31:  * poping the frame must be done explicity if the routine was not exited by
  32:  * a non-local goto.  This is done by
  33:  *   errp = Popframe();
  34:  *
  35:  * When a frame is created, it marks the current state on the runtime stack.
  36:  * Execution will continues after the Pushframe call with the value of the
  37:  * global variable 'retval' set to 0.  Some time later control may be thrown
  38:  * up the stack and it will seem that Pushframe returned again.  This time
  39:  * retval will contain a non-zero value indicating what caused the non-local
  40:  * jump.  retval will have one of the values from C_???? in h/frame.h .
  41:  * It will not have just of the C_???? values, it will only have a value
  42:  * which makes sense. For example, coming out of a Pushframe(F_CATCH,tag,nil);
  43:  * retval will either be 0 (initially) or C_THROW, [and in addition it will
  44:  * already have been determined that the tag of the catch matches the tag
  45:  * being thrown, [[ this does not apply to GO's and PROG tags]] ].
  46:  *
  47:  * In doing throws, goto's, returns, or errors up the stack we are always
  48:  * conscious of the possiblity of unwind-protect sitting between where
  49:  * control starts and where it wants to get.  Thus it may be necessary
  50:  * to save the state of the non-local jump, give control to the unwind-protect
  51:  * and have it continue the non-local jump.
  52:  */
  53: 
  54:  /*
  55:   * Inonlocalgo(class, arg1, arg2) :: do a general non-local goto.
  56:   *    	class - one of the C_???? in h/frame.h
  57:   *	arg1 - tag in C_THROW, C_GO; value in C_RETURN
  58:   *	arg2 - value in C_THROW;
  59:   *  this handles GO's, THROW's, RETURN's  but not errors, which have more
  60:   * state to throw and a lot of different things to do if there is no one
  61:   * to catch the error.
  62:   *
  63:   * This routine never returns.
  64:   */
  65: 
  66: Inonlocalgo(class, arg1, arg2)
  67: lispval arg1,arg2;
  68: {
  69:     struct frame *uwpframe, *Inlthrow();
  70:     lispval handy;
  71: 
  72:     /*
  73:      * scan for something to match 'class', return if nothing found, or
  74:      * if we must first handle an unwind protect.
  75:      */
  76:     while( uwpframe = Inlthrow(class,arg1,arg2) )
  77:     {
  78:     /* build error frame description to be use to continue this throw */
  79:     protect(lispretval = handy = newdot());
  80:         handy->d.car = Veruwpt;
  81:     handy = handy->d.cdr = newdot();
  82:     handy->d.car = inewint(class);      /* remember type */
  83:     handy = handy->d.cdr = newdot();
  84:     handy->d.car = arg1;
  85:     handy = handy->d.cdr = newdot();
  86:     handy->d.car = arg2;
  87:     retval = C_THROW;
  88:     Iretfromfr(uwpframe);
  89:     /* NOT REACHED */
  90:     }
  91: 
  92:     /*
  93:      * nothing to go to, signal the appropriate error
  94:      */
  95: 
  96:     switch(class)
  97:     {
  98:     case C_GO: errorh1(Vermisc, "No prog to go to with this tag ",
  99:                    nil,FALSE,0,arg1);
 100:         /* NOT REACHED */
 101: 
 102:     case C_RET: errorh(Vermisc, "No prog to return from", nil, FALSE, 0);
 103:         /* NOT REACHED */
 104: 
 105:     case C_THROW: errorh1(Vermisc, "No catch for this tag ", nil, FALSE , 0,
 106:                   arg1);
 107:         /* NOT REACHED */
 108:     default: error("Internal  Inonlocalgoto error" ,FALSE);
 109:         /* NOT REACHED */
 110:     }
 111: }
 112: 
 113: /*
 114:  * Inlthrow(class,arg1,arg2) :: look up the stack for a form to handle
 115:  * a value of 'class' being thrown.  If found, do the throw.  If an
 116:  * unwind-protect must be done, then return a pointer to that frame
 117:  * first.  If there is nothing to catch this throw, we return 0.
 118:  */
 119: 
 120: struct frame *
 121: Inlthrow(class, arg1, arg2)
 122: lispval arg1, arg2;
 123: {
 124:     struct frame *uwpframe = (struct frame *)0;
 125:     struct frame *curp;
 126:     int pass = 1;
 127: 
 128:     restart:
 129:     for(curp = errp; curp != (struct frame *) 0; curp = curp->olderrp)
 130:     {
 131:         switch(curp->class)
 132:         {
 133:         case F_PROG: if(class == C_RET || class == C_GO)
 134:              {
 135:                 if(pass == 2) return(uwpframe);
 136:                 else
 137:                 {
 138:                 lispretval = arg1;
 139:                 retval = class;
 140:                 Iretfromfr(curp);
 141:                 /* NOT REACHED */
 142:                 }
 143:               }
 144:               break;
 145: 
 146:         case F_CATCH: if((pass == 1) && (curp->larg1 == Veruwpt))
 147:               {
 148:                 uwpframe = curp;
 149:                 pass = 2;
 150:                 goto restart;
 151:               }
 152:               else if(class == C_THROW
 153:                     && matchtags(arg1,curp->larg1))
 154:               {
 155:                 if(pass == 2) return(uwpframe);
 156:                 else
 157:                 {
 158:                 lispretval = arg2;  /* value thrown */
 159:                 retval = class;
 160:                 Iretfromfr(curp);
 161:                 /* NOT REACHED */
 162:                 }
 163:                }
 164:                break;
 165: 
 166:         case F_RESET:  if(class == C_RESET)
 167:                {
 168:                 if(pass == 2) return(uwpframe);
 169:                 else
 170:                 {
 171:                     retval = class;
 172:                     Iretfromfr(curp);
 173:                     /* NOT REACHED */
 174:                 }
 175:                 }
 176:                 break;
 177: 
 178:         }
 179:     }
 180:     return((struct frame *)0);   /* nobody wants it */
 181: }
 182: 
 183: 
 184: Iretfromfr(fram)
 185: register struct frame *fram;
 186: {
 187:     xpopnames(fram->svbnp);
 188:     qretfromfr();   /* modified in sed script to point to real function */
 189:     /* NOT REACHED */
 190: }
 191: 
 192: /* matchtags :: return TRUE if there is any atom in common between the
 193:  * two tags.  Either tag may be an atom or an list of atoms.
 194:  */
 195: matchtags(tag1,tag2)
 196: lispval tag1, tag2;
 197: {
 198:     int repeat1 = FALSE;
 199:     int repeat2 = FALSE;
 200:     lispval temp1 = tag1;
 201:     lispval temp2 = tag2;
 202:     lispval t1,t2;
 203: 
 204:     if(TYPE(tag1) == ATOM)
 205:     {
 206:     t1 = tag1;
 207:     }
 208:     else {
 209:     t1 = tag1->d.car;
 210:     repeat1 = TRUE;
 211:     }
 212: 
 213:     if(TYPE(tag2) == ATOM)
 214:     {
 215:     t2 = tag2;
 216:     }
 217:     else {
 218:     t2 = tag2->d.car;
 219:     repeat2 = TRUE;
 220:     }
 221: 
 222: loop:
 223:     if(t1 == t2) return(TRUE);
 224:     if(repeat2)
 225:     {
 226:     if((temp2 = temp2->d.cdr) != nil)
 227:     {
 228:         t2 = temp2->d.car;
 229:         goto loop;
 230:     }
 231:     }
 232: 
 233:     if(repeat1)
 234:     {
 235:         if((temp1 = temp1->d.cdr) != nil)
 236:     {
 237:         t1 = temp1->d.car;
 238:         if(repeat2)
 239:         {
 240:             temp2 = tag2;
 241:         t2 = temp2->d.car;
 242:         goto loop;
 243:         }
 244:         else t2 = tag2;
 245:         goto loop;
 246:      }
 247:     }
 248:     return(FALSE);
 249: }
 250: 
 251: /*
 252:  * framedump :: debugging routine to print the contents of the error
 253:  * frame
 254:  *
 255:  */
 256: lispval
 257: Lframedump()
 258: {
 259:     struct frame *curp;
 260: 
 261:     printf("Frame dump\n");
 262:     for(curp = errp ; curp != (struct frame *)0 ; curp=curp->olderrp)
 263:     {
 264:     printf("at %x is ",curp);
 265: 
 266:     switch(curp->class) {
 267:     case F_PROG: printf(" prog\n");
 268:              break;
 269: 
 270:     case F_CATCH:printf(" catching ");
 271:              printr(curp->larg1,stdout);
 272:              putchar('\n');
 273:              break;
 274: 
 275:     case F_RESET:printf(" reset \n");
 276:              break;
 277: 
 278:     case F_EVAL: printf(" eval: ");
 279:              printr(curp->larg1,stdout);
 280:              putchar('\n');
 281:              break;
 282: 
 283:     case F_FUNCALL: printf(" funcall: ");
 284:              printr(curp->larg1,stdout);
 285:              putchar('\n');
 286:              break;
 287: 
 288:     case F_TO_FORT: printf(" calling fortran:\n");
 289:              break;
 290: 
 291:     case F_TO_LISP: printf(" fortran calling lisp:\n");
 292:              break;
 293: 
 294: 
 295:     default:
 296:              printf(" unknown: %d \n",curp->class);
 297:     }
 298:     fflush(stdout);
 299:     }
 300:     printf("End of stack\n");
 301:     return(nil);
 302: }

Defined functions

Inlthrow defined in line 120; used 2 times
Iretfromfr defined in line 184; used 7 times
Lframedump defined in line 256; never used
matchtags defined in line 195; used 1 times

Defined variables

rcsid defined in line 2; never used
Last modified: 1985-08-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1304
Valid CSS Valid XHTML 1.0 Strict