/*******************************************************************\

Module: C++ Language Conversion

Author: Daniel Kroening, kroening@cs.cmu.edu

\*******************************************************************/

#include <assert.h>

#include <arith_tools.h>
#include <config.h>

#include "c_types.h"
#include "parse_float.h"
#include "convert_float_literal.h"

/*******************************************************************\

Function: convert_float_literal

  Inputs:

 Outputs:

 Purpose:

\*******************************************************************/

void convert_float_literal(
  const std::string &src,
  exprt &dest)
{
  mp_integer significand;
  mp_integer exponent;
  bool is_float, is_long;
  
  parse_float(src, significand, exponent, is_float, is_long);
  
  dest=exprt("constant");
  
  dest.set("#cformat", src);

  unsigned width;

  if(is_float)
  {
    dest.type()=float_type();
    width=config.ansi_c.single_width;
  }
  else if(is_long)
  {
    dest.type()=long_double_type();
    width=config.ansi_c.long_double_width;
  }
  else
  {
    dest.type()=double_type();
    width=config.ansi_c.double_width;
  }

  unsigned fraction_bits;
  const std::string &integer_bits=dest.type().get_string("integer_bits");

  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(exponent<0)
    value/=power(10, -exponent);
  else
    value*=power(10, exponent);

  dest.set("value", integer2binary(value, width));  
}
