|
|
1.1 ! root 1: /**************************************************************** ! 2: Copyright 1990, 1991, 1993 by AT&T Bell Laboratories and Bellcore. ! 3: ! 4: Permission to use, copy, modify, and distribute this software ! 5: and its documentation for any purpose and without fee is hereby ! 6: granted, provided that the above copyright notice appear in all ! 7: copies and that both that the copyright notice and this ! 8: permission notice and warranty disclaimer appear in supporting ! 9: documentation, and that the names of AT&T Bell Laboratories or ! 10: Bellcore or any of their entities not be used in advertising or ! 11: publicity pertaining to distribution of the software without ! 12: specific, written prior permission. ! 13: ! 14: AT&T and Bellcore disclaim all warranties with regard to this ! 15: software, including all implied warranties of merchantability ! 16: and fitness. In no event shall AT&T or Bellcore be liable for ! 17: any special, indirect or consequential damages or any damages ! 18: whatsoever resulting from loss of use, data or profits, whether ! 19: in an action of contract, negligence or other tortious action, ! 20: arising out of or in connection with the use or performance of ! 21: this software. ! 22: ****************************************************************/ ! 23: ! 24: #include "defs.h" ! 25: #include "p1defs.h" ! 26: #include "output.h" ! 27: #include "names.h" ! 28: ! 29: ! 30: static void p1_addr(), p1_big_addr(), p1_binary(), p1_const(), p1_list(), ! 31: p1_literal(), p1_name(), p1_unary(), p1putn(); ! 32: static void p1putd (/* int, int */); ! 33: static void p1putds (/* int, int, char * */); ! 34: static void p1putdds (/* int, int, int, char * */); ! 35: static void p1putdd (/* int, int, int */); ! 36: static void p1putddd (/* int, int, int, int */); ! 37: ! 38: ! 39: /* p1_comment -- save the text of a Fortran comment in the intermediate ! 40: file. Make sure that there are no spurious "/ *" or "* /" characters by ! 41: mapping them onto "/+" and "+/". str is assumed to hold no newlines and be ! 42: null terminated; it may be modified by this function. */ ! 43: ! 44: void p1_comment (str) ! 45: char *str; ! 46: { ! 47: register unsigned char *pointer, *ustr; ! 48: ! 49: if (!str) ! 50: return; ! 51: ! 52: /* Get rid of any open or close comment combinations that may be in the ! 53: Fortran input */ ! 54: ! 55: ustr = (unsigned char *)str; ! 56: for(pointer = ustr; *pointer; pointer++) ! 57: if (*pointer == '*' && (pointer[1] == '/' ! 58: || pointer > ustr && pointer[-1] == '/')) ! 59: *pointer = '+'; ! 60: /* trim trailing white space */ ! 61: #ifdef isascii ! 62: while(--pointer >= ustr && (!isascii(*pointer) || isspace(*pointer))); ! 63: #else ! 64: while(--pointer >= ustr && isspace(*pointer)); ! 65: #endif ! 66: pointer[1] = 0; ! 67: p1puts (P1_COMMENT, str); ! 68: } /* p1_comment */ ! 69: ! 70: void p1_line_number (line_number) ! 71: long line_number; ! 72: { ! 73: ! 74: p1putd (P1_SET_LINE, line_number); ! 75: } /* p1_line_number */ ! 76: ! 77: /* p1_name -- Writes the address of a hash table entry into the ! 78: intermediate file */ ! 79: ! 80: static void p1_name (namep) ! 81: Namep namep; ! 82: { ! 83: p1putd (P1_NAME_POINTER, (long) namep); ! 84: namep->visused = 1; ! 85: } /* p1_name */ ! 86: ! 87: ! 88: ! 89: void p1_expr (expr) ! 90: expptr expr; ! 91: { ! 92: /* An opcode of 0 means a null entry */ ! 93: ! 94: if (expr == ENULL) { ! 95: p1putdd (P1_EXPR, 0, TYUNKNOWN); /* Should this be TYERROR? */ ! 96: return; ! 97: } /* if (expr == ENULL) */ ! 98: ! 99: switch (expr -> tag) { ! 100: case TNAME: ! 101: p1_name ((Namep) expr); ! 102: return; ! 103: case TCONST: ! 104: p1_const(&expr->constblock); ! 105: return; ! 106: case TEXPR: ! 107: /* Fall through the switch */ ! 108: break; ! 109: case TADDR: ! 110: p1_addr (&(expr -> addrblock)); ! 111: goto freeup; ! 112: case TPRIM: ! 113: warn ("p1_expr: got TPRIM"); ! 114: return; ! 115: case TLIST: ! 116: p1_list (&(expr->listblock)); ! 117: frchain( &(expr->listblock.listp) ); ! 118: return; ! 119: case TERROR: ! 120: return; ! 121: default: ! 122: erri ("p1_expr: bad tag '%d'", (int) (expr -> tag)); ! 123: return; ! 124: } ! 125: ! 126: /* Now we know that the tag is TEXPR */ ! 127: ! 128: if (is_unary_op (expr -> exprblock.opcode)) ! 129: p1_unary (&(expr -> exprblock)); ! 130: else if (is_binary_op (expr -> exprblock.opcode)) ! 131: p1_binary (&(expr -> exprblock)); ! 132: else ! 133: erri ("p1_expr: bad opcode '%d'", (int) expr -> exprblock.opcode); ! 134: freeup: ! 135: free((char *)expr); ! 136: ! 137: } /* p1_expr */ ! 138: ! 139: ! 140: ! 141: static void p1_const(cp) ! 142: register Constp cp; ! 143: { ! 144: int type = cp->vtype; ! 145: expptr vleng = cp->vleng; ! 146: union Constant *c = &cp->Const; ! 147: char cdsbuf0[64], cdsbuf1[64]; ! 148: char *cds0, *cds1; ! 149: ! 150: switch (type) { ! 151: case TYINT1: ! 152: case TYSHORT: ! 153: case TYLONG: ! 154: #ifdef TYQUAD ! 155: case TYQUAD: ! 156: #endif ! 157: case TYLOGICAL: ! 158: case TYLOGICAL1: ! 159: case TYLOGICAL2: ! 160: fprintf(pass1_file, "%d: %d %ld\n", P1_CONST, type, c->ci); ! 161: break; ! 162: case TYREAL: ! 163: case TYDREAL: ! 164: fprintf(pass1_file, "%d: %d %s\n", P1_CONST, type, ! 165: cp->vstg ? c->cds[0] : cds(dtos(c->cd[0]), cdsbuf0)); ! 166: break; ! 167: case TYCOMPLEX: ! 168: case TYDCOMPLEX: ! 169: if (cp->vstg) { ! 170: cds0 = c->cds[0]; ! 171: cds1 = c->cds[1]; ! 172: } ! 173: else { ! 174: cds0 = cds(dtos(c->cd[0]), cdsbuf0); ! 175: cds1 = cds(dtos(c->cd[1]), cdsbuf1); ! 176: } ! 177: fprintf(pass1_file, "%d: %d %s %s\n", P1_CONST, type, ! 178: cds0, cds1); ! 179: break; ! 180: case TYCHAR: ! 181: if (vleng && !ISICON (vleng)) ! 182: erri("p1_const: bad vleng '%d'\n", (int) vleng); ! 183: else ! 184: fprintf(pass1_file, "%d: %d %lx\n", P1_CONST, type, ! 185: cpexpr((expptr)cp)); ! 186: break; ! 187: default: ! 188: erri ("p1_const: bad constant type '%d'", type); ! 189: break; ! 190: } /* switch */ ! 191: } /* p1_const */ ! 192: ! 193: ! 194: void p1_asgoto (addrp) ! 195: Addrp addrp; ! 196: { ! 197: p1put (P1_ASGOTO); ! 198: p1_addr (addrp); ! 199: } /* p1_asgoto */ ! 200: ! 201: ! 202: void p1_goto (stateno) ! 203: ftnint stateno; ! 204: { ! 205: p1putd (P1_GOTO, stateno); ! 206: } /* p1_goto */ ! 207: ! 208: ! 209: static void p1_addr (addrp) ! 210: register struct Addrblock *addrp; ! 211: { ! 212: int stg; ! 213: ! 214: if (addrp == (struct Addrblock *) NULL) ! 215: return; ! 216: ! 217: stg = addrp -> vstg; ! 218: ! 219: if (ONEOF(stg, M(STGINIT)|M(STGREG)) ! 220: || ONEOF(stg, M(STGCOMMON)|M(STGEQUIV)) && ! 221: (!ISICON(addrp->memoffset) ! 222: || (addrp->uname_tag == UNAM_NAME ! 223: ? addrp->memoffset->constblock.Const.ci ! 224: != addrp->user.name->voffset ! 225: : addrp->memoffset->constblock.Const.ci)) ! 226: || ONEOF(stg, M(STGBSS)|M(STGINIT)|M(STGAUTO)|M(STGARG)) && ! 227: (!ISICON(addrp->memoffset) ! 228: || addrp->memoffset->constblock.Const.ci) ! 229: || addrp->Field || addrp->isarray || addrp->vstg == STGLENG) ! 230: { ! 231: p1_big_addr (addrp); ! 232: return; ! 233: } ! 234: ! 235: /* Write out a level of indirection for non-array arguments, which have ! 236: addrp -> memoffset set and are handled by p1_big_addr(). ! 237: Lengths are passed by value, so don't check STGLENG ! 238: 28-Jun-89 (dmg) Added the check for != TYCHAR ! 239: */ ! 240: ! 241: if (oneof_stg ( addrp -> uname_tag == UNAM_NAME ? addrp -> user.name : NULL, ! 242: stg, M(STGARG)|M(STGEQUIV)) && addrp->vtype != TYCHAR) { ! 243: p1putdd (P1_EXPR, OPWHATSIN, addrp -> vtype); ! 244: p1_expr (ENULL); /* Put dummy vleng */ ! 245: } /* if stg == STGARG */ ! 246: ! 247: switch (addrp -> uname_tag) { ! 248: case UNAM_NAME: ! 249: p1_name (addrp -> user.name); ! 250: break; ! 251: case UNAM_IDENT: ! 252: p1putdds(P1_IDENT, addrp->vtype, addrp->vstg, ! 253: addrp->user.ident); ! 254: break; ! 255: case UNAM_CHARP: ! 256: p1putdds(P1_CHARP, addrp->vtype, addrp->vstg, ! 257: addrp->user.Charp); ! 258: break; ! 259: case UNAM_EXTERN: ! 260: p1putd (P1_EXTERN, (long) addrp -> memno); ! 261: if (addrp->vclass == CLPROC) ! 262: extsymtab[addrp->memno].extype = addrp->vtype; ! 263: break; ! 264: case UNAM_CONST: ! 265: if (addrp -> memno != BAD_MEMNO) ! 266: p1_literal (addrp -> memno); ! 267: else ! 268: p1_const((struct Constblock *)addrp); ! 269: break; ! 270: case UNAM_UNKNOWN: ! 271: default: ! 272: erri ("p1_addr: unknown uname_tag '%d'", addrp -> uname_tag); ! 273: break; ! 274: } /* switch */ ! 275: } /* p1_addr */ ! 276: ! 277: ! 278: static void p1_list (listp) ! 279: struct Listblock *listp; ! 280: { ! 281: chainp lis; ! 282: int count = 0; ! 283: ! 284: if (listp == (struct Listblock *) NULL) ! 285: return; ! 286: ! 287: /* Count the number of parameters in the list */ ! 288: ! 289: for (lis = listp -> listp; lis; lis = lis -> nextp) ! 290: count++; ! 291: ! 292: p1putddd (P1_LIST, listp -> tag, listp -> vtype, count); ! 293: ! 294: for (lis = listp -> listp; lis; lis = lis -> nextp) ! 295: p1_expr ((expptr) lis -> datap); ! 296: ! 297: } /* p1_list */ ! 298: ! 299: ! 300: void p1_label (lab) ! 301: long lab; ! 302: { ! 303: if (parstate < INDATA) ! 304: earlylabs = mkchain((char *)lab, earlylabs); ! 305: else ! 306: p1putd (P1_LABEL, lab); ! 307: } ! 308: ! 309: ! 310: ! 311: static void p1_literal (memno) ! 312: long memno; ! 313: { ! 314: p1putd (P1_LITERAL, memno); ! 315: } /* p1_literal */ ! 316: ! 317: ! 318: void p1_if (expr) ! 319: expptr expr; ! 320: { ! 321: p1put (P1_IF); ! 322: p1_expr (expr); ! 323: } /* p1_if */ ! 324: ! 325: ! 326: ! 327: ! 328: void p1_elif (expr) ! 329: expptr expr; ! 330: { ! 331: p1put (P1_ELIF); ! 332: p1_expr (expr); ! 333: } /* p1_elif */ ! 334: ! 335: ! 336: ! 337: ! 338: void p1_else () ! 339: { ! 340: p1put (P1_ELSE); ! 341: } /* p1_else */ ! 342: ! 343: ! 344: ! 345: ! 346: void p1_endif () ! 347: { ! 348: p1put (P1_ENDIF); ! 349: } /* p1_endif */ ! 350: ! 351: ! 352: ! 353: ! 354: void p1else_end () ! 355: { ! 356: p1put (P1_ENDELSE); ! 357: } /* p1else_end */ ! 358: ! 359: ! 360: static void p1_big_addr (addrp) ! 361: Addrp addrp; ! 362: { ! 363: if (addrp == (Addrp) NULL) ! 364: return; ! 365: ! 366: p1putn (P1_ADDR, (int)sizeof(struct Addrblock), (char *) addrp); ! 367: p1_expr (addrp -> vleng); ! 368: p1_expr (addrp -> memoffset); ! 369: if (addrp->uname_tag == UNAM_NAME) ! 370: addrp->user.name->visused = 1; ! 371: } /* p1_big_addr */ ! 372: ! 373: ! 374: ! 375: static void p1_unary (e) ! 376: struct Exprblock *e; ! 377: { ! 378: if (e == (struct Exprblock *) NULL) ! 379: return; ! 380: ! 381: p1putdd (P1_EXPR, (int) e -> opcode, e -> vtype); ! 382: p1_expr (e -> vleng); ! 383: ! 384: switch (e -> opcode) { ! 385: case OPNEG: ! 386: case OPNEG1: ! 387: case OPNOT: ! 388: case OPABS: ! 389: case OPBITNOT: ! 390: case OPPREINC: ! 391: case OPPREDEC: ! 392: case OPADDR: ! 393: case OPIDENTITY: ! 394: case OPCHARCAST: ! 395: case OPDABS: ! 396: p1_expr(e -> leftp); ! 397: break; ! 398: default: ! 399: erri ("p1_unary: bad opcode '%d'", (int) e -> opcode); ! 400: break; ! 401: } /* switch */ ! 402: ! 403: } /* p1_unary */ ! 404: ! 405: ! 406: static void p1_binary (e) ! 407: struct Exprblock *e; ! 408: { ! 409: if (e == (struct Exprblock *) NULL) ! 410: return; ! 411: ! 412: p1putdd (P1_EXPR, e -> opcode, e -> vtype); ! 413: p1_expr (e -> vleng); ! 414: p1_expr (e -> leftp); ! 415: p1_expr (e -> rightp); ! 416: } /* p1_binary */ ! 417: ! 418: ! 419: void p1_head (class, name) ! 420: int class; ! 421: char *name; ! 422: { ! 423: p1putds (P1_HEAD, class, name ? name : ""); ! 424: } /* p1_head */ ! 425: ! 426: ! 427: void p1_subr_ret (retexp) ! 428: expptr retexp; ! 429: { ! 430: ! 431: p1put (P1_SUBR_RET); ! 432: p1_expr (cpexpr(retexp)); ! 433: } /* p1_subr_ret */ ! 434: ! 435: ! 436: ! 437: void p1comp_goto (index, count, labels) ! 438: expptr index; ! 439: int count; ! 440: struct Labelblock *labels[]; ! 441: { ! 442: struct Constblock c; ! 443: int i; ! 444: register struct Labelblock *L; ! 445: ! 446: p1put (P1_COMP_GOTO); ! 447: p1_expr (index); ! 448: ! 449: /* Write out a P1_LIST directly, to avoid the overhead of allocating a ! 450: list before it's needed HACK HACK HACK */ ! 451: ! 452: p1putddd (P1_LIST, TLIST, TYUNKNOWN, count); ! 453: c.vtype = TYLONG; ! 454: c.vleng = 0; ! 455: ! 456: for (i = 0; i < count; i++) { ! 457: L = labels[i]; ! 458: L->labused = 1; ! 459: c.Const.ci = L->stateno; ! 460: p1_const(&c); ! 461: } /* for i = 0 */ ! 462: } /* p1comp_goto */ ! 463: ! 464: ! 465: ! 466: void p1_for (init, test, inc) ! 467: expptr init, test, inc; ! 468: { ! 469: p1put (P1_FOR); ! 470: p1_expr (init); ! 471: p1_expr (test); ! 472: p1_expr (inc); ! 473: } /* p1_for */ ! 474: ! 475: ! 476: void p1for_end () ! 477: { ! 478: p1put (P1_ENDFOR); ! 479: } /* p1for_end */ ! 480: ! 481: ! 482: ! 483: ! 484: /* ---------------------------------------------------------------------- ! 485: The intermediate file actually gets written ONLY by the routines below. ! 486: To change the format of the file, you need only change these routines. ! 487: ---------------------------------------------------------------------- ! 488: */ ! 489: ! 490: ! 491: /* p1puts -- Put a typed string into the Pass 1 intermediate file. Assumes that ! 492: str contains no newlines and is null-terminated. */ ! 493: ! 494: void p1puts (type, str) ! 495: int type; ! 496: char *str; ! 497: { ! 498: fprintf (pass1_file, "%d: %s\n", type, str); ! 499: } /* p1puts */ ! 500: ! 501: ! 502: /* p1putd -- Put a typed integer into the Pass 1 intermediate file. */ ! 503: ! 504: static void p1putd (type, value) ! 505: int type; ! 506: long value; ! 507: { ! 508: fprintf (pass1_file, "%d: %ld\n", type, value); ! 509: } /* p1_putd */ ! 510: ! 511: ! 512: /* p1putdd -- Put a typed pair of integers into the intermediate file. */ ! 513: ! 514: static void p1putdd (type, v1, v2) ! 515: int type, v1, v2; ! 516: { ! 517: fprintf (pass1_file, "%d: %d %d\n", type, v1, v2); ! 518: } /* p1putdd */ ! 519: ! 520: ! 521: /* p1putddd -- Put a typed triple of integers into the intermediate file. */ ! 522: ! 523: static void p1putddd (type, v1, v2, v3) ! 524: int type, v1, v2, v3; ! 525: { ! 526: fprintf (pass1_file, "%d: %d %d %d\n", type, v1, v2, v3); ! 527: } /* p1putddd */ ! 528: ! 529: union dL { ! 530: double d; ! 531: long L[2]; ! 532: }; ! 533: ! 534: static void p1putn (type, count, str) ! 535: int type, count; ! 536: char *str; ! 537: { ! 538: int i; ! 539: ! 540: fprintf (pass1_file, "%d: ", type); ! 541: ! 542: for (i = 0; i < count; i++) ! 543: putc (str[i], pass1_file); ! 544: ! 545: putc ('\n', pass1_file); ! 546: } /* p1putn */ ! 547: ! 548: ! 549: ! 550: /* p1put -- Put a type marker into the intermediate file. */ ! 551: ! 552: void p1put(type) ! 553: int type; ! 554: { ! 555: fprintf (pass1_file, "%d:\n", type); ! 556: } /* p1put */ ! 557: ! 558: ! 559: ! 560: static void p1putds (type, i, str) ! 561: int type; ! 562: int i; ! 563: char *str; ! 564: { ! 565: fprintf (pass1_file, "%d: %d %s\n", type, i, str); ! 566: } /* p1putds */ ! 567: ! 568: ! 569: static void p1putdds (token, type, stg, str) ! 570: int token, type, stg; ! 571: char *str; ! 572: { ! 573: fprintf (pass1_file, "%d: %d %d %s\n", token, type, stg, str); ! 574: } /* p1putdds */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.