/* * Convert a f77 tree statement to something that looks like a * pcc expression tree. */ NODE * putx(bigptr q) { struct bigblock *x1; NODE *p = NULL; /* XXX */ int opc; int type, k; #ifdef PCC_DEBUG if (tflag) { printf("putx %p\n", q); fprint(q, 0); } #endif switch(q->tag) { case TERROR: ckfree(q); break; case TCONST: switch(type = q->vtype) { case TYLOGICAL: type = tyint; case TYLONG: case TYSHORT: p = mklnode(ICON, q->b_const.fconst.ci, 0, types2[type]); ckfree(q); break; case TYADDR: p = mklnode(ICON, 0, 0, types2[type]); p->n_name = copys(memname(STGCONST, (int)q->b_const.fconst.ci)); ckfree(q); break; default: p = putx(putconst(q)); break; } break; case TEXPR: switch(opc = q->b_expr.opcode) { case OPCALL: case OPCCALL: if( ISCOMPLEX(q->vtype) ) p = putcxop(q); else { putcall(q); p = callval; } break; case OPMIN: case OPMAX: p = putmnmx(q); break; case OPASSIGN: if (ISCOMPLEX(q->b_expr.leftp->vtype) || ISCOMPLEX(q->b_expr.rightp->vtype)) { frexpr(putcxeq(q)); } else if (ISCHAR(q)) p = putcheq(q); else goto putopp; break; case OPEQ: case OPNE: if (ISCOMPLEX(q->b_expr.leftp->vtype) || ISCOMPLEX(q->b_expr.rightp->vtype) ) { p = putcxcmp(q); break; } case OPLT: case OPLE: case OPGT: case OPGE: if(ISCHAR(q->b_expr.leftp)) p = putchcmp(q); else goto putopp; break; case OPPOWER: p = putpower(q); break; case OPSTAR: /* m * (2**k) -> m<<k */ if (XINT(q->b_expr.leftp->vtype) && ISICON(q->b_expr.rightp) && ((k = flog2(q->b_expr.rightp->b_const.fconst.ci))>0) ) { q->b_expr.opcode = OPLSHIFT; frexpr(q->b_expr.rightp); q->b_expr.rightp = MKICON(k); goto putopp; } case OPMOD: goto putopp; case OPPLUS: case OPMINUS: case OPSLASH: case OPNEG: if( ISCOMPLEX(q->vtype) ) p = putcxop(q); else goto putopp; break; case OPCONV: if( ISCOMPLEX(q->vtype) ) p = putcxop(q); else if (ISCOMPLEX(q->b_expr.leftp->vtype)) { p = putx(mkconv(q->vtype, realpart(putcx1(q->b_expr.leftp)))); ckfree(q); } else goto putopp; break; case OPAND: /* Create logical AND */ x1 = fmktemp(TYLOGICAL, NULL); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(0))); k = newlabel(); putif(q->b_expr.leftp, k); putif(q->b_expr.rightp, k); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(1))); putlabel(k); p = putx(x1); break; case OPNOT: /* Logical NOT */ x1 = fmktemp(TYLOGICAL, NULL); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(1))); k = newlabel(); putif(q->b_expr.leftp, k); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(0))); putlabel(k); p = putx(x1); break; case OPOR: /* Create logical OR */ x1 = fmktemp(TYLOGICAL, NULL); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(1))); k = newlabel(); putif(mkexpr(OPEQ, q->b_expr.leftp, mklogcon(0)), k); putif(mkexpr(OPEQ, q->b_expr.rightp, mklogcon(0)), k); putexpr(mkexpr(OPASSIGN, cpexpr(x1), mklogcon(0))); putlabel(k); p = putx(x1); break; case OPCOMMA: for (x1 = q; x1->b_expr.opcode == OPCOMMA; x1 = x1->b_expr.leftp) putexpr(x1->b_expr.rightp); p = putx(x1); break; case OPEQV: case OPNEQV: case OPADDR: case OPBITOR: case OPBITAND: case OPBITXOR: case OPBITNOT: case OPLSHIFT: case OPRSHIFT: putopp: p = putop(q); break; default: fatal1("putx: invalid opcode %d", opc); } break; case TADDR: p = putaddr(q, YES); break; default: fatal1("putx: impossible tag %d", q->tag); } return p; }
static void gen_power(struct powstr *powbuf, int save) { float upower[MAXNOC]; float *f_ptr; float *f_pt2; struct powstr *pow; int i, maxpop; struct sctstr sect; struct dchrstr *dcp; struct plnstr plane; struct plchrstr *pcp; struct shpstr ship; struct mchrstr *mcp; struct lndstr land; struct lchrstr *lcp; struct nukstr nuke; struct nchrstr *ncp; struct nstr_item ni; struct nstr_sect ns; struct natstr *natp; player->btused += 10; memset(powbuf, 0, MAXNOC * sizeof(*powbuf)); memset(upower, 0, sizeof(upower)); snxtsct_all(&ns); while (nxtsct(&ns, §)) { if (sect.sct_own == 0) continue; dcp = &dchr[sect.sct_type]; natp = getnatp(sect.sct_own); pow = &powbuf[sect.sct_own]; pow->p_sects += 1.0; pow->p_effic += sect.sct_effic; addtopow(sect.sct_item, pow); pow->p_power += empobj_power(sect.sct_effic, dcp->d_mat, dcp->d_cost); maxpop = max_pop(natp->nat_level[NAT_RLEV], §); pow->p_power += (1.0 + maxpop / 1000.0 * 8) * sect.sct_effic / 100.0; } snxtitem_all(&ni, EF_LAND); while (nxtitem(&ni, &land)) { if (land.lnd_own == 0) continue; lcp = &lchr[land.lnd_type]; pow = &powbuf[land.lnd_own]; addtopow(land.lnd_item, pow); upower[land.lnd_own] += empunit_power(land.lnd_effic, land.lnd_tech, lcp->l_mat, lcp->l_cost); if (!(lcp->l_flags & L_SPY)) pow->p_units += 1.0; } snxtitem_all(&ni, EF_SHIP); while (nxtitem(&ni, &ship)) { if (ship.shp_own == 0) continue; mcp = &mchr[ship.shp_type]; pow = &powbuf[ship.shp_own]; addtopow(ship.shp_item, pow); upower[ship.shp_own] += empunit_power(ship.shp_effic, ship.shp_tech, mcp->m_mat, mcp->m_cost); pow->p_ships += 1.0; } snxtitem_all(&ni, EF_PLANE); while (nxtitem(&ni, &plane)) { if (plane.pln_own == 0) continue; pcp = &plchr[plane.pln_type]; pow = &powbuf[plane.pln_own]; upower[plane.pln_own] += empunit_power(plane.pln_effic, plane.pln_tech, pcp->pl_mat, pcp->pl_cost); pow->p_planes += 1.0; } snxtitem_all(&ni, EF_NUKE); while (nxtitem(&ni, &nuke)) { if (nuke.nuk_own == 0) continue; ncp = &nchr[nuke.nuk_type]; upower[nuke.nuk_own] += empunit_power(nuke.nuk_effic, nuke.nuk_tech, ncp->n_mat, ncp->n_cost); } for (i = 1; NULL != (natp = getnatp(i)); i++) { pow = &powbuf[i]; pow->p_nation = i; if (natp->nat_stat != STAT_ACTIVE) { pow->p_power = 0.; continue; } pow->p_money = natp->nat_money; pow->p_power += money_power(natp->nat_money); pow->p_power *= power_tech_factor(natp->nat_level[NAT_TLEV]); pow->p_power += upower[i]; /* ack. add this vec to the "world power" element */ f_pt2 = &powbuf[0].p_sects; f_ptr = &pow->p_sects; while (f_ptr <= &pow->p_power) { *f_pt2 += *f_ptr; f_pt2++; f_ptr++; } } qsort(&powbuf[1], MAXNOC - 1, sizeof(*powbuf), powcmp); if (!save) return; for (i = 0; i < MAXNOC; i++) putpower(i, &powbuf[i]); #ifdef _WIN32 /* * At least some versions of Windows fail to update mtime on * write(), they delay it until the write actually hits the disk. * Bad, because `power' displays that time. Force it. */ _commit(empfile[EF_POWER].fd); #endif }