Exemplo n.º 1
0
  /**
   * Translate from an array of indices of the burnable inputs to an array of indices of all inputs
   * to the gem
   *
   * @param unboundArgsToBurn An array of indices relative to the burnable (ie unburned, unbound)
   *     inputs of the gem
   * @param sourceGem The gem that these are the inputs of
   * @return An array of indices of inputs relative to ALL inputs of the gem, corresponding to the
   *     contents of unburnedArgsToBurn.
   */
  private static int[] translateBurnCombo(int[] unboundArgsToBurn, Gem sourceGem) {
    int[] argsToBurn = new int[unboundArgsToBurn.length];

    // loop indices:
    // i - index of the current input
    // j - counter to keep track of how many unbound and unburned inputs we have passed
    // k - index of the next element of unboudnArgsToBurn to check
    for (int i = 0, j = 0, k = 0; i < sourceGem.getNInputs() && k < unboundArgsToBurn.length; i++) {
      Gem.PartInput currentInput = sourceGem.getInputPart(i);

      if (currentInput.isConnected() || currentInput.isBurnt()) {
        // Skip over unburnable inputs
        continue;
      }

      // This is the j'th burnable input

      // Check to see if this argument should be burned, and if so, add its index relative to the
      // list of all inputs
      // to the argsToBurn array
      if (unboundArgsToBurn[k] == j) {
        argsToBurn[k] = i;
        k++;
      }
      j++;
    }
    return argsToBurn;
  }
Exemplo n.º 2
0
  /**
   * Return whether autoburning will result in a unification. Only inputs on the given gem will be
   * considered for burning.
   *
   * @param destType The destination type to unify with.
   * @param gem The gem on which to attempt "autoburning".
   * @param info the typeCheck info to use.
   * @return AutoburnLogic.AutoburnInfo autoburnable result.
   */
  public static AutoburnInfo getAutoburnInfo(TypeExpr destType, Gem gem, TypeCheckInfo info) {
    // see if we got a real type
    if (destType == null) {
      return AutoburnInfo.makeNoUnificationPossibleAutoburnInfo();
    }

    int[] burnableArgIndices;
    List<TypeExpr> sourceTypeList = new ArrayList<TypeExpr>(); // input types, then output type.

    TypeExpr outType =
        (gem instanceof CollectorGem)
            ? ((CollectorGem) gem).getCollectingPart().getType()
            : gem.getOutputPart().getType();
    TypeExpr[] outTypePieces = outType.getTypePieces();

    // A collector gem's collecting part is not burnable.
    if (gem instanceof CollectorGem && !((CollectorGem) gem).isConnected()) {
      burnableArgIndices = new int[0];

    } else {
      // declare the burnt arg indices array
      burnableArgIndices = new int[gem.getNInputs()];

      if (burnableArgIndices.length != 0) {
        // get the unbound input parts of the gem and keep track of which ones are burnable
        int unburnedCount = 0;
        int burnedCount = 0;
        for (int i = 0, n = gem.getNInputs(); i < n; i++) {
          Gem.PartInput input = gem.getInputPart(i);

          if (!input.isConnected()) {
            if (input.isBurnt()) {
              sourceTypeList.add(outTypePieces[burnedCount]);
              burnedCount++;
            } else {
              sourceTypeList.add(input.getType());
              burnableArgIndices[unburnedCount] = sourceTypeList.size() - 1;
              unburnedCount++;
            }
          }
        }

        // Calculate what the output type would be if none of the arguments were burned.
        TypeExpr newOutType = outTypePieces[outTypePieces.length - 1];
        for (int i = outTypePieces.length - 2; i >= burnedCount; i--) {
          newOutType = TypeExpr.makeFunType(outTypePieces[i], newOutType);
        }
        outType = newOutType;

        // Assign to a new trimmed down array
        int[] newIndices = new int[unburnedCount];
        System.arraycopy(burnableArgIndices, 0, newIndices, 0, unburnedCount);
        burnableArgIndices = newIndices;
      }
    }

    // Add the output type to the source types.
    sourceTypeList.add(outType);

    return getAutoburnInfoWorker(
        destType, sourceTypeList.toArray(new TypeExpr[0]), burnableArgIndices, info, gem);
  }