file reorg, pathnames.h, paths.h
[unix-history] / usr / src / old / dbx / modula-2.c
CommitLineData
2a24676e
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
24a8418a 6
a629ae97 7#ifndef lint
9606e7b9 8static char sccsid[] = "@(#)modula-2.c 5.2 (Berkeley) %G%";
2a24676e 9#endif not lint
a629ae97
SL
10
11/*
12 * Modula-2 specific symbol routines.
13 */
14
9606e7b9 15static char rcsid[] = "$Header: modula-2.c,v 1.2 87/03/26 20:12:54 donn Exp $";
24a8418a 16
a629ae97
SL
17#include "defs.h"
18#include "symbols.h"
19#include "modula-2.h"
20#include "languages.h"
21#include "tree.h"
22#include "eval.h"
23#include "mappings.h"
24#include "process.h"
25#include "runtime.h"
26#include "machine.h"
27
28#ifndef public
29#endif
30
31private Language mod2;
32private boolean initialized;
33
24a8418a
ML
34
35#define ischar(t) ( \
36 (t) == t_char->type or \
37 ((t)->class == RANGE and istypename((t)->type, "char")) \
38)
39
a629ae97
SL
40/*
41 * Initialize Modula-2 information.
42 */
43
44public modula2_init ()
45{
46 mod2 = language_define("modula-2", ".mod");
47 language_setop(mod2, L_PRINTDECL, modula2_printdecl);
48 language_setop(mod2, L_PRINTVAL, modula2_printval);
49 language_setop(mod2, L_TYPEMATCH, modula2_typematch);
50 language_setop(mod2, L_BUILDAREF, modula2_buildaref);
51 language_setop(mod2, L_EVALAREF, modula2_evalaref);
52 language_setop(mod2, L_MODINIT, modula2_modinit);
53 language_setop(mod2, L_HASMODULES, modula2_hasmodules);
54 language_setop(mod2, L_PASSADDR, modula2_passaddr);
55 initialized = false;
56}
57
58/*
59 * Typematch tests if two types are compatible. The issue
60 * is a bit complicated, so several subfunctions are used for
61 * various kinds of compatibility.
62 */
63
24a8418a
ML
64private boolean builtinmatch (t1, t2)
65register Symbol t1, t2;
66{
67 boolean b;
68
69 b = (boolean) (
70 (
71 t2 == t_int->type and t1->class == RANGE and
72 (
73 istypename(t1->type, "integer") or
74 istypename(t1->type, "cardinal")
75 )
76 ) or (
77 t2 == t_char->type and
78 t1->class == RANGE and istypename(t1->type, "char")
79 ) or (
80 t2 == t_real->type and
81 t1->class == RANGE and (
82 istypename(t1->type, "real") or
83 istypename(t1->type, "longreal")
84 )
85 ) or (
86 t2 == t_boolean->type and
87 t1->class == RANGE and istypename(t1->type, "boolean")
88 )
89 );
90 return b;
91}
92
a629ae97
SL
93private boolean nilMatch (t1, t2)
94register Symbol t1, t2;
95{
96 boolean b;
97
98 b = (boolean) (
99 (t1 == t_nil and t2->class == PTR) or
100 (t1->class == PTR and t2 == t_nil)
101 );
102 return b;
103}
104
105private boolean enumMatch (t1, t2)
106register Symbol t1, t2;
107{
108 boolean b;
109
110 b = (boolean) (
24a8418a
ML
111 (t1->class == SCAL and t2->class == CONST and t2->type == t1) or
112 (t1->class == CONST and t2->class == SCAL and t1->type == t2)
a629ae97
SL
113 );
114 return b;
115}
116
117private boolean openArrayMatch (t1, t2)
118register Symbol t1, t2;
119{
120 boolean b;
121
122 b = (boolean) (
123 (
9606e7b9 124 t1->class == OPENARRAY and t1->symvalue.ndims == 1 and
a629ae97
SL
125 t2->class == ARRAY and
126 compatible(rtype(t2->chain)->type, t_int) and
127 compatible(t1->type, t2->type)
128 ) or (
9606e7b9 129 t2->class == OPENARRAY and t2->symvalue.ndims == 1 and
a629ae97
SL
130 t1->class == ARRAY and
131 compatible(rtype(t1->chain)->type, t_int) and
132 compatible(t1->type, t2->type)
133 )
134 );
135 return b;
136}
137
138private boolean isConstString (t)
139register Symbol t;
140{
141 boolean b;
142
143 b = (boolean) (
144 t->language == primlang and t->class == ARRAY and t->type == t_char
145 );
146 return b;
147}
148
149private boolean stringArrayMatch (t1, t2)
150register Symbol t1, t2;
151{
152 boolean b;
153
154 b = (boolean) (
155 (
156 isConstString(t1) and
157 t2->class == ARRAY and compatible(t2->type, t_char->type)
158 ) or (
159 isConstString(t2) and
160 t1->class == ARRAY and compatible(t1->type, t_char->type)
161 )
162 );
163 return b;
164}
165
166public boolean modula2_typematch (type1, type2)
167Symbol type1, type2;
168{
24a8418a 169 boolean b;
a629ae97
SL
170 Symbol t1, t2, tmp;
171
172 t1 = rtype(type1);
173 t2 = rtype(type2);
174 if (t1 == t2) {
175 b = true;
176 } else {
24a8418a
ML
177 if (t1 == t_char->type or t1 == t_int->type or
178 t1 == t_real->type or t1 == t_boolean->type
179 ) {
a629ae97
SL
180 tmp = t1;
181 t1 = t2;
182 t2 = tmp;
183 }
184 b = (Boolean) (
9606e7b9 185 builtinmatch(t1, t2) or
24a8418a
ML
186 nilMatch(t1, t2) or enumMatch(t1, t2) or
187 openArrayMatch(t1, t2) or stringArrayMatch(t1, t2)
a629ae97
SL
188 );
189 }
190 return b;
191}
192
193/*
194 * Indent n spaces.
195 */
196
197private indent (n)
198int n;
199{
200 if (n > 0) {
201 printf("%*c", n, ' ');
202 }
203}
204
205public modula2_printdecl (s)
206Symbol s;
207{
208 register Symbol t;
209 Boolean semicolon;
210
211 semicolon = true;
212 if (s->class == TYPEREF) {
213 resolveRef(t);
214 }
215 switch (s->class) {
216 case CONST:
217 if (s->type->class == SCAL) {
24a8418a
ML
218 semicolon = false;
219 printf("enumeration constant with value ");
220 eval(s->symvalue.constval);
221 modula2_printval(s);
a629ae97
SL
222 } else {
223 printf("const %s = ", symname(s));
24a8418a 224 eval(s->symvalue.constval);
a629ae97
SL
225 modula2_printval(s);
226 }
227 break;
228
229 case TYPE:
230 printf("type %s = ", symname(s));
231 printtype(s, s->type, 0);
232 break;
233
234 case TYPEREF:
235 printf("type %s", symname(s));
236 break;
237
238 case VAR:
239 if (isparam(s)) {
240 printf("(parameter) %s : ", symname(s));
241 } else {
242 printf("var %s : ", symname(s));
243 }
244 printtype(s, s->type, 0);
245 break;
246
247 case REF:
248 printf("(var parameter) %s : ", symname(s));
249 printtype(s, s->type, 0);
250 break;
251
252 case RANGE:
253 case ARRAY:
9606e7b9 254 case OPENARRAY:
24a8418a
ML
255 case DYNARRAY:
256 case SUBARRAY:
a629ae97
SL
257 case RECORD:
258 case VARNT:
259 case PTR:
260 printtype(s, s, 0);
261 semicolon = false;
262 break;
263
264 case FVAR:
265 printf("(function variable) %s : ", symname(s));
266 printtype(s, s->type, 0);
267 break;
268
269 case FIELD:
270 printf("(field) %s : ", symname(s));
271 printtype(s, s->type, 0);
272 break;
273
274 case PROC:
275 printf("procedure %s", symname(s));
276 listparams(s);
277 break;
278
279 case PROG:
280 printf("program %s", symname(s));
281 listparams(s);
282 break;
283
284 case FUNC:
24a8418a 285 printf("procedure %s", symname(s));
a629ae97
SL
286 listparams(s);
287 printf(" : ");
288 printtype(s, s->type, 0);
289 break;
290
291 case MODULE:
292 printf("module %s", symname(s));
293 break;
294
295 default:
24a8418a 296 printf("[%s]", classname(s));
a629ae97
SL
297 break;
298 }
299 if (semicolon) {
300 putchar(';');
301 }
302 putchar('\n');
303}
304
305/*
306 * Recursive whiz-bang procedure to print the type portion
307 * of a declaration.
308 *
309 * The symbol associated with the type is passed to allow
310 * searching for type names without getting "type blah = blah".
311 */
312
313private printtype (s, t, n)
314Symbol s;
315Symbol t;
316int n;
317{
24a8418a
ML
318 Symbol tmp;
319 int i;
a629ae97
SL
320
321 if (t->class == TYPEREF) {
322 resolveRef(t);
323 }
324 switch (t->class) {
325 case VAR:
326 case CONST:
327 case FUNC:
328 case PROC:
329 panic("printtype: class %s", classname(t));
330 break;
331
332 case ARRAY:
333 printf("array[");
334 tmp = t->chain;
335 if (tmp != nil) {
336 for (;;) {
337 printtype(tmp, tmp, n);
338 tmp = tmp->chain;
339 if (tmp == nil) {
340 break;
341 }
342 printf(", ");
343 }
344 }
345 printf("] of ");
346 printtype(t, t->type, n);
347 break;
348
9606e7b9
DS
349 case OPENARRAY:
350 printf("array of ");
351 for (i = 1; i < t->symvalue.ndims; i++) {
352 printf("array of ");
353 }
354 printtype(t, t->type, n);
355 break;
356
24a8418a
ML
357 case DYNARRAY:
358 printf("dynarray of ");
359 for (i = 1; i < t->symvalue.ndims; i++) {
360 printf("array of ");
361 }
362 printtype(t, t->type, n);
363 break;
364
365 case SUBARRAY:
366 printf("subarray of ");
367 for (i = 1; i < t->symvalue.ndims; i++) {
368 printf("array of ");
369 }
370 printtype(t, t->type, n);
371 break;
372
a629ae97
SL
373 case RECORD:
374 printRecordDecl(t, n);
375 break;
376
377 case FIELD:
378 if (t->chain != nil) {
379 printtype(t->chain, t->chain, n);
380 }
381 printf("\t%s : ", symname(t));
382 printtype(t, t->type, n);
383 printf(";\n");
384 break;
385
386 case RANGE:
387 printRangeDecl(t);
388 break;
389
390 case PTR:
391 printf("pointer to ");
392 printtype(t, t->type, n);
393 break;
394
395 case TYPE:
396 if (t->name != nil and ident(t->name)[0] != '\0') {
397 printname(stdout, t);
398 } else {
399 printtype(t, t->type, n);
400 }
401 break;
402
403 case SCAL:
404 printEnumDecl(t, n);
405 break;
406
407 case SET:
408 printf("set of ");
409 printtype(t, t->type, n);
410 break;
411
412 case TYPEREF:
413 break;
414
24a8418a
ML
415 case FPROC:
416 case FFUNC:
417 printf("procedure");
418 break;
419
a629ae97 420 default:
24a8418a 421 printf("[%s]", classname(t));
a629ae97
SL
422 break;
423 }
424}
425
426/*
427 * Print out a record declaration.
428 */
429
430private printRecordDecl (t, n)
431Symbol t;
432int n;
433{
434 register Symbol f;
435
436 if (t->chain == nil) {
437 printf("record end");
438 } else {
439 printf("record\n");
440 for (f = t->chain; f != nil; f = f->chain) {
441 indent(n+4);
442 printf("%s : ", symname(f));
443 printtype(f->type, f->type, n+4);
444 printf(";\n");
445 }
446 indent(n);
447 printf("end");
448 }
449}
450
451/*
452 * Print out the declaration of a range type.
453 */
454
455private printRangeDecl (t)
456Symbol t;
457{
458 long r0, r1;
459
460 r0 = t->symvalue.rangev.lower;
461 r1 = t->symvalue.rangev.upper;
24a8418a 462 if (ischar(t)) {
a629ae97
SL
463 if (r0 < 0x20 or r0 > 0x7e) {
464 printf("%ld..", r0);
465 } else {
466 printf("'%c'..", (char) r0);
467 }
468 if (r1 < 0x20 or r1 > 0x7e) {
469 printf("\\%lo", r1);
470 } else {
471 printf("'%c'", (char) r1);
472 }
473 } else if (r0 > 0 and r1 == 0) {
474 printf("%ld byte real", r0);
475 } else if (r0 >= 0) {
476 printf("%lu..%lu", r0, r1);
477 } else {
478 printf("%ld..%ld", r0, r1);
479 }
480}
481
482/*
483 * Print out an enumeration declaration.
484 */
485
486private printEnumDecl (e, n)
487Symbol e;
488int n;
489{
490 Symbol t;
491
492 printf("(");
493 t = e->chain;
494 if (t != nil) {
495 printf("%s", symname(t));
496 t = t->chain;
497 while (t != nil) {
498 printf(", %s", symname(t));
499 t = t->chain;
500 }
501 }
502 printf(")");
503}
504
505/*
506 * List the parameters of a procedure or function.
507 * No attempt is made to combine like types.
508 */
509
510private listparams (s)
511Symbol s;
512{
513 Symbol t;
514
515 if (s->chain != nil) {
516 putchar('(');
517 for (t = s->chain; t != nil; t = t->chain) {
518 switch (t->class) {
519 case REF:
520 printf("var ");
521 break;
522
523 case FPROC:
524 case FFUNC:
525 printf("procedure ");
526 break;
527
528 case VAR:
529 break;
530
531 default:
532 panic("unexpected class %d for parameter", t->class);
533 }
534 printf("%s", symname(t));
535 if (s->class == PROG) {
536 printf(", ");
537 } else {
538 printf(" : ");
539 printtype(t, t->type, 0);
540 if (t->chain != nil) {
541 printf("; ");
542 }
543 }
544 }
545 putchar(')');
546 }
547}
548
24a8418a
ML
549/*
550 * Test if a pointer type should be treated as a null-terminated string.
551 * The type given is the type that is pointed to.
552 */
553
554private boolean isCstring (type)
555Symbol type;
556{
557 boolean b;
558 register Symbol a, t;
559
560 a = rtype(type);
561 if (a->class == ARRAY) {
562 t = rtype(a->chain);
563 b = (boolean) (
564 t->class == RANGE and istypename(a->type, "char") and
565 (t->symvalue.rangev.upper - t->symvalue.rangev.lower + 1) <= 0
566 );
567 } else {
568 b = false;
569 }
570 return b;
571}
572
a629ae97
SL
573/*
574 * Modula 2 interface to printval.
575 */
576
577public modula2_printval (s)
578Symbol s;
579{
580 prval(s, size(s));
581}
582
583/*
584 * Print out the value on the top of the expression stack
585 * in the format for the type of the given symbol, assuming
586 * the size of the object is n bytes.
587 */
588
589private prval (s, n)
590Symbol s;
591integer n;
592{
593 Symbol t;
594 Address a;
595 integer len;
596 double r;
24a8418a 597 integer i;
a629ae97
SL
598
599 if (s->class == TYPEREF) {
600 resolveRef(s);
601 }
602 switch (s->class) {
603 case CONST:
604 case TYPE:
a629ae97 605 case REF:
24a8418a 606 case VAR:
a629ae97
SL
607 case FVAR:
608 case TAG:
a629ae97
SL
609 prval(s->type, n);
610 break;
611
24a8418a
ML
612 case FIELD:
613 if (isbitfield(s)) {
9606e7b9 614 i = extractField(s);
24a8418a
ML
615 t = rtype(s->type);
616 if (t->class == SCAL) {
617 printEnum(i, t);
618 } else {
619 printRangeVal(i, t);
620 }
621 } else {
622 prval(s->type, n);
623 }
624 break;
625
a629ae97
SL
626 case ARRAY:
627 t = rtype(s->type);
24a8418a 628 if (ischar(t)) {
a629ae97
SL
629 len = size(s);
630 sp -= len;
24a8418a 631 printf("\"%.*s\"", len, sp);
a629ae97
SL
632 break;
633 } else {
634 printarray(s);
635 }
636 break;
637
9606e7b9 638 case OPENARRAY:
24a8418a
ML
639 case DYNARRAY:
640 printDynarray(s);
641 break;
642
643 case SUBARRAY:
644 printSubarray(s);
645 break;
646
a629ae97
SL
647 case RECORD:
648 printrecord(s);
649 break;
650
651 case VARNT:
24a8418a 652 printf("[variant]");
a629ae97
SL
653 break;
654
655 case RANGE:
656 printrange(s, n);
657 break;
658
24a8418a
ML
659 /*
660 * Unresolved opaque type.
661 * Probably a pointer.
662 */
663 case TYPEREF:
664 a = pop(Address);
665 printf("@%x", a);
666 break;
667
a629ae97 668 case FILET:
24a8418a
ML
669 a = pop(Address);
670 if (a == 0) {
671 printf("nil");
672 } else {
673 printf("0x%x", a);
674 }
675 break;
676
a629ae97
SL
677 case PTR:
678 a = pop(Address);
679 if (a == 0) {
680 printf("nil");
24a8418a
ML
681 } else if (isCstring(s->type)) {
682 printString(a, true);
a629ae97
SL
683 } else {
684 printf("0x%x", a);
685 }
686 break;
687
688 case SCAL:
24a8418a
ML
689 i = 0;
690 popn(n, &i);
691 printEnum(i, s);
a629ae97
SL
692 break;
693
694 case FPROC:
695 case FFUNC:
696 a = pop(long);
697 t = whatblock(a);
698 if (t == nil) {
24a8418a 699 printf("0x%x", a);
a629ae97 700 } else {
24a8418a 701 printname(stdout, t);
a629ae97
SL
702 }
703 break;
704
705 case SET:
706 printSet(s);
707 break;
708
709 default:
710 if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) {
711 panic("printval: bad class %d", ord(s->class));
712 }
713 printf("[%s]", classname(s));
714 break;
715 }
716}
717
24a8418a
ML
718/*
719 * Print out a dynamic array.
720 */
721
722private Address printDynSlice();
723
724private printDynarray (t)
725Symbol t;
726{
727 Address base;
728 integer n;
729 Stack *savesp, *newsp;
730 Symbol eltype;
731
732 savesp = sp;
733 sp -= (t->symvalue.ndims * sizeof(Word));
734 base = pop(Address);
735 newsp = sp;
736 sp = savesp;
737 eltype = rtype(t->type);
738 if (t->symvalue.ndims == 0) {
739 if (ischar(eltype)) {
740 printString(base, true);
741 } else {
742 printf("[dynarray @nocount]");
743 }
744 } else {
745 n = ((long *) sp)[-(t->symvalue.ndims)];
746 base = printDynSlice(base, n, t->symvalue.ndims, eltype, size(eltype));
747 }
748 sp = newsp;
749}
750
751/*
752 * Print out one dimension of a multi-dimension dynamic array.
753 *
754 * Return the address of the element that follows the printed elements.
755 */
756
757private Address printDynSlice (base, count, ndims, eltype, elsize)
758Address base;
759integer count, ndims;
760Symbol eltype;
761integer elsize;
762{
763 Address b;
764 integer i, n;
765 char *slice;
766 Stack *savesp;
767
768 b = base;
769 if (ndims > 1) {
770 n = ((long *) sp)[-ndims + 1];
771 }
772 if (ndims == 1 and ischar(eltype)) {
773 slice = newarr(char, count);
774 dread(slice, b, count);
775 printf("\"%.*s\"", count, slice);
776 dispose(slice);
777 b += count;
778 } else {
779 printf("(");
780 for (i = 0; i < count; i++) {
781 if (i != 0) {
782 printf(", ");
783 }
784 if (ndims == 1) {
785 slice = newarr(char, elsize);
786 dread(slice, b, elsize);
787 savesp = sp;
788 sp = slice + elsize;
789 printval(eltype);
790 sp = savesp;
791 dispose(slice);
792 b += elsize;
793 } else {
794 b = printDynSlice(b, n, ndims - 1, eltype, elsize);
795 }
796 }
797 printf(")");
798 }
799 return b;
800}
801
802private printSubarray (t)
803Symbol t;
804{
805 printf("[subarray]");
806}
807
a629ae97
SL
808/*
809 * Print out the value of a scalar (non-enumeration) type.
810 */
811
812private printrange (s, n)
813Symbol s;
814integer n;
815{
816 double d;
817 float f;
818 integer i;
819
820 if (s->symvalue.rangev.upper == 0 and s->symvalue.rangev.lower > 0) {
821 if (n == sizeof(float)) {
822 popn(n, &f);
823 d = f;
824 } else {
825 popn(n, &d);
826 }
827 prtreal(d);
828 } else {
829 i = 0;
830 popn(n, &i);
24a8418a 831 printRangeVal(i, s);
a629ae97
SL
832 }
833}
834
835/*
836 * Print out a set.
837 */
838
839private printSet (s)
840Symbol s;
841{
842 Symbol t;
843 integer nbytes;
844
845 nbytes = size(s);
846 t = rtype(s->type);
847 printf("{");
848 sp -= nbytes;
849 if (t->class == SCAL) {
850 printSetOfEnum(t);
851 } else if (t->class == RANGE) {
852 printSetOfRange(t);
853 } else {
854 panic("expected range or enumerated base type for set");
855 }
856 printf("}");
857}
858
859/*
860 * Print out a set of an enumeration.
861 */
862
863private printSetOfEnum (t)
864Symbol t;
865{
866 register Symbol e;
867 register integer i, j, *p;
868 boolean first;
869
870 p = (int *) sp;
871 i = *p;
872 j = 0;
873 e = t->chain;
874 first = true;
875 while (e != nil) {
876 if ((i&1) == 1) {
877 if (first) {
878 first = false;
879 printf("%s", symname(e));
880 } else {
881 printf(", %s", symname(e));
882 }
883 }
884 i >>= 1;
885 ++j;
886 if (j >= sizeof(integer)*BITSPERBYTE) {
887 j = 0;
888 ++p;
889 i = *p;
890 }
891 e = e->chain;
892 }
893}
894
895/*
896 * Print out a set of a subrange type.
897 */
898
899private printSetOfRange (t)
900Symbol t;
901{
902 register integer i, j, *p;
903 long v;
904 boolean first;
905
906 p = (int *) sp;
907 i = *p;
908 j = 0;
909 v = t->symvalue.rangev.lower;
910 first = true;
911 while (v <= t->symvalue.rangev.upper) {
912 if ((i&1) == 1) {
913 if (first) {
914 first = false;
915 printf("%ld", v);
916 } else {
917 printf(", %ld", v);
918 }
919 }
920 i >>= 1;
921 ++j;
922 if (j >= sizeof(integer)*BITSPERBYTE) {
923 j = 0;
924 ++p;
925 i = *p;
926 }
927 ++v;
928 }
929}
930
24a8418a
ML
931/*
932 * Construct a node for subscripting a dynamic or subarray.
933 * The list of indices is left for processing in evalaref,
934 * unlike normal subscripting in which the list is expanded
935 * across individual INDEX nodes.
936 */
937
938private Node dynref (a, t, slist)
939Node a;
940Symbol t;
941Node slist;
942{
943 Node p, r;
944 integer n;
945
946 p = slist;
947 n = 0;
948 while (p != nil) {
949 if (not compatible(p->value.arg[0]->nodetype, t_int)) {
950 suberror("subscript \"", p->value.arg[0], "\" is the wrong type");
951 }
952 ++n;
953 p = p->value.arg[1];
954 }
955 if (n > t->symvalue.ndims and (t->symvalue.ndims != 0 or n != 1)) {
956 suberror("too many subscripts for ", a, nil);
957 } else if (n < t->symvalue.ndims) {
958 suberror("not enough subscripts for ", a, nil);
959 }
960 r = build(O_INDEX, a, slist);
961 r->nodetype = rtype(t->type);
962 return r;
963}
964
a629ae97
SL
965/*
966 * Construct a node for subscripting.
967 */
968
969public Node modula2_buildaref (a, slist)
970Node a, slist;
971{
972 register Symbol t;
973 register Node p;
24a8418a 974 Symbol eltype;
a629ae97 975 Node esub, r;
24a8418a 976 integer n;
a629ae97 977
a629ae97 978 t = rtype(a->nodetype);
9606e7b9
DS
979 switch (t->class) {
980 case OPENARRAY:
981 case DYNARRAY:
982 case SUBARRAY:
983 r = dynref(a, t, slist);
984 break;
985
986 case ARRAY:
987 r = a;
988 eltype = rtype(t->type);
989 p = slist;
24a8418a 990 t = t->chain;
9606e7b9
DS
991 while (p != nil and t != nil) {
992 esub = p->value.arg[0];
993 if (not compatible(rtype(t), rtype(esub->nodetype))) {
994 suberror("subscript \"", esub, "\" is the wrong type");
995 }
996 r = build(O_INDEX, r, esub);
997 r->nodetype = eltype;
998 p = p->value.arg[1];
999 t = t->chain;
1000 }
1001 if (p != nil) {
1002 suberror("too many subscripts for ", a, nil);
1003 } else if (t != nil) {
1004 suberror("not enough subscripts for ", a, nil);
1005 }
1006 break;
1007
1008 default:
1009 suberror("\"", a, "\" is not an array");
1010 break;
a629ae97
SL
1011 }
1012 return r;
1013}
1014
24a8418a
ML
1015/*
1016 * Subscript usage error reporting.
1017 */
1018
1019private suberror (s1, e1, s2)
1020String s1, s2;
1021Node e1;
1022{
1023 beginerrmsg();
1024 if (s1 != nil) {
1025 fprintf(stderr, s1);
1026 }
1027 if (e1 != nil) {
1028 prtree(stderr, e1);
1029 }
1030 if (s2 != nil) {
1031 fprintf(stderr, s2);
1032 }
1033 enderrmsg();
1034}
1035
1036/*
1037 * Check that a subscript value is in the appropriate range.
1038 */
1039
1040private subchk (value, lower, upper)
1041long value, lower, upper;
1042{
1043 if (value < lower or value > upper) {
1044 error("subscript value %d out of range [%d..%d]", value, lower, upper);
1045 }
1046}
1047
1048/*
1049 * Compute the offset for subscripting a dynamic array.
1050 */
1051
1052private getdynoff (ndims, sub)
1053integer ndims;
1054long *sub;
1055{
1056 long k, off, *count;
1057
1058 count = (long *) sp;
1059 off = 0;
1060 for (k = 0; k < ndims - 1; k++) {
1061 subchk(sub[k], 0, count[k] - 1);
1062 off += (sub[k] * count[k+1]);
1063 }
1064 subchk(sub[ndims - 1], 0, count[ndims - 1] - 1);
1065 return off + sub[ndims - 1];
1066}
1067
1068/*
1069 * Compute the offset associated with a subarray.
1070 */
1071
1072private getsuboff (ndims, sub)
1073integer ndims;
1074long *sub;
1075{
1076 long k, off;
1077 struct subarrayinfo {
1078 long count;
1079 long mult;
1080 } *info;
1081
1082 info = (struct subarrayinfo *) sp;
1083 off = 0;
1084 for (k = 0; k < ndims; k++) {
1085 subchk(sub[k], 0, info[k].count - 1);
1086 off += sub[k] * info[k].mult;
1087 }
1088 return off;
1089}
1090
a629ae97
SL
1091/*
1092 * Evaluate a subscript index.
1093 */
1094
24a8418a 1095public modula2_evalaref (s, base, i)
a629ae97 1096Symbol s;
24a8418a 1097Address base;
a629ae97
SL
1098long i;
1099{
24a8418a
ML
1100 Symbol t;
1101 long lb, ub, off;
1102 long *sub;
1103 Address b;
1104
1105 t = rtype(s);
1106 if (t->class == ARRAY) {
1107 findbounds(rtype(t->chain), &lb, &ub);
1108 if (i < lb or i > ub) {
1109 error("subscript %d out of range [%d..%d]", i, lb, ub);
1110 }
1111 push(long, base + (i - lb) * size(t->type));
9606e7b9
DS
1112 } else if ((t->class == OPENARRAY or t->class == DYNARRAY) and
1113 t->symvalue.ndims == 0
1114 ) {
24a8418a 1115 push(long, base + i * size(t->type));
9606e7b9
DS
1116 } else if (t->class == OPENARRAY or t->class == DYNARRAY or
1117 t->class == SUBARRAY
1118 ) {
24a8418a
ML
1119 push(long, i);
1120 sub = (long *) (sp - (t->symvalue.ndims * sizeof(long)));
1121 rpush(base, size(t));
1122 sp -= (t->symvalue.ndims * sizeof(long));
1123 b = pop(Address);
1124 sp += sizeof(Address);
1125 if (t->class == SUBARRAY) {
1126 off = getsuboff(t->symvalue.ndims, sub);
1127 } else {
1128 off = getdynoff(t->symvalue.ndims, sub);
1129 }
1130 sp = (Stack *) sub;
1131 push(long, b + off * size(t->type));
1132 } else {
1133 error("[internal error: expected array in evalaref]");
a629ae97 1134 }
a629ae97
SL
1135}
1136
1137/*
1138 * Initial Modula-2 type information.
1139 */
1140
1141#define NTYPES 12
1142
1143private Symbol inittype[NTYPES + 1];
1144
1145private addType (n, s, lower, upper)
1146integer n;
1147String s;
1148long lower, upper;
1149{
1150 register Symbol t;
1151
1152 if (n > NTYPES) {
1153 panic("initial Modula-2 type number too large for '%s'", s);
1154 }
1155 t = insert(identname(s, true));
1156 t->language = mod2;
1157 t->class = TYPE;
1158 t->type = newSymbol(nil, 0, RANGE, t, nil);
1159 t->type->symvalue.rangev.lower = lower;
1160 t->type->symvalue.rangev.upper = upper;
1161 t->type->language = mod2;
1162 inittype[n] = t;
1163}
1164
1165private initModTypes ()
1166{
1167 addType(1, "integer", 0x80000000L, 0x7fffffffL);
1168 addType(2, "char", 0L, 255L);
1169 addType(3, "boolean", 0L, 1L);
1170 addType(4, "unsigned", 0L, 0xffffffffL);
1171 addType(5, "real", 4L, 0L);
1172 addType(6, "longreal", 8L, 0L);
1173 addType(7, "word", 0L, 0xffffffffL);
1174 addType(8, "byte", 0L, 255L);
1175 addType(9, "address", 0L, 0xffffffffL);
1176 addType(10, "file", 0L, 0xffffffffL);
1177 addType(11, "process", 0L, 0xffffffffL);
1178 addType(12, "cardinal", 0L, 0x7fffffffL);
1179}
1180
1181/*
1182 * Initialize typetable.
1183 */
1184
1185public modula2_modinit (typetable)
1186Symbol typetable[];
1187{
1188 register integer i;
1189
1190 if (not initialized) {
1191 initModTypes();
24a8418a 1192 initialized = true;
a629ae97
SL
1193 }
1194 for (i = 1; i <= NTYPES; i++) {
1195 typetable[i] = inittype[i];
1196 }
1197}
1198
1199public boolean modula2_hasmodules ()
1200{
1201 return true;
1202}
1203
1204public boolean modula2_passaddr (param, exprtype)
1205Symbol param, exprtype;
1206{
1207 return false;
1208}