|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)printval.c 5.2 (Berkeley) 4/7/87";
9: #endif not lint
10:
11: /*
12: * Print out the value at the top of the stack using the given type.
13: */
14:
15: #include "defs.h"
16: #include "sym.h"
17: #include "btypes.h"
18: #include "classes.h"
19: #include "tree.h"
20: #include "process.h"
21: #include "mappings.h"
22: #include "sym.rep"
23:
24: printval(s)
25: SYM *s;
26: {
27: SYM *t;
28: ADDRESS a;
29: int len;
30: double r;
31:
32: if (s->class == REF) {
33: s = s->type;
34: }
35: switch (s->class) {
36: case ARRAY:
37: t = rtype(s->type);
38: if (t == t_char || (t->class == RANGE && t->type == t_char)) {
39: len = size(s);
40: sp -= len;
41: #ifdef tahoe
42: downalignstack();
43: #endif
44: printf("'%.*s'", len, sp);
45: break;
46: } else {
47: printarray(s);
48: }
49: break;
50:
51: case RECORD:
52: printrecord(s);
53: break;
54:
55: case VARNT:
56: error("can't print out variant records");
57: break;
58:
59: case RANGE:
60: if (s == t_real) {
61: prtreal(pop(double));
62: } else {
63: printordinal(popsmall(s), rtype(s->type));
64: }
65: break;
66:
67: case FILET:
68: case PTR:
69: a = pop(ADDRESS);
70: if (a == 0) {
71: printf("nil");
72: } else {
73: printf("0%o", a);
74: }
75: break;
76:
77: case FIELD:
78: error("missing record specification");
79: break;
80:
81: case SCAL:
82: printordinal(popsmall(s), s);
83: break;
84:
85: case FPROC:
86: case FFUNC:
87: a = fparamaddr(pop(long));
88: t = whatblock(a);
89: if (t == NIL) {
90: printf("(proc %d)", a);
91: } else {
92: printf("%s", t->symbol);
93: }
94: break;
95:
96: default:
97: if (s->class < BADUSE || s->class > VARNT) {
98: panic("printval: bad class %d", s->class);
99: }
100: error("don't know how to print a %s", classname(s));
101: /* NOTREACHED */
102: }
103: }
104:
105: /*
106: * Print out an ordinal value (either an integer, character, or
107: * an enumeration constant).
108: */
109:
110: printordinal(v, t)
111: long v;
112: SYM *t;
113: {
114: SYM *c;
115: int iv;
116:
117: iv = v;
118: if (t->class == SCAL) {
119: c = t->chain;
120: while (c != NIL && c->symvalue.iconval != iv) {
121: c = c->chain;
122: }
123: if (c == NIL) {
124: printf("(scalar = %d)", iv);
125: } else {
126: printf("%s", c->symbol);
127: }
128: } else if (t == t_char) {
129: printf("'%c'", iv);
130: } else if (t == t_boolean) {
131: printf("%s", (iv == TRUE) ? "true" : "false");
132: } else {
133: printf("%ld", v);
134: }
135: }
136:
137: /*
138: * Print out the value of a record, field by field.
139: */
140:
141: LOCAL printrecord(s)
142: SYM *s;
143: {
144: SYM *t;
145:
146: if ((t = s->chain) == NIL) {
147: error("record has no fields");
148: }
149: printf("(");
150: sp -= size(s);
151: #ifdef tahoe
152: downalignstack();
153: #endif
154: printfield(t);
155: printf(")");
156: }
157:
158: /*
159: * Print out a field, first printing out other fields.
160: * This is done because the fields are chained together backwards.
161: */
162:
163: LOCAL printfield(s)
164: SYM *s;
165: {
166: STACK *savesp;
167:
168: if (s->chain != NIL) {
169: printfield(s->chain);
170: printf(", ");
171: }
172: printf("%s = ", s->symbol);
173: savesp = sp;
174: sp += (s->symvalue.offset + size(s->type));
175: #ifdef tahoe
176: alignstack();
177: #endif
178: printval(s->type);
179: sp = savesp;
180: }
181:
182: /*
183: * Print out the contents of an array.
184: * Haven't quite figured out what the best format is.
185: *
186: * This is rather inefficient.
187: *
188: * The "2*elsize" is there since "printval" drops the stack by elsize.
189: */
190:
191: #ifdef tahoe
192: LOCAL printarray(a)
193: SYM *a;
194: {
195: STACK *savesp, *newsp;
196: SYM *eltype;
197: long elsize;
198:
199: savesp = (STACK *)(((int)sp + 3) & ~3);
200: eltype = a->type;
201: printf("(");
202: elsize = size(eltype);
203: if (eltype->class == ARRAY)
204: savesp += elsize;
205: if (elsize < sizeof(int)) {
206: register char *cp = sp - ((size(a) + 3) & ~3);
207: int psh;
208: register char *cp1, *end = cp + size(a);
209: register int savestack;
210:
211: while (cp < end) {
212: psh = 0;
213: cp1 = (char *)&psh + sizeof(int) - elsize;
214: while (cp1 < (char *)&psh + sizeof psh)
215: *cp1++ = *cp++;
216: if (end - size(a) != cp - elsize) {
217: printf(", ");
218: }
219: switch (elsize) {
220: case sizeof(char):
221: savestack = *(char *)sp;
222: push(char, psh);
223: printval(eltype);
224: *(char *)sp = savestack;
225: break;
226: case sizeof(short):
227: savestack = *(short *)sp;
228: push(short, psh);
229: printval(eltype);
230: *(short *)sp = savestack;
231: break;
232: default:
233: panic("bad size on runtime stack");
234: }
235: }
236: } else {
237: sp -= size(a);
238: downalignstack();
239: newsp = sp;
240: for (sp += elsize, alignstack(); sp <= savesp; sp += 2*elsize) {
241: if (sp - 2*elsize >= newsp) {
242: printf(", ");
243: }
244: printval(eltype);
245: if (eltype->class == ARRAY) {
246: sp -= elsize;
247: }
248: }
249: sp = newsp;
250: }
251: printf(")");
252: }
253: #else
254:
255: LOCAL printarray(a)
256: SYM *a;
257: {
258: STACK *savesp, *newsp;
259: SYM *eltype;
260: long elsize;
261:
262: savesp = sp;
263: eltype = a->type;
264: elsize = size(eltype);
265: sp -= size(a);
266: newsp = sp;
267: printf("(");
268: for (sp += elsize; sp <= savesp; sp += 2*elsize) {
269: if (sp - elsize != newsp) {
270: printf(", ");
271: }
272: printval(eltype);
273: }
274: sp = newsp;
275: printf(")");
276: }
277: #endif tahoe
278:
279: /*
280: * Print out the value of a real number.
281: * Pascal notation is somewhat different that what one gets
282: * from "%g" in printf.
283: */
284:
285: LOCAL prtreal(r)
286: double r;
287: {
288: extern char *index();
289: char buf[256];
290:
291: sprintf(buf, "%g", r);
292: if (buf[0] == '.') {
293: printf("0%s", buf);
294: } else if (buf[0] == '-' && buf[1] == '.') {
295: printf("-0%s", &buf[1]);
296: } else {
297: printf("%s", buf);
298: }
299: if (index(buf, '.') == NIL) {
300: printf(".0");
301: }
302: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.