void convert_integer_literal(
  const std::string &src,
  exprt &dest,
  unsigned base)
{
  bool is_unsigned=false;
  unsigned long_cnt=0;

  for(unsigned i=src.size(); i!=0; i--)
  {
    char ch=src[i-1];
    if(ch=='u' || ch=='U')
      is_unsigned=true;
    else if(ch=='l' || ch=='L')
      long_cnt++;
    else
      break;
  }

  mp_integer value;

  if(base==10)
  {
    dest.value(src);
    value=string2integer(src, 10);
  }
  else if(base==8)
  {
    dest.hex_or_oct(true);
    value=string2integer(src, 8);
  }
  else
  {
    dest.hex_or_oct(true);
    std::string without_prefix(src, 2, std::string::npos);
    value=string2integer(without_prefix, 16);
  }

  typet type;
  irep_idt cpp_type;

  if(is_unsigned)
    type=typet("unsignedbv");
  else
    type=typet("signedbv");

  if(long_cnt==0) {
    type.width(config.ansi_c.int_width);

    if(!is_unsigned)
      cpp_type="signed_int";
    else
      cpp_type="unsigned_int";

  } else if(long_cnt==1) {
    type.width(config.ansi_c.long_int_width);

    if(!is_unsigned)
      cpp_type="signed_long_int";
    else
      cpp_type="unsigned_long_int";

  } else {
    type.width(config.ansi_c.long_long_int_width);

    if(!is_unsigned)
      cpp_type="signed_long_long_int";
    else
      cpp_type="unsigned_long_long_int";
  }

  type.set("#cpp_type", cpp_type);

  dest=from_integer(value, type);

  dest.cformat(src);

}
Esempio n. 2
0
void convert_float_literal(const std::string &src, exprt &dest)
{
  mp_integer significand;
  mp_integer exponent;
  bool is_float, is_long;
  unsigned base;

  parse_float(src, significand, exponent, base, is_float, is_long);

  dest = exprt("constant");

  dest.cformat(src);

  if(is_float)
  {
    dest.type() = float_type();
    dest.type().set("#cpp_type", "float");
  }
  else if(is_long)
  {
    dest.type() = long_double_type();
    dest.type().set("#cpp_type", "long_double");
  }
  else
  {
    dest.type() = double_type();
    dest.type().set("#cpp_type", "double");
  }

  if(config.ansi_c.use_fixed_for_float)
  {
    unsigned width = atoi(dest.type().width().c_str());
    unsigned fraction_bits;
    const std::string &integer_bits = dest.type().integer_bits().as_string();

    if(integer_bits == "")
      fraction_bits = width / 2;
    else
      fraction_bits = width - atoi(integer_bits.c_str());

    mp_integer factor = mp_integer(1) << fraction_bits;
    mp_integer value = significand * factor;

    if(value != 0)
    {
      if(exponent < 0)
        value /= power(base, -exponent);
      else
      {
        value *= power(base, exponent);

        if(value >= power(2, width - 1))
        {
          // saturate: use "biggest value"
          value = power(2, width - 1) - 1;
        }
        else if(value <= -power(2, width - 1) - 1)
        {
          // saturate: use "smallest value"
          value = -power(2, width - 1);
        }
      }
    }

    dest.value(integer2binary(value, width));
  }
  else
  {
    ieee_floatt a;

    a.spec = to_floatbv_type(dest.type());

    if(base == 10)
      a.from_base10(significand, exponent);
    else if(base == 2) // hex
      a.build(significand, exponent);
    else
      assert(false);

    dest.value(integer2binary(a.pack(), a.spec.width()));
  }
}