1*5529Slinton /* Copyright (c) 1982 Regents of the University of California */
2*5529Slinton 
3*5529Slinton static char sccsid[] = "@(#)printval.c 1.1 01/18/82";
4*5529Slinton 
5*5529Slinton /*
6*5529Slinton  * Print out the value at the top of the stack using the given type.
7*5529Slinton  */
8*5529Slinton 
9*5529Slinton #include "defs.h"
10*5529Slinton #include "sym.h"
11*5529Slinton #include "btypes.h"
12*5529Slinton #include "classes.h"
13*5529Slinton #include "tree.h"
14*5529Slinton #include "process.h"
15*5529Slinton #include "mappings.h"
16*5529Slinton #include "sym.rep"
17*5529Slinton 
18*5529Slinton printval(s)
19*5529Slinton SYM *s;
20*5529Slinton {
21*5529Slinton 	SYM *t;
22*5529Slinton 	ADDRESS a;
23*5529Slinton 	int len;
24*5529Slinton 
25*5529Slinton 	if (s->class == REF) {
26*5529Slinton 		s = s->type;
27*5529Slinton 	}
28*5529Slinton 	switch(s->class) {
29*5529Slinton 		case ARRAY:
30*5529Slinton 			t = rtype(s->type);
31*5529Slinton 			if (t==t_char || (t->class==RANGE && t->type==t_char)) {
32*5529Slinton 				len = size(s);
33*5529Slinton 				sp -= len;
34*5529Slinton 				printf("'%s'", sp);
35*5529Slinton 				break;
36*5529Slinton 			} else {
37*5529Slinton 				printarray(s);
38*5529Slinton 			}
39*5529Slinton 			break;
40*5529Slinton 
41*5529Slinton 		case RECORD:
42*5529Slinton 			printrecord(s);
43*5529Slinton 			break;
44*5529Slinton 
45*5529Slinton 		case VARNT:
46*5529Slinton 			error("can't print out variant records");
47*5529Slinton 			break;
48*5529Slinton 
49*5529Slinton 		case RANGE:
50*5529Slinton 			if (s == t_real) {
51*5529Slinton 				printf("%g", pop(double));
52*5529Slinton 			} else if (s == t_char) {
53*5529Slinton 				printf("'%c'", pop(long));
54*5529Slinton 			} else if (s == t_boolean) {
55*5529Slinton 				printf(pop(BOOLEAN)==TRUE ? "true" : "false");
56*5529Slinton 			} else {
57*5529Slinton 				printf("%ld", pop(long));
58*5529Slinton 			}
59*5529Slinton 			break;
60*5529Slinton 
61*5529Slinton 		case FILET:
62*5529Slinton 		case PTR: {
63*5529Slinton 			ADDRESS addr;
64*5529Slinton 
65*5529Slinton 			addr = pop(ADDRESS);
66*5529Slinton 			if (addr == 0) {
67*5529Slinton 				printf("nil");
68*5529Slinton 			} else {
69*5529Slinton 				printf("0%o", addr);
70*5529Slinton 			}
71*5529Slinton 			break;
72*5529Slinton 		}
73*5529Slinton 
74*5529Slinton 		case FIELD:
75*5529Slinton 			error("missing record specification");
76*5529Slinton 			break;
77*5529Slinton 
78*5529Slinton 		case SCAL: {
79*5529Slinton 			int scalar;
80*5529Slinton 			BOOLEAN found;
81*5529Slinton 
82*5529Slinton 			scalar = pop(long);
83*5529Slinton 			found = FALSE;
84*5529Slinton 			for (t = s->chain; t != NIL; t = t->chain) {
85*5529Slinton 				if (t->symvalue.iconval == scalar) {
86*5529Slinton 					printf("%s", t->symbol);
87*5529Slinton 					found = TRUE;
88*5529Slinton 					break;
89*5529Slinton 				}
90*5529Slinton 			}
91*5529Slinton 			if (!found) {
92*5529Slinton 				printf("(scalar = %d)", scalar);
93*5529Slinton 			}
94*5529Slinton 			break;
95*5529Slinton 		}
96*5529Slinton 
97*5529Slinton 		case FPROC:
98*5529Slinton 		case FFUNC:
99*5529Slinton 		{
100*5529Slinton 			ADDRESS a;
101*5529Slinton 
102*5529Slinton 			a = fparamaddr(pop(long));
103*5529Slinton 			t = whatblock(a);
104*5529Slinton 			if (t == NIL) {
105*5529Slinton 				printf("(proc %d)", a);
106*5529Slinton 			} else {
107*5529Slinton 				printf("%s", t->symbol);
108*5529Slinton 			}
109*5529Slinton 			break;
110*5529Slinton 		}
111*5529Slinton 
112*5529Slinton 		default:
113*5529Slinton 			if (s->class < BADUSE || s->class > VARNT) {
114*5529Slinton 				panic("printval: bad class %d", s->class);
115*5529Slinton 			}
116*5529Slinton 			error("don't know how to print a %s", classname(s));
117*5529Slinton 			/* NOTREACHED */
118*5529Slinton 	}
119*5529Slinton }
120*5529Slinton 
121*5529Slinton /*
122*5529Slinton  * Print out the value of a record, field by field.
123*5529Slinton  */
124*5529Slinton 
125*5529Slinton LOCAL printrecord(s)
126*5529Slinton SYM *s;
127*5529Slinton {
128*5529Slinton 	SYM *t;
129*5529Slinton 
130*5529Slinton 	if ((t = s->chain) == NIL) {
131*5529Slinton 		error("record has no fields");
132*5529Slinton 	}
133*5529Slinton 	printf("(");
134*5529Slinton 	sp -= size(s);
135*5529Slinton 	printfield(t);
136*5529Slinton 	printf(")");
137*5529Slinton }
138*5529Slinton 
139*5529Slinton /*
140*5529Slinton  * Print out a field, first printing out other fields.
141*5529Slinton  * This is done because the fields are chained together backwards.
142*5529Slinton  */
143*5529Slinton 
144*5529Slinton LOCAL printfield(s)
145*5529Slinton SYM *s;
146*5529Slinton {
147*5529Slinton 	STACK *savesp;
148*5529Slinton 
149*5529Slinton 	if (s->chain != NIL) {
150*5529Slinton 		printfield(s->chain);
151*5529Slinton 		printf(", ");
152*5529Slinton 	}
153*5529Slinton 	printf("%s = ", s->symbol);
154*5529Slinton 	savesp = sp;
155*5529Slinton 	sp += (s->symvalue.offset + size(s->type));
156*5529Slinton 	alignstack();
157*5529Slinton 	printval(s->type);
158*5529Slinton 	sp = savesp;
159*5529Slinton }
160*5529Slinton 
161*5529Slinton /*
162*5529Slinton  * Print out the contents of an array.
163*5529Slinton  * Haven't quite figured out what the best format is.
164*5529Slinton  *
165*5529Slinton  * This is rather inefficient.
166*5529Slinton  *
167*5529Slinton  * The "2*elsize" is there since "printval" drops the stack by elsize.
168*5529Slinton  */
169*5529Slinton 
170*5529Slinton LOCAL printarray(a)
171*5529Slinton SYM *a;
172*5529Slinton {
173*5529Slinton 	STACK *savesp, *newsp;
174*5529Slinton 	SYM *eltype;
175*5529Slinton 	long elsize;
176*5529Slinton 
177*5529Slinton 	savesp = sp;
178*5529Slinton 	sp -= size(a);
179*5529Slinton 	newsp = sp;
180*5529Slinton 	eltype = a->type;
181*5529Slinton 	elsize = size(eltype);
182*5529Slinton 	printf("(");
183*5529Slinton 	for (sp += elsize; sp <= savesp; sp += 2*elsize) {
184*5529Slinton 		if (sp - elsize != newsp) {
185*5529Slinton 			printf(", ");
186*5529Slinton 		}
187*5529Slinton 		printval(eltype);
188*5529Slinton 	}
189*5529Slinton 	sp = newsp;
190*5529Slinton 	printf(")");
191*5529Slinton }
192