Annotation of 43BSD/ucb/lisp/franz/lam3.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *rcsid =
                      3:    "$Header: lam3.c,v 1.4 84/04/06 23:08:13 layer Exp $";
                      4: #endif
                      5: 
                      6: /*                                     -[Fri Aug  5 12:47:19 1983 by jkf]-
                      7:  *     lam3.c                          $Locker:  $
                      8:  * lambda functions
                      9:  *
                     10:  * (c) copyright 1982, Regents of the University of California
                     11:  */
                     12: 
                     13: # include "global.h"
                     14: # include "chars.h"
                     15: # include "chkrtab.h"
                     16: 
                     17: lispval
                     18: Lalfalp()
                     19: {
                     20:        register char  *first, *second;
                     21: 
                     22:        chkarg(2,"alphalessp");
                     23:        first = (char *) verify(lbot->val,"alphalessp: non symbol or string arg");
                     24:        second = (char *) verify((lbot+1)->val,"alphalessp: non symbol or string arg");
                     25:        if(strcmp(first,second) < 0)
                     26:                return(tatom);
                     27:        else
                     28:                return(nil);
                     29: }
                     30: 
                     31: lispval
                     32: Lncons()
                     33: {
                     34:        register lispval handy;
                     35: 
                     36:        chkarg(1,"ncons");
                     37:        handy = newdot();
                     38:        handy->d.cdr = nil;
                     39:        handy->d.car = lbot->val;
                     40:        return(handy);
                     41: }
                     42: lispval
                     43: Lzerop()
                     44: {
                     45:        register lispval handy;
                     46: 
                     47:        chkarg(1,"zerop");
                     48:        handy = lbot->val;
                     49:        switch(TYPE(handy)) {
                     50:        case INT:
                     51:                return(handy->i==0?tatom:nil);
                     52:        case DOUB:
                     53:                return(handy->r==0.0?tatom:nil);
                     54:        }
                     55:        return(nil);
                     56: }
                     57: lispval
                     58: Lonep()
                     59: {
                     60:        register lispval handy; 
                     61:        lispval Ladd();
                     62: 
                     63:        handy = lbot->val;
                     64:        switch(TYPE(handy)) {
                     65:        case INT:
                     66:                return(handy->i==1?tatom:nil);
                     67:        case DOUB:
                     68:                return(handy->r==1.0?tatom:nil);
                     69:        case SDOT:
                     70:                protect(inewint(0));
                     71:                handy = Ladd();
                     72:                if(TYPE(handy)!=INT || handy->i !=1)
                     73:                        return(nil);
                     74:                else
                     75:                        return(tatom);
                     76:        }
                     77:        return(nil);
                     78: }
                     79: 
                     80: lispval
                     81: cmpx(lssp)
                     82: {
                     83:        register struct argent *argp;
                     84:        register struct argent *outarg;
                     85:        register struct argent *onp = np;
                     86:        Savestack(3);
                     87: 
                     88: 
                     89:        argp = lbot + 1;
                     90:        outarg = np;
                     91:        while(argp < onp) {
                     92: 
                     93:                np = outarg + 2;
                     94:                lbot = outarg;
                     95:                if(lssp)
                     96:                        *outarg = argp[-1], outarg[1]  = *argp++;
                     97:                else
                     98:                        outarg[1]  = argp[-1], *outarg = *argp++;
                     99:                lbot->val = Lsub();
                    100:                np = lbot + 1;
                    101:                if(Lnegp()==nil) 
                    102:                {
                    103:                    Restorestack();
                    104:                    return(nil);
                    105:                }
                    106:        }
                    107:        Restorestack();
                    108:        return(tatom);
                    109: }
                    110: 
                    111: lispval
                    112: Lgreaterp()
                    113: {
                    114:        register int typ;
                    115:        /* do the easy cases first */
                    116:        if(np-lbot == 2)
                    117:        {   if((typ=TYPE(lbot->val)) == INT)
                    118:            {    if((typ=TYPE(lbot[1].val)) == INT)
                    119:                   return((lbot[0].val->i - lbot[1].val->i) > 0 ? tatom : nil);
                    120:                 else if(typ == DOUB)
                    121:                  return((lbot[0].val->i - lbot[1].val->r) > 0.0 ? tatom : nil);
                    122:            }
                    123:            else if(typ == DOUB)
                    124:            {    if((typ=TYPE(lbot[1].val)) == INT)
                    125:                  return((lbot[0].val->r - lbot[1].val->i) > 0.0 ? tatom : nil);
                    126:                 else if(typ == DOUB)
                    127:                  return((lbot[0].val->r - lbot[1].val->r) > 0.0 ? tatom : nil);
                    128:            }
                    129:        }
                    130:                  
                    131:        return(cmpx(FALSE));
                    132: }
                    133: 
                    134: lispval
                    135: Llessp()
                    136: {
                    137:        register int typ;
                    138:        /* do the easy cases first */
                    139:        if(np-lbot == 2)
                    140:        {   if((typ=TYPE(lbot->val)) == INT)
                    141:            {    if((typ=TYPE(lbot[1].val)) == INT)
                    142:                   return((lbot[0].val->i - lbot[1].val->i) < 0 ? tatom : nil);
                    143:                 else if(typ == DOUB)
                    144:                  return((lbot[0].val->i - lbot[1].val->r) < 0.0 ? tatom : nil);
                    145:            }
                    146:            else if(typ == DOUB)
                    147:            {    if((typ=TYPE(lbot[1].val)) == INT)
                    148:                  return((lbot[0].val->r - lbot[1].val->i) < 0.0 ? tatom : nil);
                    149:                 else if(typ == DOUB)
                    150:                  return((lbot[0].val->r - lbot[1].val->r) < 0.0 ? tatom : nil);
                    151:            }
                    152:        }
                    153:                  
                    154:        return(cmpx(TRUE));
                    155: }
                    156: 
                    157: lispval
                    158: Ldiff()
                    159: {
                    160:        register lispval arg1,arg2; 
                    161:        register handy = 0;
                    162: 
                    163: 
                    164:        chkarg(2,"Ldiff");
                    165:        arg1 = lbot->val;
                    166:        arg2 = (lbot+1)->val;
                    167:        if(TYPE(arg1)==INT && TYPE(arg2)==INT) {
                    168:                handy=arg1->i - arg2->i;
                    169:        }
                    170:        else error("non-numeric argument",FALSE);
                    171:        return(inewint(handy));
                    172: }
                    173: 
                    174: lispval
                    175: Lmod()
                    176: {
                    177:        register lispval arg1,arg2;
                    178:        lispval  handy;
                    179:        struct sdot fake1, fake2;
                    180:        fake2.CDR = 0;
                    181:        fake1.CDR = 0;
                    182: 
                    183:        chkarg(2,"mod");
                    184:        handy = arg1 = lbot->val;
                    185:        arg2 = (lbot+1)->val;
                    186:        switch(TYPE(arg1)) {
                    187:        case SDOT:
                    188:                switch(TYPE(arg2)) {
                    189:                case SDOT:                      /* both are already bignums */
                    190:                        break;
                    191:                case INT:                       /* convert arg2 to bignum   */
                    192:                        fake2.I = arg2->i;
                    193:                        arg2 =(lispval) &fake2;
                    194:                        break;
                    195:                default:
                    196:                        error("non-numeric argument",FALSE);
                    197:                }
                    198:                break;
                    199:        case INT:
                    200:                switch(TYPE(arg2)) {
                    201:                case SDOT:                      /* convert arg1 to bignum */
                    202:                        fake1.I = arg1->i;
                    203:                        arg1 =(lispval) &fake1;
                    204:                        break;
                    205:                case INT:                       /* both are fixnums       */
                    206:                        return( inewint ((arg1->i) % (arg2->i)) );
                    207:                default:
                    208:                        error("non-numeric argument",FALSE);
                    209:                }
                    210:                break;
                    211:        default:
                    212:                error("non-numeric argument",FALSE);
                    213:        }
                    214:        if(TYPE((lbot+1)->val)==INT && lbot[1].val->i==0)
                    215:                return(handy);
                    216:        divbig(arg1,arg2,(lispval *)0,&handy);
                    217:        if(handy==((lispval)&fake1))
                    218:                handy = inewint(fake1.I);
                    219:        if(handy==((lispval)&fake2))
                    220:                handy = inewint(fake2.I);
                    221:        return(handy);
                    222: }
                    223: lispval
                    224: Ladd1()
                    225: {
                    226:        register lispval handy;
                    227:        lispval Ladd();
                    228:        Savestack(1); /* fixup entry mask */
                    229:        chkarg(1,"add1");
                    230: 
                    231:        /* simple test first */
                    232:        if((TYPE(lbot->val) == INT) && (lbot->val->i < MaxINT))
                    233:        {
                    234:            Restorestack();
                    235:            return(inewint(lbot->val->i + 1));
                    236:        }
                    237:        
                    238:        handy = rdrint;
                    239:        handy->i = 1;
                    240:        protect(handy);
                    241:        handy=Ladd();
                    242:        Restorestack();
                    243:        return(handy);
                    244: 
                    245: }
                    246: 
                    247: 
                    248: 
                    249: lispval
                    250: Lsub1()
                    251: {
                    252:        register lispval handy;
                    253:        lispval Ladd();
                    254:        Savestack(1); /* fixup entry mask */
                    255:        chkarg(1,"sub1");
                    256:        
                    257:        if((TYPE(lbot->val) == INT) && (lbot->val->i > MinINT))
                    258:        {
                    259:            Restorestack();
                    260:            return(inewint(lbot->val->i - 1));
                    261:        }
                    262: 
                    263:        handy = rdrint;
                    264:        handy->i = - 1;
                    265:        protect(handy);
                    266:        handy=Ladd();
                    267:        Restorestack();
                    268:        return(handy);
                    269: }
                    270: 
                    271: lispval
                    272: Lminus()
                    273: {
                    274:        register lispval arg1, handy;
                    275:        lispval subbig();
                    276: 
                    277:        chkarg(1,"minus");
                    278:        arg1 = lbot->val;
                    279:        handy = nil;
                    280:        switch(TYPE(arg1)) {
                    281:        case INT:
                    282:                handy= inewint(0 - arg1->i);
                    283:                break;
                    284:        case DOUB:
                    285:                handy = newdoub();
                    286:                handy->r = -arg1->r;
                    287:                break;
                    288:        case SDOT: { struct sdot dummyb;
                    289:                handy = (lispval) &dummyb;
                    290:                handy->s.I = 0;
                    291:                handy->s.CDR = (lispval) 0;
                    292:                handy = subbig(handy,arg1);
                    293:                break; }
                    294: 
                    295:        default:
                    296:                error("non-numeric argument",FALSE);
                    297:        }
                    298:        return(handy);
                    299: }
                    300: 
                    301: lispval
                    302: Lnegp()
                    303: {
                    304:        register lispval handy = np[-1].val, work;
                    305:        register flag = 0;
                    306: 
                    307: loop:
                    308:        switch(TYPE(handy)) {
                    309:        case INT:
                    310:                if(handy->i < 0) flag = TRUE;
                    311:                break;
                    312:        case DOUB:
                    313:                if(handy->r < 0) flag = TRUE;
                    314:                break;
                    315:        case SDOT:
                    316:                for(work = handy;
                    317:                    work->s.CDR!=(lispval) 0;
                    318:                    work = work->s.CDR) {;}
                    319:                if(work->s.I < 0) flag = TRUE;
                    320:                break;
                    321:        default:
                    322:                handy = errorh1(Vermisc,
                    323:                                  "minusp: Non-(int,real,bignum) arg: ",
                    324:                                  nil,
                    325:                                  TRUE,
                    326:                                  0,
                    327:                                  handy);
                    328:                goto loop;
                    329:        }
                    330:        if(flag) return(tatom);
                    331:        return(nil);
                    332: }
                    333: 
                    334: lispval
                    335: Labsval()
                    336: {
                    337:        register lispval arg1;
                    338: 
                    339:        chkarg(1,"absval");
                    340:        arg1 = lbot->val;
                    341:        if(Lnegp()!=nil) return(Lminus());
                    342: 
                    343:        return(arg1);
                    344: }
                    345: 
                    346: /*
                    347:  *
                    348:  * (oblist)
                    349:  *
                    350:  * oblist returns a list of all symbols in the oblist
                    351:  *
                    352:  * written by jkf.
                    353:  */
                    354: lispval
                    355: Loblist()
                    356: {
                    357:     int indx;
                    358:     lispval headp, tailp ;
                    359:     struct atom *symb ;
                    360:     extern int hashtop;
                    361:     Savestack(0);
                    362: 
                    363:     headp = tailp = newdot(); /* allocate first DTPR */
                    364:     protect(headp);            /*protect the list from garbage collection*/
                    365:                                /*line added by kls                       */
                    366: 
                    367:     for( indx=0 ; indx <= hashtop-1 ; indx++ ) /* though oblist */
                    368:     {
                    369:        for( symb = hasht[indx] ;
                    370:             symb != (struct atom *) CNIL ;
                    371:             symb = symb-> hshlnk)
                    372:        {
                    373:            if(TYPE(symb) != ATOM) 
                    374:            {   printf(" non symbol in hasht[%d] = %x: ",indx,symb);
                    375:                printr((lispval) symb,stdout);
                    376:                printf(" \n");
                    377:                fflush(stdout);
                    378:            }
                    379:            tailp->d.car = (lispval) symb  ; /* remember this atom */
                    380:            tailp = tailp->d.cdr = newdot() ; /* link to next DTPR */
                    381:        }
                    382:     }
                    383: 
                    384:     tailp->d.cdr = nil ; /* close the list unfortunately throwing away
                    385:                          the last DTPR
                    386:                          */
                    387:     Restorestack();
                    388:     return(headp);
                    389: }
                    390: 
                    391: /*
                    392:  * Maclisp setsyntax function:
                    393:  *    (setsyntax c s x)
                    394:  * c represents character either by fixnum or atom
                    395:  * s is the atom "macro" or the atom "splicing" (in which case x is the
                    396:  * macro to be invoked); or nil (meaning don't change syntax of c); or
                    397:  * (well thats enough for now) if s is a fixnum then we modify the bits
                    398:  * for c in the readtable.
                    399:  */
                    400: 
                    401: lispval
                    402: Lsetsyn()
                    403: {
                    404:        register lispval s, c;
                    405:        register struct argent *mynp;
                    406:        register index;
                    407:        lispval x   /*  ,debugmode  */;
                    408:        extern unsigned char *ctable;
                    409:        extern lispval Istsrch();
                    410: 
                    411:        switch(np-lbot) {
                    412:        case 2:
                    413:                x= nil;                 /* only 2 args given */
                    414:        case 3:
                    415:                x = lbot[2].val;        /* all three args given */
                    416:                break;
                    417:        default:
                    418:                argerr("setsyntax");
                    419:        }
                    420:        s = Vreadtable->a.clb;
                    421:        chkrtab(s);
                    422:        /* debugging code 
                    423:        debugmode = Istsrch(matom("debugging"))->d.cdr->d.cdr->d.cdr;
                    424:        if(debugmode)  printf("Readtable addr: %x\n",ctable);
                    425:          end debugging code */
                    426:        mynp = lbot;
                    427:        c = (mynp++)->val;
                    428:        s = (mynp++)->val;
                    429: 
                    430:        switch(TYPE(c)) {
                    431:        default:
                    432:                error("neither fixnum, atom or string as char to setsyntax",FALSE);
                    433: 
                    434:        case ATOM:
                    435:                index = *(c->a.pname);
                    436:                if((c->a.pname)[1])
                    437:                    errorh1(Vermisc,"Only 1 char atoms to setsyntax",
                    438:                         nil,FALSE,0,c);
                    439:                break;
                    440: 
                    441:        case INT:
                    442:                index = c->i;
                    443:                break;
                    444: 
                    445:        case STRNG:
                    446:                index = (int) *((char *) c);
                    447:        }
                    448:        switch(TYPE(s)) {
                    449:        case ATOM:
                    450:                if(s==splice || s==macro) {
                    451:                    if(s==splice)
                    452:                            ctable[index] = VSPL;
                    453:                    else if(s==macro)
                    454:                            ctable[index] = VMAC;
                    455:                    if(TYPE(c)!=ATOM) {
                    456:                            strbuf[0] = index;
                    457:                            strbuf[1] = 0;
                    458:                            c = (getatom(TRUE));
                    459:                    }
                    460:                    Iputprop(c,x,lastrtab);
                    461:                    return(tatom);
                    462:                }
                    463: 
                    464:                /* ... fall into */
                    465:        default:  errorh1(Vermisc,"int:setsyntax : illegal second argument ",
                    466:                                nil,FALSE,0,s);
                    467:                /* not reached */
                    468:                
                    469:        case INT:
                    470:                switch(synclass(s->i)) {
                    471:                case CESC: Xesc = (char) index; break;
                    472:                case CDQ: Xdqc = (char) index; break;
                    473:                case CSD: Xsdc = (char) index;  /* string */
                    474:                }
                    475: 
                    476:                if(synclass(ctable[index])==CESC   /* if we changed the current esc */
                    477:                  && (synclass(s->i)!=CESC)          /* to something else, pick current */
                    478:                  && Xesc == (char) index) {
                    479:                        ctable[index] = s->i;
                    480:                        rpltab(CESC,&Xesc);
                    481:                }
                    482:                else if(synclass(ctable[index])==CDQ   /*  likewise for double quote */
                    483:                       && synclass(s->i) != CDQ
                    484:                       && Xdqc == (char) index)  {
                    485:                        ctable[index] = s->i;
                    486:                        rpltab(CDQ,&Xdqc);
                    487:                }
                    488:                else if(synclass(ctable[index]) == CSD  /* and for string delimiter */
                    489:                        && synclass(s->i) != CSD
                    490:                        && Xsdc == (char) index) {
                    491:                         ctable[index] = s->i;
                    492:                         rpltab(CSD,&Xsdc);
                    493:                }
                    494:                else ctable[index] = s->i;
                    495: 
                    496:                break;
                    497: 
                    498:        }
                    499:        return(tatom);
                    500: }
                    501: 
                    502: /*
                    503:  * this aux function is used by setsyntax to determine the new current
                    504:  * escape or double quote character.  It scans the character table for
                    505:  * the first character with the given class (either VESC or VDQ) and
                    506:  * puts that character in Xesc or Xdqc (whichever is pointed to by
                    507:  * addr).
                    508:  */
                    509: rpltab(cclass,addr)
                    510: char cclass;
                    511: unsigned char *addr;
                    512: {
                    513:        register int i;
                    514:        extern unsigned char *ctable;
                    515:        for(i=0; i<=127 && synclass(ctable[i]) != cclass; i++);
                    516:        if(i<=127) *addr = (unsigned char) i;
                    517:        else *addr = '\0';
                    518: }
                    519: 
                    520: 
                    521: /*
                    522:  * int:getsyntax from lisp.
                    523:  * returns the fixnum syntax code from the readtable for the given character.
                    524:  * to be used by the lisp-code function getsyntax, not to be used by 
                    525:  * joe user.
                    526:  */
                    527: lispval
                    528: Lgetsyntax()
                    529: {
                    530:     register char *name;
                    531:     int number, typ;
                    532:     lispval handy;
                    533:     
                    534:     chkarg(1,"int:getsyntax");
                    535:     handy = lbot[0].val;
                    536:     while (1)
                    537:     {
                    538:        if((typ = TYPE(handy)) == ATOM)
                    539:        {
                    540:            name = handy->a.pname;
                    541:        }
                    542:        else if (typ == STRNG)
                    543:        {
                    544:            name = (char *)handy;
                    545:        }
                    546:        else if(typ == INT)
                    547:        {
                    548:            number = handy->i;
                    549:            break;
                    550:        }
                    551:        else {
                    552:            handy =
                    553:              errorh1(Vermisc,"int:getsyntax : bad character ",
                    554:                        nil,TRUE,0,handy);
                    555:            continue;   /* start at the top */
                    556:        }
                    557:        /* figure out the number of the first byte */
                    558:        number = (int) name[0];
                    559:        if(name[1] != '\0')
                    560:        {
                    561:            handy = errorh1(Vermisc,
                    562:            "int:getsyntax : only single character allowed ",
                    563:            nil,TRUE,0,handy);
                    564:        }
                    565:        else break;
                    566:     }
                    567:     /* see if number is within range */
                    568:     if(number < 0 || number > 255)
                    569:        errorh1(Vermisc,"int:getsyntax : character number out of range ",nil,
                    570:                FALSE,0,inewint(number));
                    571:     chkrtab(Vreadtable->a.clb);  /* make sure readtable is correct */
                    572:     return(inewint(ctable[number]));
                    573: }
                    574:     
                    575:     
                    576:        
                    577:     
                    578: lispval
                    579: Lzapline()
                    580: {
                    581:        register FILE *port;
                    582:        extern FILE * rdrport;
                    583: 
                    584:        port = rdrport;
                    585:        while (!feof(port) && (getc(port)!='\n') );
                    586:        return(nil);
                    587: }

unix.superglobalmegacorp.com

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