1*16622Ssam #ifndef lint 2*16622Ssam static char sccsid[] = "@(#)modula-2.c 1.1 (Berkeley) 06/23/84"; /* from 1.4 84/03/27 10:22:04 linton Exp */ 3*16622Ssam #endif 4*16622Ssam 5*16622Ssam /* 6*16622Ssam * Modula-2 specific symbol routines. 7*16622Ssam */ 8*16622Ssam 9*16622Ssam #include "defs.h" 10*16622Ssam #include "symbols.h" 11*16622Ssam #include "modula-2.h" 12*16622Ssam #include "languages.h" 13*16622Ssam #include "tree.h" 14*16622Ssam #include "eval.h" 15*16622Ssam #include "mappings.h" 16*16622Ssam #include "process.h" 17*16622Ssam #include "runtime.h" 18*16622Ssam #include "machine.h" 19*16622Ssam 20*16622Ssam #ifndef public 21*16622Ssam #endif 22*16622Ssam 23*16622Ssam private Language mod2; 24*16622Ssam private boolean initialized; 25*16622Ssam 26*16622Ssam /* 27*16622Ssam * Initialize Modula-2 information. 28*16622Ssam */ 29*16622Ssam 30*16622Ssam public modula2_init () 31*16622Ssam { 32*16622Ssam mod2 = language_define("modula-2", ".mod"); 33*16622Ssam language_setop(mod2, L_PRINTDECL, modula2_printdecl); 34*16622Ssam language_setop(mod2, L_PRINTVAL, modula2_printval); 35*16622Ssam language_setop(mod2, L_TYPEMATCH, modula2_typematch); 36*16622Ssam language_setop(mod2, L_BUILDAREF, modula2_buildaref); 37*16622Ssam language_setop(mod2, L_EVALAREF, modula2_evalaref); 38*16622Ssam language_setop(mod2, L_MODINIT, modula2_modinit); 39*16622Ssam language_setop(mod2, L_HASMODULES, modula2_hasmodules); 40*16622Ssam language_setop(mod2, L_PASSADDR, modula2_passaddr); 41*16622Ssam initialized = false; 42*16622Ssam } 43*16622Ssam 44*16622Ssam /* 45*16622Ssam * Typematch tests if two types are compatible. The issue 46*16622Ssam * is a bit complicated, so several subfunctions are used for 47*16622Ssam * various kinds of compatibility. 48*16622Ssam */ 49*16622Ssam 50*16622Ssam private boolean nilMatch (t1, t2) 51*16622Ssam register Symbol t1, t2; 52*16622Ssam { 53*16622Ssam boolean b; 54*16622Ssam 55*16622Ssam b = (boolean) ( 56*16622Ssam (t1 == t_nil and t2->class == PTR) or 57*16622Ssam (t1->class == PTR and t2 == t_nil) 58*16622Ssam ); 59*16622Ssam return b; 60*16622Ssam } 61*16622Ssam 62*16622Ssam private boolean enumMatch (t1, t2) 63*16622Ssam register Symbol t1, t2; 64*16622Ssam { 65*16622Ssam boolean b; 66*16622Ssam 67*16622Ssam b = (boolean) ( 68*16622Ssam t1->type == t2->type and ( 69*16622Ssam (t1->class == t2->class) or 70*16622Ssam (t1->class == SCAL and t2->class == CONST) or 71*16622Ssam (t1->class == CONST and t2->class == SCAL) 72*16622Ssam ) 73*16622Ssam ); 74*16622Ssam return b; 75*16622Ssam } 76*16622Ssam 77*16622Ssam private boolean openArrayMatch (t1, t2) 78*16622Ssam register Symbol t1, t2; 79*16622Ssam { 80*16622Ssam boolean b; 81*16622Ssam 82*16622Ssam b = (boolean) ( 83*16622Ssam ( 84*16622Ssam t1->class == ARRAY and t1->chain == t_open and 85*16622Ssam t2->class == ARRAY and 86*16622Ssam compatible(rtype(t2->chain)->type, t_int) and 87*16622Ssam compatible(t1->type, t2->type) 88*16622Ssam ) or ( 89*16622Ssam t2->class == ARRAY and t2->chain == t_open and 90*16622Ssam t1->class == ARRAY and 91*16622Ssam compatible(rtype(t1->chain)->type, t_int) and 92*16622Ssam compatible(t1->type, t2->type) 93*16622Ssam ) 94*16622Ssam ); 95*16622Ssam return b; 96*16622Ssam } 97*16622Ssam 98*16622Ssam private boolean isConstString (t) 99*16622Ssam register Symbol t; 100*16622Ssam { 101*16622Ssam boolean b; 102*16622Ssam 103*16622Ssam b = (boolean) ( 104*16622Ssam t->language == primlang and t->class == ARRAY and t->type == t_char 105*16622Ssam ); 106*16622Ssam return b; 107*16622Ssam } 108*16622Ssam 109*16622Ssam private boolean stringArrayMatch (t1, t2) 110*16622Ssam register Symbol t1, t2; 111*16622Ssam { 112*16622Ssam boolean b; 113*16622Ssam 114*16622Ssam b = (boolean) ( 115*16622Ssam ( 116*16622Ssam isConstString(t1) and 117*16622Ssam t2->class == ARRAY and compatible(t2->type, t_char->type) 118*16622Ssam ) or ( 119*16622Ssam isConstString(t2) and 120*16622Ssam t1->class == ARRAY and compatible(t1->type, t_char->type) 121*16622Ssam ) 122*16622Ssam ); 123*16622Ssam return b; 124*16622Ssam } 125*16622Ssam 126*16622Ssam public boolean modula2_typematch (type1, type2) 127*16622Ssam Symbol type1, type2; 128*16622Ssam { 129*16622Ssam Boolean b; 130*16622Ssam Symbol t1, t2, tmp; 131*16622Ssam 132*16622Ssam t1 = rtype(type1); 133*16622Ssam t2 = rtype(type2); 134*16622Ssam if (t1 == t2) { 135*16622Ssam b = true; 136*16622Ssam } else { 137*16622Ssam if (t1 == t_char->type or t1 == t_int->type or t1 == t_real->type) { 138*16622Ssam tmp = t1; 139*16622Ssam t1 = t2; 140*16622Ssam t2 = tmp; 141*16622Ssam } 142*16622Ssam b = (Boolean) ( 143*16622Ssam ( 144*16622Ssam t2 == t_int->type and 145*16622Ssam t1->class == RANGE and ( 146*16622Ssam istypename(t1->type, "integer") or 147*16622Ssam istypename(t1->type, "cardinal") 148*16622Ssam ) 149*16622Ssam ) or ( 150*16622Ssam t2 == t_char->type and 151*16622Ssam t1->class == RANGE and istypename(t1->type, "char") 152*16622Ssam ) or ( 153*16622Ssam t2 == t_real->type and 154*16622Ssam t1->class == RANGE and ( 155*16622Ssam istypename(t1->type, "real") or 156*16622Ssam istypename(t1->type, "longreal") 157*16622Ssam ) 158*16622Ssam ) or ( 159*16622Ssam nilMatch(t1, t2) 160*16622Ssam ) or ( 161*16622Ssam enumMatch(t1, t2) 162*16622Ssam ) or ( 163*16622Ssam openArrayMatch(t1, t2) 164*16622Ssam ) or ( 165*16622Ssam stringArrayMatch(t1, t2) 166*16622Ssam ) 167*16622Ssam ); 168*16622Ssam } 169*16622Ssam return b; 170*16622Ssam } 171*16622Ssam 172*16622Ssam /* 173*16622Ssam * Indent n spaces. 174*16622Ssam */ 175*16622Ssam 176*16622Ssam private indent (n) 177*16622Ssam int n; 178*16622Ssam { 179*16622Ssam if (n > 0) { 180*16622Ssam printf("%*c", n, ' '); 181*16622Ssam } 182*16622Ssam } 183*16622Ssam 184*16622Ssam public modula2_printdecl (s) 185*16622Ssam Symbol s; 186*16622Ssam { 187*16622Ssam register Symbol t; 188*16622Ssam Boolean semicolon; 189*16622Ssam 190*16622Ssam semicolon = true; 191*16622Ssam if (s->class == TYPEREF) { 192*16622Ssam resolveRef(t); 193*16622Ssam } 194*16622Ssam switch (s->class) { 195*16622Ssam case CONST: 196*16622Ssam if (s->type->class == SCAL) { 197*16622Ssam printf("(enumeration constant, ord %ld)", 198*16622Ssam s->symvalue.iconval); 199*16622Ssam } else { 200*16622Ssam printf("const %s = ", symname(s)); 201*16622Ssam modula2_printval(s); 202*16622Ssam } 203*16622Ssam break; 204*16622Ssam 205*16622Ssam case TYPE: 206*16622Ssam printf("type %s = ", symname(s)); 207*16622Ssam printtype(s, s->type, 0); 208*16622Ssam break; 209*16622Ssam 210*16622Ssam case TYPEREF: 211*16622Ssam printf("type %s", symname(s)); 212*16622Ssam break; 213*16622Ssam 214*16622Ssam case VAR: 215*16622Ssam if (isparam(s)) { 216*16622Ssam printf("(parameter) %s : ", symname(s)); 217*16622Ssam } else { 218*16622Ssam printf("var %s : ", symname(s)); 219*16622Ssam } 220*16622Ssam printtype(s, s->type, 0); 221*16622Ssam break; 222*16622Ssam 223*16622Ssam case REF: 224*16622Ssam printf("(var parameter) %s : ", symname(s)); 225*16622Ssam printtype(s, s->type, 0); 226*16622Ssam break; 227*16622Ssam 228*16622Ssam case RANGE: 229*16622Ssam case ARRAY: 230*16622Ssam case RECORD: 231*16622Ssam case VARNT: 232*16622Ssam case PTR: 233*16622Ssam printtype(s, s, 0); 234*16622Ssam semicolon = false; 235*16622Ssam break; 236*16622Ssam 237*16622Ssam case FVAR: 238*16622Ssam printf("(function variable) %s : ", symname(s)); 239*16622Ssam printtype(s, s->type, 0); 240*16622Ssam break; 241*16622Ssam 242*16622Ssam case FIELD: 243*16622Ssam printf("(field) %s : ", symname(s)); 244*16622Ssam printtype(s, s->type, 0); 245*16622Ssam break; 246*16622Ssam 247*16622Ssam case PROC: 248*16622Ssam printf("procedure %s", symname(s)); 249*16622Ssam listparams(s); 250*16622Ssam break; 251*16622Ssam 252*16622Ssam case PROG: 253*16622Ssam printf("program %s", symname(s)); 254*16622Ssam listparams(s); 255*16622Ssam break; 256*16622Ssam 257*16622Ssam case FUNC: 258*16622Ssam printf("function %s", symname(s)); 259*16622Ssam listparams(s); 260*16622Ssam printf(" : "); 261*16622Ssam printtype(s, s->type, 0); 262*16622Ssam break; 263*16622Ssam 264*16622Ssam case MODULE: 265*16622Ssam printf("module %s", symname(s)); 266*16622Ssam break; 267*16622Ssam 268*16622Ssam default: 269*16622Ssam printf("%s : (class %s)", symname(s), classname(s)); 270*16622Ssam break; 271*16622Ssam } 272*16622Ssam if (semicolon) { 273*16622Ssam putchar(';'); 274*16622Ssam } 275*16622Ssam putchar('\n'); 276*16622Ssam } 277*16622Ssam 278*16622Ssam /* 279*16622Ssam * Recursive whiz-bang procedure to print the type portion 280*16622Ssam * of a declaration. 281*16622Ssam * 282*16622Ssam * The symbol associated with the type is passed to allow 283*16622Ssam * searching for type names without getting "type blah = blah". 284*16622Ssam */ 285*16622Ssam 286*16622Ssam private printtype (s, t, n) 287*16622Ssam Symbol s; 288*16622Ssam Symbol t; 289*16622Ssam int n; 290*16622Ssam { 291*16622Ssam register Symbol tmp; 292*16622Ssam 293*16622Ssam if (t->class == TYPEREF) { 294*16622Ssam resolveRef(t); 295*16622Ssam } 296*16622Ssam switch (t->class) { 297*16622Ssam case VAR: 298*16622Ssam case CONST: 299*16622Ssam case FUNC: 300*16622Ssam case PROC: 301*16622Ssam panic("printtype: class %s", classname(t)); 302*16622Ssam break; 303*16622Ssam 304*16622Ssam case ARRAY: 305*16622Ssam printf("array["); 306*16622Ssam tmp = t->chain; 307*16622Ssam if (tmp != nil) { 308*16622Ssam for (;;) { 309*16622Ssam printtype(tmp, tmp, n); 310*16622Ssam tmp = tmp->chain; 311*16622Ssam if (tmp == nil) { 312*16622Ssam break; 313*16622Ssam } 314*16622Ssam printf(", "); 315*16622Ssam } 316*16622Ssam } 317*16622Ssam printf("] of "); 318*16622Ssam printtype(t, t->type, n); 319*16622Ssam break; 320*16622Ssam 321*16622Ssam case RECORD: 322*16622Ssam printRecordDecl(t, n); 323*16622Ssam break; 324*16622Ssam 325*16622Ssam case FIELD: 326*16622Ssam if (t->chain != nil) { 327*16622Ssam printtype(t->chain, t->chain, n); 328*16622Ssam } 329*16622Ssam printf("\t%s : ", symname(t)); 330*16622Ssam printtype(t, t->type, n); 331*16622Ssam printf(";\n"); 332*16622Ssam break; 333*16622Ssam 334*16622Ssam case RANGE: 335*16622Ssam printRangeDecl(t); 336*16622Ssam break; 337*16622Ssam 338*16622Ssam case PTR: 339*16622Ssam printf("pointer to "); 340*16622Ssam printtype(t, t->type, n); 341*16622Ssam break; 342*16622Ssam 343*16622Ssam case TYPE: 344*16622Ssam if (t->name != nil and ident(t->name)[0] != '\0') { 345*16622Ssam printname(stdout, t); 346*16622Ssam } else { 347*16622Ssam printtype(t, t->type, n); 348*16622Ssam } 349*16622Ssam break; 350*16622Ssam 351*16622Ssam case SCAL: 352*16622Ssam printEnumDecl(t, n); 353*16622Ssam break; 354*16622Ssam 355*16622Ssam case SET: 356*16622Ssam printf("set of "); 357*16622Ssam printtype(t, t->type, n); 358*16622Ssam break; 359*16622Ssam 360*16622Ssam case TYPEREF: 361*16622Ssam break; 362*16622Ssam 363*16622Ssam default: 364*16622Ssam printf("(class %d)", t->class); 365*16622Ssam break; 366*16622Ssam } 367*16622Ssam } 368*16622Ssam 369*16622Ssam /* 370*16622Ssam * Print out a record declaration. 371*16622Ssam */ 372*16622Ssam 373*16622Ssam private printRecordDecl (t, n) 374*16622Ssam Symbol t; 375*16622Ssam int n; 376*16622Ssam { 377*16622Ssam register Symbol f; 378*16622Ssam 379*16622Ssam if (t->chain == nil) { 380*16622Ssam printf("record end"); 381*16622Ssam } else { 382*16622Ssam printf("record\n"); 383*16622Ssam for (f = t->chain; f != nil; f = f->chain) { 384*16622Ssam indent(n+4); 385*16622Ssam printf("%s : ", symname(f)); 386*16622Ssam printtype(f->type, f->type, n+4); 387*16622Ssam printf(";\n"); 388*16622Ssam } 389*16622Ssam indent(n); 390*16622Ssam printf("end"); 391*16622Ssam } 392*16622Ssam } 393*16622Ssam 394*16622Ssam /* 395*16622Ssam * Print out the declaration of a range type. 396*16622Ssam */ 397*16622Ssam 398*16622Ssam private printRangeDecl (t) 399*16622Ssam Symbol t; 400*16622Ssam { 401*16622Ssam long r0, r1; 402*16622Ssam 403*16622Ssam r0 = t->symvalue.rangev.lower; 404*16622Ssam r1 = t->symvalue.rangev.upper; 405*16622Ssam if (t == t_char or istypename(t, "char")) { 406*16622Ssam if (r0 < 0x20 or r0 > 0x7e) { 407*16622Ssam printf("%ld..", r0); 408*16622Ssam } else { 409*16622Ssam printf("'%c'..", (char) r0); 410*16622Ssam } 411*16622Ssam if (r1 < 0x20 or r1 > 0x7e) { 412*16622Ssam printf("\\%lo", r1); 413*16622Ssam } else { 414*16622Ssam printf("'%c'", (char) r1); 415*16622Ssam } 416*16622Ssam } else if (r0 > 0 and r1 == 0) { 417*16622Ssam printf("%ld byte real", r0); 418*16622Ssam } else if (r0 >= 0) { 419*16622Ssam printf("%lu..%lu", r0, r1); 420*16622Ssam } else { 421*16622Ssam printf("%ld..%ld", r0, r1); 422*16622Ssam } 423*16622Ssam } 424*16622Ssam 425*16622Ssam /* 426*16622Ssam * Print out an enumeration declaration. 427*16622Ssam */ 428*16622Ssam 429*16622Ssam private printEnumDecl (e, n) 430*16622Ssam Symbol e; 431*16622Ssam int n; 432*16622Ssam { 433*16622Ssam Symbol t; 434*16622Ssam 435*16622Ssam printf("("); 436*16622Ssam t = e->chain; 437*16622Ssam if (t != nil) { 438*16622Ssam printf("%s", symname(t)); 439*16622Ssam t = t->chain; 440*16622Ssam while (t != nil) { 441*16622Ssam printf(", %s", symname(t)); 442*16622Ssam t = t->chain; 443*16622Ssam } 444*16622Ssam } 445*16622Ssam printf(")"); 446*16622Ssam } 447*16622Ssam 448*16622Ssam /* 449*16622Ssam * List the parameters of a procedure or function. 450*16622Ssam * No attempt is made to combine like types. 451*16622Ssam */ 452*16622Ssam 453*16622Ssam private listparams (s) 454*16622Ssam Symbol s; 455*16622Ssam { 456*16622Ssam Symbol t; 457*16622Ssam 458*16622Ssam if (s->chain != nil) { 459*16622Ssam putchar('('); 460*16622Ssam for (t = s->chain; t != nil; t = t->chain) { 461*16622Ssam switch (t->class) { 462*16622Ssam case REF: 463*16622Ssam printf("var "); 464*16622Ssam break; 465*16622Ssam 466*16622Ssam case FPROC: 467*16622Ssam case FFUNC: 468*16622Ssam printf("procedure "); 469*16622Ssam break; 470*16622Ssam 471*16622Ssam case VAR: 472*16622Ssam break; 473*16622Ssam 474*16622Ssam default: 475*16622Ssam panic("unexpected class %d for parameter", t->class); 476*16622Ssam } 477*16622Ssam printf("%s", symname(t)); 478*16622Ssam if (s->class == PROG) { 479*16622Ssam printf(", "); 480*16622Ssam } else { 481*16622Ssam printf(" : "); 482*16622Ssam printtype(t, t->type, 0); 483*16622Ssam if (t->chain != nil) { 484*16622Ssam printf("; "); 485*16622Ssam } 486*16622Ssam } 487*16622Ssam } 488*16622Ssam putchar(')'); 489*16622Ssam } 490*16622Ssam } 491*16622Ssam 492*16622Ssam /* 493*16622Ssam * Modula 2 interface to printval. 494*16622Ssam */ 495*16622Ssam 496*16622Ssam public modula2_printval (s) 497*16622Ssam Symbol s; 498*16622Ssam { 499*16622Ssam prval(s, size(s)); 500*16622Ssam } 501*16622Ssam 502*16622Ssam /* 503*16622Ssam * Print out the value on the top of the expression stack 504*16622Ssam * in the format for the type of the given symbol, assuming 505*16622Ssam * the size of the object is n bytes. 506*16622Ssam */ 507*16622Ssam 508*16622Ssam private prval (s, n) 509*16622Ssam Symbol s; 510*16622Ssam integer n; 511*16622Ssam { 512*16622Ssam Symbol t; 513*16622Ssam Address a; 514*16622Ssam integer len; 515*16622Ssam double r; 516*16622Ssam integer scalar; 517*16622Ssam boolean found; 518*16622Ssam 519*16622Ssam if (s->class == TYPEREF) { 520*16622Ssam resolveRef(s); 521*16622Ssam } 522*16622Ssam switch (s->class) { 523*16622Ssam case CONST: 524*16622Ssam case TYPE: 525*16622Ssam case VAR: 526*16622Ssam case REF: 527*16622Ssam case FVAR: 528*16622Ssam case TAG: 529*16622Ssam case FIELD: 530*16622Ssam prval(s->type, n); 531*16622Ssam break; 532*16622Ssam 533*16622Ssam case ARRAY: 534*16622Ssam t = rtype(s->type); 535*16622Ssam if (t->class == RANGE and istypename(t->type, "char")) { 536*16622Ssam len = size(s); 537*16622Ssam sp -= len; 538*16622Ssam printf("'%.*s'", len, sp); 539*16622Ssam break; 540*16622Ssam } else { 541*16622Ssam printarray(s); 542*16622Ssam } 543*16622Ssam break; 544*16622Ssam 545*16622Ssam case RECORD: 546*16622Ssam printrecord(s); 547*16622Ssam break; 548*16622Ssam 549*16622Ssam case VARNT: 550*16622Ssam printf("can't print out variant records"); 551*16622Ssam break; 552*16622Ssam 553*16622Ssam case RANGE: 554*16622Ssam printrange(s, n); 555*16622Ssam break; 556*16622Ssam 557*16622Ssam case FILET: 558*16622Ssam case PTR: 559*16622Ssam a = pop(Address); 560*16622Ssam if (a == 0) { 561*16622Ssam printf("nil"); 562*16622Ssam } else { 563*16622Ssam printf("0x%x", a); 564*16622Ssam } 565*16622Ssam break; 566*16622Ssam 567*16622Ssam case SCAL: 568*16622Ssam popn(n, &scalar); 569*16622Ssam found = false; 570*16622Ssam for (t = s->chain; t != nil; t = t->chain) { 571*16622Ssam if (t->symvalue.iconval == scalar) { 572*16622Ssam printf("%s", symname(t)); 573*16622Ssam found = true; 574*16622Ssam break; 575*16622Ssam } 576*16622Ssam } 577*16622Ssam if (not found) { 578*16622Ssam printf("(scalar = %d)", scalar); 579*16622Ssam } 580*16622Ssam break; 581*16622Ssam 582*16622Ssam case FPROC: 583*16622Ssam case FFUNC: 584*16622Ssam a = pop(long); 585*16622Ssam t = whatblock(a); 586*16622Ssam if (t == nil) { 587*16622Ssam printf("(proc 0x%x)", a); 588*16622Ssam } else { 589*16622Ssam printf("%s", symname(t)); 590*16622Ssam } 591*16622Ssam break; 592*16622Ssam 593*16622Ssam case SET: 594*16622Ssam printSet(s); 595*16622Ssam break; 596*16622Ssam 597*16622Ssam default: 598*16622Ssam if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) { 599*16622Ssam panic("printval: bad class %d", ord(s->class)); 600*16622Ssam } 601*16622Ssam printf("[%s]", classname(s)); 602*16622Ssam break; 603*16622Ssam } 604*16622Ssam } 605*16622Ssam 606*16622Ssam /* 607*16622Ssam * Print out the value of a scalar (non-enumeration) type. 608*16622Ssam */ 609*16622Ssam 610*16622Ssam private printrange (s, n) 611*16622Ssam Symbol s; 612*16622Ssam integer n; 613*16622Ssam { 614*16622Ssam double d; 615*16622Ssam float f; 616*16622Ssam integer i; 617*16622Ssam 618*16622Ssam if (s->symvalue.rangev.upper == 0 and s->symvalue.rangev.lower > 0) { 619*16622Ssam if (n == sizeof(float)) { 620*16622Ssam popn(n, &f); 621*16622Ssam d = f; 622*16622Ssam } else { 623*16622Ssam popn(n, &d); 624*16622Ssam } 625*16622Ssam prtreal(d); 626*16622Ssam } else { 627*16622Ssam i = 0; 628*16622Ssam popn(n, &i); 629*16622Ssam if (s == t_boolean) { 630*16622Ssam printf(((Boolean) i) == true ? "true" : "false"); 631*16622Ssam } else if (s == t_char or istypename(s->type, "char")) { 632*16622Ssam printf("'%c'", i); 633*16622Ssam } else if (s->symvalue.rangev.lower >= 0) { 634*16622Ssam printf("%lu", i); 635*16622Ssam } else { 636*16622Ssam printf("%ld", i); 637*16622Ssam } 638*16622Ssam } 639*16622Ssam } 640*16622Ssam 641*16622Ssam /* 642*16622Ssam * Print out a set. 643*16622Ssam */ 644*16622Ssam 645*16622Ssam private printSet (s) 646*16622Ssam Symbol s; 647*16622Ssam { 648*16622Ssam Symbol t; 649*16622Ssam integer nbytes; 650*16622Ssam 651*16622Ssam nbytes = size(s); 652*16622Ssam t = rtype(s->type); 653*16622Ssam printf("{"); 654*16622Ssam sp -= nbytes; 655*16622Ssam if (t->class == SCAL) { 656*16622Ssam printSetOfEnum(t); 657*16622Ssam } else if (t->class == RANGE) { 658*16622Ssam printSetOfRange(t); 659*16622Ssam } else { 660*16622Ssam panic("expected range or enumerated base type for set"); 661*16622Ssam } 662*16622Ssam printf("}"); 663*16622Ssam } 664*16622Ssam 665*16622Ssam /* 666*16622Ssam * Print out a set of an enumeration. 667*16622Ssam */ 668*16622Ssam 669*16622Ssam private printSetOfEnum (t) 670*16622Ssam Symbol t; 671*16622Ssam { 672*16622Ssam register Symbol e; 673*16622Ssam register integer i, j, *p; 674*16622Ssam boolean first; 675*16622Ssam 676*16622Ssam p = (int *) sp; 677*16622Ssam i = *p; 678*16622Ssam j = 0; 679*16622Ssam e = t->chain; 680*16622Ssam first = true; 681*16622Ssam while (e != nil) { 682*16622Ssam if ((i&1) == 1) { 683*16622Ssam if (first) { 684*16622Ssam first = false; 685*16622Ssam printf("%s", symname(e)); 686*16622Ssam } else { 687*16622Ssam printf(", %s", symname(e)); 688*16622Ssam } 689*16622Ssam } 690*16622Ssam i >>= 1; 691*16622Ssam ++j; 692*16622Ssam if (j >= sizeof(integer)*BITSPERBYTE) { 693*16622Ssam j = 0; 694*16622Ssam ++p; 695*16622Ssam i = *p; 696*16622Ssam } 697*16622Ssam e = e->chain; 698*16622Ssam } 699*16622Ssam } 700*16622Ssam 701*16622Ssam /* 702*16622Ssam * Print out a set of a subrange type. 703*16622Ssam */ 704*16622Ssam 705*16622Ssam private printSetOfRange (t) 706*16622Ssam Symbol t; 707*16622Ssam { 708*16622Ssam register integer i, j, *p; 709*16622Ssam long v; 710*16622Ssam boolean first; 711*16622Ssam 712*16622Ssam p = (int *) sp; 713*16622Ssam i = *p; 714*16622Ssam j = 0; 715*16622Ssam v = t->symvalue.rangev.lower; 716*16622Ssam first = true; 717*16622Ssam while (v <= t->symvalue.rangev.upper) { 718*16622Ssam if ((i&1) == 1) { 719*16622Ssam if (first) { 720*16622Ssam first = false; 721*16622Ssam printf("%ld", v); 722*16622Ssam } else { 723*16622Ssam printf(", %ld", v); 724*16622Ssam } 725*16622Ssam } 726*16622Ssam i >>= 1; 727*16622Ssam ++j; 728*16622Ssam if (j >= sizeof(integer)*BITSPERBYTE) { 729*16622Ssam j = 0; 730*16622Ssam ++p; 731*16622Ssam i = *p; 732*16622Ssam } 733*16622Ssam ++v; 734*16622Ssam } 735*16622Ssam } 736*16622Ssam 737*16622Ssam /* 738*16622Ssam * Construct a node for subscripting. 739*16622Ssam */ 740*16622Ssam 741*16622Ssam public Node modula2_buildaref (a, slist) 742*16622Ssam Node a, slist; 743*16622Ssam { 744*16622Ssam register Symbol t; 745*16622Ssam register Node p; 746*16622Ssam Symbol etype, atype, eltype; 747*16622Ssam Node esub, r; 748*16622Ssam 749*16622Ssam r = a; 750*16622Ssam t = rtype(a->nodetype); 751*16622Ssam eltype = t->type; 752*16622Ssam if (t->class != ARRAY) { 753*16622Ssam beginerrmsg(); 754*16622Ssam prtree(stderr, a); 755*16622Ssam fprintf(stderr, " is not an array"); 756*16622Ssam enderrmsg(); 757*16622Ssam } else { 758*16622Ssam p = slist; 759*16622Ssam t = t->chain; 760*16622Ssam for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) { 761*16622Ssam esub = p->value.arg[0]; 762*16622Ssam etype = rtype(esub->nodetype); 763*16622Ssam atype = rtype(t); 764*16622Ssam if (not compatible(atype, etype)) { 765*16622Ssam beginerrmsg(); 766*16622Ssam fprintf(stderr, "subscript "); 767*16622Ssam prtree(stderr, esub); 768*16622Ssam fprintf(stderr, " is the wrong type"); 769*16622Ssam enderrmsg(); 770*16622Ssam } 771*16622Ssam r = build(O_INDEX, r, esub); 772*16622Ssam r->nodetype = eltype; 773*16622Ssam } 774*16622Ssam if (p != nil or t != nil) { 775*16622Ssam beginerrmsg(); 776*16622Ssam if (p != nil) { 777*16622Ssam fprintf(stderr, "too many subscripts for "); 778*16622Ssam } else { 779*16622Ssam fprintf(stderr, "not enough subscripts for "); 780*16622Ssam } 781*16622Ssam prtree(stderr, a); 782*16622Ssam enderrmsg(); 783*16622Ssam } 784*16622Ssam } 785*16622Ssam return r; 786*16622Ssam } 787*16622Ssam 788*16622Ssam /* 789*16622Ssam * Evaluate a subscript index. 790*16622Ssam */ 791*16622Ssam 792*16622Ssam public int modula2_evalaref (s, i) 793*16622Ssam Symbol s; 794*16622Ssam long i; 795*16622Ssam { 796*16622Ssam long lb, ub; 797*16622Ssam 798*16622Ssam chkOpenArray(s); 799*16622Ssam s = rtype(rtype(s)->chain); 800*16622Ssam findbounds(s, &lb, &ub); 801*16622Ssam if (i < lb or i > ub) { 802*16622Ssam error("subscript %d out of range [%d..%d]", i, lb, ub); 803*16622Ssam } 804*16622Ssam return (i - lb); 805*16622Ssam } 806*16622Ssam 807*16622Ssam /* 808*16622Ssam * Initial Modula-2 type information. 809*16622Ssam */ 810*16622Ssam 811*16622Ssam #define NTYPES 12 812*16622Ssam 813*16622Ssam private Symbol inittype[NTYPES + 1]; 814*16622Ssam 815*16622Ssam private addType (n, s, lower, upper) 816*16622Ssam integer n; 817*16622Ssam String s; 818*16622Ssam long lower, upper; 819*16622Ssam { 820*16622Ssam register Symbol t; 821*16622Ssam 822*16622Ssam if (n > NTYPES) { 823*16622Ssam panic("initial Modula-2 type number too large for '%s'", s); 824*16622Ssam } 825*16622Ssam t = insert(identname(s, true)); 826*16622Ssam t->language = mod2; 827*16622Ssam t->class = TYPE; 828*16622Ssam t->type = newSymbol(nil, 0, RANGE, t, nil); 829*16622Ssam t->type->symvalue.rangev.lower = lower; 830*16622Ssam t->type->symvalue.rangev.upper = upper; 831*16622Ssam t->type->language = mod2; 832*16622Ssam inittype[n] = t; 833*16622Ssam } 834*16622Ssam 835*16622Ssam private initModTypes () 836*16622Ssam { 837*16622Ssam addType(1, "integer", 0x80000000L, 0x7fffffffL); 838*16622Ssam addType(2, "char", 0L, 255L); 839*16622Ssam addType(3, "boolean", 0L, 1L); 840*16622Ssam addType(4, "unsigned", 0L, 0xffffffffL); 841*16622Ssam addType(5, "real", 4L, 0L); 842*16622Ssam addType(6, "longreal", 8L, 0L); 843*16622Ssam addType(7, "word", 0L, 0xffffffffL); 844*16622Ssam addType(8, "byte", 0L, 255L); 845*16622Ssam addType(9, "address", 0L, 0xffffffffL); 846*16622Ssam addType(10, "file", 0L, 0xffffffffL); 847*16622Ssam addType(11, "process", 0L, 0xffffffffL); 848*16622Ssam addType(12, "cardinal", 0L, 0x7fffffffL); 849*16622Ssam } 850*16622Ssam 851*16622Ssam /* 852*16622Ssam * Initialize typetable. 853*16622Ssam */ 854*16622Ssam 855*16622Ssam public modula2_modinit (typetable) 856*16622Ssam Symbol typetable[]; 857*16622Ssam { 858*16622Ssam register integer i; 859*16622Ssam 860*16622Ssam if (not initialized) { 861*16622Ssam initModTypes(); 862*16622Ssam } 863*16622Ssam for (i = 1; i <= NTYPES; i++) { 864*16622Ssam typetable[i] = inittype[i]; 865*16622Ssam } 866*16622Ssam } 867*16622Ssam 868*16622Ssam public boolean modula2_hasmodules () 869*16622Ssam { 870*16622Ssam return true; 871*16622Ssam } 872*16622Ssam 873*16622Ssam public boolean modula2_passaddr (param, exprtype) 874*16622Ssam Symbol param, exprtype; 875*16622Ssam { 876*16622Ssam return false; 877*16622Ssam } 878