From e4731931589d6313988337a921747f9caf6fc3e7 Mon Sep 17 00:00:00 2001 From: paltherr Date: Sun, 1 Feb 2004 03:15:00 +0000 Subject: - Generalized use of AConstant to represent con... - Generalized use of AConstant to represent constant values --- sources/scalac/atree/AConstant.java | 343 +++++++++++++++++++++++++++++++ sources/scalac/atree/ATreeFromSTree.java | 21 +- sources/scalac/atree/ATreeTyper.java | 23 ++- sources/scalac/atree/ATypeKind.java | 12 ++ 4 files changed, 376 insertions(+), 23 deletions(-) (limited to 'sources/scalac/atree') diff --git a/sources/scalac/atree/AConstant.java b/sources/scalac/atree/AConstant.java index 626ab2a5da..4abd485f66 100644 --- a/sources/scalac/atree/AConstant.java +++ b/sources/scalac/atree/AConstant.java @@ -8,6 +8,8 @@ package scalac.atree; +import scalac.util.Debug; + /** This class represents a constant. */ public class AConstant { @@ -30,6 +32,347 @@ public class AConstant { //######################################################################## // 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(_): + 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 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 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; + } + 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 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(); diff --git a/sources/scalac/atree/ATreeFromSTree.java b/sources/scalac/atree/ATreeFromSTree.java index 6ffeeefef2..405875c0cf 100644 --- a/sources/scalac/atree/ATreeFromSTree.java +++ b/sources/scalac/atree/ATreeFromSTree.java @@ -231,8 +231,8 @@ public class ATreeFromSTree { return make.Constant(tree, make.ZERO); return make.Load(tree, location(tree)); - case Literal(Object value): - return make.Constant(tree, constant(value)); + case Literal(AConstant value): + return make.Constant(tree, value); default: throw Debug.abort("illegal case", tree); @@ -310,22 +310,5 @@ public class ATreeFromSTree { } } - //######################################################################## - // Private Methods - Translating constants - - /** Translates the constant. */ - private AConstant constant(Object value) { - if (value instanceof Boolean ) return make.BOOLEAN((Boolean )value); - if (value instanceof Byte ) return make.BYTE (((Byte )value)); - if (value instanceof Short ) return make.SHORT ((Short )value); - if (value instanceof Character) return make.CHAR ((Character)value); - if (value instanceof Integer ) return make.INT ((Integer )value); - if (value instanceof Long ) return make.LONG ((Long )value); - if (value instanceof Float ) return make.FLOAT ((Float )value); - if (value instanceof Double ) return make.DOUBLE ((Double )value); - if (value instanceof String ) return make.STRING ((String )value); - throw Debug.abort("illegal constant", value +" -- "+ value.getClass()); - } - //######################################################################## } diff --git a/sources/scalac/atree/ATreeTyper.java b/sources/scalac/atree/ATreeTyper.java index dead4e7c40..70156802d5 100644 --- a/sources/scalac/atree/ATreeTyper.java +++ b/sources/scalac/atree/ATreeTyper.java @@ -25,6 +25,9 @@ public class ATreeTyper { //######################################################################## // Private Fields + /** The global environment */ + public final Global global; + /** The global definitions */ private final Definitions definitions; @@ -32,8 +35,9 @@ public class ATreeTyper { // Public Constructors /** Initializes this instance. */ - public ATreeTyper(Global global) { - this.definitions = global.definitions; + public ATreeTyper(Global global, Definitions definitions) { + this.global = global; + this.definitions = definitions; } //######################################################################## @@ -176,8 +180,15 @@ public class ATreeTyper { /** Returns the type of the given constant. */ public Type type(AConstant constant) { + Type base = basetype(constant); + if (global.currentPhase.id > global.PHASE.ERASURE.id()) return base; + return Type.ConstantType(base, constant); + } + + /** Returns the base type of the given constant. */ + public Type basetype(AConstant constant) { switch (constant) { - case UNIT : return definitions.UNIT_CLASS.type(); + case UNIT : return definitions.UNIT_TYPE(); case BOOLEAN(_): return definitions.BOOLEAN_TYPE(); case BYTE(_) : return definitions.BYTE_TYPE(); case SHORT(_) : return definitions.SHORT_TYPE(); @@ -199,6 +210,7 @@ public class ATreeTyper { /** Returns the type of the given type kind. */ public Type type(ATypeKind kind) { switch (kind) { + case UNIT: return definitions.UNIT_TYPE(); case BOOL: return definitions.BOOLEAN_TYPE(); // !!! case U1 : return ?; case U2 : return definitions.CHAR_TYPE(); @@ -212,12 +224,15 @@ public class ATreeTyper { case R8 : return definitions.DOUBLE_TYPE(); case REF : return definitions.ANYREF_TYPE(); case STR : return definitions.STRING_TYPE(); + case NULL: return definitions.ALLREF_TYPE(); + case ZERO: return definitions.ALL_TYPE(); default : throw Debug.abort("unknown case", kind); } } //######################################################################## - // Public Methods - aliases of type() for scala + // Public Methods - Aliases for scala + public Type[] computeType(ACode[] codes) { return type(codes); } diff --git a/sources/scalac/atree/ATypeKind.java b/sources/scalac/atree/ATypeKind.java index 57b827473d..1be2eb540d 100644 --- a/sources/scalac/atree/ATypeKind.java +++ b/sources/scalac/atree/ATypeKind.java @@ -16,6 +16,9 @@ public class ATypeKind { //######################################################################## // Public Cases + /** The unit value */ + public case UNIT; + /** A boolean value */ public case BOOL; @@ -55,12 +58,19 @@ public class ATypeKind { /** A string reference */ public case STR; + /** The null reference */ + public case NULL; + + /** The zero value */ + public case ZERO; + //######################################################################## // Public Methods /** Returns a string representation of this type kind. */ public String toString() { switch (this) { + case UNIT: return "UNIT"; case BOOL: return "BOOL"; case U1 : return "U1"; case U2 : return "U2"; @@ -74,6 +84,8 @@ public class ATypeKind { case R8 : return "R8"; case REF : return "REF"; case STR : return "STR"; + case NULL: return "NULL"; + case ZERO: return "ZERO"; default : throw Debug.abort("unknown case", this); } } -- cgit v1.2.3