package qlProject.auxiliary_expression_visitors; import java.util.Map; import qlProject.ast.expression.BinaryExpression; import qlProject.ast.expression.IExpression; import qlProject.ast.expression.IExpressionVisitor; import qlProject.ast.expression.Id; import qlProject.ast.expression.ParenthesisExpr; import qlProject.ast.expression.StringExpr.ConcatenationExpr; import qlProject.ast.expression.StringExpr.StringLiteral; import qlProject.ast.expression.arithmeticExpr.AdditionExpr; import qlProject.ast.expression.arithmeticExpr.DivisionExpr; import qlProject.ast.expression.arithmeticExpr.IntLiteral; import qlProject.ast.expression.arithmeticExpr.MultiplicationExpr; import qlProject.ast.expression.arithmeticExpr.NegationExpr; import qlProject.ast.expression.arithmeticExpr.SubtractionExpr; import qlProject.ast.expression.booleanExpr.BoolLiteral; import qlProject.ast.expression.booleanExpr.comparisonExpression.BiggerEqExpr; import qlProject.ast.expression.booleanExpr.comparisonExpression.BiggerThanExpr; import qlProject.ast.expression.booleanExpr.comparisonExpression.EqualExpr; import qlProject.ast.expression.booleanExpr.comparisonExpression.SmallerEqExpr; import qlProject.ast.expression.booleanExpr.comparisonExpression.SmallerThanExpr; import qlProject.ast.expression.booleanExpr.comparisonExpression.UnequalExpr; import qlProject.ast.expression.booleanExpr.logicalExpression.AndExpr; import qlProject.ast.expression.booleanExpr.logicalExpression.NotExpr; import qlProject.ast.expression.booleanExpr.logicalExpression.OrExpr; import qlProject.ast.value.BoolValue; import qlProject.ast.value.IntValue; import qlProject.ast.value.NullValue; import qlProject.ast.value.StringValue; import qlProject.ast.value.Value; public class ExpressionEvaluationVisitor implements IExpressionVisitor { private Map<String,Value> valuesMap; public ExpressionEvaluationVisitor(Map<String,Value> valuesMap){ this.valuesMap = valuesMap; } @Override public Object visit(NegationExpr expr) { Value v = visitExpression(expr.getSubExpression()); if (hasNullValue(v)) return new NullValue(); else {int result = (-(int)v.getValue()); return new IntValue(result); } } @Override public Object visit(ParenthesisExpr e) { return visitExpression(e.getSubExpression()); } public Value visit (NotExpr expr){ Value v = visitExpression(expr.getSubExpression()); if (hasNullValue(v)) return new NullValue(); else {boolean result = !(boolean)v.getValue(); return new BoolValue(result); } } @Override public Value visit (Id id){ if (valuesMap == null || !valuesMap.containsKey(id.getIdString())) return new NullValue(); else return valuesMap.get(id.getIdString()); } @Override public Value visit (IntLiteral intLiteral){ return new IntValue(intLiteral.getValue()); } @Override public Value visit (BoolLiteral boolLiteral){ return new BoolValue(boolLiteral.getValue()); } @Override public Value visit(StringLiteral stringLiteral) { return new StringValue(stringLiteral.getValue()); } @Override public Object visit(BiggerThanExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { boolean result = (int)visitExpression(expr.getLeft()).getValue() > (int)visitExpression(expr.getRight()).getValue(); return new BoolValue(result); } } @Override public Object visit(BiggerEqExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { boolean result = (int)visitExpression(expr.getLeft()).getValue() >= (int)visitExpression(expr.getRight()).getValue(); return new BoolValue(result); } } @Override public Object visit(SmallerThanExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { boolean result = (int)visitExpression(expr.getLeft()).getValue() < (int)visitExpression(expr.getRight()).getValue(); return new BoolValue(result); } } @Override public Object visit(SmallerEqExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { boolean result = (int)visitExpression(expr.getLeft()).getValue() <= (int)visitExpression(expr.getRight()).getValue(); return new BoolValue(result); } } @Override public Object visit(EqualExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { Object left = visitExpression(expr.getLeft()).getValue(); Object right = visitExpression(expr.getRight()).getValue(); boolean result = left.equals(right); return new BoolValue(result); } } @Override public Object visit(UnequalExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { boolean result = visitExpression(expr.getLeft()).getValue() != visitExpression(expr.getRight()).getValue(); return new BoolValue(result); } } @Override public Object visit(ConcatenationExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { String result = (String)visitExpression(expr.getLeft()).getValue() + (String)visitExpression(expr.getRight()).getValue(); return new StringValue(result); } } @Override public Object visit(OrExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new BoolValue(false); } else { boolean result = (boolean)visitExpression(expr.getLeft()).getValue() || (boolean)visitExpression(expr.getRight()).getValue(); return new BoolValue(result); } } @Override public Object visit(AndExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new BoolValue(false); } else { boolean result = (boolean)visitExpression(expr.getLeft()).getValue() && (boolean)visitExpression(expr.getRight()).getValue(); return new BoolValue(result); } } @Override public Object visit(AdditionExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { int leftValue = (int)visitExpression(expr.getLeft()).getValue(); int rightValue = (int)visitExpression(expr.getRight()).getValue(); if(sumWithinIntegerRange((Integer)leftValue, (Integer)rightValue)) return new IntValue(leftValue + rightValue); else return new NullValue(); } } @Override public Object visit(SubtractionExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { int leftValue = (int)visitExpression(expr.getLeft()).getValue(); int rightValue = (int)visitExpression(expr.getRight()).getValue(); if(differenceWithinIntegerRange(leftValue, rightValue)) return new IntValue(leftValue - rightValue); else return new NullValue(); } } @Override public Object visit(DivisionExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { int leftValue = (int)visitExpression(expr.getLeft()).getValue(); int rightValue = (int)visitExpression(expr.getRight()).getValue(); if (rightValue != 0) return new IntValue(leftValue / rightValue); else return new NullValue(); } } @Override public Object visit(MultiplicationExpr expr) { if (isNotEvaluableBinaryExpr(expr)){ return new NullValue(); } else { int leftValue = (int)visitExpression(expr.getLeft()).getValue(); int rightValue = (int)visitExpression(expr.getRight()).getValue(); if (productWithinIntegerRagne(leftValue, rightValue)) return new IntValue(leftValue * rightValue); else return new NullValue(); } } public boolean sumWithinIntegerRange(int left, int right){ if(left > 0 == right > 0){ if (left < 0 && (right < Integer.MIN_VALUE - left)){ return false; } if (left > 0 && (right > Integer.MAX_VALUE - left)){ return false; } } return true; } public boolean differenceWithinIntegerRange(int left, int right){ if(left > 0 != right > 0){ if (left < 0 && (right > Integer.MIN_VALUE - left)){ return false; } if (left > 0 && (right < Integer.MAX_VALUE - left)){ return false; } } return true; } public boolean productWithinIntegerRagne(int left, int right){ return Math.abs(left) < (Integer.MAX_VALUE/Math.abs(right)); } public boolean hasNullValue(Value v){ return v.equals(new NullValue()); } public boolean isNotEvaluableBinaryExpr(BinaryExpression expr){ Value l = visitExpression(expr.getLeft()); Value r = visitExpression(expr.getRight()); return (hasNullValue(l) || hasNullValue(r)); } Value visitExpression(IExpression e){ return ((Value)e.accept(this)); } }