121618Sdist /*
238105Sbostic * Copyright (c) 1983 The Regents of the University of California.
338105Sbostic * All rights reserved.
438105Sbostic *
5*42683Sbostic * %sccs.include.redist.c%
621618Sdist */
79675Slinton
821618Sdist #ifndef lint
9*42683Sbostic static char sccsid[] = "@(#)pascal.c 5.3 (Berkeley) 06/01/90";
1038105Sbostic #endif /* not lint */
119675Slinton
129675Slinton /*
139675Slinton * Pascal-dependent symbol routines.
149675Slinton */
159675Slinton
169675Slinton #include "defs.h"
179675Slinton #include "symbols.h"
189675Slinton #include "pascal.h"
199675Slinton #include "languages.h"
209675Slinton #include "tree.h"
219675Slinton #include "eval.h"
229675Slinton #include "mappings.h"
239675Slinton #include "process.h"
249675Slinton #include "runtime.h"
259675Slinton #include "machine.h"
269675Slinton
279675Slinton #ifndef public
289675Slinton #endif
299675Slinton
3016615Ssam private Language pasc;
3118228Slinton private boolean initialized;
3216615Ssam
339675Slinton /*
349675Slinton * Initialize Pascal information.
359675Slinton */
369675Slinton
pascal_init()379675Slinton public pascal_init()
389675Slinton {
3916615Ssam pasc = language_define("pascal", ".p");
4016615Ssam language_setop(pasc, L_PRINTDECL, pascal_printdecl);
4116615Ssam language_setop(pasc, L_PRINTVAL, pascal_printval);
4216615Ssam language_setop(pasc, L_TYPEMATCH, pascal_typematch);
4316615Ssam language_setop(pasc, L_BUILDAREF, pascal_buildaref);
4416615Ssam language_setop(pasc, L_EVALAREF, pascal_evalaref);
4516615Ssam language_setop(pasc, L_MODINIT, pascal_modinit);
4616615Ssam language_setop(pasc, L_HASMODULES, pascal_hasmodules);
4716615Ssam language_setop(pasc, L_PASSADDR, pascal_passaddr);
4818228Slinton initialized = false;
499675Slinton }
509675Slinton
519675Slinton /*
5218228Slinton * Typematch tests if two types are compatible. The issue
5318228Slinton * is a bit complicated, so several subfunctions are used for
5418228Slinton * various kinds of compatibility.
559675Slinton */
569675Slinton
builtinmatch(t1,t2)5718228Slinton private boolean builtinmatch (t1, t2)
5818228Slinton register Symbol t1, t2;
599675Slinton {
6018228Slinton boolean b;
619675Slinton
6218228Slinton b = (boolean) (
6318228Slinton (
6418228Slinton t2 == t_int->type and
6518228Slinton t1->class == RANGE and istypename(t1->type, "integer")
6618228Slinton ) or (
6718228Slinton t2 == t_char->type and
6818228Slinton t1->class == RANGE and istypename(t1->type, "char")
6918228Slinton ) or (
7018228Slinton t2 == t_real->type and
7118228Slinton t1->class == RANGE and istypename(t1->type, "real")
7218228Slinton ) or (
7318228Slinton t2 == t_boolean->type and
7418228Slinton t1->class == RANGE and istypename(t1->type, "boolean")
7518228Slinton )
7618228Slinton );
7718228Slinton return b;
7818228Slinton }
7918228Slinton
rangematch(t1,t2)8018228Slinton private boolean rangematch (t1, t2)
8118228Slinton register Symbol t1, t2;
8218228Slinton {
8318228Slinton boolean b;
8418228Slinton register Symbol rt1, rt2;
8518228Slinton
8618228Slinton if (t1->class == RANGE and t2->class == RANGE) {
8718228Slinton rt1 = rtype(t1->type);
8818228Slinton rt2 = rtype(t2->type);
8918228Slinton b = (boolean) (rt1->type == rt2->type);
9018228Slinton } else {
9118228Slinton b = false;
9218228Slinton }
9318228Slinton return b;
9418228Slinton }
9518228Slinton
nilMatch(t1,t2)9618228Slinton private boolean nilMatch (t1, t2)
9718228Slinton register Symbol t1, t2;
9818228Slinton {
9918228Slinton boolean b;
10018228Slinton
10118228Slinton b = (boolean) (
1029675Slinton (t1 == t_nil and t2->class == PTR) or
1039675Slinton (t1->class == PTR and t2 == t_nil)
1049675Slinton );
1059675Slinton return b;
1069675Slinton }
1079675Slinton
enumMatch(t1,t2)10818228Slinton private boolean enumMatch (t1, t2)
10918228Slinton register Symbol t1, t2;
11018228Slinton {
11118228Slinton boolean b;
11218228Slinton
11318228Slinton b = (boolean) (
11418228Slinton (t1->class == SCAL and t2->class == CONST and t2->type == t1) or
11518228Slinton (t1->class == CONST and t2->class == SCAL and t1->type == t2)
11618228Slinton );
11718228Slinton return b;
11818228Slinton }
11918228Slinton
isConstString(t)12018228Slinton private boolean isConstString (t)
12118228Slinton register Symbol t;
12218228Slinton {
12318228Slinton boolean b;
12418228Slinton
12518228Slinton b = (boolean) (
12618228Slinton t->language == primlang and t->class == ARRAY and t->type == t_char
12718228Slinton );
12818228Slinton return b;
12918228Slinton }
13018228Slinton
stringArrayMatch(t1,t2)13118228Slinton private boolean stringArrayMatch (t1, t2)
13218228Slinton register Symbol t1, t2;
13318228Slinton {
13418228Slinton boolean b;
13518228Slinton
13618228Slinton b = (boolean) (
13718228Slinton (
13818228Slinton isConstString(t1) and
13918228Slinton t2->class == ARRAY and compatible(t2->type, t_char->type)
14018228Slinton ) or (
14118228Slinton isConstString(t2) and
14218228Slinton t1->class == ARRAY and compatible(t1->type, t_char->type)
14318228Slinton )
14418228Slinton );
14518228Slinton return b;
14618228Slinton }
14718228Slinton
pascal_typematch(type1,type2)14818228Slinton public boolean pascal_typematch (type1, type2)
14918228Slinton Symbol type1, type2;
15018228Slinton {
15118228Slinton boolean b;
15218228Slinton Symbol t1, t2, tmp;
15318228Slinton
15418228Slinton t1 = rtype(type1);
15518228Slinton t2 = rtype(type2);
15618228Slinton if (t1 == t2) {
15718228Slinton b = true;
15818228Slinton } else {
15918228Slinton if (t1 == t_char->type or t1 == t_int->type or
16018228Slinton t1 == t_real->type or t1 == t_boolean->type
16118228Slinton ) {
16218228Slinton tmp = t1;
16318228Slinton t1 = t2;
16418228Slinton t2 = tmp;
16518228Slinton }
16618228Slinton b = (Boolean) (
16718228Slinton builtinmatch(t1, t2) or rangematch(t1, t2) or
16818228Slinton nilMatch(t1, t2) or enumMatch(t1, t2) or
16918228Slinton stringArrayMatch(t1, t2)
17018228Slinton );
17118228Slinton }
17218228Slinton return b;
17318228Slinton }
17418228Slinton
17518228Slinton /*
17618228Slinton * Indent n spaces.
17718228Slinton */
17818228Slinton
indent(n)17918228Slinton private indent (n)
18018228Slinton int n;
18118228Slinton {
18218228Slinton if (n > 0) {
18318228Slinton printf("%*c", n, ' ');
18418228Slinton }
18518228Slinton }
18618228Slinton
pascal_printdecl(s)18718228Slinton public pascal_printdecl (s)
1889675Slinton Symbol s;
1899675Slinton {
1909675Slinton register Symbol t;
1919675Slinton Boolean semicolon;
1929675Slinton
1939675Slinton semicolon = true;
19418228Slinton if (s->class == TYPEREF) {
19518228Slinton resolveRef(t);
19618228Slinton }
1979675Slinton switch (s->class) {
1989675Slinton case CONST:
1999675Slinton if (s->type->class == SCAL) {
20018228Slinton semicolon = false;
20118228Slinton printf("enum constant, ord ");
20218228Slinton eval(s->symvalue.constval);
20318228Slinton pascal_printval(s);
2049675Slinton } else {
2059675Slinton printf("const %s = ", symname(s));
20618228Slinton eval(s->symvalue.constval);
20718228Slinton pascal_printval(s);
2089675Slinton }
2099675Slinton break;
2109675Slinton
2119675Slinton case TYPE:
2129675Slinton printf("type %s = ", symname(s));
21318228Slinton printtype(s, s->type, 0);
2149675Slinton break;
2159675Slinton
21618228Slinton case TYPEREF:
21718228Slinton printf("type %s", symname(s));
21818228Slinton break;
21918228Slinton
2209675Slinton case VAR:
2219675Slinton if (isparam(s)) {
2229675Slinton printf("(parameter) %s : ", symname(s));
2239675Slinton } else {
2249675Slinton printf("var %s : ", symname(s));
2259675Slinton }
22618228Slinton printtype(s, s->type, 0);
2279675Slinton break;
2289675Slinton
2299675Slinton case REF:
2309675Slinton printf("(var parameter) %s : ", symname(s));
23118228Slinton printtype(s, s->type, 0);
2329675Slinton break;
2339675Slinton
2349675Slinton case RANGE:
2359675Slinton case ARRAY:
2369675Slinton case RECORD:
2379675Slinton case VARNT:
2389675Slinton case PTR:
23918228Slinton case FILET:
24018228Slinton printtype(s, s, 0);
2419675Slinton semicolon = false;
2429675Slinton break;
2439675Slinton
2449675Slinton case FVAR:
2459675Slinton printf("(function variable) %s : ", symname(s));
24618228Slinton printtype(s, s->type, 0);
2479675Slinton break;
2489675Slinton
2499675Slinton case FIELD:
2509675Slinton printf("(field) %s : ", symname(s));
25118228Slinton printtype(s, s->type, 0);
2529675Slinton break;
2539675Slinton
2549675Slinton case PROC:
2559675Slinton printf("procedure %s", symname(s));
2569675Slinton listparams(s);
2579675Slinton break;
2589675Slinton
2599675Slinton case PROG:
2609675Slinton printf("program %s", symname(s));
26118228Slinton listparams(s);
2629675Slinton break;
2639675Slinton
2649675Slinton case FUNC:
2659675Slinton printf("function %s", symname(s));
2669675Slinton listparams(s);
2679675Slinton printf(" : ");
26818228Slinton printtype(s, s->type, 0);
2699675Slinton break;
2709675Slinton
27118228Slinton case MODULE:
27218228Slinton printf("module %s", symname(s));
27318228Slinton break;
27418228Slinton
27518228Slinton /*
27618228Slinton * the parameter list of the following should be printed
27718228Slinton * eventually
27818228Slinton */
27918228Slinton case FPROC:
28018228Slinton printf("procedure %s()", symname(s));
28118228Slinton break;
28218228Slinton
28318228Slinton case FFUNC:
28418228Slinton printf("function %s()", symname(s));
28518228Slinton break;
28618228Slinton
2879675Slinton default:
28818228Slinton printf("%s : (class %s)", symname(s), classname(s));
28918228Slinton break;
2909675Slinton }
2919675Slinton if (semicolon) {
2929675Slinton putchar(';');
2939675Slinton }
2949675Slinton putchar('\n');
2959675Slinton }
2969675Slinton
2979675Slinton /*
2989675Slinton * Recursive whiz-bang procedure to print the type portion
29918228Slinton * of a declaration.
3009675Slinton *
3019675Slinton * The symbol associated with the type is passed to allow
3029675Slinton * searching for type names without getting "type blah = blah".
3039675Slinton */
3049675Slinton
printtype(s,t,n)30518228Slinton private printtype (s, t, n)
3069675Slinton Symbol s;
3079675Slinton Symbol t;
30818228Slinton int n;
3099675Slinton {
3109675Slinton register Symbol tmp;
3119675Slinton
31218228Slinton if (t->class == TYPEREF) {
31318228Slinton resolveRef(t);
31418228Slinton }
3159675Slinton switch (t->class) {
3169675Slinton case VAR:
3179675Slinton case CONST:
3189675Slinton case FUNC:
3199675Slinton case PROC:
3209675Slinton panic("printtype: class %s", classname(t));
3219675Slinton break;
3229675Slinton
3239675Slinton case ARRAY:
3249675Slinton printf("array[");
3259675Slinton tmp = t->chain;
3269675Slinton if (tmp != nil) {
3279675Slinton for (;;) {
32818228Slinton printtype(tmp, tmp, n);
3299675Slinton tmp = tmp->chain;
3309675Slinton if (tmp == nil) {
3319675Slinton break;
3329675Slinton }
3339675Slinton printf(", ");
3349675Slinton }
3359675Slinton }
3369675Slinton printf("] of ");
33718228Slinton printtype(t, t->type, n);
3389675Slinton break;
3399675Slinton
3409675Slinton case RECORD:
34118228Slinton printRecordDecl(t, n);
3429675Slinton break;
3439675Slinton
3449675Slinton case FIELD:
3459675Slinton if (t->chain != nil) {
34618228Slinton printtype(t->chain, t->chain, n);
3479675Slinton }
3489675Slinton printf("\t%s : ", symname(t));
34918228Slinton printtype(t, t->type, n);
3509675Slinton printf(";\n");
3519675Slinton break;
3529675Slinton
35318228Slinton case RANGE:
35418228Slinton printRangeDecl(t);
3559675Slinton break;
3569675Slinton
3579675Slinton case PTR:
35818228Slinton printf("^");
35918228Slinton printtype(t, t->type, n);
3609675Slinton break;
3619675Slinton
3629675Slinton case TYPE:
36318228Slinton if (t->name != nil and ident(t->name)[0] != '\0') {
36418228Slinton printname(stdout, t);
3659675Slinton } else {
36618228Slinton printtype(t, t->type, n);
3679675Slinton }
3689675Slinton break;
3699675Slinton
3709675Slinton case SCAL:
37118228Slinton printEnumDecl(t, n);
3729675Slinton break;
3739675Slinton
37418228Slinton case SET:
37518228Slinton printf("set of ");
37618228Slinton printtype(t, t->type, n);
37718228Slinton break;
37818228Slinton
37918228Slinton case FILET:
38018228Slinton printf("file of ");
38118228Slinton printtype(t, t->type, n);
38218228Slinton break;
38318228Slinton
38418228Slinton case TYPEREF:
38518228Slinton break;
38618228Slinton
38718228Slinton case FPROC:
38818228Slinton printf("procedure");
38918228Slinton break;
39018228Slinton
39118228Slinton case FFUNC:
39218228Slinton printf("function");
39318228Slinton break;
39418228Slinton
3959675Slinton default:
3969675Slinton printf("(class %d)", t->class);
3979675Slinton break;
3989675Slinton }
3999675Slinton }
4009675Slinton
4019675Slinton /*
40218228Slinton * Print out a record declaration.
40318228Slinton */
40418228Slinton
printRecordDecl(t,n)40518228Slinton private printRecordDecl (t, n)
40618228Slinton Symbol t;
40718228Slinton int n;
40818228Slinton {
40918228Slinton register Symbol f;
41018228Slinton
41118228Slinton if (t->chain == nil) {
41218228Slinton printf("record end");
41318228Slinton } else {
41418228Slinton printf("record\n");
41518228Slinton for (f = t->chain; f != nil; f = f->chain) {
41618228Slinton indent(n+4);
41718228Slinton printf("%s : ", symname(f));
41818228Slinton printtype(f->type, f->type, n+4);
41918228Slinton printf(";\n");
42018228Slinton }
42118228Slinton indent(n);
42218228Slinton printf("end");
42318228Slinton }
42418228Slinton }
42518228Slinton
42618228Slinton /*
42718228Slinton * Print out the declaration of a range type.
42818228Slinton */
42918228Slinton
printRangeDecl(t)43018228Slinton private printRangeDecl (t)
43118228Slinton Symbol t;
43218228Slinton {
43318228Slinton long r0, r1;
43418228Slinton
43518228Slinton r0 = t->symvalue.rangev.lower;
43618228Slinton r1 = t->symvalue.rangev.upper;
43718228Slinton if (t == t_char or istypename(t, "char")) {
43818228Slinton if (r0 < 0x20 or r0 > 0x7e) {
43918228Slinton printf("%ld..", r0);
44018228Slinton } else {
44118228Slinton printf("'%c'..", (char) r0);
44218228Slinton }
44318228Slinton if (r1 < 0x20 or r1 > 0x7e) {
44418228Slinton printf("\\%lo", r1);
44518228Slinton } else {
44618228Slinton printf("'%c'", (char) r1);
44718228Slinton }
44818228Slinton } else if (r0 > 0 and r1 == 0) {
44918228Slinton printf("%ld byte real", r0);
45018228Slinton } else if (r0 >= 0) {
45118228Slinton printf("%lu..%lu", r0, r1);
45218228Slinton } else {
45318228Slinton printf("%ld..%ld", r0, r1);
45418228Slinton }
45518228Slinton }
45618228Slinton
45718228Slinton /*
45818228Slinton * Print out an enumeration declaration.
45918228Slinton */
46018228Slinton
printEnumDecl(e,n)46118228Slinton private printEnumDecl (e, n)
46218228Slinton Symbol e;
46318228Slinton int n;
46418228Slinton {
46518228Slinton Symbol t;
46618228Slinton
46718228Slinton printf("(");
46818228Slinton t = e->chain;
46918228Slinton if (t != nil) {
47018228Slinton printf("%s", symname(t));
47118228Slinton t = t->chain;
47218228Slinton while (t != nil) {
47318228Slinton printf(", %s", symname(t));
47418228Slinton t = t->chain;
47518228Slinton }
47618228Slinton }
47718228Slinton printf(")");
47818228Slinton }
47918228Slinton
48018228Slinton /*
4819675Slinton * List the parameters of a procedure or function.
4829675Slinton * No attempt is made to combine like types.
4839675Slinton */
4849675Slinton
listparams(s)4859675Slinton private listparams(s)
4869675Slinton Symbol s;
4879675Slinton {
4889675Slinton Symbol t;
4899675Slinton
4909675Slinton if (s->chain != nil) {
4919675Slinton putchar('(');
4929675Slinton for (t = s->chain; t != nil; t = t->chain) {
4939675Slinton switch (t->class) {
4949675Slinton case REF:
4959675Slinton printf("var ");
4969675Slinton break;
4979675Slinton
4989675Slinton case VAR:
4999675Slinton break;
5009675Slinton
5019675Slinton default:
5029675Slinton panic("unexpected class %d for parameter", t->class);
5039675Slinton }
5049675Slinton printf("%s : ", symname(t));
5059675Slinton printtype(t, t->type);
5069675Slinton if (t->chain != nil) {
5079675Slinton printf("; ");
5089675Slinton }
5099675Slinton }
5109675Slinton putchar(')');
5119675Slinton }
5129675Slinton }
5139675Slinton
5149675Slinton /*
5159675Slinton * Print out the value on the top of the expression stack
5169675Slinton * in the format for the type of the given symbol.
5179675Slinton */
5189675Slinton
pascal_printval(s)51918228Slinton public pascal_printval (s)
5209675Slinton Symbol s;
5219675Slinton {
52218228Slinton prval(s, size(s));
52318228Slinton }
52418228Slinton
prval(s,n)52518228Slinton private prval (s, n)
52618228Slinton Symbol s;
52718228Slinton integer n;
52818228Slinton {
5299675Slinton Symbol t;
5309675Slinton Address a;
53118228Slinton integer len;
5329675Slinton double r;
53318228Slinton integer i;
5349675Slinton
53518228Slinton if (s->class == TYPEREF) {
53618228Slinton resolveRef(s);
53718228Slinton }
5389675Slinton switch (s->class) {
53916615Ssam case CONST:
5409675Slinton case TYPE:
54118228Slinton case REF:
54216615Ssam case VAR:
54316615Ssam case FVAR:
54416615Ssam case TAG:
54518228Slinton prval(s->type, n);
54618228Slinton break;
54718228Slinton
54816615Ssam case FIELD:
54918228Slinton prval(s->type, n);
5509675Slinton break;
5519675Slinton
5529675Slinton case ARRAY:
5539675Slinton t = rtype(s->type);
55418228Slinton if (t == t_char->type or
55518228Slinton (t->class == RANGE and istypename(t->type, "char"))
55618228Slinton ) {
5579675Slinton len = size(s);
5589675Slinton sp -= len;
5599675Slinton printf("'%.*s'", len, sp);
5609675Slinton break;
5619675Slinton } else {
5629675Slinton printarray(s);
5639675Slinton }
5649675Slinton break;
5659675Slinton
5669675Slinton case RECORD:
5679675Slinton printrecord(s);
5689675Slinton break;
5699675Slinton
5709675Slinton case VARNT:
57118228Slinton printf("[variant]");
5729675Slinton break;
5739675Slinton
5749675Slinton case RANGE:
57518228Slinton printrange(s, n);
57618228Slinton break;
5779675Slinton
57818228Slinton case FILET:
57918228Slinton a = pop(Address);
58018228Slinton if (a == 0) {
58118228Slinton printf("nil");
5829675Slinton } else {
58318228Slinton printf("0x%x", a);
5849675Slinton }
5859675Slinton break;
5869675Slinton
58718228Slinton case PTR:
58818228Slinton a = pop(Address);
58918228Slinton if (a == 0) {
59018228Slinton printf("nil");
5919675Slinton } else {
59218228Slinton printf("0x%x", a);
5939675Slinton }
5949675Slinton break;
5959675Slinton
59618228Slinton case SCAL:
59718228Slinton i = 0;
59818228Slinton popn(n, &i);
59918228Slinton if (s->symvalue.iconval < 256) {
60018228Slinton i &= 0xff;
60118228Slinton } else if (s->symvalue.iconval < 65536) {
60218228Slinton i &= 0xffff;
6039675Slinton }
60418228Slinton printEnum(i, s);
6059675Slinton break;
6069675Slinton
6079675Slinton case FPROC:
6089675Slinton case FFUNC:
60918228Slinton a = pop(long);
6109675Slinton t = whatblock(a);
6119675Slinton if (t == nil) {
61218228Slinton printf("(proc 0x%x)", a);
6139675Slinton } else {
6149675Slinton printf("%s", symname(t));
6159675Slinton }
6169675Slinton break;
6179675Slinton
61818228Slinton case SET:
61918228Slinton printSet(s);
62018228Slinton break;
62118228Slinton
6229675Slinton default:
6239675Slinton if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) {
6249675Slinton panic("printval: bad class %d", ord(s->class));
6259675Slinton }
62618228Slinton printf("[%s]", classname(s));
62718228Slinton break;
6289675Slinton }
6299675Slinton }
63016615Ssam
63116615Ssam /*
63218228Slinton * Print out the value of a scalar (non-enumeration) type.
63318228Slinton */
63418228Slinton
printrange(s,n)63518228Slinton private printrange (s, n)
63618228Slinton Symbol s;
63718228Slinton integer n;
63818228Slinton {
63918228Slinton double d;
64018228Slinton float f;
64118228Slinton integer i;
64218228Slinton
64318228Slinton if (s->symvalue.rangev.upper == 0 and s->symvalue.rangev.lower > 0) {
64418228Slinton if (n == sizeof(float)) {
64518228Slinton popn(n, &f);
64618228Slinton d = f;
64718228Slinton } else {
64818228Slinton popn(n, &d);
64918228Slinton }
65018228Slinton prtreal(d);
65118228Slinton } else {
65218228Slinton i = 0;
65318228Slinton popn(n, &i);
65418228Slinton printRangeVal(i, s);
65518228Slinton }
65618228Slinton }
65718228Slinton
65818228Slinton /*
65918228Slinton * Print out a set.
66018228Slinton */
66118228Slinton
printSet(s)66218228Slinton private printSet (s)
66318228Slinton Symbol s;
66418228Slinton {
66518228Slinton Symbol t;
66618228Slinton integer nbytes;
66718228Slinton
66818228Slinton nbytes = size(s);
66918228Slinton t = rtype(s->type);
67018228Slinton printf("[");
67118228Slinton sp -= nbytes;
67218228Slinton if (t->class == SCAL) {
67318228Slinton printSetOfEnum(t);
67418228Slinton } else if (t->class == RANGE) {
67518228Slinton printSetOfRange(t);
67618228Slinton } else {
67718228Slinton error("internal error: expected range or enumerated base type for set");
67818228Slinton }
67918228Slinton printf("]");
68018228Slinton }
68118228Slinton
68218228Slinton /*
68318228Slinton * Print out a set of an enumeration.
68418228Slinton */
68518228Slinton
printSetOfEnum(t)68618228Slinton private printSetOfEnum (t)
68718228Slinton Symbol t;
68818228Slinton {
68918228Slinton register Symbol e;
69018228Slinton register integer i, j, *p;
69118228Slinton boolean first;
69218228Slinton
69318228Slinton p = (int *) sp;
69418228Slinton i = *p;
69518228Slinton j = 0;
69618228Slinton e = t->chain;
69718228Slinton first = true;
69818228Slinton while (e != nil) {
69918228Slinton if ((i&1) == 1) {
70018228Slinton if (first) {
70118228Slinton first = false;
70218228Slinton printf("%s", symname(e));
70318228Slinton } else {
70418228Slinton printf(", %s", symname(e));
70518228Slinton }
70618228Slinton }
70718228Slinton i >>= 1;
70818228Slinton ++j;
70918228Slinton if (j >= sizeof(integer)*BITSPERBYTE) {
71018228Slinton j = 0;
71118228Slinton ++p;
71218228Slinton i = *p;
71318228Slinton }
71418228Slinton e = e->chain;
71518228Slinton }
71618228Slinton }
71718228Slinton
71818228Slinton /*
71918228Slinton * Print out a set of a subrange type.
72018228Slinton */
72118228Slinton
printSetOfRange(t)72218228Slinton private printSetOfRange (t)
72318228Slinton Symbol t;
72418228Slinton {
72518228Slinton register integer i, j, *p;
72618228Slinton long v;
72718228Slinton boolean first;
72818228Slinton
72918228Slinton p = (int *) sp;
73018228Slinton i = *p;
73118228Slinton j = 0;
73218228Slinton v = t->symvalue.rangev.lower;
73318228Slinton first = true;
73418228Slinton while (v <= t->symvalue.rangev.upper) {
73518228Slinton if ((i&1) == 1) {
73618228Slinton if (first) {
73718228Slinton first = false;
73818228Slinton printf("%ld", v);
73918228Slinton } else {
74018228Slinton printf(", %ld", v);
74118228Slinton }
74218228Slinton }
74318228Slinton i >>= 1;
74418228Slinton ++j;
74518228Slinton if (j >= sizeof(integer)*BITSPERBYTE) {
74618228Slinton j = 0;
74718228Slinton ++p;
74818228Slinton i = *p;
74918228Slinton }
75018228Slinton ++v;
75118228Slinton }
75218228Slinton }
75318228Slinton
75418228Slinton /*
75516615Ssam * Construct a node for subscripting.
75616615Ssam */
75716615Ssam
pascal_buildaref(a,slist)75816615Ssam public Node pascal_buildaref (a, slist)
75916615Ssam Node a, slist;
76016615Ssam {
76116615Ssam register Symbol t;
76216615Ssam register Node p;
76316615Ssam Symbol etype, atype, eltype;
76416615Ssam Node esub, r;
76516615Ssam
76616615Ssam t = rtype(a->nodetype);
76716615Ssam if (t->class != ARRAY) {
76816615Ssam beginerrmsg();
76916615Ssam prtree(stderr, a);
77016615Ssam fprintf(stderr, " is not an array");
77116615Ssam enderrmsg();
77216615Ssam } else {
77318228Slinton r = a;
77418228Slinton eltype = t->type;
77516615Ssam p = slist;
77616615Ssam t = t->chain;
77716615Ssam for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
77816615Ssam esub = p->value.arg[0];
77916615Ssam etype = rtype(esub->nodetype);
78016615Ssam atype = rtype(t);
78116615Ssam if (not compatible(atype, etype)) {
78216615Ssam beginerrmsg();
78316615Ssam fprintf(stderr, "subscript ");
78416615Ssam prtree(stderr, esub);
78516615Ssam fprintf(stderr, " is the wrong type");
78616615Ssam enderrmsg();
78716615Ssam }
78816615Ssam r = build(O_INDEX, r, esub);
78916615Ssam r->nodetype = eltype;
79016615Ssam }
79116615Ssam if (p != nil or t != nil) {
79216615Ssam beginerrmsg();
79316615Ssam if (p != nil) {
79416615Ssam fprintf(stderr, "too many subscripts for ");
79516615Ssam } else {
79616615Ssam fprintf(stderr, "not enough subscripts for ");
79716615Ssam }
79816615Ssam prtree(stderr, a);
79916615Ssam enderrmsg();
80016615Ssam }
80116615Ssam }
80216615Ssam return r;
80316615Ssam }
80416615Ssam
80516615Ssam /*
80616615Ssam * Evaluate a subscript index.
80716615Ssam */
80816615Ssam
pascal_evalaref(s,base,i)80918228Slinton public pascal_evalaref (s, base, i)
81016615Ssam Symbol s;
81118228Slinton Address base;
81216615Ssam long i;
81316615Ssam {
81418228Slinton Symbol t;
81516615Ssam long lb, ub;
81616615Ssam
81718228Slinton t = rtype(s);
81818228Slinton s = rtype(t->chain);
81918228Slinton findbounds(s, &lb, &ub);
82016615Ssam if (i < lb or i > ub) {
82116615Ssam error("subscript %d out of range [%d..%d]", i, lb, ub);
82216615Ssam }
82318228Slinton push(long, base + (i - lb) * size(t->type));
82416615Ssam }
82516615Ssam
82616615Ssam /*
82716615Ssam * Initial Pascal type information.
82816615Ssam */
82916615Ssam
83016615Ssam #define NTYPES 4
83116615Ssam
83218228Slinton private Symbol inittype[NTYPES + 1];
83316615Ssam
addType(n,s,lower,upper)83418228Slinton private addType (n, s, lower, upper)
83518228Slinton integer n;
83616615Ssam String s;
83716615Ssam long lower, upper;
83816615Ssam {
83916615Ssam register Symbol t;
84016615Ssam
84118228Slinton if (n > NTYPES) {
84218228Slinton panic("initial Pascal type number too large for '%s'", s);
84316615Ssam }
84418228Slinton t = insert(identname(s, true));
84516615Ssam t->language = pasc;
84618228Slinton t->class = TYPE;
84718228Slinton t->type = newSymbol(nil, 0, RANGE, t, nil);
84818228Slinton t->type->symvalue.rangev.lower = lower;
84918228Slinton t->type->symvalue.rangev.upper = upper;
85018228Slinton t->type->language = pasc;
85118228Slinton inittype[n] = t;
85216615Ssam }
85316615Ssam
initTypes()85416615Ssam private initTypes ()
85516615Ssam {
85618228Slinton addType(1, "boolean", 0L, 1L);
85718228Slinton addType(2, "char", 0L, 255L);
85818228Slinton addType(3, "integer", 0x80000000L, 0x7fffffffL);
85918228Slinton addType(4, "real", 8L, 0L);
86018228Slinton initialized = true;
86116615Ssam }
86216615Ssam
86316615Ssam /*
86416615Ssam * Initialize typetable.
86516615Ssam */
86616615Ssam
pascal_modinit(typetable)86716615Ssam public pascal_modinit (typetable)
86816615Ssam Symbol typetable[];
86916615Ssam {
87016615Ssam register integer i;
87116615Ssam
87218228Slinton if (not initialized) {
87318228Slinton initTypes();
87418228Slinton initialized = true;
87518228Slinton }
87618228Slinton for (i = 1; i <= NTYPES; i++) {
87716615Ssam typetable[i] = inittype[i];
87816615Ssam }
87916615Ssam }
88016615Ssam
pascal_hasmodules()88116615Ssam public boolean pascal_hasmodules ()
88216615Ssam {
88316615Ssam return false;
88416615Ssam }
88516615Ssam
pascal_passaddr(param,exprtype)88616615Ssam public boolean pascal_passaddr (param, exprtype)
88716615Ssam Symbol param, exprtype;
88816615Ssam {
88916615Ssam return false;
89016615Ssam }
891