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