package Models.Expressions; import Exceptions.BaseException; import Models.Program.IDictionary; import Models.Program.IHeap; import Models.Types.BooleanType; import Models.Types.IType; import Models.Types.IntegerType; import Models.Values.BooleanValue; import Models.Values.IValue; import Models.Values.IntegerValue; public class RelationalExpression implements IExpression { private IExpression leftExpression; private IExpression rightExpression; private String operator; public RelationalExpression(IExpression leftExpression, IExpression rightExpression, String operator) { this.leftExpression = leftExpression; this.rightExpression = rightExpression; this.operator = operator; } public IExpression copy() { return new RelationalExpression(this.leftExpression.copy(), this.rightExpression.copy(), this.operator); } public String toString() { return this.leftExpression.toString() + " " + this.operator + " " + this.rightExpression.toString(); } public IValue evaluate(IDictionary symbolTable, IHeap heap) throws BaseException { var leftValue = this.leftExpression.evaluate(symbolTable, heap); var rightValue = this.rightExpression.evaluate(symbolTable, heap); if (leftValue.getType().equals(new IntegerType()) && rightValue.getType().equals(new IntegerType())) { var leftIntegerValue = (IntegerValue) leftValue; var rightIntegerValue = (IntegerValue) rightValue; var leftInteger = leftIntegerValue.getValue(); var rightInteger = rightIntegerValue.getValue(); switch (this.operator) { case "<": return new BooleanValue(leftInteger < rightInteger); case "<=": return new BooleanValue(leftInteger <= rightInteger); case "==": return new BooleanValue(leftInteger == rightInteger); case "!=": return new BooleanValue(leftInteger != rightInteger); case ">": return new BooleanValue(leftInteger > rightInteger); case ">=": return new BooleanValue(leftInteger >= rightInteger); default: throw new BaseException("RelationalExpression: Invalid operator"); } } throw new BaseException("RelationalExpression: Operands are not of type IntegerType"); } public IType typeCheck(IDictionary typeTable) throws BaseException { var leftType = this.leftExpression.typeCheck(typeTable); var rightType = this.rightExpression.typeCheck(typeTable); if (leftType.equals(new IntegerType())) { if (rightType.equals(new IntegerType())) { return new BooleanType(); } throw new BaseException("RelationalExpression: Right operand is not of type IntegerType"); } throw new BaseException("RelationalExpression: Left operand is not of type IntegerType"); } }