@Override public Void visitBinaryExpression(BinaryExpression node) { visit(node.getLeftOperand()); writer.print(' '); writer.print(node.getOperator().getLexeme()); writer.print(' '); visit(node.getRightOperand()); return null; }
// Parses a binary expression private void parse(BinaryExpression be) { BinaryOperator bop = be.getOperator(); SimpleExpression lhs = new SimpleExpression(be.getLHS()); SimpleExpression rhs = new SimpleExpression(be.getRHS()); contains_side_effect |= (lhs.contains_side_effect || rhs.contains_side_effect); if (bop == BinaryOperator.SUBTRACT) { sop = ADD; SimpleExpression new_rhs = new SimpleExpression(MUL); new_rhs.add(getInt(-1)); new_rhs.add(rhs); add(lhs); add(new_rhs); } else { sop = cop.indexOf(bop); if (sop == -1) { sop = TREE; expr = be; } add(lhs); add(rhs); } }
public void visit(BinaryExpression entity) { wGetVisitor1().visit(entity.getLeftExpr()); wGetVisitor1().visit(entity.getOperator()); wGetVisitor1().visit(entity.getRightExpr()); }
/** Normalization for points-to analysis. */ private static Expression normalize(Expression arg, Symbol param) { Expression ret = arg.clone(); // default behavior. // Converts array accesses to address-of expressions. if (ret instanceof ArrayAccess) { ArrayAccess array = (ArrayAccess) ret; // Normalize the array name. Expression name = normalize(array.getArrayName(), null); Symbol base = SymbolTools.getSymbolOf(name); if (base != null && param != null && SymbolTools.isPointerParameter(param)) { // case 1: the base symbol has an array specifier. // --> - keeps the array indices while adding trailing [0]. // - converts to address-of expression. // - adds dereference operator if base is a formal parameter if (SymbolTools.isArray(base)) { // Adds a trailing subscript "[0]" intentionally. array.addIndex(new IntegerLiteral(0)); ret = new UnaryExpression(UnaryOperator.ADDRESS_OF, ret); // Formal parameter is normalized: a[10] to (*a)[10]. // This conversion is used only internally (not legal in C). if (SymbolTools.isPointerParameter(base)) { array .getArrayName() .swapWith(new UnaryExpression(UnaryOperator.DEREFERENCE, name.clone())); } // case 2: the base symbol does not have an array specifier. // --> just take the base object while converting a subscript // to a dereference. } else { ret = name; for (int i = 0; i < array.getNumIndices(); i++) { ret = new UnaryExpression(UnaryOperator.DEREFERENCE, ret.clone()); } } } else { // just normalizes the array name. array.getArrayName().swapWith(name); } // Removes pointer access and adds trailing dummy index for pointer // type. } else if (ret instanceof AccessExpression) { AccessExpression access = (AccessExpression) ret; // POINTER_ACCESS to MEMBER_ACCESS if (access.getOperator() == AccessOperator.POINTER_ACCESS) { // Normalize the LHS. Expression lhs = normalize(access.getLHS(), null); ret = new AccessExpression( new UnaryExpression(UnaryOperator.DEREFERENCE, lhs.clone()), AccessOperator.MEMBER_ACCESS, access.getRHS().clone()); } // Pointer type to address-of expression. if (param != null && SymbolTools.isPointerParameter(param)) { ret = new UnaryExpression( UnaryOperator.ADDRESS_OF, new ArrayAccess(ret.clone(), new IntegerLiteral(0))); } // Just normalize the expression child. } else if (ret instanceof UnaryExpression) { UnaryExpression ue = (UnaryExpression) ret; ue.setExpression(normalize(ue.getExpression(), null)); // Tries to convert simple pointer arithmetic to array access. } else if (ret instanceof BinaryExpression) { BinaryExpression be = (BinaryExpression) ret; Expression lhs = normalize(be.getLHS(), null); Expression rhs = normalize(be.getRHS(), null); if (param != null && SymbolTools.isPointerParameter(param) && be.getOperator() == BinaryOperator.ADD) { if (isPointerArithmeticOperand(lhs, rhs)) { ret = new UnaryExpression( UnaryOperator.ADDRESS_OF, new ArrayAccess(rhs.clone(), lhs.clone())); } else if (isPointerArithmeticOperand(rhs, lhs)) { ret = new UnaryExpression( UnaryOperator.ADDRESS_OF, new ArrayAccess(lhs.clone(), rhs.clone())); } } else { ret = new BinaryExpression(lhs.clone(), be.getOperator(), rhs.clone()); } // Type cast is discarded. } else if (ret instanceof Typecast) { ret = (Expression) ret.getChildren().get(0); } return ret; }
@SuppressWarnings("unchecked") @Override public Function<Object[], ?> visit(BinaryExpression e) { final Function<Object[], ?> first = e.getFirst().accept(this); final Function<Object[], ?> second = e.getSecond().accept(this); switch (e.getExpressionType()) { case ExpressionType.Add: return normalize( add((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.BitwiseAnd: return normalize( bitwiseAnd((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.LogicalAnd: return normalize( and((Function<Object[], Boolean>) first, (Function<Object[], Boolean>) second)); case ExpressionType.ArrayIndex: return t -> Array.get(first.apply(t), (Integer) second.apply(t)); // return new Function<Object, Object[]>() { // // @Override // public Object invoke(Object[] t) throws Throwable { // return Array.get(first.invoke(t), (Integer) second // .invoke(t)); // } // }; // case ExpressionType.Coalesce: // return coalesce((Function<?, Object[]>) first, // (Function<?, Object[]>) second); case ExpressionType.Conditional: return iif((Function<Object[], Boolean>) e.getOperator().accept(this), first, second); case ExpressionType.Divide: return normalize( divide((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.Equal: return normalize(equal(first, second)); case ExpressionType.ExclusiveOr: return normalize( xor((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.GreaterThan: return normalize( greaterThan((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.GreaterThanOrEqual: return normalize( greaterThanOrEqual( (Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.LeftShift: return normalize( shiftLeft((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.LessThan: return normalize( lessThan((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.LessThanOrEqual: return normalize( lessThanOrEqual( (Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.Modulo: return normalize( modulo((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.Multiply: return normalize( multiply((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.NotEqual: return normalize(equal(first, second).negate()); case ExpressionType.BitwiseOr: return normalize( bitwiseOr((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.LogicalOr: return normalize( or((Function<Object[], Boolean>) first, (Function<Object[], Boolean>) second)); // case ExpressionType.Power: // return power((Function<Number, Object[]>) first, // (Function<Number, Object[]>) second); case ExpressionType.RightShift: return normalize( shiftRight((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.Subtract: return normalize( subtract((Function<Object[], Number>) first, (Function<Object[], Number>) second)); case ExpressionType.InstanceOf: return normalize(instanceOf(first, (Class<?>) second.apply(null))); default: throw new IllegalArgumentException(ExpressionType.toString(e.getExpressionType())); } }