xref: /csrg-svn/old/dbx/pascal.c (revision 42683)
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