xref: /csrg-svn/old/dbx/modula-2.c (revision 18261)
1*18261Slinton /* Copyright (c) 1982 Regents of the University of California */
2*18261Slinton 
316622Ssam #ifndef lint
4*18261Slinton static	char sccsid[] = "@(#)modula-2.c	1.2 (Berkeley) 03/07/85"; /* from 1.4 84/03/27 10:22:04 linton Exp */
516622Ssam #endif
616622Ssam 
716622Ssam /*
816622Ssam  * Modula-2 specific symbol routines.
916622Ssam  */
1016622Ssam 
11*18261Slinton static char rcsid[] = "$Header: modula-2.c,v 1.6 84/12/26 10:40:33 linton Exp $";
12*18261Slinton 
1316622Ssam #include "defs.h"
1416622Ssam #include "symbols.h"
1516622Ssam #include "modula-2.h"
1616622Ssam #include "languages.h"
1716622Ssam #include "tree.h"
1816622Ssam #include "eval.h"
1916622Ssam #include "mappings.h"
2016622Ssam #include "process.h"
2116622Ssam #include "runtime.h"
2216622Ssam #include "machine.h"
2316622Ssam 
2416622Ssam #ifndef public
2516622Ssam #endif
2616622Ssam 
2716622Ssam private Language mod2;
2816622Ssam private boolean initialized;
2916622Ssam 
30*18261Slinton 
31*18261Slinton #define ischar(t) ( \
32*18261Slinton     (t) == t_char->type or \
33*18261Slinton     ((t)->class == RANGE and istypename((t)->type, "char")) \
34*18261Slinton )
35*18261Slinton 
3616622Ssam /*
3716622Ssam  * Initialize Modula-2 information.
3816622Ssam  */
3916622Ssam 
4016622Ssam public modula2_init ()
4116622Ssam {
4216622Ssam     mod2 = language_define("modula-2", ".mod");
4316622Ssam     language_setop(mod2, L_PRINTDECL, modula2_printdecl);
4416622Ssam     language_setop(mod2, L_PRINTVAL, modula2_printval);
4516622Ssam     language_setop(mod2, L_TYPEMATCH, modula2_typematch);
4616622Ssam     language_setop(mod2, L_BUILDAREF, modula2_buildaref);
4716622Ssam     language_setop(mod2, L_EVALAREF, modula2_evalaref);
4816622Ssam     language_setop(mod2, L_MODINIT, modula2_modinit);
4916622Ssam     language_setop(mod2, L_HASMODULES, modula2_hasmodules);
5016622Ssam     language_setop(mod2, L_PASSADDR, modula2_passaddr);
5116622Ssam     initialized = false;
5216622Ssam }
5316622Ssam 
5416622Ssam /*
5516622Ssam  * Typematch tests if two types are compatible.  The issue
5616622Ssam  * is a bit complicated, so several subfunctions are used for
5716622Ssam  * various kinds of compatibility.
5816622Ssam  */
5916622Ssam 
60*18261Slinton private boolean builtinmatch (t1, t2)
61*18261Slinton register Symbol t1, t2;
62*18261Slinton {
63*18261Slinton     boolean b;
64*18261Slinton 
65*18261Slinton     b = (boolean) (
66*18261Slinton 	(
67*18261Slinton 	    t2 == t_int->type and t1->class == RANGE and
68*18261Slinton 	    (
69*18261Slinton 		istypename(t1->type, "integer") or
70*18261Slinton 		istypename(t1->type, "cardinal")
71*18261Slinton 	    )
72*18261Slinton 	) or (
73*18261Slinton 	    t2 == t_char->type and
74*18261Slinton 	    t1->class == RANGE and istypename(t1->type, "char")
75*18261Slinton 	) or (
76*18261Slinton 	    t2 == t_real->type and
77*18261Slinton 	    t1->class == RANGE and (
78*18261Slinton 		istypename(t1->type, "real") or
79*18261Slinton 		istypename(t1->type, "longreal")
80*18261Slinton 	    )
81*18261Slinton 	) or (
82*18261Slinton 	    t2 == t_boolean->type and
83*18261Slinton 	    t1->class == RANGE and istypename(t1->type, "boolean")
84*18261Slinton 	)
85*18261Slinton     );
86*18261Slinton     return b;
87*18261Slinton }
88*18261Slinton 
89*18261Slinton private boolean rangematch (t1, t2)
90*18261Slinton register Symbol t1, t2;
91*18261Slinton {
92*18261Slinton     boolean b;
93*18261Slinton     register Symbol rt1, rt2;
94*18261Slinton 
95*18261Slinton     if (t1->class == RANGE and t2->class == RANGE) {
96*18261Slinton 	b = (boolean) (
97*18261Slinton 	    t1->symvalue.rangev.lower == t2->symvalue.rangev.lower and
98*18261Slinton 	    t1->symvalue.rangev.upper == t2->symvalue.rangev.upper
99*18261Slinton 	);
100*18261Slinton     } else {
101*18261Slinton 	b = false;
102*18261Slinton     }
103*18261Slinton     return b;
104*18261Slinton }
105*18261Slinton 
10616622Ssam private boolean nilMatch (t1, t2)
10716622Ssam register Symbol t1, t2;
10816622Ssam {
10916622Ssam     boolean b;
11016622Ssam 
11116622Ssam     b = (boolean) (
11216622Ssam 	(t1 == t_nil and t2->class == PTR) or
11316622Ssam 	(t1->class == PTR and t2 == t_nil)
11416622Ssam     );
11516622Ssam     return b;
11616622Ssam }
11716622Ssam 
11816622Ssam private boolean enumMatch (t1, t2)
11916622Ssam register Symbol t1, t2;
12016622Ssam {
12116622Ssam     boolean b;
12216622Ssam 
12316622Ssam     b = (boolean) (
124*18261Slinton 	(t1->class == SCAL and t2->class == CONST and t2->type == t1) or
125*18261Slinton 	(t1->class == CONST and t2->class == SCAL and t1->type == t2)
12616622Ssam     );
12716622Ssam     return b;
12816622Ssam }
12916622Ssam 
13016622Ssam private boolean openArrayMatch (t1, t2)
13116622Ssam register Symbol t1, t2;
13216622Ssam {
13316622Ssam     boolean b;
13416622Ssam 
13516622Ssam     b = (boolean) (
13616622Ssam 	(
137*18261Slinton 	    t1->class == DYNARRAY and t1->symvalue.ndims == 1 and
13816622Ssam 	    t2->class == ARRAY and
13916622Ssam 	    compatible(rtype(t2->chain)->type, t_int) and
14016622Ssam 	    compatible(t1->type, t2->type)
14116622Ssam 	) or (
142*18261Slinton 	    t2->class == DYNARRAY and t2->symvalue.ndims == 1 and
14316622Ssam 	    t1->class == ARRAY and
14416622Ssam 	    compatible(rtype(t1->chain)->type, t_int) and
14516622Ssam 	    compatible(t1->type, t2->type)
14616622Ssam 	)
14716622Ssam     );
14816622Ssam     return b;
14916622Ssam }
15016622Ssam 
15116622Ssam private boolean isConstString (t)
15216622Ssam register Symbol t;
15316622Ssam {
15416622Ssam     boolean b;
15516622Ssam 
15616622Ssam     b = (boolean) (
15716622Ssam 	t->language == primlang and t->class == ARRAY and t->type == t_char
15816622Ssam     );
15916622Ssam     return b;
16016622Ssam }
16116622Ssam 
16216622Ssam private boolean stringArrayMatch (t1, t2)
16316622Ssam register Symbol t1, t2;
16416622Ssam {
16516622Ssam     boolean b;
16616622Ssam 
16716622Ssam     b = (boolean) (
16816622Ssam 	(
16916622Ssam 	    isConstString(t1) and
17016622Ssam 	    t2->class == ARRAY and compatible(t2->type, t_char->type)
17116622Ssam 	) or (
17216622Ssam 	    isConstString(t2) and
17316622Ssam 	    t1->class == ARRAY and compatible(t1->type, t_char->type)
17416622Ssam 	)
17516622Ssam     );
17616622Ssam     return b;
17716622Ssam }
17816622Ssam 
17916622Ssam public boolean modula2_typematch (type1, type2)
18016622Ssam Symbol type1, type2;
18116622Ssam {
182*18261Slinton     boolean b;
18316622Ssam     Symbol t1, t2, tmp;
18416622Ssam 
18516622Ssam     t1 = rtype(type1);
18616622Ssam     t2 = rtype(type2);
18716622Ssam     if (t1 == t2) {
18816622Ssam 	b = true;
18916622Ssam     } else {
190*18261Slinton 	if (t1 == t_char->type or t1 == t_int->type or
191*18261Slinton 	    t1 == t_real->type or t1 == t_boolean->type
192*18261Slinton 	) {
19316622Ssam 	    tmp = t1;
19416622Ssam 	    t1 = t2;
19516622Ssam 	    t2 = tmp;
19616622Ssam 	}
19716622Ssam 	b = (Boolean) (
198*18261Slinton 	    builtinmatch(t1, t2) or rangematch(t1, t2) or
199*18261Slinton 	    nilMatch(t1, t2) or enumMatch(t1, t2) or
200*18261Slinton 	    openArrayMatch(t1, t2) or stringArrayMatch(t1, t2)
20116622Ssam 	);
20216622Ssam     }
20316622Ssam     return b;
20416622Ssam }
20516622Ssam 
20616622Ssam /*
20716622Ssam  * Indent n spaces.
20816622Ssam  */
20916622Ssam 
21016622Ssam private indent (n)
21116622Ssam int n;
21216622Ssam {
21316622Ssam     if (n > 0) {
21416622Ssam 	printf("%*c", n, ' ');
21516622Ssam     }
21616622Ssam }
21716622Ssam 
21816622Ssam public modula2_printdecl (s)
21916622Ssam Symbol s;
22016622Ssam {
22116622Ssam     register Symbol t;
22216622Ssam     Boolean semicolon;
22316622Ssam 
22416622Ssam     semicolon = true;
22516622Ssam     if (s->class == TYPEREF) {
22616622Ssam 	resolveRef(t);
22716622Ssam     }
22816622Ssam     switch (s->class) {
22916622Ssam 	case CONST:
23016622Ssam 	    if (s->type->class == SCAL) {
231*18261Slinton 		semicolon = false;
232*18261Slinton 		printf("enumeration constant with value ");
233*18261Slinton 		eval(s->symvalue.constval);
234*18261Slinton 		modula2_printval(s);
23516622Ssam 	    } else {
23616622Ssam 		printf("const %s = ", symname(s));
237*18261Slinton 		eval(s->symvalue.constval);
23816622Ssam 		modula2_printval(s);
23916622Ssam 	    }
24016622Ssam 	    break;
24116622Ssam 
24216622Ssam 	case TYPE:
24316622Ssam 	    printf("type %s = ", symname(s));
24416622Ssam 	    printtype(s, s->type, 0);
24516622Ssam 	    break;
24616622Ssam 
24716622Ssam 	case TYPEREF:
24816622Ssam 	    printf("type %s", symname(s));
24916622Ssam 	    break;
25016622Ssam 
25116622Ssam 	case VAR:
25216622Ssam 	    if (isparam(s)) {
25316622Ssam 		printf("(parameter) %s : ", symname(s));
25416622Ssam 	    } else {
25516622Ssam 		printf("var %s : ", symname(s));
25616622Ssam 	    }
25716622Ssam 	    printtype(s, s->type, 0);
25816622Ssam 	    break;
25916622Ssam 
26016622Ssam 	case REF:
26116622Ssam 	    printf("(var parameter) %s : ", symname(s));
26216622Ssam 	    printtype(s, s->type, 0);
26316622Ssam 	    break;
26416622Ssam 
26516622Ssam 	case RANGE:
26616622Ssam 	case ARRAY:
267*18261Slinton 	case DYNARRAY:
268*18261Slinton 	case SUBARRAY:
26916622Ssam 	case RECORD:
27016622Ssam 	case VARNT:
27116622Ssam 	case PTR:
27216622Ssam 	    printtype(s, s, 0);
27316622Ssam 	    semicolon = false;
27416622Ssam 	    break;
27516622Ssam 
27616622Ssam 	case FVAR:
27716622Ssam 	    printf("(function variable) %s : ", symname(s));
27816622Ssam 	    printtype(s, s->type, 0);
27916622Ssam 	    break;
28016622Ssam 
28116622Ssam 	case FIELD:
28216622Ssam 	    printf("(field) %s : ", symname(s));
28316622Ssam 	    printtype(s, s->type, 0);
28416622Ssam 	    break;
28516622Ssam 
28616622Ssam 	case PROC:
28716622Ssam 	    printf("procedure %s", symname(s));
28816622Ssam 	    listparams(s);
28916622Ssam 	    break;
29016622Ssam 
29116622Ssam 	case PROG:
29216622Ssam 	    printf("program %s", symname(s));
29316622Ssam 	    listparams(s);
29416622Ssam 	    break;
29516622Ssam 
29616622Ssam 	case FUNC:
297*18261Slinton 	    printf("procedure %s", symname(s));
29816622Ssam 	    listparams(s);
29916622Ssam 	    printf(" : ");
30016622Ssam 	    printtype(s, s->type, 0);
30116622Ssam 	    break;
30216622Ssam 
30316622Ssam 	case MODULE:
30416622Ssam 	    printf("module %s", symname(s));
30516622Ssam 	    break;
30616622Ssam 
30716622Ssam 	default:
308*18261Slinton 	    printf("[%s]", classname(s));
30916622Ssam 	    break;
31016622Ssam     }
31116622Ssam     if (semicolon) {
31216622Ssam 	putchar(';');
31316622Ssam     }
31416622Ssam     putchar('\n');
31516622Ssam }
31616622Ssam 
31716622Ssam /*
31816622Ssam  * Recursive whiz-bang procedure to print the type portion
31916622Ssam  * of a declaration.
32016622Ssam  *
32116622Ssam  * The symbol associated with the type is passed to allow
32216622Ssam  * searching for type names without getting "type blah = blah".
32316622Ssam  */
32416622Ssam 
32516622Ssam private printtype (s, t, n)
32616622Ssam Symbol s;
32716622Ssam Symbol t;
32816622Ssam int n;
32916622Ssam {
330*18261Slinton     Symbol tmp;
331*18261Slinton     int i;
33216622Ssam 
33316622Ssam     if (t->class == TYPEREF) {
33416622Ssam 	resolveRef(t);
33516622Ssam     }
33616622Ssam     switch (t->class) {
33716622Ssam 	case VAR:
33816622Ssam 	case CONST:
33916622Ssam 	case FUNC:
34016622Ssam 	case PROC:
34116622Ssam 	    panic("printtype: class %s", classname(t));
34216622Ssam 	    break;
34316622Ssam 
34416622Ssam 	case ARRAY:
34516622Ssam 	    printf("array[");
34616622Ssam 	    tmp = t->chain;
34716622Ssam 	    if (tmp != nil) {
34816622Ssam 		for (;;) {
34916622Ssam 		    printtype(tmp, tmp, n);
35016622Ssam 		    tmp = tmp->chain;
35116622Ssam 		    if (tmp == nil) {
35216622Ssam 			break;
35316622Ssam 		    }
35416622Ssam 		    printf(", ");
35516622Ssam 		}
35616622Ssam 	    }
35716622Ssam 	    printf("] of ");
35816622Ssam 	    printtype(t, t->type, n);
35916622Ssam 	    break;
36016622Ssam 
361*18261Slinton 	case DYNARRAY:
362*18261Slinton 	    printf("dynarray of ");
363*18261Slinton 	    for (i = 1; i < t->symvalue.ndims; i++) {
364*18261Slinton 		printf("array of ");
365*18261Slinton 	    }
366*18261Slinton 	    printtype(t, t->type, n);
367*18261Slinton 	    break;
368*18261Slinton 
369*18261Slinton 	case SUBARRAY:
370*18261Slinton 	    printf("subarray of ");
371*18261Slinton 	    for (i = 1; i < t->symvalue.ndims; i++) {
372*18261Slinton 		printf("array of ");
373*18261Slinton 	    }
374*18261Slinton 	    printtype(t, t->type, n);
375*18261Slinton 	    break;
376*18261Slinton 
37716622Ssam 	case RECORD:
37816622Ssam 	    printRecordDecl(t, n);
37916622Ssam 	    break;
38016622Ssam 
38116622Ssam 	case FIELD:
38216622Ssam 	    if (t->chain != nil) {
38316622Ssam 		printtype(t->chain, t->chain, n);
38416622Ssam 	    }
38516622Ssam 	    printf("\t%s : ", symname(t));
38616622Ssam 	    printtype(t, t->type, n);
38716622Ssam 	    printf(";\n");
38816622Ssam 	    break;
38916622Ssam 
39016622Ssam 	case RANGE:
39116622Ssam 	    printRangeDecl(t);
39216622Ssam 	    break;
39316622Ssam 
39416622Ssam 	case PTR:
39516622Ssam 	    printf("pointer to ");
39616622Ssam 	    printtype(t, t->type, n);
39716622Ssam 	    break;
39816622Ssam 
39916622Ssam 	case TYPE:
40016622Ssam 	    if (t->name != nil and ident(t->name)[0] != '\0') {
40116622Ssam 		printname(stdout, t);
40216622Ssam 	    } else {
40316622Ssam 		printtype(t, t->type, n);
40416622Ssam 	    }
40516622Ssam 	    break;
40616622Ssam 
40716622Ssam 	case SCAL:
40816622Ssam 	    printEnumDecl(t, n);
40916622Ssam 	    break;
41016622Ssam 
41116622Ssam 	case SET:
41216622Ssam 	    printf("set of ");
41316622Ssam 	    printtype(t, t->type, n);
41416622Ssam 	    break;
41516622Ssam 
41616622Ssam 	case TYPEREF:
41716622Ssam 	    break;
41816622Ssam 
419*18261Slinton 	case FPROC:
420*18261Slinton 	case FFUNC:
421*18261Slinton 	    printf("procedure");
422*18261Slinton 	    break;
423*18261Slinton 
42416622Ssam 	default:
425*18261Slinton 	    printf("[%s]", classname(t));
42616622Ssam 	    break;
42716622Ssam     }
42816622Ssam }
42916622Ssam 
43016622Ssam /*
43116622Ssam  * Print out a record declaration.
43216622Ssam  */
43316622Ssam 
43416622Ssam private printRecordDecl (t, n)
43516622Ssam Symbol t;
43616622Ssam int n;
43716622Ssam {
43816622Ssam     register Symbol f;
43916622Ssam 
44016622Ssam     if (t->chain == nil) {
44116622Ssam 	printf("record end");
44216622Ssam     } else {
44316622Ssam 	printf("record\n");
44416622Ssam 	for (f = t->chain; f != nil; f = f->chain) {
44516622Ssam 	    indent(n+4);
44616622Ssam 	    printf("%s : ", symname(f));
44716622Ssam 	    printtype(f->type, f->type, n+4);
44816622Ssam 	    printf(";\n");
44916622Ssam 	}
45016622Ssam 	indent(n);
45116622Ssam 	printf("end");
45216622Ssam     }
45316622Ssam }
45416622Ssam 
45516622Ssam /*
45616622Ssam  * Print out the declaration of a range type.
45716622Ssam  */
45816622Ssam 
45916622Ssam private printRangeDecl (t)
46016622Ssam Symbol t;
46116622Ssam {
46216622Ssam     long r0, r1;
46316622Ssam 
46416622Ssam     r0 = t->symvalue.rangev.lower;
46516622Ssam     r1 = t->symvalue.rangev.upper;
466*18261Slinton     if (ischar(t)) {
46716622Ssam 	if (r0 < 0x20 or r0 > 0x7e) {
46816622Ssam 	    printf("%ld..", r0);
46916622Ssam 	} else {
47016622Ssam 	    printf("'%c'..", (char) r0);
47116622Ssam 	}
47216622Ssam 	if (r1 < 0x20 or r1 > 0x7e) {
47316622Ssam 	    printf("\\%lo", r1);
47416622Ssam 	} else {
47516622Ssam 	    printf("'%c'", (char) r1);
47616622Ssam 	}
47716622Ssam     } else if (r0 > 0 and r1 == 0) {
47816622Ssam 	printf("%ld byte real", r0);
47916622Ssam     } else if (r0 >= 0) {
48016622Ssam 	printf("%lu..%lu", r0, r1);
48116622Ssam     } else {
48216622Ssam 	printf("%ld..%ld", r0, r1);
48316622Ssam     }
48416622Ssam }
48516622Ssam 
48616622Ssam /*
48716622Ssam  * Print out an enumeration declaration.
48816622Ssam  */
48916622Ssam 
49016622Ssam private printEnumDecl (e, n)
49116622Ssam Symbol e;
49216622Ssam int n;
49316622Ssam {
49416622Ssam     Symbol t;
49516622Ssam 
49616622Ssam     printf("(");
49716622Ssam     t = e->chain;
49816622Ssam     if (t != nil) {
49916622Ssam 	printf("%s", symname(t));
50016622Ssam 	t = t->chain;
50116622Ssam 	while (t != nil) {
50216622Ssam 	    printf(", %s", symname(t));
50316622Ssam 	    t = t->chain;
50416622Ssam 	}
50516622Ssam     }
50616622Ssam     printf(")");
50716622Ssam }
50816622Ssam 
50916622Ssam /*
51016622Ssam  * List the parameters of a procedure or function.
51116622Ssam  * No attempt is made to combine like types.
51216622Ssam  */
51316622Ssam 
51416622Ssam private listparams (s)
51516622Ssam Symbol s;
51616622Ssam {
51716622Ssam     Symbol t;
51816622Ssam 
51916622Ssam     if (s->chain != nil) {
52016622Ssam 	putchar('(');
52116622Ssam 	for (t = s->chain; t != nil; t = t->chain) {
52216622Ssam 	    switch (t->class) {
52316622Ssam 		case REF:
52416622Ssam 		    printf("var ");
52516622Ssam 		    break;
52616622Ssam 
52716622Ssam 		case FPROC:
52816622Ssam 		case FFUNC:
52916622Ssam 		    printf("procedure ");
53016622Ssam 		    break;
53116622Ssam 
53216622Ssam 		case VAR:
53316622Ssam 		    break;
53416622Ssam 
53516622Ssam 		default:
53616622Ssam 		    panic("unexpected class %d for parameter", t->class);
53716622Ssam 	    }
53816622Ssam 	    printf("%s", symname(t));
53916622Ssam 	    if (s->class == PROG) {
54016622Ssam 		printf(", ");
54116622Ssam 	    } else {
54216622Ssam 		printf(" : ");
54316622Ssam 		printtype(t, t->type, 0);
54416622Ssam 		if (t->chain != nil) {
54516622Ssam 		    printf("; ");
54616622Ssam 		}
54716622Ssam 	    }
54816622Ssam 	}
54916622Ssam 	putchar(')');
55016622Ssam     }
55116622Ssam }
55216622Ssam 
55316622Ssam /*
554*18261Slinton  * Test if a pointer type should be treated as a null-terminated string.
555*18261Slinton  * The type given is the type that is pointed to.
556*18261Slinton  */
557*18261Slinton 
558*18261Slinton private boolean isCstring (type)
559*18261Slinton Symbol type;
560*18261Slinton {
561*18261Slinton     boolean b;
562*18261Slinton     register Symbol a, t;
563*18261Slinton 
564*18261Slinton     a = rtype(type);
565*18261Slinton     if (a->class == ARRAY) {
566*18261Slinton 	t = rtype(a->chain);
567*18261Slinton 	b = (boolean) (
568*18261Slinton 	    t->class == RANGE and istypename(a->type, "char") and
569*18261Slinton 	    (t->symvalue.rangev.upper - t->symvalue.rangev.lower + 1) <= 0
570*18261Slinton 	);
571*18261Slinton     } else {
572*18261Slinton 	b = false;
573*18261Slinton     }
574*18261Slinton     return b;
575*18261Slinton }
576*18261Slinton 
577*18261Slinton /*
57816622Ssam  * Modula 2 interface to printval.
57916622Ssam  */
58016622Ssam 
58116622Ssam public modula2_printval (s)
58216622Ssam Symbol s;
58316622Ssam {
58416622Ssam     prval(s, size(s));
58516622Ssam }
58616622Ssam 
58716622Ssam /*
58816622Ssam  * Print out the value on the top of the expression stack
58916622Ssam  * in the format for the type of the given symbol, assuming
59016622Ssam  * the size of the object is n bytes.
59116622Ssam  */
59216622Ssam 
59316622Ssam private prval (s, n)
59416622Ssam Symbol s;
59516622Ssam integer n;
59616622Ssam {
59716622Ssam     Symbol t;
59816622Ssam     Address a;
59916622Ssam     integer len;
60016622Ssam     double r;
601*18261Slinton     integer i;
60216622Ssam 
60316622Ssam     if (s->class == TYPEREF) {
60416622Ssam 	resolveRef(s);
60516622Ssam     }
60616622Ssam     switch (s->class) {
60716622Ssam 	case CONST:
60816622Ssam 	case TYPE:
609*18261Slinton 	case REF:
61016622Ssam 	case VAR:
61116622Ssam 	case FVAR:
61216622Ssam 	case TAG:
61316622Ssam 	    prval(s->type, n);
61416622Ssam 	    break;
61516622Ssam 
616*18261Slinton 	case FIELD:
617*18261Slinton 	    if (isbitfield(s)) {
618*18261Slinton 		i = 0;
619*18261Slinton 		popn(size(s), &i);
620*18261Slinton 		i >>= (s->symvalue.field.offset mod BITSPERBYTE);
621*18261Slinton 		i &= ((1 << s->symvalue.field.length) - 1);
622*18261Slinton 		t = rtype(s->type);
623*18261Slinton 		if (t->class == SCAL) {
624*18261Slinton 		    printEnum(i, t);
625*18261Slinton 		} else {
626*18261Slinton 		    printRangeVal(i, t);
627*18261Slinton 		}
628*18261Slinton 	    } else {
629*18261Slinton 		prval(s->type, n);
630*18261Slinton 	    }
631*18261Slinton 	    break;
632*18261Slinton 
63316622Ssam 	case ARRAY:
63416622Ssam 	    t = rtype(s->type);
635*18261Slinton 	    if (ischar(t)) {
63616622Ssam 		len = size(s);
63716622Ssam 		sp -= len;
638*18261Slinton 		printf("\"%.*s\"", len, sp);
63916622Ssam 		break;
64016622Ssam 	    } else {
64116622Ssam 		printarray(s);
64216622Ssam 	    }
64316622Ssam 	    break;
64416622Ssam 
645*18261Slinton 	case DYNARRAY:
646*18261Slinton 	    printDynarray(s);
647*18261Slinton 	    break;
648*18261Slinton 
649*18261Slinton 	case SUBARRAY:
650*18261Slinton 	    printSubarray(s);
651*18261Slinton 	    break;
652*18261Slinton 
65316622Ssam 	case RECORD:
65416622Ssam 	    printrecord(s);
65516622Ssam 	    break;
65616622Ssam 
65716622Ssam 	case VARNT:
658*18261Slinton 	    printf("[variant]");
65916622Ssam 	    break;
66016622Ssam 
66116622Ssam 	case RANGE:
66216622Ssam 	    printrange(s, n);
66316622Ssam 	    break;
66416622Ssam 
665*18261Slinton 	/*
666*18261Slinton 	 * Unresolved opaque type.
667*18261Slinton 	 * Probably a pointer.
668*18261Slinton 	 */
669*18261Slinton 	case TYPEREF:
670*18261Slinton 	    a = pop(Address);
671*18261Slinton 	    printf("@%x", a);
672*18261Slinton 	    break;
673*18261Slinton 
67416622Ssam 	case FILET:
675*18261Slinton 	    a = pop(Address);
676*18261Slinton 	    if (a == 0) {
677*18261Slinton 		printf("nil");
678*18261Slinton 	    } else {
679*18261Slinton 		printf("0x%x", a);
680*18261Slinton 	    }
681*18261Slinton 	    break;
682*18261Slinton 
68316622Ssam 	case PTR:
68416622Ssam 	    a = pop(Address);
68516622Ssam 	    if (a == 0) {
68616622Ssam 		printf("nil");
687*18261Slinton 	    } else if (isCstring(s->type)) {
688*18261Slinton 		printString(a, true);
68916622Ssam 	    } else {
69016622Ssam 		printf("0x%x", a);
69116622Ssam 	    }
69216622Ssam 	    break;
69316622Ssam 
69416622Ssam 	case SCAL:
695*18261Slinton 	    i = 0;
696*18261Slinton 	    popn(n, &i);
697*18261Slinton 	    printEnum(i, s);
69816622Ssam 	    break;
69916622Ssam 
70016622Ssam 	case FPROC:
70116622Ssam 	case FFUNC:
70216622Ssam 	    a = pop(long);
70316622Ssam 	    t = whatblock(a);
70416622Ssam 	    if (t == nil) {
705*18261Slinton 		printf("0x%x", a);
70616622Ssam 	    } else {
707*18261Slinton 		printname(stdout, t);
70816622Ssam 	    }
70916622Ssam 	    break;
71016622Ssam 
71116622Ssam 	case SET:
71216622Ssam 	    printSet(s);
71316622Ssam 	    break;
71416622Ssam 
71516622Ssam 	default:
71616622Ssam 	    if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) {
71716622Ssam 		panic("printval: bad class %d", ord(s->class));
71816622Ssam 	    }
71916622Ssam 	    printf("[%s]", classname(s));
72016622Ssam 	    break;
72116622Ssam     }
72216622Ssam }
72316622Ssam 
72416622Ssam /*
725*18261Slinton  * Print out a dynamic array.
726*18261Slinton  */
727*18261Slinton 
728*18261Slinton private Address printDynSlice();
729*18261Slinton 
730*18261Slinton private printDynarray (t)
731*18261Slinton Symbol t;
732*18261Slinton {
733*18261Slinton     Address base;
734*18261Slinton     integer n;
735*18261Slinton     Stack *savesp, *newsp;
736*18261Slinton     Symbol eltype;
737*18261Slinton 
738*18261Slinton     savesp = sp;
739*18261Slinton     sp -= (t->symvalue.ndims * sizeof(Word));
740*18261Slinton     base = pop(Address);
741*18261Slinton     newsp = sp;
742*18261Slinton     sp = savesp;
743*18261Slinton     eltype = rtype(t->type);
744*18261Slinton     if (t->symvalue.ndims == 0) {
745*18261Slinton 	if (ischar(eltype)) {
746*18261Slinton 	    printString(base, true);
747*18261Slinton 	} else {
748*18261Slinton 	    printf("[dynarray @nocount]");
749*18261Slinton 	}
750*18261Slinton     } else {
751*18261Slinton 	n = ((long *) sp)[-(t->symvalue.ndims)];
752*18261Slinton 	base = printDynSlice(base, n, t->symvalue.ndims, eltype, size(eltype));
753*18261Slinton     }
754*18261Slinton     sp = newsp;
755*18261Slinton }
756*18261Slinton 
757*18261Slinton /*
758*18261Slinton  * Print out one dimension of a multi-dimension dynamic array.
759*18261Slinton  *
760*18261Slinton  * Return the address of the element that follows the printed elements.
761*18261Slinton  */
762*18261Slinton 
763*18261Slinton private Address printDynSlice (base, count, ndims, eltype, elsize)
764*18261Slinton Address base;
765*18261Slinton integer count, ndims;
766*18261Slinton Symbol eltype;
767*18261Slinton integer elsize;
768*18261Slinton {
769*18261Slinton     Address b;
770*18261Slinton     integer i, n;
771*18261Slinton     char *slice;
772*18261Slinton     Stack *savesp;
773*18261Slinton 
774*18261Slinton     b = base;
775*18261Slinton     if (ndims > 1) {
776*18261Slinton 	n = ((long *) sp)[-ndims + 1];
777*18261Slinton     }
778*18261Slinton     if (ndims == 1 and ischar(eltype)) {
779*18261Slinton 	slice = newarr(char, count);
780*18261Slinton 	dread(slice, b, count);
781*18261Slinton 	printf("\"%.*s\"", count, slice);
782*18261Slinton 	dispose(slice);
783*18261Slinton 	b += count;
784*18261Slinton     } else {
785*18261Slinton 	printf("(");
786*18261Slinton 	for (i = 0; i < count; i++) {
787*18261Slinton 	    if (i != 0) {
788*18261Slinton 		printf(", ");
789*18261Slinton 	    }
790*18261Slinton 	    if (ndims == 1) {
791*18261Slinton 		slice = newarr(char, elsize);
792*18261Slinton 		dread(slice, b, elsize);
793*18261Slinton 		savesp = sp;
794*18261Slinton 		sp = slice + elsize;
795*18261Slinton 		printval(eltype);
796*18261Slinton 		sp = savesp;
797*18261Slinton 		dispose(slice);
798*18261Slinton 		b += elsize;
799*18261Slinton 	    } else {
800*18261Slinton 		b = printDynSlice(b, n, ndims - 1, eltype, elsize);
801*18261Slinton 	    }
802*18261Slinton 	}
803*18261Slinton 	printf(")");
804*18261Slinton     }
805*18261Slinton     return b;
806*18261Slinton }
807*18261Slinton 
808*18261Slinton private printSubarray (t)
809*18261Slinton Symbol t;
810*18261Slinton {
811*18261Slinton     printf("[subarray]");
812*18261Slinton }
813*18261Slinton 
814*18261Slinton /*
81516622Ssam  * Print out the value of a scalar (non-enumeration) type.
81616622Ssam  */
81716622Ssam 
81816622Ssam private printrange (s, n)
81916622Ssam Symbol s;
82016622Ssam integer n;
82116622Ssam {
82216622Ssam     double d;
82316622Ssam     float f;
82416622Ssam     integer i;
82516622Ssam 
82616622Ssam     if (s->symvalue.rangev.upper == 0 and s->symvalue.rangev.lower > 0) {
82716622Ssam 	if (n == sizeof(float)) {
82816622Ssam 	    popn(n, &f);
82916622Ssam 	    d = f;
83016622Ssam 	} else {
83116622Ssam 	    popn(n, &d);
83216622Ssam 	}
83316622Ssam 	prtreal(d);
83416622Ssam     } else {
83516622Ssam 	i = 0;
83616622Ssam 	popn(n, &i);
837*18261Slinton 	printRangeVal(i, s);
83816622Ssam     }
83916622Ssam }
84016622Ssam 
84116622Ssam /*
84216622Ssam  * Print out a set.
84316622Ssam  */
84416622Ssam 
84516622Ssam private printSet (s)
84616622Ssam Symbol s;
84716622Ssam {
84816622Ssam     Symbol t;
84916622Ssam     integer nbytes;
85016622Ssam 
85116622Ssam     nbytes = size(s);
85216622Ssam     t = rtype(s->type);
85316622Ssam     printf("{");
85416622Ssam     sp -= nbytes;
85516622Ssam     if (t->class == SCAL) {
85616622Ssam 	printSetOfEnum(t);
85716622Ssam     } else if (t->class == RANGE) {
85816622Ssam 	printSetOfRange(t);
85916622Ssam     } else {
86016622Ssam 	panic("expected range or enumerated base type for set");
86116622Ssam     }
86216622Ssam     printf("}");
86316622Ssam }
86416622Ssam 
86516622Ssam /*
86616622Ssam  * Print out a set of an enumeration.
86716622Ssam  */
86816622Ssam 
86916622Ssam private printSetOfEnum (t)
87016622Ssam Symbol t;
87116622Ssam {
87216622Ssam     register Symbol e;
87316622Ssam     register integer i, j, *p;
87416622Ssam     boolean first;
87516622Ssam 
87616622Ssam     p = (int *) sp;
87716622Ssam     i = *p;
87816622Ssam     j = 0;
87916622Ssam     e = t->chain;
88016622Ssam     first = true;
88116622Ssam     while (e != nil) {
88216622Ssam 	if ((i&1) == 1) {
88316622Ssam 	    if (first) {
88416622Ssam 		first = false;
88516622Ssam 		printf("%s", symname(e));
88616622Ssam 	    } else {
88716622Ssam 		printf(", %s", symname(e));
88816622Ssam 	    }
88916622Ssam 	}
89016622Ssam 	i >>= 1;
89116622Ssam 	++j;
89216622Ssam 	if (j >= sizeof(integer)*BITSPERBYTE) {
89316622Ssam 	    j = 0;
89416622Ssam 	    ++p;
89516622Ssam 	    i = *p;
89616622Ssam 	}
89716622Ssam 	e = e->chain;
89816622Ssam     }
89916622Ssam }
90016622Ssam 
90116622Ssam /*
90216622Ssam  * Print out a set of a subrange type.
90316622Ssam  */
90416622Ssam 
90516622Ssam private printSetOfRange (t)
90616622Ssam Symbol t;
90716622Ssam {
90816622Ssam     register integer i, j, *p;
90916622Ssam     long v;
91016622Ssam     boolean first;
91116622Ssam 
91216622Ssam     p = (int *) sp;
91316622Ssam     i = *p;
91416622Ssam     j = 0;
91516622Ssam     v = t->symvalue.rangev.lower;
91616622Ssam     first = true;
91716622Ssam     while (v <= t->symvalue.rangev.upper) {
91816622Ssam 	if ((i&1) == 1) {
91916622Ssam 	    if (first) {
92016622Ssam 		first = false;
92116622Ssam 		printf("%ld", v);
92216622Ssam 	    } else {
92316622Ssam 		printf(", %ld", v);
92416622Ssam 	    }
92516622Ssam 	}
92616622Ssam 	i >>= 1;
92716622Ssam 	++j;
92816622Ssam 	if (j >= sizeof(integer)*BITSPERBYTE) {
92916622Ssam 	    j = 0;
93016622Ssam 	    ++p;
93116622Ssam 	    i = *p;
93216622Ssam 	}
93316622Ssam 	++v;
93416622Ssam     }
93516622Ssam }
93616622Ssam 
93716622Ssam /*
938*18261Slinton  * Construct a node for subscripting a dynamic or subarray.
939*18261Slinton  * The list of indices is left for processing in evalaref,
940*18261Slinton  * unlike normal subscripting in which the list is expanded
941*18261Slinton  * across individual INDEX nodes.
942*18261Slinton  */
943*18261Slinton 
944*18261Slinton private Node dynref (a, t, slist)
945*18261Slinton Node a;
946*18261Slinton Symbol t;
947*18261Slinton Node slist;
948*18261Slinton {
949*18261Slinton     Node p, r;
950*18261Slinton     integer n;
951*18261Slinton 
952*18261Slinton     p = slist;
953*18261Slinton     n = 0;
954*18261Slinton     while (p != nil) {
955*18261Slinton 	if (not compatible(p->value.arg[0]->nodetype, t_int)) {
956*18261Slinton 	    suberror("subscript \"", p->value.arg[0], "\" is the wrong type");
957*18261Slinton 	}
958*18261Slinton 	++n;
959*18261Slinton 	p = p->value.arg[1];
960*18261Slinton     }
961*18261Slinton     if (n > t->symvalue.ndims and (t->symvalue.ndims != 0 or n != 1)) {
962*18261Slinton 	suberror("too many subscripts for ", a, nil);
963*18261Slinton     } else if (n < t->symvalue.ndims) {
964*18261Slinton 	suberror("not enough subscripts for ", a, nil);
965*18261Slinton     }
966*18261Slinton     r = build(O_INDEX, a, slist);
967*18261Slinton     r->nodetype = rtype(t->type);
968*18261Slinton     return r;
969*18261Slinton }
970*18261Slinton 
971*18261Slinton /*
97216622Ssam  * Construct a node for subscripting.
97316622Ssam  */
97416622Ssam 
97516622Ssam public Node modula2_buildaref (a, slist)
97616622Ssam Node a, slist;
97716622Ssam {
97816622Ssam     register Symbol t;
97916622Ssam     register Node p;
980*18261Slinton     Symbol eltype;
98116622Ssam     Node esub, r;
982*18261Slinton     integer n;
98316622Ssam 
98416622Ssam     t = rtype(a->nodetype);
985*18261Slinton     if (t->class == DYNARRAY or t->class == SUBARRAY) {
986*18261Slinton 	r = dynref(a, t, slist);
987*18261Slinton     } else if (t->class == ARRAY) {
988*18261Slinton 	r = a;
989*18261Slinton 	eltype = rtype(t->type);
99016622Ssam 	p = slist;
99116622Ssam 	t = t->chain;
992*18261Slinton 	while (p != nil and t != nil) {
99316622Ssam 	    esub = p->value.arg[0];
994*18261Slinton 	    if (not compatible(rtype(t), rtype(esub->nodetype))) {
995*18261Slinton 		suberror("subscript \"", esub, "\" is the wrong type");
99616622Ssam 	    }
99716622Ssam 	    r = build(O_INDEX, r, esub);
99816622Ssam 	    r->nodetype = eltype;
999*18261Slinton 	    p = p->value.arg[1];
1000*18261Slinton 	    t = t->chain;
100116622Ssam 	}
1002*18261Slinton 	if (p != nil) {
1003*18261Slinton 	    suberror("too many subscripts for ", a, nil);
1004*18261Slinton 	} else if (t != nil) {
1005*18261Slinton 	    suberror("not enough subscripts for ", a, nil);
100616622Ssam 	}
1007*18261Slinton     } else {
1008*18261Slinton 	suberror("\"", a, "\" is not an array");
100916622Ssam     }
101016622Ssam     return r;
101116622Ssam }
101216622Ssam 
101316622Ssam /*
1014*18261Slinton  * Subscript usage error reporting.
1015*18261Slinton  */
1016*18261Slinton 
1017*18261Slinton private suberror (s1, e1, s2)
1018*18261Slinton String s1, s2;
1019*18261Slinton Node e1;
1020*18261Slinton {
1021*18261Slinton     beginerrmsg();
1022*18261Slinton     if (s1 != nil) {
1023*18261Slinton 	fprintf(stderr, s1);
1024*18261Slinton     }
1025*18261Slinton     if (e1 != nil) {
1026*18261Slinton 	prtree(stderr, e1);
1027*18261Slinton     }
1028*18261Slinton     if (s2 != nil) {
1029*18261Slinton 	fprintf(stderr, s2);
1030*18261Slinton     }
1031*18261Slinton     enderrmsg();
1032*18261Slinton }
1033*18261Slinton 
1034*18261Slinton /*
1035*18261Slinton  * Check that a subscript value is in the appropriate range.
1036*18261Slinton  */
1037*18261Slinton 
1038*18261Slinton private subchk (value, lower, upper)
1039*18261Slinton long value, lower, upper;
1040*18261Slinton {
1041*18261Slinton     if (value < lower or value > upper) {
1042*18261Slinton 	error("subscript value %d out of range [%d..%d]", value, lower, upper);
1043*18261Slinton     }
1044*18261Slinton }
1045*18261Slinton 
1046*18261Slinton /*
1047*18261Slinton  * Compute the offset for subscripting a dynamic array.
1048*18261Slinton  */
1049*18261Slinton 
1050*18261Slinton private getdynoff (ndims, sub)
1051*18261Slinton integer ndims;
1052*18261Slinton long *sub;
1053*18261Slinton {
1054*18261Slinton     long k, off, *count;
1055*18261Slinton 
1056*18261Slinton     count = (long *) sp;
1057*18261Slinton     off = 0;
1058*18261Slinton     for (k = 0; k < ndims - 1; k++) {
1059*18261Slinton 	subchk(sub[k], 0, count[k] - 1);
1060*18261Slinton 	off += (sub[k] * count[k+1]);
1061*18261Slinton     }
1062*18261Slinton     subchk(sub[ndims - 1], 0, count[ndims - 1] - 1);
1063*18261Slinton     return off + sub[ndims - 1];
1064*18261Slinton }
1065*18261Slinton 
1066*18261Slinton /*
1067*18261Slinton  * Compute the offset associated with a subarray.
1068*18261Slinton  */
1069*18261Slinton 
1070*18261Slinton private getsuboff (ndims, sub)
1071*18261Slinton integer ndims;
1072*18261Slinton long *sub;
1073*18261Slinton {
1074*18261Slinton     long k, off;
1075*18261Slinton     struct subarrayinfo {
1076*18261Slinton 	long count;
1077*18261Slinton 	long mult;
1078*18261Slinton     } *info;
1079*18261Slinton 
1080*18261Slinton     info = (struct subarrayinfo *) sp;
1081*18261Slinton     off = 0;
1082*18261Slinton     for (k = 0; k < ndims; k++) {
1083*18261Slinton 	subchk(sub[k], 0, info[k].count - 1);
1084*18261Slinton 	off += sub[k] * info[k].mult;
1085*18261Slinton     }
1086*18261Slinton     return off;
1087*18261Slinton }
1088*18261Slinton 
1089*18261Slinton /*
109016622Ssam  * Evaluate a subscript index.
109116622Ssam  */
109216622Ssam 
1093*18261Slinton public modula2_evalaref (s, base, i)
109416622Ssam Symbol s;
1095*18261Slinton Address base;
109616622Ssam long i;
109716622Ssam {
1098*18261Slinton     Symbol t;
1099*18261Slinton     long lb, ub, off;
1100*18261Slinton     long *sub;
1101*18261Slinton     Address b;
110216622Ssam 
1103*18261Slinton     t = rtype(s);
1104*18261Slinton     if (t->class == ARRAY) {
1105*18261Slinton 	findbounds(rtype(t->chain), &lb, &ub);
1106*18261Slinton 	if (i < lb or i > ub) {
1107*18261Slinton 	    error("subscript %d out of range [%d..%d]", i, lb, ub);
1108*18261Slinton 	}
1109*18261Slinton 	push(long, base + (i - lb) * size(t->type));
1110*18261Slinton     } else if (t->class == DYNARRAY and t->symvalue.ndims == 0) {
1111*18261Slinton 	push(long, base + i * size(t->type));
1112*18261Slinton     } else if (t->class == DYNARRAY or t->class == SUBARRAY) {
1113*18261Slinton 	push(long, i);
1114*18261Slinton 	sub = (long *) (sp - (t->symvalue.ndims * sizeof(long)));
1115*18261Slinton 	rpush(base, size(t));
1116*18261Slinton 	sp -= (t->symvalue.ndims * sizeof(long));
1117*18261Slinton 	b = pop(Address);
1118*18261Slinton 	sp += sizeof(Address);
1119*18261Slinton 	if (t->class == SUBARRAY) {
1120*18261Slinton 	    off = getsuboff(t->symvalue.ndims, sub);
1121*18261Slinton 	} else {
1122*18261Slinton 	    off = getdynoff(t->symvalue.ndims, sub);
1123*18261Slinton 	}
1124*18261Slinton 	sp = (Stack *) sub;
1125*18261Slinton 	push(long, b + off * size(t->type));
1126*18261Slinton     } else {
1127*18261Slinton 	error("[internal error: expected array in evalaref]");
112816622Ssam     }
112916622Ssam }
113016622Ssam 
113116622Ssam /*
113216622Ssam  * Initial Modula-2 type information.
113316622Ssam  */
113416622Ssam 
113516622Ssam #define NTYPES 12
113616622Ssam 
113716622Ssam private Symbol inittype[NTYPES + 1];
113816622Ssam 
113916622Ssam private addType (n, s, lower, upper)
114016622Ssam integer n;
114116622Ssam String s;
114216622Ssam long lower, upper;
114316622Ssam {
114416622Ssam     register Symbol t;
114516622Ssam 
114616622Ssam     if (n > NTYPES) {
114716622Ssam 	panic("initial Modula-2 type number too large for '%s'", s);
114816622Ssam     }
114916622Ssam     t = insert(identname(s, true));
115016622Ssam     t->language = mod2;
115116622Ssam     t->class = TYPE;
115216622Ssam     t->type = newSymbol(nil, 0, RANGE, t, nil);
115316622Ssam     t->type->symvalue.rangev.lower = lower;
115416622Ssam     t->type->symvalue.rangev.upper = upper;
115516622Ssam     t->type->language = mod2;
115616622Ssam     inittype[n] = t;
115716622Ssam }
115816622Ssam 
115916622Ssam private initModTypes ()
116016622Ssam {
116116622Ssam     addType(1, "integer", 0x80000000L, 0x7fffffffL);
116216622Ssam     addType(2, "char", 0L, 255L);
116316622Ssam     addType(3, "boolean", 0L, 1L);
116416622Ssam     addType(4, "unsigned", 0L, 0xffffffffL);
116516622Ssam     addType(5, "real", 4L, 0L);
116616622Ssam     addType(6, "longreal", 8L, 0L);
116716622Ssam     addType(7, "word", 0L, 0xffffffffL);
116816622Ssam     addType(8, "byte", 0L, 255L);
116916622Ssam     addType(9, "address", 0L, 0xffffffffL);
117016622Ssam     addType(10, "file", 0L, 0xffffffffL);
117116622Ssam     addType(11, "process", 0L, 0xffffffffL);
117216622Ssam     addType(12, "cardinal", 0L, 0x7fffffffL);
117316622Ssam }
117416622Ssam 
117516622Ssam /*
117616622Ssam  * Initialize typetable.
117716622Ssam  */
117816622Ssam 
117916622Ssam public modula2_modinit (typetable)
118016622Ssam Symbol typetable[];
118116622Ssam {
118216622Ssam     register integer i;
118316622Ssam 
118416622Ssam     if (not initialized) {
118516622Ssam 	initModTypes();
1186*18261Slinton 	initialized = true;
118716622Ssam     }
118816622Ssam     for (i = 1; i <= NTYPES; i++) {
118916622Ssam 	typetable[i] = inittype[i];
119016622Ssam     }
119116622Ssam }
119216622Ssam 
119316622Ssam public boolean modula2_hasmodules ()
119416622Ssam {
119516622Ssam     return true;
119616622Ssam }
119716622Ssam 
119816622Ssam public boolean modula2_passaddr (param, exprtype)
119916622Ssam Symbol param, exprtype;
120016622Ssam {
120116622Ssam     return false;
120216622Ssam }
1203