package jode; import sun.tools.java.Type; import sun.tools.java.Constants; import sun.tools.java.FieldDefinition; public class Expression extends Instruction { Operator operator; Expression[] subExpressions; Expression parent = null; public Expression(Operator op, Expression[] sub) { super(MyType.tUnknown); operator = op; subExpressions = sub; operator.setExpression(this); if (subExpressions.length != op.getOperandCount()) throw new AssertError ("Operand count mismatch: "+ subExpressions.length + " != " + op.getOperandCount()); if (subExpressions.length > 0) { Type types[] = new Type[subExpressions.length]; for (int i=0; i < types.length; i++) { subExpressions[i].parent = this; types[i] = subExpressions[i].getType(); } operator.setOperandType(types); updateSubTypes(); } this.type = operator.getType(); } public Expression negate() { if (operator.operator >= operator.COMPARE_OP && operator.operator < operator.COMPARE_OP+6) { operator.setOperator(operator.getOperator() ^ 1); return this; } else if (operator.operator == operator.LOG_AND_OP || operator.operator == operator.LOG_OR_OP) { operator.setOperator(operator.getOperator() ^ 1); for (int i=0; i< subExpressions.length; i++) { subExpressions[i] = subExpressions[i].negate(); } return this; } else if (operator.operator == operator.LOG_NOT_OP) { return subExpressions[0]; } Operator negop = new UnaryOperator(Type.tBoolean, Operator.LOG_NOT_OP); Expression[] e = { this }; return new Expression(negop, e); } public Expression tryToCombine(Expression e) { if (e.operator instanceof StoreInstruction) { StoreInstruction store = (StoreInstruction) e.operator; Expression search = this; while (true) { if (store.matches(search.operator)) { int i; for (i=0; i < e.subExpressions.length-1; i++) { if (!e.subExpressions[i].equals (search.subExpressions[i])) break; } if (i == e.subExpressions.length-1) { search.operator = new AssignOperator(store.getOperator(), store); search.subExpressions = e.subExpressions; return this; } } if (search.subExpressions.length == 0) break; if (search.getOperator() instanceof AssignOperator) search = search.subExpressions[subExpressions.length-1]; else if (search.getOperator() instanceof StringAddOperator && search.subExpressions[1] == emptyString) search = search.subExpressions[1]; else search = search.subExpressions[0]; } } return null; } public Operator getOperator() { return operator; } public Expression[] getSubExpressions() { return subExpressions; } public void updateSubTypes() { for (int i=0; i < subExpressions.length; i++) { subExpressions[i].setType(operator.getOperandType(i)); } } public void setType(Type newType) { newType = MyType.intersection(type, newType); if (newType != type) { type = newType; operator.setType(type); } } public boolean isVoid() { return operator.getType() == Type.tVoid; } String toString(int minPriority) { String[] expr = new String[subExpressions.length]; for (int i=0; i