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