예제 #1
0
파일: Block.java 프로젝트: ejrh/Whiley
    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;
      }
    }
예제 #2
0
  private SemanticType propagate(
      Expr.FunCall e,
      HashMap<String, SemanticType> environment,
      HashSet<String> generics,
      WyalFile.Context context) {

    SemanticType.Function fnType;

    try {
      Pair<NameID, SemanticType.Function> p = builder.resolveAsFunctionType(e.name, context);
      fnType = p.second();
    } catch (ResolveError re) {
      syntaxError(
          "cannot resolve as function or definition call", context.file().filename(), e, re);
      return null;
    }

    SemanticType[] fn_generics = fnType.generics();

    if (fn_generics.length != e.generics.length) {
      // could resolve this with inference in the future.
      syntaxError(
          "incorrect number of generic arguments provided (got "
              + e.generics.length
              + ", required "
              + fn_generics.length
              + ")",
          context.file().filename(),
          e);
    }

    SemanticType argument = propagate(e.operand, environment, generics, context);
    HashMap<String, SemanticType> binding = new HashMap<String, SemanticType>();

    for (int i = 0; i != e.generics.length; ++i) {
      SemanticType.Var gv = (SemanticType.Var) fn_generics[i];
      binding.put(gv.name(), builder.convert(e.generics[i], generics, context));
    }

    fnType = (SemanticType.Function) fnType.substitute(binding);
    checkIsSubtype(fnType.from(), argument, e.operand);
    return fnType;
  }