|
|
1.1 root 1: #ifndef lint
2: static char *rcsid =
3: "$Header: /na/franz/franz/RCS/io.c,v 1.8 83/08/06 08:38:42 jkf Exp $";
4: #endif
5:
6: /* -[Fri Aug 5 12:45:22 1983 by jkf]-
7: * io.c $Locker: $
8: * input output functions
9: *
10: * (c) copyright 1982, Regents of the University of California
11: */
12:
13: #include "global.h"
14: #include <ctype.h>
15: #include "chars.h"
16: #include "chkrtab.h"
17:
18: struct readtable {
19: unsigned char ctable[132];
20: } initread = {
21: /* ^@ nul ^A soh ^B stx ^C etx ^D eot ^E eng ^F ack ^G bel */
22: VERR, VERR, VERR, VERR, VERR, VERR, VERR, VERR,
23: /* ^H bs ^I ht ^J nl ^K vt ^L np ^M cr ^N so ^O si */
24: VCHAR, VSEP, VSEP, VSEP, VSEP, VSEP, VERR, VERR,
25: /* ^P dle ^Q dc1 ^R dc2 ^S dc3 ^T dc4 ^U nak ^V syn ^W etb */
26: VERR, VERR, VERR, VERR, VERR, VERR, VERR, VERR,
27: /* ^X can ^Y em ^Z sub ^[ esc ^\ fs ^] gs ^^ rs ^_ us */
28: VERR, VERR, VERR, VSEP, VERR, VERR, VERR, VERR,
29: /* sp ! " # $ % & ' */
30: VSEP, VCHAR, VSD, VCHAR, VCHAR, VCHAR, VCHAR, VSQ,
31: /* ( ) * + , - . / */
32: VLPARA, VRPARA, VCHAR, VSIGN, VCHAR, VSIGN, VPERD, VCHAR,
33: /* 0 1 2 3 4 5 6 7 */
34: VNUM, VNUM, VNUM, VNUM, VNUM, VNUM, VNUM, VNUM,
35: /* 8 9 : ; < = > ? */
36: VNUM, VNUM, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR,
37: /* @ A B C D E F G */
38: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR,
39: /* H I J K L M N O */
40: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR,
41: /* P Q R S T U V W */
42: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR,
43: /* X Y Z [ \ ] ^ _ */
44: VCHAR, VCHAR, VCHAR, VLBRCK, VESC, VRBRCK, VCHAR, VCHAR,
45: /* ` a b c d e f g */
46: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR,
47: /* h i j k l m n o */
48: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR,
49: /* p q r s t u v w */
50: VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR, VCHAR,
51: /* x y z { | } ~ del */
52: VCHAR, VCHAR, VCHAR, VCHAR, VDQ, VCHAR, VCHAR, VERR,
53: /* unused Xsdc Xesc Xdqc */
54: 0, '"', '\\', '|'
55: };
56:
57: extern unsigned char *ctable;
58: lispval atomval; /* external varaible containing atom returned
59: from internal atom reading routine */
60: lispval readrx(); lispval readr(); lispval readry();
61: char *atomtoolong();
62: int keywait;
63: int plevel = -1; /* contains maximum list recursion count */
64: int plength = -1; /* maximum number of list elements printed */
65: static int dbqflag;
66: static int mantisfl = 0;
67: extern int uctolc;
68: extern lispval lastrtab; /* external variable designating current reader
69: table */
70: static char baddot1[]=
71: "Bad reader construction: (. <something>)\nShould be (nil . <something>)\n";
72: static char baddot2[]=
73: "Bad reader construction: (<something> .)\n\
74: Should be (<something> . <something>), assumed to be (<something>)";
75: static char baddot3[]=
76: "Bad reader construction: (<something> . <something> not followed by )";
77:
78: /* readr ****************************************************************/
79: /* returns a s-expression read in from the port specified as the first */
80: /* argument. Handles superbrackets, reader macros. */
81: lispval
82: readr(useport)
83: FILE *useport;
84: {
85: register lispval handy = Vreadtable->a.clb;
86:
87: chkrtab(handy);
88: rbktf = FALSE;
89: rdrport = (FILE *) useport;
90: if(useport==stdin)
91: keywait = TRUE;
92: handy = readrx(Iratom());
93: if(useport==stdin)
94: keywait = FALSE;
95: return(handy);
96:
97: }
98:
99:
100: /* readrx **************************************************************/
101: /* returns a s-expression beginning with the syntax code of an atom */
102: /* passed in the first */
103: /* argument. Does the actual work for readr, including list, dotted */
104: /* pair, and quoted atom detection */
105: lispval
106: readrx(code)
107: register int code;
108: {
109: register lispval work;
110: register lispval *current;
111: register struct argent *result;
112: int inlbkt = FALSE;
113: lispval errorh();
114: Savestack(4); /* ???not necessary because np explicitly restored if
115: changed */
116:
117: top:
118: switch(code)
119: {
120: case TLBKT:
121: inlbkt = TRUE;
122: case TLPARA:
123: result = np;
124: current = (lispval *)np;
125: np++->val = nil; /*protect(nil);*/
126: for(EVER) {
127: switch(code = Iratom())
128: {
129: case TRPARA:
130: if(rbktf && inlbkt)
131: rbktf = FALSE;
132: goto out;
133: default:
134: atomval = readrx(code);
135: case TSCA:
136: np++->val=atomval;
137: *current = work = newdot();
138: work->d.car = atomval;
139: np--;
140: current = (lispval *) &(work->d.cdr);
141: break;
142: case TINF:
143: imacrox(result->val,TRUE);
144: work = atomval;
145: result->val = work->d.car;
146: current = (lispval *) & (result->val);
147: goto mcom;
148: case TSPL:
149: macrox(); /* input and output in atomval */
150: *current = atomval;
151: mcom:
152: while(*current!=nil) {
153: if(TYPE(*current)!=DTPR)
154: errorh1(Vermisc,"Non-list returned from splicing macro",nil,FALSE,7,*current);
155: current=(lispval *)&((*current)->d.cdr);
156: }
157: break;
158: case TPERD:
159: if(result->val==nil) {
160: work = result->val=newdot();
161: current = (lispval *) &(work->d.cdr);
162: fprintf(stderr,baddot1);
163: }
164: code = Iratom();
165: if(code==TRPARA) {
166: result->val = errorh1(Vermisc,baddot2,nil,TRUE,58,result->val);
167: goto out;
168: }
169: *current = readrx(code);
170: /* there is the possibility that the expression
171: following the dot is terminated with a "]"
172: and thus needs no closing lparens to follow
173: */
174: if(!rbktf && ((code = Iratom()))!=TRPARA) {
175: errorh2(Vermisc,baddot3,nil,TRUE,59,result->val,atomval);
176: }
177: if(rbktf && inlbkt)
178: rbktf = FALSE;
179: goto out;
180: case TEOF:
181: errorh1(Vermisc,"Premature end of file after ",
182: nil,FALSE,0,result->val);
183: }
184: if(rbktf) {
185: if(inlbkt)
186: rbktf = FALSE;
187: goto out;
188: }
189: }
190: case TSCA:
191: Restorestack();
192: return(atomval);
193: case TEOF:
194: Restorestack();
195: return(eofa);
196: case TMAC:
197: macrox();
198: Restorestack();
199: return(atomval);
200: case TINF:
201: imacrox(nil,FALSE);
202: work = atomval;
203: if(work==nil) { code = Iratom(); goto top;}
204: work = work->d.car;
205: Restorestack();
206: if(work->d.cdr==nil)
207: return(work->d.car);
208: else
209: return(work);
210: case TSPL:
211: macrox();
212: if((work = atomval)!=nil) {
213: if(TYPE(work)==DTPR && work->d.cdr==nil) {
214: Restorestack();
215: return(work->d.car);
216: } else {
217: errorh1(Vermisc,
218: "Improper value returned from splicing macro at top-level",nil,FALSE,9,work);
219: }
220: }
221: code = Iratom();
222: goto top;
223: /* return(readrx(Iratom())); */
224: case TSQ:
225: result = np;
226: protect(newdot());
227: (work = result->val)->d.car = quota;
228: work = work->d.cdr = newdot();
229: work->d.car = readrx(Iratom());
230: goto out;
231:
232: case TRPARA:
233: Restorestack();
234: return(errorh(Vermisc,
235: "read: read a right paren when expecting an s-expression",
236: nil,FALSE,0));
237: case TPERD:
238: Restorestack();
239: return(errorh(Vermisc,
240: "read: read a period when expecting an s-expression",
241: nil,FALSE,0));
242:
243: /* should never get here, we should have covered all cases above */
244: default:
245: Restorestack();
246: return(errorh1(Vermisc,"Readlist error, code ",nil,FALSE,0,inewint((long)code)));
247: }
248: out:
249: work = result->val;
250: np = result;
251: Restorestack();
252: return(work);
253: }
254: macrox()
255: {
256: FILE *svport;
257: lispval handy, Lapply();
258:
259: Savestack(0);
260: svport = rdrport; /* save from possible changing */
261: lbot = np;
262: protect(handy=Iget(atomval,lastrtab));
263: if (handy == nil)
264: {
265: errorh1(Vermisc,"read: can't find the character macro for ",nil,
266: FALSE,0,atomval);
267: }
268: protect(nil);
269: atomval = Lapply();
270: chkrtab(Vreadtable->a.clb); /* the macro could have changed
271: the readtable
272: */
273: rdrport = svport; /* restore old value */
274: Restorestack();
275: return;
276: }
277: imacrox(current,inlist)
278: register lispval current;
279: {
280: FILE *svport;
281: register lispval work;
282: lispval Lapply(), handy;
283:
284: Savestack(2);
285: svport = rdrport; /* save from possible changing */
286: if(inlist)
287: {
288: protect(handy = newdot());
289: handy->d.car = current;
290: for(work = handy->d.car; (TYPE(work->d.cdr))==DTPR; )
291: work = work->d.cdr;
292: handy->d.cdr = work;
293: }
294: else handy = current;
295:
296: lbot = np;
297: protect(Iget(atomval,lastrtab));
298: protect(handy);
299: atomval = Lfuncal();
300: chkrtab(Vreadtable->a.clb); /* the macro could have changed
301: the readtable
302: */
303: rdrport = svport; /* restore old value */
304: Restorestack();
305: return;
306: }
307:
308:
309:
310: /* ratomr ***************************************************************/
311: /* this routine returns a pointer to an atom read in from the port given*/
312: /* by the first argument */
313: lispval
314: ratomr(useport)
315: register FILE *useport;
316: {
317: rdrport = useport;
318: switch(Iratom())
319: {
320: case TEOF:
321: return(eofa);
322: case TSQ:
323: case TRPARA:
324: case TLPARA:
325: case TLBKT:
326: case TPERD:
327: strbuf[1]=0;
328: return(getatom(TRUE));
329: default:
330: return(atomval);
331: }
332: }
333:
334: #define push(); *name++ = c; if(name>=endstrb) name = atomtoolong(name);
335: #define next() (((cc=getc(useport))!=EOF)?(stats = ctable[c = cc &0177]):\
336: ((c=0),(saweof = 1),(stats = SEPMASK)))
337: Iratom()
338: {
339: register FILE *useport = rdrport;
340: register char c, marker, *name;
341: extern lispval finatom(), calcnum(), getnum();
342: int code, cc;
343: int strflag = FALSE;
344:
345: name = strbuf;
346:
347: again: cc = getc(useport);
348: if(cc==EOF)
349: {
350: clearerr(useport);
351: return(TEOF);
352: }
353: c = cc & 0177;
354: *name = c;
355:
356: switch(synclass(ctable[c])) {
357:
358: default: goto again;
359:
360: case synclass(VNUM):
361:
362: case synclass(VSIGN): *name++ = c;
363: atomval = (getnum(name));
364: return(TSCA);
365:
366: case synclass(VESC):
367: dbqflag = TRUE;
368: *name++ = getc(useport) & 0177;
369: atomval = (finatom(name));
370: return(TSCA);
371:
372: case synclass(VCHAR):
373: if(uctolc && isupper(c)) c = tolower(c);
374: *name++ = c;
375: atomval = (finatom(name));
376: return(TSCA);
377:
378: case synclass(VLPARA): return(TLPARA);
379:
380: case synclass(VRPARA): return(TRPARA);
381:
382: case synclass(VPERD): marker = peekc(useport) & 0177;
383: if(synclass(VNUM)!=synclass(ctable[marker]))
384: { if(SEPMASK & ctable[marker])
385: return(TPERD);
386: else { *name++ = c; /* this period begins an atm */
387: atomval = finatom(name);
388: return(TSCA);
389: }
390: }
391: *name++ = '.';
392: mantisfl = 1;
393: atomval = (getnum(name));
394: return(TSCA);
395:
396: case synclass(VLBRCK): return(TLBKT);
397:
398: case synclass(VRBRCK): rbktf = TRUE;
399: return(TRPARA);
400:
401: case synclass(VSQ): return(TSQ);
402:
403: case synclass(VSD): strflag = TRUE;
404: case synclass(VDQ): name = strbuf;
405: marker = c;
406: while ((c = getc(useport)) != marker) {
407:
408: if(synclass(VESC)==synclass(ctable[c]))
409: c = getc(useport) & 0177;
410: push();
411: if (feof(useport)) {
412: clearerr(useport);
413: error("EOF encountered while reading atom", FALSE);
414: }
415: }
416: *name = NULL_CHAR;
417: if(strflag)
418: atomval = (lispval) pinewstr(strbuf);
419: else
420: atomval = (getatom(TRUE));
421: return(TSCA);
422:
423: case synclass(VERR): if (c == '\0')
424: {
425: fprintf(stderr,"[read: null read and ignored]\n");
426: goto again; /* null pname */
427: }
428: fprintf(stderr,"%c (%o): ",c,(int) c);
429: error("ILLEGAL CHARACTER IN ATOM",TRUE);
430:
431: case synclass(VSINF):
432: code = TINF;
433: goto same;
434: case synclass(VSSPL):
435: code = TSPL;
436: goto same;
437: case synclass(VSMAC):
438: code = TMAC;
439: same:
440: marker = peekc(rdrport);
441: if(! (SEPMASK & ctable[marker]) ) {
442: *name++ = c; /* this is not a macro */
443: atomval = (finatom(name));
444: return(TSCA);
445: }
446: goto simple;
447: case synclass(VINF):
448: code = TINF;
449: goto simple;
450: case synclass(VSCA):
451: code = TSCA;
452: goto simple;
453: case synclass(VSPL):
454: code = TSPL;
455: goto simple;
456: case synclass(VMAC):
457: code = TMAC;
458: simple:
459: strbuf[0] = c;
460: strbuf[1] = 0;
461: atomval = (getatom(TRUE));
462: return(code);
463: }
464: }
465:
466: lispval
467: getnum(name)
468: register char *name;
469: {
470: unsigned char c;
471: register lispval result;
472: register FILE *useport=rdrport;
473: unsigned char stats;
474: int sawdigit = 0, saweof = 0,cc;
475: char *exploc = (char *) 0;
476: double realno;
477: extern lispval finatom(), calcnum(), newdoub(), dopow();
478:
479: if(mantisfl) {
480: mantisfl = 0;
481: next();
482: goto mantissa;
483: }
484: if(VNUM==ctable[*(unsigned char*)(name-1)]) sawdigit = 1;
485: while(VNUM==next()) {
486: push(); /* recognize [0-9]*, in "ex" parlance */
487: sawdigit = 1;
488: }
489: if(c=='.') {
490: push(); /* continue */
491: } else if(stats & SEPMASK) {
492: if(!saweof)ungetc((int)c,useport);
493: return(calcnum(strbuf,name,(int)ibase->a.clb->i));
494: } else if(c=='^') {
495: push();
496: return(dopow(name,(int)ibase->a.clb->i));
497: } else if(c=='_') {
498: if(sawdigit) /* _ must be preceeded by a digit */
499: {
500: push();
501: return(dopow(name,2));
502: }
503: else goto backout;
504: } else if(c=='e' || c=='E' || c=='d' ||c=='D') {
505: if(sawdigit) goto expt;
506: else goto backout;
507: } else {
508: backout:
509: ungetc((int)c,useport);
510: return(finatom(name));
511: }
512: /* at this point we have [0-9]*\. , which might
513: be a decimal int or the leading part of a
514: float */
515: if(next()!=VNUM) {
516: if(c=='e' || c=='E' || c=='d' ||c=='D')
517: goto expt;
518: else if(c=='^') {
519: push();
520: return(dopow(name,(int)ibase->a.clb->i));
521: } else if(c=='_') {
522: push();
523: return(dopow(name,2));
524: } else if( stats & SEPMASK) {
525: /* Here we have 1.x where x is not number
526: * but is a separator
527: * Here we have decimal int. NOT FORTRAN!
528: */
529: if(!saweof)ungetc((int)c,useport);
530: return(calcnum(strbuf,name-1,10));
531: }
532: else goto last; /* return a symbol */
533: }
534: mantissa:
535: do {
536: push();
537: } while (VNUM==next());
538:
539: /* Here we have [0-9]*\.[0-9]*
540: * three possibilities:
541: * next character is e,E,d or D in which case we examine
542: * the exponent [then we are faced with a similar
543: * situation to this one: is the character after the
544: * exponent a separator or not]
545: * next character is a separator, in which case we have a
546: * number (without an exponent)
547: * next character is not a separator in which case we have
548: * an atom (whose prefix just happens to look like a
549: * number)
550: */
551: if( (c == 'e') || (c == 'E') || (c == 'd') || (c == 'D')) goto expt;
552:
553: if(stats & SEPMASK) goto verylast; /* a real number */
554: else goto last; /* prefix makes it look like a number, but it isn't */
555:
556: expt:
557: exploc = name; /* remember location of exponent character */
558: push();
559: next();
560: if(c=='+' || c =='-') {
561: push();
562: next();
563: }
564: while (VNUM==stats) {
565: push();
566: next();
567: }
568:
569: /* if a separator follows then we have a number, else just
570: * an atom
571: */
572: if (stats & SEPMASK) goto verylast;
573:
574: last: /* get here when what looks like a number turns out to be an atom */
575: if(!saweof) ungetc((int)c,useport);
576: return(finatom(name));
577:
578: verylast:
579: if(!saweof) ungetc((int)c,useport);
580: /* scanf requires that the exponent be 'e' */
581: if(exploc != (char *) 0 ) *exploc = 'e';
582: *name=0;
583: sscanf(strbuf,"%F",&realno);
584: (result = newdoub())->r = realno;
585: return(result);
586: }
587:
588: lispval
589: dopow(part2,base)
590: register char *part2;
591: {
592: register char *name = part2;
593: register FILE *useport = rdrport;
594: register int power;
595: lispval work;
596: unsigned char stats,c;
597: int cc, saweof = 0;
598: char *end1 = part2 - 1; lispval Ltimes();
599: Savestack(4);
600:
601: while(VNUM==next()) {
602: push();
603: }
604: if(c!='.') {
605: if(!saweof)ungetc((int)c,useport);
606: }
607: if(c!='.' && !(stats & SEPMASK)) {
608: return(finatom(name));
609: }
610: lbot = np;
611: np++->val = inewint(base);
612: /* calculate "mantissa"*/
613: if(*end1=='.')
614: np++->val = calcnum(strbuf,end1-1,10);
615: else
616: np++->val = calcnum(strbuf,end1,(int)ibase->a.clb->i);
617:
618: /* calculate exponent */
619: if(c=='.')
620: power = calcnum(part2,name,10)->i;
621: else
622: power = calcnum(part2,name,(int)ibase->a.clb->i)->i;
623: while(power-- > 0)
624: lbot[1].val = Ltimes();
625: work = lbot[1].val;
626: Restorestack();
627: return(work);
628: }
629:
630:
631: lispval
632: calcnum(strbuf,name,base)
633: register char *name;
634: char *strbuf;
635: {
636: register char *p;
637: register lispval result, temp;
638: int negflag = 0;
639:
640: result = temp = newsdot(); /* initialize sdot cell */
641: protect(temp);
642: p = strbuf;
643: if(*p=='+') p++;
644: else if(*p=='-') {negflag = 1; p++;}
645: *name = 0;
646: if(p>=name) return(getatom(TRUE));
647:
648: for(;p < name; p++)
649: dmlad(temp,(long)base,(long)*p-'0');
650: if(negflag)
651: dmlad(temp,-1L,0L);
652:
653: if(temp->s.CDR==0) {
654: result = inewint(temp->i);
655: pruneb(np[-1].val);
656: }
657: np--;
658: return(result);
659: }
660: lispval
661: finatom(name)
662: register char *name;
663: {
664: register FILE *useport = rdrport;
665: unsigned char c, stats;
666: int cc, saweof = 0;
667:
668: while(!(next()&SEPMASK)) {
669:
670: if(synclass(stats) == synclass(VESC)) {
671: c = getc(useport) & 0177;
672: } else {
673: if(uctolc && isupper(c)) c = tolower(c);
674: }
675: push();
676: }
677: *name = NULL_CHAR;
678: if(!saweof)ungetc((int)c,useport);
679: return(getatom(TRUE));
680: }
681:
682: char *
683: atomtoolong(copyto)
684: char *copyto;
685: {
686: int size;
687: register char *oldp = strbuf;
688: register char *newp;
689: lispval nveci();
690: /*
691: * the string buffer contains an string which is too long
692: * so we get a bigger buffer.
693: */
694:
695: size = (endstrb - strbuf)*4 + 28 ;
696: newp = (char *) nveci(size);
697: atom_buffer = (lispval) newp;
698: strbuf = newp;
699: endstrb = newp + size - 1;
700: while(oldp < copyto) *newp++ = *oldp++;
701: return(newp);
702: }
703:
704: /* printr ***************************************************************/
705: /* prints the first argument onto the port specified by the second */
706:
707: /*
708: * Last modified Mar 21, 1980 for hunks
709: */
710:
711: printr(a,useport)
712: register lispval a;
713: register FILE *useport;
714: {
715: register hsize, i;
716: char strflag = 0;
717: char Idqc = 0;
718: char *chstr;
719: int curplength = plength;
720: int quot;
721: lispval Istsrch();
722: lispval debugmode;
723:
724: val_loop:
725: if(! VALID(a)) {
726: debugmode = Istsrch(matom("debugging"))->d.cdr->d.cdr->d.cdr;
727: if(debugmode != nil) {
728: printf("<printr:bad lisp data: 0x%x>\n",a);
729: error("Bad lisp data encountered by printr", FALSE);
730: } else {
731: a = badst;
732: printf("<printr:bad lisp data: 0x%x>",a);
733: return;
734: }
735: }
736:
737: switch (TYPE(a))
738: {
739:
740:
741: case UNBO: fputs("<UNBOUND>",useport);
742: break;
743:
744: case VALUE: fputs("(ptr to)",useport);
745: a = a->l;
746: goto val_loop;
747:
748: case INT: fprintf(useport,"%d",a->i);
749: break;
750:
751: case DOUB: { char buf[64];
752: lfltpr(buf,a->r);
753: fputs(buf,useport);
754: }
755: break;
756:
757: case PORT: { lispval cp;
758: if((cp = ioname[PN(a->p)]) == nil)
759: fputs("%$unopenedport",useport);
760: else fprintf(useport,"%%%s",cp);
761: }
762: break;
763:
764: case HUNK2:
765: case HUNK4:
766: case HUNK8:
767: case HUNK16:
768: case HUNK32:
769: case HUNK64:
770: case HUNK128:
771: if(plevel == 0)
772: {
773: fputs("%",useport);
774: break;
775: }
776: hsize = 2 << HUNKSIZE(a);
777: fputs("{", useport);
778: plevel--;
779: printr(a->h.hunk[0], useport);
780: curplength--;
781: for (i=1; i < hsize; i++)
782: {
783: if (a->h.hunk[i] == hunkfree)
784: break;
785: if (curplength-- == 0)
786: {
787: fputs(" ...",useport);
788: break;
789: }
790: else
791: {
792: fputs(" ", useport);
793: printr(a->h.hunk[i], useport);
794: }
795: }
796: fputs("}", useport);
797: plevel++;
798: break;
799:
800: case VECTOR:
801: chstr = "vector";
802: quot = 4; /* print out # of longwords */
803: goto veccommon;
804:
805: case VECTORI:
806: chstr = "vectori";
807: quot = 1;
808: veccommon:
809: /* print out 'vector' or 'vectori' except in
810: * these circumstances:
811: * property is a symbol, in which case print
812: * the symbol's pname
813: * property is a list with a 'print' property,
814: * in which case it is funcalled to print the
815: * vector
816: */
817: if(a->v.vector[VPropOff] != nil)
818: {
819: if ((i=TYPE(a->v.vector[VPropOff])) == ATOM)
820: {
821: chstr = a->v.vector[VPropOff]->a.pname;
822: }
823: else if ((i == DTPR) && vectorpr(a,useport))
824: {
825: break; /* printed by vectorpr */
826: }
827: else if ((i == DTPR)
828: && (a->v.vector[VPropOff]->d.car != nil)
829: && TYPE(a->v.vector[VPropOff]->d.car)
830: == ATOM)
831: {
832: chstr = a->v.vector[VPropOff]->d.car->a.pname;
833: }
834: }
835: fprintf(useport,"%s[%d]",
836: chstr, a->vl.vectorl[VSizeOff]/quot);
837: break;
838:
839: case ARRAY: fputs("array[",useport);
840: printr(a->ar.length,useport);
841: fputs("]",useport);
842: break;
843:
844: case BCD: fprintf(useport,"#%X-",a->bcd.start);
845: printr(a->bcd.discipline,useport);
846: break;
847:
848: case OTHER: fprintf(useport,"#Other-%X",a);
849: break;
850:
851: case SDOT: pbignum(a,useport);
852: break;
853:
854: case DTPR: if(plevel==0)
855: {
856: fputs("&",useport);
857: break;
858: }
859: plevel--;
860: if(a->d.car==quota && a->d.cdr!=nil
861: && a->d.cdr->d.cdr==nil) {
862: putc('\'',useport);
863: printr(a->d.cdr->d.car,useport);
864: plevel++;
865: break;
866: }
867: putc('(',useport);
868: curplength--;
869: morelist: printr(a->d.car,useport);
870: if ((a = a->d.cdr) != nil)
871: {
872: if(curplength-- == 0)
873: {
874: fputs(" ...",useport);
875: goto out;
876: }
877: putc(' ',useport);
878: if (TYPE(a) == DTPR) goto morelist;
879: fputs(". ",useport);
880: printr(a,useport);
881: }
882: out:
883: fputc(')',useport);
884: plevel++;
885: break;
886:
887: case STRNG: strflag = TRUE;
888: Idqc = Xsdc;
889:
890: case ATOM: {
891: char *front, *temp, first; int clean;
892: temp = front = (strflag ? ((char *) a) : a->a.pname);
893: if(Idqc==0) Idqc = Xdqc;
894:
895: if(Idqc) {
896: clean = first = *temp;
897: first &= 0177;
898: switch(QUTMASK & ctable[first]) {
899: case QWNFRST:
900: case QALWAYS:
901: clean = 0; break;
902: case QWNUNIQ:
903: if(temp[1]==0) clean = 0;
904: }
905: if (first=='-'||first=='+') temp++;
906: if(synclass(ctable[*temp])==VNUM) clean = 0;
907: while (clean && *temp) {
908: if((ctable[*temp]&QUTMASK)==QALWAYS)
909: clean = 0;
910: else if(uctolc && (isupper(*temp)))
911: clean = 0;
912: temp++;
913: }
914: if (clean && !strflag)
915: fputs(front,useport);
916: else {
917: putc(Idqc,useport);
918: for(temp=front;*temp;temp++) {
919: if( *temp==Idqc
920: || (synclass(ctable[*temp])) == CESC)
921: putc(Xesc,useport);
922: putc(*temp,useport);
923: }
924: putc(Idqc,useport);
925: }
926:
927: } else {
928: register char *cp = front;
929: int handy = ctable[*cp & 0177];
930:
931: if(synclass(handy)==CNUM)
932: putc(Xesc,useport);
933: else switch(handy & QUTMASK) {
934: case QWNUNIQ:
935: if(cp[1]==0) putc(Xesc,useport);
936: break;
937: case QWNFRST:
938: case QALWAYS:
939: putc(Xesc,useport);
940: }
941: for(; *cp; cp++) {
942: if((ctable[*cp]& QUTMASK)==QALWAYS)
943: putc(Xesc,useport);
944: putc(*cp,useport);
945: }
946: }
947: }
948: }
949: }
950:
951: /* -- vectorpr
952: * (perhaps) print out vector specially
953: * this is called with a vector whose property list begins with
954: * a list. We search for the 'print' property and if it exists,
955: * funcall the print function with two args: the vector and the port.
956: * We return TRUE iff we funcalled the function, else we return FALSE
957: * to have the standard printing done
958: */
959:
960: vectorpr(vec,port)
961: register lispval vec;
962: FILE *port;
963: {
964: register lispval handy;
965: Savestack(2);
966:
967:
968: for ( handy = vec->v.vector[VPropOff]->d.cdr
969: ; handy != nil; handy = handy->d.cdr->d.cdr)
970: {
971: if (handy->d.car == Vprintsym)
972: {
973: lbot = np;
974: protect(handy->d.cdr->d.car); /* function to call */
975: protect(vec);
976: protect(P(port));
977: Lfuncal();
978: Restorestack();
979: return(TRUE); /* did the call */
980: }
981: }
982: Restorestack();
983: return(FALSE); /* nothing printed */
984: }
985:
986:
987:
988:
989:
990:
991: lfltpr(buf,val) /* lisp floating point printer */
992: char *buf;
993: double val;
994: {
995: register char *cp1; char *sprintf();
996:
997: sprintf(buf,(char *)Vfloatformat->a.clb,val);
998: for(cp1 = buf; *cp1; cp1++)
999: if(*cp1=='.'|| *cp1=='E' || *cp1 == 'e') return;
1000:
1001: /* if we are here, there was no dot, so the number was
1002: an integer. Furthermore, cp1 already points to the
1003: end of the string. */
1004:
1005: *cp1++ = '.';
1006: *cp1++ = '0';
1007: *cp1++ = 0;
1008: }
1009:
1010:
1011: /* dmpport ****************************************************************/
1012: /* outputs buffer indicated by first argument whether full or not */
1013:
1014: dmpport(useport)
1015: FILE *useport;
1016: {
1017: fflush(useport);
1018: }
1019:
1020: /* protect and unprot moved to eval.c (whr) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.