|
|
1.1 ! root 1: static char *sccsid = "@(#)lam2.c 34.1 10/3/80"; ! 2: ! 3: # include "global.h" ! 4: # include <signal.h> ! 5: /* ! 6: * (flatc thing max) returns the smaller of max and the number of chars ! 7: * required to print thing linearly. ! 8: * if max argument is not given, we assume the second arg is infinity ! 9: */ ! 10: static flen; /*Internal to this module, used as a running counter of flatsize*/ ! 11: static fmax; /*used for maximum for quick reference */ ! 12: ! 13: lispval ! 14: Lflatsi() ! 15: { ! 16: register lispval current, temp; ! 17: register struct argent *mylbot = lbot; ! 18: snpand(3); /* fixup entry mask */ ! 19: ! 20: if( np-lbot == 1) fmax = 0x7fffffff; /* biggest integer */ ! 21: else fmax = mylbot[1].val->i; ! 22: flen = 0; ! 23: current = mylbot->val; ! 24: protect(nil); /*create space for argument to pntlen*/ ! 25: Iflatsi(current); ! 26: return(inewint(flen)); ! 27: } ! 28: /* ! 29: * Iflatsi does the real work of the calculation for flatc ! 30: */ ! 31: Iflatsi(current) ! 32: register lispval current; ! 33: { ! 34: register lispval handy; ! 35: register int temp; ! 36: ! 37: if(flen > fmax) return(fmax); ! 38: switch(TYPE(current)) { ! 39: ! 40: patom: ! 41: case INT: case ATOM: case DOUB: case STRNG: ! 42: np[-1].val = current; ! 43: flen += Ipntlen(); ! 44: return; ! 45: ! 46: pthing: ! 47: case DTPR: ! 48: flen++; ! 49: Iflatsi(current->d.car); ! 50: current = current->d.cdr; ! 51: if(current == nil) { ! 52: flen++; ! 53: return; ! 54: } ! 55: if(flen > fmax) return; ! 56: switch(TYPE(current)) { ! 57: case INT: case ATOM: case DOUB: ! 58: flen += 4; ! 59: goto patom; ! 60: case DTPR: ! 61: goto pthing; ! 62: } ! 63: } ! 64: } ! 65: ! 66: ! 67: #define EADC -1 ! 68: #define EAD -2 ! 69: lispval ! 70: Lread() ! 71: { return (r(EAD)); } ! 72: ! 73: lispval ! 74: Lratom() ! 75: { return (r(ATOM)); } ! 76: ! 77: lispval ! 78: Lreadc() ! 79: { return (r(EADC)); } ! 80: ! 81: #include "chars.h" ! 82: #include "chkrtab.h" ! 83: ! 84: extern char *ctable; ! 85: /* r *********************************************************************/ ! 86: /* this function maps the desired read function into the system-defined */ ! 87: /* reading functions after testing for a legal port. */ ! 88: lispval ! 89: r(op) ! 90: int op; ! 91: { ! 92: register char c; register lispval result; ! 93: int orlevel; extern int rlevel; ! 94: FILE *ttemp; ! 95: struct nament *oldbnp = bnp; ! 96: snpand(2); ! 97: ! 98: switch(np-lbot) { ! 99: case 0: ! 100: protect(nil); ! 101: case 1: ! 102: protect(nil); ! 103: case 2: break; ! 104: default: ! 105: argerr("read or ratom or readc"); ! 106: } ! 107: result = Vreadtable->a.clb; ! 108: chkrtab(result); ! 109: orlevel = rlevel; ! 110: rlevel = 0; ! 111: ttemp = okport(Vpiport->a.clb,stdin); ! 112: ttemp = okport(lbot->val,ttemp); ! 113: /*printf("entering switch\n");*/ ! 114: fflush(stdout); /* flush any pending characters */ ! 115: ! 116: switch (op) ! 117: { ! 118: case EADC: rlevel = orlevel; ! 119: switch (ctable[c = getc(ttemp) & 0177] & 0377) ! 120: { ! 121: case VEOF: ! 122: return(lbot[1].val); ! 123: default: ! 124: strbuf[0] = hash = c; ! 125: strbuf[1] = 0; ! 126: atmlen = 2; ! 127: return((lispval)getatom()); ! 128: } ! 129: case ATOM: rlevel = orlevel; ! 130: result = (ratomr(ttemp)); ! 131: goto out; ! 132: ! 133: case EAD: PUSHDOWN(Vpiport,P(ttemp)); /* rebind Vpiport */ ! 134: result = readr(ttemp); ! 135: out: if(result==eofa) ! 136: { ! 137: if(sigintcnt > 0) sigcall(SIGINT); ! 138: result = lbot[1].val; ! 139: } ! 140: rlevel = orlevel; ! 141: popnames(oldbnp); /* unwind bindings */ ! 142: return(result); ! 143: } ! 144: } ! 145: ! 146: /* Lload *****************************************************************/ ! 147: /* Reads in and executes forms from the specified file. This should */ ! 148: /* really be an nlambda taking multiple arguments, but the error */ ! 149: /* handling gets funny in that case (one file out of several not */ ! 150: /* openable, for instance). */ ! 151: lispval ! 152: Lload() ! 153: { ! 154: register FILE *port; ! 155: register char *p, *ttemp; register lispval vtemp; ! 156: register struct argent *lbot, *np; ! 157: struct nament *oldbnp = bnp; ! 158: int orlevel,typ; ! 159: char longname[100]; ! 160: char *shortname, *end2; ! 161: ! 162: chkarg(1,"load"); ! 163: if((typ = TYPE(lbot->val)) == ATOM) ! 164: ttemp = lbot->val->a.pname ; /* ttemp will point to name */ ! 165: else if(typ == STRNG) ! 166: ttemp = (char *) lbot->val; ! 167: else ! 168: return(error("FILENAME MUST BE ATOMIC",FALSE)); ! 169: strcpy(longname,"/usr/lib/lisp/" ); ! 170: for(p = longname; *p; p++); ! 171: shortname = p; ! 172: strcpy(p,ttemp); ! 173: for(; *p; p++); ! 174: end2 = p; ! 175: strcpy(p,".l"); ! 176: if ((port = fopen(shortname,"r")) == NULL && ! 177: (port = fopen(longname, "r")) == NULL) { ! 178: *end2 = 0; ! 179: if ((port = fopen(shortname,"r")) == NULL && ! 180: (port = fopen(longname, "r")) == NULL) ! 181: errorh(Vermisc,"Can't open file: ", ! 182: nil,FALSE,0,lbot->val); ! 183: } ! 184: orlevel = rlevel; ! 185: rlevel = 0; ! 186: ! 187: if(ISNIL(copval(gcload,CNIL)) && ! 188: loading->a.clb != tatom && ! 189: ISNIL(copval(gcdis,CNIL))) ! 190: gc(CNIL); /* do a gc if gc will be off */ ! 191: ! 192: /* shallow bind the value of lisp atom piport */ ! 193: /* so readmacros will work */ ! 194: PUSHDOWN(Vpiport,P(port)); ! 195: PUSHDOWN(loading,tatom); /* set indication of loading status */ ! 196: ! 197: while ((vtemp = readr(port)) != eofa) { ! 198: eval(vtemp); ! 199: } ! 200: popnames(oldbnp); /* unbind piport, loading */ ! 201: ! 202: rlevel = orlevel; ! 203: fclose(port); ! 204: return(nil); ! 205: } ! 206: ! 207: /* concat ************************************************** ! 208: - ! 209: - use: (concat arg1 arg2 ... ) ! 210: - ! 211: - concatenates the print names of all of its arguments. ! 212: - the arguments may be atoms, integers or real numbers. ! 213: - ! 214: - *********************************************************/ ! 215: lispval ! 216: Iconcat(unintern) ! 217: { ! 218: register struct argent *temnp; ! 219: register int atmlen; /* Passt auf! atmlen in the external ! 220: sense calculated by newstr */ ! 221: int i; ! 222: lispval cur; ! 223: char lstrbf[200]; /* local string buffer needed if sdot seen */ ! 224: snpand(2); ! 225: ! 226: atmlen = 0 ; ! 227: strbuf[0] = NULL_CHAR ; ! 228: ! 229: /* loop for each argument */ ! 230: for(temnp = lbot + AD ; temnp < np ; temnp++) ! 231: { ! 232: cur = temnp->val; ! 233: loop: switch(TYPE(cur)) ! 234: { ! 235: case ATOM: ! 236: strcpy(&strbuf[atmlen], ((struct atom *) cur) -> pname) ; ! 237: break; ! 238: ! 239: case STRNG: ! 240: strcpy(&strbuf[atmlen], cur); ! 241: break; ! 242: ! 243: case INT: ! 244: sprintf(&strbuf[atmlen],"%d",cur->i); ! 245: break; ! 246: ! 247: case DOUB: ! 248: sprintf(&strbuf[atmlen],"%f",cur->f); ! 249: break; ! 250: ! 251: case SDOT: ! 252: if(atmlen > 200) error("concat: string buffer overflow",FALSE); ! 253: strcpy(lstrbf,strbuf); /* save around explode */ ! 254: lbot = np; ! 255: protect(cur); /* must explode */ ! 256: cur= Lexplda(); ! 257: np = lbot; ! 258: strcpy(strbuf,lstrbf); ! 259: for( ; cur != nil ; cur = cur->d.cdr) ! 260: strbuf[atmlen++] = cur->d.car->a.pname[0]; ! 261: strbuf[atmlen] = '\0'; ! 262: break; ! 263: ! 264: default: ! 265: cur = error("Non atom or number to concat",TRUE); ! 266: goto loop; /* if returns value, try it */ ! 267: } ! 268: atmlen = strlen(strbuf); ! 269: ! 270: } ! 271: ! 272: if(unintern) ! 273: return( (lispval) newatom()); ! 274: else ! 275: return( (lispval) getatom()) ; ! 276: } ! 277: lispval ! 278: Lconcat(){ ! 279: return(Iconcat(FALSE)); ! 280: } ! 281: lispval ! 282: Luconcat(){ ! 283: return(Iconcat(TRUE)); ! 284: } ! 285: ! 286: lispval ! 287: Lputprop() ! 288: { ! 289: register struct argent *argp = lbot; ! 290: lispval Iputprop(); ! 291: snpand(1); ! 292: chkarg(3,"putprop"); ! 293: return(Iputprop(argp->val,argp[1].val,argp[2].val)); ! 294: } ! 295: ! 296: lispval ! 297: Iputprop(atm,prop,ind) ! 298: register lispval prop, ind, atm; ! 299: { ! 300: register lispval pptr; ! 301: lispval *tack; /* place to begin property list */ ! 302: lispval errorh(); ! 303: top: ! 304: switch (TYPE(atm)) { ! 305: case ATOM: ! 306: if(atm == nil) tack = &nilplist; ! 307: else tack = &(atm->a.plist); ! 308: break; ! 309: case DTPR: ! 310: for (pptr = atm->d.cdr ; pptr != nil ; pptr = pptr->d.cdr->d.cdr) ! 311: if(TYPE(pptr) != DTPR || TYPE(pptr->d.cdr) != DTPR) break; ! 312: if(pptr != nil) ! 313: { atm = errorh(Vermisc, ! 314: "putprop: bad disembodied property list", ! 315: nil,TRUE,0,atm); ! 316: goto top; ! 317: } ! 318: tack = (lispval *) &(atm->d.cdr); ! 319: break; ! 320: default: ! 321: errorh(Vermisc,"putprop: Bad first argument: ",nil,FALSE,0,atm); ! 322: } ! 323: pptr = *tack; /* start of property list */ ! 324: findit: ! 325: for (pptr = *tack ; pptr != nil ; pptr = pptr->d.cdr->d.cdr) ! 326: if (pptr->d.car == ind) { ! 327: (pptr->d.cdr)->d.car = prop; ! 328: return(prop); ! 329: } ! 330: else tack = &(pptr->d.cdr->d.cdr) ; ! 331: *tack = pptr = newdot(); ! 332: pptr->d.car = ind; ! 333: pptr = pptr->d.cdr = (lispval) newdot(); ! 334: pptr->d.car = prop; ! 335: return(prop); ! 336: } ! 337: ! 338: /* get from property list ! 339: * there are three routines to accomplish this ! 340: * Lget - lisp callable, the first arg can be a symbol or a disembodied ! 341: * property list. In the latter case we check to make sure it ! 342: * is a real one (as best we can). ! 343: * Iget - internal routine, the first arg must be a symbol, no disembodied ! 344: * plists allowed ! 345: * Igetplist - internal routine, the first arg is the plist to search. ! 346: */ ! 347: lispval ! 348: Lget() ! 349: { ! 350: register lispval ind, atm; ! 351: register lispval dum1, dum2; ! 352: lispval Igetplist(); ! 353: snpand(2); ! 354: ! 355: chkarg(2,"get"); ! 356: ind = lbot[1].val; ! 357: atm = lbot[0].val; ! 358: top: ! 359: switch(TYPE(atm)) { ! 360: case ATOM: ! 361: if(atm==nil) atm = nilplist; ! 362: else atm = atm->a.plist; ! 363: break; ! 364: ! 365: case DTPR: ! 366: for (dum1 = atm->d.cdr; dum1 != nil; dum1 = dum1->d.cdr->d.cdr) ! 367: if((TYPE(dum1) != DTPR) || ! 368: (TYPE(dum1->d.cdr) != DTPR)) break; /* bad prop list */ ! 369: if(dum1 != nil) ! 370: { atm = errorh(Vermisc, ! 371: "get: bad disembodied property list", ! 372: nil,TRUE,0,atm); ! 373: goto top; ! 374: } ! 375: atm = atm->d.cdr; ! 376: break; ! 377: default: ! 378: /* remove since maclisp doesnt treat ! 379: this as an error, ugh ! 380: return(errorh(Vermisc,"get: bad first argument: ", ! 381: nil,FALSE,0,atm)); ! 382: */ ! 383: return(nil); ! 384: } ! 385: ! 386: while (atm != nil) ! 387: { ! 388: if (atm->d.car == ind) ! 389: return ((atm->d.cdr)->d.car); ! 390: atm = (atm->d.cdr)->d.cdr; ! 391: } ! 392: return(nil); ! 393: } ! 394: /* ! 395: * Iget - the first arg must be a symbol. ! 396: */ ! 397: ! 398: lispval ! 399: Iget(atm,ind) ! 400: register lispval atm, ind; ! 401: { ! 402: lispval Igetplist(); ! 403: ! 404: if(atm==nil) ! 405: atm = nilplist; ! 406: else ! 407: atm = atm->a.plist; ! 408: return(Igetplist(atm,ind)); ! 409: } ! 410: ! 411: /* ! 412: * Igetplist ! 413: * pptr is a plist ! 414: * ind is the indicator ! 415: */ ! 416: ! 417: lispval ! 418: Igetplist(pptr,ind) ! 419: register lispval pptr,ind; ! 420: { ! 421: while (pptr != nil) ! 422: { ! 423: if (pptr->d.car == ind) ! 424: return ((pptr->d.cdr)->d.car); ! 425: pptr = (pptr->d.cdr)->d.cdr; ! 426: } ! 427: return(nil); ! 428: } ! 429: lispval ! 430: Lgetd() ! 431: { ! 432: register lispval typ; ! 433: snpand(1); ! 434: ! 435: chkarg(1,"getd"); ! 436: typ = lbot->val; ! 437: if (TYPE(typ) != ATOM) ! 438: errorh(Vermisc, ! 439: "getd: ONLY ATOMS HAVE FUNCTION DEFINITIONS", ! 440: nil, ! 441: FALSE, ! 442: 0, ! 443: typ); ! 444: return(typ->a.fnbnd); ! 445: } ! 446: lispval ! 447: Lputd() ! 448: { ! 449: register lispval atom, list; ! 450: register lispval dum1, dum2; ! 451: register struct argent *lbot, *np; ! 452: snpand(2); ! 453: ! 454: chkarg(2,"putd"); ! 455: list = lbot[1].val; ! 456: atom = lbot->val; ! 457: if (TYPE(atom) != ATOM) error("ONLY ATOMS HAVE FUNCTION DEFINITIONS",FALSE); ! 458: atom->a.fnbnd = list; ! 459: return(list); ! 460: } ! 461: ! 462: /* =========================================================== ! 463: - mapping functions which return a list of the answers ! 464: - mapcar applies the given function to successive elements ! 465: - maplist applies the given function to successive sublists ! 466: - ===========================================================*/ ! 467: ! 468: lispval ! 469: Lmapcrx(maptyp,join) ! 470: int maptyp; /* 0 = mapcar, 1 = maplist */ ! 471: int join; /* 0 = the above, 1 = s/car/can/ */ ! 472: { ! 473: register struct argent *namptr; ! 474: register index; ! 475: register lispval temp; ! 476: register lispval current; ! 477: register struct argent *lbot; ! 478: register struct argent *np; ! 479: ! 480: struct argent *first, *last; ! 481: int count; ! 482: lispval lists[25], result; ! 483: ! 484: namptr = lbot + 1; ! 485: count = np - namptr; ! 486: if (count <= 0) return (nil); ! 487: /*oldlbot = lbot; /* lbot saved by virtue of entry mask */ ! 488: result = current = (lispval) np; ! 489: protect(nil); /* set up space for returned list */ ! 490: protect(lbot->val); /*copy funarg for call to funcall */ ! 491: lbot = np -1; ! 492: first = np; ! 493: last = np += count; ! 494: for(index = 0; index < count; index++) { ! 495: temp =(namptr++)->val; ! 496: if (TYPE (temp ) != DTPR && temp!=nil) ! 497: error ( "bad list argument to map",FALSE); ! 498: lists[index] = temp; ! 499: } ! 500: for(;;) { ! 501: for(namptr=first,index=0; index<count; index++) { ! 502: temp = lists[index]; ! 503: if(temp==nil) goto done; ! 504: ! 505: if(maptyp==0) (namptr++)->val = temp->d.car; ! 506: else (namptr++)->val = temp; ! 507: ! 508: lists[index] = temp->d.cdr; ! 509: } ! 510: if (join == 0) { ! 511: current->l = newdot(); ! 512: current->l->d.car = Lfuncal(); ! 513: current = (lispval) ¤t->l->d.cdr; ! 514: } else { ! 515: current->l = Lfuncal(); ! 516: if ( TYPE ( current -> l) != DTPR && current->l != nil) ! 517: error("bad type returned from funcall inside map",FALSE); ! 518: else while ( current -> l != nil ) ! 519: current = (lispval) & (current ->l ->d.cdr); ! 520: } ! 521: np = last; ! 522: } ! 523: done: if (join == 0)current->l = nil; ! 524: /*lbot = oldlbot;*/ ! 525: return(result->l); ! 526: } ! 527: ! 528: /* ============================ ! 529: - ! 530: - Lmapcar ! 531: - =============================*/ ! 532: ! 533: lispval ! 534: Lmapcar() ! 535: { ! 536: snpand(0); ! 537: return(Lmapcrx(0,0)); } /* call general routine */ ! 538: ! 539: ! 540: /* ============================ ! 541: - ! 542: - ! 543: - Lmaplist ! 544: - ==============================*/ ! 545: ! 546: lispval ! 547: Lmaplist() ! 548: { ! 549: snpand(0); ! 550: return(Lmapcrx(1,0)); } /* call general routine */ ! 551: ! 552: ! 553: /* ================================================ ! 554: - mapping functions which return the value of the last function application. ! 555: - mapc and map ! 556: - ===================================================*/ ! 557: ! 558: lispval ! 559: Lmapcx(maptyp) ! 560: int maptyp; /* 0= mapc , 1= map */ ! 561: { ! 562: register struct argent *namptr; ! 563: register index; ! 564: register lispval temp; ! 565: register lispval result; ! 566: register struct argent *lbot; ! 567: register struct argent *np; ! 568: ! 569: int count; ! 570: struct argent *first; ! 571: lispval lists[25], errorh(); ! 572: ! 573: namptr = lbot + 1; ! 574: count = np - namptr; ! 575: if(count <= 0) return(nil); ! 576: result = lbot[1].val; /*This is what macsyma wants so ... */ ! 577: /*copy funarg for call to funcall */ ! 578: lbot = np; protect((namptr - 1)->val); ! 579: first = np; np += count; ! 580: ! 581: for(index = 0; index < count; index++) { ! 582: temp = (namptr++)->val; ! 583: while(temp!=nil && TYPE(temp)!=DTPR) ! 584: temp = errorh(Vermisc,"Inappropriate list argument to mapc",nil,TRUE,0,temp); ! 585: lists[index] = temp; ! 586: } ! 587: for(;;) { ! 588: for(namptr=first,index=0; index<count; index++) { ! 589: temp = lists[index]; ! 590: if(temp==nil) ! 591: goto done; ! 592: if(maptyp==0) ! 593: (namptr++)->val = temp->d.car; ! 594: else ! 595: (namptr++)->val = temp; ! 596: lists[index] = temp->d.cdr; ! 597: } ! 598: Lfuncal(); ! 599: } ! 600: done: ! 601: return(result); ! 602: } ! 603: ! 604: ! 605: /* ================================== ! 606: - ! 607: - mapc map the car of the lists ! 608: - ! 609: - ==================================*/ ! 610: ! 611: lispval ! 612: Lmapc() ! 613: { return( Lmapcx(0) ); } ! 614: ! 615: ! 616: /* ================================= ! 617: - ! 618: - map map the cdr of the lists ! 619: - ! 620: - ===================================*/ ! 621: ! 622: lispval ! 623: Lmap() ! 624: { return( Lmapcx(1) ); } ! 625: ! 626: ! 627: lispval ! 628: Lmapcan() ! 629: { ! 630: lispval Lmapcrx(); ! 631: ! 632: return ( Lmapcrx ( 0,1 ) ); ! 633: } ! 634: ! 635: lispval ! 636: Lmapcon() ! 637: { ! 638: lispval Lmapcrx(); ! 639: ! 640: return ( Lmapcrx ( 1,1 ) ); ! 641: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.