Annotation of 3BSD/cmd/lisp/lam2.c, revision 1.1

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

unix.superglobalmegacorp.com

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