1 /*- 2 * Copyright (c) 1980 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)printval.c 5.3 (Berkeley) 04/16/91"; 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