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