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