xref: /csrg-svn/old/dbx/pascal.c (revision 9675)
1*9675Slinton /* Copyright (c) 1982 Regents of the University of California */
2*9675Slinton 
3*9675Slinton static char sccsid[] = "@(#)@(#)pascal.c 1.1 12/15/82";
4*9675Slinton 
5*9675Slinton /*
6*9675Slinton  * Pascal-dependent symbol routines.
7*9675Slinton  */
8*9675Slinton 
9*9675Slinton #include "defs.h"
10*9675Slinton #include "symbols.h"
11*9675Slinton #include "pascal.h"
12*9675Slinton #include "languages.h"
13*9675Slinton #include "tree.h"
14*9675Slinton #include "eval.h"
15*9675Slinton #include "mappings.h"
16*9675Slinton #include "process.h"
17*9675Slinton #include "runtime.h"
18*9675Slinton #include "machine.h"
19*9675Slinton 
20*9675Slinton #ifndef public
21*9675Slinton #endif
22*9675Slinton 
23*9675Slinton /*
24*9675Slinton  * Initialize Pascal information.
25*9675Slinton  */
26*9675Slinton 
27*9675Slinton public pascal_init()
28*9675Slinton {
29*9675Slinton     Language lang;
30*9675Slinton 
31*9675Slinton     lang = language_define("pascal", ".p");
32*9675Slinton     language_setop(lang, L_PRINTDECL, pascal_printdecl);
33*9675Slinton     language_setop(lang, L_PRINTVAL, pascal_printval);
34*9675Slinton     language_setop(lang, L_TYPEMATCH, pascal_typematch);
35*9675Slinton }
36*9675Slinton 
37*9675Slinton /*
38*9675Slinton  * Compatible tests if two types are compatible.  The issue
39*9675Slinton  * is complicated a bit by ranges.
40*9675Slinton  *
41*9675Slinton  * Integers and reals are not compatible since they cannot always be mixed.
42*9675Slinton  */
43*9675Slinton 
44*9675Slinton public Boolean pascal_typematch(type1, type2)
45*9675Slinton Symbol type1, type2;
46*9675Slinton {
47*9675Slinton     Boolean b;
48*9675Slinton     register Symbol t1, t2;
49*9675Slinton 
50*9675Slinton     t1 = rtype(t1);
51*9675Slinton     t2 = rtype(t2);
52*9675Slinton     b = (Boolean)
53*9675Slinton 	(t1->type == t2->type and (
54*9675Slinton 	    (t1->class == RANGE and t2->class == RANGE) or
55*9675Slinton 	    (t1->class == SCAL and t2->class == CONST) or
56*9675Slinton 	    (t1->class == CONST and t2->class == SCAL) or
57*9675Slinton 	    (t1->type == t_char and t1->class == ARRAY and t2->class == ARRAY)
58*9675Slinton 	) or
59*9675Slinton 	(t1 == t_nil and t2->class == PTR) or
60*9675Slinton 	(t1->class == PTR and t2 == t_nil)
61*9675Slinton     );
62*9675Slinton     return b;
63*9675Slinton }
64*9675Slinton 
65*9675Slinton public pascal_printdecl(s)
66*9675Slinton Symbol s;
67*9675Slinton {
68*9675Slinton     register Symbol t;
69*9675Slinton     Boolean semicolon;
70*9675Slinton 
71*9675Slinton     semicolon = true;
72*9675Slinton     switch (s->class) {
73*9675Slinton 	case CONST:
74*9675Slinton 	    if (s->type->class == SCAL) {
75*9675Slinton 		printf("(enumeration constant, ord %ld)",
76*9675Slinton 		    s->symvalue.iconval);
77*9675Slinton 	    } else {
78*9675Slinton 		printf("const %s = ", symname(s));
79*9675Slinton 		printval(s);
80*9675Slinton 	    }
81*9675Slinton 	    break;
82*9675Slinton 
83*9675Slinton 	case TYPE:
84*9675Slinton 	    printf("type %s = ", symname(s));
85*9675Slinton 	    printtype(s, s->type);
86*9675Slinton 	    break;
87*9675Slinton 
88*9675Slinton 	case VAR:
89*9675Slinton 	    if (isparam(s)) {
90*9675Slinton 		printf("(parameter) %s : ", symname(s));
91*9675Slinton 	    } else {
92*9675Slinton 		printf("var %s : ", symname(s));
93*9675Slinton 	    }
94*9675Slinton 	    printtype(s, s->type);
95*9675Slinton 	    break;
96*9675Slinton 
97*9675Slinton 	case REF:
98*9675Slinton 	    printf("(var parameter) %s : ", symname(s));
99*9675Slinton 	    printtype(s, s->type);
100*9675Slinton 	    break;
101*9675Slinton 
102*9675Slinton 	case RANGE:
103*9675Slinton 	case ARRAY:
104*9675Slinton 	case RECORD:
105*9675Slinton 	case VARNT:
106*9675Slinton 	case PTR:
107*9675Slinton 	    printtype(s, s);
108*9675Slinton 	    semicolon = false;
109*9675Slinton 	    break;
110*9675Slinton 
111*9675Slinton 	case FVAR:
112*9675Slinton 	    printf("(function variable) %s : ", symname(s));
113*9675Slinton 	    printtype(s, s->type);
114*9675Slinton 	    break;
115*9675Slinton 
116*9675Slinton 	case FIELD:
117*9675Slinton 	    printf("(field) %s : ", symname(s));
118*9675Slinton 	    printtype(s, s->type);
119*9675Slinton 	    break;
120*9675Slinton 
121*9675Slinton 	case PROC:
122*9675Slinton 	    printf("procedure %s", symname(s));
123*9675Slinton 	    listparams(s);
124*9675Slinton 	    break;
125*9675Slinton 
126*9675Slinton 	case PROG:
127*9675Slinton 	    printf("program %s", symname(s));
128*9675Slinton 	    t = s->chain;
129*9675Slinton 	    if (t != nil) {
130*9675Slinton 		printf("(%s", symname(t));
131*9675Slinton 		for (t = t->chain; t != nil; t = t->chain) {
132*9675Slinton 		    printf(", %s", symname(t));
133*9675Slinton 		}
134*9675Slinton 		printf(")");
135*9675Slinton 	    }
136*9675Slinton 	    break;
137*9675Slinton 
138*9675Slinton 	case FUNC:
139*9675Slinton 	    printf("function %s", symname(s));
140*9675Slinton 	    listparams(s);
141*9675Slinton 	    printf(" : ");
142*9675Slinton 	    printtype(s, s->type);
143*9675Slinton 	    break;
144*9675Slinton 
145*9675Slinton 	default:
146*9675Slinton 	    error("class %s in printdecl", classname(s));
147*9675Slinton     }
148*9675Slinton     if (semicolon) {
149*9675Slinton 	putchar(';');
150*9675Slinton     }
151*9675Slinton     putchar('\n');
152*9675Slinton }
153*9675Slinton 
154*9675Slinton /*
155*9675Slinton  * Recursive whiz-bang procedure to print the type portion
156*9675Slinton  * of a declaration.  Doesn't work quite right for variant records.
157*9675Slinton  *
158*9675Slinton  * The symbol associated with the type is passed to allow
159*9675Slinton  * searching for type names without getting "type blah = blah".
160*9675Slinton  */
161*9675Slinton 
162*9675Slinton private printtype(s, t)
163*9675Slinton Symbol s;
164*9675Slinton Symbol t;
165*9675Slinton {
166*9675Slinton     register Symbol tmp;
167*9675Slinton 
168*9675Slinton     switch (t->class) {
169*9675Slinton 	case VAR:
170*9675Slinton 	case CONST:
171*9675Slinton 	case FUNC:
172*9675Slinton 	case PROC:
173*9675Slinton 	    panic("printtype: class %s", classname(t));
174*9675Slinton 	    break;
175*9675Slinton 
176*9675Slinton 	case ARRAY:
177*9675Slinton 	    printf("array[");
178*9675Slinton 	    tmp = t->chain;
179*9675Slinton 	    if (tmp != nil) {
180*9675Slinton 		for (;;) {
181*9675Slinton 		    printtype(tmp, tmp);
182*9675Slinton 		    tmp = tmp->chain;
183*9675Slinton 		    if (tmp == nil) {
184*9675Slinton 			break;
185*9675Slinton 		    }
186*9675Slinton 		    printf(", ");
187*9675Slinton 		}
188*9675Slinton 	    }
189*9675Slinton 	    printf("] of ");
190*9675Slinton 	    printtype(t, t->type);
191*9675Slinton 	    break;
192*9675Slinton 
193*9675Slinton 	case RECORD:
194*9675Slinton 	    printf("record\n");
195*9675Slinton 	    if (t->chain != nil) {
196*9675Slinton 		printtype(t->chain, t->chain);
197*9675Slinton 	    }
198*9675Slinton 	    printf("end");
199*9675Slinton 	    break;
200*9675Slinton 
201*9675Slinton 	case FIELD:
202*9675Slinton 	    if (t->chain != nil) {
203*9675Slinton 		printtype(t->chain, t->chain);
204*9675Slinton 	    }
205*9675Slinton 	    printf("\t%s : ", symname(t));
206*9675Slinton 	    printtype(t, t->type);
207*9675Slinton 	    printf(";\n");
208*9675Slinton 	    break;
209*9675Slinton 
210*9675Slinton 	case RANGE: {
211*9675Slinton 	    long r0, r1;
212*9675Slinton 
213*9675Slinton 	    r0 = t->symvalue.rangev.lower;
214*9675Slinton 	    r1 = t->symvalue.rangev.upper;
215*9675Slinton 	    if (t == t_char) {
216*9675Slinton 		if (r0 < 0x20 or r0 > 0x7e) {
217*9675Slinton 		    printf("%ld..", r0);
218*9675Slinton 		} else {
219*9675Slinton 		    printf("'%c'..", (char) r0);
220*9675Slinton 		}
221*9675Slinton 		if (r1 < 0x20 or r1 > 0x7e) {
222*9675Slinton 		    printf("\\%lo", r1);
223*9675Slinton 		} else {
224*9675Slinton 		    printf("'%c'", (char) r1);
225*9675Slinton 		}
226*9675Slinton 	    } else if (r0 > 0 and r1 == 0) {
227*9675Slinton 		printf("%ld byte real", r0);
228*9675Slinton 	    } else if (r0 >= 0) {
229*9675Slinton 		printf("%lu..%lu", r0, r1);
230*9675Slinton 	    } else {
231*9675Slinton 		printf("%ld..%ld", r0, r1);
232*9675Slinton 	    }
233*9675Slinton 	    break;
234*9675Slinton 	}
235*9675Slinton 
236*9675Slinton 	case PTR:
237*9675Slinton 	    putchar('*');
238*9675Slinton 	    printtype(t, t->type);
239*9675Slinton 	    break;
240*9675Slinton 
241*9675Slinton 	case TYPE:
242*9675Slinton 	    if (symname(t) != nil) {
243*9675Slinton 		printf("%s", symname(t));
244*9675Slinton 	    } else {
245*9675Slinton 		printtype(t, t->type);
246*9675Slinton 	    }
247*9675Slinton 	    break;
248*9675Slinton 
249*9675Slinton 	case SCAL:
250*9675Slinton 	    printf("(");
251*9675Slinton 	    t = t->type->chain;
252*9675Slinton 	    if (t != nil) {
253*9675Slinton 		printf("%s", symname(t));
254*9675Slinton 		t = t->chain;
255*9675Slinton 		while (t != nil) {
256*9675Slinton 		    printf(", %s", symname(t));
257*9675Slinton 		    t = t->chain;
258*9675Slinton 		}
259*9675Slinton 	    } else {
260*9675Slinton 		panic("empty enumeration");
261*9675Slinton 	    }
262*9675Slinton 	    printf(")");
263*9675Slinton 	    break;
264*9675Slinton 
265*9675Slinton 	default:
266*9675Slinton 	    printf("(class %d)", t->class);
267*9675Slinton 	    break;
268*9675Slinton     }
269*9675Slinton }
270*9675Slinton 
271*9675Slinton /*
272*9675Slinton  * List the parameters of a procedure or function.
273*9675Slinton  * No attempt is made to combine like types.
274*9675Slinton  */
275*9675Slinton 
276*9675Slinton private listparams(s)
277*9675Slinton Symbol s;
278*9675Slinton {
279*9675Slinton     Symbol t;
280*9675Slinton 
281*9675Slinton     if (s->chain != nil) {
282*9675Slinton 	putchar('(');
283*9675Slinton 	for (t = s->chain; t != nil; t = t->chain) {
284*9675Slinton 	    switch (t->class) {
285*9675Slinton 		case REF:
286*9675Slinton 		    printf("var ");
287*9675Slinton 		    break;
288*9675Slinton 
289*9675Slinton 		case FPROC:
290*9675Slinton 		    printf("procedure ");
291*9675Slinton 		    break;
292*9675Slinton 
293*9675Slinton 		case FFUNC:
294*9675Slinton 		    printf("function ");
295*9675Slinton 		    break;
296*9675Slinton 
297*9675Slinton 		case VAR:
298*9675Slinton 		    break;
299*9675Slinton 
300*9675Slinton 		default:
301*9675Slinton 		    panic("unexpected class %d for parameter", t->class);
302*9675Slinton 	    }
303*9675Slinton 	    printf("%s : ", symname(t));
304*9675Slinton 	    printtype(t, t->type);
305*9675Slinton 	    if (t->chain != nil) {
306*9675Slinton 		printf("; ");
307*9675Slinton 	    }
308*9675Slinton 	}
309*9675Slinton 	putchar(')');
310*9675Slinton     }
311*9675Slinton }
312*9675Slinton 
313*9675Slinton /*
314*9675Slinton  * Print out the value on the top of the expression stack
315*9675Slinton  * in the format for the type of the given symbol.
316*9675Slinton  */
317*9675Slinton 
318*9675Slinton public pascal_printval(s)
319*9675Slinton Symbol s;
320*9675Slinton {
321*9675Slinton     Symbol t;
322*9675Slinton     Address a;
323*9675Slinton     int len;
324*9675Slinton     double r;
325*9675Slinton 
326*9675Slinton     if (s->class == REF) {
327*9675Slinton 	s = s->type;
328*9675Slinton     }
329*9675Slinton     switch (s->class) {
330*9675Slinton 	case TYPE:
331*9675Slinton 	    pascal_printval(s->type);
332*9675Slinton 	    break;
333*9675Slinton 
334*9675Slinton 	case ARRAY:
335*9675Slinton 	    t = rtype(s->type);
336*9675Slinton 	    if (t==t_char or (t->class==RANGE and t->type==t_char)) {
337*9675Slinton 		len = size(s);
338*9675Slinton 		sp -= len;
339*9675Slinton 		printf("'%.*s'", len, sp);
340*9675Slinton 		break;
341*9675Slinton 	    } else {
342*9675Slinton 		printarray(s);
343*9675Slinton 	    }
344*9675Slinton 	    break;
345*9675Slinton 
346*9675Slinton 	case RECORD:
347*9675Slinton 	    printrecord(s);
348*9675Slinton 	    break;
349*9675Slinton 
350*9675Slinton 	case VARNT:
351*9675Slinton 	    error("can't print out variant records");
352*9675Slinton 	    break;
353*9675Slinton 
354*9675Slinton 
355*9675Slinton 	case RANGE:
356*9675Slinton 	    if (s == t_boolean) {
357*9675Slinton 		printf(((Boolean) popsmall(s)) == true ? "true" : "false");
358*9675Slinton 	    } else if (s == t_char) {
359*9675Slinton 		printf("'%c'", pop(char));
360*9675Slinton 	    } else if (s->symvalue.rangev.upper == 0 and
361*9675Slinton 			s->symvalue.rangev.lower > 0) {
362*9675Slinton 		switch (s->symvalue.rangev.lower) {
363*9675Slinton 		    case sizeof(float):
364*9675Slinton 			prtreal(pop(float));
365*9675Slinton 			break;
366*9675Slinton 
367*9675Slinton 		    case sizeof(double):
368*9675Slinton 			prtreal(pop(double));
369*9675Slinton 			break;
370*9675Slinton 
371*9675Slinton 		    default:
372*9675Slinton 			panic("bad real size %d", s->symvalue.rangev.lower);
373*9675Slinton 			break;
374*9675Slinton 		}
375*9675Slinton 	    } else if (s->symvalue.rangev.lower >= 0) {
376*9675Slinton 		printf("%lu", popsmall(s));
377*9675Slinton 	    } else {
378*9675Slinton 		printf("%ld", popsmall(s));
379*9675Slinton 	    }
380*9675Slinton 	    break;
381*9675Slinton 
382*9675Slinton 	case FILET:
383*9675Slinton 	case PTR: {
384*9675Slinton 	    Address addr;
385*9675Slinton 
386*9675Slinton 	    addr = pop(Address);
387*9675Slinton 	    if (addr == 0) {
388*9675Slinton 		printf("0, (nil)");
389*9675Slinton 	    } else {
390*9675Slinton 		printf("0x%x, 0%o", addr, addr);
391*9675Slinton 	    }
392*9675Slinton 	    break;
393*9675Slinton 	}
394*9675Slinton 
395*9675Slinton 	case FIELD:
396*9675Slinton 	    error("missing record specification");
397*9675Slinton 	    break;
398*9675Slinton 
399*9675Slinton 	case SCAL: {
400*9675Slinton 	    int scalar;
401*9675Slinton 	    Boolean found;
402*9675Slinton 
403*9675Slinton 	    scalar = popsmall(s);
404*9675Slinton 	    found = false;
405*9675Slinton 	    for (t = s->chain; t != nil; t = t->chain) {
406*9675Slinton 		if (t->symvalue.iconval == scalar) {
407*9675Slinton 		    printf("%s", symname(t));
408*9675Slinton 		    found = true;
409*9675Slinton 		    break;
410*9675Slinton 		}
411*9675Slinton 	    }
412*9675Slinton 	    if (not found) {
413*9675Slinton 		printf("(scalar = %d)", scalar);
414*9675Slinton 	    }
415*9675Slinton 	    break;
416*9675Slinton 	}
417*9675Slinton 
418*9675Slinton 	case FPROC:
419*9675Slinton 	case FFUNC:
420*9675Slinton 	{
421*9675Slinton 	    Address a;
422*9675Slinton 
423*9675Slinton 	    a = fparamaddr(pop(long));
424*9675Slinton 	    t = whatblock(a);
425*9675Slinton 	    if (t == nil) {
426*9675Slinton 		printf("(proc %d)", a);
427*9675Slinton 	    } else {
428*9675Slinton 		printf("%s", symname(t));
429*9675Slinton 	    }
430*9675Slinton 	    break;
431*9675Slinton 	}
432*9675Slinton 
433*9675Slinton 	default:
434*9675Slinton 	    if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) {
435*9675Slinton 		panic("printval: bad class %d", ord(s->class));
436*9675Slinton 	    }
437*9675Slinton 	    error("don't know how to print a %s", classname(s));
438*9675Slinton 	    /* NOTREACHED */
439*9675Slinton     }
440*9675Slinton }
441