Annotation of 40BSD/cmd/lisp/lam8.c, revision 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.