|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid = ! 3: "$Header: /na/franz/franz/RCS/lam3.c,v 1.2 83/08/06 08:37:32 jkf Exp $"; ! 4: #endif ! 5: ! 6: /* -[Fri Aug 5 12:47:19 1983 by jkf]- ! 7: * lam3.c $Locker: $ ! 8: * lambda functions ! 9: * ! 10: * (c) copyright 1982, Regents of the University of California ! 11: */ ! 12: ! 13: # include "global.h" ! 14: # include "chars.h" ! 15: # include "chkrtab.h" ! 16: ! 17: lispval ! 18: Lalfalp() ! 19: { ! 20: register char *first, *second; ! 21: ! 22: chkarg(2,"alphalessp"); ! 23: first = (char *) verify(lbot->val,"alphalessp: non symbol or string arg"); ! 24: second = (char *) verify((lbot+1)->val,"alphalessp: non symbol or string arg"); ! 25: if(strcmp(first,second) < 0) ! 26: return(tatom); ! 27: else ! 28: return(nil); ! 29: } ! 30: ! 31: lispval ! 32: Lncons() ! 33: { ! 34: register lispval handy; ! 35: ! 36: chkarg(1,"ncons"); ! 37: handy = newdot(); ! 38: handy->d.cdr = nil; ! 39: handy->d.car = lbot->val; ! 40: return(handy); ! 41: } ! 42: lispval ! 43: Lzerop() ! 44: { ! 45: register lispval handy; ! 46: ! 47: chkarg(1,"zerop"); ! 48: handy = lbot->val; ! 49: switch(TYPE(handy)) { ! 50: case INT: ! 51: return(handy->i==0?tatom:nil); ! 52: case DOUB: ! 53: return(handy->r==0.0?tatom:nil); ! 54: } ! 55: return(nil); ! 56: } ! 57: lispval ! 58: Lonep() ! 59: { ! 60: register lispval handy; ! 61: lispval Ladd(); ! 62: ! 63: handy = lbot->val; ! 64: switch(TYPE(handy)) { ! 65: case INT: ! 66: return(handy->i==1?tatom:nil); ! 67: case DOUB: ! 68: return(handy->r==1.0?tatom:nil); ! 69: case SDOT: ! 70: protect(inewint(0)); ! 71: handy = Ladd(); ! 72: if(TYPE(handy)!=INT || handy->i !=1) ! 73: return(nil); ! 74: else ! 75: return(tatom); ! 76: } ! 77: return(nil); ! 78: } ! 79: ! 80: lispval ! 81: cmpx(lssp) ! 82: { ! 83: register struct argent *argp; ! 84: register struct argent *outarg; ! 85: register struct argent *onp = np; ! 86: Savestack(3); ! 87: ! 88: ! 89: argp = lbot + 1; ! 90: outarg = np; ! 91: while(argp < onp) { ! 92: ! 93: np = outarg + 2; ! 94: lbot = outarg; ! 95: if(lssp) ! 96: *outarg = argp[-1], outarg[1] = *argp++; ! 97: else ! 98: outarg[1] = argp[-1], *outarg = *argp++; ! 99: lbot->val = Lsub(); ! 100: np = lbot + 1; ! 101: if(Lnegp()==nil) ! 102: { ! 103: Restorestack(); ! 104: return(nil); ! 105: } ! 106: } ! 107: Restorestack(); ! 108: return(tatom); ! 109: } ! 110: ! 111: lispval ! 112: Lgreaterp() ! 113: { ! 114: register int typ; ! 115: /* do the easy cases first */ ! 116: if(np-lbot == 2) ! 117: { if((typ=TYPE(lbot->val)) == INT) ! 118: { if((typ=TYPE(lbot[1].val)) == INT) ! 119: return((lbot[0].val->i - lbot[1].val->i) > 0 ? tatom : nil); ! 120: else if(typ == DOUB) ! 121: return((lbot[0].val->i - lbot[1].val->r) > 0.0 ? tatom : nil); ! 122: } ! 123: else if(typ == DOUB) ! 124: { if((typ=TYPE(lbot[1].val)) == INT) ! 125: return((lbot[0].val->r - lbot[1].val->i) > 0.0 ? tatom : nil); ! 126: else if(typ == DOUB) ! 127: return((lbot[0].val->r - lbot[1].val->r) > 0.0 ? tatom : nil); ! 128: } ! 129: } ! 130: ! 131: return(cmpx(FALSE)); ! 132: } ! 133: ! 134: lispval ! 135: Llessp() ! 136: { ! 137: register int typ; ! 138: /* do the easy cases first */ ! 139: if(np-lbot == 2) ! 140: { if((typ=TYPE(lbot->val)) == INT) ! 141: { if((typ=TYPE(lbot[1].val)) == INT) ! 142: return((lbot[0].val->i - lbot[1].val->i) < 0 ? tatom : nil); ! 143: else if(typ == DOUB) ! 144: return((lbot[0].val->i - lbot[1].val->r) < 0.0 ? tatom : nil); ! 145: } ! 146: else if(typ == DOUB) ! 147: { if((typ=TYPE(lbot[1].val)) == INT) ! 148: return((lbot[0].val->r - lbot[1].val->i) < 0.0 ? tatom : nil); ! 149: else if(typ == DOUB) ! 150: return((lbot[0].val->r - lbot[1].val->r) < 0.0 ? tatom : nil); ! 151: } ! 152: } ! 153: ! 154: return(cmpx(TRUE)); ! 155: } ! 156: ! 157: lispval ! 158: Ldiff() ! 159: { ! 160: register lispval arg1,arg2; ! 161: register handy = 0; ! 162: ! 163: ! 164: chkarg(2,"Ldiff"); ! 165: arg1 = lbot->val; ! 166: arg2 = (lbot+1)->val; ! 167: if(TYPE(arg1)==INT && TYPE(arg2)==INT) { ! 168: handy=arg1->i - arg2->i; ! 169: } ! 170: else error("non-numeric argument",FALSE); ! 171: return(inewint(handy)); ! 172: } ! 173: ! 174: lispval ! 175: Lmod() ! 176: { ! 177: register lispval arg1,arg2; ! 178: lispval handy; ! 179: struct sdot fake1, fake2; ! 180: fake2.CDR = 0; ! 181: fake1.CDR = 0; ! 182: ! 183: chkarg(2,"mod"); ! 184: handy = arg1 = lbot->val; ! 185: arg2 = (lbot+1)->val; ! 186: switch(TYPE(arg1)) { ! 187: case SDOT: ! 188: switch(TYPE(arg2)) { ! 189: case SDOT: /* both are already bignums */ ! 190: break; ! 191: case INT: /* convert arg2 to bignum */ ! 192: fake2.I = arg2->i; ! 193: arg2 =(lispval) &fake2; ! 194: break; ! 195: default: ! 196: error("non-numeric argument",FALSE); ! 197: } ! 198: break; ! 199: case INT: ! 200: switch(TYPE(arg2)) { ! 201: case SDOT: /* convert arg1 to bignum */ ! 202: fake1.I = arg1->i; ! 203: arg1 =(lispval) &fake1; ! 204: break; ! 205: case INT: /* both are fixnums */ ! 206: return( inewint ((arg1->i) % (arg2->i)) ); ! 207: default: ! 208: error("non-numeric argument",FALSE); ! 209: } ! 210: break; ! 211: default: ! 212: error("non-numeric argument",FALSE); ! 213: } ! 214: if(TYPE((lbot+1)->val)==INT && lbot[1].val->i==0) ! 215: return(handy); ! 216: divbig(arg1,arg2,(lispval *)0,&handy); ! 217: if(handy==((lispval)&fake1)) ! 218: handy = inewint(fake1.I); ! 219: if(handy==((lispval)&fake2)) ! 220: handy = inewint(fake2.I); ! 221: return(handy); ! 222: } ! 223: lispval ! 224: Ladd1() ! 225: { ! 226: register lispval handy; ! 227: lispval Ladd(); ! 228: Savestack(1); /* fixup entry mask */ ! 229: chkarg(1,"add1"); ! 230: ! 231: /* simple test first */ ! 232: if((TYPE(lbot->val) == INT) && (lbot->val->i < MaxINT)) ! 233: { ! 234: Restorestack(); ! 235: return(inewint(lbot->val->i + 1)); ! 236: } ! 237: ! 238: handy = rdrint; ! 239: handy->i = 1; ! 240: protect(handy); ! 241: handy=Ladd(); ! 242: Restorestack(); ! 243: return(handy); ! 244: ! 245: } ! 246: ! 247: ! 248: ! 249: lispval ! 250: Lsub1() ! 251: { ! 252: register lispval handy; ! 253: lispval Ladd(); ! 254: Savestack(1); /* fixup entry mask */ ! 255: chkarg(1,"sub1"); ! 256: ! 257: if((TYPE(lbot->val) == INT) && (lbot->val->i > MinINT)) ! 258: { ! 259: Restorestack(); ! 260: return(inewint(lbot->val->i - 1)); ! 261: } ! 262: ! 263: handy = rdrint; ! 264: handy->i = - 1; ! 265: protect(handy); ! 266: handy=Ladd(); ! 267: Restorestack(); ! 268: return(handy); ! 269: } ! 270: ! 271: lispval ! 272: Lminus() ! 273: { ! 274: register lispval arg1, handy; ! 275: lispval subbig(); ! 276: ! 277: chkarg(1,"minus"); ! 278: arg1 = lbot->val; ! 279: handy = nil; ! 280: switch(TYPE(arg1)) { ! 281: case INT: ! 282: handy= inewint(0 - arg1->i); ! 283: break; ! 284: case DOUB: ! 285: handy = newdoub(); ! 286: handy->r = -arg1->r; ! 287: break; ! 288: case SDOT: { struct sdot dummyb; ! 289: handy = (lispval) &dummyb; ! 290: handy->s.I = 0; ! 291: handy->s.CDR = (lispval) 0; ! 292: handy = subbig(handy,arg1); ! 293: break; } ! 294: ! 295: default: ! 296: error("non-numeric argument",FALSE); ! 297: } ! 298: return(handy); ! 299: } ! 300: ! 301: lispval ! 302: Lnegp() ! 303: { ! 304: register lispval handy = np[-1].val, work; ! 305: register flag = 0; ! 306: ! 307: loop: ! 308: switch(TYPE(handy)) { ! 309: case INT: ! 310: if(handy->i < 0) flag = TRUE; ! 311: break; ! 312: case DOUB: ! 313: if(handy->r < 0) flag = TRUE; ! 314: break; ! 315: case SDOT: ! 316: for(work = handy; ! 317: work->s.CDR!=(lispval) 0; ! 318: work = work->s.CDR) {;} ! 319: if(work->s.I < 0) flag = TRUE; ! 320: break; ! 321: default: ! 322: handy = errorh1(Vermisc, ! 323: "minusp: Non-(int,real,bignum) arg: ", ! 324: nil, ! 325: TRUE, ! 326: 0, ! 327: handy); ! 328: goto loop; ! 329: } ! 330: if(flag) return(tatom); ! 331: return(nil); ! 332: } ! 333: ! 334: lispval ! 335: Labsval() ! 336: { ! 337: register lispval arg1; ! 338: ! 339: chkarg(1,"absval"); ! 340: arg1 = lbot->val; ! 341: if(Lnegp()!=nil) return(Lminus()); ! 342: ! 343: return(arg1); ! 344: } ! 345: ! 346: /* ! 347: * ! 348: * (oblist) ! 349: * ! 350: * oblist returns a list of all symbols in the oblist ! 351: * ! 352: * written by jkf. ! 353: */ ! 354: lispval ! 355: Loblist() ! 356: { ! 357: int indx; ! 358: lispval headp, tailp ; ! 359: struct atom *symb ; ! 360: extern int hashtop; ! 361: Savestack(0); ! 362: ! 363: headp = tailp = newdot(); /* allocate first DTPR */ ! 364: protect(headp); /*protect the list from garbage collection*/ ! 365: /*line added by kls */ ! 366: ! 367: for( indx=0 ; indx <= hashtop-1 ; indx++ ) /* though oblist */ ! 368: { ! 369: for( symb = hasht[indx] ; ! 370: symb != (struct atom *) CNIL ; ! 371: symb = symb-> hshlnk) ! 372: { ! 373: if(TYPE(symb) != ATOM) ! 374: { printf(" non symbol in hasht[%d] = %x: ",indx,symb); ! 375: printr((lispval) symb,stdout); ! 376: printf(" \n"); ! 377: fflush(stdout); ! 378: } ! 379: tailp->d.car = (lispval) symb ; /* remember this atom */ ! 380: tailp = tailp->d.cdr = newdot() ; /* link to next DTPR */ ! 381: } ! 382: } ! 383: ! 384: tailp->d.cdr = nil ; /* close the list unfortunately throwing away ! 385: the last DTPR ! 386: */ ! 387: Restorestack(); ! 388: return(headp); ! 389: } ! 390: ! 391: /* ! 392: * Maclisp setsyntax function: ! 393: * (setsyntax c s x) ! 394: * c represents character either by fixnum or atom ! 395: * s is the atom "macro" or the atom "splicing" (in which case x is the ! 396: * macro to be invoked); or nil (meaning don't change syntax of c); or ! 397: * (well thats enough for now) if s is a fixnum then we modify the bits ! 398: * for c in the readtable. ! 399: */ ! 400: ! 401: lispval ! 402: Lsetsyn() ! 403: { ! 404: register lispval s, c; ! 405: register struct argent *mynp; ! 406: register index; ! 407: lispval x /* ,debugmode */; ! 408: extern unsigned char *ctable; ! 409: extern lispval Istsrch(); ! 410: ! 411: switch(np-lbot) { ! 412: case 2: ! 413: x= nil; /* only 2 args given */ ! 414: case 3: ! 415: x = lbot[2].val; /* all three args given */ ! 416: break; ! 417: default: ! 418: argerr("setsyntax"); ! 419: } ! 420: s = Vreadtable->a.clb; ! 421: chkrtab(s); ! 422: /* debugging code ! 423: debugmode = Istsrch(matom("debugging"))->d.cdr->d.cdr->d.cdr; ! 424: if(debugmode) printf("Readtable addr: %x\n",ctable); ! 425: end debugging code */ ! 426: mynp = lbot; ! 427: c = (mynp++)->val; ! 428: s = (mynp++)->val; ! 429: ! 430: switch(TYPE(c)) { ! 431: default: ! 432: error("neither fixnum, atom or string as char to setsyntax",FALSE); ! 433: ! 434: case ATOM: ! 435: index = *(c->a.pname); ! 436: if((c->a.pname)[1]) ! 437: errorh1(Vermisc,"Only 1 char atoms to setsyntax", ! 438: nil,FALSE,0,c); ! 439: break; ! 440: ! 441: case INT: ! 442: index = c->i; ! 443: break; ! 444: ! 445: case STRNG: ! 446: index = (int) *((char *) c); ! 447: } ! 448: switch(TYPE(s)) { ! 449: case ATOM: ! 450: if(s==splice || s==macro) { ! 451: if(s==splice) ! 452: ctable[index] = VSPL; ! 453: else if(s==macro) ! 454: ctable[index] = VMAC; ! 455: if(TYPE(c)!=ATOM) { ! 456: strbuf[0] = index; ! 457: strbuf[1] = 0; ! 458: c = (getatom(TRUE)); ! 459: } ! 460: Iputprop(c,x,lastrtab); ! 461: return(tatom); ! 462: } ! 463: ! 464: /* ... fall into */ ! 465: default: errorh1(Vermisc,"int:setsyntax : illegal second argument ", ! 466: nil,FALSE,0,s); ! 467: /* not reached */ ! 468: ! 469: case INT: ! 470: switch(synclass(s->i)) { ! 471: case CESC: Xesc = (char) index; break; ! 472: case CDQ: Xdqc = (char) index; break; ! 473: case CSD: Xsdc = (char) index; /* string */ ! 474: } ! 475: ! 476: if(synclass(ctable[index])==CESC /* if we changed the current esc */ ! 477: && (synclass(s->i)!=CESC) /* to something else, pick current */ ! 478: && Xesc == (char) index) { ! 479: ctable[index] = s->i; ! 480: rpltab(CESC,&Xesc); ! 481: } ! 482: else if(synclass(ctable[index])==CDQ /* likewise for double quote */ ! 483: && synclass(s->i) != CDQ ! 484: && Xdqc == (char) index) { ! 485: ctable[index] = s->i; ! 486: rpltab(CDQ,&Xdqc); ! 487: } ! 488: else if(synclass(ctable[index]) == CSD /* and for string delimiter */ ! 489: && synclass(s->i) != CSD ! 490: && Xsdc == (char) index) { ! 491: ctable[index] = s->i; ! 492: rpltab(CSD,&Xsdc); ! 493: } ! 494: else ctable[index] = s->i; ! 495: ! 496: break; ! 497: ! 498: } ! 499: return(tatom); ! 500: } ! 501: ! 502: /* ! 503: * this aux function is used by setsyntax to determine the new current ! 504: * escape or double quote character. It scans the character table for ! 505: * the first character with the given class (either VESC or VDQ) and ! 506: * puts that character in Xesc or Xdqc (whichever is pointed to by ! 507: * addr). ! 508: */ ! 509: rpltab(cclass,addr) ! 510: char cclass; ! 511: unsigned char *addr; ! 512: { ! 513: register int i; ! 514: extern unsigned char *ctable; ! 515: for(i=0; i<=127 && synclass(ctable[i]) != cclass; i++); ! 516: if(i<=127) *addr = (unsigned char) i; ! 517: else *addr = '\0'; ! 518: } ! 519: ! 520: ! 521: /* ! 522: * int:getsyntax from lisp. ! 523: * returns the fixnum syntax code from the readtable for the given character. ! 524: * to be used by the lisp-code function getsyntax, not to be used by ! 525: * joe user. ! 526: */ ! 527: lispval ! 528: Lgetsyntax() ! 529: { ! 530: register char *name; ! 531: int number, typ; ! 532: lispval handy; ! 533: ! 534: chkarg(1,"int:getsyntax"); ! 535: handy = lbot[0].val; ! 536: while (1) ! 537: { ! 538: if((typ = TYPE(handy)) == ATOM) ! 539: { ! 540: name = handy->a.pname; ! 541: } ! 542: else if (typ == STRNG) ! 543: { ! 544: name = (char *)handy; ! 545: } ! 546: else if(typ == INT) ! 547: { ! 548: number = handy->i; ! 549: break; ! 550: } ! 551: else { ! 552: handy = ! 553: errorh1(Vermisc,"int:getsyntax : bad character ", ! 554: nil,TRUE,0,handy); ! 555: continue; /* start at the top */ ! 556: } ! 557: /* figure out the number of the first byte */ ! 558: number = (int) name[0]; ! 559: if(name[1] != '\0') ! 560: { ! 561: handy = errorh1(Vermisc, ! 562: "int:getsyntax : only single character allowed ", ! 563: nil,TRUE,0,handy); ! 564: } ! 565: else break; ! 566: } ! 567: /* see if number is within range */ ! 568: if(number < 0 || number > 255) ! 569: errorh1(Vermisc,"int:getsyntax : character number out of range ",nil, ! 570: FALSE,0,inewint(number)); ! 571: chkrtab(Vreadtable->a.clb); /* make sure readtable is correct */ ! 572: return(inewint(ctable[number])); ! 573: } ! 574: ! 575: ! 576: ! 577: ! 578: lispval ! 579: Lzapline() ! 580: { ! 581: register FILE *port; ! 582: extern FILE * rdrport; ! 583: ! 584: port = rdrport; ! 585: while (!feof(port) && (getc(port)!='\n') ); ! 586: return(nil); ! 587: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.