Example #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());
    }
  }
Example #2
0
  public Block relabel() {
    HashMap<String, String> labels = new HashMap<String, String>();

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

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

    return block;
  }
Example #3
0
    private void determineTypesUpto(int end) {
      Type[] environment = environments[0];

      for (int i = position; i < end; ++i) {
        Code code = stmts.get(i).code;
        if (code instanceof Code.Label) {
          Code.Label label = (Code.Label) code;
          Type[] nEnv = cache.get(label.label);
          environment = join(environment, nEnv);
        } else if (code instanceof Code.AbstractAssignable) {
          Code.AbstractAssignable c = (Code.AbstractAssignable) code;
          environment = Arrays.copyOf(environment, environment.length);
          environment[c.target] = c.assignedType();
        } else if (code instanceof Code.Goto) {
          Code.Goto gto = (Code.Goto) code;
          cache.put(gto.target, environment);
          environment = null;
        } else if (code instanceof Code.If) {
          Code.If gto = (Code.If) code;
          cache.put(gto.target, environment);
        } else if (code instanceof Code.IfIs) {
          Code.IfIs gto = (Code.IfIs) code;
          Type[] trueEnv = Arrays.copyOf(environment, environment.length);
          trueEnv[gto.operand] = Type.intersect(trueEnv[gto.operand], gto.rightOperand);
          cache.put(gto.target, trueEnv);
          environment[gto.operand] =
              Type.intersect(trueEnv[gto.operand], Type.Negation(gto.rightOperand));
        } else if (code instanceof Code.Switch) {
          Code.Switch sw = (Code.Switch) code;
          for (Pair<Constant, String> c : sw.branches) {
            cache.put(c.second(), environment);
          }
          cache.put(sw.defaultTarget, environment);
        } else if (code instanceof Code.ForAll) {
          // FIXME: what this need to do is update the type for the
          // index variable, and then invalidate it afterwards.
          throw new RuntimeException("need to implement for-all loop!");
        } else if (code instanceof Code.Return || code instanceof Code.Throw) {
          environment = null;
        }

        environments[i] = environment;
      }
    }