xref: /csrg-svn/old/dbx/pascal.c (revision 38105)
121618Sdist /*
2*38105Sbostic  * Copyright (c) 1983 The Regents of the University of California.
3*38105Sbostic  * All rights reserved.
4*38105Sbostic  *
5*38105Sbostic  * Redistribution and use in source and binary forms are permitted
6*38105Sbostic  * provided that the above copyright notice and this paragraph are
7*38105Sbostic  * duplicated in all such forms and that any documentation,
8*38105Sbostic  * advertising materials, and other materials related to such
9*38105Sbostic  * distribution and use acknowledge that the software was developed
10*38105Sbostic  * by the University of California, Berkeley.  The name of the
11*38105Sbostic  * University may not be used to endorse or promote products derived
12*38105Sbostic  * from this software without specific prior written permission.
13*38105Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*38105Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*38105Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621618Sdist  */
179675Slinton 
1821618Sdist #ifndef lint
19*38105Sbostic static char sccsid[] = "@(#)pascal.c	5.2 (Berkeley) 05/23/89";
20*38105Sbostic #endif /* not lint */
219675Slinton 
229675Slinton /*
239675Slinton  * Pascal-dependent symbol routines.
249675Slinton  */
259675Slinton 
269675Slinton #include "defs.h"
279675Slinton #include "symbols.h"
289675Slinton #include "pascal.h"
299675Slinton #include "languages.h"
309675Slinton #include "tree.h"
319675Slinton #include "eval.h"
329675Slinton #include "mappings.h"
339675Slinton #include "process.h"
349675Slinton #include "runtime.h"
359675Slinton #include "machine.h"
369675Slinton 
379675Slinton #ifndef public
389675Slinton #endif
399675Slinton 
4016615Ssam private Language pasc;
4118228Slinton private boolean initialized;
4216615Ssam 
439675Slinton /*
449675Slinton  * Initialize Pascal information.
459675Slinton  */
469675Slinton 
479675Slinton public pascal_init()
489675Slinton {
4916615Ssam     pasc = language_define("pascal", ".p");
5016615Ssam     language_setop(pasc, L_PRINTDECL, pascal_printdecl);
5116615Ssam     language_setop(pasc, L_PRINTVAL, pascal_printval);
5216615Ssam     language_setop(pasc, L_TYPEMATCH, pascal_typematch);
5316615Ssam     language_setop(pasc, L_BUILDAREF, pascal_buildaref);
5416615Ssam     language_setop(pasc, L_EVALAREF, pascal_evalaref);
5516615Ssam     language_setop(pasc, L_MODINIT, pascal_modinit);
5616615Ssam     language_setop(pasc, L_HASMODULES, pascal_hasmodules);
5716615Ssam     language_setop(pasc, L_PASSADDR, pascal_passaddr);
5818228Slinton     initialized = false;
599675Slinton }
609675Slinton 
619675Slinton /*
6218228Slinton  * Typematch tests if two types are compatible.  The issue
6318228Slinton  * is a bit complicated, so several subfunctions are used for
6418228Slinton  * various kinds of compatibility.
659675Slinton  */
669675Slinton 
6718228Slinton private boolean builtinmatch (t1, t2)
6818228Slinton register Symbol t1, t2;
699675Slinton {
7018228Slinton     boolean b;
719675Slinton 
7218228Slinton     b = (boolean) (
7318228Slinton 	(
7418228Slinton 	    t2 == t_int->type and
7518228Slinton 	    t1->class == RANGE and istypename(t1->type, "integer")
7618228Slinton 	) or (
7718228Slinton 	    t2 == t_char->type and
7818228Slinton 	    t1->class == RANGE and istypename(t1->type, "char")
7918228Slinton 	) or (
8018228Slinton 	    t2 == t_real->type and
8118228Slinton 	    t1->class == RANGE and istypename(t1->type, "real")
8218228Slinton 	) or (
8318228Slinton 	    t2 == t_boolean->type and
8418228Slinton 	    t1->class == RANGE and istypename(t1->type, "boolean")
8518228Slinton 	)
8618228Slinton     );
8718228Slinton     return b;
8818228Slinton }
8918228Slinton 
9018228Slinton private boolean rangematch (t1, t2)
9118228Slinton register Symbol t1, t2;
9218228Slinton {
9318228Slinton     boolean b;
9418228Slinton     register Symbol rt1, rt2;
9518228Slinton 
9618228Slinton     if (t1->class == RANGE and t2->class == RANGE) {
9718228Slinton 	rt1 = rtype(t1->type);
9818228Slinton 	rt2 = rtype(t2->type);
9918228Slinton 	b = (boolean) (rt1->type == rt2->type);
10018228Slinton     } else {
10118228Slinton 	b = false;
10218228Slinton     }
10318228Slinton     return b;
10418228Slinton }
10518228Slinton 
10618228Slinton private boolean nilMatch (t1, t2)
10718228Slinton register Symbol t1, t2;
10818228Slinton {
10918228Slinton     boolean b;
11018228Slinton 
11118228Slinton     b = (boolean) (
1129675Slinton 	(t1 == t_nil and t2->class == PTR) or
1139675Slinton 	(t1->class == PTR and t2 == t_nil)
1149675Slinton     );
1159675Slinton     return b;
1169675Slinton }
1179675Slinton 
11818228Slinton private boolean enumMatch (t1, t2)
11918228Slinton register Symbol t1, t2;
12018228Slinton {
12118228Slinton     boolean b;
12218228Slinton 
12318228Slinton     b = (boolean) (
12418228Slinton 	(t1->class == SCAL and t2->class == CONST and t2->type == t1) or
12518228Slinton 	(t1->class == CONST and t2->class == SCAL and t1->type == t2)
12618228Slinton     );
12718228Slinton     return b;
12818228Slinton }
12918228Slinton 
13018228Slinton private boolean isConstString (t)
13118228Slinton register Symbol t;
13218228Slinton {
13318228Slinton     boolean b;
13418228Slinton 
13518228Slinton     b = (boolean) (
13618228Slinton 	t->language == primlang and t->class == ARRAY and t->type == t_char
13718228Slinton     );
13818228Slinton     return b;
13918228Slinton }
14018228Slinton 
14118228Slinton private boolean stringArrayMatch (t1, t2)
14218228Slinton register Symbol t1, t2;
14318228Slinton {
14418228Slinton     boolean b;
14518228Slinton 
14618228Slinton     b = (boolean) (
14718228Slinton 	(
14818228Slinton 	    isConstString(t1) and
14918228Slinton 	    t2->class == ARRAY and compatible(t2->type, t_char->type)
15018228Slinton 	) or (
15118228Slinton 	    isConstString(t2) and
15218228Slinton 	    t1->class == ARRAY and compatible(t1->type, t_char->type)
15318228Slinton 	)
15418228Slinton     );
15518228Slinton     return b;
15618228Slinton }
15718228Slinton 
15818228Slinton public boolean pascal_typematch (type1, type2)
15918228Slinton Symbol type1, type2;
16018228Slinton {
16118228Slinton     boolean b;
16218228Slinton     Symbol t1, t2, tmp;
16318228Slinton 
16418228Slinton     t1 = rtype(type1);
16518228Slinton     t2 = rtype(type2);
16618228Slinton     if (t1 == t2) {
16718228Slinton 	b = true;
16818228Slinton     } else {
16918228Slinton 	if (t1 == t_char->type or t1 == t_int->type or
17018228Slinton 	    t1 == t_real->type or t1 == t_boolean->type
17118228Slinton 	) {
17218228Slinton 	    tmp = t1;
17318228Slinton 	    t1 = t2;
17418228Slinton 	    t2 = tmp;
17518228Slinton 	}
17618228Slinton 	b = (Boolean) (
17718228Slinton 	    builtinmatch(t1, t2) or rangematch(t1, t2) or
17818228Slinton 	    nilMatch(t1, t2) or enumMatch(t1, t2) or
17918228Slinton 	    stringArrayMatch(t1, t2)
18018228Slinton 	);
18118228Slinton     }
18218228Slinton     return b;
18318228Slinton }
18418228Slinton 
18518228Slinton /*
18618228Slinton  * Indent n spaces.
18718228Slinton  */
18818228Slinton 
18918228Slinton private indent (n)
19018228Slinton int n;
19118228Slinton {
19218228Slinton     if (n > 0) {
19318228Slinton 	printf("%*c", n, ' ');
19418228Slinton     }
19518228Slinton }
19618228Slinton 
19718228Slinton public pascal_printdecl (s)
1989675Slinton Symbol s;
1999675Slinton {
2009675Slinton     register Symbol t;
2019675Slinton     Boolean semicolon;
2029675Slinton 
2039675Slinton     semicolon = true;
20418228Slinton     if (s->class == TYPEREF) {
20518228Slinton 	resolveRef(t);
20618228Slinton     }
2079675Slinton     switch (s->class) {
2089675Slinton 	case CONST:
2099675Slinton 	    if (s->type->class == SCAL) {
21018228Slinton 		semicolon = false;
21118228Slinton 		printf("enum constant, ord ");
21218228Slinton 		eval(s->symvalue.constval);
21318228Slinton 		pascal_printval(s);
2149675Slinton 	    } else {
2159675Slinton 		printf("const %s = ", symname(s));
21618228Slinton 		eval(s->symvalue.constval);
21718228Slinton 		pascal_printval(s);
2189675Slinton 	    }
2199675Slinton 	    break;
2209675Slinton 
2219675Slinton 	case TYPE:
2229675Slinton 	    printf("type %s = ", symname(s));
22318228Slinton 	    printtype(s, s->type, 0);
2249675Slinton 	    break;
2259675Slinton 
22618228Slinton 	case TYPEREF:
22718228Slinton 	    printf("type %s", symname(s));
22818228Slinton 	    break;
22918228Slinton 
2309675Slinton 	case VAR:
2319675Slinton 	    if (isparam(s)) {
2329675Slinton 		printf("(parameter) %s : ", symname(s));
2339675Slinton 	    } else {
2349675Slinton 		printf("var %s : ", symname(s));
2359675Slinton 	    }
23618228Slinton 	    printtype(s, s->type, 0);
2379675Slinton 	    break;
2389675Slinton 
2399675Slinton 	case REF:
2409675Slinton 	    printf("(var parameter) %s : ", symname(s));
24118228Slinton 	    printtype(s, s->type, 0);
2429675Slinton 	    break;
2439675Slinton 
2449675Slinton 	case RANGE:
2459675Slinton 	case ARRAY:
2469675Slinton 	case RECORD:
2479675Slinton 	case VARNT:
2489675Slinton 	case PTR:
24918228Slinton 	case FILET:
25018228Slinton 	    printtype(s, s, 0);
2519675Slinton 	    semicolon = false;
2529675Slinton 	    break;
2539675Slinton 
2549675Slinton 	case FVAR:
2559675Slinton 	    printf("(function variable) %s : ", symname(s));
25618228Slinton 	    printtype(s, s->type, 0);
2579675Slinton 	    break;
2589675Slinton 
2599675Slinton 	case FIELD:
2609675Slinton 	    printf("(field) %s : ", symname(s));
26118228Slinton 	    printtype(s, s->type, 0);
2629675Slinton 	    break;
2639675Slinton 
2649675Slinton 	case PROC:
2659675Slinton 	    printf("procedure %s", symname(s));
2669675Slinton 	    listparams(s);
2679675Slinton 	    break;
2689675Slinton 
2699675Slinton 	case PROG:
2709675Slinton 	    printf("program %s", symname(s));
27118228Slinton 	    listparams(s);
2729675Slinton 	    break;
2739675Slinton 
2749675Slinton 	case FUNC:
2759675Slinton 	    printf("function %s", symname(s));
2769675Slinton 	    listparams(s);
2779675Slinton 	    printf(" : ");
27818228Slinton 	    printtype(s, s->type, 0);
2799675Slinton 	    break;
2809675Slinton 
28118228Slinton 	case MODULE:
28218228Slinton 	    printf("module %s", symname(s));
28318228Slinton 	    break;
28418228Slinton 
28518228Slinton 	  /*
28618228Slinton 	   * the parameter list of the following should be printed
28718228Slinton 	   * eventually
28818228Slinton 	   */
28918228Slinton 	case  FPROC:
29018228Slinton 	    printf("procedure %s()", symname(s));
29118228Slinton 	    break;
29218228Slinton 
29318228Slinton 	case FFUNC:
29418228Slinton 	    printf("function %s()", symname(s));
29518228Slinton 	    break;
29618228Slinton 
2979675Slinton 	default:
29818228Slinton 	    printf("%s : (class %s)", symname(s), classname(s));
29918228Slinton 	    break;
3009675Slinton     }
3019675Slinton     if (semicolon) {
3029675Slinton 	putchar(';');
3039675Slinton     }
3049675Slinton     putchar('\n');
3059675Slinton }
3069675Slinton 
3079675Slinton /*
3089675Slinton  * Recursive whiz-bang procedure to print the type portion
30918228Slinton  * of a declaration.
3109675Slinton  *
3119675Slinton  * The symbol associated with the type is passed to allow
3129675Slinton  * searching for type names without getting "type blah = blah".
3139675Slinton  */
3149675Slinton 
31518228Slinton private printtype (s, t, n)
3169675Slinton Symbol s;
3179675Slinton Symbol t;
31818228Slinton int n;
3199675Slinton {
3209675Slinton     register Symbol tmp;
3219675Slinton 
32218228Slinton     if (t->class == TYPEREF) {
32318228Slinton 	resolveRef(t);
32418228Slinton     }
3259675Slinton     switch (t->class) {
3269675Slinton 	case VAR:
3279675Slinton 	case CONST:
3289675Slinton 	case FUNC:
3299675Slinton 	case PROC:
3309675Slinton 	    panic("printtype: class %s", classname(t));
3319675Slinton 	    break;
3329675Slinton 
3339675Slinton 	case ARRAY:
3349675Slinton 	    printf("array[");
3359675Slinton 	    tmp = t->chain;
3369675Slinton 	    if (tmp != nil) {
3379675Slinton 		for (;;) {
33818228Slinton 		    printtype(tmp, tmp, n);
3399675Slinton 		    tmp = tmp->chain;
3409675Slinton 		    if (tmp == nil) {
3419675Slinton 			break;
3429675Slinton 		    }
3439675Slinton 		    printf(", ");
3449675Slinton 		}
3459675Slinton 	    }
3469675Slinton 	    printf("] of ");
34718228Slinton 	    printtype(t, t->type, n);
3489675Slinton 	    break;
3499675Slinton 
3509675Slinton 	case RECORD:
35118228Slinton 	    printRecordDecl(t, n);
3529675Slinton 	    break;
3539675Slinton 
3549675Slinton 	case FIELD:
3559675Slinton 	    if (t->chain != nil) {
35618228Slinton 		printtype(t->chain, t->chain, n);
3579675Slinton 	    }
3589675Slinton 	    printf("\t%s : ", symname(t));
35918228Slinton 	    printtype(t, t->type, n);
3609675Slinton 	    printf(";\n");
3619675Slinton 	    break;
3629675Slinton 
36318228Slinton 	case RANGE:
36418228Slinton 	    printRangeDecl(t);
3659675Slinton 	    break;
3669675Slinton 
3679675Slinton 	case PTR:
36818228Slinton 	    printf("^");
36918228Slinton 	    printtype(t, t->type, n);
3709675Slinton 	    break;
3719675Slinton 
3729675Slinton 	case TYPE:
37318228Slinton 	    if (t->name != nil and ident(t->name)[0] != '\0') {
37418228Slinton 		printname(stdout, t);
3759675Slinton 	    } else {
37618228Slinton 		printtype(t, t->type, n);
3779675Slinton 	    }
3789675Slinton 	    break;
3799675Slinton 
3809675Slinton 	case SCAL:
38118228Slinton 	    printEnumDecl(t, n);
3829675Slinton 	    break;
3839675Slinton 
38418228Slinton 	case SET:
38518228Slinton 	    printf("set of ");
38618228Slinton 	    printtype(t, t->type, n);
38718228Slinton 	    break;
38818228Slinton 
38918228Slinton 	case FILET:
39018228Slinton 	    printf("file of ");
39118228Slinton 	    printtype(t, t->type, n);
39218228Slinton 	    break;
39318228Slinton 
39418228Slinton 	case TYPEREF:
39518228Slinton 	    break;
39618228Slinton 
39718228Slinton 	case FPROC:
39818228Slinton 	    printf("procedure");
39918228Slinton 	    break;
40018228Slinton 
40118228Slinton 	case FFUNC:
40218228Slinton 	    printf("function");
40318228Slinton 	    break;
40418228Slinton 
4059675Slinton 	default:
4069675Slinton 	    printf("(class %d)", t->class);
4079675Slinton 	    break;
4089675Slinton     }
4099675Slinton }
4109675Slinton 
4119675Slinton /*
41218228Slinton  * Print out a record declaration.
41318228Slinton  */
41418228Slinton 
41518228Slinton private printRecordDecl (t, n)
41618228Slinton Symbol t;
41718228Slinton int n;
41818228Slinton {
41918228Slinton     register Symbol f;
42018228Slinton 
42118228Slinton     if (t->chain == nil) {
42218228Slinton 	printf("record end");
42318228Slinton     } else {
42418228Slinton 	printf("record\n");
42518228Slinton 	for (f = t->chain; f != nil; f = f->chain) {
42618228Slinton 	    indent(n+4);
42718228Slinton 	    printf("%s : ", symname(f));
42818228Slinton 	    printtype(f->type, f->type, n+4);
42918228Slinton 	    printf(";\n");
43018228Slinton 	}
43118228Slinton 	indent(n);
43218228Slinton 	printf("end");
43318228Slinton     }
43418228Slinton }
43518228Slinton 
43618228Slinton /*
43718228Slinton  * Print out the declaration of a range type.
43818228Slinton  */
43918228Slinton 
44018228Slinton private printRangeDecl (t)
44118228Slinton Symbol t;
44218228Slinton {
44318228Slinton     long r0, r1;
44418228Slinton 
44518228Slinton     r0 = t->symvalue.rangev.lower;
44618228Slinton     r1 = t->symvalue.rangev.upper;
44718228Slinton     if (t == t_char or istypename(t, "char")) {
44818228Slinton 	if (r0 < 0x20 or r0 > 0x7e) {
44918228Slinton 	    printf("%ld..", r0);
45018228Slinton 	} else {
45118228Slinton 	    printf("'%c'..", (char) r0);
45218228Slinton 	}
45318228Slinton 	if (r1 < 0x20 or r1 > 0x7e) {
45418228Slinton 	    printf("\\%lo", r1);
45518228Slinton 	} else {
45618228Slinton 	    printf("'%c'", (char) r1);
45718228Slinton 	}
45818228Slinton     } else if (r0 > 0 and r1 == 0) {
45918228Slinton 	printf("%ld byte real", r0);
46018228Slinton     } else if (r0 >= 0) {
46118228Slinton 	printf("%lu..%lu", r0, r1);
46218228Slinton     } else {
46318228Slinton 	printf("%ld..%ld", r0, r1);
46418228Slinton     }
46518228Slinton }
46618228Slinton 
46718228Slinton /*
46818228Slinton  * Print out an enumeration declaration.
46918228Slinton  */
47018228Slinton 
47118228Slinton private printEnumDecl (e, n)
47218228Slinton Symbol e;
47318228Slinton int n;
47418228Slinton {
47518228Slinton     Symbol t;
47618228Slinton 
47718228Slinton     printf("(");
47818228Slinton     t = e->chain;
47918228Slinton     if (t != nil) {
48018228Slinton 	printf("%s", symname(t));
48118228Slinton 	t = t->chain;
48218228Slinton 	while (t != nil) {
48318228Slinton 	    printf(", %s", symname(t));
48418228Slinton 	    t = t->chain;
48518228Slinton 	}
48618228Slinton     }
48718228Slinton     printf(")");
48818228Slinton }
48918228Slinton 
49018228Slinton /*
4919675Slinton  * List the parameters of a procedure or function.
4929675Slinton  * No attempt is made to combine like types.
4939675Slinton  */
4949675Slinton 
4959675Slinton private listparams(s)
4969675Slinton Symbol s;
4979675Slinton {
4989675Slinton     Symbol t;
4999675Slinton 
5009675Slinton     if (s->chain != nil) {
5019675Slinton 	putchar('(');
5029675Slinton 	for (t = s->chain; t != nil; t = t->chain) {
5039675Slinton 	    switch (t->class) {
5049675Slinton 		case REF:
5059675Slinton 		    printf("var ");
5069675Slinton 		    break;
5079675Slinton 
5089675Slinton 		case VAR:
5099675Slinton 		    break;
5109675Slinton 
5119675Slinton 		default:
5129675Slinton 		    panic("unexpected class %d for parameter", t->class);
5139675Slinton 	    }
5149675Slinton 	    printf("%s : ", symname(t));
5159675Slinton 	    printtype(t, t->type);
5169675Slinton 	    if (t->chain != nil) {
5179675Slinton 		printf("; ");
5189675Slinton 	    }
5199675Slinton 	}
5209675Slinton 	putchar(')');
5219675Slinton     }
5229675Slinton }
5239675Slinton 
5249675Slinton /*
5259675Slinton  * Print out the value on the top of the expression stack
5269675Slinton  * in the format for the type of the given symbol.
5279675Slinton  */
5289675Slinton 
52918228Slinton public pascal_printval (s)
5309675Slinton Symbol s;
5319675Slinton {
53218228Slinton     prval(s, size(s));
53318228Slinton }
53418228Slinton 
53518228Slinton private prval (s, n)
53618228Slinton Symbol s;
53718228Slinton integer n;
53818228Slinton {
5399675Slinton     Symbol t;
5409675Slinton     Address a;
54118228Slinton     integer len;
5429675Slinton     double r;
54318228Slinton     integer i;
5449675Slinton 
54518228Slinton     if (s->class == TYPEREF) {
54618228Slinton 	resolveRef(s);
54718228Slinton     }
5489675Slinton     switch (s->class) {
54916615Ssam 	case CONST:
5509675Slinton 	case TYPE:
55118228Slinton 	case REF:
55216615Ssam 	case VAR:
55316615Ssam 	case FVAR:
55416615Ssam 	case TAG:
55518228Slinton 	    prval(s->type, n);
55618228Slinton 	    break;
55718228Slinton 
55816615Ssam 	case FIELD:
55918228Slinton 		prval(s->type, n);
5609675Slinton 	    break;
5619675Slinton 
5629675Slinton 	case ARRAY:
5639675Slinton 	    t = rtype(s->type);
56418228Slinton 	    if (t == t_char->type or
56518228Slinton 		(t->class == RANGE and istypename(t->type, "char"))
56618228Slinton 	    ) {
5679675Slinton 		len = size(s);
5689675Slinton 		sp -= len;
5699675Slinton 		printf("'%.*s'", len, sp);
5709675Slinton 		break;
5719675Slinton 	    } else {
5729675Slinton 		printarray(s);
5739675Slinton 	    }
5749675Slinton 	    break;
5759675Slinton 
5769675Slinton 	case RECORD:
5779675Slinton 	    printrecord(s);
5789675Slinton 	    break;
5799675Slinton 
5809675Slinton 	case VARNT:
58118228Slinton 	    printf("[variant]");
5829675Slinton 	    break;
5839675Slinton 
5849675Slinton 	case RANGE:
58518228Slinton 	    printrange(s, n);
58618228Slinton 	    break;
5879675Slinton 
58818228Slinton 	case FILET:
58918228Slinton 	    a = pop(Address);
59018228Slinton 	    if (a == 0) {
59118228Slinton 		printf("nil");
5929675Slinton 	    } else {
59318228Slinton 		printf("0x%x", a);
5949675Slinton 	    }
5959675Slinton 	    break;
5969675Slinton 
59718228Slinton 	case PTR:
59818228Slinton 	    a = pop(Address);
59918228Slinton 	    if (a == 0) {
60018228Slinton 		printf("nil");
6019675Slinton 	    } else {
60218228Slinton 		printf("0x%x", a);
6039675Slinton 	    }
6049675Slinton 	    break;
6059675Slinton 
60618228Slinton 	case SCAL:
60718228Slinton 	    i = 0;
60818228Slinton 	    popn(n, &i);
60918228Slinton 	    if (s->symvalue.iconval < 256) {
61018228Slinton 		i &= 0xff;
61118228Slinton 	    } else if (s->symvalue.iconval < 65536) {
61218228Slinton 		i &= 0xffff;
6139675Slinton 	    }
61418228Slinton 	    printEnum(i, s);
6159675Slinton 	    break;
6169675Slinton 
6179675Slinton 	case FPROC:
6189675Slinton 	case FFUNC:
61918228Slinton 	    a = pop(long);
6209675Slinton 	    t = whatblock(a);
6219675Slinton 	    if (t == nil) {
62218228Slinton 		printf("(proc 0x%x)", a);
6239675Slinton 	    } else {
6249675Slinton 		printf("%s", symname(t));
6259675Slinton 	    }
6269675Slinton 	    break;
6279675Slinton 
62818228Slinton 	case SET:
62918228Slinton 	    printSet(s);
63018228Slinton 	    break;
63118228Slinton 
6329675Slinton 	default:
6339675Slinton 	    if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) {
6349675Slinton 		panic("printval: bad class %d", ord(s->class));
6359675Slinton 	    }
63618228Slinton 	    printf("[%s]", classname(s));
63718228Slinton 	    break;
6389675Slinton     }
6399675Slinton }
64016615Ssam 
64116615Ssam /*
64218228Slinton  * Print out the value of a scalar (non-enumeration) type.
64318228Slinton  */
64418228Slinton 
64518228Slinton private printrange (s, n)
64618228Slinton Symbol s;
64718228Slinton integer n;
64818228Slinton {
64918228Slinton     double d;
65018228Slinton     float f;
65118228Slinton     integer i;
65218228Slinton 
65318228Slinton     if (s->symvalue.rangev.upper == 0 and s->symvalue.rangev.lower > 0) {
65418228Slinton 	if (n == sizeof(float)) {
65518228Slinton 	    popn(n, &f);
65618228Slinton 	    d = f;
65718228Slinton 	} else {
65818228Slinton 	    popn(n, &d);
65918228Slinton 	}
66018228Slinton 	prtreal(d);
66118228Slinton     } else {
66218228Slinton 	i = 0;
66318228Slinton 	popn(n, &i);
66418228Slinton 	printRangeVal(i, s);
66518228Slinton     }
66618228Slinton }
66718228Slinton 
66818228Slinton /*
66918228Slinton  * Print out a set.
67018228Slinton  */
67118228Slinton 
67218228Slinton private printSet (s)
67318228Slinton Symbol s;
67418228Slinton {
67518228Slinton     Symbol t;
67618228Slinton     integer nbytes;
67718228Slinton 
67818228Slinton     nbytes = size(s);
67918228Slinton     t = rtype(s->type);
68018228Slinton     printf("[");
68118228Slinton     sp -= nbytes;
68218228Slinton     if (t->class == SCAL) {
68318228Slinton 	printSetOfEnum(t);
68418228Slinton     } else if (t->class == RANGE) {
68518228Slinton 	printSetOfRange(t);
68618228Slinton     } else {
68718228Slinton 	error("internal error: expected range or enumerated base type for set");
68818228Slinton     }
68918228Slinton     printf("]");
69018228Slinton }
69118228Slinton 
69218228Slinton /*
69318228Slinton  * Print out a set of an enumeration.
69418228Slinton  */
69518228Slinton 
69618228Slinton private printSetOfEnum (t)
69718228Slinton Symbol t;
69818228Slinton {
69918228Slinton     register Symbol e;
70018228Slinton     register integer i, j, *p;
70118228Slinton     boolean first;
70218228Slinton 
70318228Slinton     p = (int *) sp;
70418228Slinton     i = *p;
70518228Slinton     j = 0;
70618228Slinton     e = t->chain;
70718228Slinton     first = true;
70818228Slinton     while (e != nil) {
70918228Slinton 	if ((i&1) == 1) {
71018228Slinton 	    if (first) {
71118228Slinton 		first = false;
71218228Slinton 		printf("%s", symname(e));
71318228Slinton 	    } else {
71418228Slinton 		printf(", %s", symname(e));
71518228Slinton 	    }
71618228Slinton 	}
71718228Slinton 	i >>= 1;
71818228Slinton 	++j;
71918228Slinton 	if (j >= sizeof(integer)*BITSPERBYTE) {
72018228Slinton 	    j = 0;
72118228Slinton 	    ++p;
72218228Slinton 	    i = *p;
72318228Slinton 	}
72418228Slinton 	e = e->chain;
72518228Slinton     }
72618228Slinton }
72718228Slinton 
72818228Slinton /*
72918228Slinton  * Print out a set of a subrange type.
73018228Slinton  */
73118228Slinton 
73218228Slinton private printSetOfRange (t)
73318228Slinton Symbol t;
73418228Slinton {
73518228Slinton     register integer i, j, *p;
73618228Slinton     long v;
73718228Slinton     boolean first;
73818228Slinton 
73918228Slinton     p = (int *) sp;
74018228Slinton     i = *p;
74118228Slinton     j = 0;
74218228Slinton     v = t->symvalue.rangev.lower;
74318228Slinton     first = true;
74418228Slinton     while (v <= t->symvalue.rangev.upper) {
74518228Slinton 	if ((i&1) == 1) {
74618228Slinton 	    if (first) {
74718228Slinton 		first = false;
74818228Slinton 		printf("%ld", v);
74918228Slinton 	    } else {
75018228Slinton 		printf(", %ld", v);
75118228Slinton 	    }
75218228Slinton 	}
75318228Slinton 	i >>= 1;
75418228Slinton 	++j;
75518228Slinton 	if (j >= sizeof(integer)*BITSPERBYTE) {
75618228Slinton 	    j = 0;
75718228Slinton 	    ++p;
75818228Slinton 	    i = *p;
75918228Slinton 	}
76018228Slinton 	++v;
76118228Slinton     }
76218228Slinton }
76318228Slinton 
76418228Slinton /*
76516615Ssam  * Construct a node for subscripting.
76616615Ssam  */
76716615Ssam 
76816615Ssam public Node pascal_buildaref (a, slist)
76916615Ssam Node a, slist;
77016615Ssam {
77116615Ssam     register Symbol t;
77216615Ssam     register Node p;
77316615Ssam     Symbol etype, atype, eltype;
77416615Ssam     Node esub, r;
77516615Ssam 
77616615Ssam     t = rtype(a->nodetype);
77716615Ssam     if (t->class != ARRAY) {
77816615Ssam 	beginerrmsg();
77916615Ssam 	prtree(stderr, a);
78016615Ssam 	fprintf(stderr, " is not an array");
78116615Ssam 	enderrmsg();
78216615Ssam     } else {
78318228Slinton 	r = a;
78418228Slinton 	eltype = t->type;
78516615Ssam 	p = slist;
78616615Ssam 	t = t->chain;
78716615Ssam 	for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
78816615Ssam 	    esub = p->value.arg[0];
78916615Ssam 	    etype = rtype(esub->nodetype);
79016615Ssam 	    atype = rtype(t);
79116615Ssam 	    if (not compatible(atype, etype)) {
79216615Ssam 		beginerrmsg();
79316615Ssam 		fprintf(stderr, "subscript ");
79416615Ssam 		prtree(stderr, esub);
79516615Ssam 		fprintf(stderr, " is the wrong type");
79616615Ssam 		enderrmsg();
79716615Ssam 	    }
79816615Ssam 	    r = build(O_INDEX, r, esub);
79916615Ssam 	    r->nodetype = eltype;
80016615Ssam 	}
80116615Ssam 	if (p != nil or t != nil) {
80216615Ssam 	    beginerrmsg();
80316615Ssam 	    if (p != nil) {
80416615Ssam 		fprintf(stderr, "too many subscripts for ");
80516615Ssam 	    } else {
80616615Ssam 		fprintf(stderr, "not enough subscripts for ");
80716615Ssam 	    }
80816615Ssam 	    prtree(stderr, a);
80916615Ssam 	    enderrmsg();
81016615Ssam 	}
81116615Ssam     }
81216615Ssam     return r;
81316615Ssam }
81416615Ssam 
81516615Ssam /*
81616615Ssam  * Evaluate a subscript index.
81716615Ssam  */
81816615Ssam 
81918228Slinton public pascal_evalaref (s, base, i)
82016615Ssam Symbol s;
82118228Slinton Address base;
82216615Ssam long i;
82316615Ssam {
82418228Slinton     Symbol t;
82516615Ssam     long lb, ub;
82616615Ssam 
82718228Slinton     t = rtype(s);
82818228Slinton     s = rtype(t->chain);
82918228Slinton     findbounds(s, &lb, &ub);
83016615Ssam     if (i < lb or i > ub) {
83116615Ssam 	error("subscript %d out of range [%d..%d]", i, lb, ub);
83216615Ssam     }
83318228Slinton     push(long, base + (i - lb) * size(t->type));
83416615Ssam }
83516615Ssam 
83616615Ssam /*
83716615Ssam  * Initial Pascal type information.
83816615Ssam  */
83916615Ssam 
84016615Ssam #define NTYPES 4
84116615Ssam 
84218228Slinton private Symbol inittype[NTYPES + 1];
84316615Ssam 
84418228Slinton private addType (n, s, lower, upper)
84518228Slinton integer n;
84616615Ssam String s;
84716615Ssam long lower, upper;
84816615Ssam {
84916615Ssam     register Symbol t;
85016615Ssam 
85118228Slinton     if (n > NTYPES) {
85218228Slinton 	panic("initial Pascal type number too large for '%s'", s);
85316615Ssam     }
85418228Slinton     t = insert(identname(s, true));
85516615Ssam     t->language = pasc;
85618228Slinton     t->class = TYPE;
85718228Slinton     t->type = newSymbol(nil, 0, RANGE, t, nil);
85818228Slinton     t->type->symvalue.rangev.lower = lower;
85918228Slinton     t->type->symvalue.rangev.upper = upper;
86018228Slinton     t->type->language = pasc;
86118228Slinton     inittype[n] = t;
86216615Ssam }
86316615Ssam 
86416615Ssam private initTypes ()
86516615Ssam {
86618228Slinton     addType(1, "boolean", 0L, 1L);
86718228Slinton     addType(2, "char", 0L, 255L);
86818228Slinton     addType(3, "integer", 0x80000000L, 0x7fffffffL);
86918228Slinton     addType(4, "real", 8L, 0L);
87018228Slinton     initialized = true;
87116615Ssam }
87216615Ssam 
87316615Ssam /*
87416615Ssam  * Initialize typetable.
87516615Ssam  */
87616615Ssam 
87716615Ssam public pascal_modinit (typetable)
87816615Ssam Symbol typetable[];
87916615Ssam {
88016615Ssam     register integer i;
88116615Ssam 
88218228Slinton     if (not initialized) {
88318228Slinton 	initTypes();
88418228Slinton 	initialized = true;
88518228Slinton     }
88618228Slinton     for (i = 1; i <= NTYPES; i++) {
88716615Ssam 	typetable[i] = inittype[i];
88816615Ssam     }
88916615Ssam }
89016615Ssam 
89116615Ssam public boolean pascal_hasmodules ()
89216615Ssam {
89316615Ssam     return false;
89416615Ssam }
89516615Ssam 
89616615Ssam public boolean pascal_passaddr (param, exprtype)
89716615Ssam Symbol param, exprtype;
89816615Ssam {
89916615Ssam     return false;
90016615Ssam }
901