1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)printval.c 1.7 02/14/83"; 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 double r; 25 26 if (s->class == REF) { 27 s = s->type; 28 } 29 switch (s->class) { 30 case ARRAY: 31 t = rtype(s->type); 32 if (t == t_char || (t->class == RANGE && t->type == t_char)) { 33 len = size(s); 34 sp -= len; 35 printf("'%.*s'", len, sp); 36 break; 37 } else { 38 printarray(s); 39 } 40 break; 41 42 case RECORD: 43 printrecord(s); 44 break; 45 46 case VARNT: 47 error("can't print out variant records"); 48 break; 49 50 case RANGE: 51 if (s == t_real) { 52 prtreal(pop(double)); 53 } else { 54 printordinal(popsmall(s), rtype(s->type)); 55 } 56 break; 57 58 case FILET: 59 case PTR: 60 a = pop(ADDRESS); 61 if (a == 0) { 62 printf("nil"); 63 } else { 64 printf("0%o", a); 65 } 66 break; 67 68 case FIELD: 69 error("missing record specification"); 70 break; 71 72 case SCAL: 73 printordinal(popsmall(s), s); 74 break; 75 76 case FPROC: 77 case FFUNC: 78 a = fparamaddr(pop(long)); 79 t = whatblock(a); 80 if (t == NIL) { 81 printf("(proc %d)", a); 82 } else { 83 printf("%s", t->symbol); 84 } 85 break; 86 87 default: 88 if (s->class < BADUSE || s->class > VARNT) { 89 panic("printval: bad class %d", s->class); 90 } 91 error("don't know how to print a %s", classname(s)); 92 /* NOTREACHED */ 93 } 94 } 95 96 /* 97 * Print out an ordinal value (either an integer, character, or 98 * an enumeration constant). 99 */ 100 101 printordinal(v, t) 102 long v; 103 SYM *t; 104 { 105 BOOLEAN found; 106 SYM *c; 107 int iv; 108 109 iv = v; 110 if (t->class == SCAL) { 111 c = t->chain; 112 while (c != NIL && c->symvalue.iconval != iv) { 113 c = c->chain; 114 } 115 if (c == NIL) { 116 printf("(scalar = %d)", iv); 117 } else { 118 printf("%s", c->symbol); 119 } 120 } else if (t == t_char) { 121 printf("'%c'", iv); 122 } else if (t == t_boolean) { 123 printf("%s", (iv == TRUE) ? "true" : "false"); 124 } else { 125 printf("%ld", v); 126 } 127 } 128 129 /* 130 * Print out the value of a record, field by field. 131 */ 132 133 LOCAL printrecord(s) 134 SYM *s; 135 { 136 SYM *t; 137 138 if ((t = s->chain) == NIL) { 139 error("record has no fields"); 140 } 141 printf("("); 142 sp -= size(s); 143 printfield(t); 144 printf(")"); 145 } 146 147 /* 148 * Print out a field, first printing out other fields. 149 * This is done because the fields are chained together backwards. 150 */ 151 152 LOCAL printfield(s) 153 SYM *s; 154 { 155 STACK *savesp; 156 157 if (s->chain != NIL) { 158 printfield(s->chain); 159 printf(", "); 160 } 161 printf("%s = ", s->symbol); 162 savesp = sp; 163 sp += (s->symvalue.offset + size(s->type)); 164 printval(s->type); 165 sp = savesp; 166 } 167 168 /* 169 * Print out the contents of an array. 170 * Haven't quite figured out what the best format is. 171 * 172 * This is rather inefficient. 173 * 174 * The "2*elsize" is there since "printval" drops the stack by elsize. 175 */ 176 177 LOCAL printarray(a) 178 SYM *a; 179 { 180 STACK *savesp, *newsp; 181 SYM *eltype; 182 long elsize; 183 184 savesp = sp; 185 sp -= size(a); 186 newsp = sp; 187 eltype = a->type; 188 elsize = size(eltype); 189 printf("("); 190 for (sp += elsize; sp <= savesp; sp += 2*elsize) { 191 if (sp - elsize != newsp) { 192 printf(", "); 193 } 194 printval(eltype); 195 } 196 sp = newsp; 197 printf(")"); 198 } 199 200 /* 201 * Print out the value of a real number. 202 * Pascal notation is somewhat different that what one gets 203 * from "%g" in printf. 204 */ 205 206 LOCAL prtreal(r) 207 double r; 208 { 209 extern char *index(); 210 char *p, buf[256]; 211 212 sprintf(buf, "%g", r); 213 if (buf[0] == '.') { 214 printf("0%s", buf); 215 } else if (buf[0] == '-' && buf[1] == '.') { 216 printf("-0%s", &buf[1]); 217 } else { 218 printf("%s", buf); 219 } 220 if (index(buf, '.') == NIL) { 221 printf(".0"); 222 } 223 } 224