xref: /csrg-svn/old/dbx/pascal.c (revision 18228)
19675Slinton /* Copyright (c) 1982 Regents of the University of California */
29675Slinton 
3*18228Slinton static	char sccsid[] = "@(#)pascal.c	1.4 (Berkeley) 03/01/85";
49675Slinton 
5*18228Slinton static char rcsid[] = "$Header: pascal.c,v 1.5 84/12/26 10:41:18 linton Exp $";
6*18228Slinton 
79675Slinton /*
89675Slinton  * Pascal-dependent symbol routines.
99675Slinton  */
109675Slinton 
119675Slinton #include "defs.h"
129675Slinton #include "symbols.h"
139675Slinton #include "pascal.h"
149675Slinton #include "languages.h"
159675Slinton #include "tree.h"
169675Slinton #include "eval.h"
179675Slinton #include "mappings.h"
189675Slinton #include "process.h"
199675Slinton #include "runtime.h"
209675Slinton #include "machine.h"
219675Slinton 
229675Slinton #ifndef public
239675Slinton #endif
249675Slinton 
2516615Ssam private Language pasc;
26*18228Slinton private boolean initialized;
2716615Ssam 
289675Slinton /*
299675Slinton  * Initialize Pascal information.
309675Slinton  */
319675Slinton 
329675Slinton public pascal_init()
339675Slinton {
3416615Ssam     pasc = language_define("pascal", ".p");
3516615Ssam     language_setop(pasc, L_PRINTDECL, pascal_printdecl);
3616615Ssam     language_setop(pasc, L_PRINTVAL, pascal_printval);
3716615Ssam     language_setop(pasc, L_TYPEMATCH, pascal_typematch);
3816615Ssam     language_setop(pasc, L_BUILDAREF, pascal_buildaref);
3916615Ssam     language_setop(pasc, L_EVALAREF, pascal_evalaref);
4016615Ssam     language_setop(pasc, L_MODINIT, pascal_modinit);
4116615Ssam     language_setop(pasc, L_HASMODULES, pascal_hasmodules);
4216615Ssam     language_setop(pasc, L_PASSADDR, pascal_passaddr);
43*18228Slinton     initialized = false;
449675Slinton }
459675Slinton 
469675Slinton /*
47*18228Slinton  * Typematch tests if two types are compatible.  The issue
48*18228Slinton  * is a bit complicated, so several subfunctions are used for
49*18228Slinton  * various kinds of compatibility.
509675Slinton  */
519675Slinton 
52*18228Slinton private boolean builtinmatch (t1, t2)
53*18228Slinton register Symbol t1, t2;
549675Slinton {
55*18228Slinton     boolean b;
569675Slinton 
57*18228Slinton     b = (boolean) (
58*18228Slinton 	(
59*18228Slinton 	    t2 == t_int->type and
60*18228Slinton 	    t1->class == RANGE and istypename(t1->type, "integer")
61*18228Slinton 	) or (
62*18228Slinton 	    t2 == t_char->type and
63*18228Slinton 	    t1->class == RANGE and istypename(t1->type, "char")
64*18228Slinton 	) or (
65*18228Slinton 	    t2 == t_real->type and
66*18228Slinton 	    t1->class == RANGE and istypename(t1->type, "real")
67*18228Slinton 	) or (
68*18228Slinton 	    t2 == t_boolean->type and
69*18228Slinton 	    t1->class == RANGE and istypename(t1->type, "boolean")
70*18228Slinton 	)
71*18228Slinton     );
72*18228Slinton     return b;
73*18228Slinton }
74*18228Slinton 
75*18228Slinton private boolean rangematch (t1, t2)
76*18228Slinton register Symbol t1, t2;
77*18228Slinton {
78*18228Slinton     boolean b;
79*18228Slinton     register Symbol rt1, rt2;
80*18228Slinton 
81*18228Slinton     if (t1->class == RANGE and t2->class == RANGE) {
82*18228Slinton 	rt1 = rtype(t1->type);
83*18228Slinton 	rt2 = rtype(t2->type);
84*18228Slinton 	b = (boolean) (rt1->type == rt2->type);
85*18228Slinton     } else {
86*18228Slinton 	b = false;
87*18228Slinton     }
88*18228Slinton     return b;
89*18228Slinton }
90*18228Slinton 
91*18228Slinton private boolean nilMatch (t1, t2)
92*18228Slinton register Symbol t1, t2;
93*18228Slinton {
94*18228Slinton     boolean b;
95*18228Slinton 
96*18228Slinton     b = (boolean) (
979675Slinton 	(t1 == t_nil and t2->class == PTR) or
989675Slinton 	(t1->class == PTR and t2 == t_nil)
999675Slinton     );
1009675Slinton     return b;
1019675Slinton }
1029675Slinton 
103*18228Slinton private boolean enumMatch (t1, t2)
104*18228Slinton register Symbol t1, t2;
105*18228Slinton {
106*18228Slinton     boolean b;
107*18228Slinton 
108*18228Slinton     b = (boolean) (
109*18228Slinton 	(t1->class == SCAL and t2->class == CONST and t2->type == t1) or
110*18228Slinton 	(t1->class == CONST and t2->class == SCAL and t1->type == t2)
111*18228Slinton     );
112*18228Slinton     return b;
113*18228Slinton }
114*18228Slinton 
115*18228Slinton private boolean isConstString (t)
116*18228Slinton register Symbol t;
117*18228Slinton {
118*18228Slinton     boolean b;
119*18228Slinton 
120*18228Slinton     b = (boolean) (
121*18228Slinton 	t->language == primlang and t->class == ARRAY and t->type == t_char
122*18228Slinton     );
123*18228Slinton     return b;
124*18228Slinton }
125*18228Slinton 
126*18228Slinton private boolean stringArrayMatch (t1, t2)
127*18228Slinton register Symbol t1, t2;
128*18228Slinton {
129*18228Slinton     boolean b;
130*18228Slinton 
131*18228Slinton     b = (boolean) (
132*18228Slinton 	(
133*18228Slinton 	    isConstString(t1) and
134*18228Slinton 	    t2->class == ARRAY and compatible(t2->type, t_char->type)
135*18228Slinton 	) or (
136*18228Slinton 	    isConstString(t2) and
137*18228Slinton 	    t1->class == ARRAY and compatible(t1->type, t_char->type)
138*18228Slinton 	)
139*18228Slinton     );
140*18228Slinton     return b;
141*18228Slinton }
142*18228Slinton 
143*18228Slinton public boolean pascal_typematch (type1, type2)
144*18228Slinton Symbol type1, type2;
145*18228Slinton {
146*18228Slinton     boolean b;
147*18228Slinton     Symbol t1, t2, tmp;
148*18228Slinton 
149*18228Slinton     t1 = rtype(type1);
150*18228Slinton     t2 = rtype(type2);
151*18228Slinton     if (t1 == t2) {
152*18228Slinton 	b = true;
153*18228Slinton     } else {
154*18228Slinton 	if (t1 == t_char->type or t1 == t_int->type or
155*18228Slinton 	    t1 == t_real->type or t1 == t_boolean->type
156*18228Slinton 	) {
157*18228Slinton 	    tmp = t1;
158*18228Slinton 	    t1 = t2;
159*18228Slinton 	    t2 = tmp;
160*18228Slinton 	}
161*18228Slinton 	b = (Boolean) (
162*18228Slinton 	    builtinmatch(t1, t2) or rangematch(t1, t2) or
163*18228Slinton 	    nilMatch(t1, t2) or enumMatch(t1, t2) or
164*18228Slinton 	    stringArrayMatch(t1, t2)
165*18228Slinton 	);
166*18228Slinton     }
167*18228Slinton     return b;
168*18228Slinton }
169*18228Slinton 
170*18228Slinton /*
171*18228Slinton  * Indent n spaces.
172*18228Slinton  */
173*18228Slinton 
174*18228Slinton private indent (n)
175*18228Slinton int n;
176*18228Slinton {
177*18228Slinton     if (n > 0) {
178*18228Slinton 	printf("%*c", n, ' ');
179*18228Slinton     }
180*18228Slinton }
181*18228Slinton 
182*18228Slinton public pascal_printdecl (s)
1839675Slinton Symbol s;
1849675Slinton {
1859675Slinton     register Symbol t;
1869675Slinton     Boolean semicolon;
1879675Slinton 
1889675Slinton     semicolon = true;
189*18228Slinton     if (s->class == TYPEREF) {
190*18228Slinton 	resolveRef(t);
191*18228Slinton     }
1929675Slinton     switch (s->class) {
1939675Slinton 	case CONST:
1949675Slinton 	    if (s->type->class == SCAL) {
195*18228Slinton 		semicolon = false;
196*18228Slinton 		printf("enum constant, ord ");
197*18228Slinton 		eval(s->symvalue.constval);
198*18228Slinton 		pascal_printval(s);
1999675Slinton 	    } else {
2009675Slinton 		printf("const %s = ", symname(s));
201*18228Slinton 		eval(s->symvalue.constval);
202*18228Slinton 		pascal_printval(s);
2039675Slinton 	    }
2049675Slinton 	    break;
2059675Slinton 
2069675Slinton 	case TYPE:
2079675Slinton 	    printf("type %s = ", symname(s));
208*18228Slinton 	    printtype(s, s->type, 0);
2099675Slinton 	    break;
2109675Slinton 
211*18228Slinton 	case TYPEREF:
212*18228Slinton 	    printf("type %s", symname(s));
213*18228Slinton 	    break;
214*18228Slinton 
2159675Slinton 	case VAR:
2169675Slinton 	    if (isparam(s)) {
2179675Slinton 		printf("(parameter) %s : ", symname(s));
2189675Slinton 	    } else {
2199675Slinton 		printf("var %s : ", symname(s));
2209675Slinton 	    }
221*18228Slinton 	    printtype(s, s->type, 0);
2229675Slinton 	    break;
2239675Slinton 
2249675Slinton 	case REF:
2259675Slinton 	    printf("(var parameter) %s : ", symname(s));
226*18228Slinton 	    printtype(s, s->type, 0);
2279675Slinton 	    break;
2289675Slinton 
2299675Slinton 	case RANGE:
2309675Slinton 	case ARRAY:
2319675Slinton 	case RECORD:
2329675Slinton 	case VARNT:
2339675Slinton 	case PTR:
234*18228Slinton 	case FILET:
235*18228Slinton 	    printtype(s, s, 0);
2369675Slinton 	    semicolon = false;
2379675Slinton 	    break;
2389675Slinton 
2399675Slinton 	case FVAR:
2409675Slinton 	    printf("(function variable) %s : ", symname(s));
241*18228Slinton 	    printtype(s, s->type, 0);
2429675Slinton 	    break;
2439675Slinton 
2449675Slinton 	case FIELD:
2459675Slinton 	    printf("(field) %s : ", symname(s));
246*18228Slinton 	    printtype(s, s->type, 0);
2479675Slinton 	    break;
2489675Slinton 
2499675Slinton 	case PROC:
2509675Slinton 	    printf("procedure %s", symname(s));
2519675Slinton 	    listparams(s);
2529675Slinton 	    break;
2539675Slinton 
2549675Slinton 	case PROG:
2559675Slinton 	    printf("program %s", symname(s));
256*18228Slinton 	    listparams(s);
2579675Slinton 	    break;
2589675Slinton 
2599675Slinton 	case FUNC:
2609675Slinton 	    printf("function %s", symname(s));
2619675Slinton 	    listparams(s);
2629675Slinton 	    printf(" : ");
263*18228Slinton 	    printtype(s, s->type, 0);
2649675Slinton 	    break;
2659675Slinton 
266*18228Slinton 	case MODULE:
267*18228Slinton 	    printf("module %s", symname(s));
268*18228Slinton 	    break;
269*18228Slinton 
270*18228Slinton 	  /*
271*18228Slinton 	   * the parameter list of the following should be printed
272*18228Slinton 	   * eventually
273*18228Slinton 	   */
274*18228Slinton 	case  FPROC:
275*18228Slinton 	    printf("procedure %s()", symname(s));
276*18228Slinton 	    break;
277*18228Slinton 
278*18228Slinton 	case FFUNC:
279*18228Slinton 	    printf("function %s()", symname(s));
280*18228Slinton 	    break;
281*18228Slinton 
2829675Slinton 	default:
283*18228Slinton 	    printf("%s : (class %s)", symname(s), classname(s));
284*18228Slinton 	    break;
2859675Slinton     }
2869675Slinton     if (semicolon) {
2879675Slinton 	putchar(';');
2889675Slinton     }
2899675Slinton     putchar('\n');
2909675Slinton }
2919675Slinton 
2929675Slinton /*
2939675Slinton  * Recursive whiz-bang procedure to print the type portion
294*18228Slinton  * of a declaration.
2959675Slinton  *
2969675Slinton  * The symbol associated with the type is passed to allow
2979675Slinton  * searching for type names without getting "type blah = blah".
2989675Slinton  */
2999675Slinton 
300*18228Slinton private printtype (s, t, n)
3019675Slinton Symbol s;
3029675Slinton Symbol t;
303*18228Slinton int n;
3049675Slinton {
3059675Slinton     register Symbol tmp;
3069675Slinton 
307*18228Slinton     if (t->class == TYPEREF) {
308*18228Slinton 	resolveRef(t);
309*18228Slinton     }
3109675Slinton     switch (t->class) {
3119675Slinton 	case VAR:
3129675Slinton 	case CONST:
3139675Slinton 	case FUNC:
3149675Slinton 	case PROC:
3159675Slinton 	    panic("printtype: class %s", classname(t));
3169675Slinton 	    break;
3179675Slinton 
3189675Slinton 	case ARRAY:
3199675Slinton 	    printf("array[");
3209675Slinton 	    tmp = t->chain;
3219675Slinton 	    if (tmp != nil) {
3229675Slinton 		for (;;) {
323*18228Slinton 		    printtype(tmp, tmp, n);
3249675Slinton 		    tmp = tmp->chain;
3259675Slinton 		    if (tmp == nil) {
3269675Slinton 			break;
3279675Slinton 		    }
3289675Slinton 		    printf(", ");
3299675Slinton 		}
3309675Slinton 	    }
3319675Slinton 	    printf("] of ");
332*18228Slinton 	    printtype(t, t->type, n);
3339675Slinton 	    break;
3349675Slinton 
3359675Slinton 	case RECORD:
336*18228Slinton 	    printRecordDecl(t, n);
3379675Slinton 	    break;
3389675Slinton 
3399675Slinton 	case FIELD:
3409675Slinton 	    if (t->chain != nil) {
341*18228Slinton 		printtype(t->chain, t->chain, n);
3429675Slinton 	    }
3439675Slinton 	    printf("\t%s : ", symname(t));
344*18228Slinton 	    printtype(t, t->type, n);
3459675Slinton 	    printf(";\n");
3469675Slinton 	    break;
3479675Slinton 
348*18228Slinton 	case RANGE:
349*18228Slinton 	    printRangeDecl(t);
3509675Slinton 	    break;
3519675Slinton 
3529675Slinton 	case PTR:
353*18228Slinton 	    printf("^");
354*18228Slinton 	    printtype(t, t->type, n);
3559675Slinton 	    break;
3569675Slinton 
3579675Slinton 	case TYPE:
358*18228Slinton 	    if (t->name != nil and ident(t->name)[0] != '\0') {
359*18228Slinton 		printname(stdout, t);
3609675Slinton 	    } else {
361*18228Slinton 		printtype(t, t->type, n);
3629675Slinton 	    }
3639675Slinton 	    break;
3649675Slinton 
3659675Slinton 	case SCAL:
366*18228Slinton 	    printEnumDecl(t, n);
3679675Slinton 	    break;
3689675Slinton 
369*18228Slinton 	case SET:
370*18228Slinton 	    printf("set of ");
371*18228Slinton 	    printtype(t, t->type, n);
372*18228Slinton 	    break;
373*18228Slinton 
374*18228Slinton 	case FILET:
375*18228Slinton 	    printf("file of ");
376*18228Slinton 	    printtype(t, t->type, n);
377*18228Slinton 	    break;
378*18228Slinton 
379*18228Slinton 	case TYPEREF:
380*18228Slinton 	    break;
381*18228Slinton 
382*18228Slinton 	case FPROC:
383*18228Slinton 	    printf("procedure");
384*18228Slinton 	    break;
385*18228Slinton 
386*18228Slinton 	case FFUNC:
387*18228Slinton 	    printf("function");
388*18228Slinton 	    break;
389*18228Slinton 
3909675Slinton 	default:
3919675Slinton 	    printf("(class %d)", t->class);
3929675Slinton 	    break;
3939675Slinton     }
3949675Slinton }
3959675Slinton 
3969675Slinton /*
397*18228Slinton  * Print out a record declaration.
398*18228Slinton  */
399*18228Slinton 
400*18228Slinton private printRecordDecl (t, n)
401*18228Slinton Symbol t;
402*18228Slinton int n;
403*18228Slinton {
404*18228Slinton     register Symbol f;
405*18228Slinton 
406*18228Slinton     if (t->chain == nil) {
407*18228Slinton 	printf("record end");
408*18228Slinton     } else {
409*18228Slinton 	printf("record\n");
410*18228Slinton 	for (f = t->chain; f != nil; f = f->chain) {
411*18228Slinton 	    indent(n+4);
412*18228Slinton 	    printf("%s : ", symname(f));
413*18228Slinton 	    printtype(f->type, f->type, n+4);
414*18228Slinton 	    printf(";\n");
415*18228Slinton 	}
416*18228Slinton 	indent(n);
417*18228Slinton 	printf("end");
418*18228Slinton     }
419*18228Slinton }
420*18228Slinton 
421*18228Slinton /*
422*18228Slinton  * Print out the declaration of a range type.
423*18228Slinton  */
424*18228Slinton 
425*18228Slinton private printRangeDecl (t)
426*18228Slinton Symbol t;
427*18228Slinton {
428*18228Slinton     long r0, r1;
429*18228Slinton 
430*18228Slinton     r0 = t->symvalue.rangev.lower;
431*18228Slinton     r1 = t->symvalue.rangev.upper;
432*18228Slinton     if (t == t_char or istypename(t, "char")) {
433*18228Slinton 	if (r0 < 0x20 or r0 > 0x7e) {
434*18228Slinton 	    printf("%ld..", r0);
435*18228Slinton 	} else {
436*18228Slinton 	    printf("'%c'..", (char) r0);
437*18228Slinton 	}
438*18228Slinton 	if (r1 < 0x20 or r1 > 0x7e) {
439*18228Slinton 	    printf("\\%lo", r1);
440*18228Slinton 	} else {
441*18228Slinton 	    printf("'%c'", (char) r1);
442*18228Slinton 	}
443*18228Slinton     } else if (r0 > 0 and r1 == 0) {
444*18228Slinton 	printf("%ld byte real", r0);
445*18228Slinton     } else if (r0 >= 0) {
446*18228Slinton 	printf("%lu..%lu", r0, r1);
447*18228Slinton     } else {
448*18228Slinton 	printf("%ld..%ld", r0, r1);
449*18228Slinton     }
450*18228Slinton }
451*18228Slinton 
452*18228Slinton /*
453*18228Slinton  * Print out an enumeration declaration.
454*18228Slinton  */
455*18228Slinton 
456*18228Slinton private printEnumDecl (e, n)
457*18228Slinton Symbol e;
458*18228Slinton int n;
459*18228Slinton {
460*18228Slinton     Symbol t;
461*18228Slinton 
462*18228Slinton     printf("(");
463*18228Slinton     t = e->chain;
464*18228Slinton     if (t != nil) {
465*18228Slinton 	printf("%s", symname(t));
466*18228Slinton 	t = t->chain;
467*18228Slinton 	while (t != nil) {
468*18228Slinton 	    printf(", %s", symname(t));
469*18228Slinton 	    t = t->chain;
470*18228Slinton 	}
471*18228Slinton     }
472*18228Slinton     printf(")");
473*18228Slinton }
474*18228Slinton 
475*18228Slinton /*
4769675Slinton  * List the parameters of a procedure or function.
4779675Slinton  * No attempt is made to combine like types.
4789675Slinton  */
4799675Slinton 
4809675Slinton private listparams(s)
4819675Slinton Symbol s;
4829675Slinton {
4839675Slinton     Symbol t;
4849675Slinton 
4859675Slinton     if (s->chain != nil) {
4869675Slinton 	putchar('(');
4879675Slinton 	for (t = s->chain; t != nil; t = t->chain) {
4889675Slinton 	    switch (t->class) {
4899675Slinton 		case REF:
4909675Slinton 		    printf("var ");
4919675Slinton 		    break;
4929675Slinton 
4939675Slinton 		case VAR:
4949675Slinton 		    break;
4959675Slinton 
4969675Slinton 		default:
4979675Slinton 		    panic("unexpected class %d for parameter", t->class);
4989675Slinton 	    }
4999675Slinton 	    printf("%s : ", symname(t));
5009675Slinton 	    printtype(t, t->type);
5019675Slinton 	    if (t->chain != nil) {
5029675Slinton 		printf("; ");
5039675Slinton 	    }
5049675Slinton 	}
5059675Slinton 	putchar(')');
5069675Slinton     }
5079675Slinton }
5089675Slinton 
5099675Slinton /*
5109675Slinton  * Print out the value on the top of the expression stack
5119675Slinton  * in the format for the type of the given symbol.
5129675Slinton  */
5139675Slinton 
514*18228Slinton public pascal_printval (s)
5159675Slinton Symbol s;
5169675Slinton {
517*18228Slinton     prval(s, size(s));
518*18228Slinton }
519*18228Slinton 
520*18228Slinton private prval (s, n)
521*18228Slinton Symbol s;
522*18228Slinton integer n;
523*18228Slinton {
5249675Slinton     Symbol t;
5259675Slinton     Address a;
526*18228Slinton     integer len;
5279675Slinton     double r;
528*18228Slinton     integer i;
5299675Slinton 
530*18228Slinton     if (s->class == TYPEREF) {
531*18228Slinton 	resolveRef(s);
532*18228Slinton     }
5339675Slinton     switch (s->class) {
53416615Ssam 	case CONST:
5359675Slinton 	case TYPE:
536*18228Slinton 	case REF:
53716615Ssam 	case VAR:
53816615Ssam 	case FVAR:
53916615Ssam 	case TAG:
540*18228Slinton 	    prval(s->type, n);
541*18228Slinton 	    break;
542*18228Slinton 
54316615Ssam 	case FIELD:
544*18228Slinton 		prval(s->type, n);
5459675Slinton 	    break;
5469675Slinton 
5479675Slinton 	case ARRAY:
5489675Slinton 	    t = rtype(s->type);
549*18228Slinton 	    if (t == t_char->type or
550*18228Slinton 		(t->class == RANGE and istypename(t->type, "char"))
551*18228Slinton 	    ) {
5529675Slinton 		len = size(s);
5539675Slinton 		sp -= len;
5549675Slinton 		printf("'%.*s'", len, sp);
5559675Slinton 		break;
5569675Slinton 	    } else {
5579675Slinton 		printarray(s);
5589675Slinton 	    }
5599675Slinton 	    break;
5609675Slinton 
5619675Slinton 	case RECORD:
5629675Slinton 	    printrecord(s);
5639675Slinton 	    break;
5649675Slinton 
5659675Slinton 	case VARNT:
566*18228Slinton 	    printf("[variant]");
5679675Slinton 	    break;
5689675Slinton 
5699675Slinton 	case RANGE:
570*18228Slinton 	    printrange(s, n);
571*18228Slinton 	    break;
5729675Slinton 
573*18228Slinton 	case FILET:
574*18228Slinton 	    a = pop(Address);
575*18228Slinton 	    if (a == 0) {
576*18228Slinton 		printf("nil");
5779675Slinton 	    } else {
578*18228Slinton 		printf("0x%x", a);
5799675Slinton 	    }
5809675Slinton 	    break;
5819675Slinton 
582*18228Slinton 	case PTR:
583*18228Slinton 	    a = pop(Address);
584*18228Slinton 	    if (a == 0) {
585*18228Slinton 		printf("nil");
5869675Slinton 	    } else {
587*18228Slinton 		printf("0x%x", a);
5889675Slinton 	    }
5899675Slinton 	    break;
5909675Slinton 
591*18228Slinton 	case SCAL:
592*18228Slinton 	    i = 0;
593*18228Slinton 	    popn(n, &i);
594*18228Slinton 	    if (s->symvalue.iconval < 256) {
595*18228Slinton 		i &= 0xff;
596*18228Slinton 	    } else if (s->symvalue.iconval < 65536) {
597*18228Slinton 		i &= 0xffff;
5989675Slinton 	    }
599*18228Slinton 	    printEnum(i, s);
6009675Slinton 	    break;
6019675Slinton 
6029675Slinton 	case FPROC:
6039675Slinton 	case FFUNC:
604*18228Slinton 	    a = pop(long);
6059675Slinton 	    t = whatblock(a);
6069675Slinton 	    if (t == nil) {
607*18228Slinton 		printf("(proc 0x%x)", a);
6089675Slinton 	    } else {
6099675Slinton 		printf("%s", symname(t));
6109675Slinton 	    }
6119675Slinton 	    break;
6129675Slinton 
613*18228Slinton 	case SET:
614*18228Slinton 	    printSet(s);
615*18228Slinton 	    break;
616*18228Slinton 
6179675Slinton 	default:
6189675Slinton 	    if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) {
6199675Slinton 		panic("printval: bad class %d", ord(s->class));
6209675Slinton 	    }
621*18228Slinton 	    printf("[%s]", classname(s));
622*18228Slinton 	    break;
6239675Slinton     }
6249675Slinton }
62516615Ssam 
62616615Ssam /*
627*18228Slinton  * Print out the value of a scalar (non-enumeration) type.
628*18228Slinton  */
629*18228Slinton 
630*18228Slinton private printrange (s, n)
631*18228Slinton Symbol s;
632*18228Slinton integer n;
633*18228Slinton {
634*18228Slinton     double d;
635*18228Slinton     float f;
636*18228Slinton     integer i;
637*18228Slinton 
638*18228Slinton     if (s->symvalue.rangev.upper == 0 and s->symvalue.rangev.lower > 0) {
639*18228Slinton 	if (n == sizeof(float)) {
640*18228Slinton 	    popn(n, &f);
641*18228Slinton 	    d = f;
642*18228Slinton 	} else {
643*18228Slinton 	    popn(n, &d);
644*18228Slinton 	}
645*18228Slinton 	prtreal(d);
646*18228Slinton     } else {
647*18228Slinton 	i = 0;
648*18228Slinton 	popn(n, &i);
649*18228Slinton 	printRangeVal(i, s);
650*18228Slinton     }
651*18228Slinton }
652*18228Slinton 
653*18228Slinton /*
654*18228Slinton  * Print out a set.
655*18228Slinton  */
656*18228Slinton 
657*18228Slinton private printSet (s)
658*18228Slinton Symbol s;
659*18228Slinton {
660*18228Slinton     Symbol t;
661*18228Slinton     integer nbytes;
662*18228Slinton 
663*18228Slinton     nbytes = size(s);
664*18228Slinton     t = rtype(s->type);
665*18228Slinton     printf("[");
666*18228Slinton     sp -= nbytes;
667*18228Slinton     if (t->class == SCAL) {
668*18228Slinton 	printSetOfEnum(t);
669*18228Slinton     } else if (t->class == RANGE) {
670*18228Slinton 	printSetOfRange(t);
671*18228Slinton     } else {
672*18228Slinton 	error("internal error: expected range or enumerated base type for set");
673*18228Slinton     }
674*18228Slinton     printf("]");
675*18228Slinton }
676*18228Slinton 
677*18228Slinton /*
678*18228Slinton  * Print out a set of an enumeration.
679*18228Slinton  */
680*18228Slinton 
681*18228Slinton private printSetOfEnum (t)
682*18228Slinton Symbol t;
683*18228Slinton {
684*18228Slinton     register Symbol e;
685*18228Slinton     register integer i, j, *p;
686*18228Slinton     boolean first;
687*18228Slinton 
688*18228Slinton     p = (int *) sp;
689*18228Slinton     i = *p;
690*18228Slinton     j = 0;
691*18228Slinton     e = t->chain;
692*18228Slinton     first = true;
693*18228Slinton     while (e != nil) {
694*18228Slinton 	if ((i&1) == 1) {
695*18228Slinton 	    if (first) {
696*18228Slinton 		first = false;
697*18228Slinton 		printf("%s", symname(e));
698*18228Slinton 	    } else {
699*18228Slinton 		printf(", %s", symname(e));
700*18228Slinton 	    }
701*18228Slinton 	}
702*18228Slinton 	i >>= 1;
703*18228Slinton 	++j;
704*18228Slinton 	if (j >= sizeof(integer)*BITSPERBYTE) {
705*18228Slinton 	    j = 0;
706*18228Slinton 	    ++p;
707*18228Slinton 	    i = *p;
708*18228Slinton 	}
709*18228Slinton 	e = e->chain;
710*18228Slinton     }
711*18228Slinton }
712*18228Slinton 
713*18228Slinton /*
714*18228Slinton  * Print out a set of a subrange type.
715*18228Slinton  */
716*18228Slinton 
717*18228Slinton private printSetOfRange (t)
718*18228Slinton Symbol t;
719*18228Slinton {
720*18228Slinton     register integer i, j, *p;
721*18228Slinton     long v;
722*18228Slinton     boolean first;
723*18228Slinton 
724*18228Slinton     p = (int *) sp;
725*18228Slinton     i = *p;
726*18228Slinton     j = 0;
727*18228Slinton     v = t->symvalue.rangev.lower;
728*18228Slinton     first = true;
729*18228Slinton     while (v <= t->symvalue.rangev.upper) {
730*18228Slinton 	if ((i&1) == 1) {
731*18228Slinton 	    if (first) {
732*18228Slinton 		first = false;
733*18228Slinton 		printf("%ld", v);
734*18228Slinton 	    } else {
735*18228Slinton 		printf(", %ld", v);
736*18228Slinton 	    }
737*18228Slinton 	}
738*18228Slinton 	i >>= 1;
739*18228Slinton 	++j;
740*18228Slinton 	if (j >= sizeof(integer)*BITSPERBYTE) {
741*18228Slinton 	    j = 0;
742*18228Slinton 	    ++p;
743*18228Slinton 	    i = *p;
744*18228Slinton 	}
745*18228Slinton 	++v;
746*18228Slinton     }
747*18228Slinton }
748*18228Slinton 
749*18228Slinton /*
75016615Ssam  * Construct a node for subscripting.
75116615Ssam  */
75216615Ssam 
75316615Ssam public Node pascal_buildaref (a, slist)
75416615Ssam Node a, slist;
75516615Ssam {
75616615Ssam     register Symbol t;
75716615Ssam     register Node p;
75816615Ssam     Symbol etype, atype, eltype;
75916615Ssam     Node esub, r;
76016615Ssam 
76116615Ssam     t = rtype(a->nodetype);
76216615Ssam     if (t->class != ARRAY) {
76316615Ssam 	beginerrmsg();
76416615Ssam 	prtree(stderr, a);
76516615Ssam 	fprintf(stderr, " is not an array");
76616615Ssam 	enderrmsg();
76716615Ssam     } else {
768*18228Slinton 	r = a;
769*18228Slinton 	eltype = t->type;
77016615Ssam 	p = slist;
77116615Ssam 	t = t->chain;
77216615Ssam 	for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
77316615Ssam 	    esub = p->value.arg[0];
77416615Ssam 	    etype = rtype(esub->nodetype);
77516615Ssam 	    atype = rtype(t);
77616615Ssam 	    if (not compatible(atype, etype)) {
77716615Ssam 		beginerrmsg();
77816615Ssam 		fprintf(stderr, "subscript ");
77916615Ssam 		prtree(stderr, esub);
78016615Ssam 		fprintf(stderr, " is the wrong type");
78116615Ssam 		enderrmsg();
78216615Ssam 	    }
78316615Ssam 	    r = build(O_INDEX, r, esub);
78416615Ssam 	    r->nodetype = eltype;
78516615Ssam 	}
78616615Ssam 	if (p != nil or t != nil) {
78716615Ssam 	    beginerrmsg();
78816615Ssam 	    if (p != nil) {
78916615Ssam 		fprintf(stderr, "too many subscripts for ");
79016615Ssam 	    } else {
79116615Ssam 		fprintf(stderr, "not enough subscripts for ");
79216615Ssam 	    }
79316615Ssam 	    prtree(stderr, a);
79416615Ssam 	    enderrmsg();
79516615Ssam 	}
79616615Ssam     }
79716615Ssam     return r;
79816615Ssam }
79916615Ssam 
80016615Ssam /*
80116615Ssam  * Evaluate a subscript index.
80216615Ssam  */
80316615Ssam 
804*18228Slinton public pascal_evalaref (s, base, i)
80516615Ssam Symbol s;
806*18228Slinton Address base;
80716615Ssam long i;
80816615Ssam {
809*18228Slinton     Symbol t;
81016615Ssam     long lb, ub;
81116615Ssam 
812*18228Slinton     t = rtype(s);
813*18228Slinton     s = rtype(t->chain);
814*18228Slinton     findbounds(s, &lb, &ub);
81516615Ssam     if (i < lb or i > ub) {
81616615Ssam 	error("subscript %d out of range [%d..%d]", i, lb, ub);
81716615Ssam     }
818*18228Slinton     push(long, base + (i - lb) * size(t->type));
81916615Ssam }
82016615Ssam 
82116615Ssam /*
82216615Ssam  * Initial Pascal type information.
82316615Ssam  */
82416615Ssam 
82516615Ssam #define NTYPES 4
82616615Ssam 
827*18228Slinton private Symbol inittype[NTYPES + 1];
82816615Ssam 
829*18228Slinton private addType (n, s, lower, upper)
830*18228Slinton integer n;
83116615Ssam String s;
83216615Ssam long lower, upper;
83316615Ssam {
83416615Ssam     register Symbol t;
83516615Ssam 
836*18228Slinton     if (n > NTYPES) {
837*18228Slinton 	panic("initial Pascal type number too large for '%s'", s);
83816615Ssam     }
839*18228Slinton     t = insert(identname(s, true));
84016615Ssam     t->language = pasc;
841*18228Slinton     t->class = TYPE;
842*18228Slinton     t->type = newSymbol(nil, 0, RANGE, t, nil);
843*18228Slinton     t->type->symvalue.rangev.lower = lower;
844*18228Slinton     t->type->symvalue.rangev.upper = upper;
845*18228Slinton     t->type->language = pasc;
846*18228Slinton     inittype[n] = t;
84716615Ssam }
84816615Ssam 
84916615Ssam private initTypes ()
85016615Ssam {
851*18228Slinton     addType(1, "boolean", 0L, 1L);
852*18228Slinton     addType(2, "char", 0L, 255L);
853*18228Slinton     addType(3, "integer", 0x80000000L, 0x7fffffffL);
854*18228Slinton     addType(4, "real", 8L, 0L);
855*18228Slinton     initialized = true;
85616615Ssam }
85716615Ssam 
85816615Ssam /*
85916615Ssam  * Initialize typetable.
86016615Ssam  */
86116615Ssam 
86216615Ssam public pascal_modinit (typetable)
86316615Ssam Symbol typetable[];
86416615Ssam {
86516615Ssam     register integer i;
86616615Ssam 
867*18228Slinton     if (not initialized) {
868*18228Slinton 	initTypes();
869*18228Slinton 	initialized = true;
870*18228Slinton     }
871*18228Slinton     for (i = 1; i <= NTYPES; i++) {
87216615Ssam 	typetable[i] = inittype[i];
87316615Ssam     }
87416615Ssam }
87516615Ssam 
87616615Ssam public boolean pascal_hasmodules ()
87716615Ssam {
87816615Ssam     return false;
87916615Ssam }
88016615Ssam 
88116615Ssam public boolean pascal_passaddr (param, exprtype)
88216615Ssam Symbol param, exprtype;
88316615Ssam {
88416615Ssam     return false;
88516615Ssam }
886