BSD 4_1c_2 release
[unix-history] / usr / src / ucb / pascal / pdx / sym / printval.c
CommitLineData
204ed195
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
e804469b 3static 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
18printval(s)
19SYM *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
101printordinal(v, t)
102long v;
103SYM *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
133LOCAL printrecord(s)
134SYM *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
152LOCAL printfield(s)
153SYM *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
177LOCAL printarray(a)
178SYM *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 206LOCAL prtreal(r)
7275bc1e
ML
207double 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}