Annotation of 41BSD/cmd/lisp/lam3.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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