Annotation of 40BSD/cmd/lisp/lam8.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)lam8.c      34.5 11/7/80";
                      2: 
                      3: #include "global.h"
                      4: #include <sys/types.h>
                      5: #include <pagsiz.h>
                      6: #include "naout.h"
                      7: 
                      8: /* various functions from the c math library */
                      9: double sin(),cos(),asin(),acos(),atan2(),sqrt(), log(), exp();
                     10: extern int current;
                     11: 
                     12: lispval Imath(func)
                     13: double (*func)();
                     14: {
                     15:        register lispval handy;
                     16:        register double res;
                     17:        chkarg(1,"Math functions");
                     18: 
                     19:        switch(TYPE(handy=lbot->val)) {
                     20:         case INT: res = func((double)handy->i); 
                     21:                   break;
                     22: 
                     23:         case DOUB: res = func(handy->r);
                     24:                   break;
                     25: 
                     26:         default:  error("Non fixnum or flonum to math function",FALSE);
                     27:        }
                     28:        handy = newdoub();
                     29:        handy->r = res;
                     30:        return(handy);
                     31: }
                     32: lispval Lsin()
                     33: {
                     34:        return(Imath(sin));
                     35: }
                     36: 
                     37: lispval Lcos()
                     38: {
                     39:        return(Imath(cos));
                     40: }
                     41: 
                     42: lispval Lasin()
                     43: {
                     44:        return(Imath(asin));
                     45: }
                     46: 
                     47: lispval Lacos()
                     48: {
                     49:        return(Imath(acos));
                     50: }
                     51: 
                     52: lispval Lsqrt()
                     53: {
                     54:        return(Imath(sqrt));
                     55: }
                     56: lispval Lexp()
                     57: {
                     58:        return(Imath(exp));
                     59: }
                     60: 
                     61: lispval Llog()
                     62: {
                     63:        return(Imath(log));
                     64: }
                     65: 
                     66: /* although we call this atan, it is really atan2 to the c-world,
                     67:    that is, it takes two args
                     68:  */
                     69: lispval Latan()
                     70: {
                     71:        register lispval arg;
                     72:        register double arg1v;
                     73:        register double res;
                     74:        chkarg(2,"arctan");
                     75: 
                     76:        switch(TYPE(arg=lbot->val)) {
                     77: 
                     78:        case INT:  arg1v = (double) arg->i;
                     79:                   break;
                     80: 
                     81:        case DOUB: arg1v = arg->r;
                     82:                   break;
                     83: 
                     84:        default:   error("Non fixnum or flonum arg to atan2",FALSE);
                     85:        }
                     86: 
                     87:        switch(TYPE(arg = (lbot+1)->val)) {
                     88: 
                     89:        case INT: res = atan2(arg1v,(double) arg->i);
                     90:                  break;
                     91: 
                     92:        case DOUB: res = atan2(arg1v, arg->r);
                     93:                  break;
                     94: 
                     95:        default:  error("Non fixnum or flonum to atan2",FALSE);
                     96:        }
                     97:        arg = newdoub();
                     98:        arg->r = res;
                     99:        return(arg);
                    100: }
                    101: 
                    102: /* (random) returns a fixnum in the range -2**30 to 2**30 -1
                    103:    (random fixnum) returns a fixnum in the range 0 to fixnum-1
                    104:  */
                    105: lispval
                    106: Lrandom()
                    107: {
                    108:        register int curval;
                    109:        float pow();
                    110: 
                    111:        curval = rand();        /* get numb from 0 to 2**31-1 */
                    112: 
                    113:        if(np==lbot) return(inewint(curval-(int)pow((double)2,(double)30)));
                    114: 
                    115:        if((TYPE(lbot->val) != INT)
                    116:            || (lbot->val->i <= 0)) errorh(Vermisc,"random: non fixnum arg:",
                    117:                                                 nil, FALSE, 0, lbot->val);
                    118: 
                    119:        return(inewint(curval % lbot->val->i )); 
                    120: 
                    121: }
                    122: lispval
                    123: Lmakunb()
                    124: {
                    125:        register lispval work;
                    126: 
                    127:        chkarg(1,"makunbound");
                    128:        work = lbot->val;
                    129:        if(work==nil || (TYPE(work)!=ATOM))
                    130:                return(work);
                    131:        work->a.clb = CNIL;
                    132:        return(work);
                    133: }
                    134: lispval
                    135: Lpolyev()
                    136: {
                    137:        register int count; 
                    138:        register double *handy, *base;
                    139:        register struct argent *argp, *lbot, *np;
                    140:        lispval result; int type;
                    141: 
                    142:        count = 2 * (((int) np) - (int) lbot);
                    143:        if(count == 0) 
                    144:                return(inewint(0));
                    145:        if(count == 8)
                    146:                return(lbot->val);
                    147:        base = handy = (double *) alloca(count);
                    148:        for(argp = lbot; argp < np; argp++) {
                    149:                while((type = TYPE(argp->val))!=DOUB && type!=INT)
                    150:                        argp->val = (lispval) errorh(Vermisc,"%%machine-polyev:non-real arg",nil,TRUE,73,lbot,argp->val);
                    151:                if(TYPE(argp->val)==INT) {
                    152:                        *handy++ = argp->val->i;
                    153:                } else
                    154:                        *handy++ = argp->val->r;
                    155:        }
                    156:        count = count/sizeof(double) - 2;
                    157:        asm("polyd      (r9),r11,8(r9)");
                    158:        asm("movd       r0,(r9)");
                    159:        result = newdoub();
                    160:        result->r = *base;
                    161:        return(result);
                    162: }
                    163: typedef struct doub {
                    164:        unsigned short f1:7,expt:8,sign:1;
                    165:        unsigned short f2,f3p1:14,f3p2:2,f4;
                    166: } *dp;
                    167: 
                    168: typedef struct quad2 {
                    169:        unsigned long g4:16,g3p1:14;
                    170: } *qp2;
                    171: 
                    172: typedef struct quad1 {
                    173:        unsigned long g3p2:2,g2:16,g1:7,hide:1;
                    174: } *qp1;
                    175: 
                    176: static long workbuf[2];
                    177: static int  exponent;
                    178: static Idebig()
                    179: {
                    180:        register lispval work;
                    181:        register dp rdp;
                    182:        register qp1 rqp1;
                    183:        register qp2 rqp2;
                    184:        register struct argent *lbot,np;
                    185:        workbuf[1]  = workbuf[0] = 0;
                    186: 
                    187:        work = lbot->val;               /* Unfold mantissa */
                    188:        rqp2 = (qp2) workbuf + 1;
                    189:        rqp1 = (qp1) workbuf;
                    190:        rdp = (dp) work;
                    191:        rqp2->g4 = rdp->f4;
                    192:        rqp2->g3p1 = rdp->f3p1;
                    193:        rqp1->g3p2 = rdp->f3p2;
                    194:        rqp1->g2 = rdp->f2;
                    195:        rqp1->g1 = rdp->f1;
                    196:        rqp1->hide = 1;
                    197:        if(rdp->sign) {
                    198:                workbuf[0] = (- workbuf[0]);
                    199:                if(workbuf[1] = (- workbuf[1]) & 0xC0000000)
                    200:                        workbuf[0]--;
                    201:        }
                    202:        /* calcuate exponent and adjustment */
                    203:        exponent = -129 - 55 + (int) rdp->expt;
                    204: }
                    205: lispval
                    206: Lfdecom()
                    207: {
                    208:        register lispval result, handy;
                    209:        register dum1,dum2;
                    210:        register struct argent *lbot,*np;
                    211: 
                    212:        chkarg(1,"Decompose-float");
                    213:        while(TYPE(lbot->val)!=DOUB)
                    214:                lbot->val = error("Decompose-float: Non-real argument",TRUE);
                    215:        Idebig();
                    216:        np++->val = result = handy = newdot();
                    217:        handy->d.car = inewint(exponent);
                    218:        handy = handy->d.cdr = newdot();
                    219:        handy = handy->d.car = newsdot();
                    220:        handy->s.I = workbuf[1];
                    221:        handy = handy->s.CDR = newsdot();
                    222:        handy->s.I = workbuf[0];
                    223: }
                    224: 
                    225: lispval
                    226: Lfseek()
                    227: {
                    228:        register lispval result, handy;
                    229:        register dum1,dum2;
                    230:        register struct argent *lbot,*np;
                    231: 
                    232:        FILE *f;
                    233:        long disk_addr, offset, whence;
                    234:        lispval retp;
                    235: 
                    236:        chkarg(3,"fseek");                      /* Make sure there are three arguments*/
                    237: 
                    238:        f = lbot->val->p;               /* Get first argument into f */
                    239:        if (TYPE(lbot->val)!=PORT)      /* Check type of first */
                    240:                error("fseek: First argument must be a port.",FALSE);
                    241: 
                    242:        offset = lbot[1].val->i;        /* Get second argument */
                    243:        if (TYPE(lbot[1].val)!=INT)
                    244:                error("fseek: Second argument must be an integer.",FALSE);
                    245: 
                    246:        whence = lbot[2].val->i;        /* Get last arg */
                    247:        if (TYPE(lbot[2].val)!=INT)
                    248:                error("fseek: Third argument must be an integer.",FALSE);
                    249: 
                    250:        if (fseek(f, offset, whence) == -1)
                    251:                error("fseek: Illegal parameters.",FALSE);
                    252: 
                    253:        retp = inewint(ftell(f));
                    254: 
                    255:        return((lispval) retp);
                    256: }
                    257: 
                    258: /* function hashtabstat  : return list of number of members in  each bucket */
                    259: lispval Lhashst()
                    260: {
                    261:        register lispval handy,cur;
                    262:        register struct atom *pnt;
                    263:        int i,cnt;
                    264:        extern int hashtop;
                    265:        snpand(3);
                    266: 
                    267:        handy = newdot();
                    268:        protect(handy);
                    269:        cur = handy;
                    270:        for(i = 0; i < hashtop; i++)
                    271:        {
                    272:            pnt = hasht[i];
                    273:            for(cnt = 0; pnt != (struct atom *) CNIL ; pnt=pnt->hshlnk , cnt++);
                    274:            cur->d.cdr = newdot();
                    275:            cur = cur->d.cdr;
                    276:            cur->d.car = inewint(cnt);
                    277:        }
                    278:        cur->d.cdr = nil;
                    279:        return(handy->d.cdr);
                    280: }
                    281: 
                    282: 
                    283: /* Lctcherr
                    284:   this routine should only be called by the unwind protect simulation
                    285:   lisp code
                    286:   It is called after an unwind-protect frame has been entered and
                    287:   evalated and we want to get on with the error or throw
                    288:   We only handle the case where there are 0 to 2 extra arguments to the
                    289:   error call.
                    290: */
                    291: lispval
                    292: Lctcherr()
                    293: {
                    294:        register lispval handy;
                    295:        lispval type,messg,valret,contuab,uniqid,datum1,datum2;
                    296:        snpand(1);
                    297: 
                    298:        if(lbot-np==0) protect(nil);
                    299:        if((handy = lbot->val) == nil) return(nil);
                    300: 
                    301:        if(handy->d.car == tatom)
                    302:        {       /* continuaing a throw */
                    303:                Idothrow(handy->d.cdr->d.car, handy->d.cdr->d.cdr->d.car);
                    304:                error("ctcherr: throw label gone!",FALSE);
                    305:        }
                    306: 
                    307:        /* decode the arg list */
                    308:        handy = handy->d.cdr;
                    309:        type = handy->d.car;
                    310:        handy = handy->d.cdr;
                    311:        messg = handy->d.car;
                    312:        handy = handy->d.cdr;
                    313:        valret = handy->d.car;
                    314:        handy = handy->d.cdr;
                    315:        contuab = handy->d.car;
                    316:        handy = handy->d.cdr;
                    317:        uniqid = handy->d.car;
                    318:        handy = handy->d.cdr;
                    319: 
                    320:        /* if not extra args */
                    321:        if(handy == nil)
                    322:        {
                    323:          errorh(type,messg->a.pname,valret,contuab->i,uniqid->i);
                    324:        }
                    325:        datum1 = handy->d.car;
                    326:        handy = handy->d.cdr;
                    327: 
                    328:        /* if one extra arg */
                    329:        if(handy == nil)
                    330:        {
                    331:          errorh(type,messg->a.pname,valret,contuab->i,uniqid->i,datum1);
                    332:        }
                    333: 
                    334:        /* if two or more extra args, just use first 2 */
                    335:        datum2 = handy->d.car;
                    336:        errorh(type,messg->a.pname,valret,contuab->i,uniqid->i,datum1,datum2);
                    337: }
                    338: 
                    339: /*
                    340:  *     (*makhunk '<fixnum>)
                    341:  *                       <fixnum>
                    342:  * Create a hunk of size 2       . <fixnum> must be between 0 and 6.
                    343:  *
                    344:  */
                    345: 
                    346: lispval
                    347: LMakhunk()
                    348: {
                    349:        register int hsize, hcntr;
                    350:        register lispval result;
                    351: 
                    352:        chkarg(1,"Makehunk");
                    353:        if (TYPE(lbot->val)==INT)
                    354:        {
                    355:                hsize = lbot->val->i;           /* size of hunk (0-6) */
                    356:                if ((hsize >= 0) && (hsize <= 6))
                    357:                {
                    358:                        result = newhunk(hsize);
                    359:                        hsize = 2 << hsize;     /* size of hunk (2-128) */
                    360:                        for (hcntr = 0; hcntr < hsize; hcntr++)
                    361:                                result->h.hunk[hcntr] = hunkfree;
                    362:                }
                    363:                else
                    364:                        error("*makhunk: Illegal hunk size", FALSE);
                    365:        return(result);
                    366:        }
                    367:        else
                    368:                error("*makhunk: First arg must be an fixnum",FALSE);
                    369: }
                    370: 
                    371: /*
                    372:  *     (cxr '<fixnum> '<hunk>)
                    373:  * Returns the <fixnum>'th element of <hunk>
                    374:  *
                    375:  */
                    376: lispval
                    377: Lcxr()
                    378: {
                    379:        register lispval temp;
                    380: 
                    381:        chkarg(2,"cxr");
                    382:        if (TYPE(lbot->val)!=INT)
                    383:                error("cxr: First arg must be a fixnum", FALSE);
                    384:        else
                    385:        {
                    386:                if (! HUNKP(lbot[1].val))
                    387:                        error("cxr: Second arg must be a hunk", FALSE);
                    388:                else
                    389:                        if ( (lbot->val->i >= 0) &&
                    390:                             (lbot->val->i < (2 << HUNKSIZE(lbot[1].val))) )
                    391:                        {
                    392:                                temp = lbot[1].val->h.hunk[lbot->val->i];
                    393:                                if (temp != hunkfree)
                    394:                                        return(temp);
                    395:                                else
                    396:                                        error("cxr: Arg outside of hunk range",
                    397:                                              FALSE);
                    398:                        }
                    399:                        else
                    400:                                error("cxr: Arg outside of hunk range", FALSE);
                    401:        }
                    402: }
                    403: 
                    404: /*
                    405:  *     (rplacx '<fixnum> '<hunk> '<expr>)
                    406:  * Replaces the <fixnum>'th element of <hunk> with <expr>.
                    407:  *
                    408:  */
                    409: lispval
                    410: Lrplacx()
                    411: {
                    412:        lispval *handy;
                    413:        chkarg(3,"rplacx");
                    414:        if (TYPE(lbot->val)!=INT)
                    415:                error("rplacx: First arg must be a fixnum", FALSE);
                    416:        else
                    417:        {
                    418:                if (! HUNKP(lbot[1].val))
                    419:                        error("rplacx: Second arg must be a hunk", FALSE);
                    420:                else
                    421:                {
                    422:                        if ( (lbot->val->i >= 0) &&
                    423:                             (lbot->val->i < (2 << HUNKSIZE(lbot[1].val))) )
                    424:                        {
                    425:                           if (*(handy = &(lbot[1].val->h.hunk[lbot->val->i]))
                    426:                                        != hunkfree)
                    427:                                    *handy  = lbot[2].val;
                    428:                                else
                    429:                                        error("rplacx: Arg outside hunk range", FALSE);
                    430:                        }
                    431:                        else
                    432:                                error("rplacx: Arg outside hunk range", FALSE);
                    433:                }
                    434:        }
                    435:        return(lbot[1].val);
                    436: }
                    437: 
                    438: /*
                    439:  *     (*rplacx '<fixnum> '<hunk> '<expr>)
                    440:  * Replaces the <fixnum>'th element of <hunk> with <expr>. This is the
                    441:  * same as (rplacx ...) except with this function you can replace EMPTY's.
                    442:  *
                    443:  */
                    444: lispval
                    445: Lstarrpx()
                    446: {
                    447:        chkarg(3,"*rplacx");
                    448:        if (TYPE(lbot->val)!=INT)
                    449:                error("*rplacx: First arg must be a fixnum", FALSE);
                    450:        else
                    451:        {
                    452:                if (! HUNKP(lbot[1].val))
                    453:                        error("*rplacx: Second arg must be a hunk", FALSE);
                    454:                else
                    455:                {
                    456:                        if ( (lbot->val->i >= 0) &&
                    457:                             (lbot->val->i < (2 << HUNKSIZE(lbot[1].val))) )
                    458:                                lbot[1].val->h.hunk[lbot->val->i] = lbot[2].val;
                    459:                        else
                    460:                                error("*rplacx: Arg outside hunk range", FALSE);
                    461:                }
                    462:        }
                    463:        return(lbot[1].val);
                    464: }
                    465: 
                    466: /*
                    467:  *     (hunksize '<hunk>)
                    468:  * Returns the size of <hunk>
                    469:  *
                    470:  */
                    471: lispval
                    472: Lhunksize()
                    473: {
                    474:        register int size,i;
                    475: 
                    476:        chkarg(1,"hunksize");
                    477:        if (HUNKP(lbot->val))
                    478:        {
                    479:                size = 2 << HUNKSIZE(lbot->val);
                    480:                for (i = size-1; i >= 0; i--)
                    481:                {
                    482:                        if (lbot->val->h.hunk[i] != hunkfree)
                    483:                        {
                    484:                                size = i + 1;
                    485:                                break;
                    486:                        }
                    487:                }
                    488:                return( inewint(size) );
                    489:        }
                    490:        else
                    491:                error("hunksize: First argument must me a hunk", FALSE);
                    492: }
                    493: 
                    494: /*
                    495:  *     (fileopen  filename mode)
                    496:  * open a file for read, write, or append the arguments can be either
                    497:  * strings or atoms.
                    498:  */
                    499: lispval
                    500: Lfileopen()
                    501: {
                    502:        FILE *port;
                    503:        register lispval name;
                    504:        register lispval mode;
                    505:        register char *namech;
                    506:        register char *modech;
                    507:        register struct argent *lbot, *np;
                    508:        int typ;
                    509: 
                    510:        chkarg(2,"fileopen");
                    511:        name = lbot->val;
                    512:        mode = lbot[1].val;
                    513: 
                    514:        namech = (char *) verify(name,"fileopen:args must be atoms or strings");
                    515:        modech = (char *) verify(mode,"fileopen:args must be atoms or strings");
                    516: 
                    517:        while (modech[0] != 'r' && modech[0] != 'w' && modech[0] != 'a')
                    518:        {
                    519:                mode = errorh(Vermisc,"Modes are only r, w, a.",nil,TRUE,31,(char *) 0);
                    520:                modech = (char *) verify(mode,"fileopen:args must be atoms or strings");
                    521:        }
                    522: 
                    523:        while ((port = fopen(namech, modech)) == NULL)
                    524:        {
                    525:            name = errorh(Vermisc,"Unable to open file.",nil,TRUE,31,name);
                    526:            namech = (char *) verify(name,"fileopen:args must be atoms or strings");
                    527:        }
                    528:                    /* xports is a FILE *, cc complains about adding pointers */
                    529: 
                    530:        return( (lispval) (xports + (port - _iob)));
                    531: }
                    532: 
                    533: /*
                    534:  *     (*mod '<number> '<modulus>)
                    535:  * This function returns <number> mod <modulus> (for balanced modulus).
                    536:  * It is used in vaxima as a speed enhancement.
                    537:  */
                    538: lispval
                    539: LstarMod()
                    540: {
                    541:        register int mod_div_2, number, modulus;
                    542: 
                    543:        chkarg(2,"*mod");
                    544:        if ((TYPE(lbot->val) == INT) && (TYPE(lbot[1].val) == INT))
                    545:        {
                    546:                modulus = lbot[1].val->i;
                    547:                number = lbot->val->i % modulus;
                    548:                mod_div_2 = modulus / 2;
                    549:                if (number < 0)
                    550:                {
                    551:                        if (number < (-mod_div_2))
                    552:                                number += modulus;
                    553:                }
                    554:                else
                    555:                {
                    556:                        if (number > mod_div_2)
                    557:                                number -= modulus;
                    558:                }
                    559:                return( inewint(number) );
                    560:        }
                    561:        else
                    562:                error("*mod: Arguments must be fixnums", FALSE);
                    563: }
                    564: lispval
                    565: Llsh()
                    566: {
                    567:        register struct argent *mylbot = lbot;
                    568:        int val,shift;
                    569: 
                    570:        chkarg(2,"lsh");
                    571:        if((TYPE(mylbot->val) != INT) || (TYPE(mylbot[1].val) != INT))
                    572:                errorh(Vermisc,
                    573:                       "Non ints to lsh",
                    574:                       nil,FALSE,0,mylbot->val,mylbot[1].val);
                    575:        val = mylbot[0].val->i;
                    576:        shift = mylbot[1].val->i;
                    577:        if(shift < -32 || shift > 32)
                    578:          return(inewint(0));
                    579:        val = val << shift;     /* do the shift */
                    580:        if((val < 0) && (shift < 0))
                    581:        {       /* special case: the vax doesn't have a logical shift
                    582:                   instruction, so we must zero out the ones which
                    583:                   will propogate from the sign position
                    584:                */
                    585:                return(inewint ( val & ~(0x80000000 << (shift+1))));
                    586:        }
                    587:        else return( inewint(val));
                    588: }
                    589: 
                    590: lispval
                    591: Lrot()
                    592: {
                    593:        register rot,val;               /* these must be the first registers */
                    594:        register struct argent *mylbot = lbot;
                    595: 
                    596:        chkarg(2,"rot");
                    597:        if((TYPE(mylbot->val) != INT) || (TYPE(mylbot[1].val) != INT))
                    598:                errorh(Vermisc,
                    599:                       "Non ints to rot",
                    600:                       nil,FALSE,0,mylbot->val,mylbot[1].val);
                    601:        val = mylbot[0].val->i;
                    602:        rot = mylbot[1].val->i;
                    603:        rot = rot % 32 ;        /* bring it down below one byte in size */
                    604:        asm(" rotl r11,r10,r10 ");  /* rotate val by rot and put back in val */
                    605:        return( inewint(val));
                    606: }
                    607: 
                    608: /*----------------- vms routines to simulate dumplisp -------------------- */
                    609: #ifdef VMS
                    610: 
                    611: extern char firstalloc[];
                    612: extern int lsbrkpnt;
                    613: extern char zfreespace[];
                    614: extern int end;
                    615: 
                    616: #define roundup(a,b) (((a-1)|(b-1))+1)
                    617: lispval
                    618: Lsavelsp()
                    619: {
                    620:        char *filnm;
                    621:        int fp,i,num,start;
                    622: 
                    623:        chkarg(1,"savelisp");
                    624: 
                    625:        filnm = (char *) verify(lbot->val, "savelisp: non atom arg");
                    626:        if((fp=creat(filnm,0666)) < 0)
                    627:                errorh(Vermisc,"savelisp: can't open file",nil,FALSE,0,
                    628:                                          lbot->val);
                    629:        start = roundup((int)firstalloc,PAGSIZ);
                    630:        num = roundup(((int)lsbrkpnt)-NBPG-start,PAGSIZ);
                    631:        if((num = write(fp,start,num)) <= 0)
                    632:                error("savelisp: write failed ",FALSE);
                    633:        printf(" %x bytes written from %x to %x \n",num,start,start+num-1);
                    634:        close(fp);
                    635:        return(tatom);
                    636: }
                    637: 
                    638: lispval
                    639: Lrestlsp()
                    640: {
                    641:        char *filnm;
                    642:        int fp,i,num,start;
                    643:        extern int xcycle;
                    644: 
                    645:        chkarg(1,"restorelisp");
                    646: 
                    647:        filnm = (char *) verify(lbot->val,"restorelisp: non atom arg");
                    648:        if((fp=open(filnm,0)) < 0)
                    649:                errorh(Vermisc,"restorelisp: can't open file",nil,FALSE,0,
                    650:                                             lbot->val);
                    651: 
                    652:        start = roundup((int)firstalloc,PAGSIZ);
                    653:        if((num = vread(fp,start,((int)&end)-start)) <= 0)
                    654:                error("restorelisp: read failed " ,FALSE);
                    655:        printf(" %x bytes read into %x to %x\n",num,start,start+num-1);
                    656:        xcycle = 0;     /* indicate no saved pages to xsbrk */
                    657:        close(fp);
                    658:        bnp = orgbnp;
                    659:        lbot = np = orgnp;
                    660:        contval = 0;
                    661:        reset(BRRETB);                  /* reset */
                    662: }
                    663: #endif
                    664: 
                    665: /*----------------------------------------------------------- */
                    666: 
                    667: 
                    668: /* getaddress --
                    669:  *
                    670:  * (getaddress '|_entry1| 'fncname1 '|_entry2| 'fncname2 ...)
                    671:  *
                    672:  * binds value of symbol |_entry1| to function defition of atom fncname1, etc.
                    673:  *
                    674:  * returns fnc-binding of fncname1.
                    675:  *
                    676:  */
                    677: 
                    678: lispval
                    679: Lgetaddress(){
                    680:        register struct argent *mlbot = lbot;
                    681:        register lispval work;
                    682:        register int numberofargs, i;
                    683:        register struct argent *lbot, *np;
                    684:        char *gstab();
                    685:        char ostabf[128];
                    686:        struct nlist NTABLE[100];
                    687:        lispval dispget();
                    688: 
                    689:        snpand(2);
                    690: 
                    691:        if(np-lbot == 2) protect(nil);  /* allow 2 args */
                    692:        numberofargs = (np - lbot)/3;
                    693:        if(numberofargs * 3 != np-lbot)
                    694:           error("getaddress: arguments must come in triples ",FALSE);
                    695: 
                    696:        for ( i=0; i<numberofargs; i++,mlbot += 3) {
                    697:                NTABLE[i].n_value = 0;
                    698:                mlbot[0].val = verify(mlbot[0].val,"Incorrect entry specification for binding");
                    699:                NTABLE[i].n_un.n_name = (char *) mlbot[0].val;
                    700:                while(TYPE(mlbot[1].val) != ATOM)
                    701:                        mlbot[1].val = errorh(Vermisc,
                    702:                                        "Bad associated atom name for binding",
                    703:                                          nil,TRUE,0,mlbot[1].val);
                    704:                mlbot[2].val = dispget(mlbot[2].val,"getaddress: Incorrect discipline specification ",Vsubrou->a.pname);
                    705:        }
                    706:        NTABLE[(numberofargs)].n_un.n_name = "";
                    707:        strcpyn(ostabf,gstab(),128);
                    708:        if ( nlist(ostabf,NTABLE) == -1 ) {
                    709:            errorh(Vermisc,"Getaddress: Bad file",nil,FALSE,0,inewstr(ostabf));
                    710:        } else 
                    711:            for (i=0,mlbot=lbot+1; i<numberofargs; i++,mlbot+=3) {
                    712:                if ( NTABLE[i].n_value == 0 )
                    713:                    fprintf(stderr,"Undefined symbol: %s\n",
                    714:                              NTABLE[i].n_un.n_name);
                    715:                else {
                    716:                    work= newfunct();
                    717:                    work->bcd.entry = (lispval (*) ())NTABLE[i].n_value;
                    718:                    work->bcd.discipline = mlbot[1].val;
                    719:                    mlbot->val->a.fnbnd = work;
                    720:                }
                    721:            };
                    722:        return(lbot[1].val->a.fnbnd);
                    723: };
                    724: 
                    725: /* very temporary function to test the validity of the bind stack */
                    726: 
                    727: bndchk()
                    728: {  
                    729:        register struct nament *npt;
                    730:        register lispval in2;
                    731: 
                    732:        in2 = inewint(200);
                    733:        for(npt=orgbnp; npt < bnp; npt++)
                    734:        {  if((int) npt->atm < (int) in2) asm(" halt ");
                    735:        }
                    736: }
                    737: 
                    738: /*
                    739:  *     formatted printer for lisp data
                    740:  *    use: (cprintf formatstring datum [port])
                    741:  */
                    742: lispval
                    743: Lcprintf()
                    744: {
                    745:     FILE *p;
                    746:     char *fstrng;
                    747:     lispval v;
                    748:     if(np-lbot == 2) protect(nil);     /* write to standard output port */
                    749:     chkarg(3,"cprintf");
                    750: 
                    751:     fstrng = (char *)verify(lbot->val,"cprintf: first arg not string or symbol");
                    752: 
                    753:     p = okport(lbot[2].val,okport(Vpoport->a.clb,poport));
                    754: 
                    755:     switch(TYPE(v=lbot[1].val)) {
                    756: 
                    757:        case INT:  fprintf(p,fstrng,v->i);
                    758:                   break;
                    759: 
                    760:        case DOUB: fprintf(p,fstrng,v->r);
                    761:                   break;
                    762: 
                    763:        case ATOM: fprintf(p,fstrng,v->a.pname);
                    764:                   break;
                    765: 
                    766:        case STRNG:fprintf(p,fstrng,v);
                    767:                   break;
                    768: 
                    769:        default:   error("cprintf: Illegal second argument",FALSE);
                    770:    };
                    771: 
                    772:    return(lbot[1].val);
                    773: }
                    774: 
                    775: lispval
                    776: Lprobef()
                    777: {
                    778:        char *name;
                    779:        chkarg(1,"probef");
                    780: 
                    781:        name = (char *)verify(lbot->val,"probef: not symbol or string arg ");
                    782: 
                    783:        if(access(name,0) == 0) return(tatom);
                    784:        else return(nil);
                    785: }
                    786: 
                    787: lispval
                    788: Lsubstring()
                    789: {      register char *name;
                    790:        register lispval index,length;
                    791:        int restofstring = FALSE;
                    792:        int len,ind,reallen;
                    793:        extern char strbuf[];
                    794: 
                    795:        switch (np-lbot) 
                    796:        {
                    797:          case 2: restofstring = TRUE;
                    798:                  break;
                    799: 
                    800:          case 3: break;
                    801: 
                    802:          default: chkarg(3,"substring");
                    803:        }
                    804: 
                    805:        name = (char *)verify(lbot[0].val,"substring: not symbol or string arg ");
                    806: 
                    807:        while (TYPE(index = lbot[1].val) != INT)
                    808:        {  lbot[1].val = errorh(Vermisc,"substring: non integer index ",nil,
                    809:                                                    TRUE,0,index);
                    810:        }
                    811: 
                    812:        len = strlen(name);
                    813:        ind = index->i;
                    814: 
                    815:        if(ind < 0) ind = len+1 + ind;
                    816: 
                    817:        if(ind < 1 || ind > len) return(nil);   /*index out of bounds*/
                    818:        if(restofstring) return((lispval)inewstr(name+ind-1));
                    819: 
                    820:        while (TYPE(length = lbot[2].val) != INT)
                    821:        { lbot[2].val = errorh(Vermisc,"substring: not integer length ",nil,
                    822:                                                   TRUE,0,length);
                    823:        }
                    824: 
                    825:        if((reallen = length->i ) < 0 || (reallen + ind) > len)
                    826:          return((lispval)inewstr(name+ind-1));
                    827: 
                    828:        strncpy(strbuf,name+ind-1,reallen);
                    829:        strbuf[reallen] = '\0';
                    830:        return((lispval)newstr());
                    831: }
                    832: 
                    833: lispval
                    834: Lsubstringn()
                    835: {
                    836:        register char *name;
                    837:        register int len,ind,reallen;
                    838:        lispval index,length;
                    839:        int restofstring = FALSE;
                    840:        snpand(4);
                    841: 
                    842:        if((np-lbot) == 2) restofstring = TRUE;
                    843:        else { chkarg(3,"substringn");}
                    844: 
                    845:        name = (char *) verify(lbot[0].val,"substringn: non symbol or string arg ");
                    846: 
                    847:        while (TYPE(index = lbot[1].val) != INT)
                    848:        {  lbot[1].val = errorh(Vermisc,"substringn: non integer index ",nil,
                    849:                                                    TRUE,0,index);
                    850:        }
                    851: 
                    852:        if(!restofstring)
                    853:        {
                    854:            while (TYPE(length = lbot[2].val) != INT)
                    855:            { lbot[2].val = errorh(Vermisc,"substringn: not integer length ",
                    856:                                                        nil, TRUE,0,length);
                    857:            }
                    858:            reallen = length->i;
                    859:        }
                    860:        else reallen = -1;
                    861: 
                    862:        len = strlen(name);
                    863:        ind = index->i;
                    864:        if(ind < 0) ind = len + 1 + ind;
                    865:        if( ind < 1 || ind > len) return(nil);
                    866: 
                    867:        if(reallen == 0) 
                    868:            return((lispval)inewint(*(name + ind - 1)));
                    869:        else {
                    870:            char *pnt = name + ind - 1;
                    871:            char *last = name + len -1;
                    872:            lispval cur,start;
                    873: 
                    874:            protect(cur = start = newdot());
                    875:            cur->d.car = inewint(*pnt);
                    876:            while(++pnt <= last && --reallen != 0)
                    877:            {
                    878:               cur->d.cdr = newdot();
                    879:               cur = cur->d.cdr;
                    880:               cur->d.car = inewint(*pnt);
                    881:            }
                    882:            return(start);
                    883:        }
                    884: 
                    885: }
                    886: 

unix.superglobalmegacorp.com

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