1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)printdecl.c 1.1 01/18/82";
4 
5 /*
6  * print out the type of a symbol
7  */
8 
9 #include "defs.h"
10 #include "sym.h"
11 #include "symtab.h"
12 #include "tree.h"
13 #include "btypes.h"
14 #include "classes.h"
15 #include "sym.rep"
16 
17 printdecl(s)
18 SYM *s;
19 {
20 	register SYM *t;
21 	BOOLEAN semicolon;
22 
23 	semicolon = TRUE;
24 	switch(s->class) {
25 		case CONST:
26 			if (s->type->class == SCAL) {
27 				printf("(enumeration constant, ord %ld)",
28 					s->symvalue.iconval);
29 			} else {
30 				printf("const %s = ", s->symbol);
31 				if (s->type == t_real->type) {
32 					printf("%g", s->symvalue.fconval);
33 				} else {
34 					printf("%ld", s->symvalue.iconval);
35 				}
36 			}
37 			break;
38 
39 		case TYPE:
40 			printf("type %s = ", s->symbol);
41 			printtype(s, s->type);
42 			break;
43 
44 		case VAR:
45 			if (isparam(s)) {
46 				printf("(parameter) %s : ", s->symbol);
47 			} else {
48 				printf("var %s : ", s->symbol);
49 			}
50 			printtype(s, s->type);
51 			break;
52 
53 		case REF:
54 			printf("(var parameter) %s : ", s->symbol);
55 			printtype(s, s->type);
56 			break;
57 
58 		case RANGE:
59 		case ARRAY:
60 		case RECORD:
61 		case VARNT:
62 		case PTR:
63 			printtype(s, s);
64 			semicolon = FALSE;
65 			break;
66 
67 		case FVAR:
68 			printf("(function variable) %s : ", s->symbol);
69 			printtype(s, s->type);
70 			break;
71 
72 		case FIELD:
73 			printf("(field) %s : ", s->symbol);
74 			printtype(s, s->type);
75 			break;
76 
77 		case PROC:
78 			printf("procedure %s", s->symbol);
79 			listparams(s);
80 			break;
81 
82 		case PROG:
83 			printf("program %s", s->symbol);
84 			t = s->chain;
85 			if (t != NIL) {
86 				printf("(%s", t->symbol);
87 				for (t = t->chain; t != NIL; t = t->chain) {
88 					printf(", %s", t->symbol);
89 				}
90 				printf(")");
91 			}
92 			break;
93 
94 		case FUNC:
95 			printf("function %s", s->symbol);
96 			listparams(s);
97 			printf(" : ");
98 			printtype(s, s->type);
99 			break;
100 
101 		default:
102 			error("class %s in printdecl", classname(s));
103 	}
104 	if (semicolon) {
105 		putchar(';');
106 	}
107 	putchar('\n');
108 }
109 
110 /*
111  * Recursive whiz-bang procedure to print the type portion
112  * of a declaration.  Doesn't work quite right for variant records.
113  *
114  * The symbol associated with the type is passed to allow
115  * searching for type names without getting "type blah = blah".
116  */
117 
118 LOCAL printtype(s, t)
119 SYM *s;
120 SYM *t;
121 {
122 	register SYM *tmp;
123 
124 	tmp = findtype(t);
125 	if (tmp != NIL && tmp != s) {
126 		printf("%s", tmp->symbol);
127 		return;
128 	}
129 	switch(t->class) {
130 		case VAR:
131 		case CONST:
132 		case FUNC:
133 		case PROC:
134 			panic("printtype: class %s", classname(t));
135 			break;
136 
137 		case ARRAY:
138 			printf("array[");
139 			tmp = t->chain;
140 			for (;;) {
141 				printtype(tmp, tmp);
142 				tmp = tmp->chain;
143 				if (tmp == NIL) {
144 					break;
145 				}
146 				printf(", ");
147 			}
148 			printf("] of ");
149 			printtype(t, t->type);
150 			break;
151 
152 		case RECORD:
153 			printf("record\n");
154 			if (t->chain != NIL) {
155 				printtype(t->chain, t->chain);
156 			}
157 			printf("end");
158 			break;
159 
160 		case FIELD:
161 			if (t->chain != NIL) {
162 				printtype(t->chain, t->chain);
163 			}
164 			printf("\t%s : ", t->symbol);
165 			printtype(t, t->type);
166 			printf(";\n");
167 			break;
168 
169 		case RANGE: {
170 			long r0, r1;
171 
172 			r0 = t->symvalue.rangev.lower;
173 			r1 = t->symvalue.rangev.upper;
174 			if (t == t_char) {
175 				printf("'%c'..'%c'", (char) r0, (char) r1);
176 			} else {
177 				printf("%ld..%ld", r0, r1);
178 			}
179 			break;
180 		}
181 
182 		case PTR:
183 			putchar('^');
184 			printtype(t, t->type);
185 			break;
186 
187 		case TYPE:
188 			if (t->symbol != NIL) {
189 				printf("%s", t->symbol);
190 			} else {
191 				printtype(t, t->type);
192 			}
193 			break;
194 
195 		case SCAL:
196 			printf("(");
197 			t = t->type->chain;
198 			if (t != NIL) {
199 				printf("%s", t->symbol);
200 				t = t->chain;
201 				while (t != NIL) {
202 					printf(", %s", t->symbol);
203 					t = t->chain;
204 				}
205 			} else {
206 				panic("empty enumeration");
207 			}
208 			printf(")");
209 			break;
210 
211 		default:
212 			printf("(class %d)", t->class);
213 			break;
214 	}
215 }
216 
217 /*
218  * List the parameters of a procedure or function.
219  * No attempt is made to combine like types.
220  */
221 
222 listparams(s)
223 SYM *s;
224 {
225 	SYM *t;
226 
227 	if (s->chain != NIL) {
228 		putchar('(');
229 		for (t = s->chain; t != NIL; t = t->chain) {
230 			switch (t->class) {
231 				case REF:
232 					printf("var ");
233 					break;
234 
235 				case FPROC:
236 					printf("procedure ");
237 					break;
238 
239 				case FFUNC:
240 					printf("function ");
241 					break;
242 
243 				case VAR:
244 					break;
245 
246 				default:
247 					panic("unexpected class %d for parameter", t->class);
248 			}
249 			printf("%s : ", t->symbol);
250 			printtype(t, t->type);
251 			if (t->chain != NIL) {
252 				printf("; ");
253 			}
254 		}
255 		putchar(')');
256 	}
257 }
258