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