output.c
来自「把fortran语言编的程序转为c语言编的程序, 运行环境linux」· C语言 代码 · 共 1,671 行 · 第 1/3 页
C
1,671 行
nice_printf(fp, "*"); switch (addrp -> uname_tag) { case UNAM_REF: nice_printf(fp, "%s_%s(", addrp->user.name->cvarname, addrp->cmplx_sub ? "subscr" : "ref"); out_args(fp, addrp->memoffset); nice_printf(fp, ")"); return; case UNAM_NAME: out_name (fp, addrp -> user.name); break; case UNAM_IDENT: if (*(s = addrp->user.ident) == ' ') { if (multitype) nice_printf(fp, "%s", xretslot[addrp->vtype]->user.ident); else nice_printf(fp, "%s", s+1); } else { nice_printf(fp, "%s", s); } break; case UNAM_CHARP: nice_printf(fp, "%s", addrp->user.Charp); break; case UNAM_EXTERN: extern_out (fp, &extsymtab[addrp -> memno]); break; case UNAM_CONST: switch(addrp->vstg) { case STGCONST: out_const(fp, (Constp)addrp); break; case STGMEMNO: output_literal (fp, (int)addrp->memno, (Constp)addrp); break; default: Fatal("unexpected vstg in out_addr"); } break; case UNAM_UNKNOWN: default: nice_printf (fp, "Unknown Addrp"); break; } /* switch *//* It's okay to just throw in the brackets here because they have a precedence level of 15, the highest value. */ if ((addrp->uname_tag == UNAM_NAME && addrp->user.name->vdim || addrp->ntempelt > 1 || addrp->isarray) && addrp->vtype != TYCHAR) { expptr offset; was_array = 1; offset = addrp -> memoffset; addrp->memoffset = 0; if (ONEOF(addrp->vstg, M(STGCOMMON)|M(STGEQUIV)) && addrp -> uname_tag == UNAM_NAME && !addrp->skip_offset) offset = mkexpr (OPMINUS, offset, mkintcon ( addrp -> user.name -> voffset)); nice_printf (fp, "["); offset = mkexpr (OPSLASH, offset, ICON (typesize[addrp -> vtype] * (addrp -> Field ? 2 : 1))); expr_out (fp, offset); nice_printf (fp, "]"); }/* Check for structure field reference */ if (addrp -> Field && addrp -> uname_tag != UNAM_CONST && addrp -> uname_tag != UNAM_UNKNOWN) { if (oneof_stg((addrp -> uname_tag == UNAM_NAME ? addrp -> user.name : (Namep) NULL), addrp -> vstg, M(STGARG)|M(STGEQUIV)) && !was_array && (addrp->vclass != CLPROC || !multitype)) nice_printf (fp, "->%s", addrp -> Field); else nice_printf (fp, ".%s", addrp -> Field); } /* if *//* Check for character subscripting */ if (addrp->vtype == TYCHAR && (addrp->vclass != CLPROC || addrp->uname_tag == UNAM_NAME && addrp->user.name->vprocclass == PTHISPROC) && addrp -> memoffset && (addrp -> uname_tag != UNAM_NAME || addrp -> user.name -> vtype == TYCHAR) && (!ISICON (addrp -> memoffset) || (addrp -> memoffset -> constblock.Const.ci))) { int use_paren = 0; expptr e = addrp -> memoffset; if (!e) return; addrp->memoffset = 0; if (ONEOF(addrp->vstg, M(STGCOMMON)|M(STGEQUIV)) && addrp -> uname_tag == UNAM_NAME) { e = mkexpr (OPMINUS, e, mkintcon (addrp -> user.name -> voffset));/* mkexpr will simplify it to zero if possible */ if (e->tag == TCONST && e->constblock.Const.ci == 0) return; } /* if addrp -> vstg == STGCOMMON *//* In the worst case, parentheses might be needed OUTSIDE the expression, too. But since I think this subscripting can only appear as a parameter in a procedure call, I don't think outside parens will ever be needed. INSIDE parens are handled below */ nice_printf (fp, " + "); if (e -> tag == TEXPR) { int arg_prec = op_precedence (e -> exprblock.opcode); int prec = op_precedence (OPPLUS); use_paren = arg_prec && (arg_prec < prec || (arg_prec == prec && is_left_assoc (OPPLUS))); } /* if e -> tag == TEXPR */ if (use_paren) nice_printf (fp, "("); expr_out (fp, e); if (use_paren) nice_printf (fp, ")"); } /* if */} /* out_addr */ static void#ifdef KR_headersoutput_literal(fp, memno, cp) FILE *fp; int memno; Constp cp;#elseoutput_literal(FILE *fp, int memno, Constp cp)#endif{ struct Literal *litp, *lastlit; lastlit = litpool + nliterals; for (litp = litpool; litp < lastlit; litp++) { if (litp -> litnum == memno) break; } /* for litp */ if (litp >= lastlit) out_const (fp, cp); else { nice_printf (fp, "%s", lit_name (litp)); litp->lituse++; }} /* output_literal */ static void#ifdef KR_headersoutput_prim(fp, primp) FILE *fp; struct Primblock *primp;#elseoutput_prim(FILE *fp, struct Primblock *primp)#endif{ if (primp == NULL) return; out_name (fp, primp -> namep); if (primp -> argsp) output_arg_list (fp, primp -> argsp); if (primp -> fcharp != (expptr) NULL || primp -> lcharp != (expptr) NULL) nice_printf (fp, "Sorry, no substrings yet");} static void#ifdef KR_headersoutput_arg_list(fp, listp) FILE *fp; struct Listblock *listp;#elseoutput_arg_list(FILE *fp, struct Listblock *listp)#endif{ chainp arg_list; if (listp == (struct Listblock *) NULL || listp -> listp == (chainp) NULL) return; nice_printf (fp, "("); for (arg_list = listp -> listp; arg_list; arg_list = arg_list -> nextp) { expr_out (fp, (expptr) arg_list -> datap); if (arg_list -> nextp != (chainp) NULL)/* Might want to add a hook in here to accomodate the style setting which wants spaces after commas */ nice_printf (fp, ","); } /* for arg_list */ nice_printf (fp, ")");} /* output_arg_list */ static void#ifdef KR_headersoutput_unary(fp, e) FILE *fp; struct Exprblock *e;#elseoutput_unary(FILE *fp, struct Exprblock *e)#endif{ if (e == NULL) return; switch (e -> opcode) { case OPNEG: if (e->vtype == TYREAL && forcedouble) { e->opcode = OPNEG_KLUDGE; output_binary(fp,e); e->opcode = OPNEG; break; } case OPNEG1: case OPNOT: case OPABS: case OPBITNOT: case OPWHATSIN: case OPPREINC: case OPPREDEC: case OPADDR: case OPIDENTITY: case OPCHARCAST: case OPDABS: output_binary (fp, e); break; case OPCALL: case OPCCALL: nice_printf (fp, "Sorry, no OPCALL yet"); break; default: erri ("output_unary: bad opcode", (int) e -> opcode); break; } /* switch */} /* output_unary */ static char *#ifdef KR_headersfindconst(m) register long m;#elsefindconst(register long m)#endif{ register struct Literal *litp, *litpe; litp = litpool; for(litpe = litp + nliterals; litp < litpe; litp++) if (litp->litnum == m) return litp->cds[0]; Fatal("findconst failure!"); return 0; } static int#ifdef KR_headersopconv_fudge(fp, e) FILE *fp; struct Exprblock *e;#elseopconv_fudge(FILE *fp, struct Exprblock *e)#endif{ /* special handling for ichar and character*1 */ register expptr lp; register union Expression *Offset; register char *cp; int lt; char buf[8]; unsigned int k; Namep np; if (!(lp = e->leftp)) /* possible with erroneous Fortran */ return 1; lt = lp->headblock.vtype; if (lt == TYCHAR) { switch(lp->tag) { case TNAME: nice_printf(fp, "*(unsigned char *)"); out_name(fp, (Namep)lp); return 1; case TCONST: tconst: cp = lp->constblock.Const.ccp; tconst1: k = *(unsigned char *)cp; if (k < 128) { /* ASCII character */ sprintf(buf, chr_fmt[k], k); nice_printf(fp, "'%s'", buf); } else nice_printf(fp, "%d", k); return 1; case TADDR: switch(lp->addrblock.vstg) { case STGMEMNO: if (halign && e->vtype != TYCHAR) { nice_printf(fp, "*(%s *)", c_type_decl(e->vtype,0)); expr_out(fp, lp); return 1; } cp = findconst(lp->addrblock.memno); goto tconst1; case STGCONST: goto tconst; } lp->addrblock.vtype = tyint; Offset = lp->addrblock.memoffset; switch(lp->addrblock.uname_tag) { case UNAM_REF: nice_printf(fp, "*(unsigned char *)"); return 0; case UNAM_NAME: np = lp->addrblock.user.name; if (ONEOF(np->vstg, M(STGCOMMON)|M(STGEQUIV))) Offset = mkexpr(OPMINUS, Offset, ICON(np->voffset)); } lp->addrblock.memoffset = Offset ? mkexpr(OPSTAR, Offset, ICON(typesize[tyint])) : ICON(0); lp->addrblock.isarray = 1; /* STGCOMMON or STGEQUIV would cause */ /* voffset to be added in a second time */ lp->addrblock.vstg = STGUNKNOWN; nice_printf(fp, "*(unsigned char *)&"); return 0; default: badtag("opconv_fudge", lp->tag); } } if (lt != e->vtype) nice_printf(fp, "(%s) ", c_type_decl(e->vtype, 0)); return 0; } static void#ifdef KR_headersoutput_binary(fp, e) FILE *fp; struct Exprblock *e;#elseoutput_binary(FILE *fp, struct Exprblock *e)#endif{ char *format; extern table_entry opcode_table[]; int prec; if (e == NULL || e -> tag != TEXPR) return;/* Instead of writing a huge switch, I've incorporated the output format into a table. Things like "%l" and "%r" stand for the left and right subexpressions. This should allow both prefix and infix functions to be specified (e.g. "(%l * %r", "z_div (%l, %r"). Of course, I should REALLY think out the ramifications of writing out straight text, as opposed to some intermediate format, which could figure out and optimize on the the number of required blanks (we don't want "x - (-y)" to become "x --y", for example). Special cases (such as incomplete implementations) could still be implemented as part of the switch, they will just have some dummy value instead of the string pattern. Another difficulty is the fact that the complex functions will differ from the integer and real ones *//* Handle a special case. We don't want to output "x + - 4", or "y - - 3"*/ if ((e -> opcode == OPPLUS || e -> opcode == OPMINUS) && e -> rightp && e -> rightp -> tag == TCONST && isnegative_const (&(e -> rightp -> constblock)) && is_negatable (&(e -> rightp -> constblock))) { e -> opcode = (e -> opcode == OPPLUS) ? OPMINUS : OPPLUS; negate_const (&(e -> rightp -> constblock)); } /* if e -> opcode == PLUS or MINUS */ prec = op_precedence (e -> opcode); format = op_format (e -> opcode); if (format != SPECIAL_FMT) { while (*format) { if (*format == '%') { int arg_prec, use_paren = 0; expptr lp, rp; switch (*(format + 1)) { case 'l': lp = e->leftp; if (lp && lp->tag == TEXPR) { arg_prec = op_precedence(lp->exprblock.opcode); use_paren = arg_prec && (arg_prec < prec || (arg_prec == prec && is_right_assoc (prec))); } /* if e -> leftp */ if (e->opcode == OPCONV && opconv_fudge(fp,e)) break; if (use_paren) nice_printf (fp, "("); expr_out(fp, lp); if (use_paren) nice_printf (fp, ")"); break; case 'r': rp = e->rightp; if (rp && rp->tag == TEXPR) { arg_prec = op_precedence(rp->exprblock.opcode); use_paren = arg_prec && (arg_prec < prec || (arg_prec == prec && is_left_assoc (prec))); use_paren = use_paren || (rp->exprblock.opcode == OPNEG && prec >= op_precedence(OPMINUS)); } /* if e -> rightp */ if (use_paren) nice_printf (fp, "("); expr_out(fp, rp); if (use_paren) nice_printf (fp, ")"); break; case '\0': case '%': nice_printf (fp, "%%"); break; default: erri ("output_binary: format err: '%%%c' illegal", (int) *(format + 1)); break; } /* switch */ format += 2; } else nice_printf (fp, "%c", *format++); } /* while *format */ } else {/* Handle Special cases of formatting */ switch (e -> opcode) { case OPCCALL: case OPCALL: out_call (fp, (int) e -> opcode, e -> vtype, e -> vleng, e -> leftp, e -> rightp); break; case OPCOMMA_ARG: doin_setbound = 1; nice_printf(fp, "("); expr_out(fp, e->leftp); nice_printf(fp, ", &"); doin_setbound = 0; expr_out(fp, e->rightp); nice_printf(fp, ")"); break; case OPADDR: default: nice_printf (fp, "Sorry, can't format OPCODE '%d'", e -> opcode); break; } } /* else */} /* output_binary */ void#ifdef KR_headersout_call(outfile, op, ftype, len, name, args) FILE *outfile; int op; int ftype; expptr len; expptr name; expptr args;#elseout_call(FILE *outfile, int op, int ftype, expptr len, expptr name, expptr args)#endif{ chainp arglist; /* Pointer to any actual arguments */ chainp cp; /* Iterator over argument lists */ Addrp ret_val = (Addrp) NULL; /* Function return value buffer, if any is required */ int byvalue; /* True iff we're calling a C library routine */ int done_once; /* Used for writing commas to outfile */ int narg, t; register expptr q; long L; Argtypes *at; Atype *A, *Ac; Namep np; extern int forcereal;/* Don't use addresses if we're calling a C function */ byvalue = op == OPCCALL; if (args) arglist = args -> listblock.listp; else arglist = CHNULL;/* If this is a CHARACTER function, the first argument is the result */ if (ftype == TYCHAR) if (ISICON (len)) { ret_val = (Addrp) (arglist -> datap); arglist = arglist -> nextp; } else { err ("adjustable character function"); return; } /* else *//* If this is a COMPLEX function, the first argument is the result */ else if (ISCOMPLEX (ftype)) { ret_val = (Addrp) (arglist -> datap); arglist = arglist -> nextp; } /* if ISCOMPLEX *//* Now we can actually start to write out the function invocation */ if (ftype == TYREAL && forcereal) nice_printf(outfile, "(real)"); if (name -> tag == TEXPR && name -> exprblock.opcode == OPWHATSIN) { nice_printf (outfile, "("); np = (Namep)name->exprblock.leftp; /*expr_out will free name */ expr_out (outfile, name); nice_printf (outfile, ")");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?