public Expression visitConCall()

in base/src/main/java/org/arend/core/expr/visitor/ExpressionTransformer.java [102:204]


  public Expression visitConCall(ConCallExpression expr, P params) {
    Expression it = expr;
    if (expr.getDefinition() == Prelude.SUC) {
      int n = 0;
      Expression result;
      do {
        result = preVisitConCall((ConCallExpression) it, params);
        if (result != null) {
          it = result;
          break;
        }
        n++;
        it = (((ConCallExpression) it).getDefCallArguments()).get(0);
      } while (it instanceof ConCallExpression && ((ConCallExpression) it).getDefinition() == Prelude.SUC);

      if (result == null) {
        it = visit(it, params);
        if (it == null) {
          return null;
        }
      }

      if (it instanceof IntegerExpression) {
        return ((IntegerExpression) it).plus(n);
      }

      return ExpressionFactory.add(it, n);
    }

    if (useStack(expr)) {
      return visitConCallWithStack(expr, params);
    }

    int recursiveParam = expr.getDefinition().getRecursiveParameter();
    Expression result = null;
    ConCallExpression prevConCall = null;
    while (true) {
      ConCallExpression conCall = (ConCallExpression) it;
      it = preVisitConCall(conCall, params);
      if (it != null) {
        if (prevConCall != null) {
          prevConCall.getDefCallArguments().set(recursiveParam, it);
          prevConCall.fixBoxes();
          return result;
        } else {
          return it;
        }
      }

      List<Expression> dataTypeArgs = visitDataTypeArguments(conCall.getDataTypeArguments(), params);
      if (dataTypeArgs == null) return null;
      it = makeConCall(conCall.getDefinition(), conCall.getLevels(), dataTypeArgs, new ArrayList<>());
      if (prevConCall != null) {
        prevConCall.getDefCallArguments().set(recursiveParam, it);
        prevConCall.fixBoxes();
      } else {
        result = it;
      }
      prevConCall = (ConCallExpression) it;

      recursiveParam = conCall.getDefinition().getRecursiveParameter();
      if (recursiveParam < 0) {
        for (Expression arg : conCall.getDefCallArguments()) {
          Expression newArg = visit(arg, params);
          if (newArg == null) {
            return null;
          }
          prevConCall.getDefCallArguments().add(newArg);
        }
        prevConCall.fixBoxes();
        return result;
      }

      for (int i = 0; i < conCall.getDefCallArguments().size(); i++) {
        if (i != recursiveParam) {
          Expression newArg = visit(conCall.getDefCallArguments().get(i), params);
          if (newArg == null) {
            return null;
          }
          prevConCall.getDefCallArguments().add(newArg);
        } else {
          prevConCall.getDefCallArguments().add(null);
        }
      }

      it = conCall.getDefCallArguments().get(recursiveParam);
      if (!(it instanceof ConCallExpression)) {
        break;
      }
      if (useStack((ConCallExpression) it)) {
        Expression newArg = visitConCallWithStack((ConCallExpression) it, params);
        if (newArg == null) return null;
        prevConCall.getDefCallArguments().set(recursiveParam, newArg);
        return result;
      }
    }

    Expression newArg = visit(it, params);
    if (newArg == null) return null;
    prevConCall.getDefCallArguments().set(recursiveParam, newArg);
    prevConCall.fixBoxes();
    return result;
  }