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

1.1     ! root        1: 
        !             2: # include "global.h"
        !             3: # include <sgtty.h>
        !             4: # include "chkrtab.h"
        !             5: /**************************************************************************/
        !             6: /*                                                                        */
        !             7: /*   file: ccdfns.i                                                       */
        !             8: /*   contents: LISP functions coded in C                                  */
        !             9: /*                                                                        */
        !            10: /*   These include LISP primitives, numeric and boolean functions and     */
        !            11: /*     predicates, some list-processing functions, i/o support functions */
        !            12: /*     and control flow functions (e.g. cont, break).                    */
        !            13: /*   There are two types of functions: lambda (prefixed "L") and nlambda  */
        !            14: /*     (prefixed "N").                                                   */
        !            15: /*   Lambda's all call chkarg to insure that at least the minimum number  */
        !            16: /*     of necessary arguments are on the namestack.                      */
        !            17: /*   All functions take their arguments from the namestack in a read-     */
        !            18: /*     only manner, and return their results via the normal C value      */
        !            19: /*     return mechanism.                                                 */
        !            20: /*                                                                       */
        !            21: 
        !            22: 
        !            23: 
        !            24: lispval
        !            25: Leval()
        !            26: {
        !            27:        register lispval temp;
        !            28: 
        !            29:        chkarg(1);
        !            30:        temp = lbot->val;
        !            31:            return(eval(temp));
        !            32: }
        !            33: 
        !            34: lispval
        !            35: Lxcar()
        !            36: {      register int typ;
        !            37:        register lispval temp, result;
        !            38: 
        !            39:        chkarg(1);
        !            40:        temp = lbot->val;
        !            41:        if (((typ = TYPE(temp)) == DTPR) || (typ == ATOM))
        !            42:            return(temp -> car);
        !            43:        else if(typ == SDOT) {
        !            44:                result = inewint(temp->i);
        !            45:                return(result);
        !            46:        } else if(Schainp!=nil && typ==ATOM)
        !            47:                return(nil);
        !            48:        else
        !            49:                return(error("BAD ARG TO CAR",FALSE));
        !            50: 
        !            51: }
        !            52: 
        !            53: lispval
        !            54: Lxcdr()
        !            55: {      register int typ;
        !            56:        register lispval temp, result;
        !            57: 
        !            58:        chkarg(1);
        !            59:        temp = lbot->val;
        !            60:        if(temp==nil) return (nil);
        !            61: 
        !            62:        if ((typ = TYPE(temp)) == DTPR) 
        !            63:            return(temp -> cdr);
        !            64:        else if(typ==SDOT) {
        !            65:                if(temp->CDR==0) return(nil);
        !            66:                return(temp->CDR);
        !            67:        } else if(Schainp!=nil && typ==ATOM)
        !            68:                return(nil);
        !            69:        else
        !            70:                return(error("BAD ARG TO CDR",FALSE));
        !            71: }
        !            72: 
        !            73: lispval
        !            74: cxxr(as,ds)
        !            75: register int as,ds;
        !            76: {
        !            77: 
        !            78:        register lispval temp, temp2;
        !            79:        int i, typ;
        !            80:        lispval errorh();
        !            81: 
        !            82:        chkarg(1);
        !            83:        temp = lbot->val;
        !            84: 
        !            85:        for( i=0 ; i<ds ; i++)
        !            86:        {
        !            87:            if( temp != nil)
        !            88:            {
        !            89:                if ((typ = TYPE(temp)) == DTPR) 
        !            90:                    temp = temp -> cdr;
        !            91:                else if(typ==SDOT) {
        !            92:                        if(temp->CDR==0) temp = nil;
        !            93:                        else temp = temp->CDR;
        !            94:                }
        !            95:                else if(Schainp!=nil && typ==ATOM)
        !            96:                        return(nil);
        !            97:                else
        !            98:                        return(errorh(Vermisc,"BAD ARG TO CDR",nil,FALSE,5,temp));
        !            99:            }
        !           100:        }
        !           101: 
        !           102:        for( i=0 ; i<as ; i++)
        !           103:        {
        !           104:            if( temp != nil )
        !           105:            {
        !           106:                if ((typ = TYPE(temp)) == DTPR)
        !           107:                    temp = temp -> car;
        !           108:                else if(typ == SDOT)
        !           109:                        temp2 = inewint(temp->i), temp = temp2;
        !           110:                else if(Schainp!=nil && typ==ATOM)
        !           111:                        return(nil);
        !           112:                else
        !           113:                        return(errorh(Vermisc,"BAD ARG TO CAR",nil,FALSE,5,temp));
        !           114:            }
        !           115:        }
        !           116: 
        !           117:        return(temp);
        !           118: }
        !           119: 
        !           120: 
        !           121: lispval
        !           122: Lcar()
        !           123: {      return(cxxr(1,0));
        !           124: }
        !           125: 
        !           126: lispval
        !           127: Lcdr()
        !           128: {      return(cxxr(0,1));
        !           129: }
        !           130: 
        !           131: lispval
        !           132: Lcadr()
        !           133: {      return(cxxr(1,1));
        !           134: }
        !           135: 
        !           136: lispval
        !           137: Lcaar()
        !           138: {      return(cxxr(2,0));
        !           139: }
        !           140: 
        !           141: lispval
        !           142: Lc02r()
        !           143: {      return(cxxr(0,2));      /* cddr */
        !           144: }
        !           145: 
        !           146: lispval
        !           147: Lc12r()
        !           148: {      return(cxxr(1,2));      /* caddr */
        !           149: }
        !           150: 
        !           151: lispval
        !           152: Lc03r()
        !           153: {      return(cxxr(0,3));      /* cdddr */
        !           154: }
        !           155: 
        !           156: lispval
        !           157: Lc13r()
        !           158: {      return(cxxr(1,3));      /* cadddr */
        !           159: }
        !           160: 
        !           161: lispval
        !           162: Lc04r()
        !           163: {      return(cxxr(0,4));      /* cddddr */
        !           164: }
        !           165: 
        !           166: lispval
        !           167: Lc14r()
        !           168: {      return(cxxr(1,4));      /* caddddr */
        !           169: }
        !           170: 
        !           171: /*************************
        !           172: *  
        !           173: *  (nthelem num list)
        !           174: * returns the num'th element of the list, by doing a caddddd...ddr
        !           175: * where there are num-1 d's
        !           176: * if num<=0 or greater than the length of the list, we return nil
        !           177: ******************************************************/
        !           178: 
        !           179: lispval
        !           180: Lnthelem()
        !           181: {
        !           182:        register lispval temp;
        !           183:        register int i;
        !           184: 
        !           185:        chkarg(2);
        !           186: 
        !           187:        if( TYPE(temp = lbot->val) != INT)
        !           188:        return (error ("First arg to nthelem must be a fixnum",FALSE));
        !           189: 
        !           190:        i = temp->i;    /* pick up the first arg */
        !           191: 
        !           192:        if( i <= 0) return(nil);
        !           193: 
        !           194:        ++lbot;                 /* fix lbot for call to cxxr() 'cadddd..r' */
        !           195:        temp = cxxr(1,i-1);
        !           196:        --lbot;
        !           197: 
        !           198:        return(temp);
        !           199: }
        !           200: 
        !           201: 
        !           202: 
        !           203: 
        !           204: 
        !           205: lispval
        !           206: Lscons()
        !           207: {
        !           208:        register struct argent *argp = lbot;
        !           209:        register lispval retp, handy;
        !           210:        register int typ;
        !           211: 
        !           212:        chkarg(2);
        !           213:        retp = newsdot();
        !           214:        handy = (argp) -> val;
        !           215:        if(TYPE(handy)!=INT)
        !           216:                error("First arg to scons must be an int.",FALSE);
        !           217:        retp->I = handy->i;
        !           218:        handy = (argp+1)->val;
        !           219:        if(handy==nil)
        !           220:                retp->CDR = (lispval) 0;
        !           221:        else {
        !           222:                if(TYPE(handy)!=SDOT)
        !           223:                        error("Currently you may only link sdots to sdots.",FALSE);
        !           224:                retp->CDR = handy;
        !           225:        }
        !           226:        return(retp);
        !           227: }
        !           228: lispval
        !           229: Lcons()
        !           230: {   register struct argent *argp;
        !           231:             lispval       retp;
        !           232: 
        !           233:        chkarg(2);
        !           234:        retp = newdot();
        !           235:        retp -> cdr = ((argp = np-1) -> val);
        !           236:        retp -> car = (--argp) -> val;
        !           237:        return(retp);
        !           238: }
        !           239: #define CA 0
        !           240: #define CD 1
        !           241: 
        !           242: lispval
        !           243: rpla(what)
        !           244: int what;
        !           245: {      register struct argent *argp;
        !           246:        register int typ; register lispval first, second;
        !           247: 
        !           248:        chkarg(2);
        !           249:        argp = np-1;
        !           250:        first = (argp-1)->val;
        !           251:        while(first==nil)
        !           252:                first = error("Attempt to rplac[ad] nil.",TRUE);
        !           253:        second = argp->val;
        !           254:        if (((typ = TYPE(first)) == DTPR) || (typ == ATOM)) {
        !           255:                if (what == CA)
        !           256:                        first->car = second;
        !           257:                else 
        !           258:                        first->cdr = second;
        !           259:                return(first);
        !           260:        }
        !           261:        if (typ==SDOT) {
        !           262:                if(what == CA) {
        !           263:                        typ = TYPE(second);
        !           264:                        if(typ!=INT) error("Rplacca of a bignum will only replace INTS",FALSE);
        !           265:                        first->i = second->i;
        !           266:                } else {
        !           267:                        if(second==nil)
        !           268:                                first->CDR = (lispval) 0;
        !           269:                        else
        !           270:                                first->CDR = second;
        !           271:                }
        !           272:                return(first);
        !           273:        }
        !           274:        return(error("BAD ARG TO RPLA",FALSE));
        !           275: }
        !           276: lispval
        !           277: Lrplaca()
        !           278: {      return(rpla(CA));       }
        !           279: 
        !           280: lispval
        !           281: Lrplacd()
        !           282: {      return(rpla(CD));       }
        !           283: 
        !           284: 
        !           285: lispval
        !           286: Leq()
        !           287: {
        !           288:        register struct argent *mynp = lbot + AD;
        !           289:        int itemp, flag;
        !           290: 
        !           291:        chkarg(2);
        !           292:        if(mynp->val==(mynp+1)->val) return(tatom);
        !           293:        return(nil);
        !           294: }
        !           295: 
        !           296: 
        !           297: 
        !           298: lispval
        !           299: Lnull()
        !           300: {      chkarg(1);
        !           301:        return ((lbot->val == nil) ? tatom : nil);
        !           302: }
        !           303: 
        !           304: 
        !           305: 
        !           306: /* Lreturn **************************************************************/
        !           307: /* Returns the first argument - which is nill if not specified.                */
        !           308: Lreturn()
        !           309:        {
        !           310:        chkarg(1);
        !           311:        contval = lbot->val;
        !           312:        reset(BRRETN);
        !           313:        }
        !           314: 
        !           315: 
        !           316: /* Lretbrk **************************************************************/
        !           317: /* The first argument must be an integer and must be in the range      */
        !           318: /* -1 .. -depth.                                                       */
        !           319: lispval
        !           320: Lretbrk()
        !           321:        {
        !           322:        lispval number;
        !           323:        register level;
        !           324: 
        !           325: 
        !           326:        chkarg(1);
        !           327:        number = lbot->val;
        !           328:        if (TYPE(number) != INT)
        !           329:                level = -1;
        !           330:        else
        !           331:                level = number->i;
        !           332:        if(level < 0)
        !           333:                level += depth;
        !           334:        contval = (lispval) level;
        !           335:        if (level < depth)
        !           336:                reset(BRRETB);
        !           337:        return(nil);
        !           338: }
        !           339: 
        !           340: 
        !           341: 
        !           342: lispval
        !           343: Linfile()
        !           344: {
        !           345:        FILE *port;
        !           346:        register lispval name;
        !           347:        snpand(1);
        !           348: 
        !           349:        chkarg(1);
        !           350:        name = lbot->val;
        !           351:        while (TYPE(name)!=ATOM)
        !           352:                name = error("Please supply atom name for port.",TRUE);
        !           353:        /* return nil if file couldnt be opened
        !           354:        if ((port = fopen(name->pname,"r")) == NULL) return(nil); */    
        !           355: 
        !           356:        while ((port = fopen(name->pname,"r")) == NULL)
        !           357:                name = errorh(Vermisc,"Unable to open file for reading.",nil,TRUE,31,name);
        !           358:                                                                
        !           359:        return((lispval)(xports + (port - _iob)));
        !           360: }
        !           361: 
        !           362: lispval
        !           363: Loutfile()
        !           364: {
        !           365:        FILE *port; register lispval name;
        !           366: 
        !           367:        chkarg(1);
        !           368:        name = lbot->val;
        !           369:        while (TYPE(name)!=ATOM)
        !           370:                name = error("Please supply atom name for port.",TRUE);
        !           371:        while ((port = fopen(name->pname,"w")) == NULL)
        !           372:                name = errorh(Vermisc,"Unable to open file for writing.",nil,TRUE,31,name);
        !           373:        return((lispval)(xports + (port - _iob)));
        !           374: }
        !           375: lispval
        !           376: Lterpr()
        !           377: {
        !           378:        FILE *port;
        !           379: 
        !           380:        chkarg(1);
        !           381:        port = okport(lbot->val,okport(Vpoport->clb,stdout));
        !           382:        putc('\n',port);
        !           383:        fflush(port);
        !           384:        return(nil);
        !           385: }
        !           386: lispval
        !           387: Lclose()
        !           388: {
        !           389:        lispval port;
        !           390: 
        !           391:        if(lbot==np)
        !           392:                port = error("Close requires one argument of type port",TRUE);
        !           393:        port = lbot->val;
        !           394:        if((TYPE(port))==PORT) fclose(port->p);
        !           395:        return(tatom);
        !           396: }
        !           397: 
        !           398: lispval
        !           399: Lnwritn()
        !           400: {
        !           401:        register FILE *port;
        !           402:        register value;
        !           403: 
        !           404:        chkarg(1);
        !           405:        port = okport(lbot->val,okport(Vpoport->clb,stdout));
        !           406:        value = port->_ptr - port->_base;
        !           407:        return(inewint(value));
        !           408: }
        !           409: 
        !           410: lispval
        !           411: Ldrain()
        !           412: {
        !           413:        register FILE *port;
        !           414:        register int iodes;
        !           415:        struct sgttyb arg;
        !           416: 
        !           417:        chkarg(1);
        !           418:        port = okport(lbot->val, okport(Vpoport->clb,stdout));
        !           419:        if(port->_flag & _IOWRT) {
        !           420:                fflush(port);
        !           421:                return(nil);
        !           422:        }
        !           423:        if(! port->_flag & _IOREAD) return(nil);
        !           424:        port->_cnt = 0;
        !           425:        port->_ptr = port->_base;
        !           426:        iodes = fileno(port);
        !           427:        if(gtty(iodes,&arg) != -1) stty(iodes,&arg);
        !           428:        return((lispval)(xports + (port - _iob)));
        !           429: }
        !           430: lispval
        !           431: Llist()
        !           432: {
        !           433:        /* added for the benefit of mapping functions. */
        !           434:        register struct argent *ulim, *namptr;
        !           435:        register lispval temp, result;
        !           436:        register struct argent *lbot, *np;
        !           437: 
        !           438:        ulim = np;
        !           439:        namptr = lbot + AD;
        !           440:        temp = result = (lispval) np;
        !           441:        protect(nil);
        !           442:        for(; namptr < ulim;) {
        !           443:                temp = temp->l = newdot();
        !           444:                temp->car = (namptr++)->val;
        !           445:        }
        !           446:        temp->l = nil;
        !           447:        return(result->l);
        !           448: }
        !           449: 
        !           450: lispval
        !           451: Lnumberp()
        !           452: {
        !           453:        chkarg(1);
        !           454:        switch(TYPE(lbot->val)) {
        !           455:        case INT: case DOUB: case SDOT:
        !           456:                return(tatom);
        !           457:        }
        !           458:        return(nil);
        !           459: }
        !           460: 
        !           461: lispval
        !           462: Latom()
        !           463: {
        !           464:        chkarg(1);
        !           465:        if(TYPE(lbot->val)==DTPR)
        !           466:                return(nil);
        !           467:        else
        !           468:                return(tatom);
        !           469: }
        !           470: lispval
        !           471: Ltype()
        !           472: {
        !           473:        chkarg(1);
        !           474:        switch(TYPE(lbot->val)) {
        !           475:        case INT:
        !           476:                return(int_name);
        !           477:        case ATOM:
        !           478:                return(atom_name);
        !           479:        case SDOT:
        !           480:                return(sdot_name);
        !           481:        case DOUB:
        !           482:                return(doub_name);
        !           483:        case DTPR:
        !           484:                return(dtpr_name);
        !           485:        case STRNG:
        !           486:                return(str_name);
        !           487:        case ARRAY:
        !           488:                return(array_name);
        !           489:        case BCD:
        !           490:                return(funct_name);
        !           491:        case VALUE:
        !           492:                return(val_name);
        !           493:        case PORT:
        !           494:                return(matom("port"));          /* fix this when name exists */
        !           495:        }
        !           496:        return(nil);
        !           497: }
        !           498: 
        !           499: lispval
        !           500: Ldtpr()
        !           501: {
        !           502:        chkarg(1);
        !           503:        return(typred(DTPR,lbot->val));
        !           504: }
        !           505: 
        !           506: lispval
        !           507: Lbcdp()
        !           508: {
        !           509:        chkarg(1);
        !           510:        return(typred(BCD,lbot->val));
        !           511: }
        !           512: 
        !           513: lispval
        !           514: Lportp()
        !           515: {
        !           516:        chkarg(1);
        !           517:        return(typred(PORT,lbot->val));
        !           518: }
        !           519: 
        !           520: lispval
        !           521: Larrayp()
        !           522: {
        !           523:        chkarg(1);
        !           524:        return(typred(ARRAY,lbot->val));
        !           525: }
        !           526: lispval
        !           527: Lset()
        !           528: {
        !           529:        lispval varble;
        !           530:        snpand(0);
        !           531: 
        !           532:        chkarg(2);
        !           533:        varble = lbot->val;
        !           534:        switch(TYPE(varble))
        !           535:                {
        !           536:        case ATOM:      return(varble->clb = lbot[1].val);
        !           537: 
        !           538:        case VALUE:     return(varble->l = lbot[1].val);
        !           539:                }
        !           540: 
        !           541:        error("IMPROPER USE OF SET",FALSE);
        !           542: }
        !           543: lispval
        !           544: Lequal()
        !           545: {
        !           546:        chkarg(2);
        !           547: 
        !           548:        if( lbot[1].val == lbot->val ) return(tatom);
        !           549:        if(Iequal(lbot[1].val,lbot->val)) return(tatom); else return(nil);
        !           550: }
        !           551: 
        !           552: Iequal(first,second) 
        !           553: register lispval first, second;
        !           554: {
        !           555:        register type1, type2;
        !           556:        register struct argent *lbot, *np;
        !           557:        lispval Lsub(),Lzerop();
        !           558: 
        !           559:        if(first==second)
        !           560:                return(1);
        !           561:        type1=TYPE(first);
        !           562:        type2=TYPE(second);
        !           563:        if(type1!=type2) {
        !           564:                if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT))
        !           565:                        goto dosub;
        !           566:                return(0);
        !           567:        }
        !           568:        switch(type1) {
        !           569:        case DTPR:
        !           570:                 return(
        !           571:                        Iequal(first->car,second->car) &&
        !           572:                        Iequal(first->cdr,second->cdr) );
        !           573:        case DOUB:
        !           574:                return(first->r==second->r);
        !           575:        case INT:
        !           576:                return( (first->i==second->i));
        !           577: dosub:
        !           578:        case SDOT:
        !           579:                lbot = np;
        !           580:                np++->val = first;
        !           581:                np++->val = second;
        !           582:                lbot->val = Lsub();
        !           583:                np = lbot + 1;
        !           584:                return(Lzerop()!=nil);
        !           585:        case VALUE:
        !           586:                return( first->l==second->l );
        !           587:        case STRNG:
        !           588:                return(strcmp(first,second)==0);
        !           589:        }
        !           590:        return(0);
        !           591: }
        !           592: 
        !           593: lispval
        !           594: Lprint()
        !           595: {
        !           596:        chkarg(2);
        !           597:        chkrtab(Vreadtable->clb);
        !           598:        printr(lbot->val,okport(lbot[1].val,okport(Vpoport->clb,poport)));
        !           599:        return(nil);
        !           600: }
        !           601: 
        !           602: FILE *
        !           603: okport(arg,proper) 
        !           604: lispval arg;
        !           605: FILE *proper;
        !           606: {
        !           607:        if(TYPE(arg)!=PORT)
        !           608:                return(proper);
        !           609:        else
        !           610:                return(arg->p);
        !           611: }
        !           612: lispval
        !           613: Lpatom()
        !           614: {
        !           615:        register lispval temp;
        !           616:        FILE *port;
        !           617: 
        !           618:        chkarg(2);
        !           619:        temp = Vreadtable->clb;
        !           620:        chkrtab(temp);
        !           621:        port = okport(lbot[1].val, okport(Vpoport->clb,stdout));
        !           622:        if ((TYPE((temp = (lbot)->val)))!=ATOM)
        !           623:                printr(temp, port);
        !           624:        else
        !           625:                fputs(temp->pname, port);
        !           626:        return(temp);
        !           627: }
        !           628: 
        !           629: /*
        !           630:  * (pntlen thing) returns the length it takes to print out
        !           631:  * an atom or number.
        !           632:  */
        !           633: 
        !           634: lispval
        !           635: Lpntlen()
        !           636: {
        !           637:        register lispval temp;
        !           638:        return(inewint(Ipntlen()));
        !           639: }
        !           640: Ipntlen()
        !           641: {
        !           642:        register lispval temp;
        !           643:        register char *handy;
        !           644: 
        !           645:        temp = np[-1].val;
        !           646: loop:  switch(TYPE(temp)) {
        !           647: 
        !           648:        case ATOM:
        !           649:                handy = temp->pname;
        !           650:                break;
        !           651: 
        !           652:        case INT:
        !           653:                sprintf(strbuf,"%d",temp->i);
        !           654:                handy =strbuf;
        !           655:                break;
        !           656: 
        !           657:        case DOUB:
        !           658:                sprintf(strbuf,"%g",temp->r);
        !           659:                handy =strbuf;
        !           660:                break;
        !           661: 
        !           662:        default:
        !           663:                temp = error("Non atom or number to pntlen\n",TRUE);
        !           664:                goto loop;
        !           665:        }
        !           666: 
        !           667:        return( strlen(handy));
        !           668: }

unix.superglobalmegacorp.com

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