|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.