1*9675Slinton /* Copyright (c) 1982 Regents of the University of California */ 2*9675Slinton 3*9675Slinton static char sccsid[] = "@(#)@(#)pascal.c 1.1 12/15/82"; 4*9675Slinton 5*9675Slinton /* 6*9675Slinton * Pascal-dependent symbol routines. 7*9675Slinton */ 8*9675Slinton 9*9675Slinton #include "defs.h" 10*9675Slinton #include "symbols.h" 11*9675Slinton #include "pascal.h" 12*9675Slinton #include "languages.h" 13*9675Slinton #include "tree.h" 14*9675Slinton #include "eval.h" 15*9675Slinton #include "mappings.h" 16*9675Slinton #include "process.h" 17*9675Slinton #include "runtime.h" 18*9675Slinton #include "machine.h" 19*9675Slinton 20*9675Slinton #ifndef public 21*9675Slinton #endif 22*9675Slinton 23*9675Slinton /* 24*9675Slinton * Initialize Pascal information. 25*9675Slinton */ 26*9675Slinton 27*9675Slinton public pascal_init() 28*9675Slinton { 29*9675Slinton Language lang; 30*9675Slinton 31*9675Slinton lang = language_define("pascal", ".p"); 32*9675Slinton language_setop(lang, L_PRINTDECL, pascal_printdecl); 33*9675Slinton language_setop(lang, L_PRINTVAL, pascal_printval); 34*9675Slinton language_setop(lang, L_TYPEMATCH, pascal_typematch); 35*9675Slinton } 36*9675Slinton 37*9675Slinton /* 38*9675Slinton * Compatible tests if two types are compatible. The issue 39*9675Slinton * is complicated a bit by ranges. 40*9675Slinton * 41*9675Slinton * Integers and reals are not compatible since they cannot always be mixed. 42*9675Slinton */ 43*9675Slinton 44*9675Slinton public Boolean pascal_typematch(type1, type2) 45*9675Slinton Symbol type1, type2; 46*9675Slinton { 47*9675Slinton Boolean b; 48*9675Slinton register Symbol t1, t2; 49*9675Slinton 50*9675Slinton t1 = rtype(t1); 51*9675Slinton t2 = rtype(t2); 52*9675Slinton b = (Boolean) 53*9675Slinton (t1->type == t2->type and ( 54*9675Slinton (t1->class == RANGE and t2->class == RANGE) or 55*9675Slinton (t1->class == SCAL and t2->class == CONST) or 56*9675Slinton (t1->class == CONST and t2->class == SCAL) or 57*9675Slinton (t1->type == t_char and t1->class == ARRAY and t2->class == ARRAY) 58*9675Slinton ) or 59*9675Slinton (t1 == t_nil and t2->class == PTR) or 60*9675Slinton (t1->class == PTR and t2 == t_nil) 61*9675Slinton ); 62*9675Slinton return b; 63*9675Slinton } 64*9675Slinton 65*9675Slinton public pascal_printdecl(s) 66*9675Slinton Symbol s; 67*9675Slinton { 68*9675Slinton register Symbol t; 69*9675Slinton Boolean semicolon; 70*9675Slinton 71*9675Slinton semicolon = true; 72*9675Slinton switch (s->class) { 73*9675Slinton case CONST: 74*9675Slinton if (s->type->class == SCAL) { 75*9675Slinton printf("(enumeration constant, ord %ld)", 76*9675Slinton s->symvalue.iconval); 77*9675Slinton } else { 78*9675Slinton printf("const %s = ", symname(s)); 79*9675Slinton printval(s); 80*9675Slinton } 81*9675Slinton break; 82*9675Slinton 83*9675Slinton case TYPE: 84*9675Slinton printf("type %s = ", symname(s)); 85*9675Slinton printtype(s, s->type); 86*9675Slinton break; 87*9675Slinton 88*9675Slinton case VAR: 89*9675Slinton if (isparam(s)) { 90*9675Slinton printf("(parameter) %s : ", symname(s)); 91*9675Slinton } else { 92*9675Slinton printf("var %s : ", symname(s)); 93*9675Slinton } 94*9675Slinton printtype(s, s->type); 95*9675Slinton break; 96*9675Slinton 97*9675Slinton case REF: 98*9675Slinton printf("(var parameter) %s : ", symname(s)); 99*9675Slinton printtype(s, s->type); 100*9675Slinton break; 101*9675Slinton 102*9675Slinton case RANGE: 103*9675Slinton case ARRAY: 104*9675Slinton case RECORD: 105*9675Slinton case VARNT: 106*9675Slinton case PTR: 107*9675Slinton printtype(s, s); 108*9675Slinton semicolon = false; 109*9675Slinton break; 110*9675Slinton 111*9675Slinton case FVAR: 112*9675Slinton printf("(function variable) %s : ", symname(s)); 113*9675Slinton printtype(s, s->type); 114*9675Slinton break; 115*9675Slinton 116*9675Slinton case FIELD: 117*9675Slinton printf("(field) %s : ", symname(s)); 118*9675Slinton printtype(s, s->type); 119*9675Slinton break; 120*9675Slinton 121*9675Slinton case PROC: 122*9675Slinton printf("procedure %s", symname(s)); 123*9675Slinton listparams(s); 124*9675Slinton break; 125*9675Slinton 126*9675Slinton case PROG: 127*9675Slinton printf("program %s", symname(s)); 128*9675Slinton t = s->chain; 129*9675Slinton if (t != nil) { 130*9675Slinton printf("(%s", symname(t)); 131*9675Slinton for (t = t->chain; t != nil; t = t->chain) { 132*9675Slinton printf(", %s", symname(t)); 133*9675Slinton } 134*9675Slinton printf(")"); 135*9675Slinton } 136*9675Slinton break; 137*9675Slinton 138*9675Slinton case FUNC: 139*9675Slinton printf("function %s", symname(s)); 140*9675Slinton listparams(s); 141*9675Slinton printf(" : "); 142*9675Slinton printtype(s, s->type); 143*9675Slinton break; 144*9675Slinton 145*9675Slinton default: 146*9675Slinton error("class %s in printdecl", classname(s)); 147*9675Slinton } 148*9675Slinton if (semicolon) { 149*9675Slinton putchar(';'); 150*9675Slinton } 151*9675Slinton putchar('\n'); 152*9675Slinton } 153*9675Slinton 154*9675Slinton /* 155*9675Slinton * Recursive whiz-bang procedure to print the type portion 156*9675Slinton * of a declaration. Doesn't work quite right for variant records. 157*9675Slinton * 158*9675Slinton * The symbol associated with the type is passed to allow 159*9675Slinton * searching for type names without getting "type blah = blah". 160*9675Slinton */ 161*9675Slinton 162*9675Slinton private printtype(s, t) 163*9675Slinton Symbol s; 164*9675Slinton Symbol t; 165*9675Slinton { 166*9675Slinton register Symbol tmp; 167*9675Slinton 168*9675Slinton switch (t->class) { 169*9675Slinton case VAR: 170*9675Slinton case CONST: 171*9675Slinton case FUNC: 172*9675Slinton case PROC: 173*9675Slinton panic("printtype: class %s", classname(t)); 174*9675Slinton break; 175*9675Slinton 176*9675Slinton case ARRAY: 177*9675Slinton printf("array["); 178*9675Slinton tmp = t->chain; 179*9675Slinton if (tmp != nil) { 180*9675Slinton for (;;) { 181*9675Slinton printtype(tmp, tmp); 182*9675Slinton tmp = tmp->chain; 183*9675Slinton if (tmp == nil) { 184*9675Slinton break; 185*9675Slinton } 186*9675Slinton printf(", "); 187*9675Slinton } 188*9675Slinton } 189*9675Slinton printf("] of "); 190*9675Slinton printtype(t, t->type); 191*9675Slinton break; 192*9675Slinton 193*9675Slinton case RECORD: 194*9675Slinton printf("record\n"); 195*9675Slinton if (t->chain != nil) { 196*9675Slinton printtype(t->chain, t->chain); 197*9675Slinton } 198*9675Slinton printf("end"); 199*9675Slinton break; 200*9675Slinton 201*9675Slinton case FIELD: 202*9675Slinton if (t->chain != nil) { 203*9675Slinton printtype(t->chain, t->chain); 204*9675Slinton } 205*9675Slinton printf("\t%s : ", symname(t)); 206*9675Slinton printtype(t, t->type); 207*9675Slinton printf(";\n"); 208*9675Slinton break; 209*9675Slinton 210*9675Slinton case RANGE: { 211*9675Slinton long r0, r1; 212*9675Slinton 213*9675Slinton r0 = t->symvalue.rangev.lower; 214*9675Slinton r1 = t->symvalue.rangev.upper; 215*9675Slinton if (t == t_char) { 216*9675Slinton if (r0 < 0x20 or r0 > 0x7e) { 217*9675Slinton printf("%ld..", r0); 218*9675Slinton } else { 219*9675Slinton printf("'%c'..", (char) r0); 220*9675Slinton } 221*9675Slinton if (r1 < 0x20 or r1 > 0x7e) { 222*9675Slinton printf("\\%lo", r1); 223*9675Slinton } else { 224*9675Slinton printf("'%c'", (char) r1); 225*9675Slinton } 226*9675Slinton } else if (r0 > 0 and r1 == 0) { 227*9675Slinton printf("%ld byte real", r0); 228*9675Slinton } else if (r0 >= 0) { 229*9675Slinton printf("%lu..%lu", r0, r1); 230*9675Slinton } else { 231*9675Slinton printf("%ld..%ld", r0, r1); 232*9675Slinton } 233*9675Slinton break; 234*9675Slinton } 235*9675Slinton 236*9675Slinton case PTR: 237*9675Slinton putchar('*'); 238*9675Slinton printtype(t, t->type); 239*9675Slinton break; 240*9675Slinton 241*9675Slinton case TYPE: 242*9675Slinton if (symname(t) != nil) { 243*9675Slinton printf("%s", symname(t)); 244*9675Slinton } else { 245*9675Slinton printtype(t, t->type); 246*9675Slinton } 247*9675Slinton break; 248*9675Slinton 249*9675Slinton case SCAL: 250*9675Slinton printf("("); 251*9675Slinton t = t->type->chain; 252*9675Slinton if (t != nil) { 253*9675Slinton printf("%s", symname(t)); 254*9675Slinton t = t->chain; 255*9675Slinton while (t != nil) { 256*9675Slinton printf(", %s", symname(t)); 257*9675Slinton t = t->chain; 258*9675Slinton } 259*9675Slinton } else { 260*9675Slinton panic("empty enumeration"); 261*9675Slinton } 262*9675Slinton printf(")"); 263*9675Slinton break; 264*9675Slinton 265*9675Slinton default: 266*9675Slinton printf("(class %d)", t->class); 267*9675Slinton break; 268*9675Slinton } 269*9675Slinton } 270*9675Slinton 271*9675Slinton /* 272*9675Slinton * List the parameters of a procedure or function. 273*9675Slinton * No attempt is made to combine like types. 274*9675Slinton */ 275*9675Slinton 276*9675Slinton private listparams(s) 277*9675Slinton Symbol s; 278*9675Slinton { 279*9675Slinton Symbol t; 280*9675Slinton 281*9675Slinton if (s->chain != nil) { 282*9675Slinton putchar('('); 283*9675Slinton for (t = s->chain; t != nil; t = t->chain) { 284*9675Slinton switch (t->class) { 285*9675Slinton case REF: 286*9675Slinton printf("var "); 287*9675Slinton break; 288*9675Slinton 289*9675Slinton case FPROC: 290*9675Slinton printf("procedure "); 291*9675Slinton break; 292*9675Slinton 293*9675Slinton case FFUNC: 294*9675Slinton printf("function "); 295*9675Slinton break; 296*9675Slinton 297*9675Slinton case VAR: 298*9675Slinton break; 299*9675Slinton 300*9675Slinton default: 301*9675Slinton panic("unexpected class %d for parameter", t->class); 302*9675Slinton } 303*9675Slinton printf("%s : ", symname(t)); 304*9675Slinton printtype(t, t->type); 305*9675Slinton if (t->chain != nil) { 306*9675Slinton printf("; "); 307*9675Slinton } 308*9675Slinton } 309*9675Slinton putchar(')'); 310*9675Slinton } 311*9675Slinton } 312*9675Slinton 313*9675Slinton /* 314*9675Slinton * Print out the value on the top of the expression stack 315*9675Slinton * in the format for the type of the given symbol. 316*9675Slinton */ 317*9675Slinton 318*9675Slinton public pascal_printval(s) 319*9675Slinton Symbol s; 320*9675Slinton { 321*9675Slinton Symbol t; 322*9675Slinton Address a; 323*9675Slinton int len; 324*9675Slinton double r; 325*9675Slinton 326*9675Slinton if (s->class == REF) { 327*9675Slinton s = s->type; 328*9675Slinton } 329*9675Slinton switch (s->class) { 330*9675Slinton case TYPE: 331*9675Slinton pascal_printval(s->type); 332*9675Slinton break; 333*9675Slinton 334*9675Slinton case ARRAY: 335*9675Slinton t = rtype(s->type); 336*9675Slinton if (t==t_char or (t->class==RANGE and t->type==t_char)) { 337*9675Slinton len = size(s); 338*9675Slinton sp -= len; 339*9675Slinton printf("'%.*s'", len, sp); 340*9675Slinton break; 341*9675Slinton } else { 342*9675Slinton printarray(s); 343*9675Slinton } 344*9675Slinton break; 345*9675Slinton 346*9675Slinton case RECORD: 347*9675Slinton printrecord(s); 348*9675Slinton break; 349*9675Slinton 350*9675Slinton case VARNT: 351*9675Slinton error("can't print out variant records"); 352*9675Slinton break; 353*9675Slinton 354*9675Slinton 355*9675Slinton case RANGE: 356*9675Slinton if (s == t_boolean) { 357*9675Slinton printf(((Boolean) popsmall(s)) == true ? "true" : "false"); 358*9675Slinton } else if (s == t_char) { 359*9675Slinton printf("'%c'", pop(char)); 360*9675Slinton } else if (s->symvalue.rangev.upper == 0 and 361*9675Slinton s->symvalue.rangev.lower > 0) { 362*9675Slinton switch (s->symvalue.rangev.lower) { 363*9675Slinton case sizeof(float): 364*9675Slinton prtreal(pop(float)); 365*9675Slinton break; 366*9675Slinton 367*9675Slinton case sizeof(double): 368*9675Slinton prtreal(pop(double)); 369*9675Slinton break; 370*9675Slinton 371*9675Slinton default: 372*9675Slinton panic("bad real size %d", s->symvalue.rangev.lower); 373*9675Slinton break; 374*9675Slinton } 375*9675Slinton } else if (s->symvalue.rangev.lower >= 0) { 376*9675Slinton printf("%lu", popsmall(s)); 377*9675Slinton } else { 378*9675Slinton printf("%ld", popsmall(s)); 379*9675Slinton } 380*9675Slinton break; 381*9675Slinton 382*9675Slinton case FILET: 383*9675Slinton case PTR: { 384*9675Slinton Address addr; 385*9675Slinton 386*9675Slinton addr = pop(Address); 387*9675Slinton if (addr == 0) { 388*9675Slinton printf("0, (nil)"); 389*9675Slinton } else { 390*9675Slinton printf("0x%x, 0%o", addr, addr); 391*9675Slinton } 392*9675Slinton break; 393*9675Slinton } 394*9675Slinton 395*9675Slinton case FIELD: 396*9675Slinton error("missing record specification"); 397*9675Slinton break; 398*9675Slinton 399*9675Slinton case SCAL: { 400*9675Slinton int scalar; 401*9675Slinton Boolean found; 402*9675Slinton 403*9675Slinton scalar = popsmall(s); 404*9675Slinton found = false; 405*9675Slinton for (t = s->chain; t != nil; t = t->chain) { 406*9675Slinton if (t->symvalue.iconval == scalar) { 407*9675Slinton printf("%s", symname(t)); 408*9675Slinton found = true; 409*9675Slinton break; 410*9675Slinton } 411*9675Slinton } 412*9675Slinton if (not found) { 413*9675Slinton printf("(scalar = %d)", scalar); 414*9675Slinton } 415*9675Slinton break; 416*9675Slinton } 417*9675Slinton 418*9675Slinton case FPROC: 419*9675Slinton case FFUNC: 420*9675Slinton { 421*9675Slinton Address a; 422*9675Slinton 423*9675Slinton a = fparamaddr(pop(long)); 424*9675Slinton t = whatblock(a); 425*9675Slinton if (t == nil) { 426*9675Slinton printf("(proc %d)", a); 427*9675Slinton } else { 428*9675Slinton printf("%s", symname(t)); 429*9675Slinton } 430*9675Slinton break; 431*9675Slinton } 432*9675Slinton 433*9675Slinton default: 434*9675Slinton if (ord(s->class) < ord(BADUSE) or ord(s->class) > ord(TYPEREF)) { 435*9675Slinton panic("printval: bad class %d", ord(s->class)); 436*9675Slinton } 437*9675Slinton error("don't know how to print a %s", classname(s)); 438*9675Slinton /* NOTREACHED */ 439*9675Slinton } 440*9675Slinton } 441