xref: /csrg-svn/old/dbx/pascal.c (revision 21618)
1*21618Sdist /*
2*21618Sdist  * Copyright (c) 1983 Regents of the University of California.
3*21618Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21618Sdist  * specifies the terms and conditions for redistribution.
5*21618Sdist  */
69675Slinton 
7*21618Sdist #ifndef lint
8*21618Sdist static char sccsid[] = "@(#)pascal.c	5.1 (Berkeley) 05/31/85";
9*21618Sdist #endif not lint
109675Slinton 
1118228Slinton static char rcsid[] = "$Header: pascal.c,v 1.5 84/12/26 10:41:18 linton Exp $";
1218228Slinton 
139675Slinton /*
149675Slinton  * Pascal-dependent symbol routines.
159675Slinton  */
169675Slinton 
179675Slinton #include "defs.h"
189675Slinton #include "symbols.h"
199675Slinton #include "pascal.h"
209675Slinton #include "languages.h"
219675Slinton #include "tree.h"
229675Slinton #include "eval.h"
239675Slinton #include "mappings.h"
249675Slinton #include "process.h"
259675Slinton #include "runtime.h"
269675Slinton #include "machine.h"
279675Slinton 
289675Slinton #ifndef public
299675Slinton #endif
309675Slinton 
3116615Ssam private Language pasc;
3218228Slinton private boolean initialized;
3316615Ssam 
349675Slinton /*
359675Slinton  * Initialize Pascal information.
369675Slinton  */
379675Slinton 
389675Slinton public pascal_init()
399675Slinton {
4016615Ssam     pasc = language_define("pascal", ".p");
4116615Ssam     language_setop(pasc, L_PRINTDECL, pascal_printdecl);
4216615Ssam     language_setop(pasc, L_PRINTVAL, pascal_printval);
4316615Ssam     language_setop(pasc, L_TYPEMATCH, pascal_typematch);
4416615Ssam     language_setop(pasc, L_BUILDAREF, pascal_buildaref);
4516615Ssam     language_setop(pasc, L_EVALAREF, pascal_evalaref);
4616615Ssam     language_setop(pasc, L_MODINIT, pascal_modinit);
4716615Ssam     language_setop(pasc, L_HASMODULES, pascal_hasmodules);
4816615Ssam     language_setop(pasc, L_PASSADDR, pascal_passaddr);
4918228Slinton     initialized = false;
509675Slinton }
519675Slinton 
529675Slinton /*
5318228Slinton  * Typematch tests if two types are compatible.  The issue
5418228Slinton  * is a bit complicated, so several subfunctions are used for
5518228Slinton  * various kinds of compatibility.
569675Slinton  */
579675Slinton 
5818228Slinton private boolean builtinmatch (t1, t2)
5918228Slinton register Symbol t1, t2;
609675Slinton {
6118228Slinton     boolean b;
629675Slinton 
6318228Slinton     b = (boolean) (
6418228Slinton 	(
6518228Slinton 	    t2 == t_int->type and
6618228Slinton 	    t1->class == RANGE and istypename(t1->type, "integer")
6718228Slinton 	) or (
6818228Slinton 	    t2 == t_char->type and
6918228Slinton 	    t1->class == RANGE and istypename(t1->type, "char")
7018228Slinton 	) or (
7118228Slinton 	    t2 == t_real->type and
7218228Slinton 	    t1->class == RANGE and istypename(t1->type, "real")
7318228Slinton 	) or (
7418228Slinton 	    t2 == t_boolean->type and
7518228Slinton 	    t1->class == RANGE and istypename(t1->type, "boolean")
7618228Slinton 	)
7718228Slinton     );
7818228Slinton     return b;
7918228Slinton }
8018228Slinton 
8118228Slinton private boolean rangematch (t1, t2)
8218228Slinton register Symbol t1, t2;
8318228Slinton {
8418228Slinton     boolean b;
8518228Slinton     register Symbol rt1, rt2;
8618228Slinton 
8718228Slinton     if (t1->class == RANGE and t2->class == RANGE) {
8818228Slinton 	rt1 = rtype(t1->type);
8918228Slinton 	rt2 = rtype(t2->type);
9018228Slinton 	b = (boolean) (rt1->type == rt2->type);
9118228Slinton     } else {
9218228Slinton 	b = false;
9318228Slinton     }
9418228Slinton     return b;
9518228Slinton }
9618228Slinton 
9718228Slinton private boolean nilMatch (t1, t2)
9818228Slinton register Symbol t1, t2;
9918228Slinton {
10018228Slinton     boolean b;
10118228Slinton 
10218228Slinton     b = (boolean) (
1039675Slinton 	(t1 == t_nil and t2->class == PTR) or
1049675Slinton 	(t1->class == PTR and t2 == t_nil)
1059675Slinton     );
1069675Slinton     return b;
1079675Slinton }
1089675Slinton 
10918228Slinton private boolean enumMatch (t1, t2)
11018228Slinton register Symbol t1, t2;
11118228Slinton {
11218228Slinton     boolean b;
11318228Slinton 
11418228Slinton     b = (boolean) (
11518228Slinton 	(t1->class == SCAL and t2->class == CONST and t2->type == t1) or
11618228Slinton 	(t1->class == CONST and t2->class == SCAL and t1->type == t2)
11718228Slinton     );
11818228Slinton     return b;
11918228Slinton }
12018228Slinton 
12118228Slinton private boolean isConstString (t)
12218228Slinton register Symbol t;
12318228Slinton {
12418228Slinton     boolean b;
12518228Slinton 
12618228Slinton     b = (boolean) (
12718228Slinton 	t->language == primlang and t->class == ARRAY and t->type == t_char
12818228Slinton     );
12918228Slinton     return b;
13018228Slinton }
13118228Slinton 
13218228Slinton private boolean stringArrayMatch (t1, t2)
13318228Slinton register Symbol t1, t2;
13418228Slinton {
13518228Slinton     boolean b;
13618228Slinton 
13718228Slinton     b = (boolean) (
13818228Slinton 	(
13918228Slinton 	    isConstString(t1) and
14018228Slinton 	    t2->class == ARRAY and compatible(t2->type, t_char->type)
14118228Slinton 	) or (
14218228Slinton 	    isConstString(t2) and
14318228Slinton 	    t1->class == ARRAY and compatible(t1->type, t_char->type)
14418228Slinton 	)
14518228Slinton     );
14618228Slinton     return b;
14718228Slinton }
14818228Slinton 
14918228Slinton public boolean pascal_typematch (type1, type2)
15018228Slinton Symbol type1, type2;
15118228Slinton {
15218228Slinton     boolean b;
15318228Slinton     Symbol t1, t2, tmp;
15418228Slinton 
15518228Slinton     t1 = rtype(type1);
15618228Slinton     t2 = rtype(type2);
15718228Slinton     if (t1 == t2) {
15818228Slinton 	b = true;
15918228Slinton     } else {
16018228Slinton 	if (t1 == t_char->type or t1 == t_int->type or
16118228Slinton 	    t1 == t_real->type or t1 == t_boolean->type
16218228Slinton 	) {
16318228Slinton 	    tmp = t1;
16418228Slinton 	    t1 = t2;
16518228Slinton 	    t2 = tmp;
16618228Slinton 	}
16718228Slinton 	b = (Boolean) (
16818228Slinton 	    builtinmatch(t1, t2) or rangematch(t1, t2) or
16918228Slinton 	    nilMatch(t1, t2) or enumMatch(t1, t2) or
17018228Slinton 	    stringArrayMatch(t1, t2)
17118228Slinton 	);
17218228Slinton     }
17318228Slinton     return b;
17418228Slinton }
17518228Slinton 
17618228Slinton /*
17718228Slinton  * Indent n spaces.
17818228Slinton  */
17918228Slinton 
18018228Slinton private indent (n)
18118228Slinton int n;
18218228Slinton {
18318228Slinton     if (n > 0) {
18418228Slinton 	printf("%*c", n, ' ');
18518228Slinton     }
18618228Slinton }
18718228Slinton 
18818228Slinton public pascal_printdecl (s)
1899675Slinton Symbol s;
1909675Slinton {
1919675Slinton     register Symbol t;
1929675Slinton     Boolean semicolon;
1939675Slinton 
1949675Slinton     semicolon = true;
19518228Slinton     if (s->class == TYPEREF) {
19618228Slinton 	resolveRef(t);
19718228Slinton     }
1989675Slinton     switch (s->class) {
1999675Slinton 	case CONST:
2009675Slinton 	    if (s->type->class == SCAL) {
20118228Slinton 		semicolon = false;
20218228Slinton 		printf("enum constant, ord ");
20318228Slinton 		eval(s->symvalue.constval);
20418228Slinton 		pascal_printval(s);
2059675Slinton 	    } else {
2069675Slinton 		printf("const %s = ", symname(s));
20718228Slinton 		eval(s->symvalue.constval);
20818228Slinton 		pascal_printval(s);
2099675Slinton 	    }
2109675Slinton 	    break;
2119675Slinton 
2129675Slinton 	case TYPE:
2139675Slinton 	    printf("type %s = ", symname(s));
21418228Slinton 	    printtype(s, s->type, 0);
2159675Slinton 	    break;
2169675Slinton 
21718228Slinton 	case TYPEREF:
21818228Slinton 	    printf("type %s", symname(s));
21918228Slinton 	    break;
22018228Slinton 
2219675Slinton 	case VAR:
2229675Slinton 	    if (isparam(s)) {
2239675Slinton 		printf("(parameter) %s : ", symname(s));
2249675Slinton 	    } else {
2259675Slinton 		printf("var %s : ", symname(s));
2269675Slinton 	    }
22718228Slinton 	    printtype(s, s->type, 0);
2289675Slinton 	    break;
2299675Slinton 
2309675Slinton 	case REF:
2319675Slinton 	    printf("(var parameter) %s : ", symname(s));
23218228Slinton 	    printtype(s, s->type, 0);
2339675Slinton 	    break;
2349675Slinton 
2359675Slinton 	case RANGE:
2369675Slinton 	case ARRAY:
2379675Slinton 	case RECORD:
2389675Slinton 	case VARNT:
2399675Slinton 	case PTR:
24018228Slinton 	case FILET:
24118228Slinton 	    printtype(s, s, 0);
2429675Slinton 	    semicolon = false;
2439675Slinton 	    break;
2449675Slinton 
2459675Slinton 	case FVAR:
2469675Slinton 	    printf("(function variable) %s : ", symname(s));
24718228Slinton 	    printtype(s, s->type, 0);
2489675Slinton 	    break;
2499675Slinton 
2509675Slinton 	case FIELD:
2519675Slinton 	    printf("(field) %s : ", symname(s));
25218228Slinton 	    printtype(s, s->type, 0);
2539675Slinton 	    break;
2549675Slinton 
2559675Slinton 	case PROC:
2569675Slinton 	    printf("procedure %s", symname(s));
2579675Slinton 	    listparams(s);
2589675Slinton 	    break;
2599675Slinton 
2609675Slinton 	case PROG:
2619675Slinton 	    printf("program %s", symname(s));
26218228Slinton 	    listparams(s);
2639675Slinton 	    break;
2649675Slinton 
2659675Slinton 	case FUNC:
2669675Slinton 	    printf("function %s", symname(s));
2679675Slinton 	    listparams(s);
2689675Slinton 	    printf(" : ");
26918228Slinton 	    printtype(s, s->type, 0);
2709675Slinton 	    break;
2719675Slinton 
27218228Slinton 	case MODULE:
27318228Slinton 	    printf("module %s", symname(s));
27418228Slinton 	    break;
27518228Slinton 
27618228Slinton 	  /*
27718228Slinton 	   * the parameter list of the following should be printed
27818228Slinton 	   * eventually
27918228Slinton 	   */
28018228Slinton 	case  FPROC:
28118228Slinton 	    printf("procedure %s()", symname(s));
28218228Slinton 	    break;
28318228Slinton 
28418228Slinton 	case FFUNC:
28518228Slinton 	    printf("function %s()", symname(s));
28618228Slinton 	    break;
28718228Slinton 
2889675Slinton 	default:
28918228Slinton 	    printf("%s : (class %s)", symname(s), classname(s));
29018228Slinton 	    break;
2919675Slinton     }
2929675Slinton     if (semicolon) {
2939675Slinton 	putchar(';');
2949675Slinton     }
2959675Slinton     putchar('\n');
2969675Slinton }
2979675Slinton 
2989675Slinton /*
2999675Slinton  * Recursive whiz-bang procedure to print the type portion
30018228Slinton  * of a declaration.
3019675Slinton  *
3029675Slinton  * The symbol associated with the type is passed to allow
3039675Slinton  * searching for type names without getting "type blah = blah".
3049675Slinton  */
3059675Slinton 
30618228Slinton private printtype (s, t, n)
3079675Slinton Symbol s;
3089675Slinton Symbol t;
30918228Slinton int n;
3109675Slinton {
3119675Slinton     register Symbol tmp;
3129675Slinton 
31318228Slinton     if (t->class == TYPEREF) {
31418228Slinton 	resolveRef(t);
31518228Slinton     }
3169675Slinton     switch (t->class) {
3179675Slinton 	case VAR:
3189675Slinton 	case CONST:
3199675Slinton 	case FUNC:
3209675Slinton 	case PROC:
3219675Slinton 	    panic("printtype: class %s", classname(t));
3229675Slinton 	    break;
3239675Slinton 
3249675Slinton 	case ARRAY:
3259675Slinton 	    printf("array[");
3269675Slinton 	    tmp = t->chain;
3279675Slinton 	    if (tmp != nil) {
3289675Slinton 		for (;;) {
32918228Slinton 		    printtype(tmp, tmp, n);
3309675Slinton 		    tmp = tmp->chain;
3319675Slinton 		    if (tmp == nil) {
3329675Slinton 			break;
3339675Slinton 		    }
3349675Slinton 		    printf(", ");
3359675Slinton 		}
3369675Slinton 	    }
3379675Slinton 	    printf("] of ");
33818228Slinton 	    printtype(t, t->type, n);
3399675Slinton 	    break;
3409675Slinton 
3419675Slinton 	case RECORD:
34218228Slinton 	    printRecordDecl(t, n);
3439675Slinton 	    break;
3449675Slinton 
3459675Slinton 	case FIELD:
3469675Slinton 	    if (t->chain != nil) {
34718228Slinton 		printtype(t->chain, t->chain, n);
3489675Slinton 	    }
3499675Slinton 	    printf("\t%s : ", symname(t));
35018228Slinton 	    printtype(t, t->type, n);
3519675Slinton 	    printf(";\n");
3529675Slinton 	    break;
3539675Slinton 
35418228Slinton 	case RANGE:
35518228Slinton 	    printRangeDecl(t);
3569675Slinton 	    break;
3579675Slinton 
3589675Slinton 	case PTR:
35918228Slinton 	    printf("^");
36018228Slinton 	    printtype(t, t->type, n);
3619675Slinton 	    break;
3629675Slinton 
3639675Slinton 	case TYPE:
36418228Slinton 	    if (t->name != nil and ident(t->name)[0] != '\0') {
36518228Slinton 		printname(stdout, t);
3669675Slinton 	    } else {
36718228Slinton 		printtype(t, t->type, n);
3689675Slinton 	    }
3699675Slinton 	    break;
3709675Slinton 
3719675Slinton 	case SCAL:
37218228Slinton 	    printEnumDecl(t, n);
3739675Slinton 	    break;
3749675Slinton 
37518228Slinton 	case SET:
37618228Slinton 	    printf("set of ");
37718228Slinton 	    printtype(t, t->type, n);
37818228Slinton 	    break;
37918228Slinton 
38018228Slinton 	case FILET:
38118228Slinton 	    printf("file of ");
38218228Slinton 	    printtype(t, t->type, n);
38318228Slinton 	    break;
38418228Slinton 
38518228Slinton 	case TYPEREF:
38618228Slinton 	    break;
38718228Slinton 
38818228Slinton 	case FPROC:
38918228Slinton 	    printf("procedure");
39018228Slinton 	    break;
39118228Slinton 
39218228Slinton 	case FFUNC:
39318228Slinton 	    printf("function");
39418228Slinton 	    break;
39518228Slinton 
3969675Slinton 	default:
3979675Slinton 	    printf("(class %d)", t->class);
3989675Slinton 	    break;
3999675Slinton     }
4009675Slinton }
4019675Slinton 
4029675Slinton /*
40318228Slinton  * Print out a record declaration.
40418228Slinton  */
40518228Slinton 
40618228Slinton private printRecordDecl (t, n)
40718228Slinton Symbol t;
40818228Slinton int n;
40918228Slinton {
41018228Slinton     register Symbol f;
41118228Slinton 
41218228Slinton     if (t->chain == nil) {
41318228Slinton 	printf("record end");
41418228Slinton     } else {
41518228Slinton 	printf("record\n");
41618228Slinton 	for (f = t->chain; f != nil; f = f->chain) {
41718228Slinton 	    indent(n+4);
41818228Slinton 	    printf("%s : ", symname(f));
41918228Slinton 	    printtype(f->type, f->type, n+4);
42018228Slinton 	    printf(";\n");
42118228Slinton 	}
42218228Slinton 	indent(n);
42318228Slinton 	printf("end");
42418228Slinton     }
42518228Slinton }
42618228Slinton 
42718228Slinton /*
42818228Slinton  * Print out the declaration of a range type.
42918228Slinton  */
43018228Slinton 
43118228Slinton private printRangeDecl (t)
43218228Slinton Symbol t;
43318228Slinton {
43418228Slinton     long r0, r1;
43518228Slinton 
43618228Slinton     r0 = t->symvalue.rangev.lower;
43718228Slinton     r1 = t->symvalue.rangev.upper;
43818228Slinton     if (t == t_char or istypename(t, "char")) {
43918228Slinton 	if (r0 < 0x20 or r0 > 0x7e) {
44018228Slinton 	    printf("%ld..", r0);
44118228Slinton 	} else {
44218228Slinton 	    printf("'%c'..", (char) r0);
44318228Slinton 	}
44418228Slinton 	if (r1 < 0x20 or r1 > 0x7e) {
44518228Slinton 	    printf("\\%lo", r1);
44618228Slinton 	} else {
44718228Slinton 	    printf("'%c'", (char) r1);
44818228Slinton 	}
44918228Slinton     } else if (r0 > 0 and r1 == 0) {
45018228Slinton 	printf("%ld byte real", r0);
45118228Slinton     } else if (r0 >= 0) {
45218228Slinton 	printf("%lu..%lu", r0, r1);
45318228Slinton     } else {
45418228Slinton 	printf("%ld..%ld", r0, r1);
45518228Slinton     }
45618228Slinton }
45718228Slinton 
45818228Slinton /*
45918228Slinton  * Print out an enumeration declaration.
46018228Slinton  */
46118228Slinton 
46218228Slinton private printEnumDecl (e, n)
46318228Slinton Symbol e;
46418228Slinton int n;
46518228Slinton {
46618228Slinton     Symbol t;
46718228Slinton 
46818228Slinton     printf("(");
46918228Slinton     t = e->chain;
47018228Slinton     if (t != nil) {
47118228Slinton 	printf("%s", symname(t));
47218228Slinton 	t = t->chain;
47318228Slinton 	while (t != nil) {
47418228Slinton 	    printf(", %s", symname(t));
47518228Slinton 	    t = t->chain;
47618228Slinton 	}
47718228Slinton     }
47818228Slinton     printf(")");
47918228Slinton }
48018228Slinton 
48118228Slinton /*
4829675Slinton  * List the parameters of a procedure or function.
4839675Slinton  * No attempt is made to combine like types.
4849675Slinton  */
4859675Slinton 
4869675Slinton private listparams(s)
4879675Slinton Symbol s;
4889675Slinton {
4899675Slinton     Symbol t;
4909675Slinton 
4919675Slinton     if (s->chain != nil) {
4929675Slinton 	putchar('(');
4939675Slinton 	for (t = s->chain; t != nil; t = t->chain) {
4949675Slinton 	    switch (t->class) {
4959675Slinton 		case REF:
4969675Slinton 		    printf("var ");
4979675Slinton 		    break;
4989675Slinton 
4999675Slinton 		case VAR:
5009675Slinton 		    break;
5019675Slinton 
5029675Slinton 		default:
5039675Slinton 		    panic("unexpected class %d for parameter", t->class);
5049675Slinton 	    }
5059675Slinton 	    printf("%s : ", symname(t));
5069675Slinton 	    printtype(t, t->type);
5079675Slinton 	    if (t->chain != nil) {
5089675Slinton 		printf("; ");
5099675Slinton 	    }
5109675Slinton 	}
5119675Slinton 	putchar(')');
5129675Slinton     }
5139675Slinton }
5149675Slinton 
5159675Slinton /*
5169675Slinton  * Print out the value on the top of the expression stack
5179675Slinton  * in the format for the type of the given symbol.
5189675Slinton  */
5199675Slinton 
52018228Slinton public pascal_printval (s)
5219675Slinton Symbol s;
5229675Slinton {
52318228Slinton     prval(s, size(s));
52418228Slinton }
52518228Slinton 
52618228Slinton private prval (s, n)
52718228Slinton Symbol s;
52818228Slinton integer n;
52918228Slinton {
5309675Slinton     Symbol t;
5319675Slinton     Address a;
53218228Slinton     integer len;
5339675Slinton     double r;
53418228Slinton     integer i;
5359675Slinton 
53618228Slinton     if (s->class == TYPEREF) {
53718228Slinton 	resolveRef(s);
53818228Slinton     }
5399675Slinton     switch (s->class) {
54016615Ssam 	case CONST:
5419675Slinton 	case TYPE:
54218228Slinton 	case REF:
54316615Ssam 	case VAR:
54416615Ssam 	case FVAR:
54516615Ssam 	case TAG:
54618228Slinton 	    prval(s->type, n);
54718228Slinton 	    break;
54818228Slinton 
54916615Ssam 	case FIELD:
55018228Slinton 		prval(s->type, n);
5519675Slinton 	    break;
5529675Slinton 
5539675Slinton 	case ARRAY:
5549675Slinton 	    t = rtype(s->type);
55518228Slinton 	    if (t == t_char->type or
55618228Slinton 		(t->class == RANGE and istypename(t->type, "char"))
55718228Slinton 	    ) {
5589675Slinton 		len = size(s);
5599675Slinton 		sp -= len;
5609675Slinton 		printf("'%.*s'", len, sp);
5619675Slinton 		break;
5629675Slinton 	    } else {
5639675Slinton 		printarray(s);
5649675Slinton 	    }
5659675Slinton 	    break;
5669675Slinton 
5679675Slinton 	case RECORD:
5689675Slinton 	    printrecord(s);
5699675Slinton 	    break;
5709675Slinton 
5719675Slinton 	case VARNT:
57218228Slinton 	    printf("[variant]");
5739675Slinton 	    break;
5749675Slinton 
5759675Slinton 	case RANGE:
57618228Slinton 	    printrange(s, n);
57718228Slinton 	    break;
5789675Slinton 
57918228Slinton 	case FILET:
58018228Slinton 	    a = pop(Address);
58118228Slinton 	    if (a == 0) {
58218228Slinton 		printf("nil");
5839675Slinton 	    } else {
58418228Slinton 		printf("0x%x", a);
5859675Slinton 	    }
5869675Slinton 	    break;
5879675Slinton 
58818228Slinton 	case PTR:
58918228Slinton 	    a = pop(Address);
59018228Slinton 	    if (a == 0) {
59118228Slinton 		printf("nil");
5929675Slinton 	    } else {
59318228Slinton 		printf("0x%x", a);
5949675Slinton 	    }
5959675Slinton 	    break;
5969675Slinton 
59718228Slinton 	case SCAL:
59818228Slinton 	    i = 0;
59918228Slinton 	    popn(n, &i);
60018228Slinton 	    if (s->symvalue.iconval < 256) {
60118228Slinton 		i &= 0xff;
60218228Slinton 	    } else if (s->symvalue.iconval < 65536) {
60318228Slinton 		i &= 0xffff;
6049675Slinton 	    }
60518228Slinton 	    printEnum(i, s);
6069675Slinton 	    break;
6079675Slinton 
6089675Slinton 	case FPROC:
6099675Slinton 	case FFUNC:
61018228Slinton 	    a = pop(long);
6119675Slinton 	    t = whatblock(a);
6129675Slinton 	    if (t == nil) {
61318228Slinton 		printf("(proc 0x%x)", a);
6149675Slinton 	    } else {
6159675Slinton 		printf("%s", symname(t));
6169675Slinton 	    }
6179675Slinton 	    break;
6189675Slinton 
61918228Slinton 	case SET:
62018228Slinton 	    printSet(s);
62118228Slinton 	    break;
62218228Slinton 
6239675Slinton 	default:
6249675Slinton 	    if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) {
6259675Slinton 		panic("printval: bad class %d", ord(s->class));
6269675Slinton 	    }
62718228Slinton 	    printf("[%s]", classname(s));
62818228Slinton 	    break;
6299675Slinton     }
6309675Slinton }
63116615Ssam 
63216615Ssam /*
63318228Slinton  * Print out the value of a scalar (non-enumeration) type.
63418228Slinton  */
63518228Slinton 
63618228Slinton private printrange (s, n)
63718228Slinton Symbol s;
63818228Slinton integer n;
63918228Slinton {
64018228Slinton     double d;
64118228Slinton     float f;
64218228Slinton     integer i;
64318228Slinton 
64418228Slinton     if (s->symvalue.rangev.upper == 0 and s->symvalue.rangev.lower > 0) {
64518228Slinton 	if (n == sizeof(float)) {
64618228Slinton 	    popn(n, &f);
64718228Slinton 	    d = f;
64818228Slinton 	} else {
64918228Slinton 	    popn(n, &d);
65018228Slinton 	}
65118228Slinton 	prtreal(d);
65218228Slinton     } else {
65318228Slinton 	i = 0;
65418228Slinton 	popn(n, &i);
65518228Slinton 	printRangeVal(i, s);
65618228Slinton     }
65718228Slinton }
65818228Slinton 
65918228Slinton /*
66018228Slinton  * Print out a set.
66118228Slinton  */
66218228Slinton 
66318228Slinton private printSet (s)
66418228Slinton Symbol s;
66518228Slinton {
66618228Slinton     Symbol t;
66718228Slinton     integer nbytes;
66818228Slinton 
66918228Slinton     nbytes = size(s);
67018228Slinton     t = rtype(s->type);
67118228Slinton     printf("[");
67218228Slinton     sp -= nbytes;
67318228Slinton     if (t->class == SCAL) {
67418228Slinton 	printSetOfEnum(t);
67518228Slinton     } else if (t->class == RANGE) {
67618228Slinton 	printSetOfRange(t);
67718228Slinton     } else {
67818228Slinton 	error("internal error: expected range or enumerated base type for set");
67918228Slinton     }
68018228Slinton     printf("]");
68118228Slinton }
68218228Slinton 
68318228Slinton /*
68418228Slinton  * Print out a set of an enumeration.
68518228Slinton  */
68618228Slinton 
68718228Slinton private printSetOfEnum (t)
68818228Slinton Symbol t;
68918228Slinton {
69018228Slinton     register Symbol e;
69118228Slinton     register integer i, j, *p;
69218228Slinton     boolean first;
69318228Slinton 
69418228Slinton     p = (int *) sp;
69518228Slinton     i = *p;
69618228Slinton     j = 0;
69718228Slinton     e = t->chain;
69818228Slinton     first = true;
69918228Slinton     while (e != nil) {
70018228Slinton 	if ((i&1) == 1) {
70118228Slinton 	    if (first) {
70218228Slinton 		first = false;
70318228Slinton 		printf("%s", symname(e));
70418228Slinton 	    } else {
70518228Slinton 		printf(", %s", symname(e));
70618228Slinton 	    }
70718228Slinton 	}
70818228Slinton 	i >>= 1;
70918228Slinton 	++j;
71018228Slinton 	if (j >= sizeof(integer)*BITSPERBYTE) {
71118228Slinton 	    j = 0;
71218228Slinton 	    ++p;
71318228Slinton 	    i = *p;
71418228Slinton 	}
71518228Slinton 	e = e->chain;
71618228Slinton     }
71718228Slinton }
71818228Slinton 
71918228Slinton /*
72018228Slinton  * Print out a set of a subrange type.
72118228Slinton  */
72218228Slinton 
72318228Slinton private printSetOfRange (t)
72418228Slinton Symbol t;
72518228Slinton {
72618228Slinton     register integer i, j, *p;
72718228Slinton     long v;
72818228Slinton     boolean first;
72918228Slinton 
73018228Slinton     p = (int *) sp;
73118228Slinton     i = *p;
73218228Slinton     j = 0;
73318228Slinton     v = t->symvalue.rangev.lower;
73418228Slinton     first = true;
73518228Slinton     while (v <= t->symvalue.rangev.upper) {
73618228Slinton 	if ((i&1) == 1) {
73718228Slinton 	    if (first) {
73818228Slinton 		first = false;
73918228Slinton 		printf("%ld", v);
74018228Slinton 	    } else {
74118228Slinton 		printf(", %ld", v);
74218228Slinton 	    }
74318228Slinton 	}
74418228Slinton 	i >>= 1;
74518228Slinton 	++j;
74618228Slinton 	if (j >= sizeof(integer)*BITSPERBYTE) {
74718228Slinton 	    j = 0;
74818228Slinton 	    ++p;
74918228Slinton 	    i = *p;
75018228Slinton 	}
75118228Slinton 	++v;
75218228Slinton     }
75318228Slinton }
75418228Slinton 
75518228Slinton /*
75616615Ssam  * Construct a node for subscripting.
75716615Ssam  */
75816615Ssam 
75916615Ssam public Node pascal_buildaref (a, slist)
76016615Ssam Node a, slist;
76116615Ssam {
76216615Ssam     register Symbol t;
76316615Ssam     register Node p;
76416615Ssam     Symbol etype, atype, eltype;
76516615Ssam     Node esub, r;
76616615Ssam 
76716615Ssam     t = rtype(a->nodetype);
76816615Ssam     if (t->class != ARRAY) {
76916615Ssam 	beginerrmsg();
77016615Ssam 	prtree(stderr, a);
77116615Ssam 	fprintf(stderr, " is not an array");
77216615Ssam 	enderrmsg();
77316615Ssam     } else {
77418228Slinton 	r = a;
77518228Slinton 	eltype = t->type;
77616615Ssam 	p = slist;
77716615Ssam 	t = t->chain;
77816615Ssam 	for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
77916615Ssam 	    esub = p->value.arg[0];
78016615Ssam 	    etype = rtype(esub->nodetype);
78116615Ssam 	    atype = rtype(t);
78216615Ssam 	    if (not compatible(atype, etype)) {
78316615Ssam 		beginerrmsg();
78416615Ssam 		fprintf(stderr, "subscript ");
78516615Ssam 		prtree(stderr, esub);
78616615Ssam 		fprintf(stderr, " is the wrong type");
78716615Ssam 		enderrmsg();
78816615Ssam 	    }
78916615Ssam 	    r = build(O_INDEX, r, esub);
79016615Ssam 	    r->nodetype = eltype;
79116615Ssam 	}
79216615Ssam 	if (p != nil or t != nil) {
79316615Ssam 	    beginerrmsg();
79416615Ssam 	    if (p != nil) {
79516615Ssam 		fprintf(stderr, "too many subscripts for ");
79616615Ssam 	    } else {
79716615Ssam 		fprintf(stderr, "not enough subscripts for ");
79816615Ssam 	    }
79916615Ssam 	    prtree(stderr, a);
80016615Ssam 	    enderrmsg();
80116615Ssam 	}
80216615Ssam     }
80316615Ssam     return r;
80416615Ssam }
80516615Ssam 
80616615Ssam /*
80716615Ssam  * Evaluate a subscript index.
80816615Ssam  */
80916615Ssam 
81018228Slinton public pascal_evalaref (s, base, i)
81116615Ssam Symbol s;
81218228Slinton Address base;
81316615Ssam long i;
81416615Ssam {
81518228Slinton     Symbol t;
81616615Ssam     long lb, ub;
81716615Ssam 
81818228Slinton     t = rtype(s);
81918228Slinton     s = rtype(t->chain);
82018228Slinton     findbounds(s, &lb, &ub);
82116615Ssam     if (i < lb or i > ub) {
82216615Ssam 	error("subscript %d out of range [%d..%d]", i, lb, ub);
82316615Ssam     }
82418228Slinton     push(long, base + (i - lb) * size(t->type));
82516615Ssam }
82616615Ssam 
82716615Ssam /*
82816615Ssam  * Initial Pascal type information.
82916615Ssam  */
83016615Ssam 
83116615Ssam #define NTYPES 4
83216615Ssam 
83318228Slinton private Symbol inittype[NTYPES + 1];
83416615Ssam 
83518228Slinton private addType (n, s, lower, upper)
83618228Slinton integer n;
83716615Ssam String s;
83816615Ssam long lower, upper;
83916615Ssam {
84016615Ssam     register Symbol t;
84116615Ssam 
84218228Slinton     if (n > NTYPES) {
84318228Slinton 	panic("initial Pascal type number too large for '%s'", s);
84416615Ssam     }
84518228Slinton     t = insert(identname(s, true));
84616615Ssam     t->language = pasc;
84718228Slinton     t->class = TYPE;
84818228Slinton     t->type = newSymbol(nil, 0, RANGE, t, nil);
84918228Slinton     t->type->symvalue.rangev.lower = lower;
85018228Slinton     t->type->symvalue.rangev.upper = upper;
85118228Slinton     t->type->language = pasc;
85218228Slinton     inittype[n] = t;
85316615Ssam }
85416615Ssam 
85516615Ssam private initTypes ()
85616615Ssam {
85718228Slinton     addType(1, "boolean", 0L, 1L);
85818228Slinton     addType(2, "char", 0L, 255L);
85918228Slinton     addType(3, "integer", 0x80000000L, 0x7fffffffL);
86018228Slinton     addType(4, "real", 8L, 0L);
86118228Slinton     initialized = true;
86216615Ssam }
86316615Ssam 
86416615Ssam /*
86516615Ssam  * Initialize typetable.
86616615Ssam  */
86716615Ssam 
86816615Ssam public pascal_modinit (typetable)
86916615Ssam Symbol typetable[];
87016615Ssam {
87116615Ssam     register integer i;
87216615Ssam 
87318228Slinton     if (not initialized) {
87418228Slinton 	initTypes();
87518228Slinton 	initialized = true;
87618228Slinton     }
87718228Slinton     for (i = 1; i <= NTYPES; i++) {
87816615Ssam 	typetable[i] = inittype[i];
87916615Ssam     }
88016615Ssam }
88116615Ssam 
88216615Ssam public boolean pascal_hasmodules ()
88316615Ssam {
88416615Ssam     return false;
88516615Ssam }
88616615Ssam 
88716615Ssam public boolean pascal_passaddr (param, exprtype)
88816615Ssam Symbol param, exprtype;
88916615Ssam {
89016615Ssam     return false;
89116615Ssam }
892