summaryrefslogblamecommitdiff
path: root/sources/scalac/atree/AConstant.java
blob: 12c58d5889bf46254f34792acff2953311adf757 (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                          
                         
                            
 


                                        

                                                                   












                                                                              
                                          





                                                                              





















                                                  
                            





































































































































































































                                                                  

                                         

















                                                                           

                         






























































                                             






                                            



                         






























                                                                 

                                       








                                                    






                                                                              
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
\*                                                                      */

// $Id$

package scalac.atree;

import scalac.util.Debug;
import scalac.symtab.Symbol;

/** This class represents a constant. */
public class AConstant {

    public static final AConstant[] EMPTY_ARRAY = new AConstant[0];

    //########################################################################
    // Public Cases

    public case UNIT;
    public case BOOLEAN(boolean value);
    public case BYTE(byte value);
    public case SHORT(short value);
    public case CHAR(char value);
    public case INT(int value);
    public case LONG(long value);
    public case FLOAT(float value);
    public case DOUBLE(double value);
    public case STRING(String value);
    public case SYMBOL_NAME(Symbol value);
    public case NULL;
    public case ZERO;

    //########################################################################
    // Public Methods

    /** Returns the type kind of this constant. */
    public ATypeKind kind() {
        switch (this) {
        case UNIT:
            return ATypeKind.UNIT;
        case BOOLEAN(_):
            return ATypeKind.BOOL;
        case BYTE(_):
            return ATypeKind.I1;
        case SHORT(_):
            return ATypeKind.I2;
        case CHAR(_):
            return ATypeKind.U2;
        case INT(_):
            return ATypeKind.I4;
        case LONG(_):
            return ATypeKind.I8;
        case FLOAT(_):
            return ATypeKind.R4;
        case DOUBLE(_):
            return ATypeKind.R8;
        case STRING(_):
        case SYMBOL_NAME(_):
            return ATypeKind.STR;
        case NULL:
            return ATypeKind.NULL;
        case ZERO:
            return ATypeKind.ZERO;
        default:
            throw Debug.abort("unknown case", this);
        }
    }


    /** Converts this constant to a boolean value. */
    public boolean booleanValue() {
        switch (this) {
        case BOOLEAN(boolean value):
            return value;
        default:
            throw Debug.abort("not convertible to boolean", this);
        }
    }

    /** Converts this constant to a byte value. */
    public byte byteValue() {
        switch (this) {
        case BYTE(byte value):
            return (byte)value;
        case SHORT(short value):
            return (byte)value;
        case CHAR(char value):
            return (byte)value;
        case INT(int value):
            return (byte)value;
        case LONG(long value):
            return (byte)value;
        case FLOAT(float value):
            return (byte)value;
        case DOUBLE(double value):
            return (byte)value;
        default:
            throw Debug.abort("not convertible to byte", this);
        }
    }

    /** Converts this constant to a short value. */
    public short shortValue() {
        switch (this) {
        case BYTE(byte value):
            return (short)value;
        case SHORT(short value):
            return (short)value;
        case CHAR(char value):
            return (short)value;
        case INT(int value):
            return (short)value;
        case LONG(long value):
            return (short)value;
        case FLOAT(float value):
            return (short)value;
        case DOUBLE(double value):
            return (short)value;
        default:
            throw Debug.abort("not convertible to short", this);
        }
    }

    /** Converts this constant to a char value. */
    public char charValue() {
        switch (this) {
        case BYTE(byte value):
            return (char)value;
        case SHORT(short value):
            return (char)value;
        case CHAR(char value):
            return (char)value;
        case INT(int value):
            return (char)value;
        case LONG(long value):
            return (char)value;
        case FLOAT(float value):
            return (char)value;
        case DOUBLE(double value):
            return (char)value;
        default:
            throw Debug.abort("not convertible to char", this);
        }
    }

    /** Converts this constant to a int value. */
    public int intValue() {
        switch (this) {
        case BYTE(byte value):
            return (int)value;
        case SHORT(short value):
            return (int)value;
        case CHAR(char value):
            return (int)value;
        case INT(int value):
            return (int)value;
        case LONG(long value):
            return (int)value;
        case FLOAT(float value):
            return (int)value;
        case DOUBLE(double value):
            return (int)value;
        default:
            throw Debug.abort("not convertible to int", this);
        }
    }

    /** Converts this constant to a long value. */
    public long longValue() {
        switch (this) {
        case BYTE(byte value):
            return (long)value;
        case SHORT(short value):
            return (long)value;
        case CHAR(char value):
            return (long)value;
        case INT(int value):
            return (long)value;
        case LONG(long value):
            return (long)value;
        case FLOAT(float value):
            return (long)value;
        case DOUBLE(double value):
            return (long)value;
        default:
            throw Debug.abort("not convertible to long", this);
        }
    }

    /** Converts this constant to a float value. */
    public float floatValue() {
        switch (this) {
        case BYTE(byte value):
            return (float)value;
        case SHORT(short value):
            return (float)value;
        case CHAR(char value):
            return (float)value;
        case INT(int value):
            return (float)value;
        case LONG(long value):
            return (float)value;
        case FLOAT(float value):
            return (float)value;
        case DOUBLE(double value):
            return (float)value;
        default:
            throw Debug.abort("not convertible to float", this);
        }
    }

    /** Converts this constant to a double value. */
    public double doubleValue() {
        switch (this) {
        case BYTE(byte value):
            return (double)value;
        case SHORT(short value):
            return (double)value;
        case CHAR(char value):
            return (double)value;
        case INT(int value):
            return (double)value;
        case LONG(long value):
            return (double)value;
        case FLOAT(float value):
            return (double)value;
        case DOUBLE(double value):
            return (double)value;
        default:
            throw Debug.abort("not convertible to double", this);
        }
    }

    /** Converts this constant to a String value. */
    public String stringValue() {
        switch (this) {
        case UNIT:
            return "()";
        case BOOLEAN(boolean value):
            return String.valueOf(value);
        case BYTE(byte value):
            return String.valueOf(value);
        case SHORT(short value):
            return String.valueOf(value);
        case CHAR(char value):
            return String.valueOf(value);
        case INT(int value):
            return String.valueOf(value);
        case LONG(long value):
            return String.valueOf(value);
        case FLOAT(float value):
            return String.valueOf(value);
        case DOUBLE(double value):
            return String.valueOf(value);
        case STRING(String value):
            return value;
        case SYMBOL_NAME(Symbol value):
            return value.name.toString();
        case NULL:
            return String.valueOf(null);
        default:
            throw Debug.abort("not convertible to String", this);
        }
    }

    /** Tests whether this constant equals given Object. */
    public boolean equals(Object that) {
        if (this == that) return true;
        return (that instanceof AConstant) && this.equals((AConstant)that);
    }

    /** Tests whether this constant equals given one. */
    public boolean equals(AConstant that) {
        if (this == that) return true;
        if (null == that) return false;
        switch (this) {
        case UNIT:
            return false;
        case BOOLEAN(boolean ivalue):
            switch (that) {
            case BOOLEAN(boolean avalue):
                return ivalue == avalue;
            default:
                return false;
            }
        case BYTE(byte ivalue):
            switch (that) {
            case BYTE(byte avalue):
                return ivalue == avalue;
            default:
                return false;
            }
        case SHORT(short ivalue):
            switch (that) {
            case SHORT(short avalue):
                return ivalue == avalue;
            default:
                return false;
            }
        case CHAR(char ivalue):
            switch (that) {
            case CHAR(char avalue):
                return ivalue == avalue;
            default:
                return false;
            }
        case INT(int ivalue):
            switch (that) {
            case INT(int avalue):
                return ivalue == avalue;
            default:
                return false;
            }
        case LONG(long ivalue):
            switch (that) {
            case LONG(long avalue):
                return ivalue == avalue;
            default:
                return false;
            }
        case FLOAT(float ivalue):
            switch (that) {
            case FLOAT(float avalue):
                return ivalue == avalue;
            default:
                return false;
            }
        case DOUBLE(double ivalue):
            switch (that) {
            case DOUBLE(double avalue):
                return ivalue == avalue;
            default:
                return false;
            }
        case STRING(String ivalue):
            switch (that) {
            case STRING(String avalue):
                return ivalue.equals(avalue);
            default:
                return false;
            }
        case SYMBOL_NAME(Symbol ivalue):
            switch (that) {
            case SYMBOL_NAME(Symbol avalue):
                return ivalue == avalue;
            default:
                return false;
            }
        case NULL:
            return false;
        case ZERO:
            return false;
        default:
            throw Debug.abort("unknown case", this);
        }
    }

    /** Returns the hash code of this constant. */
    public int hashCode() {
        switch (this) {
        case UNIT:
            return 4041;
        case BOOLEAN(boolean value):
            return value ? 1231 : 1237;
        case BYTE(byte value):
            return value;
        case SHORT(short value):
            return value;
        case CHAR(char value):
            return value;
        case INT(int value):
            return value;
        case LONG(long value):
            long bits = value;
            return (int)(bits ^ (bits >>> 32));
        case FLOAT(float value):
            int bits = java.lang.Float.floatToIntBits(value);
            return bits;
        case DOUBLE(double value):
            long bits = java.lang.Double.doubleToLongBits(value);
            return (int)(bits ^ (bits >>> 32));
        case STRING(String value):
            return value.hashCode();
        case SYMBOL_NAME(Symbol value):
            return value.hashCode();
        case NULL:
            return 0;
        case ZERO:
            return 0;
        default:
            throw Debug.abort("unknown case", this);
        }
    }

    /** Returns a string representation of this constant. */
    public String toString() {
        return new ATreePrinter().printConstant(this).toString();
    }

    //########################################################################
}