Annotation of 3BSD/cmd/lisp/lam5.c, revision 1.1.1.1

1.1       root        1: #include "global.h"
                      2: #include "chkrtab.h"
                      3: 
                      4: /*===========================================
                      5: -
                      6: -      explode functions
                      7: - The following function partially implement two explode functions,
                      8: - explodec and exploden.  They only work for atom arguments.
                      9: -
                     10: -===========================================*/
                     11: 
                     12: #include "chars.h"
                     13: lispval
                     14: Lexpldx(kind,slashify)
                     15: int kind, slashify;    /* 0=explodec   1=exploden  */
                     16: {
                     17:        int typ, i;
                     18:        char ch, *strb, strbb[BUFSIZ];  /* temporary string buffer */
                     19:        register lispval last, handy;
                     20:        char Idqc = Xdqc;
                     21:        snpand(4); /* kludge register save mask */
                     22: 
                     23:        chkarg(1);
                     24: 
                     25:        handy = Vreadtable->clb;
                     26:        chkrtab(handy);
                     27:        handy = lbot->val;
                     28:        *strbuf = 0;
                     29:        typ=TYPE(handy);        /* we only work for a few types */
                     30: 
                     31: 
                     32:        /* put the characters to return in the string buffer strb */
                     33: 
                     34:        switch(typ) {
                     35:        case STRNG:
                     36:                strb = (char *) handy;
                     37:                if(Xsdc)Idqc = Xsdc;
                     38:                goto common;
                     39:        case ATOM:
                     40:                strb = handy->pname;
                     41:                if(strb[0]==0) {
                     42:                        strb = strbb;
                     43:                        strbb[0] = Xdqc;
                     44:                        strbb[1] = Xdqc;
                     45:                        strbb[2] = 0;
                     46:                } else
                     47:        common:
                     48:                if(slashify != 0)
                     49:                {
                     50:                        register char *cp, *out = strbb;
                     51:                        cp = strb;
                     52:                        strb = strbb;
                     53:                        if(ctable[(*cp)&0177]==VNUM)
                     54:                                *out++ = Xesc;
                     55:                        for(; *cp; cp++)
                     56:                        {
                     57:                                if(ctable[*cp]& QUTMASK)
                     58:                                        *out++ = Xesc;
                     59:                                *out++ = *cp;
                     60:                        }
                     61:                        *out = 0;
                     62:                }
                     63:                                
                     64:                break;
                     65:        case INT:
                     66:                strb = strbb;
                     67:                sprintf(strb, "%d", lbot->val->i);
                     68:                break;
                     69:        case DOUB:
                     70:                strb = strbb;
                     71:                sprintf(strb, "%0.16G", lbot->val->r);
                     72:                break;
                     73:        case SDOT:
                     74:        {
                     75:                struct _iobuf _strbuf;
                     76:                register count;
                     77:                for((handy = lbot->val), count = 12;
                     78:                    handy->CDR!=(lispval) 0;
                     79:                    (handy = handy->CDR), count += 12);
                     80:                strb = (char *) alloca(count);
                     81: 
                     82:                _strbuf._flag = _IOWRT+_IOSTRG;
                     83:                _strbuf._ptr = strb;
                     84:                _strbuf._cnt = count;
                     85:                pbignum(lbot->val,&_strbuf);
                     86:                putc('.',&_strbuf);
                     87:                putc(0,&_strbuf);
                     88:                break;
                     89:        }
                     90:        default:
                     91:                        errorh(Vermisc,"EXPLODE ARG MUST BE STRING, SYMBOL, FIXNUM, OR FLONUM",nil,FALSE,0,handy);
                     92:                        return(nil);
                     93:                }
                     94: 
                     95: 
                     96:        if( strb[0] != NULL_CHAR )      /* if there is something to do */
                     97:        {
                     98:            register lispval prev;
                     99: 
                    100:            protect(handy = last = newdot()); 
                    101:            strbuf[1] = NULL_CHAR ;     /* set up for getatom */
                    102:            atmlen = 2;
                    103: 
                    104:            for(i=0; ch = strb[i++]; ) {
                    105:                switch(kind) {
                    106: 
                    107:                  case 0: strbuf[0] = hash = ch;   /* character explode */
                    108:                          hash = 177 & hash;    /* cut 1st bit off if any */
                    109:                          last->car = (lispval) getatom(); /* look in oblist */
                    110:                          break;
                    111: 
                    112:                  case 1: 
                    113:                          last->car = inewint(ch);
                    114:                          break;
                    115:                }
                    116: 
                    117:                /* advance pointers */
                    118:                prev = last;
                    119:                last->cdr = newdot();
                    120:                last = last->cdr;
                    121:            }
                    122: 
                    123:            /* end list with a nil pointer */
                    124:            prev->cdr = nil;
                    125:            return(handy);
                    126:        }
                    127:        else return(nil);       /* return nil if no characters */
                    128: }
                    129: 
                    130: /*===========================
                    131: -
                    132: - (explodec 'atm) returns (a t m)
                    133: - (explodec 234) returns (\2 \3 \4)
                    134: -===========================*/
                    135: 
                    136: lispval
                    137: Lexpldc()
                    138: { return(Lexpldx(0,0)); }
                    139: 
                    140: 
                    141: /*===========================
                    142: -
                    143: - (exploden 'abc) returns (65 66 67)
                    144: - (exploden 123)  returns (49 50 51)
                    145: -=============================*/
                    146: 
                    147: 
                    148: lispval
                    149: Lexpldn()
                    150: { return(Lexpldx(1,0)); }
                    151: 
                    152: /*===========================
                    153: -
                    154: - (explodea "123")  returns (\\ \1 \2 \3);
                    155: - (explodea 123)  returns (\1 \2 \3);
                    156: -=============================*/
                    157: 
                    158: lispval
                    159: Lexplda()
                    160: { return(Lexpldx(0,1)); }
                    161: 
                    162: /*
                    163:  * (argv) returns how many arguments where on the command line which invoked
                    164:  * lisp; (argv i) returns the i'th argument made into an atom;
                    165:  */
                    166: 
                    167: lispval
                    168: Largv()
                    169: {
                    170:        register lispval handy;
                    171:        register index;
                    172:        register char c, *base;
                    173:        extern int Xargc;
                    174:        extern char **Xargv;
                    175: 
                    176:        chkarg(1);
                    177:        handy = lbot->val;
                    178:        
                    179:        if(TYPE(handy)==INT && handy->i>=0 && handy->i<Xargc) {
                    180:                strcpy(strbuf,Xargv[handy->i]);
                    181:                return(getatom());
                    182:        } else { 
                    183:                return(inewint(Xargc));
                    184:        }
                    185: }
                    186: /*
                    187:  * (chdir <atom>) executes a chdir command
                    188:  * if successful, return t otherwise returns nil
                    189:  */
                    190: lispval Lchdir(){
                    191:        register lispval handy;
                    192: 
                    193:        chkarg(1);
                    194:        handy=lbot->val;
                    195:        if(TYPE(handy)==ATOM && (chdir(handy->pname)>=0))
                    196:                return(tatom);
                    197:        else
                    198:                return(nil);
                    199: }
                    200: 
                    201: /* ==========================================================
                    202: -
                    203: -      ascii   - convert from number to ascii character
                    204: -
                    205: - form:(ascii number)
                    206: -
                    207: -      the number is checked so that it is in the range 0-255
                    208: - then it is made a character and returned
                    209: - =========================================================*/
                    210: 
                    211: lispval
                    212: Lascii() 
                    213: {
                    214:        register lispval handy;
                    215: 
                    216:        handy = lbot->val;              /* get argument */
                    217: 
                    218:        if(TYPE(handy) != INT)          /* insure that it is an integer */
                    219:        {       error("argument not an integer",FALSE);
                    220:                return(nil);
                    221:        }
                    222: 
                    223:        if(handy->i < 0 || handy->i > 0377)     /* insure that it is in range*/
                    224:        {       error("argument is out of ascii range",FALSE);
                    225:                return(nil);
                    226:        }
                    227: 
                    228:        strbuf[0] = handy->i ;  /* ok value, make into a char */
                    229:        strbuf[1] = NULL_CHAR;
                    230: 
                    231:        /* lookup and possibly intern the atom given in strbuf */
                    232: 
                    233:        return( (lispval) getatom() );
                    234: }
                    235: 
                    236: /*
                    237:  *  boole - maclisp bitwise boolean function
                    238:  *  (boole k x y) where k determines which of 16 possible bitwise 
                    239:  *  truth tables may be applied.  Common values are 1 (and) 6 (xor) 7 (or)
                    240:  *  the result is mapped over each pair of bits on input
                    241:  */
                    242: lispval
                    243: Lboole(){
                    244:        register x, y;
                    245:        register lispval result;
                    246:        register struct argent *mynp;
                    247:        int k;
                    248: 
                    249:        if(np - lbot < 3)
                    250:                error("Boole demands at least 3 args",FALSE);
                    251:        mynp = lbot+AD;
                    252:        k = mynp->val->i & 15;
                    253:        x = (mynp+1)->val->i;
                    254:        for(mynp += 2; mynp < np; mynp++) {
                    255:                y = mynp->val->i;
                    256:                switch(k) {
                    257: 
                    258:                case 0: x = 0;
                    259:                        break;
                    260:                case 1: x = x & y;
                    261:                        break;
                    262:                case 2: x = y & ~x;
                    263:                        break;
                    264:                case 3: x = y;
                    265:                        break;
                    266:                case 4: x = x & ~y;
                    267:                        break;
                    268:                /* case 5:      x = x; break; */
                    269:                case 6: x = x ^ y;
                    270:                        break;
                    271:                case 7: x = x | y;
                    272:                        break;
                    273:                case 8: x = ~(x | y);
                    274:                        break;
                    275:                case 9: x = ~(x ^ y);
                    276:                        break;
                    277:                case 10: x = ~x;
                    278:                        break;
                    279:                case 11: x = ~x | y;
                    280:                        break;
                    281:                case 12: x = ~y;
                    282:                        break;
                    283:                case 13: x = x | ~y;
                    284:                        break;
                    285:                case 14: x = ~x | ~y;
                    286:                        break;
                    287:                case 15: x = -1;
                    288:                }
                    289:        }
                    290:        return(inewint(x));
                    291: }
                    292: lispval
                    293: Lfact()
                    294: {
                    295:        register lispval result, handy;
                    296:        register itemp;
                    297:        snpand(3); /* fixup entry mask */
                    298: 
                    299:        result = lbot->val;
                    300:        if(TYPE(result)!=INT) error("Factorial of Non-fixnum.  If you want me\
                    301: to calculate fact of > 2^30 We will be here till doomsday!.",FALSE);
                    302:        itemp = result->i;
                    303:        protect(result = newsdot());
                    304:        result->CDR=(lispval)0;
                    305:        result->i = 1;
                    306:        for(; itemp > 1; itemp--)
                    307:                dmlad(result,itemp,0);
                    308:        if(result->CDR) return(result);
                    309:        (handy = newint())->i = result->i;
                    310:        return(handy);
                    311: }
                    312: /*
                    313:  * fix -- maclisp floating to fixnum conversion
                    314:  * for the moment, mereley convert floats to ints.
                    315:  * eventual convert to bignum if too big to fit.
                    316:  */
                    317:  lispval Lfix() 
                    318:  {
                    319:        register lispval result, handy;
                    320: 
                    321:        chkarg(1);
                    322:        handy = lbot->val;
                    323:        switch(TYPE(handy)) {
                    324:        default:
                    325:                error("innaproriate arg to fix.",FALSE);
                    326:        case INT:
                    327:        case SDOT:
                    328:                return(handy);
                    329:        case DOUB:
                    330:                if(handy->r >= 0)
                    331:                        return(inewint((int)handy->r));
                    332:                else
                    333:                        return(inewint(((int)handy->r)-1));
                    334:        }
                    335: }
                    336: 
                    337: lispval
                    338: Lfloat()
                    339: {
                    340:        register lispval handy,result;
                    341:        chkarg(1);
                    342:        handy = lbot->val;
                    343:        switch(TYPE(handy))
                    344:        {
                    345:          case DOUB: return(handy);
                    346: 
                    347: 
                    348:          case INT:  result = newdoub();
                    349:                     result->r = (double) handy->i;
                    350:                     return(result);
                    351:                     
                    352: 
                    353:          default: error(Vermisc,"Bad argument to float",nil,FALSE,0,handy);
                    354:        }
                    355: }
                    356: 
                    357: /* Lbreak ***************************************************************/
                    358: /* If first argument is not nil, this is evaluated and printed.  Then  */
                    359: /* error is called with the "breaking" message.                                */
                    360: lispval Lbreak() {
                    361:        register lispval hold;
                    362: 
                    363:        if (np > lbot) {
                    364:                printr(lbot->val,poport);
                    365:                dmpport(poport);
                    366:        }
                    367:        return(error("",TRUE));
                    368: }
                    369: 
                    370: 
                    371: lispval LDivide() {
                    372:        register lispval result, work, temp;
                    373:        register struct argent *mynp;
                    374:        register struct argent *lbot, *np;
                    375:        int typ;
                    376:        lispval quo, rem; struct sdot dummy;
                    377: 
                    378:        chkarg(2);
                    379:        mynp = lbot;
                    380:        result = mynp->val;
                    381:        work = (mynp+1)->val;
                    382: 
                    383:        if((typ=TYPE(result))==INT) {
                    384:                protect(temp=newsdot());
                    385:                temp->i = result->i;
                    386:                result = temp;
                    387:        } else if (typ!=SDOT)
                    388:                error("First arg to divide neither a bignum nor int.",FALSE);
                    389:        typ = TYPE(work);
                    390:        if(typ != INT && typ != SDOT)
                    391:                error("second arg to Divide neither an sdot nor an int.",FALSE);
                    392:        if(typ == INT) {
                    393:                dummy.CDR = (lispval) 0;
                    394:                dummy.I = work->i;
                    395:                work = (lispval) &dummy;
                    396:        }
                    397:        divbig(result,work, &quo, &rem);
                    398:        protect(quo);
                    399:        if(rem==((lispval) &dummy))
                    400:                protect(rem = inewint(dummy.I));
                    401:        protect(result = work = newdot());
                    402:        work->car = quo;
                    403:        (work->cdr = newdot())->car = rem;
                    404:        return(result);
                    405: }
                    406: lispval LEmuldiv(){
                    407:        register struct argent * mynp = lbot+AD;
                    408:        register lispval work, result;
                    409:        int quo, rem;
                    410:        snpand(3); /* fix register mask */
                    411: 
                    412:        /* (Emuldiv mul1 mult2 add quo) => 
                    413:                temp = mul1 + mul2 + sext(add);
                    414:                result = (list temp/quo temp%quo);
                    415:                to mix C and lisp a bit */
                    416: 
                    417:        Imuldiv(mynp[0].val->i, mynp[1].val->i, mynp[2].val->i,
                    418:                mynp[3].val->i, &quo, &rem);
                    419:        protect(result=newdot());
                    420:        (result->car=inewint(quo));
                    421:        work = result->cdr = newdot();
                    422:        (work->car=inewint(rem));
                    423:        return(result);
                    424: }
                    425: static Imuldiv() {
                    426: asm("  emul    4(ap),8(ap),12(ap),r0");
                    427: asm("  ediv    16(ap),r0,*20(ap),*24(ap)");
                    428: }
                    429: 
                    430: 

unix.superglobalmegacorp.com

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