package ql.ast.expression_evaluator; import ql.ast.expression.Id; import ql.ast.expression.ParenthesesExpression; import ql.ast.expression.arithmetic.Add; import ql.ast.expression.arithmetic.Divide; import ql.ast.expression.arithmetic.Multiply; import ql.ast.expression.arithmetic.Remainder; import ql.ast.expression.arithmetic.Subtract; import ql.ast.expression.arithmetic.UnaryMinus; import ql.ast.expression.arithmetic.UnaryPlus; import ql.ast.expression.comparison.Equal; import ql.ast.expression.comparison.GreaterThan; import ql.ast.expression.comparison.GreaterThanEqual; import ql.ast.expression.comparison.LessThan; import ql.ast.expression.comparison.LessThanEqual; import ql.ast.expression.comparison.NotEqual; import ql.ast.expression.literal.BooleanLiteral; import ql.ast.expression.literal.NumberLiteral; import ql.ast.expression.literal.StringLiteral; import ql.ast.expression.logical.LogicalAnd; import ql.ast.expression.logical.LogicalOr; import ql.ast.expression.logical.Not; import ql.ast.expression_value.BooleanValue; import ql.ast.expression_value.IValue; import ql.ast.expression_value.NullValue; import ql.ast.expression_value.NumberValue; import ql.ast.expression_value.StringValue; import ql.ast.type.NumberType; import ql.ast.visitor_elements.IExpressionElementVisitor; /** * @author orosu */ public class ExpressionEvaluatorVisitor implements IExpressionElementVisitor<IValue> { private final ValueEnvironment _valueEnvironment; // used to get value by id public ExpressionEvaluatorVisitor(ValueEnvironment valueEnvironment) { this._valueEnvironment = valueEnvironment; } @Override public IValue visit(Id id) { return this._valueEnvironment.getById(id.getValue()); } @Override public IValue visit(Add add) { IValue leftValue = add.getLeftSubExpression().accept(this); IValue rightValue = add.getRightSubExpression().accept(this); if (leftValue.equals(new NullValue()) || rightValue.equals(new NullValue())) { return new NullValue(); } return ((NumberValue) leftValue).add((NumberValue) rightValue); } @Override public IValue visit(Divide divide) { IValue leftValue = divide.getLeftSubExpression().accept(this); IValue rightValue = divide.getRightSubExpression().accept(this); if (leftValue.equals(new NullValue()) || rightValue.equals(new NullValue())) { return new NullValue(); } return ((NumberValue) leftValue).divide((NumberValue) rightValue); } @Override public IValue visit(Multiply multiply) { IValue leftValue = multiply.getLeftSubExpression().accept(this); IValue rightValue = multiply.getRightSubExpression().accept(this); if (leftValue.equals(new NullValue()) || rightValue.equals(new NullValue())) { return new NullValue(); } return ((NumberValue) leftValue).multiply((NumberValue) rightValue); } @Override public IValue visit(Remainder remainder) { IValue leftValue = remainder.getLeftSubExpression().accept(this); IValue rightValue = remainder.getRightSubExpression().accept(this); if (leftValue.equals(new NullValue()) || rightValue.equals(new NullValue())) { return new NullValue(); } return ((NumberValue) leftValue).remainder((NumberValue) rightValue); } @Override public IValue visit(Subtract subtract) { IValue leftValue = subtract.getLeftSubExpression().accept(this); IValue rightValue = subtract.getRightSubExpression().accept(this); if (leftValue.equals(new NullValue()) || rightValue.equals(new NullValue())) { return new NullValue(); } return ((NumberValue) leftValue).subtract((NumberValue) rightValue); } @Override public IValue visit(GreaterThan greaterThan) { IValue leftValue = greaterThan.getLeftSubExpression().accept(this); IValue rightValue = greaterThan.getRightSubExpression().accept(this); if (leftValue.equals(new NullValue()) || rightValue.equals(new NullValue())) { return new NullValue(); } return ((NumberValue) leftValue).greaterThan((NumberValue) rightValue); } @Override public IValue visit(GreaterThanEqual greaterThanEqual) { IValue leftValue = greaterThanEqual.getLeftSubExpression().accept(this); IValue rightValue = greaterThanEqual.getRightSubExpression().accept(this); if (leftValue.equals(new NullValue()) || rightValue.equals(new NullValue())) { return new NullValue(); } return ((NumberValue) leftValue).greaterThanEqual((NumberValue) rightValue); } @Override public IValue visit(LessThan lessThan) { IValue leftValue = lessThan.getLeftSubExpression().accept(this); IValue rightValue = lessThan.getRightSubExpression().accept(this); if (leftValue.equals(new NullValue()) || rightValue.equals(new NullValue())) { return new NullValue(); } return ((NumberValue) leftValue).lessThan((NumberValue) rightValue); } @Override public IValue visit(LessThanEqual lessThanEqual) { IValue leftValue = lessThanEqual.getLeftSubExpression().accept(this); IValue rightValue = lessThanEqual.getRightSubExpression().accept(this); if (leftValue.equals(new NullValue()) || rightValue.equals(new NullValue())) { return new NullValue(); } return ((NumberValue) leftValue).lessThanEqual((NumberValue) rightValue); } @Override public BooleanValue visit(LogicalAnd logicalAnd) { BooleanValue leftValue = (BooleanValue) logicalAnd.getLeftSubExpression().accept(this); BooleanValue rightValue = (BooleanValue) logicalAnd.getRightSubExpression().accept(this); return leftValue.and(rightValue); } @Override public BooleanValue visit(LogicalOr logicalOr) { BooleanValue leftValue = (BooleanValue) logicalOr.getLeftSubExpression().accept(this); BooleanValue rightValue = (BooleanValue) logicalOr.getRightSubExpression().accept(this); return leftValue.or(rightValue); } @Override public BooleanValue visit(Equal equal) { IValue leftValue = equal.getLeftSubExpression().accept(this); IValue rightValue = equal.getRightSubExpression().accept(this); return new BooleanValue(leftValue.equalsValue(rightValue)); } @Override public IValue visit(NotEqual notEqual) { IValue leftValue = notEqual.getLeftSubExpression().accept(this); IValue rightValue = notEqual.getRightSubExpression().accept(this); return new BooleanValue(!leftValue.equalsValue(rightValue)); } @Override public IValue visit(Not not) { IValue value = not.getSubExpression().accept(this); if (value.equals(new NullValue())) { return new NullValue(); } return ((BooleanValue) value).not(); } @Override public IValue visit(UnaryMinus unaryMinus) { IValue value = unaryMinus.getSubExpression().accept(this); return ((NumberValue) value).unaryMinus(); } @Override public IValue visit(UnaryPlus unaryPlus) { IValue value = unaryPlus.getSubExpression().accept(this); return ((NumberValue) value).unaryPlus(); } @Override public IValue visit(ParenthesesExpression parensExpr) { return parensExpr.getSubExpression().accept(this); } @Override public BooleanValue visit(BooleanLiteral booleanLiteral) { return new BooleanValue(booleanLiteral.getLiteral()); } @Override public NumberValue visit(NumberLiteral numberLiteral) { return ((NumberType) numberLiteral.getType()).accept( new NumberTypeValueGetterVisitor(numberLiteral.getLiteral()) ); } @Override public StringValue visit(StringLiteral stringLiteral) { return new StringValue(stringLiteral.getLiteral()); } }