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

1.1     ! root        1: static char *sccsid = "@(#)lam1.c      34.3 10/24/80";
        !             2: 
        !             3: # include "global.h"
        !             4: # include <sgtty.h>
        !             5: # include "chkrtab.h"
        !             6: /**************************************************************************/
        !             7: /*                                                                        */
        !             8: /*   file: ccdfns.i                                                       */
        !             9: /*   contents: LISP functions coded in C                                  */
        !            10: /*                                                                        */
        !            11: /*   These include LISP primitives, numeric and boolean functions and     */
        !            12: /*     predicates, some list-processing functions, i/o support functions */
        !            13: /*     and control flow functions (e.g. cont, break).                    */
        !            14: /*   There are two types of functions: lambda (prefixed "L") and nlambda  */
        !            15: /*     (prefixed "N").                                                   */
        !            16: /*   Lambda's all call chkarg to insure that at least the minimum number  */
        !            17: /*     of necessary arguments are on the namestack.                      */
        !            18: /*   All functions take their arguments from the namestack in a read-     */
        !            19: /*     only manner, and return their results via the normal C value      */
        !            20: /*     return mechanism.                                                 */
        !            21: /*                                                                       */
        !            22: 
        !            23: lispval
        !            24: Leval()
        !            25: {
        !            26:        register lispval temp;
        !            27: 
        !            28:        chkarg(1,"eval");
        !            29:        temp = lbot->val;
        !            30:            return(eval(temp));
        !            31: }
        !            32: 
        !            33: lispval
        !            34: Lxcar()
        !            35: {      register int typ;
        !            36:        register lispval temp, result;
        !            37: 
        !            38:        chkarg(1,"xcar");
        !            39:        temp = lbot->val;
        !            40:        if (((typ = TYPE(temp)) == DTPR) || (typ == ATOM) || HUNKP(temp))
        !            41:            return(temp->d.car);
        !            42:        else if(typ == SDOT) {
        !            43:                result = inewint(temp->i);
        !            44:                return(result);
        !            45:        } else if(Schainp!=nil && typ==ATOM)
        !            46:                return(nil);
        !            47:        else
        !            48:                return(error("Bad arg to car",FALSE));
        !            49: 
        !            50: }
        !            51: 
        !            52: lispval
        !            53: Lxcdr()
        !            54: {      register int typ;
        !            55:        register lispval temp, result;
        !            56: 
        !            57:        chkarg(1,"xcdr");
        !            58:        temp = lbot->val;
        !            59:        if(temp==nil) return (nil);
        !            60: 
        !            61:        if (((typ = TYPE(temp)) == DTPR) || HUNKP(temp)) 
        !            62:            return(temp->d.cdr);
        !            63:        else if(typ==SDOT) {
        !            64:                if(temp->s.CDR==0) return(nil);
        !            65:                return(temp->s.CDR);
        !            66:        } else if(Schainp!=nil && typ==ATOM)
        !            67:                return(nil);
        !            68:        else
        !            69:                return(error("Bad arg to cdr", FALSE));
        !            70: }
        !            71: 
        !            72: lispval
        !            73: cxxr(as,ds)
        !            74: register int as,ds;
        !            75: {
        !            76: 
        !            77:        register lispval temp, temp2;
        !            78:        int i, typ;
        !            79:        lispval errorh();
        !            80: 
        !            81:        chkarg(1,"c{ad}+r");
        !            82:        temp = lbot->val;
        !            83: 
        !            84:        for( i=0 ; i<ds ; i++)
        !            85:        {
        !            86:            if( temp != nil)
        !            87:            {
        !            88:                typ = TYPE(temp);
        !            89:                if ((typ == DTPR) || HUNKP(temp))
        !            90:                    temp = temp->d.cdr;
        !            91:                else
        !            92:                    if(typ==SDOT)
        !            93:                    {
        !            94:                        if(temp->s.CDR==0)
        !            95:                            temp = nil;
        !            96:                        else
        !            97:                            temp = temp->s.CDR;
        !            98:                    }
        !            99:                else
        !           100:                    if(Schainp!=nil && typ==ATOM)
        !           101:                        return(nil);
        !           102:                else
        !           103:                    return(errorh(Vermisc,"Bad arg to cdr",nil,FALSE,5,temp));
        !           104:            }
        !           105:        }
        !           106: 
        !           107:        for( i=0 ; i<as ; i++)
        !           108:        {
        !           109:            if( temp != nil )
        !           110:            {
        !           111:                typ = TYPE(temp);
        !           112:                if ((typ == DTPR) || HUNKP(temp))
        !           113:                    temp = temp->d.car;
        !           114:                else if(typ == SDOT)
        !           115:                        temp2 = inewint(temp->i), temp = temp2;
        !           116:                else if(Schainp!=nil && typ==ATOM)
        !           117:                    return(nil);
        !           118:                else
        !           119:                    return(errorh(Vermisc,"Bad arg to car",nil,FALSE,5,temp));
        !           120:            }
        !           121:        }
        !           122: 
        !           123:        return(temp);
        !           124: }
        !           125: 
        !           126: lispval
        !           127: Lcar()
        !           128: {      return(cxxr(1,0)); }
        !           129: 
        !           130: lispval
        !           131: Lcdr()
        !           132: {      return(cxxr(0,1)); }
        !           133: 
        !           134: lispval
        !           135: Lcadr()
        !           136: {      return(cxxr(1,1)); }
        !           137: 
        !           138: lispval
        !           139: Lcaar()
        !           140: {      return(cxxr(2,0)); }
        !           141: 
        !           142: lispval
        !           143: Lc02r()
        !           144: {      return(cxxr(0,2)); }    /* cddr */
        !           145: 
        !           146: lispval
        !           147: Lc12r()
        !           148: {      return(cxxr(1,2)); }    /* caddr */
        !           149: 
        !           150: lispval
        !           151: Lc03r()
        !           152: {      return(cxxr(0,3)); }    /* cdddr */
        !           153: 
        !           154: lispval
        !           155: Lc13r()
        !           156: {      return(cxxr(1,3)); }    /* cadddr */
        !           157: 
        !           158: lispval
        !           159: Lc04r()
        !           160: {      return(cxxr(0,4)); }    /* cddddr */
        !           161: 
        !           162: lispval
        !           163: Lc14r()
        !           164: {      return(cxxr(1,4)); }    /* caddddr */
        !           165: 
        !           166: /*
        !           167:  *  
        !           168:  *     (nthelem num list)
        !           169:  *
        !           170:  * Returns the num'th element of the list, by doing a caddddd...ddr
        !           171:  * where there are num-1 d's. If num<=0 or greater than the length of
        !           172:  * the list, we return nil.
        !           173:  *
        !           174:  */
        !           175: 
        !           176: lispval
        !           177: Lnthelem()
        !           178: {
        !           179:        register lispval temp;
        !           180:        register int i;
        !           181: 
        !           182:        chkarg(2,"nthelem");
        !           183: 
        !           184:        if( TYPE(temp = lbot->val) != INT)
        !           185:        return (error ("First arg to nthelem must be a fixnum",FALSE));
        !           186: 
        !           187:        i = temp->i;    /* pick up the first arg */
        !           188: 
        !           189:        if( i <= 0) return(nil);
        !           190: 
        !           191:        ++lbot;                 /* fix lbot for call to cxxr() 'cadddd..r' */
        !           192:        temp = cxxr(1,i-1);
        !           193:        --lbot;
        !           194: 
        !           195:        return(temp);
        !           196: }
        !           197: 
        !           198: lispval
        !           199: Lscons()
        !           200: {
        !           201:        register struct argent *argp = lbot;
        !           202:        register lispval retp, handy;
        !           203:        register int typ;
        !           204: 
        !           205:        chkarg(2,"scons");
        !           206:        retp = newsdot();
        !           207:        handy = (argp) -> val;
        !           208:        if(TYPE(handy)!=INT)
        !           209:                error("First arg to scons must be an int.",FALSE);
        !           210:        retp->s.I = handy->i;
        !           211:        handy = (argp+1)->val;
        !           212:        if(handy==nil)
        !           213:                retp->s.CDR = (lispval) 0;
        !           214:        else {
        !           215:                if(TYPE(handy)!=SDOT)
        !           216:                    error("Currently you may only link sdots to sdots.",FALSE);
        !           217:                retp->s.CDR = handy;
        !           218:        }
        !           219:        return(retp);
        !           220: }
        !           221: 
        !           222: lispval
        !           223: Lcons()
        !           224: {
        !           225:        register lispval retp;
        !           226:        register struct argent *argp;
        !           227: 
        !           228:        chkarg(2,"cons");
        !           229:        retp = newdot();
        !           230:        retp->d.car = ((argp = lbot) -> val);
        !           231:        retp->d.cdr = argp[1].val;
        !           232:        return(retp);
        !           233: }
        !           234: #define CA 0
        !           235: #define CD 1
        !           236: 
        !           237: lispval
        !           238: rpla(what)
        !           239: int what;
        !           240: {      register struct argent *argp;
        !           241:        register int typ; register lispval first, second;
        !           242: 
        !           243:        chkarg(2,"rplac[ad]");
        !           244:        argp = np-1;
        !           245:        first = (argp-1)->val;
        !           246:        while(first==nil)
        !           247:                first = error("Attempt to rplac[ad] nil.",TRUE);
        !           248:        second = argp->val;
        !           249:        if (((typ = TYPE(first)) == DTPR) || (typ == ATOM) || HUNKP(first)) {
        !           250:                if (what == CA)
        !           251:                        first->d.car = second;
        !           252:                else 
        !           253:                        first->d.cdr = second;
        !           254:                return(first);
        !           255:        }
        !           256:        if (typ==SDOT) {
        !           257:                if(what == CA) {
        !           258:                        typ = TYPE(second);
        !           259:                        if(typ!=INT) error("Rplacca of a bignum will only replace INTS",FALSE);
        !           260:                        first->s.I = second->i;
        !           261:                } else {
        !           262:                        if(second==nil)
        !           263:                                first->s.CDR = (lispval) 0;
        !           264:                        else
        !           265:                                first->s.CDR = second;
        !           266:                }
        !           267:                return(first);
        !           268:        }
        !           269:        return(error("Bad arg to rpla",FALSE));
        !           270: }
        !           271: lispval
        !           272: Lrplaca()
        !           273: {      return(rpla(CA));       }
        !           274: 
        !           275: lispval
        !           276: Lrplacd()
        !           277: {      return(rpla(CD));       }
        !           278: 
        !           279: 
        !           280: lispval
        !           281: Leq()
        !           282: {
        !           283:        register struct argent *mynp = lbot + AD;
        !           284:        int itemp, flag;
        !           285: 
        !           286:        chkarg(2,"eq");
        !           287:        if(mynp->val==(mynp+1)->val) return(tatom);
        !           288:        return(nil);
        !           289: }
        !           290: 
        !           291: 
        !           292: 
        !           293: lispval
        !           294: Lnull()
        !           295: {      chkarg(1,"null");
        !           296:        return ((lbot->val == nil) ? tatom : nil);
        !           297: }
        !           298: 
        !           299: 
        !           300: 
        !           301: /* Lreturn **************************************************************/
        !           302: /* Returns the first argument - which is nill if not specified.                */
        !           303: 
        !           304: Lreturn()
        !           305:        {
        !           306:        snpand(0);
        !           307:        if(lbot==np) protect (nil);
        !           308:        contval = lbot->val;
        !           309:        reset(BRRETN);
        !           310:        }
        !           311: 
        !           312: 
        !           313: /* Lretbrk **************************************************************/
        !           314: /* The first argument must be an integer and must be in the range      */
        !           315: /* -1 .. -depth.                                                       */
        !           316: lispval
        !           317: Lretbrk()
        !           318:        {
        !           319:        lispval number;
        !           320:        register level;
        !           321: 
        !           322:        snpand(1);
        !           323:        if(lbot==np) protect (nil);
        !           324:        number = lbot->val;
        !           325:        if (TYPE(number) != INT)
        !           326:                level = -1;
        !           327:        else
        !           328:                level = number->i;
        !           329:        if(level < 0)
        !           330:                level += depth;
        !           331:        contval = (lispval) level;
        !           332:        if (level < depth)
        !           333:                reset(BRRETB);
        !           334:        return(nil);
        !           335: }
        !           336: 
        !           337: 
        !           338: 
        !           339: lispval
        !           340: Linfile()
        !           341: {
        !           342:        FILE *port;
        !           343:        register lispval name;
        !           344:        int typ;
        !           345:        snpand(1);
        !           346: 
        !           347:        chkarg(1,"infile");
        !           348:        name = lbot->val;
        !           349: loop:
        !           350:        name = verify(name,"infile: file name must be atom or string");
        !           351:        /* return nil if file couldnt be opened
        !           352:        if ((port = fopen((char *)name,"r")) == NULL) return(nil); */   
        !           353: 
        !           354:        if ((port = fopen((char *)name,"r")) == NULL) {
        !           355:                name = errorh(Vermisc,"Unable to open file for reading.",nil,TRUE,31,name);
        !           356:                goto loop;
        !           357:        }
        !           358:        ioname[PN(port)] = (lispval) inewstr(name);     /* remember name */
        !           359:        return(P(port));
        !           360: }
        !           361: 
        !           362: lispval
        !           363: Loutfile()
        !           364: {
        !           365:        FILE *port; register lispval name;
        !           366: 
        !           367:        chkarg(1,"outfile");
        !           368:        name = lbot->val;
        !           369: loop:
        !           370:        name = verify(name,"Please supply atom or string name for port.");
        !           371:        if ((port = fopen(name,"w")) == NULL) {
        !           372:                name = errorh(Vermisc,"Unable to open file for writing.",nil,TRUE,31,name);
        !           373:                goto loop;
        !           374:        }
        !           375:        ioname[PN(port)] = (lispval) inewstr(name);
        !           376:        return(P(port));
        !           377: }
        !           378: 
        !           379: lispval
        !           380: Lterpr()
        !           381: {
        !           382:        FILE *port;
        !           383: 
        !           384:        snpand(0);
        !           385:        if(lbot==np) protect (nil);
        !           386:        port = okport(lbot->val,okport(Vpoport->a.clb,stdout));
        !           387:        putc('\n',port);
        !           388:        fflush(port);
        !           389:        return(nil);
        !           390: }
        !           391: 
        !           392: lispval
        !           393: Lclose()
        !           394: {
        !           395:        lispval port;
        !           396: 
        !           397:        if(lbot==np)
        !           398:                port = error("Close requires one argument of type port",TRUE);
        !           399:        port = lbot->val;
        !           400:        if((TYPE(port))==PORT) fclose(port->p);
        !           401:        ioname[PN(port->p)] = nil;
        !           402:        return(tatom);
        !           403: }
        !           404: 
        !           405: lispval
        !           406: Lnwritn()
        !           407: {
        !           408:        register FILE *port;
        !           409:        register value;
        !           410: 
        !           411:        snpand(2);
        !           412:        if(lbot==np) protect (nil);
        !           413:        port = okport(lbot->val,okport(Vpoport->a.clb,stdout));
        !           414:        value = port->_ptr - port->_base;
        !           415:        return(inewint(value));
        !           416: }
        !           417: 
        !           418: lispval
        !           419: Ldrain()
        !           420: {
        !           421:        register FILE *port;
        !           422:        register int iodes;
        !           423:        struct sgttyb arg;
        !           424: 
        !           425:        snpand(2);
        !           426:        if(lbot==np) protect (nil);
        !           427:        port = okport(lbot->val, okport(Vpoport->a.clb,stdout));
        !           428:        if(port->_flag & _IOWRT) {
        !           429:                fflush(port);
        !           430:                return(nil);
        !           431:        }
        !           432:        if(! port->_flag & _IOREAD) return(nil);
        !           433:        port->_cnt = 0;
        !           434:        port->_ptr = port->_base;
        !           435:        iodes = fileno(port);
        !           436:        if(gtty(iodes,&arg) != -1) stty(iodes,&arg);
        !           437:        return((lispval)(xports + (port - _iob)));
        !           438: }
        !           439: 
        !           440: lispval
        !           441: Llist()
        !           442: {
        !           443:        /* added for the benefit of mapping functions. */
        !           444:        register struct argent *ulim, *namptr;
        !           445:        register lispval temp, result;
        !           446:        register struct argent *lbot, *np;
        !           447: 
        !           448:        ulim = np;
        !           449:        namptr = lbot + AD;
        !           450:        temp = result = (lispval) np;
        !           451:        protect(nil);
        !           452:        for(; namptr < ulim;) {
        !           453:                temp = temp->l = newdot();
        !           454:                temp->d.car = (namptr++)->val;
        !           455:        }
        !           456:        temp->l = nil;
        !           457:        return(result->l);
        !           458: }
        !           459: 
        !           460: lispval
        !           461: Lnumberp()
        !           462: {
        !           463:        chkarg(1,"numberp");
        !           464:        switch(TYPE(lbot->val)) {
        !           465:        case INT: case DOUB: case SDOT:
        !           466:                return(tatom);
        !           467:        }
        !           468:        return(nil);
        !           469: }
        !           470: 
        !           471: lispval
        !           472: Latom()
        !           473: {
        !           474:        register struct argent *lb = lbot;
        !           475:        chkarg(1,"atom");
        !           476:        if(TYPE(lb->val)==DTPR || (HUNKP(lb->val)))
        !           477:                return(nil);
        !           478:        else
        !           479:                return(tatom);
        !           480: }
        !           481: 
        !           482: lispval
        !           483: Ltype()
        !           484: {
        !           485:        chkarg(1,"type");
        !           486:        switch(TYPE(lbot->val)) {
        !           487:        case INT:
        !           488:                return(int_name);
        !           489:        case ATOM:
        !           490:                return(atom_name);
        !           491:        case SDOT:
        !           492:                return(sdot_name);
        !           493:        case DOUB:
        !           494:                return(doub_name);
        !           495:        case DTPR:
        !           496:                return(dtpr_name);
        !           497:        case STRNG:
        !           498:                return(str_name);
        !           499:        case ARRAY:
        !           500:                return(array_name);
        !           501:        case BCD:
        !           502:                return(funct_name);
        !           503: 
        !           504:        case HUNK2:
        !           505:                return(hunk_name[0]);
        !           506:        case HUNK4:
        !           507:                return(hunk_name[1]);
        !           508:        case HUNK8:
        !           509:                return(hunk_name[2]);
        !           510:        case HUNK16:
        !           511:                return(hunk_name[3]);
        !           512:        case HUNK32:
        !           513:                return(hunk_name[4]);
        !           514:        case HUNK64:
        !           515:                return(hunk_name[5]);
        !           516:        case HUNK128:
        !           517:                return(hunk_name[6]);
        !           518: 
        !           519:        case VALUE:
        !           520:                return(val_name);
        !           521:        case PORT:
        !           522:                return(port_name);
        !           523:        }
        !           524:        return(nil);
        !           525: }
        !           526: 
        !           527: lispval
        !           528: Ldtpr()
        !           529: {
        !           530:        chkarg(1,"dtpr");
        !           531:        return(typred(DTPR, lbot->val));
        !           532: }
        !           533: 
        !           534: lispval
        !           535: Lbcdp()
        !           536: {
        !           537:        chkarg(1,"bcdp");
        !           538:        return(typred(BCD, lbot->val));
        !           539: }
        !           540: 
        !           541: lispval
        !           542: Lportp()
        !           543: {
        !           544:        chkarg(1,"portp");
        !           545:        return(typred(PORT, lbot->val));
        !           546: }
        !           547: 
        !           548: lispval
        !           549: Larrayp()
        !           550: {
        !           551:        chkarg(1,"arrayp");
        !           552:        return(typred(ARRAY, lbot->val));
        !           553: }
        !           554: 
        !           555: /*
        !           556:  *     (hunkp 'g_arg1)
        !           557:  * Returns t if g_arg1 is a hunk, otherwise returns nil.
        !           558:  */
        !           559: 
        !           560: lispval
        !           561: Lhunkp()
        !           562: {
        !           563:        chkarg(1,"hunkp");
        !           564:        if (HUNKP(lbot->val))
        !           565:                return(tatom);          /* If a hunk, return t */
        !           566:        else
        !           567:                return(nil);            /* else nil */
        !           568: }
        !           569: 
        !           570: lispval
        !           571: Lset()
        !           572: {
        !           573:        lispval varble;
        !           574:        snpand(0);
        !           575: 
        !           576:        chkarg(2,"set");
        !           577:        varble = lbot->val;
        !           578:        switch(TYPE(varble))
        !           579:                {
        !           580:        case ATOM:      return(varble->a.clb = lbot[1].val);
        !           581: 
        !           582:        case VALUE:     return(varble->l = lbot[1].val);
        !           583:                }
        !           584: 
        !           585:        error("IMPROPER USE OF SET",FALSE);
        !           586: }
        !           587: 
        !           588: lispval
        !           589: Lequal()
        !           590: {
        !           591:        register lispval first, second;
        !           592:        register type1, type2;
        !           593:        register struct argent *lbot, *np;
        !           594:        lispval Lsub(),Lzerop(), *stack(), unstack(), *sp();
        !           595:        lispval *oldsp; int mustloop = FALSE, result;
        !           596:        chkarg(2,"equal");
        !           597: 
        !           598: 
        !           599:        if(lbot->val==lbot[1].val) return(tatom);
        !           600: 
        !           601:        for((oldsp=sp(), stack(lbot->val,lbot[1].val));
        !           602:            oldsp > sp();) {
        !           603: 
        !           604:            first = unstack(); second = unstack();
        !           605:     again:
        !           606:            if(first==second) continue;
        !           607: 
        !           608:            type1=TYPE(first); type2=TYPE(second);
        !           609:            if(type1!=type2) {
        !           610:                if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT))
        !           611:                    goto dosub;
        !           612:                return(nil);
        !           613:            }
        !           614:            switch(type1) {
        !           615:            case DTPR:
        !           616:                stack(first->d.cdr,second->d.cdr);
        !           617:                first = first->d.car; second = second->d.car;
        !           618:                goto again;
        !           619:            case DOUB:
        !           620:                if(first->r!=second->r)
        !           621:                    return(nil);
        !           622:                continue;
        !           623:            case INT:
        !           624:                if(first->i!=second->i)
        !           625:                    return(nil);
        !           626:                continue;
        !           627:     dosub:
        !           628:            case SDOT:
        !           629:                lbot = np;
        !           630:                np++->val = first;
        !           631:                np++->val = second;
        !           632:                lbot->val = Lsub();
        !           633:                if(TYPE(lbot->val)!=INT || lbot->val->i!=0)
        !           634:                    return(nil);
        !           635:                np = lbot;
        !           636:                continue;
        !           637:            case VALUE:
        !           638:                if(first->l!=second->l)
        !           639:                    return(nil);
        !           640:                continue;
        !           641:            case STRNG:
        !           642:                if(strcmp(first,second)!=0)
        !           643:                    return(nil);
        !           644:                continue;
        !           645: 
        !           646:            default:
        !           647:                return(nil);
        !           648:            }
        !           649:        }
        !           650:        return(tatom);
        !           651: }
        !           652: lispval
        !           653: oLequal()
        !           654: {
        !           655:        chkarg(2,"equal");
        !           656: 
        !           657:        if( lbot[1].val == lbot->val ) return(tatom);
        !           658:        if(Iequal(lbot[1].val,lbot->val)) return(tatom); else return(nil);
        !           659: }
        !           660: 
        !           661: Iequal(first,second) 
        !           662: register lispval first, second;
        !           663: {
        !           664:        register type1, type2;
        !           665:        register struct argent *lbot, *np;
        !           666:        lispval Lsub(),Lzerop();
        !           667: 
        !           668:        if(first==second)
        !           669:                return(1);
        !           670:        type1=TYPE(first);
        !           671:        type2=TYPE(second);
        !           672:        if(type1!=type2) {
        !           673:                if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT))
        !           674:                        goto dosub;
        !           675:                return(0);
        !           676:        }
        !           677:        switch(type1) {
        !           678:        case DTPR:
        !           679:                 return(
        !           680:                        Iequal(first->d.car,second->d.car) &&
        !           681:                        Iequal(first->d.cdr,second->d.cdr) );
        !           682:        case DOUB:
        !           683:                return(first->r==second->r);
        !           684:        case INT:
        !           685:                return( (first->i==second->i));
        !           686: dosub:
        !           687:        case SDOT:
        !           688:                lbot = np;
        !           689:                np++->val = first;
        !           690:                np++->val = second;
        !           691:                lbot->val = Lsub();
        !           692:                np = lbot + 1;
        !           693:                return(TYPE(lbot->val)==INT&& lbot->val->i==0);
        !           694:        case VALUE:
        !           695:                return( first->l==second->l );
        !           696:        case STRNG:
        !           697:                return(strcmp(first,second)==0);
        !           698:        }
        !           699:        return(0);
        !           700: }
        !           701: lispval
        !           702: Zequal()
        !           703: {
        !           704:        register lispval first, second;
        !           705:        register type1, type2;
        !           706:        register struct argent *lbot, *np;
        !           707:        lispval Lsub(),Lzerop(), *stack(), unstack(), *sp();
        !           708:        lispval *oldsp; int mustloop = FALSE, result;
        !           709:        chkarg(2,"equal");
        !           710: 
        !           711: 
        !           712:        if(lbot->val==lbot[1].val) return(tatom);
        !           713: 
        !           714:        for((oldsp=sp(), stack(lbot->val,lbot[1].val));
        !           715:            oldsp > sp();) {
        !           716: 
        !           717:            first = unstack(); second = unstack();
        !           718:     again:
        !           719:            if(first==second) continue;
        !           720: 
        !           721:            type1=TYPE(first); type2=TYPE(second);
        !           722:            if(type1!=type2) {
        !           723:                if((type1==SDOT&&type2==INT)||(type1==INT&&type2==SDOT))
        !           724:                    goto dosub;
        !           725:                return(nil);
        !           726:            }
        !           727:            switch(type1) {
        !           728:            case DTPR:
        !           729:                stack(first->d.cdr,second->d.cdr);
        !           730:                first = first->d.car; second = second->d.car;
        !           731:                goto again;
        !           732:            case DOUB:
        !           733:                if(first->r!=second->r)
        !           734:                    return(nil);
        !           735:                continue;
        !           736:            case INT:
        !           737:                if(first->i!=second->i)
        !           738:                    return(nil);
        !           739:                continue;
        !           740:     dosub:
        !           741:            case SDOT:
        !           742:                lbot = np;
        !           743:                np++->val = first;
        !           744:                np++->val = second;
        !           745:                lbot->val = Lsub();
        !           746:                if(TYPE(lbot->val)!=INT || lbot->val->i!=0)
        !           747:                    return(nil);
        !           748:                np = lbot;
        !           749:                continue;
        !           750:            case VALUE:
        !           751:                if(first->l!=second->l)
        !           752:                    return(nil);
        !           753:                continue;
        !           754:            case STRNG:
        !           755:                if(strcmp(first,second)!=0)
        !           756:                    return(nil);
        !           757:                continue;
        !           758:            }
        !           759:        }
        !           760:        return(tatom);
        !           761: }
        !           762: 
        !           763: lispval
        !           764: Lprint()
        !           765: {
        !           766:        extern int prinlevel,prinlength;
        !           767: 
        !           768:        snpand(0);
        !           769:        if(np-lbot==1) protect(nil);
        !           770:        chkarg(2,"print");
        !           771:        chkrtab(Vreadtable->a.clb);
        !           772:        if(TYPE(Vprinlevel->a.clb) == INT)
        !           773:        { 
        !           774:           prinlevel = Vprinlevel->a.clb->i;
        !           775:        }
        !           776:        else prinlevel = -1;
        !           777:        if(TYPE(Vprinlength->a.clb) == INT)
        !           778:        {
        !           779:            prinlength = Vprinlength->a.clb->i;
        !           780:        }
        !           781:        else prinlength = -1;
        !           782:        printr(lbot->val,okport(lbot[1].val,okport(Vpoport->a.clb,poport)));
        !           783:        return(nil);
        !           784: }
        !           785: 
        !           786: /* patom does not use prinlevel or prinlength */
        !           787: lispval
        !           788: Lpatom()
        !           789: {
        !           790:        register lispval temp;
        !           791:        register int typ;
        !           792:        FILE *port;
        !           793:        extern int prinlevel,prinlength;
        !           794: 
        !           795:        snpand(2);
        !           796:        if(np-lbot==1) protect(nil);
        !           797:        chkarg(2,"patom");
        !           798:        temp = Vreadtable->a.clb;
        !           799:        chkrtab(temp);
        !           800:        port = okport(lbot[1].val, okport(Vpoport->a.clb,stdout));
        !           801:        if ((typ= TYPE((temp = (lbot)->val))) == ATOM)
        !           802:                fputs(temp->a.pname, port);
        !           803:        else if(typ == STRNG)
        !           804:                fputs(temp,port);
        !           805:        else
        !           806:        {
        !           807:                printr(temp, port);
        !           808:        }
        !           809:        return(temp);
        !           810: }
        !           811: 
        !           812: /*
        !           813:  * (pntlen thing) returns the length it takes to print out
        !           814:  * an atom or number.
        !           815:  */
        !           816: 
        !           817: lispval
        !           818: Lpntlen()
        !           819: {
        !           820:        register lispval temp;
        !           821:        return(inewint(Ipntlen()));
        !           822: }
        !           823: Ipntlen()
        !           824: {
        !           825:        register lispval temp;
        !           826:        register char *handy;
        !           827: 
        !           828:        temp = np[-1].val;
        !           829: loop:  switch(TYPE(temp)) {
        !           830: 
        !           831:        case ATOM:
        !           832:                handy = temp->a.pname;
        !           833:                break;
        !           834: 
        !           835:        case STRNG:
        !           836:                handy = (char *) temp;
        !           837:                break;
        !           838: 
        !           839:        case INT:
        !           840:                sprintf(strbuf,"%d",temp->i);
        !           841:                handy =strbuf;
        !           842:                break;
        !           843: 
        !           844:        case DOUB:
        !           845:                sprintf(strbuf,"%g",temp->r);
        !           846:                handy =strbuf;
        !           847:                break;
        !           848: 
        !           849:        default:
        !           850:                temp = error("Non atom or number to pntlen\n",TRUE);
        !           851:                goto loop;
        !           852:        }
        !           853: 
        !           854:        return( strlen(handy));
        !           855: }
        !           856: #undef okport
        !           857: FILE *
        !           858: okport(arg,proper) 
        !           859: lispval arg;
        !           860: FILE *proper;
        !           861: {
        !           862:        if(TYPE(arg)!=PORT)
        !           863:                return(proper);
        !           864:        else
        !           865:                return(arg->p);
        !           866: }

unix.superglobalmegacorp.com

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