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