package net.iplantevin.ql.evaluation; import net.iplantevin.ql.ast.expressions.Expression; import net.iplantevin.ql.ast.expressions.Par; import net.iplantevin.ql.ast.expressions.literals.Bool; import net.iplantevin.ql.ast.expressions.literals.ID; import net.iplantevin.ql.ast.expressions.literals.Int; import net.iplantevin.ql.ast.expressions.literals.Str; import net.iplantevin.ql.ast.expressions.operators.Add; import net.iplantevin.ql.ast.expressions.operators.And; import net.iplantevin.ql.ast.expressions.operators.Binary; import net.iplantevin.ql.ast.expressions.operators.Div; import net.iplantevin.ql.ast.expressions.operators.EQ; import net.iplantevin.ql.ast.expressions.operators.GEQ; import net.iplantevin.ql.ast.expressions.operators.GT; import net.iplantevin.ql.ast.expressions.operators.LEQ; import net.iplantevin.ql.ast.expressions.operators.LT; import net.iplantevin.ql.ast.expressions.operators.Mul; import net.iplantevin.ql.ast.expressions.operators.NEQ; import net.iplantevin.ql.ast.expressions.operators.Neg; import net.iplantevin.ql.ast.expressions.operators.Not; import net.iplantevin.ql.ast.expressions.operators.Or; import net.iplantevin.ql.ast.expressions.operators.Pos; import net.iplantevin.ql.ast.expressions.operators.Sub; import net.iplantevin.ql.ast.expressions.operators.Unary; import net.iplantevin.ql.ast.visitors.IExpressionVisitor; import java.util.HashMap; import java.util.Map; /** * Visitor that takes an expression and returns the appropriate value. * * @author Ivan */ public class EvaluationVisitor implements IExpressionVisitor<Value> { private final Map<String, Value> values; public EvaluationVisitor() { values = new HashMap<String, Value>(); } public void storeValue(String identifier, Value value) { values.put(identifier, value); } public Value getValue(String identifier) { if (values.containsKey(identifier)) { return values.get(identifier); } else { return new UndefinedVal(); } } public Value evaluate(Expression expression) { try { return expression.accept(this); } catch (ArithmeticException e) { return new UndefinedVal(); } catch (Exception e) { return new UndefinedVal(); } } private Value leftValue(Binary expression) { return expression.getLeftHS().accept(this); } private Value rightValue(Binary expression) { return expression.getRightHS().accept(this); } private Value unaryValue(Unary expression) { return expression.getExpression().accept(this); } ///////////////////////////////////////////// // Expression visitor methods ///////////////////////////////////////////// @Override public Value visit(Par par) { return par.getExpression().accept(this); } @Override public Value visit(Add add) { return leftValue(add).add(rightValue(add)); } @Override public Value visit(And and) { return leftValue(and).and(rightValue(and)); } @Override public Value visit(Div div) { return leftValue(div).div(rightValue(div)); } @Override public Value visit(EQ eq) { return leftValue(eq).equal(rightValue(eq)); } @Override public Value visit(GEQ geq) { return leftValue(geq).geq(rightValue(geq)); } @Override public Value visit(GT gt) { return leftValue(gt).gt(rightValue(gt)); } @Override public Value visit(LEQ leq) { return leftValue(leq).leq(rightValue(leq)); } @Override public Value visit(LT lt) { return leftValue(lt).lt(rightValue(lt)); } @Override public Value visit(Mul mul) { return leftValue(mul).mul(rightValue(mul)); } @Override public Value visit(Neg neg) { return unaryValue(neg).neg(); } @Override public Value visit(NEQ neq) { return leftValue(neq).notEqual(rightValue(neq)); } @Override public Value visit(Not not) { return unaryValue(not).not(); } @Override public Value visit(Or or) { return leftValue(or).or(rightValue(or)); } @Override public Value visit(Pos pos) { return unaryValue(pos).pos(); } @Override public Value visit(Sub sub) { return leftValue(sub).sub(rightValue(sub)); } @Override public Value visit(Bool bool) { return new BoolVal(bool.getValue()); } @Override public Value visit(ID id) { return getValue(id.getName()); } @Override public Value visit(Int integer) { return new IntVal(integer.getValue()); } @Override public Value visit(Str str) { return new StrVal(str.getText()); } }