Beispiel #1
0
  /**
   * Import an external block into this one, using a given <i>binding</i>. The binding indicates how
   * the input variables for the external block should be mapped into the variables of this block.
   *
   * <p>
   *
   * <p>Every input variable in the block must be bound to something in the binding. Otherwise, an
   * IllegalArgumentException is raised. In the case of an input bound to a slot >= numSlots(), then
   * the number of slots is increased automatically. <b>NOTE:</b> temporary variables used in the
   * external block will be mapped automatically to unused slots in this environment to prevent
   * collisions. Therefore, temporary variables should not be specified in the binding.
   */
  public void importExternal(Block block, Map<Integer, Integer> binding) {
    int freeSlot = numSlots();

    // First, sanity check that all input variables are bound
    HashMap<Integer, Integer> nbinding = new HashMap<Integer, Integer>();
    for (int i = 0; i != block.numInputs; ++i) {
      Integer target = binding.get(i);
      if (target == null) {
        throw new IllegalArgumentException("Input not mapped by input");
      }
      nbinding.put(i, target);
      freeSlot = Math.max(target + 1, freeSlot);
    }

    // Second, determine binding for temporary variables
    for (int i = block.numInputs; i != block.numSlots(); ++i) {
      nbinding.put(i, i + freeSlot);
    }

    // Third, determine relabelling
    HashMap<String, String> labels = new HashMap<String, String>();

    for (Entry s : block) {
      if (s.code instanceof Code.Label) {
        Code.Label l = (Code.Label) s.code;
        labels.put(l.label, freshLabel());
      }
    }

    // Finally, apply the binding and relabel any labels as well.
    for (Entry s : block) {
      Code ncode = s.code.remap(nbinding).relabel(labels);
      append(ncode, s.attributes());
    }
  }