Annotation of 40BSD/cmd/lisp/fex1.c, revision 1.1

1.1     ! root        1: static char *sccsid = "@(#)fex1.c      34.2 11/7/80";
        !             2: 
        !             3: #include "global.h"
        !             4: /* Nprog ****************************************************************/
        !             5: /* This first sets the local variables to nil while saving their old   */
        !             6: /* values on the name stack.  Then, pointers to various things are     */
        !             7: /* saved as this function may be returned to by an "Ngo" or by a       */
        !             8: /* "Lreturn".  At the end is the loop that cycles through the contents */
        !             9: /* of the prog.                                                                */
        !            10: 
        !            11: lispval
        !            12: Nprog() {
        !            13:        int     saveme[SAVSIZE];
        !            14:        register struct nament *mybnp = bnp;
        !            15:        register struct argent *savednp;
        !            16:        register lispval where, temp;
        !            17:        register struct argent *lbot, *np;
        !            18:        struct argent *savedlbot;
        !            19:        struct nament *savedbnp;
        !            20:        struct nament *topbind;
        !            21:        long myerrp; extern long errp;
        !            22: 
        !            23:        savednp = np;
        !            24:        savedlbot = lbot;
        !            25:        savedbnp = bnp;
        !            26:        temp = where = (lbot->val)->d.car;
        !            27:        while (TYPE(temp) == DTPR)
        !            28:        {
        !            29:                temp = where->d.car;
        !            30:                if (TYPE(temp) == ATOM)
        !            31:                        {
        !            32:                        bnp->atm = temp;
        !            33:                        bnp->val = (temp)->a.clb;
        !            34:                        (temp)->a.clb = nil;
        !            35:                        temp = where = where->d.cdr;
        !            36:                        if(bnp++ > bnplim)
        !            37:                                binderr();
        !            38:                        }
        !            39:                else return(CNIL);
        !            40:        }
        !            41:        topbind = bnp;
        !            42:        myerrp = errp;
        !            43:        if (where != nil) return(CNIL);
        !            44:        temp = where = savedlbot->val->d.cdr;
        !            45:        getexit(saveme);
        !            46:        while (retval = setexit()) {
        !            47:                errp = myerrp;
        !            48:                switch (retval) {
        !            49: 
        !            50:                case BRRETN:    resexit(saveme);
        !            51:                                popnames(savedbnp);
        !            52:                                lbot = savedlbot;
        !            53:                                return(contval);
        !            54: 
        !            55:                case BRGOTO:    where = (savedlbot->val)->d.cdr;
        !            56:                                while ((TYPE(where) == DTPR) && (where->d.car != contval))
        !            57:                                        where = where->d.cdr;
        !            58:                                if (where->d.car == contval) {
        !            59:                                        /* This seems wrong - M Marcus
        !            60:                                        resexit(saveme);        */
        !            61:                                        popnames(topbind);
        !            62:                                        lbot = savedlbot;
        !            63:                                        break;
        !            64:                                }
        !            65: 
        !            66:                default:
        !            67:                        resexit(saveme);
        !            68:                        reset(retval);
        !            69: 
        !            70:                }
        !            71:        }
        !            72:        while (TYPE(where) == DTPR)
        !            73:                {
        !            74:                temp = where->d.car;
        !            75:                if((TYPE(temp))!=ATOM) eval(temp);
        !            76:                where = where->d.cdr;
        !            77:                }
        !            78:        resexit(saveme);
        !            79:        return((where == nil) ? nil : CNIL);
        !            80:        }
        !            81: 
        !            82: lispval globtag;
        !            83: /*
        !            84:    Ncatch is now actually *catch , which has the form
        !            85:      (*catch tag form)
        !            86:     tag is evaluated and then the catch entry is set up.
        !            87:       then form is evaluated
        !            88:     finally the catch entry is removed.
        !            89: 
        !            90:     (catch form [tag]) is translated to (*catch 'tag form)
        !            91:      by a macro.
        !            92:  */
        !            93: lispval
        !            94: Ncatch()
        !            95: {
        !            96:        struct  argent  *savednp,*savedlbot;
        !            97:        register lispval where, tag, todo;
        !            98:        register temp;
        !            99:        register struct argent *lbot, *np;
        !           100:        int type;
        !           101: 
        !           102: 
        !           103:        where = lbot->val;
        !           104:        if((TYPE(where))!=DTPR) return(nil);
        !           105:        todo = where->d.cdr->d.car;
        !           106:        tag = eval(where->d.car);
        !           107:        while((TYPE(tag)!=ATOM) && (TYPE(tag) != DTPR))
        !           108:                tag = error("Bad type of tag in *catch.",TRUE);
        !           109:        asm("   pushab  On1");
        !           110:        asm("   pushr   $0x2540");
        !           111:        asm("   subl2   $44,sp");       /* THIS IS A CROCK ....
        !           112:                                           saves current environment
        !           113:                                           for (return) z.B. */
        !           114:        asm("   movc3   $44,_setsav,(sp)");
        !           115:        asm("   pushl   _bnp");
        !           116:        asm("   pushl   r10");
        !           117:        asm("   pushl   $1");
        !           118:        asm("   pushl   _errp");
        !           119:        asm("   movl    sp,_errp");
        !           120:        where = (eval(todo));
        !           121:        asm("   movl    (sp),_errp");
        !           122:        return(where);
        !           123:        asm("On1:ret");
        !           124: }
        !           125: 
        !           126: /* (errset form [flag])  
        !           127:    if present, flag determines if the error message will be printed
        !           128:    if an error reaches the errset.
        !           129:    if no error occurs, errset returns a list of one element, the 
        !           130:     value returned from form.
        !           131:    if an error occurs, nil is usually returned although it could
        !           132:     be non nil if err threw a non nil value 
        !           133:  */
        !           134: 
        !           135: lispval Nerrset()
        !           136: {
        !           137:        register lispval flag,where,todo; /* order important */
        !           138:        register lispval handy = Vlerall;         /* to access this easily */
        !           139:        register struct argent *lbot, *np;
        !           140:        where = lbot->val;
        !           141: 
        !           142:        if(TYPE(where) != DTPR) return(nil);    /* no form */
        !           143: 
        !           144:        todo = where->d.car;            /* form to eval */
        !           145:        flag = where->d.cdr;
        !           146:        if(flag != nil) flag = eval(flag->d.car);       /* tag to tell if er messg */
        !           147:        else flag = tatom;      /* if not present , assume t */
        !           148: 
        !           149:        /* push on a catch frame */
        !           150: 
        !           151:        asm("   pushab  On2");          /* where to jump if error */
        !           152:        asm("   pushr   $0x2540");
        !           153:        asm("   subl2   $44,sp");       /* THIS IS A CROCK ....
        !           154:                                           saves current environment
        !           155:                                           for (return) z.B. */
        !           156:        asm("   movc3   $44,_setsav,(sp)");
        !           157:        asm("   pushl   _bnp");
        !           158:        asm("   pushl   r8");   /* tag , (ER%all)       */
        !           159:        asm("   pushl   r11");          /* flag                 */
        !           160:        asm("   pushl   _errp");        /* link in              */
        !           161:        asm("   movl    sp,_errp");     /*  "                   */
        !           162: 
        !           163:        /* evaluate form, and if ok, listify */
        !           164: 
        !           165:        handy = eval(todo);
        !           166:        asm("   movl    (sp),_errp");   /* unlink this frame    */
        !           167:        protect(handy);                 /* may gc on nxt call   */
        !           168:        (flag = newdot()) ->d.car = handy; /* listify arg */
        !           169: 
        !           170:        return(flag);
        !           171: 
        !           172:        asm("On2: ret");                /* if error occured */
        !           173:        
        !           174: }
        !           175:        
        !           176: /* this was changed from throw to *throw 21nov79
        !           177:    it really should be called Lthrow
        !           178: */
        !           179: Nthrow()
        !           180: {
        !           181:        register lispval todo, where;
        !           182:        lispval globtag,contval;
        !           183:        snpand(2);  /* save register mask */
        !           184:        switch(np-lbot) {
        !           185:        case 0:
        !           186:                protect(nil);
        !           187:        case 1:
        !           188:                protect(nil);
        !           189:        case 2: break;
        !           190:        default:
        !           191:                argerr("throw");
        !           192:        }
        !           193:        globtag = lbot->val;
        !           194:        contval = (lbot+1)->val;
        !           195:        Idothrow(globtag,contval);
        !           196:        error("Uncaught throw",FALSE);
        !           197: }
        !           198: #include "catchfram.h"
        !           199: 
        !           200: Idothrow(tag,value)
        !           201: lispval tag,value;
        !           202: {
        !           203:        typedef struct catchfr *cp;
        !           204:        register cp curp;       /* must be first register */
        !           205:        extern long errp;
        !           206:        extern lispval globtag;
        !           207:        int pass1,founduw;
        !           208:        lispval handy,handy2;
        !           209:        snpand(1);
        !           210: 
        !           211:        globtag = tag;
        !           212:        /*
        !           213:        printf("throw,value ");printr(tag,stdout); printf(" ");
        !           214:        printr(value,stdout); fflush(stdout);
        !           215:        */
        !           216:        pass1 = TRUE;
        !           217:   ps2:
        !           218:        founduw = FALSE;
        !           219: 
        !           220:        for (curp=(cp)errp ; curp != (cp) nil ; curp =curp->link)
        !           221:        {
        !           222:          /*  printf(" lbl: ");printr(curp->labl,stdout);fflush(stdout); */
        !           223:            if(curp->labl == Veruwpt) 
        !           224:            {  founduw = TRUE;
        !           225:               if(!pass1) goto foundit;
        !           226:            }
        !           227:            if(curp->labl == nil || curp->labl == tag) goto foundit;
        !           228:            if(TYPE(curp->labl) == DTPR)
        !           229:            {
        !           230:               for( handy = curp->labl ; handy != nil ; handy = handy->d.cdr)
        !           231:               {
        !           232:                   if(handy->d.car == tag) goto foundit;
        !           233:               }
        !           234:            }
        !           235:        }
        !           236:        return;
        !           237: 
        !           238:           foundit:                     /* restore context at catch */
        !           239:               if(pass1 && founduw)
        !           240:               {   pass1 = FALSE;
        !           241:                   goto ps2;
        !           242:                }
        !           243:                if(founduw)             /* remember the state */
        !           244:                {   protect(handy2 = newdot());
        !           245:                    handy2->d.car = Veruwpt;
        !           246:                    handy = handy2->d.cdr = newdot();
        !           247:                    handy->d.car = tatom;       /* t for throw */
        !           248:                    handy = handy->d.cdr = newdot();
        !           249:                    handy->d.car = tag;
        !           250:                    handy = handy->d.cdr = newdot();
        !           251:                    handy->d.car = value;
        !           252:                    value = handy2;
        !           253:                 /*   printf("Ret uwp: ");printr(value,stdout);fflush(stdout);*/
        !           254:                }
        !           255: 
        !           256:                popnames(curp->svbnp);
        !           257:                errp = (int) curp->link;
        !           258:                /* 
        !           259:                 * return value must go into r7 until after movc3 since
        !           260:                 * a movc3 clobbers r0
        !           261:                 */
        !           262:                asm("   movl    8(ap),r7");   /* return value */
        !           263:                asm("   addl3   $16,r11,sp");
        !           264:                                /* account for current (return) */
        !           265:                asm("   movc3   $44,(sp),_setsav");
        !           266:                asm("   addl2   $44,sp");
        !           267:                asm("   popr    $0x2540");
        !           268:                asm("   movl    r7,r0");
        !           269:                asm("   rsb");
        !           270:                
        !           271: }
        !           272: 
        !           273: 
        !           274: 
        !           275: /* Ngo ******************************************************************/
        !           276: /* First argument only is checked - and must be an atom or evaluate    */
        !           277: /* to one.                                                             */
        !           278: Ngo()
        !           279:        {
        !           280:        contval = (lbot->val)->d.car;
        !           281:        while (TYPE(contval) != ATOM)
        !           282:                {
        !           283:                contval = eval(contval);
        !           284:                while (TYPE(contval) != ATOM) contval = error("GO ARG NOT ATOM",TRUE);
        !           285:                }
        !           286:        reset(BRGOTO);
        !           287:        }
        !           288: 
        !           289: 
        !           290: /* Nreset ***************************************************************/
        !           291: /* All arguments are ignored.  This just returns-from-break to depth 0.        */
        !           292: Nreset()
        !           293:        {
        !           294:        contval = 0;
        !           295:        reset(BRRETB);
        !           296:        }
        !           297: 
        !           298: /* Nresetio *************************************************************/
        !           299: 
        !           300: lispval
        !           301: Nresetio() {
        !           302:        register FILE *p;
        !           303: 
        !           304:        for(p = &_iob[3]; p < _iob + _NFILE; p++) {
        !           305:                if(p->_flag & (_IOWRT | _IOREAD)) fclose(p);
        !           306:                }
        !           307:        return(nil);
        !           308: 
        !           309: }
        !           310: 
        !           311: 
        !           312: /* Nbreak ***************************************************************/
        !           313: /* If first argument is not nil, this is evaluated and printed.  Then  */
        !           314: /* error is called with the "breaking" message.                                */
        !           315: 
        !           316: lispval
        !           317: Nbreak()
        !           318: {
        !           319:        register lispval hold; register FILE *port;
        !           320:        port = okport(Vpoport->a.clb,stdout);
        !           321:        fprintf(port,"Breaking:");
        !           322: 
        !           323:        if ((hold = lbot->val) != nil && ((hold = hold->d.car) != nil))
        !           324:        {
        !           325:                printr(hold,port);
        !           326:        }
        !           327:        putc('\n',port);
        !           328:        dmpport(port);
        !           329:        return(errorh(Verbrk,"",nil,TRUE,0));
        !           330: }
        !           331: 
        !           332: 
        !           333: /* Nexit ****************************************************************/
        !           334: /* Just calls lispend with no message.                                 */
        !           335: Nexit()
        !           336:        {
        !           337:        lispend("");
        !           338:        }
        !           339: 
        !           340: 
        !           341: /* Nsys *****************************************************************/
        !           342: /* Just calls lispend with no message.                                 */
        !           343: 
        !           344: lispval
        !           345: Nsys()
        !           346:        {
        !           347:        lispend("");
        !           348:        }
        !           349: 
        !           350: 
        !           351: 
        !           352: 
        !           353: lispval
        !           354: Ndef() {
        !           355:        register lispval arglist, body, name, form;
        !           356:        snpand(4);
        !           357:        
        !           358:        form = lbot->val;
        !           359:        name = form->d.car;
        !           360:        body = form->d.cdr->d.car;
        !           361:        arglist = body->d.cdr->d.car;
        !           362:        if((TYPE(arglist))!=DTPR && arglist != nil)
        !           363:                error("Warning: defining function with nonlist of args",
        !           364:                        TRUE);
        !           365:        name->a.fnbnd = body;
        !           366:        return(name);
        !           367: }
        !           368: 
        !           369: 
        !           370: lispval
        !           371: Nquote()
        !           372: {
        !           373:        snpand(0);
        !           374:        return((lbot->val)->d.car);
        !           375: }
        !           376: 
        !           377: 
        !           378: lispval
        !           379: Nsetq()
        !           380: {      register lispval handy, where, value;
        !           381:        register int lefttype;
        !           382:        register struct argent *lbot, *np;
        !           383: 
        !           384: 
        !           385:        for(where = lbot->val; where != nil; where = handy->d.cdr) {
        !           386:                handy = where->d.cdr;
        !           387:                if((TYPE(handy))!=DTPR)
        !           388:                        error("odd number of args to setq",FALSE);
        !           389:                if((lefttype=TYPE(where->d.car))==ATOM) {
        !           390:                        if(where->d.car==nil)
        !           391:                                error("Attempt to set nil",FALSE);
        !           392:                        where->d.car->a.clb = value = eval(handy->d.car);
        !           393:                 }else if(lefttype==VALUE)
        !           394:                        where->d.car->l = value = eval(handy->d.car);
        !           395:                else error("CAN ONLY SETQ ATOMS OR VALUES",FALSE);
        !           396:        }
        !           397:        return(value);
        !           398: }
        !           399: 
        !           400: 
        !           401: lispval
        !           402: Ncond()
        !           403: {
        !           404:        register lispval  where, last;
        !           405:        snpand(2);
        !           406: 
        !           407:        where = lbot->val;
        !           408:        last = nil;
        !           409:        for(;;) {
        !           410:                if ((TYPE(where))!=DTPR)
        !           411:                        break;
        !           412:                if ((TYPE(where->d.car))!=DTPR)
        !           413:                        break;
        !           414:                if ((last=eval((where->d.car)->d.car)) != nil)
        !           415:                        break;
        !           416:                where = where->d.cdr;
        !           417:        }
        !           418: 
        !           419:        if ((TYPE(where)) != DTPR)
        !           420:                        return(nil);
        !           421:        where = (where->d.car)->d.cdr;
        !           422:        while ((TYPE(where))==DTPR) {
        !           423:                        last = eval(where->d.car);
        !           424:                        where = where->d.cdr;
        !           425:        }
        !           426:        return(last);
        !           427: }
        !           428: 
        !           429: lispval
        !           430: Nand()
        !           431: {
        !           432:        register lispval current, temp;
        !           433:        snpand(2);
        !           434: 
        !           435:        current = lbot->val;
        !           436:        temp = tatom;
        !           437:        while (current != nil)
        !           438:                if ( (temp = current->d.car)!=nil && (temp = eval(temp))!=nil) 
        !           439:                        current = current->d.cdr;
        !           440:                else {
        !           441:                        current = nil;
        !           442:                        temp = nil;
        !           443:                }
        !           444:        return(temp);
        !           445: }
        !           446: 
        !           447: 
        !           448: lispval
        !           449: Nor()
        !           450: {
        !           451:        register lispval current, temp;
        !           452:        snpand(2);
        !           453: 
        !           454:        current = lbot->val;
        !           455:        temp = nil;
        !           456:        while (current != nil)
        !           457:                if ( (temp = eval(current->d.car)) == nil)
        !           458:                        current = current->d.cdr;
        !           459:                else
        !           460:                        break;
        !           461:        return(temp);
        !           462: }
        !           463: 
        !           464: 
        !           465: lispval
        !           466: Nprocess() {
        !           467:        int wflag , childsi , childso , childnum, child;
        !           468:        register lispval current, temp;
        !           469:        char * sharg;
        !           470:        int handler;
        !           471:        int itemp;
        !           472:        FILE *bufs[2],*obufs[2];
        !           473: 
        !           474:        wflag = 1;
        !           475:        childsi = 0;
        !           476:        childso = 1;
        !           477:        current = lbot->val;
        !           478:        if( (TYPE(current))!=DTPR )
        !           479:                return(nil);
        !           480:        temp = current->d.car;
        !           481:        if( (TYPE(temp))!=ATOM )
        !           482:                return(nil);
        !           483: 
        !           484:        sharg = temp->a.pname;
        !           485: 
        !           486:        if( (current = current->d.cdr)!=nil && (TYPE((temp = current->d.car)))==ATOM ) {
        !           487:        
        !           488:                if (temp == tatom) {
        !           489:                        wflag = 0;
        !           490:                        childsi = 0;
        !           491:                } else if (temp != nil) {
        !           492:                        fpipe(bufs);
        !           493:                        wflag = 0;
        !           494:                        temp->a.clb = P(bufs[1]);
        !           495:                        childsi = fileno(bufs[0]);
        !           496:                }
        !           497:        
        !           498:                if( (current = current->d.cdr)!=nil && (TYPE((temp = current->d.car)))==ATOM ) {
        !           499:        
        !           500:                        if (temp != nil) {
        !           501:                                fpipe(obufs);
        !           502:                                temp->a.clb = P(obufs[0]);
        !           503:                                childso = fileno(obufs[1]);
        !           504:                        }
        !           505:                }
        !           506:        }
        !           507:        handler = signal(2,1);
        !           508:        if((child = fork()) == 0 ) {
        !           509:                if(wflag!=0 && handler !=1)
        !           510:                        signal(2,0);
        !           511:                else
        !           512:                        signal(2,1);
        !           513:                if(childsi != 0) {
        !           514:                        close(0);
        !           515:                        dup(childsi);
        !           516:                }
        !           517:                if (childso !=1) {
        !           518:                        close(1);
        !           519:                        dup(childso);
        !           520:                }
        !           521:                execlp("csh", "csh", "-c",sharg,0);
        !           522:                execlp("sh", "sh", "-c",sharg,0);
        !           523:                exit(-1); /* if exec fails, signal problems*/
        !           524:        }
        !           525: 
        !           526:        if(childsi != 0) fclose(bufs[0]);
        !           527:        if(childso != 1) fclose(obufs[1]);
        !           528: 
        !           529:        if(wflag && child!= -1) {
        !           530:                int status=0;
        !           531:                wait(&status);
        !           532:                itemp = status >> 8;
        !           533:        } else
        !           534:                itemp = child;
        !           535:        signal(2,handler);
        !           536:        return(inewint(itemp));
        !           537: }

unix.superglobalmegacorp.com

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