Commit | Line | Data |
---|---|---|
204ed195 ML |
1 | /* Copyright (c) 1982 Regents of the University of California */ |
2 | ||
e804469b | 3 | static char sccsid[] = "@(#)printval.c 1.7 2/14/83"; |
204ed195 ML |
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 | { | |
00434a44 ML |
21 | SYM *t; |
22 | ADDRESS a; | |
23 | int len; | |
7275bc1e | 24 | double r; |
00434a44 ML |
25 | |
26 | if (s->class == REF) { | |
27 | s = s->type; | |
28 | } | |
1a53fa88 | 29 | switch (s->class) { |
00434a44 ML |
30 | case ARRAY: |
31 | t = rtype(s->type); | |
1a53fa88 | 32 | if (t == t_char || (t->class == RANGE && t->type == t_char)) { |
00434a44 ML |
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) { | |
a18a57e7 | 52 | prtreal(pop(double)); |
00434a44 | 53 | } else { |
1a53fa88 | 54 | printordinal(popsmall(s), rtype(s->type)); |
00434a44 ML |
55 | } |
56 | break; | |
57 | ||
58 | case FILET: | |
1a53fa88 ML |
59 | case PTR: |
60 | a = pop(ADDRESS); | |
61 | if (a == 0) { | |
00434a44 ML |
62 | printf("nil"); |
63 | } else { | |
1a53fa88 | 64 | printf("0%o", a); |
00434a44 ML |
65 | } |
66 | break; | |
204ed195 | 67 | |
00434a44 ML |
68 | case FIELD: |
69 | error("missing record specification"); | |
70 | break; | |
71 | ||
1a53fa88 ML |
72 | case SCAL: |
73 | printordinal(popsmall(s), s); | |
00434a44 | 74 | break; |
204ed195 | 75 | |
00434a44 ML |
76 | case FPROC: |
77 | case FFUNC: | |
00434a44 ML |
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; | |
00434a44 ML |
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 | } | |
204ed195 ML |
94 | } |
95 | ||
1a53fa88 ML |
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 | ||
204ed195 ML |
129 | /* |
130 | * Print out the value of a record, field by field. | |
131 | */ | |
132 | ||
133 | LOCAL printrecord(s) | |
134 | SYM *s; | |
135 | { | |
00434a44 ML |
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(")"); | |
204ed195 ML |
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 | { | |
00434a44 ML |
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; | |
204ed195 ML |
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 | { | |
00434a44 ML |
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(", "); | |
204ed195 | 193 | } |
00434a44 ML |
194 | printval(eltype); |
195 | } | |
196 | sp = newsp; | |
197 | printf(")"); | |
204ed195 | 198 | } |
7275bc1e ML |
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 | ||
a18a57e7 | 206 | LOCAL prtreal(r) |
7275bc1e ML |
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 | } |