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) 04/07/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 } 303