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