Annotation of 42BSD/ucb/lisp/franz/lam8.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *rcsid =
                      3:    "$Header: lam8.c,v 1.9 83/09/12 14:16:52 sklower Exp $";
                      4: #endif
                      5: 
                      6: /*                                     -[Fri Aug 12 07:54:00 1983 by jkf]-
                      7:  *     lam8.c                          $Locker:  $
                      8:  * lambda functions
                      9:  *
                     10:  * (c) copyright 1982, Regents of the University of California
                     11:  */
                     12: 
                     13: #include "global.h"
                     14: #include <sys/types.h>
                     15: #include <sys/stat.h>
                     16: #include "frame.h"
                     17: 
                     18: /* various functions from the c math library */
                     19: double sin(),cos(),asin(),acos(),atan2(),sqrt(), log(), exp();
                     20: extern int current;
                     21: 
                     22: lispval Imath(func)
                     23: double (*func)();
                     24: {
                     25:        register lispval handy;
                     26:        register double res;
                     27:        chkarg(1,"Math functions");
                     28: 
                     29:        switch(TYPE(handy=lbot->val)) {
                     30:         case INT: res = func((double)handy->i); 
                     31:                   break;
                     32: 
                     33:         case DOUB: res = func(handy->r);
                     34:                   break;
                     35: 
                     36:         default:  error("Non fixnum or flonum to math function",FALSE);
                     37:        }
                     38:        handy = newdoub();
                     39:        handy->r = res;
                     40:        return(handy);
                     41: }
                     42: lispval Lsin()
                     43: {
                     44:        return(Imath(sin));
                     45: }
                     46: 
                     47: lispval Lcos()
                     48: {
                     49:        return(Imath(cos));
                     50: }
                     51: 
                     52: lispval Lasin()
                     53: {
                     54:        return(Imath(asin));
                     55: }
                     56: 
                     57: lispval Lacos()
                     58: {
                     59:        return(Imath(acos));
                     60: }
                     61: 
                     62: lispval Lsqrt()
                     63: {
                     64:        return(Imath(sqrt));
                     65: }
                     66: lispval Lexp()
                     67: {
                     68:        return(Imath(exp));
                     69: }
                     70: 
                     71: lispval Llog()
                     72: {
                     73:        return(Imath(log));
                     74: }
                     75: 
                     76: /* although we call this atan, it is really atan2 to the c-world,
                     77:    that is, it takes two args
                     78:  */
                     79: lispval Latan()
                     80: {
                     81:        register lispval arg;
                     82:        register double arg1v;
                     83:        register double res;
                     84:        chkarg(2,"arctan");
                     85: 
                     86:        switch(TYPE(arg=lbot->val)) {
                     87: 
                     88:        case INT:  arg1v = (double) arg->i;
                     89:                   break;
                     90: 
                     91:        case DOUB: arg1v = arg->r;
                     92:                   break;
                     93: 
                     94:        default:   error("Non fixnum or flonum arg to atan2",FALSE);
                     95:        }
                     96: 
                     97:        switch(TYPE(arg = (lbot+1)->val)) {
                     98: 
                     99:        case INT: res = atan2(arg1v,(double) arg->i);
                    100:                  break;
                    101: 
                    102:        case DOUB: res = atan2(arg1v, arg->r);
                    103:                  break;
                    104: 
                    105:        default:  error("Non fixnum or flonum to atan2",FALSE);
                    106:        }
                    107:        arg = newdoub();
                    108:        arg->r = res;
                    109:        return(arg);
                    110: }
                    111: 
                    112: /* (random) returns a fixnum in the range -2**30 to 2**30 -1
                    113:    (random fixnum) returns a fixnum in the range 0 to fixnum-1
                    114:  */
                    115: lispval
                    116: Lrandom()
                    117: {
                    118:        register int curval;
                    119:        float pow();
                    120: 
                    121:        curval = rand();        /* get numb from 0 to 2**31-1 */
                    122: 
                    123:        if(np==lbot) return(inewint(curval-(int)pow((double)2,(double)30)));
                    124: 
                    125:        if((TYPE(lbot->val) != INT)
                    126:            || (lbot->val->i <= 0)) errorh1(Vermisc,"random: non fixnum arg:",
                    127:                                                 nil, FALSE, 0, lbot->val);
                    128: 
                    129:        return(inewint(curval % lbot->val->i )); 
                    130: 
                    131: }
                    132: lispval
                    133: Lmakunb()
                    134: {
                    135:        register lispval work;
                    136: 
                    137:        chkarg(1,"makunbound");
                    138:        work = lbot->val;
                    139:        if(work==nil || (TYPE(work)!=ATOM))
                    140:                return(work);
                    141:        work->a.clb = CNIL;
                    142:        return(work);
                    143: }
                    144: 
                    145: lispval
                    146: Lfseek()
                    147: {
                    148: 
                    149:        FILE *f;
                    150:        long offset, whence;
                    151:        lispval retp;
                    152: 
                    153:        chkarg(3,"fseek");                      /* Make sure there are three arguments*/
                    154: 
                    155:        f = lbot->val->p;               /* Get first argument into f */
                    156:        if (TYPE(lbot->val)!=PORT)      /* Check type of first */
                    157:                error("fseek: First argument must be a port.",FALSE);
                    158: 
                    159:        offset = lbot[1].val->i;        /* Get second argument */
                    160:        if (TYPE(lbot[1].val)!=INT)
                    161:                error("fseek: Second argument must be an integer.",FALSE);
                    162: 
                    163:        whence = lbot[2].val->i;        /* Get last arg */
                    164:        if (TYPE(lbot[2].val)!=INT)
                    165:                error("fseek: Third argument must be an integer.",FALSE);
                    166: 
                    167:        if (fseek(f, offset, (int)whence) == -1)
                    168:                error("fseek: Illegal parameters.",FALSE);
                    169: 
                    170:        retp = inewint(ftell(f));
                    171: 
                    172:        return((lispval) retp);
                    173: }
                    174: 
                    175: /* function hashtabstat  : return list of number of members in  each bucket */
                    176: lispval Lhashst()
                    177: {
                    178:        register lispval handy,cur;
                    179:        register struct atom *pnt;
                    180:        int i,cnt;
                    181:        extern int hashtop;
                    182:        Savestack(3);
                    183: 
                    184:        handy = newdot();
                    185:        protect(handy);
                    186:        cur = handy;
                    187:        for(i = 0; i < hashtop; i++)
                    188:        {
                    189:            pnt = hasht[i];
                    190:            for(cnt = 0; pnt != (struct atom *) CNIL ; pnt=pnt->hshlnk , cnt++);
                    191:            cur->d.cdr = newdot();
                    192:            cur = cur->d.cdr;
                    193:            cur->d.car = inewint(cnt);
                    194:        }
                    195:        cur->d.cdr = nil;
                    196:        Restorestack();
                    197:        return(handy->d.cdr);
                    198: }
                    199: 
                    200: 
                    201: /* Lctcherr
                    202:   this routine should only be called by the unwind protect simulation
                    203:   lisp code
                    204:   It is called after an unwind-protect frame has been entered and
                    205:   evalated and we want to get on with the error or throw
                    206:   We only handle the case where there are 0 to 2 extra arguments to the
                    207:   error call.
                    208: */
                    209: lispval
                    210: Lctcherr()
                    211: {
                    212:        register lispval handy;
                    213:        lispval type,messg,valret,contuab,uniqid,datum1,datum2;
                    214: 
                    215:        chkarg(1,"I-throw-err");
                    216: 
                    217:        handy = lbot->val;
                    218:        
                    219:        if(TYPE(handy->d.car) == INT)
                    220:        {       /* continuing a non error (throw,reset, etc) */
                    221:                Inonlocalgo((int)handy->d.car->i,
                    222:                            handy->d.cdr->d.car, 
                    223:                            handy->d.cdr->d.cdr->d.car);
                    224:                /* NOT REACHED */
                    225:        }
                    226: 
                    227:        if(handy->d.car != nil)
                    228:        {
                    229:            errorh1(Vermisc,"I-do-throw: first element not fixnum or nil",
                    230:                   nil,FALSE,0,handy);
                    231:        }
                    232:            
                    233:        /* decode the arg list */
                    234:        handy = handy->d.cdr;
                    235:        type = handy->d.car;
                    236:        handy = handy->d.cdr;
                    237:        messg = handy->d.car;
                    238:        handy = handy->d.cdr;
                    239:        valret = handy->d.car;
                    240:        handy = handy->d.cdr;
                    241:        contuab = handy->d.car;
                    242:        handy = handy->d.cdr;
                    243:        uniqid = handy->d.car;
                    244:        handy = handy->d.cdr;
                    245: 
                    246:        /* if not extra args */
                    247:        if(handy == nil)
                    248:        {
                    249:          errorh(type,messg->a.pname,valret,(int)contuab->i,(int)uniqid->i);
                    250:        }
                    251:        datum1 = handy->d.car;
                    252:        handy = handy->d.cdr;
                    253: 
                    254:        /* if one extra arg */
                    255:        if(handy == nil)
                    256:        {
                    257:          errorh1(type,messg->a.pname,valret,(int)contuab->i,(int)uniqid->i,datum1);
                    258:        }
                    259: 
                    260:        /* if two or more extra args, just use first 2 */
                    261:        datum2 = handy->d.car;
                    262:        errorh2(type,messg->a.pname,valret,(int)contuab->i,(int)uniqid->i,datum1,datum2);
                    263: }
                    264: 
                    265: /*
                    266:  *     (*makhunk '<fixnum>)
                    267:  *                       <fixnum>
                    268:  * Create a hunk of size 2       . <fixnum> must be between 0 and 6.
                    269:  *
                    270:  */
                    271: 
                    272: lispval
                    273: LMakhunk()
                    274: {
                    275:        register int hsize, hcntr;
                    276:        register lispval result;
                    277: 
                    278:        chkarg(1,"Makehunk");
                    279:        if (TYPE(lbot->val)==INT)
                    280:        {
                    281:                hsize = lbot->val->i;           /* size of hunk (0-6) */
                    282:                if ((hsize >= 0) && (hsize <= 6))
                    283:                {
                    284:                        result = newhunk(hsize);
                    285:                        hsize = 2 << hsize;     /* size of hunk (2-128) */
                    286:                        for (hcntr = 0; hcntr < hsize; hcntr++)
                    287:                                result->h.hunk[hcntr] = hunkfree;
                    288:                }
                    289:                else
                    290:                        error("*makhunk: Illegal hunk size", FALSE);
                    291:        return(result);
                    292:        }
                    293:        else
                    294:                error("*makhunk: First arg must be an fixnum",FALSE);
                    295:        /* NOTREACHED */
                    296: }
                    297: 
                    298: /*
                    299:  *     (cxr '<fixnum> '<hunk>)
                    300:  * Returns the <fixnum>'th element of <hunk>
                    301:  *
                    302:  */
                    303: lispval
                    304: Lcxr()
                    305: {
                    306:        register lispval temp;
                    307: 
                    308:        chkarg(2,"cxr");
                    309:        if (TYPE(lbot->val)!=INT)
                    310:                error("cxr: First arg must be a fixnum", FALSE);
                    311:        else
                    312:        {
                    313:                if (! HUNKP(lbot[1].val))
                    314:                        error("cxr: Second arg must be a hunk", FALSE);
                    315:                else
                    316:                        if ( (lbot->val->i >= 0) &&
                    317:                             (lbot->val->i < (2 << HUNKSIZE(lbot[1].val))) )
                    318:                        {
                    319:                                temp = lbot[1].val->h.hunk[lbot->val->i];
                    320:                                if (temp != hunkfree)
                    321:                                        return(temp);
                    322:                                else
                    323:                                        error("cxr: Arg outside of hunk range",
                    324:                                              FALSE);
                    325:                        }
                    326:                        else
                    327:                                error("cxr: Arg outside of hunk range", FALSE);
                    328:        }
                    329:        /* NOTREACHED */
                    330: }
                    331: 
                    332: /*
                    333:  *     (rplacx '<fixnum> '<hunk> '<expr>)
                    334:  * Replaces the <fixnum>'th element of <hunk> with <expr>.
                    335:  *
                    336:  */
                    337: lispval
                    338: Lrplacx()
                    339: {
                    340:        lispval *handy;
                    341:        chkarg(3,"rplacx");
                    342:        if (TYPE(lbot->val)!=INT)
                    343:                error("rplacx: First arg must be a fixnum", FALSE);
                    344:        else
                    345:        {
                    346:                if (! HUNKP(lbot[1].val))
                    347:                        error("rplacx: Second arg must be a hunk", FALSE);
                    348:                else
                    349:                {
                    350:                        if ( (lbot->val->i >= 0) &&
                    351:                             (lbot->val->i < (2 << HUNKSIZE(lbot[1].val))) )
                    352:                        {
                    353:                           if (*(handy = &(lbot[1].val->h.hunk[lbot->val->i]))
                    354:                                        != hunkfree)
                    355:                                    *handy  = lbot[2].val;
                    356:                                else
                    357:                                        error("rplacx: Arg outside hunk range", FALSE);
                    358:                        }
                    359:                        else
                    360:                                error("rplacx: Arg outside hunk range", FALSE);
                    361:                }
                    362:        }
                    363:        return(lbot[1].val);
                    364: }
                    365: 
                    366: /*
                    367:  *     (*rplacx '<fixnum> '<hunk> '<expr>)
                    368:  * Replaces the <fixnum>'th element of <hunk> with <expr>. This is the
                    369:  * same as (rplacx ...) except with this function you can replace EMPTY's.
                    370:  *
                    371:  */
                    372: lispval
                    373: Lstarrpx()
                    374: {
                    375:        chkarg(3,"*rplacx");
                    376:        if (TYPE(lbot->val)!=INT)
                    377:                error("*rplacx: First arg must be a fixnum", FALSE);
                    378:        else
                    379:        {
                    380:                if (! HUNKP(lbot[1].val))
                    381:                        error("*rplacx: Second arg must be a hunk", FALSE);
                    382:                else
                    383:                {
                    384:                        if ( (lbot->val->i >= 0) &&
                    385:                             (lbot->val->i < (2 << HUNKSIZE(lbot[1].val))) )
                    386:                                lbot[1].val->h.hunk[lbot->val->i] = lbot[2].val;
                    387:                        else
                    388:                                error("*rplacx: Arg outside hunk range", FALSE);
                    389:                }
                    390:        }
                    391:        return(lbot[1].val);
                    392: }
                    393: 
                    394: /*
                    395:  *     (hunksize '<hunk>)
                    396:  * Returns the size of <hunk>
                    397:  *
                    398:  */
                    399: lispval
                    400: Lhunksize()
                    401: {
                    402:        register int size,i;
                    403: 
                    404:        chkarg(1,"hunksize");
                    405:        if (HUNKP(lbot->val))
                    406:        {
                    407:                size = 2 << HUNKSIZE(lbot->val);
                    408:                for (i = size-1; i >= 0; i--)
                    409:                {
                    410:                        if (lbot->val->h.hunk[i] != hunkfree)
                    411:                        {
                    412:                                size = i + 1;
                    413:                                break;
                    414:                        }
                    415:                }
                    416:                return( inewint(size) );
                    417:        }
                    418:        else
                    419:                error("hunksize: First argument must me a hunk", FALSE);
                    420:                        /* NOTREACHED */
                    421: }
                    422: 
                    423: /*
                    424:  * (hunk-to-list 'hunk)        returns a list of the hunk elements
                    425:  */
                    426: lispval
                    427: Lhtol()
                    428: {
                    429:     register lispval handy,retval,last;
                    430:     register int i;
                    431:     int size;
                    432:     Savestack(4);
                    433: 
                    434:     chkarg(1,"hunk-to-list");
                    435:     handy = lbot->val;
                    436:     if(!(HUNKP(handy)))
                    437:        errorh1(Vermisc,"hunk-to-list: non hunk argument: ", nil,0,FALSE,
                    438:                        handy);
                    439:     size = 2 << HUNKSIZE(handy);
                    440:     retval = nil;
                    441:     for(i=0 ; i < size ; i++)
                    442:     {
                    443:        if(handy->h.hunk[i] != hunkfree)
                    444:        {
                    445:            if(retval==nil)
                    446:            {
                    447:                protect(retval=newdot());
                    448:                last = retval;
                    449:            }
                    450:            else {
                    451:                last = (last->d.cdr = newdot());
                    452:            }
                    453:            last->d.car = handy->h.hunk[i];
                    454:        }
                    455:        else break;
                    456:     }
                    457:     Restorestack();
                    458:     return(retval);
                    459: }
                    460:            
                    461: /*
                    462:  *     (fileopen  filename mode)
                    463:  * open a file for read, write, or append the arguments can be either
                    464:  * strings or atoms.
                    465:  */
                    466: lispval
                    467: Lfileopen()
                    468: {
                    469:        FILE *port;
                    470:        register lispval name;
                    471:        register lispval mode;
                    472:        register char *namech;
                    473:        register char *modech;
                    474: 
                    475:        chkarg(2,"fileopen");
                    476:        name = lbot->val;
                    477:        mode = lbot[1].val;
                    478: 
                    479:        namech = (char *) verify(name,"fileopen:args must be atoms or strings");
                    480:        modech = (char *) verify(mode,"fileopen:args must be atoms or strings");
                    481: 
                    482:        while (modech[0] != 'r' && modech[0] != 'w' && modech[0] != 'a')
                    483:        {
                    484:                mode = errorh(Vermisc,"Modes are only r, w, a.",nil,TRUE,31);
                    485:                modech = (char *) verify(mode,"fileopen:args must be atoms or strings");
                    486:        }
                    487: 
                    488:        while ((port = fopen(namech, modech)) == NULL)
                    489:        {
                    490:            name = errorh1(Vermisc,"Unable to open file.",nil,TRUE,31,name);
                    491:            namech = (char *) verify(name,"fileopen:args must be atoms or strings");
                    492:        }
                    493:            /* xports is a FILE *, cc complains about adding pointers */
                    494: 
                    495:        ioname[PN(port)] = (lispval) inewstr(namech);   /* remember name */
                    496:        return( (lispval) (xports + (port - _iob)));
                    497: }
                    498: 
                    499: /*
                    500:  *     (*invmod '<number> '<modulus>)
                    501:  * This function returns the inverse of  <number>
                    502:  * mod <modulus> in balanced representation
                    503:  * It is used in vaxima as a speed enhancement.
                    504:  */
                    505: 
                    506: static lispval
                    507: Ibalmod(invmodp)
                    508: {
                    509:        register long mod_div_2, number, modulus;
                    510: 
                    511:        chkarg(2,"*mod");
                    512:        if ((TYPE(lbot->val) == INT) && (TYPE(lbot[1].val) == INT))
                    513:        {
                    514:                modulus = lbot[1].val->i;
                    515:                if(invmodp) number = invmod(lbot->val->i , modulus);
                    516:                else number = lbot->val->i % modulus;
                    517:                mod_div_2 = modulus / 2;
                    518:                if (number < 0)
                    519:                {
                    520:                        if (number < (-mod_div_2))
                    521:                                number += modulus;
                    522:                }
                    523:                else
                    524:                {
                    525:                        if (number > mod_div_2)
                    526:                                number -= modulus;
                    527:                }
                    528:                return( inewint(number) );
                    529:        }
                    530:        else
                    531:                error("*mod: Arguments must be fixnums", FALSE);
                    532:        /* NOTREACHED */
                    533: }
                    534: 
                    535: invmod (n,modulus)
                    536: long n , modulus;
                    537: 
                    538: { 
                    539:        long a1,a2,a3,y1,y2,y3,q;
                    540: 
                    541:        a1 = modulus; 
                    542:        a2 = n; 
                    543:        y1 = 0; 
                    544:        y2= 1; 
                    545:        goto step3;
                    546: step2: 
                    547:        q = a1 /a2; /*truncated quotient */
                    548:        a3= mmuladd(modulus-a2,q,a1,modulus);
                    549:        y3= mmuladd(modulus-y2,q,y1,modulus);
                    550:        a1 = a2; 
                    551:        a2= a3; 
                    552:        y1=y2; 
                    553:        y2=y3;
                    554: step3: 
                    555:        if (a2==0) error("invmod: inverse of zero divisor",TRUE);
                    556:        else if (a2 != 1) goto step2;
                    557:        else return (y2);
                    558:        /* NOTREACHED */
                    559: }
                    560: 
                    561: lispval
                    562: Lstarinvmod()
                    563: {
                    564:        return(Ibalmod(TRUE));
                    565: }
                    566: 
                    567: /*
                    568:  *     (*mod '<number> '<modulus>)
                    569:  * This function returns <number> mod <modulus> (for balanced modulus).
                    570:  * It is used in vaxima as a speed enhancement.
                    571:  */
                    572: lispval
                    573: LstarMod()
                    574: {
                    575:        return(Ibalmod(FALSE));
                    576: }
                    577: 
                    578: lispval
                    579: Llsh()
                    580: {
                    581:        register struct argent *mylbot = lbot;
                    582:        int val,shift;
                    583: 
                    584:        chkarg(2,"lsh");
                    585:        if((TYPE(mylbot->val) != INT) || (TYPE(mylbot[1].val) != INT))
                    586:                errorh2(Vermisc,
                    587:                       "Non ints to lsh",
                    588:                       nil,FALSE,0,mylbot->val,mylbot[1].val);
                    589:        val = mylbot[0].val->i;
                    590:        shift = mylbot[1].val->i;
                    591:        if(shift < -32 || shift > 32)
                    592:          return(inewint(0));
                    593:        if (shift < 0)
                    594:                val = val >> -shift;
                    595:        else
                    596:                val = val << shift;
                    597:        if((val < 0) && (shift < 0))
                    598:        {       /* special case: the vax doesn't have a logical shift
                    599:                   instruction, so we must zero out the ones which
                    600:                   will propogate from the sign position
                    601:                */
                    602:                return(inewint ( val & ~(0x80000000 << (shift+1))));
                    603:        }
                    604:        else return( inewint(val));
                    605: }
                    606: 
                    607: /* very temporary function to test the validity of the bind stack */
                    608: 
                    609: bndchk()
                    610: {  
                    611:        register struct nament *npt;
                    612:        register lispval in2;
                    613: 
                    614:        in2 = inewint(200);
                    615:        for(npt=orgbnp; npt < bnp; npt++)
                    616:        {  if((int) npt->atm < (int) in2) abort();
                    617:        }
                    618: }
                    619: 
                    620: /*
                    621:  *     formatted printer for lisp data
                    622:  *    use: (cprintf formatstring datum [port])
                    623:  */
                    624: lispval
                    625: Lcprintf()
                    626: {
                    627:     FILE *p;
                    628:     char *fstrng;
                    629:     lispval v;
                    630:     if(np-lbot == 2) protect(nil);     /* write to standard output port */
                    631:     chkarg(3,"cprintf");
                    632: 
                    633:     fstrng = (char *)verify(lbot->val,"cprintf: first arg not string or symbol");
                    634: 
                    635:     p = okport(lbot[2].val,okport(Vpoport->a.clb,poport));
                    636: 
                    637:     switch(TYPE(v=lbot[1].val)) {
                    638: 
                    639:        case INT:  fprintf(p,fstrng,v->i);
                    640:                   break;
                    641: 
                    642:        case DOUB: fprintf(p,fstrng,v->r);
                    643:                   break;
                    644: 
                    645:        case ATOM: fprintf(p,fstrng,v->a.pname);
                    646:                   break;
                    647: 
                    648:        case STRNG:fprintf(p,fstrng,v);
                    649:                   break;
                    650: 
                    651:        default:   error("cprintf: Illegal second argument",FALSE);
                    652:    };
                    653: 
                    654:    return(lbot[1].val);
                    655: }
                    656: 
                    657: 
                    658: /*
                    659:  * C style sprintf: (sprintf "format" {<arg-list>})
                    660:  *
                    661:  * This function stacks the arguments onto the C stack in reverse
                    662:  * order and then calls sprintf with one argument...This is what the
                    663:  * C compiler does, so it works just fine. The return value is the
                    664:  * string that is the result of the sprintf.
                    665:  */
                    666: lispval
                    667: Lsprintf()
                    668: {
                    669:        register struct argent *argp;
                    670:        register int j;
                    671:        char sbuf[600], *sprintf();                     /* better way? */
                    672:        Keepxs();
                    673: 
                    674:        if (np-lbot == 0) {
                    675:                argerr("sprintf");
                    676:        }
                    677:        if (TYPE(lbot->val)==STRNG || TYPE(lbot->val)==INT) {
                    678:                for (argp = np-1; argp >= lbot; argp--) {
                    679:                        switch(TYPE(argp->val)) {
                    680:                          case ATOM:
                    681:                                stack((long)argp->val->a.pname);
                    682:                                break;
                    683: 
                    684:                          case DOUB:
                    685: #ifndef SPISFP
                    686:                                stack(argp->val->r);
                    687: #else
                    688:                                {double rr = argp->val->r;
                    689:                                stack(((long *)&rr)[1]);
                    690:                                stack(((long *)&rr)[0]);}
                    691: #endif
                    692:                                break;
                    693: 
                    694:                          case INT:
                    695:                                stack(argp->val->i);
                    696:                                break;
                    697: 
                    698:                          case STRNG:
                    699:                                stack((long)argp->val);
                    700:                                break;
                    701: 
                    702:                          default:
                    703:                                error("sprintf: Bad data type to sprintf",
                    704:                                                FALSE);
                    705:                        }
                    706:                }
                    707:                sprintf(sbuf);
                    708:                for (j = 0; j < np-lbot; j++)
                    709:                        unstack();
                    710:        } else
                    711:                error("sprintf: First arg must be an atom or string", FALSE);
                    712:        Freexs();
                    713:        return ((lispval) inewstr(sbuf));
                    714: }
                    715: 
                    716: lispval
                    717: Lprobef()
                    718: {
                    719:        char *name;
                    720:        chkarg(1,"probef");
                    721: 
                    722:        name = (char *)verify(lbot->val,"probef: not symbol or string arg ");
                    723: 
                    724:        if(access(name,0) == 0) return(tatom);
                    725:        else return(nil);
                    726: }
                    727: 
                    728: lispval
                    729: Lsubstring()
                    730: {      register char *name;
                    731:        register lispval index,length;
                    732:        int restofstring = FALSE;
                    733:        int len,ind,reallen;
                    734: 
                    735:        switch (np-lbot) 
                    736:        {
                    737:          case 2: restofstring = TRUE;
                    738:                  break;
                    739: 
                    740:          case 3: break;
                    741: 
                    742:          default: chkarg(3,"substring");
                    743:        }
                    744: 
                    745:        name = (char *)verify(lbot[0].val,"substring: not symbol or string arg ");
                    746: 
                    747:        while (TYPE(index = lbot[1].val) != INT)
                    748:        {  lbot[1].val = errorh1(Vermisc,"substring: non integer index ",nil,
                    749:                                                    TRUE,0,index);
                    750:        }
                    751: 
                    752:        len = strlen(name);
                    753:        ind = index->i;
                    754: 
                    755:        if(ind < 0) ind = len+1 + ind;
                    756: 
                    757:        if(ind < 1 || ind > len) return(nil);   /*index out of bounds*/
                    758:        if(restofstring) return((lispval)inewstr(name+ind-1));
                    759: 
                    760:        while (TYPE(length = lbot[2].val) != INT)
                    761:        { lbot[2].val = errorh1(Vermisc,"substring: not integer length ",nil,
                    762:                                                   TRUE,0,length);
                    763:        }
                    764: 
                    765:        if((reallen = length->i ) < 0 || (reallen + ind) > len)
                    766:          return((lispval)inewstr(name+ind-1));
                    767: 
                    768:        strncpy(strbuf,name+ind-1,reallen);
                    769:        strbuf[reallen] = '\0';
                    770:        return((lispval)newstr(0));
                    771: }
                    772: 
                    773: /*
                    774:  * This is substringn
                    775:  */
                    776: lispval
                    777: Lsstrn()
                    778: {
                    779:        register char *name;
                    780:        register int len,ind,reallen;
                    781:        lispval index,length;
                    782:        int restofstring = FALSE;
                    783:        Savestack(4);
                    784: 
                    785:        if((np-lbot) == 2) restofstring = TRUE;
                    786:        else { chkarg(3,"substringn");}
                    787: 
                    788:        name = (char *) verify(lbot[0].val,"substringn: non symbol or string arg ");
                    789: 
                    790:        while (TYPE(index = lbot[1].val) != INT)
                    791:        {  lbot[1].val = errorh1(Vermisc,"substringn: non integer index ",nil,
                    792:                                                    TRUE,0,index);
                    793:        }
                    794: 
                    795:        if(!restofstring)
                    796:        {
                    797:            while (TYPE(length = lbot[2].val) != INT)
                    798:            { lbot[2].val = errorh1(Vermisc,"substringn: not integer length ",
                    799:                                                        nil, TRUE,0,length);
                    800:            }
                    801:            reallen = length->i;
                    802:        }
                    803:        else reallen = -1;
                    804: 
                    805:        len = strlen(name);
                    806:        ind = index->i;
                    807:        if(ind < 0) ind = len + 1 + ind;
                    808:        if( ind < 1 || ind > len) return(nil);
                    809: 
                    810:        if(reallen == 0) 
                    811:            return((lispval)inewint(*(name + ind - 1)));
                    812:        else {
                    813:            char *pnt = name + ind - 1;
                    814:            char *last = name + len -1;
                    815:            lispval cur,start;
                    816: 
                    817:            protect(cur = start = newdot());
                    818:            cur->d.car = inewint(*pnt);
                    819:            while(++pnt <= last && --reallen != 0)
                    820:            {
                    821:               cur->d.cdr = newdot();
                    822:               cur = cur->d.cdr;
                    823:               cur->d.car = inewint(*pnt);
                    824:            }
                    825:            Restorestack();
                    826:            return(start);
                    827:        }
                    828: 
                    829: }
                    830: 
                    831: lispval Ipurcopy();
                    832: 
                    833: 
                    834: lispval
                    835: Lpurcopy()
                    836: {
                    837:        chkarg(1,"purcopy");
                    838:        return(Ipurcopy(lbot[0].val));
                    839: }
                    840:            
                    841: lispval
                    842: Ipurcopy(handy)
                    843: lispval handy;
                    844: {
                    845:     extern int *beginsweep;
                    846:     register lispval retv, curv, lv;
                    847:     int i,size;
                    848: 
                    849:     switch(TYPE(handy)) {
                    850: 
                    851:        case DTPR:
                    852:                   retv = curv = pnewdot();
                    853:                   lv = handy;
                    854:                   while(TRUE)
                    855:                   {
                    856:                      curv->d.car = Ipurcopy(lv->d.car);
                    857:                      if(TYPE(lv = lv->d.cdr) == DTPR)
                    858:                      {
                    859:                          curv->d.cdr = pnewdot();
                    860:                          curv = curv->d.cdr;
                    861:                      }
                    862:                      else {
                    863:                          curv->d.cdr = Ipurcopy(lv);
                    864:                          break;
                    865:                      }
                    866:                    }
                    867:                    return(retv);
                    868: 
                    869:        case SDOT:
                    870:                    retv = curv = pnewsdot();
                    871:                    lv = handy;
                    872:                    while(TRUE)
                    873:                    {
                    874:                        curv->s.I = lv->s.I;
                    875:                        if(lv->s.CDR == (lispval) 0) break;
                    876:                        lv = lv->s.CDR;
                    877:                        curv->s.CDR = pnewdot();
                    878:                        curv = curv->s.CDR;
                    879:                    }
                    880:                    curv->s.CDR = 0;
                    881:                    return(retv);
                    882: 
                    883:        case INT:
                    884:                    if((int *)handy < beginsweep) return(handy);
                    885:                    retv = pnewint();
                    886:                    retv->i = handy->i;
                    887:                    return(retv);
                    888: 
                    889:        case DOUB:
                    890:                    retv = pnewdoub();
                    891:                    retv->r = handy->r;
                    892:                    return(retv);
                    893: 
                    894:        case HUNK2:
                    895:                i = 0;
                    896:                goto hunkit;
                    897: 
                    898:        case HUNK4:
                    899:                i = 1;
                    900:                goto hunkit;
                    901: 
                    902:        case HUNK8:
                    903:                i = 2;
                    904:                goto hunkit;
                    905: 
                    906:        case HUNK16:
                    907:                i = 3;
                    908:                goto hunkit;
                    909: 
                    910:        case HUNK32:
                    911:                i = 4;
                    912:                goto hunkit;
                    913: 
                    914:        case HUNK64:
                    915:                i = 5;
                    916:                goto hunkit;
                    917: 
                    918:        case HUNK128:
                    919:                i = 6; 
                    920: 
                    921:            hunkit:
                    922:                retv = pnewhunk(i);
                    923:                size = 2 << i ; /* number of elements to copy over */
                    924:                for( i = 0; i < size ; i++)
                    925:                {
                    926:                    retv->h.hunk[i] = Ipurcopy(handy->h.hunk[i]);
                    927:                }
                    928:                return(retv);
                    929: 
                    930: 
                    931: 
                    932:        case STRNG:
                    933: #ifdef GCSTRINGS
                    934:                { extern char purepage[];
                    935: 
                    936:                  if(purepage[((int)handy)>>9]==0)
                    937:                        return((lispval)pinewstr((char *)handy));}
                    938:                
                    939: #endif
                    940:        case ATOM: 
                    941:        case BCD:
                    942:        case PORT:
                    943:            return(handy);      /* We don't want to purcopy these, yet
                    944:                                 * it won't hurt if we don't mark them
                    945:                                 * since they either aren't swept or 
                    946:                                 * will be marked in a special way 
                    947:                                 */
                    948:        case ARRAY:
                    949:                error("purcopy: can't purcopy array structures",FALSE);
                    950: 
                    951:        default:
                    952:                error(" bad type to purcopy ",FALSE);
                    953:        /* NOTREACHED */
                    954:     }
                    955: }
                    956: 
                    957: /*
                    958:  * Lpurep returns t if the given arg is in pure space
                    959:  */
                    960: lispval
                    961: Lpurep()
                    962: {
                    963:     lispval Ipurep();
                    964: 
                    965:     chkarg(1,"purep");
                    966:     return(Ipurep(lbot->val));
                    967: }
                    968: 
                    969: 
                    970: 
                    971: /* vector functions */
                    972: lispval newvec(), nveci(), Inewvector();
                    973: 
                    974: /* vector creation and initialization functions */
                    975: lispval
                    976: Lnvec()
                    977: {
                    978:     return(Inewvector(3));
                    979: }
                    980: 
                    981: lispval
                    982: Lnvecb()
                    983: {
                    984:     return(Inewvector(0));
                    985: }
                    986: 
                    987: lispval
                    988: Lnvecw()
                    989: {
                    990:     return(Inewvector(1));
                    991: }
                    992: 
                    993: lispval
                    994: Lnvecl()
                    995: {
                    996:     return(Inewvector(2));
                    997: }
                    998: 
                    999: /*
                   1000:  * (new-vector 'x_size ['g_fill] ['g_prop])
                   1001:  * class = 0: byte \
                   1002:  *       = 1: word  > immediate
                   1003:  *       = 2: long /
                   1004:  *      = 3: long
                   1005:  */
                   1006: lispval
                   1007: Inewvector(class)
                   1008: {
                   1009:     register int i;
                   1010:     register lispval handy;
                   1011:     register lispval *handy2;
                   1012:     char *chandy;
                   1013:     short *whandy;
                   1014:     long *lhandy;
                   1015:     lispval sizearg, fillarg, proparg;
                   1016:     int size, vsize;
                   1017: 
                   1018:     fillarg = proparg = nil;
                   1019:     
                   1020:     switch(np-lbot) {
                   1021:        case 3: proparg = lbot[2].val;
                   1022:        case 2: fillarg = lbot[1].val;
                   1023:        case 1: sizearg = lbot[0].val;
                   1024:                break;
                   1025:        default: argerr("new-vector");
                   1026:     }
                   1027:     
                   1028:     while((TYPE(sizearg) != INT) || sizearg->i < 0)
                   1029:        sizearg = errorh1(Vermisc,"new-vector: bad size for vector ",nil,
                   1030:                                TRUE,0,sizearg);
                   1031:     size = sizearg->i;
                   1032:     switch(class)
                   1033:     {
                   1034:        case 0: vsize = size * sizeof(char);
                   1035:                break;
                   1036:        case 1: vsize = size * sizeof(short);
                   1037:                break;
                   1038:        default: vsize = size * sizeof(long);
                   1039:                break;
                   1040:     }
                   1041:     
                   1042:     if(class != 3) handy = nveci(vsize);
                   1043:     else handy = newvec(vsize);
                   1044:     
                   1045:     switch(class)
                   1046:     {
                   1047:        case 0: chandy = (char *)handy;
                   1048:                for(i = 0 ; i < size ; i++) *chandy++ = (char) (fillarg->i);
                   1049:                break;
                   1050:                
                   1051:        case 1: whandy = (short *)handy;
                   1052:                for(i = 0 ; i < size ; i++) *whandy++ = (short) (fillarg->i);
                   1053:                break;
                   1054:                
                   1055:        case 2: lhandy = (long *)handy;
                   1056:                for(i = 0 ; i < size ; i++) *lhandy++ = (fillarg->i);
                   1057:                break;
                   1058: 
                   1059:        case 3: handy2 = (lispval *)handy;
                   1060:                for(i = 0 ; i < size ; i++) *handy2++ = fillarg;
                   1061:                break;
                   1062:     }
                   1063:     handy->v.vector[-1] = proparg;
                   1064:     return(handy);
                   1065: }
                   1066: 
                   1067: lispval
                   1068: Lvectorp()
                   1069: {
                   1070:     chkarg(1,"vectorp");
                   1071:     if(TYPE(lbot->val) == VECTOR) return(tatom);
                   1072:     else return(nil);
                   1073: }
                   1074: 
                   1075: lispval
                   1076: Lpvp()
                   1077: {
                   1078:     chkarg(1,"vectorip");
                   1079:     if(TYPE(lbot->val) == VECTORI) return(tatom);
                   1080:     else return(nil);
                   1081: }
                   1082: 
                   1083: /*
                   1084:  * int:vref  vector[i] index class
                   1085:  *  class = 0: byte immed, 1: word immed, 2: long immed, 3: long
                   1086:  */
                   1087: lispval
                   1088: LIvref()
                   1089: {
                   1090:     register lispval vect;
                   1091:     register int index;
                   1092:     int class;
                   1093:     
                   1094:     chkarg(3,"int:vref");
                   1095:     vect = lbot[0].val;
                   1096:     index = lbot[1].val->i;
                   1097:     class = lbot[2].val->i;
                   1098:     switch(class)
                   1099:     {
                   1100:         case 0: return(inewint(vect->vb.vectorb[index]));
                   1101:         case 1: return(inewint(vect->vw.vectorw[index]));
                   1102:         case 2: return(inewint(vect->vl.vectorl[index]));
                   1103:        case 3: return(vect->v.vector[index]);
                   1104:     }
                   1105:     error("int:vref: impossible class detected",FALSE);
                   1106:     /* NOTREACHED */
                   1107: }
                   1108: 
                   1109: /*
                   1110:  * int:vset vector[i] index value class
                   1111:  *  class = 0: byte immed, 1: word immed, 2: long immed, 3: long
                   1112:  */
                   1113: lispval
                   1114: LIvset()
                   1115: {
                   1116:     register lispval vect,value;
                   1117:     register int index;
                   1118:     int class;
                   1119:     
                   1120:     chkarg(4,"int:vset");
                   1121:     vect = lbot[0].val;
                   1122:     index = lbot[1].val->i;
                   1123:     value = lbot[2].val;
                   1124:     class = lbot[3].val->i;
                   1125:     switch(class)
                   1126:     {
                   1127:         case 0: vect->vb.vectorb[index] = (char)value->i;
                   1128:                break;
                   1129:         case 1: vect->vw.vectorw[index] = (short)value->i;
                   1130:                break;
                   1131:         case 2: vect->vl.vectorl[index] = value->i;
                   1132:                break;
                   1133:        case 3: vect->v.vector[index] = value;
                   1134:                break;
                   1135:     }
                   1136:     return(value);
                   1137: }
                   1138: 
                   1139: /*
                   1140:  * LIvsize == (int:vsize 'vector 'x_shift)
                   1141:  *  return the vsize field of the vector shifted right by x_shift
                   1142:  */
                   1143: lispval
                   1144: LIvsize()
                   1145: {
                   1146:     int typ;
                   1147:     
                   1148:     chkarg(2,"int:vsize");
                   1149:     return(inewint((lbot[0].val->vl.vectorl[VSizeOff]) >> lbot[1].val->i));
                   1150: }
                   1151: 
                   1152: lispval
                   1153: Lvprop()
                   1154: {
                   1155:     int typ;
                   1156:     chkarg(1,"vprop");
                   1157:     
                   1158:     if(((typ = TYPE(lbot->val)) != VECTOR) && (typ != VECTORI))
                   1159:        errorh1(Vermisc,"vprop: non vector argument: ", nil, FALSE,0,
                   1160:                        lbot->val);
                   1161:     return(lbot[0].val->v.vector[VPropOff]);
                   1162: }
                   1163: 
                   1164:     
                   1165: lispval
                   1166: Lvsp()
                   1167: {
                   1168:        int typ;
                   1169:        lispval vector, property;
                   1170:        chkarg(2,"vsetprop");
                   1171: 
                   1172:        vector = lbot->val;
                   1173:        property = lbot[1].val;
                   1174:        typ = TYPE(vector);
                   1175: 
                   1176:        if(typ != VECTOR && typ !=VECTORI)
                   1177:                errorh1(Vermisc,"vsetprop: non vector argument: ",
                   1178:                                nil,FALSE,0,vector);
                   1179:        vector->v.vector[VPropOff] = property;
                   1180:        return(property);
                   1181: }
                   1182: 
                   1183: 
                   1184: /* vecequal
                   1185:  *  check if the two vector arguments are 'equal'
                   1186:  *  this is called by equal which has already checked that
                   1187:  *  the arguments are vector
                   1188:  */
                   1189: vecequal(v,w)
                   1190: lispval v,w;
                   1191: {
                   1192:     int i;
                   1193:     lispval vv, ww, ret;
                   1194:     int vsize = (int) v->v.vector[VSizeOff];
                   1195:     int wsize = (int) w->v.vector[VSizeOff];
                   1196:     struct argent *oldlbot = lbot;
                   1197:     lispval Lequal();
                   1198: 
                   1199:     if(vsize != wsize) return(FALSE);
                   1200: 
                   1201:     vsize /= sizeof(int);      /* determine number of entries */
                   1202: 
                   1203:     for(i = 0 ; i < vsize ; i++)
                   1204:     {
                   1205:        vv = v->v.vector[i];
                   1206:        ww = w->v.vector[i];
                   1207:        /* avoid calling equal if they are eq */
                   1208:        if(vv != ww)
                   1209:        {
                   1210:            lbot = np;
                   1211:            protect(vv);
                   1212:            protect(ww);
                   1213:            ret = Lequal();
                   1214:            np = lbot;
                   1215:            lbot = oldlbot;
                   1216:            if(ret == nil)  return(FALSE);
                   1217:        }
                   1218:     }
                   1219:     return(TRUE);
                   1220: }
                   1221:             
                   1222: /* veciequal
                   1223:  *  check if the two vectori arguments are 'equal'
                   1224:  *  this is called by equal which has already checked that
                   1225:  *  the arguments are vector
                   1226:  *  Note: this would run faster if we did as many 'longword'
                   1227:  *  comparisons as possible and then did byte comparisons.
                   1228:  *  or if we used pointers instead of indexing.
                   1229:  */
                   1230: veciequal(v,w)
                   1231: lispval v,w;
                   1232: {
                   1233:     char vv, ww;
                   1234:     int i;
                   1235:     int vsize = (int) v->v.vector[VSizeOff];
                   1236:     int wsize = (int) w->v.vector[VSizeOff];
                   1237: 
                   1238:     if(vsize != wsize) return(FALSE);
                   1239: 
                   1240: 
                   1241:     for(i = 0 ; i < vsize ; i++)
                   1242:     {
                   1243:        if(v->vb.vectorb[i] != w->vb.vectorb[i]) return(FALSE);
                   1244:     }
                   1245:     return(TRUE);
                   1246: }

unix.superglobalmegacorp.com

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