Annotation of 41BSD/cmd/lisp/lam2.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)lam2.c      34.1 10/3/80";
                      2: 
                      3: # include "global.h"
                      4: # include <signal.h>
                      5: /*
                      6:  * (flatc thing max) returns the smaller of max and the number of chars
                      7:  * required to print thing linearly.
                      8:  * if max argument is not given, we assume the second arg is infinity
                      9:  */
                     10: static flen; /*Internal to this module, used as a running counter of flatsize*/
                     11: static fmax; /*used for maximum for quick reference */
                     12: 
                     13: lispval
                     14: Lflatsi()
                     15: {
                     16:        register lispval current, temp;
                     17:        register struct argent *mylbot = lbot;
                     18:        snpand(3); /* fixup entry mask */
                     19: 
                     20:        if( np-lbot == 1) fmax = 0x7fffffff;    /* biggest integer */
                     21:        else fmax = mylbot[1].val->i;
                     22:        flen = 0; 
                     23:        current = mylbot->val;
                     24:        protect(nil);                   /*create space for argument to pntlen*/
                     25:        Iflatsi(current);
                     26:        return(inewint(flen));
                     27: }
                     28: /*
                     29:  * Iflatsi does the real work of the calculation for flatc
                     30:  */
                     31: Iflatsi(current)
                     32: register lispval current;
                     33: {
                     34:        register lispval handy;
                     35:        register int temp;
                     36: 
                     37:        if(flen > fmax) return(fmax);
                     38:        switch(TYPE(current)) {
                     39: 
                     40:        patom:
                     41:        case INT: case ATOM: case DOUB: case STRNG:
                     42:                np[-1].val = current;
                     43:                flen += Ipntlen();
                     44:                return;
                     45:        
                     46:        pthing:
                     47:        case DTPR:
                     48:                flen++;
                     49:                Iflatsi(current->d.car);
                     50:                current = current->d.cdr;
                     51:                if(current == nil) {
                     52:                        flen++;
                     53:                        return;
                     54:                }
                     55:                if(flen > fmax) return;
                     56:                switch(TYPE(current)) {
                     57:                case INT: case ATOM: case DOUB:
                     58:                        flen += 4;
                     59:                        goto patom;
                     60:                case DTPR:
                     61:                        goto pthing;
                     62:                }
                     63:        }
                     64: }
                     65: 
                     66: 
                     67: #define EADC -1
                     68: #define EAD  -2
                     69: lispval
                     70: Lread()
                     71: { return (r(EAD)); }
                     72: 
                     73: lispval
                     74: Lratom()
                     75: { return (r(ATOM)); }
                     76: 
                     77: lispval
                     78: Lreadc()
                     79: { return (r(EADC)); }
                     80: 
                     81: #include "chars.h"
                     82: #include "chkrtab.h"
                     83: 
                     84: extern char *ctable;
                     85: /* r *********************************************************************/
                     86: /* this function maps the desired read         function into the system-defined */
                     87: /* reading functions after testing for a legal port.                    */
                     88: lispval
                     89: r(op)
                     90: int op;
                     91: {
                     92:        register char c; register lispval result;
                     93:        int orlevel; extern int rlevel;
                     94:        FILE *ttemp;
                     95:        struct nament *oldbnp = bnp;
                     96:        snpand(2);
                     97: 
                     98:        switch(np-lbot) {
                     99:        case 0:
                    100:                protect(nil);
                    101:        case 1:
                    102:                protect(nil);
                    103:        case 2: break;
                    104:        default:
                    105:                argerr("read or ratom or readc");
                    106:        }
                    107:        result = Vreadtable->a.clb;
                    108:        chkrtab(result);
                    109:        orlevel = rlevel;
                    110:        rlevel = 0;
                    111:        ttemp = okport(Vpiport->a.clb,stdin);
                    112:        ttemp = okport(lbot->val,ttemp);
                    113: /*printf("entering switch\n");*/
                    114:        fflush(stdout);         /* flush any pending characters */
                    115: 
                    116:        switch (op)
                    117:        {
                    118:        case EADC:      rlevel = orlevel;
                    119:                        switch (ctable[c = getc(ttemp) & 0177] & 0377)
                    120:                        {
                    121:                        case VEOF:
                    122:                                return(lbot[1].val);
                    123:                        default:
                    124:                                strbuf[0] = hash = c;
                    125:                                strbuf[1] = 0;
                    126:                                atmlen = 2;
                    127:                                return((lispval)getatom());
                    128:                        }
                    129:        case ATOM:      rlevel = orlevel;
                    130:                        result = (ratomr(ttemp));
                    131:                        goto out;
                    132: 
                    133:        case EAD:       PUSHDOWN(Vpiport,P(ttemp)); /* rebind Vpiport */
                    134:                        result = readr(ttemp);
                    135:        out:            if(result==eofa)
                    136:                        {    
                    137:                             if(sigintcnt > 0) sigcall(SIGINT);
                    138:                             result = lbot[1].val;
                    139:                        }
                    140:                        rlevel = orlevel;
                    141:                        popnames(oldbnp);       /* unwind bindings */
                    142:                        return(result);
                    143:        }
                    144: }
                    145: 
                    146: /* Lload *****************************************************************/
                    147: /* Reads in and executes forms from the specified file. This should      */
                    148: /* really be an nlambda taking multiple arguments, but the error        */
                    149: /* handling gets funny in that case (one file out of several not        */
                    150: /* openable, for instance).                                             */
                    151: lispval
                    152: Lload()
                    153: {
                    154:        register FILE *port;
                    155:        register char *p, *ttemp; register lispval vtemp;
                    156:        register struct argent *lbot, *np;
                    157:        struct nament *oldbnp = bnp;
                    158:        int orlevel,typ;
                    159:        char longname[100];
                    160:        char *shortname, *end2;
                    161: 
                    162:        chkarg(1,"load");
                    163:        if((typ = TYPE(lbot->val)) == ATOM)
                    164:            ttemp =  lbot->val->a.pname ;  /* ttemp will point to name */
                    165:        else if(typ == STRNG)
                    166:            ttemp = (char *) lbot->val;
                    167:        else 
                    168:             return(error("FILENAME MUST BE ATOMIC",FALSE));
                    169:        strcpy(longname,"/usr/lib/lisp/" );
                    170:        for(p = longname; *p; p++);
                    171:                shortname = p;
                    172:        strcpy(p,ttemp);
                    173:        for(; *p; p++);
                    174:                end2 = p;
                    175:        strcpy(p,".l");
                    176:        if ((port = fopen(shortname,"r")) == NULL &&
                    177:                (port = fopen(longname, "r")) == NULL) {
                    178:                        *end2 = 0;
                    179:                        if ((port = fopen(shortname,"r")) == NULL &&
                    180:                                (port = fopen(longname, "r")) == NULL)
                    181:                                        errorh(Vermisc,"Can't open file: ", 
                    182:                                                     nil,FALSE,0,lbot->val);
                    183:        }
                    184:        orlevel = rlevel;
                    185:        rlevel = 0;
                    186: 
                    187:        if(ISNIL(copval(gcload,CNIL)) &&
                    188:                loading->a.clb != tatom &&
                    189:                ISNIL(copval(gcdis,CNIL)))
                    190:                gc(CNIL);       /*  do a gc if gc will be off  */
                    191: 
                    192:        /* shallow bind the value of lisp atom piport   */
                    193:        /* so readmacros will work                      */
                    194:        PUSHDOWN(Vpiport,P(port));
                    195:        PUSHDOWN(loading,tatom);        /* set indication of loading status */
                    196: 
                    197:        while ((vtemp = readr(port)) != eofa) {
                    198:            eval(vtemp);
                    199:        }
                    200:        popnames(oldbnp);               /* unbind piport, loading */
                    201: 
                    202:        rlevel = orlevel;
                    203:        fclose(port);
                    204:        return(nil);
                    205: }
                    206: 
                    207: /* concat **************************************************
                    208: -
                    209: -  use: (concat arg1 arg2 ... )
                    210: -
                    211: -  concatenates the print names of all of its arguments.
                    212: - the arguments may be atoms, integers or real numbers.
                    213: -
                    214: - *********************************************************/
                    215: lispval
                    216: Iconcat(unintern)
                    217: {
                    218:        register struct argent *temnp;
                    219:        register int atmlen; /* Passt auf!  atmlen in the external
                    220:                                sense calculated by newstr          */
                    221:        int i;
                    222:        lispval cur;
                    223:        char lstrbf[200];       /* local string buffer needed if sdot seen */
                    224:        snpand(2);
                    225: 
                    226:        atmlen = 0 ;    
                    227:        strbuf[0] = NULL_CHAR ;
                    228: 
                    229:        /* loop for each argument */
                    230:        for(temnp = lbot + AD ; temnp < np ; temnp++)
                    231:        {
                    232:            cur = temnp->val;
                    233:       loop: switch(TYPE(cur))
                    234:            {
                    235:            case ATOM:
                    236:                 strcpy(&strbuf[atmlen], ((struct atom *) cur) -> pname) ;
                    237:                 break;
                    238: 
                    239:            case STRNG:
                    240:                 strcpy(&strbuf[atmlen], cur);
                    241:                 break;
                    242: 
                    243:            case INT:
                    244:                 sprintf(&strbuf[atmlen],"%d",cur->i);
                    245:                 break;
                    246: 
                    247:            case DOUB:
                    248:                 sprintf(&strbuf[atmlen],"%f",cur->f);
                    249:                 break;
                    250: 
                    251:            case SDOT:
                    252:                 if(atmlen > 200) error("concat: string buffer overflow",FALSE);
                    253:                 strcpy(lstrbf,strbuf);  /* save around explode */
                    254:                 lbot = np;
                    255:                 protect(cur);          /* must explode */
                    256:                 cur= Lexplda();
                    257:                 np = lbot;
                    258:                 strcpy(strbuf,lstrbf);
                    259:                 for( ; cur != nil ; cur = cur->d.cdr)
                    260:                   strbuf[atmlen++] = cur->d.car->a.pname[0]; 
                    261:                 strbuf[atmlen] = '\0';
                    262:                 break;
                    263:                    
                    264:            default:
                    265:                 cur = error("Non atom or number to concat",TRUE);
                    266:                 goto loop;    /* if returns value, try it */
                    267:           }
                    268:           atmlen = strlen(strbuf);
                    269: 
                    270:        }
                    271: 
                    272:        if(unintern)
                    273:                return( (lispval) newatom());
                    274:        else
                    275:                return( (lispval) getatom()) ;
                    276: }
                    277: lispval
                    278: Lconcat(){
                    279:        return(Iconcat(FALSE));
                    280: }
                    281: lispval
                    282: Luconcat(){
                    283:        return(Iconcat(TRUE));
                    284: }
                    285: 
                    286: lispval
                    287: Lputprop()
                    288: {
                    289:        register struct argent *argp = lbot;
                    290:        lispval Iputprop();
                    291:        snpand(1);
                    292:        chkarg(3,"putprop");
                    293:        return(Iputprop(argp->val,argp[1].val,argp[2].val));
                    294: }
                    295: 
                    296: lispval
                    297: Iputprop(atm,prop,ind)
                    298: register lispval prop, ind, atm;
                    299: {
                    300:        register lispval pptr;
                    301:        lispval *tack;          /* place to begin property list */
                    302:        lispval errorh();
                    303:  top:
                    304:        switch (TYPE(atm)) {
                    305:        case ATOM:
                    306:                if(atm == nil) tack = &nilplist;
                    307:                else tack =  &(atm->a.plist);
                    308:                break;
                    309:        case DTPR:
                    310:                for (pptr = atm->d.cdr ; pptr != nil ; pptr = pptr->d.cdr->d.cdr)
                    311:                    if(TYPE(pptr) != DTPR || TYPE(pptr->d.cdr) != DTPR) break;
                    312:                if(pptr != nil) 
                    313:                {   atm = errorh(Vermisc,
                    314:                                 "putprop: bad disembodied property list",
                    315:                                 nil,TRUE,0,atm);
                    316:                    goto top;
                    317:                }
                    318:                tack = (lispval *) &(atm->d.cdr);
                    319:                break;
                    320:        default:
                    321:                errorh(Vermisc,"putprop: Bad first argument: ",nil,FALSE,0,atm);
                    322:        }
                    323:        pptr = *tack;   /* start of property list */
                    324:        findit:
                    325:        for (pptr = *tack ; pptr != nil ; pptr = pptr->d.cdr->d.cdr)
                    326:                if (pptr->d.car == ind) {
                    327:                        (pptr->d.cdr)->d.car = prop;
                    328:                        return(prop);
                    329:                }
                    330:                else tack = &(pptr->d.cdr->d.cdr) ;
                    331:        *tack = pptr = newdot();
                    332:        pptr->d.car = ind;
                    333:        pptr = pptr->d.cdr = (lispval) newdot();
                    334:        pptr->d.car = prop;
                    335:        return(prop);
                    336: }
                    337: 
                    338: /* get from property list 
                    339:  *   there are three routines to accomplish this
                    340:  *     Lget - lisp callable, the first arg can be a symbol or a disembodied
                    341:  *           property list.  In the latter case we check to make sure it
                    342:  *           is a real one (as best we can).
                    343:  *     Iget - internal routine, the first arg must be a symbol, no disembodied
                    344:  *           plists allowed
                    345:  *     Igetplist - internal routine, the first arg is the plist to search.
                    346:  */
                    347: lispval
                    348: Lget()
                    349: {
                    350:        register lispval ind, atm;
                    351:        register lispval dum1, dum2;
                    352:        lispval Igetplist();
                    353:        snpand(2);
                    354: 
                    355:        chkarg(2,"get");
                    356:        ind = lbot[1].val;
                    357:        atm = lbot[0].val;
                    358: top:
                    359:        switch(TYPE(atm)) {
                    360:        case ATOM:
                    361:                if(atm==nil) atm = nilplist;
                    362:                else atm = atm->a.plist;
                    363:                break;          
                    364: 
                    365:        case DTPR:
                    366:                for (dum1 = atm->d.cdr; dum1 != nil; dum1 = dum1->d.cdr->d.cdr)
                    367:                    if((TYPE(dum1) != DTPR) || 
                    368:                       (TYPE(dum1->d.cdr) != DTPR)) break; /* bad prop list */
                    369:                if(dum1 != nil) 
                    370:                {   atm = errorh(Vermisc,
                    371:                                 "get: bad disembodied property list",
                    372:                                 nil,TRUE,0,atm);
                    373:                    goto top;
                    374:                }
                    375:                atm = atm->d.cdr;
                    376:                break;
                    377:        default:
                    378:                /* remove since maclisp doesnt treat
                    379:                   this as an error, ugh
                    380:                   return(errorh(Vermisc,"get: bad first argument: ",
                    381:                               nil,FALSE,0,atm));
                    382:                 */
                    383:                 return(nil);
                    384:        }
                    385: 
                    386:        while (atm != nil)
                    387:                {
                    388:                        if (atm->d.car == ind)
                    389:                                return ((atm->d.cdr)->d.car);
                    390:                        atm = (atm->d.cdr)->d.cdr;
                    391:                }
                    392:        return(nil);
                    393: }
                    394: /*
                    395:  * Iget - the first arg must be a symbol.
                    396:  */
                    397:        
                    398: lispval
                    399: Iget(atm,ind)
                    400: register lispval atm, ind;
                    401: {
                    402:        lispval Igetplist();
                    403: 
                    404:        if(atm==nil)
                    405:                atm = nilplist;
                    406:        else
                    407:                atm = atm->a.plist;
                    408:        return(Igetplist(atm,ind));
                    409: }
                    410: 
                    411: /*
                    412:  *  Igetplist
                    413:  * pptr is a plist
                    414:  * ind is the indicator
                    415:  */
                    416: 
                    417: lispval
                    418: Igetplist(pptr,ind)
                    419: register lispval pptr,ind;
                    420: {
                    421:        while (pptr != nil)
                    422:                {
                    423:                        if (pptr->d.car == ind)
                    424:                                return ((pptr->d.cdr)->d.car);
                    425:                        pptr = (pptr->d.cdr)->d.cdr;
                    426:                }
                    427:        return(nil);
                    428: }
                    429: lispval
                    430: Lgetd()
                    431: {
                    432:        register lispval typ;
                    433:        snpand(1);
                    434:        
                    435:        chkarg(1,"getd");
                    436:        typ = lbot->val;
                    437:        if (TYPE(typ) != ATOM) 
                    438:           errorh(Vermisc,
                    439:                  "getd: ONLY ATOMS HAVE FUNCTION DEFINITIONS",
                    440:                  nil,
                    441:                  FALSE,
                    442:                  0,
                    443:                  typ);
                    444:        return(typ->a.fnbnd);
                    445: }
                    446: lispval
                    447: Lputd()
                    448: {
                    449:        register lispval atom, list;
                    450:        register lispval dum1, dum2;
                    451:        register struct argent *lbot, *np;
                    452:        snpand(2);
                    453:        
                    454:        chkarg(2,"putd");
                    455:        list = lbot[1].val;
                    456:        atom = lbot->val;
                    457:        if (TYPE(atom) != ATOM) error("ONLY ATOMS HAVE FUNCTION DEFINITIONS",FALSE);
                    458:        atom->a.fnbnd = list;
                    459:        return(list);
                    460: }
                    461: 
                    462: /* ===========================================================
                    463: - mapping functions which return a list of the answers
                    464: - mapcar applies the given function to successive elements
                    465: - maplist applies the given function to successive sublists
                    466: - ===========================================================*/
                    467: 
                    468: lispval
                    469: Lmapcrx(maptyp,join)
                    470: int maptyp;            /* 0 = mapcar,  1 = maplist  */
                    471: int join;              /* 0 = the above, 1 = s/car/can/ */
                    472: {
                    473:        register struct argent *namptr;
                    474:        register index;
                    475:        register lispval temp;
                    476:        register lispval current;
                    477:        register struct argent *lbot;
                    478:        register struct argent *np;
                    479: 
                    480:        struct argent *first, *last;
                    481:        int count;
                    482:        lispval lists[25], result;
                    483:        
                    484:        namptr = lbot + 1;
                    485:        count = np - namptr;
                    486:        if (count <= 0) return (nil);
                    487:        /*oldlbot = lbot;               /* lbot saved by virtue of entry mask */
                    488:        result = current =  (lispval) np;
                    489:        protect(nil);                   /* set up space for returned list */
                    490:        protect(lbot->val);     /*copy funarg for call to funcall */
                    491:        lbot = np -1;
                    492:        first = np;
                    493:        last = np += count;
                    494:        for(index = 0; index < count; index++) {
                    495:                temp =(namptr++)->val; 
                    496:                if (TYPE (temp ) != DTPR && temp!=nil) 
                    497:                        error ( "bad list argument to map",FALSE);
                    498:                lists[index] = temp;
                    499:        }
                    500:        for(;;) {
                    501:                for(namptr=first,index=0; index<count; index++) {
                    502:                        temp = lists[index];
                    503:                        if(temp==nil) goto done;
                    504: 
                    505:                        if(maptyp==0) (namptr++)->val = temp->d.car;
                    506:                        else (namptr++)->val = temp;
                    507: 
                    508:                        lists[index] = temp->d.cdr;
                    509:                }
                    510:                if (join == 0) {
                    511:                        current->l = newdot();
                    512:                        current->l->d.car = Lfuncal();
                    513:                        current = (lispval) &current->l->d.cdr;
                    514:                } else {
                    515:                        current->l = Lfuncal();
                    516:                        if ( TYPE ( current -> l) != DTPR && current->l != nil)
                    517:                                error("bad type returned from funcall inside map",FALSE);
                    518:                        else  while ( current -> l  != nil )
                    519:                                        current = (lispval) & (current ->l ->d.cdr);
                    520:                }
                    521:                np = last;
                    522:        }
                    523: done:  if (join == 0)current->l = nil;
                    524:        /*lbot = oldlbot;*/
                    525:        return(result->l);
                    526: }
                    527: 
                    528: /* ============================
                    529: -
                    530: - Lmapcar
                    531: - =============================*/
                    532: 
                    533: lispval
                    534: Lmapcar()
                    535: {
                    536:        snpand(0);
                    537:        return(Lmapcrx(0,0)); } /* call general routine */
                    538: 
                    539: 
                    540: /* ============================
                    541: -
                    542: -
                    543: -  Lmaplist
                    544: - ==============================*/
                    545: 
                    546: lispval
                    547: Lmaplist()
                    548: {
                    549:        snpand(0);
                    550:        return(Lmapcrx(1,0)); } /* call general routine */
                    551: 
                    552: 
                    553: /* ================================================
                    554: - mapping functions which return the value of the last function application.
                    555: - mapc and map
                    556: - ===================================================*/
                    557: 
                    558: lispval
                    559: Lmapcx(maptyp)
                    560: int maptyp;            /* 0= mapc   , 1= map  */
                    561: {
                    562:        register struct argent *namptr;
                    563:        register index;
                    564:        register lispval temp;
                    565:        register lispval result;
                    566:        register struct argent *lbot;
                    567:        register struct argent *np;
                    568: 
                    569:        int count;
                    570:        struct argent *first;
                    571:        lispval lists[25], errorh();
                    572:        
                    573:        namptr = lbot + 1;
                    574:        count = np - namptr;
                    575:        if(count <= 0) return(nil);
                    576:        result = lbot[1].val;           /*This is what macsyma wants so ... */
                    577:                                        /*copy funarg for call to funcall */
                    578:        lbot = np; protect((namptr - 1)->val);
                    579:        first = np; np += count;
                    580: 
                    581:        for(index = 0; index < count; index++) {
                    582:                temp = (namptr++)->val;
                    583:                while(temp!=nil && TYPE(temp)!=DTPR)
                    584:                        temp = errorh(Vermisc,"Inappropriate list argument to mapc",nil,TRUE,0,temp);
                    585:                lists[index] = temp;
                    586:        }
                    587:        for(;;) {
                    588:                for(namptr=first,index=0; index<count; index++) {
                    589:                        temp = lists[index];
                    590:                        if(temp==nil)
                    591:                                goto done;
                    592:                        if(maptyp==0)
                    593:                                (namptr++)->val = temp->d.car;
                    594:                        else
                    595:                                (namptr++)->val = temp;
                    596:                        lists[index] = temp->d.cdr;
                    597:                }
                    598:                Lfuncal();
                    599:        }
                    600: done:  
                    601:        return(result);
                    602: }
                    603: 
                    604: 
                    605: /* ==================================
                    606: -
                    607: -      mapc   map the car of the lists
                    608: -
                    609: - ==================================*/
                    610: 
                    611: lispval
                    612: Lmapc()
                    613: {      return( Lmapcx(0) );  }
                    614: 
                    615: 
                    616: /* =================================
                    617: -
                    618: -      map    map the cdr of the lists
                    619: -
                    620: - ===================================*/
                    621: 
                    622: lispval
                    623: Lmap()
                    624: {      return( Lmapcx(1) );   }
                    625: 
                    626: 
                    627: lispval
                    628: Lmapcan()
                    629: { 
                    630:        lispval Lmapcrx();
                    631: 
                    632:        return ( Lmapcrx ( 0,1 ) ); 
                    633: } 
                    634: 
                    635: lispval
                    636: Lmapcon()
                    637: { 
                    638:        lispval Lmapcrx();
                    639: 
                    640:        return ( Lmapcrx ( 1,1 ) ); 
                    641: }

unix.superglobalmegacorp.com

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