19675Slinton /* Copyright (c) 1982 Regents of the University of California */ 29675Slinton 3*18228Slinton static char sccsid[] = "@(#)pascal.c 1.4 (Berkeley) 03/01/85"; 49675Slinton 5*18228Slinton static char rcsid[] = "$Header: pascal.c,v 1.5 84/12/26 10:41:18 linton Exp $"; 6*18228Slinton 79675Slinton /* 89675Slinton * Pascal-dependent symbol routines. 99675Slinton */ 109675Slinton 119675Slinton #include "defs.h" 129675Slinton #include "symbols.h" 139675Slinton #include "pascal.h" 149675Slinton #include "languages.h" 159675Slinton #include "tree.h" 169675Slinton #include "eval.h" 179675Slinton #include "mappings.h" 189675Slinton #include "process.h" 199675Slinton #include "runtime.h" 209675Slinton #include "machine.h" 219675Slinton 229675Slinton #ifndef public 239675Slinton #endif 249675Slinton 2516615Ssam private Language pasc; 26*18228Slinton private boolean initialized; 2716615Ssam 289675Slinton /* 299675Slinton * Initialize Pascal information. 309675Slinton */ 319675Slinton 329675Slinton public pascal_init() 339675Slinton { 3416615Ssam pasc = language_define("pascal", ".p"); 3516615Ssam language_setop(pasc, L_PRINTDECL, pascal_printdecl); 3616615Ssam language_setop(pasc, L_PRINTVAL, pascal_printval); 3716615Ssam language_setop(pasc, L_TYPEMATCH, pascal_typematch); 3816615Ssam language_setop(pasc, L_BUILDAREF, pascal_buildaref); 3916615Ssam language_setop(pasc, L_EVALAREF, pascal_evalaref); 4016615Ssam language_setop(pasc, L_MODINIT, pascal_modinit); 4116615Ssam language_setop(pasc, L_HASMODULES, pascal_hasmodules); 4216615Ssam language_setop(pasc, L_PASSADDR, pascal_passaddr); 43*18228Slinton initialized = false; 449675Slinton } 459675Slinton 469675Slinton /* 47*18228Slinton * Typematch tests if two types are compatible. The issue 48*18228Slinton * is a bit complicated, so several subfunctions are used for 49*18228Slinton * various kinds of compatibility. 509675Slinton */ 519675Slinton 52*18228Slinton private boolean builtinmatch (t1, t2) 53*18228Slinton register Symbol t1, t2; 549675Slinton { 55*18228Slinton boolean b; 569675Slinton 57*18228Slinton b = (boolean) ( 58*18228Slinton ( 59*18228Slinton t2 == t_int->type and 60*18228Slinton t1->class == RANGE and istypename(t1->type, "integer") 61*18228Slinton ) or ( 62*18228Slinton t2 == t_char->type and 63*18228Slinton t1->class == RANGE and istypename(t1->type, "char") 64*18228Slinton ) or ( 65*18228Slinton t2 == t_real->type and 66*18228Slinton t1->class == RANGE and istypename(t1->type, "real") 67*18228Slinton ) or ( 68*18228Slinton t2 == t_boolean->type and 69*18228Slinton t1->class == RANGE and istypename(t1->type, "boolean") 70*18228Slinton ) 71*18228Slinton ); 72*18228Slinton return b; 73*18228Slinton } 74*18228Slinton 75*18228Slinton private boolean rangematch (t1, t2) 76*18228Slinton register Symbol t1, t2; 77*18228Slinton { 78*18228Slinton boolean b; 79*18228Slinton register Symbol rt1, rt2; 80*18228Slinton 81*18228Slinton if (t1->class == RANGE and t2->class == RANGE) { 82*18228Slinton rt1 = rtype(t1->type); 83*18228Slinton rt2 = rtype(t2->type); 84*18228Slinton b = (boolean) (rt1->type == rt2->type); 85*18228Slinton } else { 86*18228Slinton b = false; 87*18228Slinton } 88*18228Slinton return b; 89*18228Slinton } 90*18228Slinton 91*18228Slinton private boolean nilMatch (t1, t2) 92*18228Slinton register Symbol t1, t2; 93*18228Slinton { 94*18228Slinton boolean b; 95*18228Slinton 96*18228Slinton b = (boolean) ( 979675Slinton (t1 == t_nil and t2->class == PTR) or 989675Slinton (t1->class == PTR and t2 == t_nil) 999675Slinton ); 1009675Slinton return b; 1019675Slinton } 1029675Slinton 103*18228Slinton private boolean enumMatch (t1, t2) 104*18228Slinton register Symbol t1, t2; 105*18228Slinton { 106*18228Slinton boolean b; 107*18228Slinton 108*18228Slinton b = (boolean) ( 109*18228Slinton (t1->class == SCAL and t2->class == CONST and t2->type == t1) or 110*18228Slinton (t1->class == CONST and t2->class == SCAL and t1->type == t2) 111*18228Slinton ); 112*18228Slinton return b; 113*18228Slinton } 114*18228Slinton 115*18228Slinton private boolean isConstString (t) 116*18228Slinton register Symbol t; 117*18228Slinton { 118*18228Slinton boolean b; 119*18228Slinton 120*18228Slinton b = (boolean) ( 121*18228Slinton t->language == primlang and t->class == ARRAY and t->type == t_char 122*18228Slinton ); 123*18228Slinton return b; 124*18228Slinton } 125*18228Slinton 126*18228Slinton private boolean stringArrayMatch (t1, t2) 127*18228Slinton register Symbol t1, t2; 128*18228Slinton { 129*18228Slinton boolean b; 130*18228Slinton 131*18228Slinton b = (boolean) ( 132*18228Slinton ( 133*18228Slinton isConstString(t1) and 134*18228Slinton t2->class == ARRAY and compatible(t2->type, t_char->type) 135*18228Slinton ) or ( 136*18228Slinton isConstString(t2) and 137*18228Slinton t1->class == ARRAY and compatible(t1->type, t_char->type) 138*18228Slinton ) 139*18228Slinton ); 140*18228Slinton return b; 141*18228Slinton } 142*18228Slinton 143*18228Slinton public boolean pascal_typematch (type1, type2) 144*18228Slinton Symbol type1, type2; 145*18228Slinton { 146*18228Slinton boolean b; 147*18228Slinton Symbol t1, t2, tmp; 148*18228Slinton 149*18228Slinton t1 = rtype(type1); 150*18228Slinton t2 = rtype(type2); 151*18228Slinton if (t1 == t2) { 152*18228Slinton b = true; 153*18228Slinton } else { 154*18228Slinton if (t1 == t_char->type or t1 == t_int->type or 155*18228Slinton t1 == t_real->type or t1 == t_boolean->type 156*18228Slinton ) { 157*18228Slinton tmp = t1; 158*18228Slinton t1 = t2; 159*18228Slinton t2 = tmp; 160*18228Slinton } 161*18228Slinton b = (Boolean) ( 162*18228Slinton builtinmatch(t1, t2) or rangematch(t1, t2) or 163*18228Slinton nilMatch(t1, t2) or enumMatch(t1, t2) or 164*18228Slinton stringArrayMatch(t1, t2) 165*18228Slinton ); 166*18228Slinton } 167*18228Slinton return b; 168*18228Slinton } 169*18228Slinton 170*18228Slinton /* 171*18228Slinton * Indent n spaces. 172*18228Slinton */ 173*18228Slinton 174*18228Slinton private indent (n) 175*18228Slinton int n; 176*18228Slinton { 177*18228Slinton if (n > 0) { 178*18228Slinton printf("%*c", n, ' '); 179*18228Slinton } 180*18228Slinton } 181*18228Slinton 182*18228Slinton public pascal_printdecl (s) 1839675Slinton Symbol s; 1849675Slinton { 1859675Slinton register Symbol t; 1869675Slinton Boolean semicolon; 1879675Slinton 1889675Slinton semicolon = true; 189*18228Slinton if (s->class == TYPEREF) { 190*18228Slinton resolveRef(t); 191*18228Slinton } 1929675Slinton switch (s->class) { 1939675Slinton case CONST: 1949675Slinton if (s->type->class == SCAL) { 195*18228Slinton semicolon = false; 196*18228Slinton printf("enum constant, ord "); 197*18228Slinton eval(s->symvalue.constval); 198*18228Slinton pascal_printval(s); 1999675Slinton } else { 2009675Slinton printf("const %s = ", symname(s)); 201*18228Slinton eval(s->symvalue.constval); 202*18228Slinton pascal_printval(s); 2039675Slinton } 2049675Slinton break; 2059675Slinton 2069675Slinton case TYPE: 2079675Slinton printf("type %s = ", symname(s)); 208*18228Slinton printtype(s, s->type, 0); 2099675Slinton break; 2109675Slinton 211*18228Slinton case TYPEREF: 212*18228Slinton printf("type %s", symname(s)); 213*18228Slinton break; 214*18228Slinton 2159675Slinton case VAR: 2169675Slinton if (isparam(s)) { 2179675Slinton printf("(parameter) %s : ", symname(s)); 2189675Slinton } else { 2199675Slinton printf("var %s : ", symname(s)); 2209675Slinton } 221*18228Slinton printtype(s, s->type, 0); 2229675Slinton break; 2239675Slinton 2249675Slinton case REF: 2259675Slinton printf("(var parameter) %s : ", symname(s)); 226*18228Slinton printtype(s, s->type, 0); 2279675Slinton break; 2289675Slinton 2299675Slinton case RANGE: 2309675Slinton case ARRAY: 2319675Slinton case RECORD: 2329675Slinton case VARNT: 2339675Slinton case PTR: 234*18228Slinton case FILET: 235*18228Slinton printtype(s, s, 0); 2369675Slinton semicolon = false; 2379675Slinton break; 2389675Slinton 2399675Slinton case FVAR: 2409675Slinton printf("(function variable) %s : ", symname(s)); 241*18228Slinton printtype(s, s->type, 0); 2429675Slinton break; 2439675Slinton 2449675Slinton case FIELD: 2459675Slinton printf("(field) %s : ", symname(s)); 246*18228Slinton printtype(s, s->type, 0); 2479675Slinton break; 2489675Slinton 2499675Slinton case PROC: 2509675Slinton printf("procedure %s", symname(s)); 2519675Slinton listparams(s); 2529675Slinton break; 2539675Slinton 2549675Slinton case PROG: 2559675Slinton printf("program %s", symname(s)); 256*18228Slinton listparams(s); 2579675Slinton break; 2589675Slinton 2599675Slinton case FUNC: 2609675Slinton printf("function %s", symname(s)); 2619675Slinton listparams(s); 2629675Slinton printf(" : "); 263*18228Slinton printtype(s, s->type, 0); 2649675Slinton break; 2659675Slinton 266*18228Slinton case MODULE: 267*18228Slinton printf("module %s", symname(s)); 268*18228Slinton break; 269*18228Slinton 270*18228Slinton /* 271*18228Slinton * the parameter list of the following should be printed 272*18228Slinton * eventually 273*18228Slinton */ 274*18228Slinton case FPROC: 275*18228Slinton printf("procedure %s()", symname(s)); 276*18228Slinton break; 277*18228Slinton 278*18228Slinton case FFUNC: 279*18228Slinton printf("function %s()", symname(s)); 280*18228Slinton break; 281*18228Slinton 2829675Slinton default: 283*18228Slinton printf("%s : (class %s)", symname(s), classname(s)); 284*18228Slinton break; 2859675Slinton } 2869675Slinton if (semicolon) { 2879675Slinton putchar(';'); 2889675Slinton } 2899675Slinton putchar('\n'); 2909675Slinton } 2919675Slinton 2929675Slinton /* 2939675Slinton * Recursive whiz-bang procedure to print the type portion 294*18228Slinton * of a declaration. 2959675Slinton * 2969675Slinton * The symbol associated with the type is passed to allow 2979675Slinton * searching for type names without getting "type blah = blah". 2989675Slinton */ 2999675Slinton 300*18228Slinton private printtype (s, t, n) 3019675Slinton Symbol s; 3029675Slinton Symbol t; 303*18228Slinton int n; 3049675Slinton { 3059675Slinton register Symbol tmp; 3069675Slinton 307*18228Slinton if (t->class == TYPEREF) { 308*18228Slinton resolveRef(t); 309*18228Slinton } 3109675Slinton switch (t->class) { 3119675Slinton case VAR: 3129675Slinton case CONST: 3139675Slinton case FUNC: 3149675Slinton case PROC: 3159675Slinton panic("printtype: class %s", classname(t)); 3169675Slinton break; 3179675Slinton 3189675Slinton case ARRAY: 3199675Slinton printf("array["); 3209675Slinton tmp = t->chain; 3219675Slinton if (tmp != nil) { 3229675Slinton for (;;) { 323*18228Slinton printtype(tmp, tmp, n); 3249675Slinton tmp = tmp->chain; 3259675Slinton if (tmp == nil) { 3269675Slinton break; 3279675Slinton } 3289675Slinton printf(", "); 3299675Slinton } 3309675Slinton } 3319675Slinton printf("] of "); 332*18228Slinton printtype(t, t->type, n); 3339675Slinton break; 3349675Slinton 3359675Slinton case RECORD: 336*18228Slinton printRecordDecl(t, n); 3379675Slinton break; 3389675Slinton 3399675Slinton case FIELD: 3409675Slinton if (t->chain != nil) { 341*18228Slinton printtype(t->chain, t->chain, n); 3429675Slinton } 3439675Slinton printf("\t%s : ", symname(t)); 344*18228Slinton printtype(t, t->type, n); 3459675Slinton printf(";\n"); 3469675Slinton break; 3479675Slinton 348*18228Slinton case RANGE: 349*18228Slinton printRangeDecl(t); 3509675Slinton break; 3519675Slinton 3529675Slinton case PTR: 353*18228Slinton printf("^"); 354*18228Slinton printtype(t, t->type, n); 3559675Slinton break; 3569675Slinton 3579675Slinton case TYPE: 358*18228Slinton if (t->name != nil and ident(t->name)[0] != '\0') { 359*18228Slinton printname(stdout, t); 3609675Slinton } else { 361*18228Slinton printtype(t, t->type, n); 3629675Slinton } 3639675Slinton break; 3649675Slinton 3659675Slinton case SCAL: 366*18228Slinton printEnumDecl(t, n); 3679675Slinton break; 3689675Slinton 369*18228Slinton case SET: 370*18228Slinton printf("set of "); 371*18228Slinton printtype(t, t->type, n); 372*18228Slinton break; 373*18228Slinton 374*18228Slinton case FILET: 375*18228Slinton printf("file of "); 376*18228Slinton printtype(t, t->type, n); 377*18228Slinton break; 378*18228Slinton 379*18228Slinton case TYPEREF: 380*18228Slinton break; 381*18228Slinton 382*18228Slinton case FPROC: 383*18228Slinton printf("procedure"); 384*18228Slinton break; 385*18228Slinton 386*18228Slinton case FFUNC: 387*18228Slinton printf("function"); 388*18228Slinton break; 389*18228Slinton 3909675Slinton default: 3919675Slinton printf("(class %d)", t->class); 3929675Slinton break; 3939675Slinton } 3949675Slinton } 3959675Slinton 3969675Slinton /* 397*18228Slinton * Print out a record declaration. 398*18228Slinton */ 399*18228Slinton 400*18228Slinton private printRecordDecl (t, n) 401*18228Slinton Symbol t; 402*18228Slinton int n; 403*18228Slinton { 404*18228Slinton register Symbol f; 405*18228Slinton 406*18228Slinton if (t->chain == nil) { 407*18228Slinton printf("record end"); 408*18228Slinton } else { 409*18228Slinton printf("record\n"); 410*18228Slinton for (f = t->chain; f != nil; f = f->chain) { 411*18228Slinton indent(n+4); 412*18228Slinton printf("%s : ", symname(f)); 413*18228Slinton printtype(f->type, f->type, n+4); 414*18228Slinton printf(";\n"); 415*18228Slinton } 416*18228Slinton indent(n); 417*18228Slinton printf("end"); 418*18228Slinton } 419*18228Slinton } 420*18228Slinton 421*18228Slinton /* 422*18228Slinton * Print out the declaration of a range type. 423*18228Slinton */ 424*18228Slinton 425*18228Slinton private printRangeDecl (t) 426*18228Slinton Symbol t; 427*18228Slinton { 428*18228Slinton long r0, r1; 429*18228Slinton 430*18228Slinton r0 = t->symvalue.rangev.lower; 431*18228Slinton r1 = t->symvalue.rangev.upper; 432*18228Slinton if (t == t_char or istypename(t, "char")) { 433*18228Slinton if (r0 < 0x20 or r0 > 0x7e) { 434*18228Slinton printf("%ld..", r0); 435*18228Slinton } else { 436*18228Slinton printf("'%c'..", (char) r0); 437*18228Slinton } 438*18228Slinton if (r1 < 0x20 or r1 > 0x7e) { 439*18228Slinton printf("\\%lo", r1); 440*18228Slinton } else { 441*18228Slinton printf("'%c'", (char) r1); 442*18228Slinton } 443*18228Slinton } else if (r0 > 0 and r1 == 0) { 444*18228Slinton printf("%ld byte real", r0); 445*18228Slinton } else if (r0 >= 0) { 446*18228Slinton printf("%lu..%lu", r0, r1); 447*18228Slinton } else { 448*18228Slinton printf("%ld..%ld", r0, r1); 449*18228Slinton } 450*18228Slinton } 451*18228Slinton 452*18228Slinton /* 453*18228Slinton * Print out an enumeration declaration. 454*18228Slinton */ 455*18228Slinton 456*18228Slinton private printEnumDecl (e, n) 457*18228Slinton Symbol e; 458*18228Slinton int n; 459*18228Slinton { 460*18228Slinton Symbol t; 461*18228Slinton 462*18228Slinton printf("("); 463*18228Slinton t = e->chain; 464*18228Slinton if (t != nil) { 465*18228Slinton printf("%s", symname(t)); 466*18228Slinton t = t->chain; 467*18228Slinton while (t != nil) { 468*18228Slinton printf(", %s", symname(t)); 469*18228Slinton t = t->chain; 470*18228Slinton } 471*18228Slinton } 472*18228Slinton printf(")"); 473*18228Slinton } 474*18228Slinton 475*18228Slinton /* 4769675Slinton * List the parameters of a procedure or function. 4779675Slinton * No attempt is made to combine like types. 4789675Slinton */ 4799675Slinton 4809675Slinton private listparams(s) 4819675Slinton Symbol s; 4829675Slinton { 4839675Slinton Symbol t; 4849675Slinton 4859675Slinton if (s->chain != nil) { 4869675Slinton putchar('('); 4879675Slinton for (t = s->chain; t != nil; t = t->chain) { 4889675Slinton switch (t->class) { 4899675Slinton case REF: 4909675Slinton printf("var "); 4919675Slinton break; 4929675Slinton 4939675Slinton case VAR: 4949675Slinton break; 4959675Slinton 4969675Slinton default: 4979675Slinton panic("unexpected class %d for parameter", t->class); 4989675Slinton } 4999675Slinton printf("%s : ", symname(t)); 5009675Slinton printtype(t, t->type); 5019675Slinton if (t->chain != nil) { 5029675Slinton printf("; "); 5039675Slinton } 5049675Slinton } 5059675Slinton putchar(')'); 5069675Slinton } 5079675Slinton } 5089675Slinton 5099675Slinton /* 5109675Slinton * Print out the value on the top of the expression stack 5119675Slinton * in the format for the type of the given symbol. 5129675Slinton */ 5139675Slinton 514*18228Slinton public pascal_printval (s) 5159675Slinton Symbol s; 5169675Slinton { 517*18228Slinton prval(s, size(s)); 518*18228Slinton } 519*18228Slinton 520*18228Slinton private prval (s, n) 521*18228Slinton Symbol s; 522*18228Slinton integer n; 523*18228Slinton { 5249675Slinton Symbol t; 5259675Slinton Address a; 526*18228Slinton integer len; 5279675Slinton double r; 528*18228Slinton integer i; 5299675Slinton 530*18228Slinton if (s->class == TYPEREF) { 531*18228Slinton resolveRef(s); 532*18228Slinton } 5339675Slinton switch (s->class) { 53416615Ssam case CONST: 5359675Slinton case TYPE: 536*18228Slinton case REF: 53716615Ssam case VAR: 53816615Ssam case FVAR: 53916615Ssam case TAG: 540*18228Slinton prval(s->type, n); 541*18228Slinton break; 542*18228Slinton 54316615Ssam case FIELD: 544*18228Slinton prval(s->type, n); 5459675Slinton break; 5469675Slinton 5479675Slinton case ARRAY: 5489675Slinton t = rtype(s->type); 549*18228Slinton if (t == t_char->type or 550*18228Slinton (t->class == RANGE and istypename(t->type, "char")) 551*18228Slinton ) { 5529675Slinton len = size(s); 5539675Slinton sp -= len; 5549675Slinton printf("'%.*s'", len, sp); 5559675Slinton break; 5569675Slinton } else { 5579675Slinton printarray(s); 5589675Slinton } 5599675Slinton break; 5609675Slinton 5619675Slinton case RECORD: 5629675Slinton printrecord(s); 5639675Slinton break; 5649675Slinton 5659675Slinton case VARNT: 566*18228Slinton printf("[variant]"); 5679675Slinton break; 5689675Slinton 5699675Slinton case RANGE: 570*18228Slinton printrange(s, n); 571*18228Slinton break; 5729675Slinton 573*18228Slinton case FILET: 574*18228Slinton a = pop(Address); 575*18228Slinton if (a == 0) { 576*18228Slinton printf("nil"); 5779675Slinton } else { 578*18228Slinton printf("0x%x", a); 5799675Slinton } 5809675Slinton break; 5819675Slinton 582*18228Slinton case PTR: 583*18228Slinton a = pop(Address); 584*18228Slinton if (a == 0) { 585*18228Slinton printf("nil"); 5869675Slinton } else { 587*18228Slinton printf("0x%x", a); 5889675Slinton } 5899675Slinton break; 5909675Slinton 591*18228Slinton case SCAL: 592*18228Slinton i = 0; 593*18228Slinton popn(n, &i); 594*18228Slinton if (s->symvalue.iconval < 256) { 595*18228Slinton i &= 0xff; 596*18228Slinton } else if (s->symvalue.iconval < 65536) { 597*18228Slinton i &= 0xffff; 5989675Slinton } 599*18228Slinton printEnum(i, s); 6009675Slinton break; 6019675Slinton 6029675Slinton case FPROC: 6039675Slinton case FFUNC: 604*18228Slinton a = pop(long); 6059675Slinton t = whatblock(a); 6069675Slinton if (t == nil) { 607*18228Slinton printf("(proc 0x%x)", a); 6089675Slinton } else { 6099675Slinton printf("%s", symname(t)); 6109675Slinton } 6119675Slinton break; 6129675Slinton 613*18228Slinton case SET: 614*18228Slinton printSet(s); 615*18228Slinton break; 616*18228Slinton 6179675Slinton default: 6189675Slinton if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) { 6199675Slinton panic("printval: bad class %d", ord(s->class)); 6209675Slinton } 621*18228Slinton printf("[%s]", classname(s)); 622*18228Slinton break; 6239675Slinton } 6249675Slinton } 62516615Ssam 62616615Ssam /* 627*18228Slinton * Print out the value of a scalar (non-enumeration) type. 628*18228Slinton */ 629*18228Slinton 630*18228Slinton private printrange (s, n) 631*18228Slinton Symbol s; 632*18228Slinton integer n; 633*18228Slinton { 634*18228Slinton double d; 635*18228Slinton float f; 636*18228Slinton integer i; 637*18228Slinton 638*18228Slinton if (s->symvalue.rangev.upper == 0 and s->symvalue.rangev.lower > 0) { 639*18228Slinton if (n == sizeof(float)) { 640*18228Slinton popn(n, &f); 641*18228Slinton d = f; 642*18228Slinton } else { 643*18228Slinton popn(n, &d); 644*18228Slinton } 645*18228Slinton prtreal(d); 646*18228Slinton } else { 647*18228Slinton i = 0; 648*18228Slinton popn(n, &i); 649*18228Slinton printRangeVal(i, s); 650*18228Slinton } 651*18228Slinton } 652*18228Slinton 653*18228Slinton /* 654*18228Slinton * Print out a set. 655*18228Slinton */ 656*18228Slinton 657*18228Slinton private printSet (s) 658*18228Slinton Symbol s; 659*18228Slinton { 660*18228Slinton Symbol t; 661*18228Slinton integer nbytes; 662*18228Slinton 663*18228Slinton nbytes = size(s); 664*18228Slinton t = rtype(s->type); 665*18228Slinton printf("["); 666*18228Slinton sp -= nbytes; 667*18228Slinton if (t->class == SCAL) { 668*18228Slinton printSetOfEnum(t); 669*18228Slinton } else if (t->class == RANGE) { 670*18228Slinton printSetOfRange(t); 671*18228Slinton } else { 672*18228Slinton error("internal error: expected range or enumerated base type for set"); 673*18228Slinton } 674*18228Slinton printf("]"); 675*18228Slinton } 676*18228Slinton 677*18228Slinton /* 678*18228Slinton * Print out a set of an enumeration. 679*18228Slinton */ 680*18228Slinton 681*18228Slinton private printSetOfEnum (t) 682*18228Slinton Symbol t; 683*18228Slinton { 684*18228Slinton register Symbol e; 685*18228Slinton register integer i, j, *p; 686*18228Slinton boolean first; 687*18228Slinton 688*18228Slinton p = (int *) sp; 689*18228Slinton i = *p; 690*18228Slinton j = 0; 691*18228Slinton e = t->chain; 692*18228Slinton first = true; 693*18228Slinton while (e != nil) { 694*18228Slinton if ((i&1) == 1) { 695*18228Slinton if (first) { 696*18228Slinton first = false; 697*18228Slinton printf("%s", symname(e)); 698*18228Slinton } else { 699*18228Slinton printf(", %s", symname(e)); 700*18228Slinton } 701*18228Slinton } 702*18228Slinton i >>= 1; 703*18228Slinton ++j; 704*18228Slinton if (j >= sizeof(integer)*BITSPERBYTE) { 705*18228Slinton j = 0; 706*18228Slinton ++p; 707*18228Slinton i = *p; 708*18228Slinton } 709*18228Slinton e = e->chain; 710*18228Slinton } 711*18228Slinton } 712*18228Slinton 713*18228Slinton /* 714*18228Slinton * Print out a set of a subrange type. 715*18228Slinton */ 716*18228Slinton 717*18228Slinton private printSetOfRange (t) 718*18228Slinton Symbol t; 719*18228Slinton { 720*18228Slinton register integer i, j, *p; 721*18228Slinton long v; 722*18228Slinton boolean first; 723*18228Slinton 724*18228Slinton p = (int *) sp; 725*18228Slinton i = *p; 726*18228Slinton j = 0; 727*18228Slinton v = t->symvalue.rangev.lower; 728*18228Slinton first = true; 729*18228Slinton while (v <= t->symvalue.rangev.upper) { 730*18228Slinton if ((i&1) == 1) { 731*18228Slinton if (first) { 732*18228Slinton first = false; 733*18228Slinton printf("%ld", v); 734*18228Slinton } else { 735*18228Slinton printf(", %ld", v); 736*18228Slinton } 737*18228Slinton } 738*18228Slinton i >>= 1; 739*18228Slinton ++j; 740*18228Slinton if (j >= sizeof(integer)*BITSPERBYTE) { 741*18228Slinton j = 0; 742*18228Slinton ++p; 743*18228Slinton i = *p; 744*18228Slinton } 745*18228Slinton ++v; 746*18228Slinton } 747*18228Slinton } 748*18228Slinton 749*18228Slinton /* 75016615Ssam * Construct a node for subscripting. 75116615Ssam */ 75216615Ssam 75316615Ssam public Node pascal_buildaref (a, slist) 75416615Ssam Node a, slist; 75516615Ssam { 75616615Ssam register Symbol t; 75716615Ssam register Node p; 75816615Ssam Symbol etype, atype, eltype; 75916615Ssam Node esub, r; 76016615Ssam 76116615Ssam t = rtype(a->nodetype); 76216615Ssam if (t->class != ARRAY) { 76316615Ssam beginerrmsg(); 76416615Ssam prtree(stderr, a); 76516615Ssam fprintf(stderr, " is not an array"); 76616615Ssam enderrmsg(); 76716615Ssam } else { 768*18228Slinton r = a; 769*18228Slinton eltype = t->type; 77016615Ssam p = slist; 77116615Ssam t = t->chain; 77216615Ssam for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) { 77316615Ssam esub = p->value.arg[0]; 77416615Ssam etype = rtype(esub->nodetype); 77516615Ssam atype = rtype(t); 77616615Ssam if (not compatible(atype, etype)) { 77716615Ssam beginerrmsg(); 77816615Ssam fprintf(stderr, "subscript "); 77916615Ssam prtree(stderr, esub); 78016615Ssam fprintf(stderr, " is the wrong type"); 78116615Ssam enderrmsg(); 78216615Ssam } 78316615Ssam r = build(O_INDEX, r, esub); 78416615Ssam r->nodetype = eltype; 78516615Ssam } 78616615Ssam if (p != nil or t != nil) { 78716615Ssam beginerrmsg(); 78816615Ssam if (p != nil) { 78916615Ssam fprintf(stderr, "too many subscripts for "); 79016615Ssam } else { 79116615Ssam fprintf(stderr, "not enough subscripts for "); 79216615Ssam } 79316615Ssam prtree(stderr, a); 79416615Ssam enderrmsg(); 79516615Ssam } 79616615Ssam } 79716615Ssam return r; 79816615Ssam } 79916615Ssam 80016615Ssam /* 80116615Ssam * Evaluate a subscript index. 80216615Ssam */ 80316615Ssam 804*18228Slinton public pascal_evalaref (s, base, i) 80516615Ssam Symbol s; 806*18228Slinton Address base; 80716615Ssam long i; 80816615Ssam { 809*18228Slinton Symbol t; 81016615Ssam long lb, ub; 81116615Ssam 812*18228Slinton t = rtype(s); 813*18228Slinton s = rtype(t->chain); 814*18228Slinton findbounds(s, &lb, &ub); 81516615Ssam if (i < lb or i > ub) { 81616615Ssam error("subscript %d out of range [%d..%d]", i, lb, ub); 81716615Ssam } 818*18228Slinton push(long, base + (i - lb) * size(t->type)); 81916615Ssam } 82016615Ssam 82116615Ssam /* 82216615Ssam * Initial Pascal type information. 82316615Ssam */ 82416615Ssam 82516615Ssam #define NTYPES 4 82616615Ssam 827*18228Slinton private Symbol inittype[NTYPES + 1]; 82816615Ssam 829*18228Slinton private addType (n, s, lower, upper) 830*18228Slinton integer n; 83116615Ssam String s; 83216615Ssam long lower, upper; 83316615Ssam { 83416615Ssam register Symbol t; 83516615Ssam 836*18228Slinton if (n > NTYPES) { 837*18228Slinton panic("initial Pascal type number too large for '%s'", s); 83816615Ssam } 839*18228Slinton t = insert(identname(s, true)); 84016615Ssam t->language = pasc; 841*18228Slinton t->class = TYPE; 842*18228Slinton t->type = newSymbol(nil, 0, RANGE, t, nil); 843*18228Slinton t->type->symvalue.rangev.lower = lower; 844*18228Slinton t->type->symvalue.rangev.upper = upper; 845*18228Slinton t->type->language = pasc; 846*18228Slinton inittype[n] = t; 84716615Ssam } 84816615Ssam 84916615Ssam private initTypes () 85016615Ssam { 851*18228Slinton addType(1, "boolean", 0L, 1L); 852*18228Slinton addType(2, "char", 0L, 255L); 853*18228Slinton addType(3, "integer", 0x80000000L, 0x7fffffffL); 854*18228Slinton addType(4, "real", 8L, 0L); 855*18228Slinton initialized = true; 85616615Ssam } 85716615Ssam 85816615Ssam /* 85916615Ssam * Initialize typetable. 86016615Ssam */ 86116615Ssam 86216615Ssam public pascal_modinit (typetable) 86316615Ssam Symbol typetable[]; 86416615Ssam { 86516615Ssam register integer i; 86616615Ssam 867*18228Slinton if (not initialized) { 868*18228Slinton initTypes(); 869*18228Slinton initialized = true; 870*18228Slinton } 871*18228Slinton for (i = 1; i <= NTYPES; i++) { 87216615Ssam typetable[i] = inittype[i]; 87316615Ssam } 87416615Ssam } 87516615Ssam 87616615Ssam public boolean pascal_hasmodules () 87716615Ssam { 87816615Ssam return false; 87916615Ssam } 88016615Ssam 88116615Ssam public boolean pascal_passaddr (param, exprtype) 88216615Ssam Symbol param, exprtype; 88316615Ssam { 88416615Ssam return false; 88516615Ssam } 886