1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)printval.c 1.6 03/09/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 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 if (s == t_char) { 54 printf("'%c'", pop(char)); 55 } else if (s == t_boolean) { 56 printf(popsmall(s) == TRUE ? "true" : "false"); 57 } else { 58 printf("%ld", popsmall(s)); 59 } 60 break; 61 62 case FILET: 63 case PTR: { 64 ADDRESS addr; 65 66 addr = pop(ADDRESS); 67 if (addr == 0) { 68 printf("nil"); 69 } else { 70 printf("0%o", addr); 71 } 72 break; 73 } 74 75 case FIELD: 76 error("missing record specification"); 77 break; 78 79 case SCAL: { 80 int scalar; 81 BOOLEAN found; 82 83 scalar = popsmall(s); 84 found = FALSE; 85 for (t = s->chain; t != NIL; t = t->chain) { 86 if (t->symvalue.iconval == scalar) { 87 printf("%s", t->symbol); 88 found = TRUE; 89 break; 90 } 91 } 92 if (!found) { 93 printf("(scalar = %d)", scalar); 94 } 95 break; 96 } 97 98 case FPROC: 99 case FFUNC: 100 { 101 ADDRESS a; 102 103 a = fparamaddr(pop(long)); 104 t = whatblock(a); 105 if (t == NIL) { 106 printf("(proc %d)", a); 107 } else { 108 printf("%s", t->symbol); 109 } 110 break; 111 } 112 113 default: 114 if (s->class < BADUSE || s->class > VARNT) { 115 panic("printval: bad class %d", s->class); 116 } 117 error("don't know how to print a %s", classname(s)); 118 /* NOTREACHED */ 119 } 120 } 121 122 /* 123 * Print out the value of a record, field by field. 124 */ 125 126 LOCAL printrecord(s) 127 SYM *s; 128 { 129 SYM *t; 130 131 if ((t = s->chain) == NIL) { 132 error("record has no fields"); 133 } 134 printf("("); 135 sp -= size(s); 136 printfield(t); 137 printf(")"); 138 } 139 140 /* 141 * Print out a field, first printing out other fields. 142 * This is done because the fields are chained together backwards. 143 */ 144 145 LOCAL printfield(s) 146 SYM *s; 147 { 148 STACK *savesp; 149 150 if (s->chain != NIL) { 151 printfield(s->chain); 152 printf(", "); 153 } 154 printf("%s = ", s->symbol); 155 savesp = sp; 156 sp += (s->symvalue.offset + size(s->type)); 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 193 /* 194 * Print out the value of a real number. 195 * Pascal notation is somewhat different that what one gets 196 * from "%g" in printf. 197 */ 198 199 LOCAL prtreal(r) 200 double r; 201 { 202 extern char *index(); 203 char *p, buf[256]; 204 205 sprintf(buf, "%g", r); 206 if (buf[0] == '.') { 207 printf("0%s", buf); 208 } else if (buf[0] == '-' && buf[1] == '.') { 209 printf("-0%s", &buf[1]); 210 } else { 211 printf("%s", buf); 212 } 213 if (index(buf, '.') == NIL) { 214 printf(".0"); 215 } 216 } 217