Example #1
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 #2
0
  private SemanticType propagate(
      Expr.Nary e,
      HashMap<String, SemanticType> environment,
      HashSet<String> generics,
      WyalFile.Context context) {
    Expr[] e_operands = e.operands;
    SemanticType[] op_types = new SemanticType[e_operands.length];

    for (int i = 0; i != e_operands.length; ++i) {
      op_types[i] = propagate(e_operands[i], environment, generics, context);
    }

    switch (e.op) {
      case AND:
      case OR:
        for (int i = 0; i != e_operands.length; ++i) {
          checkIsSubtype(SemanticType.Bool, op_types[i], e_operands[i]);
        }
        return SemanticType.Bool;
      case TUPLE:
        return SemanticType.Tuple(op_types);
      case SET:
        if (op_types.length == 0) {
          return SemanticType.Set(true, SemanticType.Void);
        } else {
          return SemanticType.Set(true, SemanticType.Or(op_types));
        }
      case LIST:
        if (op_types.length == 0) {
          return SemanticType.Set(true, SemanticType.Void);
        } else {
          return SemanticType.Set(
              true, SemanticType.Tuple(SemanticType.Int, SemanticType.Or(op_types)));
        }
    }

    internalFailure("unknown nary expression encountered (" + e + ")", filename, e);
    return null; // deadcode
  }
Example #3
0
 /**
  * Check that t1 :> t2 or, equivalently, that t2 is a subtype of t1. A type
  * <code>t1</code> is said to be a subtype of another type <code>t2</code>
  * iff the semantic set described by <code>t1</code> contains that described
  * by <code>t2</code>.
  *
  * @param t1
  *            --- Semantic type that should contain <code>t2</code>.
  * @param t2
  *            --- Semantic type that shold be contained by <code>t1/code>.
  * @param element
  *            --- Syntax error is reported against this element if
  *            <code>t1</code> does not contain <code>t2</code>.
  */
 private void checkIsSubtype(SemanticType t1, SemanticType t2, SyntacticElement element) {
   if (!SemanticType.isSubtype(t1, t2)) {
     syntaxError("expected type " + t1 + ", got type " + t2, filename, element);
   }
 }
Example #4
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
  }