|
|
1.1 root 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: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)modula-2.c 5.2 (Berkeley) 1/12/88";
9: #endif not lint
10:
11: /*
12: * Modula-2 specific symbol routines.
13: */
14:
15: static char rcsid[] = "$Header: modula-2.c,v 1.2 87/03/26 20:12:54 donn Exp $";
16:
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:
31: private Language mod2;
32: private boolean initialized;
33:
34:
35: #define ischar(t) ( \
36: (t) == t_char->type or \
37: ((t)->class == RANGE and istypename((t)->type, "char")) \
38: )
39:
40: /*
41: * Initialize Modula-2 information.
42: */
43:
44: public 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:
64: private boolean builtinmatch (t1, t2)
65: register 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:
93: private boolean nilMatch (t1, t2)
94: register 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:
105: private boolean enumMatch (t1, t2)
106: register Symbol t1, t2;
107: {
108: boolean b;
109:
110: b = (boolean) (
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)
113: );
114: return b;
115: }
116:
117: private boolean openArrayMatch (t1, t2)
118: register Symbol t1, t2;
119: {
120: boolean b;
121:
122: b = (boolean) (
123: (
124: t1->class == OPENARRAY and t1->symvalue.ndims == 1 and
125: t2->class == ARRAY and
126: compatible(rtype(t2->chain)->type, t_int) and
127: compatible(t1->type, t2->type)
128: ) or (
129: t2->class == OPENARRAY and t2->symvalue.ndims == 1 and
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:
138: private boolean isConstString (t)
139: register 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:
149: private boolean stringArrayMatch (t1, t2)
150: register 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:
166: public boolean modula2_typematch (type1, type2)
167: Symbol type1, type2;
168: {
169: boolean b;
170: Symbol t1, t2, tmp;
171:
172: t1 = rtype(type1);
173: t2 = rtype(type2);
174: if (t1 == t2) {
175: b = true;
176: } else {
177: if (t1 == t_char->type or t1 == t_int->type or
178: t1 == t_real->type or t1 == t_boolean->type
179: ) {
180: tmp = t1;
181: t1 = t2;
182: t2 = tmp;
183: }
184: b = (Boolean) (
185: builtinmatch(t1, t2) or
186: nilMatch(t1, t2) or enumMatch(t1, t2) or
187: openArrayMatch(t1, t2) or stringArrayMatch(t1, t2)
188: );
189: }
190: return b;
191: }
192:
193: /*
194: * Indent n spaces.
195: */
196:
197: private indent (n)
198: int n;
199: {
200: if (n > 0) {
201: printf("%*c", n, ' ');
202: }
203: }
204:
205: public modula2_printdecl (s)
206: Symbol 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) {
218: semicolon = false;
219: printf("enumeration constant with value ");
220: eval(s->symvalue.constval);
221: modula2_printval(s);
222: } else {
223: printf("const %s = ", symname(s));
224: eval(s->symvalue.constval);
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:
254: case OPENARRAY:
255: case DYNARRAY:
256: case SUBARRAY:
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:
285: printf("procedure %s", symname(s));
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:
296: printf("[%s]", classname(s));
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:
313: private printtype (s, t, n)
314: Symbol s;
315: Symbol t;
316: int n;
317: {
318: Symbol tmp;
319: int i;
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:
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:
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:
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:
415: case FPROC:
416: case FFUNC:
417: printf("procedure");
418: break;
419:
420: default:
421: printf("[%s]", classname(t));
422: break;
423: }
424: }
425:
426: /*
427: * Print out a record declaration.
428: */
429:
430: private printRecordDecl (t, n)
431: Symbol t;
432: int 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:
455: private printRangeDecl (t)
456: Symbol t;
457: {
458: long r0, r1;
459:
460: r0 = t->symvalue.rangev.lower;
461: r1 = t->symvalue.rangev.upper;
462: if (ischar(t)) {
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:
486: private printEnumDecl (e, n)
487: Symbol e;
488: int 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:
510: private listparams (s)
511: Symbol 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:
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:
554: private boolean isCstring (type)
555: Symbol 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:
573: /*
574: * Modula 2 interface to printval.
575: */
576:
577: public modula2_printval (s)
578: Symbol 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:
589: private prval (s, n)
590: Symbol s;
591: integer n;
592: {
593: Symbol t;
594: Address a;
595: integer len;
596: double r;
597: integer i;
598:
599: if (s->class == TYPEREF) {
600: resolveRef(s);
601: }
602: switch (s->class) {
603: case CONST:
604: case TYPE:
605: case REF:
606: case VAR:
607: case FVAR:
608: case TAG:
609: prval(s->type, n);
610: break;
611:
612: case FIELD:
613: if (isbitfield(s)) {
614: i = extractField(s);
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:
626: case ARRAY:
627: t = rtype(s->type);
628: if (ischar(t)) {
629: len = size(s);
630: sp -= len;
631: printf("\"%.*s\"", len, sp);
632: break;
633: } else {
634: printarray(s);
635: }
636: break;
637:
638: case OPENARRAY:
639: case DYNARRAY:
640: printDynarray(s);
641: break;
642:
643: case SUBARRAY:
644: printSubarray(s);
645: break;
646:
647: case RECORD:
648: printrecord(s);
649: break;
650:
651: case VARNT:
652: printf("[variant]");
653: break;
654:
655: case RANGE:
656: printrange(s, n);
657: break;
658:
659: /*
660: * Unresolved opaque type.
661: * Probably a pointer.
662: */
663: case TYPEREF:
664: a = pop(Address);
665: printf("@%x", a);
666: break;
667:
668: case FILET:
669: a = pop(Address);
670: if (a == 0) {
671: printf("nil");
672: } else {
673: printf("0x%x", a);
674: }
675: break;
676:
677: case PTR:
678: a = pop(Address);
679: if (a == 0) {
680: printf("nil");
681: } else if (isCstring(s->type)) {
682: printString(a, true);
683: } else {
684: printf("0x%x", a);
685: }
686: break;
687:
688: case SCAL:
689: i = 0;
690: popn(n, &i);
691: printEnum(i, s);
692: break;
693:
694: case FPROC:
695: case FFUNC:
696: a = pop(long);
697: t = whatblock(a);
698: if (t == nil) {
699: printf("0x%x", a);
700: } else {
701: printname(stdout, t);
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:
718: /*
719: * Print out a dynamic array.
720: */
721:
722: private Address printDynSlice();
723:
724: private printDynarray (t)
725: Symbol 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:
757: private Address printDynSlice (base, count, ndims, eltype, elsize)
758: Address base;
759: integer count, ndims;
760: Symbol eltype;
761: integer 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:
802: private printSubarray (t)
803: Symbol t;
804: {
805: printf("[subarray]");
806: }
807:
808: /*
809: * Print out the value of a scalar (non-enumeration) type.
810: */
811:
812: private printrange (s, n)
813: Symbol s;
814: integer 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);
831: printRangeVal(i, s);
832: }
833: }
834:
835: /*
836: * Print out a set.
837: */
838:
839: private printSet (s)
840: Symbol 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:
863: private printSetOfEnum (t)
864: Symbol 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:
899: private printSetOfRange (t)
900: Symbol 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:
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:
938: private Node dynref (a, t, slist)
939: Node a;
940: Symbol t;
941: Node 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:
965: /*
966: * Construct a node for subscripting.
967: */
968:
969: public Node modula2_buildaref (a, slist)
970: Node a, slist;
971: {
972: register Symbol t;
973: register Node p;
974: Symbol eltype;
975: Node esub, r;
976: integer n;
977:
978: t = rtype(a->nodetype);
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;
990: t = t->chain;
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;
1011: }
1012: return r;
1013: }
1014:
1015: /*
1016: * Subscript usage error reporting.
1017: */
1018:
1019: private suberror (s1, e1, s2)
1020: String s1, s2;
1021: Node 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:
1040: private subchk (value, lower, upper)
1041: long 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:
1052: private getdynoff (ndims, sub)
1053: integer ndims;
1054: long *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:
1072: private getsuboff (ndims, sub)
1073: integer ndims;
1074: long *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:
1091: /*
1092: * Evaluate a subscript index.
1093: */
1094:
1095: public modula2_evalaref (s, base, i)
1096: Symbol s;
1097: Address base;
1098: long i;
1099: {
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));
1112: } else if ((t->class == OPENARRAY or t->class == DYNARRAY) and
1113: t->symvalue.ndims == 0
1114: ) {
1115: push(long, base + i * size(t->type));
1116: } else if (t->class == OPENARRAY or t->class == DYNARRAY or
1117: t->class == SUBARRAY
1118: ) {
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]");
1134: }
1135: }
1136:
1137: /*
1138: * Initial Modula-2 type information.
1139: */
1140:
1141: #define NTYPES 12
1142:
1143: private Symbol inittype[NTYPES + 1];
1144:
1145: private addType (n, s, lower, upper)
1146: integer n;
1147: String s;
1148: long 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:
1165: private 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:
1185: public modula2_modinit (typetable)
1186: Symbol typetable[];
1187: {
1188: register integer i;
1189:
1190: if (not initialized) {
1191: initModTypes();
1192: initialized = true;
1193: }
1194: for (i = 1; i <= NTYPES; i++) {
1195: typetable[i] = inittype[i];
1196: }
1197: }
1198:
1199: public boolean modula2_hasmodules ()
1200: {
1201: return true;
1202: }
1203:
1204: public boolean modula2_passaddr (param, exprtype)
1205: Symbol param, exprtype;
1206: {
1207: return false;
1208: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.