Example #1
0
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
}
Example #2
0
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;
}