private Expr cleanupOpExpr(OpExpr opExp) { FunctionalRef ref = opExp.getOp(); List<Expr> args = opExp.getArgs(); if (args.size() <= 1) return opExp; IdOrOp name = ref.getNames().get(0); if (!(name instanceof Op)) return bug(name, "The name field of OpRef should be Op."); Op qop = (Op) name; if (OprUtil.isEnclosing(qop)) return opExp; if (OprUtil.isUnknownFixity(qop)) return bug(opExp, "The operator fixity is unknown: " + ((Op) qop).getText()); boolean prefix = OprUtil.hasPrefixColon(qop); boolean suffix = OprUtil.hasSuffixColon(qop); if (!prefix && !suffix) return opExp; qop = OprUtil.noColon(qop); Iterator<Expr> i = args.iterator(); Expr res = i.next(); Span sp = NodeUtil.getSpan(opExp); for (Expr arg : Iter.iter(i)) { if (prefix) { res = thunk(res); } if (suffix) { arg = thunk(arg); } res = ExprFactory.makeOpExpr(sp, qop, res, arg); } return res; }
@Override public Node forOpExpr(OpExpr that) { FunctionalRef op_result = (FunctionalRef) recur(that.getOp()); /** * * For BIG OP <| BIG OT <| f y | y <- ys |> | ys <- gg |> Is this case, BIG <||> is being * removed. The nested reduction is replaced with __bigOperator2(BIG OP, BIG OT, gg) * * <p>by Kento */ String str = op_result.toString(); String theListEnclosingOperatorName = "BIG <| BIG |>"; String someBigOperatorName = "BIG"; // make sure the body is of application of some big operator if ((str.length() >= someBigOperatorName.length() && str.substring(0, someBigOperatorName.length()).equals(someBigOperatorName))) { // make sure that BIG OP (Accumulator (BIG <||>, gs)) if (that.getArgs().size() == 1 && that.getArgs().get(0) instanceof Accumulator && ((Accumulator) that.getArgs().get(0)) .getAccOp() .toString() .equals(theListEnclosingOperatorName)) { Accumulator acc = (Accumulator) that.getArgs().get(0); Expr body = visitGenerators(NodeUtil.getSpan(acc), acc.getGens(), acc.getBody()); /** * * If the accumulation is a nested reduction like <| BIG OT <| f y | y <- ys |> | ys <- gg * |> , visitGenerators returns a tuple of ((BIG OT, f), gg) (this should be refactored, * though) In this case, the nested reduction is replaced with __bigOperator2 */ if (body instanceof TupleExpr) { // a tuple of the inner Accumulator (op, body) and the gg TupleExpr tuple = (TupleExpr) body; TupleExpr innerAccumTuple = (TupleExpr) tuple.getExprs().get(0); Expr opexpI = (Expr) innerAccumTuple.getExprs().get(0); Expr innerBody = (Expr) innerAccumTuple.getExprs().get(1); FunctionalRef ref = (FunctionalRef) op_result; IdOrOp name = ref.getNames().get(0); // make sure the operator is actually an operator if (!(name instanceof Op)) return null; Expr opexpO = ExprFactory.makeOpExpr(NodeUtil.getSpan(that), (Op) name, ref.getStaticArgs()); Expr gg = tuple.getExprs().get(1); Expr res = ExprFactory.make_RewriteFnApp( NodeUtil.getSpan(that), BIGOP2_NAME, ExprFactory.makeTupleExpr(NodeUtil.getSpan(body), opexpO, opexpI, gg, innerBody)); return (Expr) recur(res); } } } List<Expr> args_result = recurOnListOfExpr(that.getArgs()); OpExpr new_op; if (op_result == that.getOp() && args_result == that.getArgs()) { new_op = that; } else { new_op = ExprFactory.makeOpExpr( NodeUtil.getSpan(that), NodeUtil.isParenthesized(that), NodeUtil.getExprType(that), op_result, args_result); } return cleanupOpExpr(new_op); }