private Expr ternary(Expr condition, Expr thenExpr, Expr elseExpr) { return new ParenExpr(new TernaryExpr(condition, thenExpr, elseExpr)); }
@Override public Expr generateExpr(IRandom generator, Expr... args) { assert args.length == getNumArguments(); return new ParenExpr(new TernaryExpr(args[0], args[1], args[2])); }
@Override public Expr visitConditional_expression(Conditional_expressionContext ctx) { assert ctx.expression().size() == ctx.assignment_expression().size(); // First, visit all the args, slapping them into a list List<Expr> argsInOrder = new ArrayList<>(); argsInOrder.add(visitLogical_or_expression(ctx.logical_or_expression())); for (int i = 0; i < ctx.expression().size(); i++) { argsInOrder.add(visitExpression(ctx.expression(i))); argsInOrder.add(visitAssignment_expression(ctx.assignment_expression(i))); } assert (argsInOrder.size() % 2) == 1; // should be an odd number of args in total // Now visit the list in reverse order, building up the ternary Expr result = argsInOrder.get(argsInOrder.size() - 1); for (int i = argsInOrder.size() - 2; i >= 0; i -= 2) { assert (i % 2) == 1; result = new TernaryExpr(argsInOrder.get(i - 1), argsInOrder.get(i), result); } return result; }
@Override public TernaryExpr clone() { return new TernaryExpr(test.clone(), thenExpr.clone(), elseExpr.clone()); }
@Override public void visitArrayIndexExpr(ArrayIndexExpr arrayIndexExpr) { Type type = typer.lookupType(arrayIndexExpr.getArray()); if (type == null) { return; } type = type.getWithoutQualifiers(); assert isArrayVectorOrMatrix(type); if (!staticallyInBounds(arrayIndexExpr.getIndex(), type)) { arrayIndexExpr.setIndex(new TernaryExpr( new BinaryExpr( new BinaryExpr( new ParenExpr(arrayIndexExpr.getIndex().clone()), new IntConstantExpr("0"), BinOp.GE), new BinaryExpr( new ParenExpr(arrayIndexExpr.getIndex().clone()), new IntConstantExpr(getSize(type).toString()), BinOp.LT), BinOp.LAND), arrayIndexExpr.getIndex(), new IntConstantExpr("0")) ); } super.visitArrayIndexExpr(arrayIndexExpr); }