|
|
1.1 root 1: static char Sccsid[] = "a2.c @(#)a2.c 1.1 10/1/82 Berkeley ";
2: #include "apl.h"
3: #include "aplmap.h"
4:
5: int chartab[];
6: char *ecvt();
7:
8: ex_print()
9: {
10:
11: if(epr0())
12: putchar('\n');
13: }
14:
15: ex_hprint()
16: {
17:
18: epr0();
19: pop();
20: }
21:
22: epr0()
23: {
24: register struct item *p;
25: register data *dp;
26: register i;
27: int j;
28: int param[4];
29:
30: p = fetch1();
31: if(p->type == DU)
32: return(0);
33: if(p->size == 0)
34: return(1);
35: if(p->type == DA) {
36:
37: /* Use "epr1()" to figure out the maximum field width
38: * required by any of the values to be printed.
39: */
40:
41: for(i=0; i<4; i++)
42: param[i] = 0;
43: dp = p->datap;
44: for(i=0; i<p->size; i++)
45: epr1(*dp++, param);
46: i = param[1] + param[2]; /* size if fp */
47: if(i > thread.digits)
48: i += 100; /* set "e" format flag */
49: if(param[2])
50: i++;
51: if(i > param[0]+5) {
52: i = param[0] + 5; /* size if ep */
53: param[1] = param[0];
54: param[2] = -1;
55: }
56: if(param[3])
57: i++; /* sign */
58: i++; /* leading space */
59: param[0] = i;
60: dp = p->datap;
61: }
62: bidx(p);
63: for(i=1; i<p->size; i++) {
64: if(intflg)
65: break;
66: if(p->type == CH) {
67: j = getdat(p);
68: putchar(j);
69: } else
70: epr2(*dp++, param);
71: for(j=p->rank-2; j>=0; j--)
72: if(i%idx.del[j] == 0)
73: putchar('\n'); /* end of dimension reached */
74: }
75: if(p->type == CH) {
76: j = getdat(p);
77: putchar(j);
78: } else
79: epr2(*dp, param);
80: return(1);
81: }
82:
83: epr1(d, param)
84: data d;
85: int *param;
86: {
87: double f;
88: register a;
89: register char *c;
90: int dp, sg;
91:
92:
93: /* This routine figures out the field with required by the value
94: * "d". It adjusts the four elements of "param" so that they
95: * contain the maximum of their old values or the requirements for
96: * the current data item.
97: *
98: * param[0] = number of significant digits
99: * param[1] = number of digits to left of decimal point
100: * param[2] = number of digits to right of decimal point
101: * param[3] = 0 if positive, 1 if negative
102: */
103:
104: f = d;
105: c = ecvt(f, thread.digits, &dp, &sg);
106: if (f == zero) /* kludge due to change in ecvt */
107: dp = 1;
108: a = thread.digits;
109: while(c[a-1]=='0' && a>1)
110: a--;
111: if(a > param[0]) /* sig digits */
112: param[0] = a;
113: a -= dp;
114: if(a < 0)
115: a = 0;
116: if(a > param[2]) /* digits to right of dp */
117: param[2] = a;
118: if(dp > param[1]) /* digits to left of dp */
119: param[1] = dp;
120: param[3] |= sg; /* and sign */
121: }
122:
123: epr2(d, param)
124: int *param;
125: data d;
126: {
127: register i;
128: register char *c, *mc;
129: double f;
130: int dp, sg;
131:
132: if(param[0]+column > thread.width && !mencflg) {
133: putchar('\n');
134: putto(param[0]);
135: }
136: f = d;
137: c = ecvt(f, thread.digits, &dp, &sg);
138: if (f == zero)
139: dp = 1; /* kludge due to change in ecvt */
140: mc = c + thread.digits;
141: putchar(' ');
142: sg = sg? '-': ' '; /* '-' used to be '"' */
143: if(param[2] < 0) {
144: if(param[3])
145: putchar(sg);
146: for(i=0; i<param[1]; i++) {
147: putchar(*c++);
148: if(i == 0)
149: putchar('.');
150: }
151: putchar('e');
152: dp--;
153: if(dp < 0) {
154: putchar('-'); /* '=' used to be '"' */
155: dp = -dp;
156: } else
157: putchar('+'); /* apl style plus sign, used to be ':' */
158: putchar(dp/10 + '0');
159: putchar(dp%10 + '0');
160: return;
161: }
162: i = dp;
163: if(i < 0)
164: i = 0;
165: for(; i<param[1]; i++)
166: putchar(' ');
167: if(param[3])
168: putchar(sg);
169: for(i=0; i<dp; i++)
170: if(c >= mc)
171: putchar('0'); else
172: putchar(*c++);
173: for(i=0; i<param[2]; i++) {
174: if(i == 0)
175: putchar('.');
176: if(dp < 0) {
177: putchar('0');
178: dp++;
179: } else
180: if(c >= mc)
181: putchar('0'); else
182: putchar(*c++);
183: }
184: }
185:
186: error(s)
187: char *s;
188: {
189: register c;
190: register char *cp, *cs;
191:
192: intflg = 0;
193: if(ifile) {
194: CLOSEF(ifile);
195: ifile = 0;
196: }
197: cp = s;
198: while(c = *cp++) {
199: if(c >= 'A' && c <= 'Z') {
200: switch(c) {
201:
202: case 'I':
203: cs = "\ninterrupt";
204: break;
205:
206: case 'L':
207: cs = "L";
208: break;
209:
210: case 'C':
211: cs = "conformability";
212: break;
213:
214: case 'S':
215: cs = "syntax";
216: break;
217:
218: case 'R':
219: cs = "rank";
220: break;
221:
222: case 'X':
223: cs = "index";
224: break;
225:
226: case 'Y':
227: cs = "character";
228: break;
229:
230: case 'M':
231: cs = "memory";
232: break;
233:
234: case 'D':
235: cs = "domain";
236: break;
237:
238: case 'T':
239: cs = "type";
240: break;
241:
242: case 'E':
243: cs = "error";
244: break;
245:
246: case 'P':
247: cs = "programmer";
248: break;
249:
250: case 'B':
251: cs = "botch";
252: break;
253:
254: default:
255: putchar(c);
256: continue;
257: }
258: printf(cs);
259: continue;
260: }
261: putchar(c);
262: }
263: putchar('\n');
264: if (prwsflg) exit(0); /* if "prws", just exit */
265: /*
266: * produce traceback and mark state indicator.
267: */
268: tback(0);
269: if(gsip)
270: gsip->suspended = 1;
271: else {
272: while(sp > stack)
273: pop(); /* zap garbage */
274: reset();
275: }
276: mainloop(); /* reenter mainloop */
277: }
278:
279: printf(f, a)
280: char *f;
281: {
282: register char *s, *cp;
283: register *p;
284:
285: s = f;
286: p = &a;
287: while(*s) {
288: if(s[0] == '%')
289: switch(s[1]){
290: case 'd':
291: putn(*p++);
292: s += 2;
293: continue;
294: case 'o':
295: puto(*p++);
296: s += 2;
297: continue;
298: case 's':
299: cp = (char *)*p++;
300: s += 2;
301: while(*cp)
302: putchar(*cp++);
303: continue;
304: case 'f':
305: putf(p);
306: p += 4; /* 4 words per floating arg */
307: s += 2;
308: continue;
309: }
310: putchar(*s++);
311: }
312: }
313:
314: putn(n)
315: {
316: register a;
317:
318: if(n < 0) {
319: n = -n;
320: if(n < 0) {
321: printf("32768");
322: return;
323: }
324: putchar('-'); /* apl minus sign, was '"' */
325: }
326: if(a=n/10)
327: putn(a);
328: putchar(n%10 + '0');
329: }
330:
331: putf(p)
332: data *p;
333: {
334: int param[4];
335: register int i;
336:
337: param[1] = param[2] = param[3] = param[0] = 0;
338: epr1(*p, param);
339: i = param[1] + param[2]; /* size if fp */
340: if(i > thread.digits)
341: i += 100;
342: if(param[2])
343: i++;
344: if(i > param[0]+5) {
345: i = param[0] + 5; /* size if ep */
346: param[1] = param[0];
347: param[2] = -1;
348: }
349: if(param[3])
350: i++; /* sign */
351: i++; /* leading space */
352: param[0] = i;
353: epr2(*p, param);
354: /*
355: * register i,j;
356: *
357: * i = *p;
358: * j = (*p * 1000.0) - (i * 1000.0);
359: * putn(i);
360: * putchar('.');
361: * putchar('0' + j/100);
362: * putchar('0' + (j/10)%10);
363: * putchar('0' + j%10);
364: */
365: }
366:
367: puto(n)
368: {
369: if(n&0177770)
370: puto( (n>>3) & 017777);
371: putchar( '0' + (n&07));
372: }
373:
374: getchar()
375: {
376: int c;
377:
378: c = 0;
379: if(READF(ifile, &c, 1) == 1 && echoflg == 1 && !ifile)
380: WRITEF(1, &c, 1);
381:
382: /* The following code converts the input character
383: * to the ASCII equivalent (internal format) if
384: * terminal character mapping is in force.
385: */
386:
387: if (apl_term && c >= 041 && !ifile) c = map_ascii[(c&0177)-041];
388: if (c && protofile && ifile == 0) WRITEF(protofile, &c, 1);
389:
390: return(c);
391: }
392:
393: putchar(c)
394: {
395: register i;
396:
397:
398: /* This is the basic character output routine. If "mencflg"
399: * is zero, output is performed on file descriptor 1. If
400: * "menclfg" is non-zero, output is placed into the buffer
401: * pointed to by "mencptr".
402: */
403:
404: if(mencflg) { /* Format operator */
405: if(c != '\n') {
406: mencflg = 1;
407: *mencptr++ = c;
408: }
409: else
410: if(mencflg > 1)
411: mencptr += rowsz;
412: else
413: mencflg = 2;
414: return;
415: }
416:
417:
418: switch(c){ /* Normal output */
419:
420: case '\0':
421: return;
422:
423: case '\b':
424: if(column)
425: column--;
426: break;
427:
428: case '\t':
429: column = (column+8) & ~7;
430: break;
431:
432: case '\r':
433: case '\n':
434: column = 0;
435: break;
436:
437: default:
438: column++;
439: }
440:
441: if (column > thread.width) printf("\n "); /* adjust for width */
442:
443: if(intflg == 0) {
444: if(c & 0200) {
445: i = chartab[c & 0177];
446: putchar(i>>8);
447: c = i & 0177;
448: putchar('\b');
449: }
450:
451: if(protofile)
452: WRITEF(protofile, &c, 1);
453:
454:
455: /* The following code converts the internal value
456: * to the APL character for modified terminals
457: * if the APL conversion was requested.
458: */
459:
460: if (apl_term && c >= 041)
461: c = map_apl[c-041];
462: #ifdef PURDUE_EE
463: if (apl_term && c == 010)
464: c = '^';
465: #endif
466:
467: WRITEF(1, &c, 1);
468: #ifdef NBUF
469: if (c == '\n' && !prwsflg)
470: newbuf(files[1].fd_buf, 1);
471: #endif
472: }
473: }
474:
475: char *ty[] = {
476: 0,"DA","CH","LV","QD","QQ","IN","EL","NF","MF","DF","QC","QV","DU","QX","LB"
477: };
478:
479: dstack()
480: {
481: register struct item **p;
482: register i,n;
483:
484: p = sp;
485: n = 0;
486: while(--p > stack){
487: printf("\t%o: sp[%d]: type = ", p, --n);
488: if((i=(*p)->type) >= 0 && i <= LBL && ty[i])
489: printf(ty[i]);
490: else
491: printf("%d", (*p)->type);
492: switch(i){
493: default:
494: putchar('\n');
495: break;
496: case LV:
497: printf(", n = %s\n", ((struct nlist *)*p)->namep);
498: break;
499:
500: case CH:
501: if((*p)->size == 0)
502: goto nullone;
503: if((*p)->rank == 1){
504: printf(", \"");
505: for(i=0; i<(*p)->size; i++)
506: putchar(((struct chrstrct *)(*p)->datap)->c[i]);
507: printf("\"\n");
508: } else
509: goto rnk;
510: break;
511:
512: case DA:
513: case LBL:
514: if((*p)->size == 0)
515: goto nullone;
516: if((*p)->rank == 0){
517: printf(", v = %f\n", (*p)->datap[0]);
518: }
519: break;
520: rnk:
521: printf(", rank = %d\n", (*p)->rank);
522: break;
523:
524: nullone:
525: printf(", <null>\n");
526: break;
527: }
528: }
529: putchar('\n');
530: }
531:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.