summaryrefslogtreecommitdiff
path: root/sources/scalac/atree
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2004-02-01 03:15:00 +0000
committerpaltherr <paltherr@epfl.ch>2004-02-01 03:15:00 +0000
commite4731931589d6313988337a921747f9caf6fc3e7 (patch)
tree92c7298118201c435ef42d99d6b6d6c00a70c64a /sources/scalac/atree
parentc9e045f5c67d44313e9e2436ec107e514548272e (diff)
downloadscala-e4731931589d6313988337a921747f9caf6fc3e7.tar.gz
scala-e4731931589d6313988337a921747f9caf6fc3e7.tar.bz2
scala-e4731931589d6313988337a921747f9caf6fc3e7.zip
- Generalized use of AConstant to represent con...
- Generalized use of AConstant to represent constant values
Diffstat (limited to 'sources/scalac/atree')
-rw-r--r--sources/scalac/atree/AConstant.java343
-rw-r--r--sources/scalac/atree/ATreeFromSTree.java21
-rw-r--r--sources/scalac/atree/ATreeTyper.java23
-rw-r--r--sources/scalac/atree/ATypeKind.java12
4 files changed, 376 insertions, 23 deletions
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);
@@ -311,21 +311,4 @@ 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);
}
}