Example #1
0
  private void propagate(
      TypePattern pattern,
      HashMap<String, SemanticType> environment,
      HashSet<String> generics,
      WyalFile.Context context) {
    SemanticType type = builder.convert(pattern.toSyntacticType(), generics, context);

    if (pattern instanceof TypePattern.Tuple) {
      TypePattern.Tuple tt = (TypePattern.Tuple) pattern;
      for (TypePattern p : tt.patterns) {
        propagate(p, environment, generics, context);
      }
    }
    if (pattern.var != null) {
      environment.put(pattern.var, type);
    }
    if (pattern.source != null) {
      SemanticType ct = propagate(pattern.source, environment, generics, context);
      checkIsSubtype(SemanticType.SetAny, ct, pattern);
      // TODO: need effective set here
      SemanticType.Set set_t = (SemanticType.Set) ct;
      checkIsSubtype(type, set_t.element(), pattern);
    }
    if (pattern.constraint != null) {
      SemanticType ct = propagate(pattern.constraint, environment, generics, context);
      checkIsSubtype(SemanticType.Bool, ct, pattern);
    }

    pattern.attributes().add(new TypeAttribute(type));
  }
Example #2
0
 private SemanticType propagate(
     Expr.Ternary e,
     HashMap<String, SemanticType> environment,
     HashSet<String> generics,
     WyalFile.Context context) {
   SemanticType firstType = propagate(e.firstOperand, environment, generics, context);
   SemanticType secondType = propagate(e.secondOperand, environment, generics, context);
   SemanticType thirdType = propagate(e.thirdOperand, environment, generics, context);
   switch (e.op) {
     case UPDATE:
       checkIsSubtype(SemanticType.SetTupleAnyAny, firstType, e.firstOperand);
       // FIXME: should this handle map updates?
       checkIsSubtype(SemanticType.Int, secondType, e.secondOperand);
       SemanticType.Set l = (SemanticType.Set) firstType;
       SemanticType.Tuple elementType = SemanticType.Tuple(SemanticType.Int, thirdType);
       checkIsSubtype(l.element(), elementType, e.thirdOperand);
       return firstType;
     case SUBLIST:
       checkIsSubtype(SemanticType.SetTupleAnyAny, firstType, e.firstOperand);
       checkIsSubtype(SemanticType.Int, secondType, e.secondOperand);
       checkIsSubtype(SemanticType.Int, thirdType, e.thirdOperand);
       return firstType;
   }
   internalFailure("unknown ternary expression encountered (" + e + ")", filename, e);
   return null; // deadcode
 }
Example #3
0
  private SemanticType propagate(
      Expr.IndexOf e,
      HashMap<String, SemanticType> environment,
      HashSet<String> generics,
      WyalFile.Context context) {
    SemanticType src_type = propagate(e.operand, environment, generics, context);
    SemanticType index_type = propagate(e.index, environment, generics, context);
    if (src_type instanceof SemanticType.EffectiveTuple) {
      SemanticType.EffectiveTuple tt = (SemanticType.EffectiveTuple) src_type;
      checkIsSubtype(SemanticType.Int, index_type, e.operand);
      if (!(e.index instanceof Expr.Constant)) {
        syntaxError("constant index required for tuple load", filename, e.index);
      }
    } else {
      checkIsSubtype(SemanticType.SetTupleAnyAny, src_type, e.operand);
      // FIXME: handle case for effective set (i.e. union of sets)
      SemanticType.Set st = (SemanticType.Set) src_type;
      SemanticType.EffectiveTuple tt = (SemanticType.EffectiveTuple) st.element();
      // FIXME: handle case for effective tuple of wrong size
      checkIsSubtype(tt.tupleElement(0), index_type, e.index);
    }

    return src_type;
  }
Example #4
0
 /**
  * Calculate the most precise type that captures those possible values a given expression can
  * evaluate to.
  *
  * @param e
  * @return
  */
 public static SemanticType returnType(Expr e) {
   SemanticType type = e.attribute(TypeAttribute.class).type;
   if (e instanceof Expr.Variable || e instanceof Expr.Constant || e instanceof Expr.Quantifier) {
     return type;
   } else if (e instanceof Expr.Unary) {
     Expr.Unary ue = (Expr.Unary) e;
     switch (ue.op) {
       case NOT:
         return SemanticType.Bool;
       case NEG:
         return type;
       case LENGTHOF:
         return SemanticType.Int;
     }
   } else if (e instanceof Expr.Binary) {
     Expr.Binary ue = (Expr.Binary) e;
     switch (ue.op) {
       case ADD:
       case SUB:
       case MUL:
       case DIV:
       case REM:
       case SETUNION:
       case SETINTERSECTION:
       case LISTAPPEND:
       case RANGE:
         return type;
       case EQ:
       case NEQ:
       case IMPLIES:
       case IFF:
       case LT:
       case LTEQ:
       case GT:
       case GTEQ:
       case IN:
       case SUBSET:
       case SUBSETEQ:
       case SUPSET:
       case SUPSETEQ:
         return SemanticType.Bool;
     }
   } else if (e instanceof Expr.Ternary) {
     Expr.Ternary ue = (Expr.Ternary) e;
     switch (ue.op) {
       case UPDATE:
       case SUBLIST:
         return type;
     }
   } else if (e instanceof Expr.Nary) {
     Expr.Nary ue = (Expr.Nary) e;
     switch (ue.op) {
       case AND:
       case OR:
         return SemanticType.Bool;
       case TUPLE:
       case SET:
       case LIST:
         return type;
     }
   } else if (e instanceof Expr.IndexOf) {
     Expr.IndexOf ue = (Expr.IndexOf) e;
     if (type instanceof SemanticType.EffectiveTuple) {
       SemanticType.EffectiveTuple tt = (SemanticType.EffectiveTuple) type;
       Value.Integer idx = (Value.Integer) ((Expr.Constant) ue.index).value;
       return tt.tupleElement(idx.value.intValue());
     } else {
       SemanticType.Set st = (SemanticType.Set) type;
       SemanticType.EffectiveTuple tt = (SemanticType.EffectiveTuple) st.element();
       return tt.tupleElement(1);
     }
   } else {
     Expr.FunCall fc = (Expr.FunCall) e;
     return ((SemanticType.Function) type).to();
   }
   // should be deadcode.
   throw new IllegalArgumentException("Invalid opcode for expression");
 }
Example #5
0
  private SemanticType propagate(
      Expr.Binary e,
      HashMap<String, SemanticType> environment,
      HashSet<String> generics,
      WyalFile.Context context) {
    SemanticType lhs_type = propagate(e.leftOperand, environment, generics, context);
    SemanticType rhs_type = propagate(e.rightOperand, environment, generics, context);

    switch (e.op) {
      case ADD:
      case SUB:
      case MUL:
      case DIV:
      case REM:
        checkIsSubtype(SemanticType.IntOrReal, lhs_type, e.leftOperand);
        checkIsSubtype(SemanticType.IntOrReal, rhs_type, e.rightOperand);
        return SemanticType.Or(lhs_type, rhs_type);
      case EQ:
      case NEQ:
        return SemanticType.Or(lhs_type, rhs_type);
      case IMPLIES:
      case IFF:
        checkIsSubtype(SemanticType.Bool, lhs_type, e.leftOperand);
        checkIsSubtype(SemanticType.Bool, rhs_type, e.rightOperand);
        return SemanticType.Bool;
      case LT:
      case LTEQ:
      case GT:
      case GTEQ:
        checkIsSubtype(SemanticType.IntOrReal, lhs_type, e.leftOperand);
        checkIsSubtype(SemanticType.IntOrReal, rhs_type, e.rightOperand);
        return SemanticType.Or(lhs_type, rhs_type);
      case IN:
        {
          checkIsSubtype(SemanticType.SetAny, rhs_type, e.rightOperand);
          SemanticType.Set s = (SemanticType.Set) rhs_type;
          return s;
        }
      case SUBSET:
      case SUBSETEQ:
      case SUPSET:
      case SUPSETEQ:
        {
          checkIsSubtype(SemanticType.SetAny, lhs_type, e.leftOperand);
          checkIsSubtype(SemanticType.SetAny, rhs_type, e.rightOperand);
          // following can cause some problems
          // checkIsSubtype(lhs_type,rhs_type,e);
          return SemanticType.Or(lhs_type, rhs_type);
        }
      case SETUNION:
        {
          checkIsSubtype(SemanticType.SetAny, lhs_type, e.leftOperand);
          checkIsSubtype(SemanticType.SetAny, rhs_type, e.rightOperand);
          SemanticType.Set l = (SemanticType.Set) lhs_type;
          SemanticType.Set r = (SemanticType.Set) rhs_type;
          return SemanticType.Set(true, SemanticType.Or(l.element(), r.element()));
        }
      case SETINTERSECTION:
        {
          checkIsSubtype(SemanticType.SetAny, lhs_type, e.leftOperand);
          checkIsSubtype(SemanticType.SetAny, rhs_type, e.rightOperand);
          // TODO: the following gives a more accurate type, but there are
          // some outstanding issues related to the type system reduction
          // rules.
          // return SemanticType.And(lhs_type,rhs_type);
          SemanticType.Set l = (SemanticType.Set) lhs_type;
          SemanticType.Set r = (SemanticType.Set) rhs_type;
          return SemanticType.Set(true, SemanticType.Or(l.element(), r.element()));
        }
      case LISTAPPEND:
        {
          checkIsSubtype(SemanticType.SetTupleAnyAny, lhs_type, e.leftOperand);
          checkIsSubtype(SemanticType.SetTupleAnyAny, rhs_type, e.rightOperand);
          SemanticType.Set l = (SemanticType.Set) lhs_type;
          SemanticType.Set r = (SemanticType.Set) rhs_type;
          return SemanticType.Set(true, SemanticType.Or(l.element(), r.element()));
        }
      case RANGE:
        {
          checkIsSubtype(SemanticType.Int, lhs_type, e.leftOperand);
          checkIsSubtype(SemanticType.Int, rhs_type, e.rightOperand);
          return SemanticType.Set(true, SemanticType.Tuple(SemanticType.Int, SemanticType.Int));
        }
    }

    internalFailure("unknown binary expression encountered (" + e + ")", filename, e);
    return null; // deadcode
  }