Annotation of 3BSD/cmd/lisp/lam1.c, revision 1.1.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.