Annotation of 42BSD/ucb/lisp/franz/frame.c, revision 1.1

1.1     ! root        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: }
        !           303: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.