package fr.umlv.talk.stackinterp2;

public class Values {
  private Values() {
    throw null;
  }
  
  // values encoding
  // xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxx1 -> a small integer (31 bits)
  // xxxxxxxx xxxxxxxx xxxxxxxx xxxxxx10 -> a constant index (30 bits)
  // xxxxxxxx xxxxxxxx xxxxxxxx xxxxxx00 -> reference in heap (32 bits aligned)
  
  public static boolean isSmallInteger(int tagValue) {
    return (tagValue & 0b1) != 0;
  }
  
  public static int asSmallInteger(int tagValue) {
    return tagValue >>> 1;
  }
  
  public static boolean isReference(int tagValue) {
    return (tagValue & 0b11) == 0;
  }
  
  public static int asConstantIndex(int tagValue) {
    return tagValue >>> 2;
  }
  
  public static int asTagObjectFromSmallInteger(int smallInt) {
    assert smallInt >= 0;
    return smallInt << 1 | 0b1;
  }
  
  public static int asTagObjectFromConstantIndex(int constantIndex) {
    assert constantIndex >= 0;
    return constantIndex << 2 | 0b10;
  }
}
