package jeql.syntax; import jeql.api.error.ExecutionException; import jeql.engine.Scope; import jeql.syntax.operation.ArithmeticOperation; import jeql.syntax.operation.BooleanOperation; import jeql.syntax.operation.ComparisonOperation; import jeql.syntax.operation.Operation; import jeql.syntax.operation.RegExOperation; public class BinaryExpressionNode extends ParseTreeNode { private String opStr; private int opCode; private ParseTreeNode e1; private ParseTreeNode e2; private Operation operation; public BinaryExpressionNode(String opStr, ParseTreeNode e1, ParseTreeNode e2, int line) { setLoc(line); this.opStr = opStr; this.opCode = Operation.toOpcode(opStr); this.e1 = e1; this.e2 = e2; switch(opCode) { case Operation.RE_FIND: case Operation.RE_MATCH: operation = new RegExOperation(e1, e2, opStr, opCode); break; case Operation.GT: case Operation.GE: case Operation.LT: case Operation.LE: case Operation.EQ: case Operation.NE: operation = new ComparisonOperation(e1, e2, opStr, opCode); break; case Operation.AND: case Operation.OR: case Operation.XOR: operation = new BooleanOperation(e1, e2, opStr, opCode); break; default: operation = new ArithmeticOperation(e1, e2, opStr, opCode); } } public int getOpCode() { return opCode; } /** * Gets the operand from a given side of the expression * @param side 0 or 1, for LHS or RHS * @return */ public ParseTreeNode getSide(int side) { if (side == 0) return e1; return e2; } public Class getType(Scope scope) { return operation.getType(scope); /* if (Operation.isRelOp(opCode)) return Boolean.class; Class t1 = e1.getType(scope); Class t2 = e2.getType(scope); return Operation.getType(t1, t2); */ } public void bind(Scope scope) { e1.bind(scope); e2.bind(scope); } public Object eval(Scope scope) { Object v1 = e1.eval(scope); // short circuits for boolean operations if (opCode == Operation.AND) { if (v1 != null && ((Boolean) v1).booleanValue() == false) { return Boolean.FALSE; } } if (opCode == Operation.OR) { if (v1 != null && ((Boolean) v1).booleanValue() == true) { return Boolean.TRUE; } } Object v2 = e2.eval(scope); return operation.compute(v1, v2); } }