package zinara.ast.expression; import zinara.ast.type.*; import zinara.code_generator.*; import zinara.exceptions.TypeClashException; import zinara.exceptions.InvalidCodeException; import zinara.parser.sym; import zinara.parser.parser; import java.io.IOException; public class BinaryRelationalExp extends BooleanExp { public int operator; public Expression left; public Expression right; public BinaryRelationalExp (int o, Expression l, Expression r) throws TypeClashException { operator=o; left=l; right=r; type = parser.operators.check(this.operator, this.left.getType(), this.right.getType()); if ((l.getType().getType() instanceof IntType) && (r.getType().getType() instanceof FloatType)) left = new CastedExp(new FloatType(), l); else if ((l.getType().getType() instanceof FloatType) && (r.getType().getType() instanceof IntType)) right = new CastedExp(new FloatType(), r); } public Type getType() { return type; } public String toString() { return "("+left + " " + operator + " " + right+")" ; } public void tox86(Genx86 generator) throws IOException,InvalidCodeException{ left.register = register; right.register = register + 1; String leftReg = generator.regName(left.register,left.type); String rightReg = generator.regName(right.register,right.type); //save generator.write(generator.save(register+1)); left.tox86(generator); right.tox86(generator); generator.write(generator.compare(leftReg,rightReg, left.type,right.type)); switch(operator) { case sym.LT: lowerThan(generator, leftReg, rightReg, false); break; case sym.GT: greaterThan(generator, leftReg, rightReg, false); break; case sym.LTE: lowerThan(generator, leftReg, rightReg, true); break; case sym.GTE: greaterThan(generator, leftReg, rightReg, true); break; case sym.SHEQ: equal(generator, leftReg, rightReg, false); break; case sym.DEEQ: equal(generator, leftReg, rightReg, true); break; case sym.NOEQ: notEqual(generator, leftReg, rightReg); } //restore generator.write(generator.restore(register+1)); generator.write(generator.jump(noLabel)); } public void lowerThan(Genx86 generator, String a, String b, boolean orEqual) throws IOException,InvalidCodeException { if (orEqual) generator.write(generator.jle(yesLabel)); else generator.write(generator.jl(yesLabel)); } public void greaterThan(Genx86 generator, String a, String b, boolean orEqual) throws IOException,InvalidCodeException { if (orEqual) generator.write(generator.jge(yesLabel)); else generator.write(generator.jg(yesLabel)); } public void equal(Genx86 generator, String a, String b, boolean deep) throws IOException,InvalidCodeException { generator.write(generator.je(yesLabel)); } public void notEqual(Genx86 generator, String a, String b) throws IOException,InvalidCodeException { generator.write(generator.jne(yesLabel)); } public boolean isStaticallyKnown() { return left.isStaticallyKnown() && right.isStaticallyKnown(); } public Object staticValue() { Object leftO = left.staticValue(); Object rightO = right.staticValue(); if (leftO instanceof Integer && rightO instanceof Integer) { int leftE = ((Integer)leftO).intValue(); int rightE = ((Integer)rightO).intValue(); switch(operator) { case sym.LT: return new Boolean(leftE < rightE); case sym.GT: return new Boolean(leftE > rightE); case sym.LTE: return new Boolean(leftE <= rightE); case sym.GTE: return new Boolean(leftE >= rightE); case sym.SHEQ: return new Boolean(leftE == rightE); case sym.DEEQ: return new Boolean(leftE == rightE); case sym.NOEQ: return new Boolean(leftE != rightE); } } else if (leftO instanceof Float && rightO instanceof Float) { float leftE = ((Float)leftO).floatValue(); float rightE = ((Float)rightO).floatValue(); switch(operator) { case sym.LT: return new Boolean(leftE < rightE); case sym.GT: return new Boolean(leftE > rightE); case sym.LTE: return new Boolean(leftE <= rightE); case sym.GTE: return new Boolean(leftE >= rightE); case sym.SHEQ: return new Boolean(leftE == rightE); case sym.DEEQ: return new Boolean(leftE == rightE); case sym.NOEQ: return new Boolean(leftE != rightE); } } else if (leftO instanceof Character && rightO instanceof Character) { char leftE = ((Character)leftO).charValue(); char rightE = ((Character)rightO).charValue(); switch(operator) { case sym.LT: return new Boolean(leftE < rightE); case sym.GT: return new Boolean(leftE > rightE); case sym.LTE: return new Boolean(leftE <= rightE); case sym.GTE: return new Boolean(leftE >= rightE); case sym.SHEQ: return new Boolean(leftE == rightE); case sym.DEEQ: return new Boolean(leftE == rightE); case sym.NOEQ: return new Boolean(leftE != rightE); } } else if (leftO instanceof Boolean && rightO instanceof Boolean) { boolean leftE = ((Boolean)leftO).booleanValue(); boolean rightE = ((Boolean)rightO).booleanValue(); switch(operator) { case sym.LT: return new Boolean(relationalBoolean(leftE, rightE, 0)); case sym.GT: return new Boolean(relationalBoolean(leftE, rightE, 1)); case sym.LTE: return new Boolean(relationalBoolean(leftE, rightE, 2)); case sym.GTE: return new Boolean(relationalBoolean(leftE, rightE, 3)); case sym.SHEQ: return new Boolean(leftE == rightE); case sym.DEEQ: return new Boolean(leftE == rightE); case sym.NOEQ: return new Boolean(leftE != rightE); } } else if (leftO instanceof Integer && rightO instanceof Float) { int leftE = ((Integer)leftO).intValue(); float rightE = ((Float)rightO).floatValue(); switch(operator) { case sym.LT: return new Boolean(leftE < rightE); case sym.GT: return new Boolean(leftE > rightE); case sym.LTE: return new Boolean(leftE <= rightE); case sym.GTE: return new Boolean(leftE >= rightE); case sym.SHEQ: return new Boolean(leftE == rightE); case sym.DEEQ: return new Boolean(leftE == rightE); case sym.NOEQ: return new Boolean(leftE != rightE); } } else if (leftO instanceof Float && rightO instanceof Integer) { float leftE = ((Float)leftO).floatValue(); int rightE = ((Integer)rightO).intValue(); switch(operator) { case sym.LT: return new Boolean(leftE < rightE); case sym.GT: return new Boolean(leftE > rightE); case sym.LTE: return new Boolean(leftE <= rightE); case sym.GTE: return new Boolean(leftE >= rightE); case sym.SHEQ: return new Boolean(leftE == rightE); case sym.DEEQ: return new Boolean(leftE == rightE); case sym.NOEQ: return new Boolean(leftE != rightE); } } return null; } public boolean relationalBoolean(boolean o1, boolean o2, int type) { return false; } }