// What a numeric literal's type is before anything constrains it.
//
// Ported from wax/src/lib-wax/typing.ml.
//
// This is the first thing in the checker that produces an annotation, and it
// produces the LEAST committed one it can. A literal's spelling says only what
// it cannot be; `subtype` and `join_value_types` decide the rest from how it is
// used. Keeping literals as raw strings through the whole front end is what
// makes that possible, and this is the function that cashes it in.

///|
/// The lattice type of a float literal.
///
/// A literal that fits an f32 stays FLEXIBLE -- it could be either width, and
/// its use decides. One that does not fit is pinned to f64 immediately, because
/// there is no choice left to make: f32 would overflow it to infinity.
pub fn float_literal_lattice(s : String) -> @infer.InferredType {
  if @number.is_float32(s) {
    Float
  } else {
    Valtype(@infer.f64_valtype)
  }
}

///|
/// The lattice type of an integer literal.
///
/// The magnitude alone rules widths out, and each exclusion is a real one:
///
///   * Over the 32-bit range it cannot be i32, so it is `LargeInt`, which
///     defaults to i64 -- not `Number`, which defaults to i32.
///   * Too big for u64 it cannot be any integer at all, so it is treated as a
///     float. Using it as an integer is then a clean type error rather than an
///     overflow in the encoder, which is where the reference used to crash.
///
/// The sign is a separate negation in the AST, so what arrives here is
/// unsigned.
pub fn int_literal_lattice(s : String) -> @infer.InferredType {
  if !@number.is_int64(s) {
    float_literal_lattice(s)
  } else if !@number.is_int32(s) {
    LargeInt
  } else {
    Number
  }
}