00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "defs.h"
00025 #include "names.h"
00026 #include "output.h"
00027
00028 #ifndef TRUE
00029 #define TRUE 1
00030 #endif
00031 #ifndef FALSE
00032 #define FALSE 0
00033 #endif
00034
00035 char _assoc_table[] = { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 };
00036
00037
00038
00039
00040
00041 table_entry opcode_table[] = {
00042 { 0, 0, NULL },
00043 { BINARY_OP, 12, "%l + %r" },
00044 { BINARY_OP, 12, "%l - %r" },
00045 { BINARY_OP, 13, "%l * %r" },
00046 { BINARY_OP, 13, "%l / %r" },
00047 { BINARY_OP, 0, "power (%l, %r)" },
00048 { UNARY_OP, 14, "-%l" },
00049 { BINARY_OP, 4, "%l || %r" },
00050 { BINARY_OP, 5, "%l && %r" },
00051 { BINARY_OP, 9, "%l == %r" },
00052 { BINARY_OP, 9, "%l != %r" },
00053 { UNARY_OP, 14, "! %l" },
00054 { BINARY_OP, 0, "concat (%l, %r)" },
00055 { BINARY_OP, 10, "%l < %r" },
00056 { BINARY_OP, 9, "%l == %r" },
00057 { BINARY_OP, 10, "%l > %r" },
00058 { BINARY_OP, 10, "%l <= %r" },
00059 { BINARY_OP, 9, "%l != %r" },
00060 { BINARY_OP, 10, "%l >= %r" },
00061 { BINARY_OP, 15, SPECIAL_FMT },
00062 { BINARY_OP, 15, SPECIAL_FMT },
00063
00064
00065
00066 { BINARY_OP, 2, "%l = %r" },
00067 { BINARY_OP, 2, "%l += %r" },
00068 { BINARY_OP, 2, "%l *= %r" },
00069 { BINARY_OP, 14, "%l" },
00070 { BINARY_OP, 11, "%l << %r" },
00071 { BINARY_OP, 13, "%l %% %r" },
00072 { BINARY_OP, 1, "%l, %r" },
00073
00074
00075
00076 { BINARY_OP, 3, "%l ? %r" },
00077 { BINARY_OP, 3, "%l : %r" },
00078 { UNARY_OP, 0, "abs(%l)" },
00079 { BINARY_OP, 0, SPECIAL_FMT },
00080 { BINARY_OP, 0, SPECIAL_FMT },
00081 { UNARY_OP, 14, "&%l" },
00082
00083 { BINARY_OP, 15, SPECIAL_FMT },
00084 { BINARY_OP, 6, "%l | %r" },
00085 { BINARY_OP, 8, "%l & %r" },
00086 { BINARY_OP, 7, "%l ^ %r" },
00087 { UNARY_OP, 14, "~ %l" },
00088 { BINARY_OP, 11, "%l >> %r" },
00089
00090
00091
00092 { UNARY_OP, 14, "*%l" },
00093 { BINARY_OP, 2, "%l -= %r" },
00094 { BINARY_OP, 2, "%l /= %r" },
00095 { BINARY_OP, 2, "%l %%= %r" },
00096 { BINARY_OP, 2, "%l <<= %r" },
00097 { BINARY_OP, 2, "%l >>= %r" },
00098 { BINARY_OP, 2, "%l &= %r" },
00099 { BINARY_OP, 2, "%l ^= %r" },
00100 { BINARY_OP, 2, "%l |= %r" },
00101 { UNARY_OP, 14, "++%l" },
00102 { UNARY_OP, 14, "--%l" },
00103 { BINARY_OP, 15, "%l.%r" },
00104 { BINARY_OP, 15, "%l -> %r"},
00105 { UNARY_OP, 14, "-%l" },
00106 { BINARY_OP, 0, "dmin(%l,%r)" },
00107 { BINARY_OP, 0, "dmax(%l,%r)" },
00108 { BINARY_OP, 2, "%l = &%r" },
00109 { UNARY_OP, 15, "%l" },
00110 { UNARY_OP, 14, "(char *)&%l" },
00111 { UNARY_OP, 0, "dabs(%l)" },
00112 { BINARY_OP, 0, "min(%l,%r)" },
00113 { BINARY_OP, 0, "max(%l,%r)" },
00114 { BINARY_OP, 0, "bit_test(%l,%r)" },
00115 { BINARY_OP, 0, "bit_clear(%l,%r)" },
00116 { BINARY_OP, 0, "bit_set(%l,%r)" },
00117 #ifdef TYQUAD
00118 { BINARY_OP, 0, "qbit_clear(%l,%r)" },
00119 { BINARY_OP, 0, "qbit_set(%l,%r)" },
00120 #endif
00121
00122
00123
00124 { UNARY_OP, 14, "-(doublereal)%l" }
00125 };
00126
00127 #define OPNEG_KLUDGE (sizeof(opcode_table)/sizeof(table_entry) - 1)
00128
00129 extern int dneg, trapuv;
00130 static char opeqable[sizeof(opcode_table)/sizeof(table_entry)];
00131
00132
00133 static void output_arg_list Argdcl((FILEP, struct Listblock*));
00134 static void output_binary Argdcl((FILEP, Exprp));
00135 static void output_list Argdcl((FILEP, struct Listblock*));
00136 static void output_literal Argdcl((FILEP, long, Constp));
00137 static void output_prim Argdcl((FILEP, struct Primblock*));
00138 static void output_unary Argdcl((FILEP, Exprp));
00139
00140
00141 void
00142 #ifdef KR_headers
00143 expr_out(fp, e)
00144 FILE *fp;
00145 expptr e;
00146 #else
00147 expr_out(FILE *fp, expptr e)
00148 #endif
00149 {
00150 Namep var;
00151 expptr leftp, rightp;
00152 int opcode;
00153
00154 if (e == (expptr) NULL)
00155 return;
00156
00157 switch (e -> tag) {
00158 case TNAME: out_name (fp, (struct Nameblock *) e);
00159 return;
00160
00161 case TCONST: out_const(fp, &e->constblock);
00162 goto end_out;
00163 case TEXPR:
00164 break;
00165
00166 case TADDR: out_addr (fp, &(e -> addrblock));
00167 goto end_out;
00168
00169 case TPRIM: if (!nerr)
00170 warn ("expr_out: got TPRIM");
00171 output_prim (fp, &(e -> primblock));
00172 return;
00173
00174 case TLIST: output_list (fp, &(e -> listblock));
00175 end_out: frexpr(e);
00176 return;
00177
00178 case TIMPLDO: err ("expr_out: got TIMPLDO");
00179 return;
00180
00181 case TERROR:
00182 default:
00183 erri ("expr_out: bad tag '%d'", e -> tag);
00184 }
00185
00186
00187
00188
00189
00190 if (e -> exprblock.opcode == OPASSIGN && e -> exprblock.rightp)
00191 switch(e->exprblock.rightp->tag) {
00192 case TEXPR:
00193 opcode = e -> exprblock.rightp -> exprblock.opcode;
00194
00195 if (opeqable[opcode]) {
00196 if ((leftp = e -> exprblock.leftp) &&
00197 (rightp = e -> exprblock.rightp -> exprblock.leftp)) {
00198
00199 if (same_ident (leftp, rightp)) {
00200 expptr temp = e -> exprblock.rightp;
00201
00202 e -> exprblock.opcode = op_assign(opcode);
00203
00204 e -> exprblock.rightp = temp -> exprblock.rightp;
00205 temp->exprblock.rightp = 0;
00206 frexpr(temp);
00207 }
00208 }
00209 }
00210 break;
00211
00212 case TNAME:
00213 if (trapuv) {
00214 var = &e->exprblock.rightp->nameblock;
00215 if (ISREAL(var->vtype)
00216 && var->vclass == CLVAR
00217 && ONEOF(var->vstg, M(STGAUTO)|M(STGBSS))
00218 && !var->vsave) {
00219 expr_out(fp, e -> exprblock.leftp);
00220 nice_printf(fp, " = _0 + ");
00221 expr_out(fp, e->exprblock.rightp);
00222 goto done;
00223 }
00224 }
00225 }
00226
00227
00228
00229
00230 {
00231 opcode = e -> exprblock.opcode;
00232 leftp = e -> exprblock.leftp;
00233 rightp = e -> exprblock.rightp;
00234
00235 if (leftp && rightp && (leftp -> headblock.vstg == STGARG ||
00236 ISINT (leftp -> headblock.vtype)) &&
00237 (opcode == OPPLUSEQ || opcode == OPMINUSEQ) &&
00238 ISINT (rightp -> headblock.vtype) &&
00239 ISICON (e -> exprblock.rightp) &&
00240 (ISONE (e -> exprblock.rightp) ||
00241 e -> exprblock.rightp -> constblock.Const.ci == -1)) {
00242
00243
00244
00245 if (!ISONE (e -> exprblock.rightp))
00246 opcode = (opcode == OPPLUSEQ) ? OPMINUSEQ : OPPLUSEQ;
00247
00248
00249
00250 if (opcode == OPPLUSEQ)
00251 e -> exprblock.opcode = OPPREINC;
00252 else
00253 e -> exprblock.opcode = OPPREDEC;
00254
00255
00256
00257 frexpr (e -> exprblock.rightp);
00258 e->exprblock.rightp = 0;
00259 }
00260 }
00261
00262
00263 if (is_unary_op (e -> exprblock.opcode))
00264 output_unary (fp, &(e -> exprblock));
00265 else if (is_binary_op (e -> exprblock.opcode))
00266 output_binary (fp, &(e -> exprblock));
00267 else
00268 erri ("expr_out: bad opcode '%d'", (int) e -> exprblock.opcode);
00269
00270 done:
00271 free((char *)e);
00272
00273 }
00274
00275
00276 void
00277 #ifdef KR_headers
00278 out_and_free_statement(outfile, expr)
00279 FILE *outfile;
00280 expptr expr;
00281 #else
00282 out_and_free_statement(FILE *outfile, expptr expr)
00283 #endif
00284 {
00285 if (expr)
00286 expr_out (outfile, expr);
00287
00288 nice_printf (outfile, ";\n");
00289 }
00290
00291
00292
00293 int
00294 #ifdef KR_headers
00295 same_ident(left, right)
00296 expptr left;
00297 expptr right;
00298 #else
00299 same_ident(expptr left, expptr right)
00300 #endif
00301 {
00302 if (!left || !right)
00303 return 0;
00304
00305 if (left -> tag == TNAME && right -> tag == TNAME && left == right)
00306 return 1;
00307
00308 if (left -> tag == TADDR && right -> tag == TADDR &&
00309 left -> addrblock.uname_tag == right -> addrblock.uname_tag)
00310 switch (left -> addrblock.uname_tag) {
00311 case UNAM_REF:
00312 case UNAM_NAME:
00313
00314
00315
00316 if (left -> addrblock.user.name -> vdim ||
00317 right -> addrblock.user.name -> vdim)
00318 if (left -> addrblock.user.name !=
00319 right -> addrblock.user.name ||
00320 !same_expr (left -> addrblock.memoffset,
00321 right -> addrblock.memoffset))
00322 return 0;
00323
00324 return same_ident ((expptr) (left -> addrblock.user.name),
00325 (expptr) right -> addrblock.user.name);
00326 case UNAM_IDENT:
00327 return strcmp(left->addrblock.user.ident,
00328 right->addrblock.user.ident) == 0;
00329 case UNAM_CHARP:
00330 return strcmp(left->addrblock.user.Charp,
00331 right->addrblock.user.Charp) == 0;
00332 default:
00333 return 0;
00334 }
00335
00336 if (left->tag == TEXPR && left->exprblock.opcode == OPWHATSIN
00337 && right->tag == TEXPR && right->exprblock.opcode == OPWHATSIN)
00338 return same_ident(left->exprblock.leftp,
00339 right->exprblock.leftp);
00340
00341 return 0;
00342 }
00343
00344 static int
00345 #ifdef KR_headers
00346 samefpconst(c1, c2, n)
00347 register Constp c1;
00348 register Constp c2;
00349 register int n;
00350 #else
00351 samefpconst(register Constp c1, register Constp c2, register int n)
00352 #endif
00353 {
00354 char *s1, *s2;
00355 if (!c1->vstg && !c2->vstg)
00356 return c1->Const.cd[n] == c2->Const.cd[n];
00357 s1 = c1->vstg ? c1->Const.cds[n] : dtos(c1->Const.cd[n]);
00358 s2 = c2->vstg ? c2->Const.cds[n] : dtos(c2->Const.cd[n]);
00359 return !strcmp(s1, s2);
00360 }
00361
00362 static int
00363 #ifdef KR_headers
00364 sameconst(c1, c2)
00365 register Constp c1;
00366 register Constp c2;
00367 #else
00368 sameconst(register Constp c1, register Constp c2)
00369 #endif
00370 {
00371 switch(c1->vtype) {
00372 case TYCOMPLEX:
00373 case TYDCOMPLEX:
00374 if (!samefpconst(c1,c2,1))
00375 return 0;
00376 case TYREAL:
00377 case TYDREAL:
00378 return samefpconst(c1,c2,0);
00379 case TYCHAR:
00380 return c1->Const.ccp1.blanks == c2->Const.ccp1.blanks
00381 && c1->vleng->constblock.Const.ci
00382 == c2->vleng->constblock.Const.ci
00383 && !memcmp(c1->Const.ccp, c2->Const.ccp,
00384 (int)c1->vleng->constblock.Const.ci);
00385 case TYSHORT:
00386 case TYINT:
00387 case TYLOGICAL:
00388 return c1->Const.ci == c2->Const.ci;
00389 }
00390 err("unexpected type in sameconst");
00391 return 0;
00392 }
00393
00394
00395
00396
00397
00398 int
00399 #ifdef KR_headers
00400 same_expr(e1, e2)
00401 expptr e1;
00402 expptr e2;
00403 #else
00404 same_expr(expptr e1, expptr e2)
00405 #endif
00406 {
00407 if (!e1 || !e2)
00408 return !e1 && !e2;
00409
00410 if (e1 -> tag != e2 -> tag || e1 -> headblock.vtype != e2 -> headblock.vtype)
00411 return 0;
00412
00413 switch (e1 -> tag) {
00414 case TEXPR:
00415 if (e1 -> exprblock.opcode != e2 -> exprblock.opcode)
00416 return 0;
00417
00418 return same_expr (e1 -> exprblock.leftp, e2 -> exprblock.leftp) &&
00419 same_expr (e1 -> exprblock.rightp, e2 -> exprblock.rightp);
00420 case TNAME:
00421 case TADDR:
00422 return same_ident (e1, e2);
00423 case TCONST:
00424 return sameconst(&e1->constblock, &e2->constblock);
00425 default:
00426 return 0;
00427 }
00428 }
00429
00430
00431
00432 void
00433 #ifdef KR_headers
00434 out_name(fp, namep)
00435 FILE *fp;
00436 Namep namep;
00437 #else
00438 out_name(FILE *fp, Namep namep)
00439 #endif
00440 {
00441 extern int usedefsforcommon;
00442 Extsym *comm;
00443
00444 if (namep == NULL)
00445 return;
00446
00447
00448
00449
00450 if (namep->vstg == STGCOMMON && !namep->vcommequiv && !usedefsforcommon) {
00451 comm = &extsymtab[namep->vardesc.varno];
00452 extern_out(fp, comm);
00453 nice_printf(fp, "%d.", comm->curno);
00454 }
00455
00456 if (namep->vprocclass == PTHISPROC && namep->vtype != TYSUBR)
00457 nice_printf(fp, xretslot[namep->vtype]->user.ident);
00458 else
00459 nice_printf (fp, "%s", namep->cvarname);
00460 }
00461
00462
00463 #define cpd(n) cp->vstg ? cp->Const.cds[n] : dtos(cp->Const.cd[n])
00464
00465 void
00466 #ifdef KR_headers
00467 out_const(fp, cp)
00468 FILE *fp;
00469 register Constp cp;
00470 #else
00471 out_const(FILE *fp, register Constp cp)
00472 #endif
00473 {
00474 static char real_buf[50], imag_buf[50];
00475 ftnint j;
00476 unsigned int k;
00477 int type = cp->vtype;
00478
00479 switch (type) {
00480 case TYINT1:
00481 case TYSHORT:
00482 nice_printf (fp, "%ld", cp->Const.ci);
00483 break;
00484 case TYLONG:
00485 #ifdef TYQUAD0
00486 case TYQUAD:
00487 #endif
00488 nice_printf (fp, "%ld", cp->Const.ci);
00489 break;
00490 #ifndef NO_LONG_LONG
00491 case TYQUAD:
00492 if (cp->Const.cd[1] == 123.456)
00493 nice_printf (fp, "%s", cp->Const.cds[0]);
00494 else
00495 nice_printf (fp, "%lld", cp->Const.cq);
00496 break;
00497 #endif
00498 case TYREAL:
00499 nice_printf(fp, "%s", flconst(real_buf, cpd(0)));
00500 break;
00501 case TYDREAL:
00502 nice_printf(fp, "%s", cpd(0));
00503 break;
00504 case TYCOMPLEX:
00505 nice_printf(fp, cm_fmt_string, flconst(real_buf, cpd(0)),
00506 flconst(imag_buf, cpd(1)));
00507 break;
00508 case TYDCOMPLEX:
00509 nice_printf(fp, dcm_fmt_string, cpd(0), cpd(1));
00510 break;
00511 case TYLOGICAL1:
00512 case TYLOGICAL2:
00513 case TYLOGICAL:
00514 nice_printf (fp, "%s", cp->Const.ci ? "TRUE_" : "FALSE_");
00515 break;
00516 case TYCHAR: {
00517 char *c = cp->Const.ccp, *ce;
00518
00519 if (c == NULL) {
00520 nice_printf (fp, "\"\"");
00521 break;
00522 }
00523
00524 nice_printf (fp, "\"");
00525 ce = c + cp->vleng->constblock.Const.ci;
00526 while(c < ce) {
00527 k = *(unsigned char *)c++;
00528 nice_printf(fp, str_fmt[k]);
00529 }
00530 for(j = cp->Const.ccp1.blanks; j > 0; j--)
00531 nice_printf(fp, " ");
00532 nice_printf (fp, "\"");
00533 break;
00534 }
00535 default:
00536 erri ("out_const: bad type '%d'", (int) type);
00537 break;
00538 }
00539
00540 }
00541 #undef cpd
00542
00543 static void
00544 #ifdef KR_headers
00545 out_args(fp, ep)
00546 FILE *fp;
00547 expptr ep;
00548 #else
00549 out_args(FILE *fp, expptr ep)
00550 #endif
00551 {
00552 chainp arglist;
00553
00554 if(ep->tag != TLIST)
00555 badtag("out_args", ep->tag);
00556 for(arglist = ep->listblock.listp;;) {
00557 expr_out(fp, (expptr)arglist->datap);
00558 arglist->datap = 0;
00559 if (!(arglist = arglist->nextp))
00560 break;
00561 nice_printf(fp, ", ");
00562 }
00563 }
00564
00565
00566
00567
00568
00569 void
00570 #ifdef KR_headers
00571 out_addr(fp, addrp)
00572 FILE *fp;
00573 struct Addrblock *addrp;
00574 #else
00575 out_addr(FILE *fp, struct Addrblock *addrp)
00576 #endif
00577 {
00578 extern Extsym *extsymtab;
00579 int was_array = 0;
00580 char *s;
00581
00582
00583 if (addrp == NULL)
00584 return;
00585 if (doin_setbound
00586 && addrp->vstg == STGARG
00587 && addrp->vtype != TYCHAR
00588 && ISICON(addrp->memoffset)
00589 && !addrp->memoffset->constblock.Const.ci)
00590 nice_printf(fp, "*");
00591
00592 switch (addrp -> uname_tag) {
00593 case UNAM_REF:
00594 nice_printf(fp, "%s_%s(", addrp->user.name->cvarname,
00595 addrp->cmplx_sub ? "subscr" : "ref");
00596 out_args(fp, addrp->memoffset);
00597 nice_printf(fp, ")");
00598 return;
00599 case UNAM_NAME:
00600 out_name (fp, addrp -> user.name);
00601 break;
00602 case UNAM_IDENT:
00603 if (*(s = addrp->user.ident) == ' ') {
00604 if (multitype)
00605 nice_printf(fp, "%s",
00606 xretslot[addrp->vtype]->user.ident);
00607 else
00608 nice_printf(fp, "%s", s+1);
00609 }
00610 else {
00611 nice_printf(fp, "%s", s);
00612 }
00613 break;
00614 case UNAM_CHARP:
00615 nice_printf(fp, "%s", addrp->user.Charp);
00616 break;
00617 case UNAM_EXTERN:
00618 extern_out (fp, &extsymtab[addrp -> memno]);
00619 break;
00620 case UNAM_CONST:
00621 switch(addrp->vstg) {
00622 case STGCONST:
00623 out_const(fp, (Constp)addrp);
00624 break;
00625 case STGMEMNO:
00626 output_literal (fp, addrp->memno,
00627 (Constp)addrp);
00628 break;
00629 default:
00630 Fatal("unexpected vstg in out_addr");
00631 }
00632 break;
00633 case UNAM_UNKNOWN:
00634 default:
00635 nice_printf (fp, "Unknown Addrp");
00636 break;
00637 }
00638
00639
00640
00641
00642 if ((addrp->uname_tag == UNAM_NAME && addrp->user.name->vdim
00643 || addrp->ntempelt > 1 || addrp->isarray)
00644 && addrp->vtype != TYCHAR) {
00645 expptr offset;
00646
00647 was_array = 1;
00648
00649 offset = addrp -> memoffset;
00650 addrp->memoffset = 0;
00651 if (ONEOF(addrp->vstg, M(STGCOMMON)|M(STGEQUIV))
00652 && addrp -> uname_tag == UNAM_NAME
00653 && !addrp->skip_offset)
00654 offset = mkexpr (OPMINUS, offset, mkintcon (
00655 addrp -> user.name -> voffset));
00656
00657 nice_printf (fp, "[");
00658
00659 offset = mkexpr (OPSLASH, offset,
00660 ICON (typesize[addrp -> vtype] * (addrp -> Field ? 2 : 1)));
00661 expr_out (fp, offset);
00662 nice_printf (fp, "]");
00663 }
00664
00665
00666
00667 if (addrp -> Field && addrp -> uname_tag != UNAM_CONST &&
00668 addrp -> uname_tag != UNAM_UNKNOWN) {
00669 if (oneof_stg((addrp -> uname_tag == UNAM_NAME ? addrp -> user.name :
00670 (Namep) NULL), addrp -> vstg, M(STGARG)|M(STGEQUIV))
00671 && !was_array && (addrp->vclass != CLPROC || !multitype))
00672 nice_printf (fp, "->%s", addrp -> Field);
00673 else
00674 nice_printf (fp, ".%s", addrp -> Field);
00675 }
00676
00677
00678
00679 if (addrp->vtype == TYCHAR &&
00680 (addrp->vclass != CLPROC || addrp->uname_tag == UNAM_NAME
00681 && addrp->user.name->vprocclass == PTHISPROC) &&
00682 addrp -> memoffset &&
00683 (addrp -> uname_tag != UNAM_NAME ||
00684 addrp -> user.name -> vtype == TYCHAR) &&
00685 (!ISICON (addrp -> memoffset) ||
00686 (addrp -> memoffset -> constblock.Const.ci))) {
00687
00688 int use_paren = 0;
00689 expptr e = addrp -> memoffset;
00690
00691 if (!e)
00692 return;
00693 addrp->memoffset = 0;
00694
00695 if (ONEOF(addrp->vstg, M(STGCOMMON)|M(STGEQUIV))
00696 && addrp -> uname_tag == UNAM_NAME) {
00697 e = mkexpr (OPMINUS, e, mkintcon (addrp -> user.name -> voffset));
00698
00699
00700 if (e->tag == TCONST && e->constblock.Const.ci == 0)
00701 return;
00702 }
00703
00704
00705
00706
00707
00708
00709 nice_printf (fp, " + ");
00710 if (e -> tag == TEXPR) {
00711 int arg_prec = op_precedence (e -> exprblock.opcode);
00712 int prec = op_precedence (OPPLUS);
00713 use_paren = arg_prec && (arg_prec < prec || (arg_prec == prec &&
00714 is_left_assoc (OPPLUS)));
00715 }
00716 if (use_paren) nice_printf (fp, "(");
00717 expr_out (fp, e);
00718 if (use_paren) nice_printf (fp, ")");
00719 }
00720 }
00721
00722
00723 static void
00724 #ifdef KR_headers
00725 output_literal(fp, memno, cp)
00726 FILE *fp;
00727 long memno;
00728 Constp cp;
00729 #else
00730 output_literal(FILE *fp, long memno, Constp cp)
00731 #endif
00732 {
00733 struct Literal *litp, *lastlit;
00734
00735 lastlit = litpool + nliterals;
00736
00737 for (litp = litpool; litp < lastlit; litp++) {
00738 if (litp -> litnum == memno)
00739 break;
00740 }
00741
00742 if (litp >= lastlit)
00743 out_const (fp, cp);
00744 else {
00745 nice_printf (fp, "%s", lit_name (litp));
00746 litp->lituse++;
00747 }
00748 }
00749
00750
00751 static void
00752 #ifdef KR_headers
00753 output_prim(fp, primp)
00754 FILE *fp;
00755 struct Primblock *primp;
00756 #else
00757 output_prim(FILE *fp, struct Primblock *primp)
00758 #endif
00759 {
00760 if (primp == NULL)
00761 return;
00762
00763 out_name (fp, primp -> namep);
00764 if (primp -> argsp)
00765 output_arg_list (fp, primp -> argsp);
00766
00767 if (primp -> fcharp != (expptr) NULL || primp -> lcharp != (expptr) NULL)
00768 nice_printf (fp, "Sorry, no substrings yet");
00769 }
00770
00771
00772
00773 static void
00774 #ifdef KR_headers
00775 output_arg_list(fp, listp)
00776 FILE *fp;
00777 struct Listblock *listp;
00778 #else
00779 output_arg_list(FILE *fp, struct Listblock *listp)
00780 #endif
00781 {
00782 chainp arg_list;
00783
00784 if (listp == (struct Listblock *) NULL || listp -> listp == (chainp) NULL)
00785 return;
00786
00787 nice_printf (fp, "(");
00788
00789 for (arg_list = listp -> listp; arg_list; arg_list = arg_list -> nextp) {
00790 expr_out (fp, (expptr) arg_list -> datap);
00791 if (arg_list -> nextp != (chainp) NULL)
00792
00793
00794
00795
00796 nice_printf (fp, ",");
00797 }
00798
00799 nice_printf (fp, ")");
00800 }
00801
00802
00803
00804 static void
00805 #ifdef KR_headers
00806 output_unary(fp, e)
00807 FILE *fp;
00808 struct Exprblock *e;
00809 #else
00810 output_unary(FILE *fp, struct Exprblock *e)
00811 #endif
00812 {
00813 if (e == NULL)
00814 return;
00815
00816 switch (e -> opcode) {
00817 case OPNEG:
00818 if (e->vtype == TYREAL && dneg) {
00819 e->opcode = OPNEG_KLUDGE;
00820 output_binary(fp,e);
00821 e->opcode = OPNEG;
00822 break;
00823 }
00824 case OPNEG1:
00825 case OPNOT:
00826 case OPABS:
00827 case OPBITNOT:
00828 case OPWHATSIN:
00829 case OPPREINC:
00830 case OPPREDEC:
00831 case OPADDR:
00832 case OPIDENTITY:
00833 case OPCHARCAST:
00834 case OPDABS:
00835 output_binary (fp, e);
00836 break;
00837 case OPCALL:
00838 case OPCCALL:
00839 nice_printf (fp, "Sorry, no OPCALL yet");
00840 break;
00841 default:
00842 erri ("output_unary: bad opcode", (int) e -> opcode);
00843 break;
00844 }
00845 }
00846
00847
00848 static char *
00849 #ifdef KR_headers
00850 findconst(m)
00851 register long m;
00852 #else
00853 findconst(register long m)
00854 #endif
00855 {
00856 register struct Literal *litp, *litpe;
00857
00858 litp = litpool;
00859 for(litpe = litp + nliterals; litp < litpe; litp++)
00860 if (litp->litnum == m)
00861 return litp->cds[0];
00862 Fatal("findconst failure!");
00863 return 0;
00864 }
00865
00866 static int
00867 #ifdef KR_headers
00868 opconv_fudge(fp, e)
00869 FILE *fp;
00870 struct Exprblock *e;
00871 #else
00872 opconv_fudge(FILE *fp, struct Exprblock *e)
00873 #endif
00874 {
00875
00876 register expptr lp;
00877 register union Expression *Offset;
00878 register char *cp;
00879 int lt;
00880 char buf[8], *s;
00881 unsigned int k;
00882 Namep np;
00883 Addrp ap;
00884
00885 if (!(lp = e->leftp))
00886 return 1;
00887 lt = lp->headblock.vtype;
00888 if (lt == TYCHAR) {
00889 switch(lp->tag) {
00890 case TNAME:
00891 nice_printf(fp, "*(unsigned char *)");
00892 out_name(fp, (Namep)lp);
00893 return 1;
00894 case TCONST:
00895 tconst:
00896 cp = lp->constblock.Const.ccp;
00897 tconst1:
00898 k = *(unsigned char *)cp;
00899 if (k < 128) {
00900 sprintf(buf, chr_fmt[k], k);
00901 nice_printf(fp, "'%s'", buf);
00902 }
00903 else
00904 nice_printf(fp, "%d", k);
00905 return 1;
00906 case TADDR:
00907 switch(lp->addrblock.vstg) {
00908 case STGMEMNO:
00909 if (halign && e->vtype != TYCHAR) {
00910 nice_printf(fp, "*(%s *)",
00911 c_type_decl(e->vtype,0));
00912 expr_out(fp, lp);
00913 return 1;
00914 }
00915 cp = findconst(lp->addrblock.memno);
00916 goto tconst1;
00917 case STGCONST:
00918 goto tconst;
00919 }
00920 lp->addrblock.vtype = tyint;
00921 Offset = lp->addrblock.memoffset;
00922 switch(lp->addrblock.uname_tag) {
00923 case UNAM_REF:
00924 nice_printf(fp, "*(unsigned char *)");
00925 return 0;
00926 case UNAM_NAME:
00927 np = lp->addrblock.user.name;
00928 if (ONEOF(np->vstg,
00929 M(STGCOMMON)|M(STGEQUIV)))
00930 Offset = mkexpr(OPMINUS, Offset,
00931 ICON(np->voffset));
00932 }
00933 lp->addrblock.memoffset = Offset ?
00934 mkexpr(OPSTAR, Offset,
00935 ICON(typesize[tyint]))
00936 : ICON(0);
00937 lp->addrblock.isarray = 1;
00938
00939
00940 lp->addrblock.vstg = STGUNKNOWN;
00941 nice_printf(fp, "*(unsigned char *)&");
00942 return 0;
00943 default:
00944 badtag("opconv_fudge", lp->tag);
00945 }
00946 }
00947 if (lt != e->vtype) {
00948 s = c_type_decl(e->vtype, 0);
00949 if (ISCOMPLEX(lt)) {
00950 tryagain:
00951 np = (Namep)e->leftp;
00952 switch(np->tag) {
00953 case TNAME:
00954 nice_printf(fp, "(%s) %s%sr", s,
00955 np->cvarname,
00956 np->vstg == STGARG ? "->" : ".");
00957 return 1;
00958 case TADDR:
00959 ap = (Addrp)np;
00960 switch(ap->uname_tag) {
00961 case UNAM_IDENT:
00962 nice_printf(fp, "(%s) %s.r", s,
00963 ap->user.ident);
00964 return 1;
00965 case UNAM_NAME:
00966 nice_printf(fp, "(%s) ", s);
00967 out_addr(fp, ap);
00968 nice_printf(fp, ".r");
00969 return 1;
00970 case UNAM_REF:
00971 nice_printf(fp, "(%s) %s_%s(",
00972 s, ap->user.name->cvarname,
00973 ap->cmplx_sub ? "subscr" : "ref");
00974 out_args(fp, ap->memoffset);
00975 nice_printf(fp, ").r");
00976 return 1;
00977 default:
00978 fatali(
00979 "Bad uname_tag %d in opconv_fudge",
00980 ap->uname_tag);
00981 }
00982 case TEXPR:
00983 e = (Exprp)np;
00984 if (e->opcode == OPWHATSIN)
00985 goto tryagain;
00986 default:
00987 fatali("Unexpected tag %d in opconv_fudge",
00988 np->tag);
00989 }
00990 }
00991 nice_printf(fp, "(%s) ", s);
00992 }
00993 return 0;
00994 }
00995
00996
00997 static void
00998 #ifdef KR_headers
00999 output_binary(fp, e)
01000 FILE *fp;
01001 struct Exprblock *e;
01002 #else
01003 output_binary(FILE *fp, struct Exprblock *e)
01004 #endif
01005 {
01006 char *format;
01007 int prec;
01008
01009 if (e == NULL || e -> tag != TEXPR)
01010 return;
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 if ((e -> opcode == OPPLUS || e -> opcode == OPMINUS) &&
01028 e -> rightp && e -> rightp -> tag == TCONST &&
01029 isnegative_const (&(e -> rightp -> constblock)) &&
01030 is_negatable (&(e -> rightp -> constblock))) {
01031
01032 e -> opcode = (e -> opcode == OPPLUS) ? OPMINUS : OPPLUS;
01033 negate_const (&(e -> rightp -> constblock));
01034 }
01035
01036 prec = op_precedence (e -> opcode);
01037 format = op_format (e -> opcode);
01038
01039 if (format != SPECIAL_FMT) {
01040 while (*format) {
01041 if (*format == '%') {
01042 int arg_prec, use_paren = 0;
01043 expptr lp, rp;
01044
01045 switch (*(format + 1)) {
01046 case 'l':
01047 lp = e->leftp;
01048 if (lp && lp->tag == TEXPR) {
01049 arg_prec = op_precedence(lp->exprblock.opcode);
01050
01051 use_paren = arg_prec &&
01052 (arg_prec < prec || (arg_prec == prec &&
01053 is_right_assoc (prec)));
01054 }
01055 if (e->opcode == OPCONV && opconv_fudge(fp,e))
01056 break;
01057 if (use_paren)
01058 nice_printf (fp, "(");
01059 expr_out(fp, lp);
01060 if (use_paren)
01061 nice_printf (fp, ")");
01062 break;
01063 case 'r':
01064 rp = e->rightp;
01065 if (rp && rp->tag == TEXPR) {
01066 arg_prec = op_precedence(rp->exprblock.opcode);
01067
01068 use_paren = arg_prec &&
01069 (arg_prec < prec || (arg_prec == prec &&
01070 is_left_assoc (prec)));
01071 use_paren = use_paren ||
01072 (rp->exprblock.opcode == OPNEG
01073 && prec >= op_precedence(OPMINUS));
01074 }
01075 if (use_paren)
01076 nice_printf (fp, "(");
01077 expr_out(fp, rp);
01078 if (use_paren)
01079 nice_printf (fp, ")");
01080 break;
01081 case '\0':
01082 case '%':
01083 nice_printf (fp, "%%");
01084 break;
01085 default:
01086 erri ("output_binary: format err: '%%%c' illegal",
01087 (int) *(format + 1));
01088 break;
01089 }
01090 format += 2;
01091 } else
01092 nice_printf (fp, "%c", *format++);
01093 }
01094 } else {
01095
01096
01097
01098 switch (e -> opcode) {
01099 case OPCCALL:
01100 case OPCALL:
01101 out_call (fp, (int) e -> opcode, e -> vtype,
01102 e -> vleng, e -> leftp, e -> rightp);
01103 break;
01104
01105 case OPCOMMA_ARG:
01106 doin_setbound = 1;
01107 nice_printf(fp, "(");
01108 expr_out(fp, e->leftp);
01109 nice_printf(fp, ", &");
01110 doin_setbound = 0;
01111 expr_out(fp, e->rightp);
01112 nice_printf(fp, ")");
01113 break;
01114
01115 case OPADDR:
01116 default:
01117 nice_printf (fp, "Sorry, can't format OPCODE '%d'",
01118 e -> opcode);
01119 break;
01120 }
01121
01122 }
01123 }
01124
01125 void
01126 #ifdef KR_headers
01127 out_call(outfile, op, ftype, len, name, args)
01128 FILE *outfile;
01129 int op;
01130 int ftype;
01131 expptr len;
01132 expptr name;
01133 expptr args;
01134 #else
01135 out_call(FILE *outfile, int op, int ftype, expptr len, expptr name, expptr args)
01136 #endif
01137 {
01138 chainp arglist;
01139 chainp cp;
01140 Addrp ret_val = (Addrp) NULL;
01141
01142
01143 int byvalue;
01144
01145 int done_once;
01146 int narg, t;
01147 register expptr q;
01148 long L;
01149 Argtypes *at;
01150 Atype *A, *Ac;
01151 Namep np;
01152 extern int forcereal;
01153
01154
01155
01156 byvalue = op == OPCCALL;
01157
01158 if (args)
01159 arglist = args -> listblock.listp;
01160 else
01161 arglist = CHNULL;
01162
01163
01164
01165 if (ftype == TYCHAR)
01166 if (ISICON (len)) {
01167 ret_val = (Addrp) (arglist -> datap);
01168 arglist = arglist -> nextp;
01169 } else {
01170 err ("adjustable character function");
01171 return;
01172 }
01173
01174
01175
01176 else if (ISCOMPLEX (ftype)) {
01177 ret_val = (Addrp) (arglist -> datap);
01178 arglist = arglist -> nextp;
01179 }
01180
01181
01182 np = name->tag == TEXPR && name->exprblock.opcode == OPWHATSIN
01183 ? (Namep)name->exprblock.leftp : (Namep)name;
01184
01185 A = Ac = 0;
01186 if (np->tag == TNAME && (at = np->arginfo)) {
01187 if (at->nargs > 0)
01188 A = at->atypes;
01189 if (Ansi && (at->defined || at->nargs > 0))
01190 Ac = at->atypes;
01191 }
01192
01193
01194
01195 if (ftype == TYREAL && forcereal)
01196 nice_printf(outfile, "(real)");
01197 if (name -> tag == TEXPR && name -> exprblock.opcode == OPWHATSIN) {
01198 nice_printf (outfile, "(");
01199 expr_out (outfile, name);
01200 nice_printf (outfile, ")");
01201 }
01202 else
01203 expr_out(outfile, name);
01204
01205 nice_printf(outfile, "(");
01206
01207 if (ret_val) {
01208 if (ISCOMPLEX (ftype))
01209 nice_printf (outfile, "&");
01210 expr_out (outfile, (expptr) ret_val);
01211 if (Ac)
01212 Ac++;
01213
01214
01215
01216
01217 }
01218 done_once = ret_val ? TRUE : FALSE;
01219
01220
01221
01222 narg = -1;
01223 for (cp = arglist; cp; cp = cp -> nextp, done_once = TRUE) {
01224
01225 if (done_once)
01226 nice_printf (outfile, ", ");
01227 narg++;
01228
01229 if (!( q = (expptr)cp->datap) )
01230 continue;
01231
01232 if (q->tag == TADDR) {
01233 if (q->addrblock.vtype > TYERROR) {
01234
01235 nice_printf(outfile, "&%s", q->addrblock.user.ident);
01236 continue;
01237 }
01238 if (!byvalue && q->addrblock.isarray
01239 && q->addrblock.vtype != TYCHAR
01240 && q->addrblock.memoffset->tag == TCONST) {
01241
01242
01243
01244 L = q->addrblock.memoffset->constblock.Const.ci;
01245 if (ONEOF(q->addrblock.vstg, M(STGCOMMON)|M(STGEQUIV))
01246 && q->addrblock.uname_tag == UNAM_NAME)
01247 L -= q->addrblock.user.name->voffset;
01248 if (L)
01249 goto skip_deref;
01250
01251 if (Ac && narg < at->dnargs
01252 && q->headblock.vtype != (t = Ac[narg].type)
01253 && t > TYADDR && t < TYSUBR)
01254 nice_printf(outfile, "(%s*)", Typename[t]);
01255
01256
01257
01258
01259 switch(q->addrblock.uname_tag) {
01260 case UNAM_NAME:
01261 out_name(outfile, q->addrblock.user.name);
01262 continue;
01263 case UNAM_IDENT:
01264 nice_printf(outfile, "%s",
01265 q->addrblock.user.ident);
01266 continue;
01267 case UNAM_CHARP:
01268 nice_printf(outfile, "%s",
01269 q->addrblock.user.Charp);
01270 continue;
01271 case UNAM_EXTERN:
01272 extern_out(outfile,
01273 &extsymtab[q->addrblock.memno]);
01274 continue;
01275 }
01276 }
01277 }
01278
01279
01280
01281 skip_deref:
01282 if (q -> tag == TEXPR && q -> exprblock.opcode == OPWHATSIN)
01283 q = q -> exprblock.leftp;
01284
01285 if (q->headblock.vclass == CLPROC) {
01286 if (Castargs && (q->tag != TNAME
01287 || q->nameblock.vprocclass != PTHISPROC)
01288 && (q->tag != TADDR
01289 || q->addrblock.uname_tag != UNAM_NAME
01290 || q->addrblock.user.name->vprocclass
01291 != PTHISPROC))
01292 {
01293 if (A && (t = A[narg].type) >= 200)
01294 t %= 100;
01295 else {
01296 t = q->headblock.vtype;
01297 if (q->tag == TNAME && q->nameblock.vimpltype)
01298 t = TYUNKNOWN;
01299 }
01300 nice_printf(outfile, "(%s)", usedcasts[t] = casttypes[t]);
01301 }
01302 }
01303 else if (Ac && narg < at->dnargs
01304 && q->headblock.vtype != (t = Ac[narg].type)
01305 && t > TYADDR && t < TYSUBR)
01306 nice_printf(outfile, "(%s*)", Typename[t]);
01307
01308 if ((q -> tag == TADDR || q-> tag == TNAME) &&
01309 (byvalue || q -> headblock.vstg != STGREG)) {
01310 if (q -> headblock.vtype != TYCHAR)
01311 if (byvalue) {
01312
01313 if (q -> tag == TADDR &&
01314 q -> addrblock.uname_tag == UNAM_NAME &&
01315 ! q -> addrblock.user.name -> vdim &&
01316 oneof_stg(q -> addrblock.user.name, q -> addrblock.vstg,
01317 M(STGARG)|M(STGEQUIV)) &&
01318 ! ISCOMPLEX(q->addrblock.user.name->vtype))
01319 nice_printf (outfile, "*");
01320 else if (q -> tag == TNAME
01321 && oneof_stg(&q->nameblock, q -> nameblock.vstg,
01322 M(STGARG)|M(STGEQUIV))
01323 && !(q -> nameblock.vdim))
01324 nice_printf (outfile, "*");
01325
01326 } else {
01327 expptr memoffset;
01328
01329 if (q->tag == TADDR && (
01330 !ONEOF (q -> addrblock.vstg, M(STGEXT)|M(STGLENG))
01331 && (ONEOF(q->addrblock.vstg,
01332 M(STGCOMMON)|M(STGEQUIV)|M(STGMEMNO))
01333 || ((memoffset = q->addrblock.memoffset)
01334 && (!ISICON(memoffset)
01335 || memoffset->constblock.Const.ci)))
01336 || ONEOF(q->addrblock.vstg,
01337 M(STGINIT)|M(STGAUTO)|M(STGBSS))
01338 && !q->addrblock.isarray))
01339 nice_printf (outfile, "&");
01340 else if (q -> tag == TNAME
01341 && !oneof_stg(&q->nameblock, q -> nameblock.vstg,
01342 M(STGARG)|M(STGEXT)|M(STGEQUIV)))
01343 nice_printf (outfile, "&");
01344 }
01345
01346 expr_out (outfile, q);
01347 }
01348
01349
01350
01351 else if (q -> tag == TCONST) {
01352 if (q->constblock.vtype == TYLONG)
01353 nice_printf(outfile, "(ftnlen)%ld",
01354 q->constblock.Const.ci);
01355 else
01356 out_const(outfile, &q->constblock);
01357 }
01358
01359
01360
01361
01362
01363 else if (!ISCOMPLEX (q -> headblock.vtype) && !ISCHAR (q)){
01364 int use_paren = q -> tag == TEXPR &&
01365 op_precedence (q -> exprblock.opcode) <=
01366 op_precedence (OPCOMMA);
01367 if (q->headblock.vtype == TYREAL) {
01368 if (forcereal) {
01369 nice_printf(outfile, "(real)");
01370 use_paren = 1;
01371 }
01372 }
01373 else if (!Ansi && ISINT(q->headblock.vtype)) {
01374 nice_printf(outfile, "(ftnlen)");
01375 use_paren = 1;
01376 }
01377 if (use_paren) nice_printf (outfile, "(");
01378 expr_out (outfile, q);
01379 if (use_paren) nice_printf (outfile, ")");
01380 }
01381 else
01382 err ("out_call: unknown parameter");
01383
01384 }
01385
01386 if (arglist)
01387 frchain (&arglist);
01388
01389 nice_printf (outfile, ")");
01390
01391 }
01392
01393
01394 char *
01395 #ifdef KR_headers
01396 flconst(buf, x)
01397 char *buf;
01398 char *x;
01399 #else
01400 flconst(char *buf, char *x)
01401 #endif
01402 {
01403 sprintf(buf, fl_fmt_string, x);
01404 return buf;
01405 }
01406
01407 char *
01408 #ifdef KR_headers
01409 dtos(x)
01410 double x;
01411 #else
01412 dtos(double x)
01413 #endif
01414 {
01415 static char buf[64];
01416 #ifdef USE_DTOA
01417 g_fmt(buf, x);
01418 #else
01419 sprintf(buf, db_fmt_string, x);
01420 #endif
01421 return strcpy(mem(strlen(buf)+1,0), buf);
01422 }
01423
01424 char tr_tab[Table_size];
01425
01426
01427
01428
01429
01430 void
01431 out_init(Void)
01432 {
01433 extern int tab_size;
01434 register char *s;
01435
01436 s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+-.";
01437 while(*s)
01438 tr_tab[*s++] = 3;
01439 tr_tab['>'] = 1;
01440
01441 opeqable[OPPLUS] = 1;
01442 opeqable[OPMINUS] = 1;
01443 opeqable[OPSTAR] = 1;
01444 opeqable[OPSLASH] = 1;
01445 opeqable[OPMOD] = 1;
01446 opeqable[OPLSHIFT] = 1;
01447 opeqable[OPBITAND] = 1;
01448 opeqable[OPBITXOR] = 1;
01449 opeqable[OPBITOR ] = 1;
01450
01451
01452
01453
01454 if (fl_fmt_string == NULL || *fl_fmt_string == '\0')
01455 fl_fmt_string = (char*)(Ansi == 1 ? "%sf" : "(float)%s");
01456
01457 if (db_fmt_string == NULL || *db_fmt_string == '\0')
01458 db_fmt_string = "%.17g";
01459
01460
01461
01462
01463
01464
01465 if (cm_fmt_string == NULL || *cm_fmt_string == '\0') {
01466 cm_fmt_string = "{%s,%s}";
01467 }
01468
01469 if (dcm_fmt_string == NULL || *dcm_fmt_string == '\0') {
01470 dcm_fmt_string = "{%s,%s}";
01471 }
01472
01473 tab_size = 4;
01474 }
01475
01476
01477 void
01478 #ifdef KR_headers
01479 extern_out(fp, extsym)
01480 FILE *fp;
01481 Extsym *extsym;
01482 #else
01483 extern_out(FILE *fp, Extsym *extsym)
01484 #endif
01485 {
01486 if (extsym == (Extsym *) NULL)
01487 return;
01488
01489 nice_printf (fp, "%s", extsym->cextname);
01490
01491 }
01492
01493
01494
01495 static void
01496 #ifdef KR_headers
01497 output_list(fp, listp)
01498 FILE *fp;
01499 struct Listblock *listp;
01500 #else
01501 output_list(FILE *fp, struct Listblock *listp)
01502 #endif
01503 {
01504 int did_one = 0;
01505 chainp elts;
01506
01507 nice_printf (fp, "(");
01508 if (listp)
01509 for (elts = listp -> listp; elts; elts = elts -> nextp) {
01510 if (elts -> datap) {
01511 if (did_one)
01512 nice_printf (fp, ", ");
01513 expr_out (fp, (expptr) elts -> datap);
01514 did_one = 1;
01515 }
01516 }
01517 nice_printf (fp, ")");
01518 }
01519
01520
01521 void
01522 #ifdef KR_headers
01523 out_asgoto(outfile, expr)
01524 FILE *outfile;
01525 expptr expr;
01526 #else
01527 out_asgoto(FILE *outfile, expptr expr)
01528 #endif
01529 {
01530 chainp value;
01531 Namep namep;
01532 int k;
01533
01534 if (expr == (expptr) NULL) {
01535 err ("out_asgoto: NULL variable expr");
01536 return;
01537 }
01538
01539 nice_printf (outfile, Ansi ? "switch (" : "switch ((int)");
01540 expr_out (outfile, expr);
01541 nice_printf (outfile, ") {\n");
01542 next_tab (outfile);
01543
01544
01545
01546 switch(expr->tag) {
01547 case TNAME:
01548
01549 namep = &expr->nameblock;
01550 break;
01551 case TEXPR:
01552 if (expr->exprblock.opcode == OPWHATSIN
01553 && expr->exprblock.leftp->tag == TNAME)
01554
01555 namep = &expr->exprblock.leftp->nameblock;
01556 else
01557 goto bad;
01558 break;
01559 case TADDR:
01560 if (expr->addrblock.uname_tag == UNAM_NAME) {
01561
01562 namep = expr->addrblock.user.name;
01563 break;
01564 }
01565 default:
01566 bad:
01567 err("out_asgoto: bad expr");
01568 return;
01569 }
01570
01571 for(k = 0, value = namep -> varxptr.assigned_values; value;
01572 value = value->nextp, k++) {
01573 nice_printf (outfile, "case %d: goto %s;\n", k,
01574 user_label((long)value->datap));
01575 }
01576 prev_tab (outfile);
01577
01578 nice_printf (outfile, "}\n");
01579 }
01580
01581 void
01582 #ifdef KR_headers
01583 out_if(outfile, expr)
01584 FILE *outfile;
01585 expptr expr;
01586 #else
01587 out_if(FILE *outfile, expptr expr)
01588 #endif
01589 {
01590 nice_printf (outfile, "if (");
01591 expr_out (outfile, expr);
01592 nice_printf (outfile, ") {\n");
01593 next_tab (outfile);
01594 }
01595
01596 static void
01597 #ifdef KR_headers
01598 output_rbrace(outfile, s)
01599 FILE *outfile;
01600 char *s;
01601 #else
01602 output_rbrace(FILE *outfile, char *s)
01603 #endif
01604 {
01605 extern int last_was_label;
01606 register char *fmt;
01607
01608 if (last_was_label) {
01609 last_was_label = 0;
01610 fmt = ";%s";
01611 }
01612 else
01613 fmt = "%s";
01614 nice_printf(outfile, fmt, s);
01615 }
01616
01617 void
01618 #ifdef KR_headers
01619 out_else(outfile)
01620 FILE *outfile;
01621 #else
01622 out_else(FILE *outfile)
01623 #endif
01624 {
01625 prev_tab (outfile);
01626 output_rbrace(outfile, "} else {\n");
01627 next_tab (outfile);
01628 }
01629
01630 void
01631 #ifdef KR_headers
01632 elif_out(outfile, expr)
01633 FILE *outfile;
01634 expptr expr;
01635 #else
01636 elif_out(FILE *outfile, expptr expr)
01637 #endif
01638 {
01639 prev_tab (outfile);
01640 output_rbrace(outfile, "} else ");
01641 out_if (outfile, expr);
01642 }
01643
01644 void
01645 #ifdef KR_headers
01646 endif_out(outfile)
01647 FILE *outfile;
01648 #else
01649 endif_out(FILE *outfile)
01650 #endif
01651 {
01652 prev_tab (outfile);
01653 output_rbrace(outfile, "}\n");
01654 }
01655
01656 void
01657 #ifdef KR_headers
01658 end_else_out(outfile)
01659 FILE *outfile;
01660 #else
01661 end_else_out(FILE *outfile)
01662 #endif
01663 {
01664 prev_tab (outfile);
01665 output_rbrace(outfile, "}\n");
01666 }
01667
01668
01669
01670 void
01671 #ifdef KR_headers
01672 compgoto_out(outfile, index, labels)
01673 FILE *outfile;
01674 expptr index;
01675 expptr labels;
01676 #else
01677 compgoto_out(FILE *outfile, expptr index, expptr labels)
01678 #endif
01679 {
01680 char *s1, *s2;
01681
01682 if (index == ENULL)
01683 err ("compgoto_out: null index for computed goto");
01684 else if (labels && labels -> tag != TLIST)
01685 erri ("compgoto_out: expected label list, got tag '%d'",
01686 labels -> tag);
01687 else {
01688 chainp elts;
01689 int i = 1;
01690
01691 s2 = ") {\n";
01692 if (Ansi)
01693 s1 = "switch (";
01694 else if (index->tag == TNAME || index->tag == TEXPR
01695 && index->exprblock.opcode == OPWHATSIN)
01696 s1 = "switch ((int)";
01697 else {
01698 s1 = "switch ((int)(";
01699 s2 = ")) {\n";
01700 }
01701 nice_printf(outfile, s1);
01702 expr_out (outfile, index);
01703 nice_printf (outfile, s2);
01704 next_tab (outfile);
01705
01706 for (elts = labels -> listblock.listp; elts; elts = elts -> nextp, i++) {
01707 if (elts -> datap) {
01708 if (ISICON(((expptr) (elts -> datap))))
01709 nice_printf (outfile, "case %d: goto %s;\n", i,
01710 user_label(((expptr)(elts->datap))->constblock.Const.ci));
01711 else
01712 err ("compgoto_out: bad label in label list");
01713 }
01714 }
01715 prev_tab (outfile);
01716 nice_printf (outfile, "}\n");
01717 }
01718 }
01719
01720
01721 void
01722 #ifdef KR_headers
01723 out_for(outfile, init, test, inc)
01724 FILE *outfile;
01725 expptr init;
01726 expptr test;
01727 expptr inc;
01728 #else
01729 out_for(FILE *outfile, expptr init, expptr test, expptr inc)
01730 #endif
01731 {
01732 nice_printf (outfile, "for (");
01733 expr_out (outfile, init);
01734 nice_printf (outfile, "; ");
01735 expr_out (outfile, test);
01736 nice_printf (outfile, "; ");
01737 expr_out (outfile, inc);
01738 nice_printf (outfile, ") {\n");
01739 next_tab (outfile);
01740 }
01741
01742
01743 void
01744 #ifdef KR_headers
01745 out_end_for(outfile)
01746 FILE *outfile;
01747 #else
01748 out_end_for(FILE *outfile)
01749 #endif
01750 {
01751 prev_tab (outfile);
01752 nice_printf (outfile, "}\n");
01753 }