Expression *Target::paintAsType(Expression *e, Type *type) { union { d_int32 int32value; d_int64 int64value; float float32value; double float64value; } u; assert(e->type->size() == type->size()); switch (e->type->ty) { case Tint32: case Tuns32: u.int32value = (d_int32)e->toInteger(); break; case Tint64: case Tuns64: u.int64value = (d_int64)e->toInteger(); break; case Tfloat32: u.float32value = e->toReal(); break; case Tfloat64: u.float64value = e->toReal(); break; default: assert(0); } switch (type->ty) { case Tint32: case Tuns32: return new IntegerExp(e->loc, u.int32value, type); case Tint64: case Tuns64: return new IntegerExp(e->loc, u.int64value, type); case Tfloat32: return new RealExp(e->loc, ldouble(u.float32value), type); case Tfloat64: return new RealExp(e->loc, ldouble(u.float64value), type); default: assert(0); } return NULL; // avoid warning }
Expression *PowExp::optimize(int result) { Expression *e; e1 = e1->optimize(result); e2 = e2->optimize(result); // Replace 1 ^^ x or 1.0^^x by (x, 1) if ((e1->op == TOKint64 && e1->toInteger() == 1) || (e1->op == TOKfloat64 && e1->toReal() == 1.0)) { e = new CommaExp(loc, e2, e1); } // Replace -1 ^^ x by (x&1) ? -1 : 1, where x is integral else if (e2->type->isintegral() && e1->op == TOKint64 && (sinteger_t)e1->toInteger() == -1L) { Type* resultType = type; e = new AndExp(loc, e2, new IntegerExp(loc, 1, e2->type)); e = new CondExp(loc, e, new IntegerExp(loc, -1L, resultType), new IntegerExp(loc, 1L, resultType)); } // Replace x ^^ 0 or x^^0.0 by (x, 1) else if ((e2->op == TOKint64 && e2->toInteger() == 0) || (e2->op == TOKfloat64 && e2->toReal() == 0.0)) { if (e1->type->isintegral()) e = new IntegerExp(loc, 1, e1->type); else e = new RealExp(loc, ldouble(1.0), e1->type); e = new CommaExp(loc, e1, e); } // Replace x ^^ 1 or x^^1.0 by (x) else if ((e2->op == TOKint64 && e2->toInteger() == 1) || (e2->op == TOKfloat64 && e2->toReal() == 1.0)) { e = e1; } // Replace x ^^ -1.0 by (1.0 / x) else if ((e2->op == TOKfloat64 && e2->toReal() == -1.0)) { e = new DivExp(loc, new RealExp(loc, ldouble(1.0), e2->type), e1); } // All other negative integral powers are illegal else if ((e1->type->isintegral()) && (e2->op == TOKint64) && (sinteger_t)e2->toInteger() < 0) { error("cannot raise %s to a negative integer power. Did you mean (cast(real)%s)^^%s ?", e1->type->toBasetype()->toChars(), e1->toChars(), e2->toChars()); e = new ErrorExp(); } else { // If e2 *could* have been an integer, make it one. if (e2->op == TOKfloat64 && (e2->toReal() == (sinteger_t)(e2->toReal()))) e2 = new IntegerExp(loc, e2->toInteger(), Type::tint64); if (e1->isConst() == 1 && e2->isConst() == 1) { e = Pow(type, e1, e2); if (e != EXP_CANT_INTERPRET) return e; } e = this; } return e; }
//------------------------------------------------------------------------------ GDChart & GDChart::createChart() { create(width_,height_); bool isIntergerOnlyValues = true; intptr_t i, j, xCount = 0, x, y, x0 = 0, y0 = 0; // calc min max ldouble minValue = DBL_MAX, maxValue = -DBL_MAX; for( i = data_.count() - 1; i >= 0; i-- ){ j = data_[i].count(); xCount = tmax(xCount,j); const Array<ldouble> & data = data_[i]; for( j = data.count() - 1; j >= 0; j-- ){ volatile intmax_t v = intmax_t(data[j]); volatile ldouble lv = ldouble(v); if( lv != data[j] ) isIntergerOnlyValues = false; minValue = tmin(minValue,data[j]); maxValue = tmax(maxValue,data[j]); } } ldouble yAxis = (maxValue - minValue) / (height_ - topBorder_ - bottomBorder_); intptr_t leftBorderDelta = 0, rightBorderDelta = 0, topBorderDelta = 0, bottomBorderDelta = 0; // clear image fill(0,0,colorAllocate(255,255,255)); // draw lines intptr_t lineColor = colorAllocate(230,230,230); // draw vert grid lines for( j = 0; j < xCount; j++ ){ x = (width_ - leftBorder_ - rightBorder_) * j / (xCount - 1) + leftBorder_; line(x,topBorder_,x,height_ - bottomBorder_,lineColor); } intptr_t yLabelColor = makeColor(ldouble(j),ldouble(j),ldouble(j)); for( y = topBorder_; uintptr_t(y) <= height_ - bottomBorder_; y += fontHeight(font_) * 2 ){ ldouble v = maxValue - (y - topBorder_) * yAxis; // draw horiz grid line line(leftBorder_,y,width_ - rightBorder_,y,lineColor); // draw ylabel utf8::String label; if( isIntergerOnlyValues ){ label = printTraffic(intmax_t(v),true);//utf8::String::print("%"PRIdPTR,intptr_t(v)); } else { label = utf8::String::print("%.2"PRF_LDBL"f",v); } uintptr_t sz = label.size(); x = leftBorder_ - sz * fontWidth(font_); string(GD::font(font_),x,y,label.c_str(),yLabelColor); if( x < 0 && -x > leftBorderDelta ) leftBorderDelta = -x; } // draw data lines for( i = 0; uintptr_t(i) < data_.count(); i++ ){ intptr_t color = makeColor(ldouble(i + 1),ldouble(i + 1),ldouble(i + 1)); const Array<ldouble> & data = data_[i]; for( j = 0; uintptr_t(j) < data.count(); j++ ){ x = (width_ - leftBorder_ - rightBorder_) * j / (xCount - 1) + leftBorder_; y = intptr_t(height_ - topBorder_ - bottomBorder_ - (data[j] - minValue) / yAxis) + topBorder_; if( j > 0 ) line(x0,y0,x,y,color); x0 = x; y0 = y; } } intptr_t xBarSize = 2, yBarSize = 2; intptr_t barColor = colorAllocate(255,0,0); intptr_t xLabelColor = makeColor(ldouble(i + 1),ldouble(i + 1),ldouble(i + 1)); for( i = 0; uintptr_t(i) < data_.count(); i++ ){ const Array<ldouble> & data = data_[i]; for( j = 0; uintptr_t(j) < data.count(); j++ ){ x = (width_ - leftBorder_ - rightBorder_) * j / (xCount - 1) + leftBorder_; y = intptr_t(height_ - topBorder_ - bottomBorder_ - (data[j] - minValue) / yAxis) + topBorder_; // draw bar filledRectangle( tmax(leftBorder_,uintptr_t(x - xBarSize)), tmax(topBorder_,uintptr_t(y - yBarSize)), tmin(width_ - rightBorder_,uintptr_t(x + xBarSize)), tmin(height_ - bottomBorder_,uintptr_t(y + yBarSize)), barColor ); x0 = x; y0 = y; // draw xlabel y = height_ - bottomBorder_ + xBarSize; utf8::String label(utf8::String::print("%"PRIdPTR,intptr_t(j + xlvs_))); string(GD::font(font_),x + xBarSize,y,label.c_str(),xLabelColor); if( y + fontHeight(font_) >= height_ ) bottomBorderDelta = y + fontHeight(font_) - height_ + 1; x = x + xBarSize + fontWidth(font_) * label.size(); if( uintptr_t(x) >= width_ ) rightBorderDelta = x - width_ + 1; } } if( leftBorderDelta != 0 || rightBorderDelta != 0 || topBorderDelta != 0 || bottomBorderDelta != 0 ){ GDChart chart(*this); chart.leftBorder_ += leftBorderDelta; chart.rightBorder_ += rightBorderDelta; chart.topBorder_ += topBorderDelta; chart.bottomBorder_ += bottomBorderDelta; chart.createChart(); xchg(image_,chart.image_); xchg(png_,chart.png_); xchg(pngSize_,chart.pngSize_); } else { gdFree(png_); png_ = pngPtrEx(&pngSize_,9); } return *this; }