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