return en;
}
+ public boolean isFinal() {
+ return modifier.isFinal();
+ }
+
public boolean isStatic() {
return modifier.isStatic();
}
//Get src value
if (an.getSrc()!=null) {
- NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
- first=np_src.getBegin();
- last=np_src.getEnd();
+ if(an.getSrc().getEval() != null) {
+ first = last = new FlatLiteralNode(an.getSrc().getType(), an.getSrc().getEval().longValue(), src_tmp);
+ } else {
+ NodePair np_src=flattenExpressionNode(an.getSrc(),src_tmp);
+ first=np_src.getBegin();
+ last=np_src.getEnd();
+ }
} else if (!pre) {
FlatLiteralNode fln=new FlatLiteralNode(new TypeDescriptor(TypeDescriptor.INT),new Integer(1),src_tmp);
first=fln;
else
return left.getType().dereference();
}
+
+ public Long evaluate() {
+ eval = null;
+ return eval; //null;
+ }
}
public int kind() {
return Kind.ArrayInitializerNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ return eval; //null;
+ }
}
public int kind() {
return Kind.AssignmentNode;
}
+
+ public Long evaluate() {
+ eval = left.evaluate();
+ return eval;
+ }
}
public int kind() {
return Kind.CastNode;
}
+
+ public Long evaluate() {
+ eval = exp.evaluate();
+ return eval;
+ }
}
public int kind() {
return Kind.ClassTypeNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ return eval; //null;
+ }
}
public int kind() {
return Kind.CreateObjectNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ return eval; //null;
+ }
}
import IR.TypeDescriptor;
public class ExpressionNode extends TreeNode {
+ Long eval = null;
+
public TypeDescriptor getType() {
throw new Error();
}
public String printNode(int indentlevel) {
return null;
}
+
+ public Long evaluate() {
+ throw new Error();
+ }
+
+ public Long getEval() {
+ return this.eval;
+ }
}
return getField().getType();
}
+ public Long evaluate() {
+ // if the field is a constant value then OK
+ eval = null;
+ if(field.isStatic() && field.isFinal()) {
+ eval = field.getExpressionNode().evaluate();
+ } else if (field.isEnum()) {
+ eval = Long.valueOf((long)field.enumValue());
+ }
+ return eval;
+ }
}
public int kind() {
return Kind.InstanceOfNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ return eval; //null;
+ }
}
public int kind() {
return Kind.LiteralNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ if(this.type.isChar() || this.type.isInt()) {
+ eval = Long.parseLong(this.value.toString());
+ }
+ return eval;
+ }
}
public int kind() {
return Kind.MethodInvokeNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ return eval; //null;
+ }
}
public int kind() {
return Kind.NameNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ if(fd != null ) {
+ if(fd.isFinal() && fd.isStatic()) {
+ eval = fd.getExpressionNode().evaluate();
+ } else if(fd.isEnum()) {
+ eval = Long.valueOf((long)fd.enumValue());
+ }
+ } else if(en!= null) {
+ eval = en.evaluate();
+ }
+ return eval; //null;
+ }
}
public int kind() {
return Kind.OffsetNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ return eval; //null;
+ }
}
public int kind() {
return Kind.OpNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ Long l = this.left.evaluate();
+ if(l != null) {
+ if (this.op.getOp() == Operation.LOGIC_NOT)
+ eval = Long.valueOf(l.longValue() > 0 ? 0 : 1);
+ else if (this.op.getOp() == Operation.COMP)
+ eval = Long.valueOf((long)(~l.longValue()));
+ else {
+ Long r = this.right.evaluate();
+ if(r != null) {
+ //if (this.op.getOp() == Operation.LOGIC_OR)
+ // return Long.valueOf((long)(l.longValue() || r.longValue()));
+ //else if (this.op.getOp() == Operation.LOGIC_AND)
+ // return Long.valueOf((long)(l.longValue() && r.longValue()));
+ /*else */if (this.op.getOp() == Operation.BIT_OR)
+ eval = Long.valueOf(l.longValue() | r.longValue());
+ else if (this.op.getOp() == Operation.BIT_XOR)
+ eval = Long.valueOf(l.longValue() ^ r.longValue());
+ else if (this.op.getOp() == Operation.BIT_AND)
+ eval = Long.valueOf(l.longValue() & r.longValue());
+ else if (this.op.getOp() == Operation.EQUAL)
+ eval = Long.valueOf((l.longValue() == r.longValue())?1:0);
+ else if (this.op.getOp() == Operation.NOTEQUAL)
+ eval = Long.valueOf((l.longValue() != r.longValue())?1:0);
+ else if (this.op.getOp() == Operation.LT)
+ eval = Long.valueOf((l.longValue() < r.longValue())?1:0);
+ else if (this.op.getOp() == Operation.GT)
+ eval = Long.valueOf((l.longValue() > r.longValue())?1:0);
+ else if (this.op.getOp() == Operation.LTE)
+ eval = Long.valueOf((l.longValue() <= r.longValue())?1:0);
+ else if (this.op.getOp() == Operation.GTE)
+ eval = Long.valueOf((l.longValue() >= r.longValue())?1:0);
+ else if (this.op.getOp() == Operation.LEFTSHIFT)
+ eval = Long.valueOf(l.longValue() << r.longValue());
+ else if (this.op.getOp() == Operation.RIGHTSHIFT)
+ eval = Long.valueOf(l.longValue() >> r.longValue());
+ else if (this.op.getOp() == Operation.URIGHTSHIFT)
+ eval = Long.valueOf(l.longValue() >>> r.longValue());
+ else if (this.op.getOp() == Operation.SUB)
+ eval = Long.valueOf(l.longValue() - r.longValue());
+ else if (this.op.getOp() == Operation.ADD)
+ eval = Long.valueOf(l.longValue() + r.longValue());
+ else if (this.op.getOp() == Operation.MULT)
+ eval = Long.valueOf(l.longValue() * r.longValue());
+ else if (this.op.getOp() == Operation.DIV)
+ eval = Long.valueOf(l.longValue() / r.longValue());
+ else if (this.op.getOp() == Operation.MOD)
+ eval = Long.valueOf(l.longValue() % r.longValue());
+ else if (this.op.getOp() == Operation.UNARYPLUS)
+ eval = Long.valueOf(+l.longValue());
+ else if (this.op.getOp() == Operation.UNARYMINUS)
+ eval = Long.valueOf(-l.longValue() );
+ else if (this.op.getOp() == Operation.ASSIGN)
+ eval = Long.valueOf(r.longValue());
+ }
+ }
+ }
+ return eval;
+ }
}
fd = new FieldDescriptor(new Modifiers(Modifiers.PUBLIC|Modifiers.FINAL), new TypeDescriptor(TypeDescriptor.INT), fieldname, null, false);
fd.setAsEnum();
fd.setEnumValue(value);
- } else if(!fd.isStatic()) {
+ } else if(fd.isStatic()) {
// check if this field is a static field
+ if(fd.getExpressionNode() != null) {
+ checkExpressionNode(md,nametable,fd.getExpressionNode(),null);
+ }
+ } else {
throw new Error("Dereference of the non-static field "+ fieldname + " in "+fan.printNode(0)+" in "+md);
}
}
}
if (td!=null)
- if (!typeutil.isSuperorType(td,ln.getType()))
- throw new Error("Field node returns "+ln.getType()+", but need "+td+" in "+md);
+ if (!typeutil.isSuperorType(td,ln.getType())) {
+ Long l = ln.evaluate();
+ if((ln.getType().isByte() || ln.getType().isShort()
+ || ln.getType().isChar() || ln.getType().isInt())
+ && (l != null)
+ && (td.isByte() || td.isShort() || td.isChar()
+ || td.isInt() || td.isLong())) {
+ long lnvalue = l.longValue();
+ if((td.isByte() && ((lnvalue > 127) || (lnvalue < -128)))
+ || (td.isShort() && ((lnvalue > 32767) || (lnvalue < -32768)))
+ || (td.isChar() && ((lnvalue > 65535) || (lnvalue < 0)))
+ || (td.isInt() && ((lnvalue > 2147483647) || (lnvalue < -2147483648)))
+ || (td.isLong() && ((lnvalue > 9223372036854775807L) || (lnvalue < -9223372036854775808L)))) {
+ throw new Error("Field node returns "+ln.getType()+", but need "+td+" in "+md);
+ }
+ } else {
+ throw new Error("Field node returns "+ln.getType()+", but need "+td+" in "+md);
+ }
+ }
}
void checkNameNode(Descriptor md, SymbolTable nametable, NameNode nn, TypeDescriptor td) {
}
if (!postinc&&!typeutil.isSuperorType(an.getDest().getType(),an.getSrc().getType())) {
- throw new Error("Type of rside ("+an.getSrc().getType().toPrettyString()+") not compatible with type of lside ("+an.getDest().getType().toPrettyString()+")"+an.printNode(0));
+ TypeDescriptor dt = an.getDest().getType();
+ TypeDescriptor st = an.getSrc().getType();
+ Long l = an.getSrc().evaluate();
+ if((st.isByte() || st.isShort() || st.isChar() || st.isInt())
+ && (l != null)
+ && (dt.isByte() || dt.isShort() || dt.isChar() || dt.isInt() || dt.isLong())) {
+ long lnvalue = l.longValue();
+ if((dt.isByte() && ((lnvalue > 127) || (lnvalue < -128)))
+ || (dt.isShort() && ((lnvalue > 32767) || (lnvalue < -32768)))
+ || (dt.isChar() && ((lnvalue > 65535) || (lnvalue < 0)))
+ || (dt.isInt() && ((lnvalue > 2147483647) || (lnvalue < -2147483648)))
+ || (dt.isLong() && ((lnvalue > 9223372036854775807L) || (lnvalue < -9223372036854775808L)))) {
+ throw new Error("Field node returns "+st+", but need "+dt+" in "+md);
+ }
+ } else {
+ throw new Error("Type of rside ("+an.getSrc().getType().toPrettyString()+") not compatible with type of lside ("+an.getDest().getType().toPrettyString()+")"+an.printNode(0));
+ }
}
}
public int kind() {
return Kind.TertiaryNode;
}
+
+ public Long evaluate() {
+ eval = null;
+ Long c = this.cond.evaluate();
+ if(c != null) {
+ Long t = this.trueExpr.evaluate();
+ if(t != null) {
+ Long f = this.falseExpr.evaluate();
+ if(f != null) {
+ if(c.intValue() > 0) {
+ eval = t;
+ } else {
+ eval = f;
+ }
+ }
+ }
+ }
+ return eval;
+ }
}
\ No newline at end of file
--- /dev/null
+class AssignmentConversionTest {
+ public static final int sfi = 100;
+
+ public static void main(String[] args) {
+ short s = 12; // narrow 12 to short
+ float f = s; // widen short to float
+ System.out.println("f=12 : " + (int)f);
+
+ char c = '\u0009';
+ int l = c; // widen char to int
+ System.out.println("l=0x9 : 0x" + Integer.toString(l));
+
+ f = 1.23f;
+ double d = f; // widen float to double
+ System.out.println("d=123 : " + (int)(d*100));
+
+ s = AssignmentConversionTest.sfi;
+ System.out.println("s=100 : " + s);
+
+ s = 12+2;
+ System.out.println("s=12+2=" + (12+2) + ": "+ s);
+
+ s = 12-2;
+ System.out.println("s=12-2=" + (12-2) + ": "+ s);
+
+ s = 12*2;
+ System.out.println("s=12*2=" + (12*2) + ": "+ s);
+
+ s = 12/2;
+ System.out.println("s=12/2=" + (12/2) + ": "+ s);
+
+ s = 12%2;
+ System.out.println("s=12%2=" + (12%2) + ": "+ s);
+
+ s = 12|2;
+ System.out.println("s=12|2=" + (12|2) + ": "+ s);
+
+ s = 12^2;
+ System.out.println("s=12^2=" + (12^2) + ": "+ s);
+
+ s = 12&2;
+ System.out.println("s=12&2=" + (12&2) + ": "+ s);
+
+ s = 12>2?1:2;
+ System.out.println("s=12>2?1:2=" + (12>2?1:2) + ": "+ s);
+
+ s = 12<2?1:2;
+ System.out.println("s=12<2?1:2=" + (12<2?1:2) + ": "+ s);
+
+ /*
+ byte a = 12<2;
+
+ s = 12%2?1:2;
+ System.out.println("s=12&2=" + (12%2?1:2) + ": "+ s);
+
+ short se = 123;
+ char ce = se; // error: would require cast
+ se = ce; // error: would require cast
+ */
+ }
+}