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