Example #1
0
/*
 * 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;
}
Example #2
0
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, &sect)) {
	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], &sect);
	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
}