Example #1
0
    string TypeName(Type type, TextWriter wr)
    {
      Contract.Requires(type != null);
      Contract.Ensures(Contract.Result<string>() != null);

      var xType = type.NormalizeExpand();
      if (xType is TypeProxy) {
        // unresolved proxy; just treat as ref, since no particular type information is apparently needed for this type
        return "object";
      }

      if (xType is BoolType) {
        return "bool";
      } else if (xType is CharType) {
        return "char";
      } else if (xType is IntType) {
        return "BigInteger";
      } else if (xType is RealType) {
        return "Dafny.BigRational";
      } else if (xType.AsNewtype != null) {
        NativeType nativeType = xType.AsNewtype.NativeType;
        if (nativeType != null) {
          return nativeType.Name;
        }
        return TypeName(xType.AsNewtype.BaseType, wr);
      } else if (xType is ObjectType) {
        return "object";
      } else if (xType.IsArrayType) {
        ArrayClassDecl at = xType.AsArrayType;
        Contract.Assert(at != null);  // follows from type.IsArrayType
        Type elType = UserDefinedType.ArrayElementType(xType);
        string name = TypeName(elType, wr) + "[";
        for (int i = 1; i < at.Dims; i++) {
          name += ",";
        }
        return name + "]";
      } else if (xType is UserDefinedType) {
        var udt = (UserDefinedType)xType;
        var s = udt.FullCompileName;
        var rc = udt.ResolvedClass;
        if (DafnyOptions.O.IronDafny && 
            !(xType is ArrowType) &&
            rc != null &&
            rc.Module != null &&
            !rc.Module.IsDefaultModule) {
          while (rc.ClonedFrom != null || rc.ExclusiveRefinement != null) {
            if (rc.ClonedFrom != null) {
              rc = (TopLevelDecl)rc.ClonedFrom;
            } else {
              Contract.Assert(rc.ExclusiveRefinement != null);
              rc = rc.ExclusiveRefinement;
            }
          }
          s = rc.FullCompileName;
        }
        return TypeName_UDT(s, udt.TypeArgs, wr);
      } else if (xType is SetType) {
        Type argType = ((SetType)xType).Arg;
        if (argType is ObjectType) {
          Error("compilation of set<object> is not supported; consider introducing a ghost", wr);
        }
        return DafnySetClass + "<" + TypeName(argType, wr) + ">";
      } else if (xType is SeqType) {
        Type argType = ((SeqType)xType).Arg;
        if (argType is ObjectType) {
          Error("compilation of seq<object> is not supported; consider introducing a ghost", wr);
        }
        return DafnySeqClass + "<" + TypeName(argType, wr) + ">";
      } else if (xType is MultiSetType) {
        Type argType = ((MultiSetType)xType).Arg;
        if (argType is ObjectType) {
          Error("compilation of seq<object> is not supported; consider introducing a ghost", wr);
        }
        return DafnyMultiSetClass + "<" + TypeName(argType, wr) + ">";
      } else if (xType is MapType) {
        Type domType = ((MapType)xType).Domain;
        Type ranType = ((MapType)xType).Range;
        if (domType is ObjectType || ranType is ObjectType) {
          Error("compilation of map<object, _> or map<_, object> is not supported; consider introducing a ghost", wr);
        }
        return DafnyMapClass + "<" + TypeName(domType, wr) + "," + TypeName(ranType, wr) + ">";
      } else {
        Contract.Assert(false); throw new cce.UnreachableException();  // unexpected type
      }
    }
Example #2
0
    string DefaultValue(Type type, TextWriter wr)
    {
      Contract.Requires(type != null);
      Contract.Ensures(Contract.Result<string>() != null);

      var xType = type.NormalizeExpand();
      if (xType is TypeProxy) {
        // unresolved proxy; just treat as ref, since no particular type information is apparently needed for this type
        return "null";
      }

      if (xType is BoolType) {
        return "false";
      } else if (xType is CharType) {
        return "'D'";
      } else if (xType is IntType) {
        return "BigInteger.Zero";
      } else if (xType is RealType) {
        return "Dafny.BigRational.ZERO";
      } else if (xType.AsNewtype != null) {
        if (xType.AsNewtype.NativeType != null) {
          return "0";
        }
        return DefaultValue(xType.AsNewtype.BaseType, wr);
      } else if (xType.IsRefType) {
        return string.Format("({0})null", TypeName(xType, wr));
      } else if (xType.IsDatatype) {
        var udt = (UserDefinedType)xType;
        var s = "@" + udt.FullCompileName;
        var rc = udt.ResolvedClass;
        if (DafnyOptions.O.IronDafny && 
            !(xType is ArrowType) &&
            rc != null &&
            rc.Module != null &&
            !rc.Module.IsDefaultModule) {
          while (rc.ClonedFrom != null || rc.ExclusiveRefinement != null) {
            if (rc.ClonedFrom != null) {
              rc = (TopLevelDecl)rc.ClonedFrom;
            } else {
              Contract.Assert(rc.ExclusiveRefinement != null);
              rc = rc.ExclusiveRefinement;
            }
          }
          s = "@" + rc.FullCompileName;
        }
        if (udt.TypeArgs.Count != 0) {
          s += "<" + TypeNames(udt.TypeArgs, wr) + ">";
        }
        return string.Format("new {0}()", s);
      } else if (xType.IsTypeParameter) {
        var udt = (UserDefinedType)xType;
        string s = "default(@" + udt.FullCompileName;
        if (udt.TypeArgs.Count != 0)
        {
          s += "<" + TypeNames(udt.TypeArgs, wr) + ">";
        }
        s += ")";
        return s;
      } else if (xType is SetType) {
        return DafnySetClass + "<" + TypeName(((SetType)xType).Arg, wr) + ">.Empty";
      } else if (xType is MultiSetType) {
        return DafnyMultiSetClass + "<" + TypeName(((MultiSetType)xType).Arg, wr) + ">.Empty";
      } else if (xType is SeqType) {
        return DafnySeqClass + "<" + TypeName(((SeqType)xType).Arg, wr) + ">.Empty";
      } else if (xType is MapType) {
        return TypeName(xType, wr) + ".Empty";
      } else if (xType is ArrowType) {
        return "null";
      } else {
        Contract.Assert(false); throw new cce.UnreachableException();  // unexpected type
      }
    }
Example #3
0
 // KRemlin extraction does not support some types.  Where possible, references to them are
 // skipped, rather than emitting Kremlin JSON for C extraction that will not execute.
 bool IsUnsupportedType(Type type)
 {
     var xType = type.NormalizeExpand();
       if (xType is IntType ||
     xType is RealType ||
     xType is BitvectorType ||
     xType is ObjectType ||
     xType is SetType ||
     xType is SeqType ||
     xType is MultiSetType ||
     xType is MapType) {
     return true;
       }
       return false;
 }
Example #4
0
        void WriteTypeWidth(Type type)
        {
            Contract.Requires(type != null);
              Contract.Ensures(Contract.Result<string>() != null);

              Formatting old = j.Formatting;
              j.Formatting = Formatting.None;

              using (WriteArray()) {
            var xType = type.NormalizeExpand();
            if (xType is TypeProxy) {
              j.WriteComment("BUGBUG Width of TypeProxy not supported");  // bugbug: implement
              j.WriteValue("0");
            }
            else if (xType is BoolType) {
              j.WriteValue(KremlinAst.Bool);
            }
            else if (xType is CharType) {
              // bugbug: is this the right way to express a Dafny char?
              j.WriteValue(KremlinAst.Int8);
            }
            else if (xType is IntType) {
              var it = (IntType)xType;
              j.WriteComment("BUGBUG Dafny IntType is unsupported");  // bugbug: implement
            }
            else if (xType is RealType) {
              j.WriteComment("BUGBUG Dafny RealType is unsupported");  // bugbug: implement
            }
            else if (xType.AsNewtype != null) {
              NativeType nativeType = xType.AsNewtype.NativeType;
              if (nativeType != null) {
            j.WriteValue(nativeType.KremlinType());
              }
              else {
            WriteTypeWidth(xType.AsNewtype.BaseType);
              }
            }
            else if (xType is ObjectType) {
              j.WriteComment("BUGBUG Dafny ObjectType is unsupported"); // bugbug: implement
            }
            else if (xType.IsArrayType) {
              j.WriteComment("BUGBUG Dafny IsArrayType is unsupported"); // bugbug: implement
            }
            else if (xType is UserDefinedType) {
              j.WriteComment("BUGBUG Dafny UserDefinedType is unsupported"); // bugbug: implement
            }
            else if (xType is SetType) {
              Type argType = ((SetType)xType).Arg;
              if (argType is ObjectType) {
            Error("compilation of set<object> is not supported; consider introducing a ghost", j);
              }
              j.WriteComment("BUGBUG SetType is unsupported"); // bugbug: implement
            }
            else if (xType is SeqType) {
              Type argType = ((SeqType)xType).Arg;
              if (argType is ObjectType) {
            Error("compilation of seq<object> is not supported; consider introducing a ghost", j);
              }
              WriteTypeName(((SeqType)xType).Arg);
            }
            else if (xType is MultiSetType) {
              Type argType = ((MultiSetType)xType).Arg;
              if (argType is ObjectType) {
            Error("compilation of seq<object> is not supported; consider introducing a ghost", j);
              }
              j.WriteComment("BUGBUG MultiSetType is unsupported"); // bugbug: implement
            }
            else if (xType is MapType) {
              Type domType = ((MapType)xType).Domain;
              Type ranType = ((MapType)xType).Range;
              if (domType is ObjectType || ranType is ObjectType) {
            Error("compilation of map<object, _> or map<_, object> is not supported; consider introducing a ghost", j);
              }
              j.WriteComment("BUGBUG MapType is unsupported"); // bugbug: implement
            }
            else {
              Contract.Assert(false); throw new cce.UnreachableException();  // unexpected type
            }
              }
              j.Formatting = old;
        }
Example #5
0
        void WriteTypeName(Type type)
        {
            Contract.Requires(type != null);
              Contract.Ensures(Contract.Result<string>() != null);

              Formatting old = j.Formatting;
              j.Formatting = Formatting.None;

              using (WriteArray()) {
            var xType = type.NormalizeExpand();
            if (xType is TypeProxy) {
              // unresolved proxy; just treat as ref, since no particular type information is apparently needed for this type
              j.WriteValue(KremlinAst.TUnit);
            }
            else if (xType is BoolType) {
              j.WriteValue(KremlinAst.TBool);
            }
            else if (xType is CharType) {
              // bugbug: is this the right way to express a Dafny char?
              j.WriteValue(KremlinAst.TInt);
              using (WriteArray()) {
            j.WriteValue(KremlinAst.Int8);
              }
            }
            else if (xType is IntType) {
              var it = (IntType)xType;
              // bugbug: A Dafny IntType is an infinite-precision integer.  Add
              //         runtime support for them as needed.
              j.WriteValue(KremlinAst.TQualified);
              using (WriteArray()) {
            using (WriteArray()) {
              j.WriteValue("Dafny");
            }
            j.WriteValue("BigInt");
              }
            }
            else if (xType is RealType) {
              j.WriteComment("BUGBUG Dafny RealType is unsupported");  // bugbug: implement
            }
            else if (xType is BitvectorType) {
              j.WriteComment("BUGBUG Dafny BitvectorType is unsupported");  // bugbug: implement
            }
            else if (xType.AsNewtype != null) {
              NativeType nativeType = xType.AsNewtype.NativeType;
              if (nativeType != null) {
            j.WriteValue(KremlinAst.TInt);
            using (WriteArray()) {
              j.WriteValue(nativeType.KremlinType());
            }
              }
              else {
            WriteTypeName(xType.AsNewtype.BaseType);
              }
            }
            else if (xType is ObjectType) {
              j.WriteComment("BUGBUG Dafny ObjectType is unsupported"); // bugbug: implement
            }
            else if (xType.IsArrayType) {
              ArrayClassDecl at = xType.AsArrayType;
              Contract.Assert(at != null);  // follows from type.IsArrayType
              Type elType = UserDefinedType.ArrayElementType(xType);
              j.WriteValue(KremlinAst.TBuf);
              WriteTypeName(elType);
              // bugbug: at.Dims is currently ignored
            }
            else if (xType is UserDefinedType) {
              var udt = (UserDefinedType)xType;
              var s = udt.FullName;
              var rc = udt.ResolvedClass;
              if (DafnyOptions.O.IronDafny &&
              !(xType is ArrowType) &&
              rc != null &&
              rc.Module != null &&
              !rc.Module.IsDefaultModule) {
            while (rc.ClonedFrom != null || rc.ExclusiveRefinement != null) {
              if (rc.ClonedFrom != null) {
                rc = (TopLevelDecl)rc.ClonedFrom;
              }
              else {
                Contract.Assert(rc.ExclusiveRefinement != null);
                rc = rc.ExclusiveRefinement;
              }
            }
            s = rc.FullName;
              }
              WriteTypeName_UDT(s, udt.TypeArgs);
            }
            else if (xType is SetType) {
              Type argType = ((SetType)xType).Arg;
              if (argType is ObjectType) {
            Error("compilation of set<object> is not supported; consider introducing a ghost", j);
              }
              j.WriteComment("BUGBUG SetType is unsupported"); // bugbug: implement
            }
            else if (xType is SeqType) {
              Type argType = ((SeqType)xType).Arg;
              if (argType is ObjectType) {
            Error("compilation of seq<object> is not supported; consider introducing a ghost", j);
              }
              j.WriteValue(KremlinAst.TBuf);
              WriteTypeName(argType);
            }
            else if (xType is MultiSetType) {
              Type argType = ((MultiSetType)xType).Arg;
              if (argType is ObjectType) {
            Error("compilation of seq<object> is not supported; consider introducing a ghost", j);
              }
              j.WriteComment("BUGBUG MultiSetType is unsupported"); // bugbug: implement
            }
            else if (xType is MapType) {
              Type domType = ((MapType)xType).Domain;
              Type ranType = ((MapType)xType).Range;
              if (domType is ObjectType || ranType is ObjectType) {
            Error("compilation of map<object, _> or map<_, object> is not supported; consider introducing a ghost", j);
              }
              j.WriteComment("BUGBUG MapType is unsupported"); // bugbug: implement
            }
            else {
              Contract.Assert(false); throw new cce.UnreachableException();  // unexpected type
            }
              }
              j.Formatting = old;
        }
Example #6
0
        // Write out a default value as an expr
        void WriteDefaultValue(Type type)
        {
            Contract.Requires(type != null);
              Contract.Ensures(Contract.Result<string>() != null);

              var xType = type.NormalizeExpand();
              if (xType is TypeProxy) {
            // unresolved proxy; just treat as ref, since no particular type information is apparently needed for this type
            WriteEUnit();
              }

              if (xType is BoolType) {
            var old = j.Formatting;
            j.Formatting = Formatting.None;
            using (WriteArray()) {
              j.WriteValue(KremlinAst.EConstant);
              using (WriteArray()) {
            j.WriteValue(KremlinAst.TBool);
            j.WriteValue(false);
              }
            }
            j.Formatting = old;
              }
              else if (xType is CharType) {
            var old = j.Formatting;
            j.Formatting = Formatting.None;
            using (WriteArray()) {
              j.WriteValue(KremlinAst.EConstant);
              using (WriteArray()) {
            j.WriteValue(KremlinAst.TInt);
            j.WriteValue((int)'D');
              }
            }
            j.Formatting = old;
              }
              else if (xType is IntType) {
            var it = (IntType)xType;
            WriteEAbort("BUGBUG Dafny IntType is unsupported");  // bugbug: implement
              }
              else if (xType is RealType) {
            WriteEAbort("BUGBUG Dafny RealType is unsupported");  // bugbug: implement
              }
              else if (xType is BitvectorType) {
            WriteEAbort("BUGBUG Dafny BitvectorType is unsupported");  // bugbug: implement
              }
              else if (xType.AsNewtype != null) {
            if (xType.AsNewtype.NativeType != null) {
              var nativeType = xType.AsNewtype.NativeType;
              var old = j.Formatting;
              j.Formatting = Formatting.None;
              using (WriteArray()) {
            j.WriteValue(KremlinAst.EConstant);
            using (WriteArray()) { // of K.t
              using (WriteArray()) {
                j.WriteValue(nativeType.KremlinType());
              }
              j.WriteValue("0");
            }
              }
              j.Formatting = old;
            }
            else {
              WriteDefaultValue(xType.AsNewtype.BaseType);
            }
              }
              else if (xType.IsArrayType) {
            ArrayClassDecl at = xType.AsArrayType;
            Contract.Assert(at != null);  // follows from type.IsArrayType
            using (WriteArray()) {
              j.WriteValue(KremlinAst.EAny);
            }
              }
              else if (xType.IsRefType) {
            using (WriteArray()) {
              j.WriteValue(KremlinAst.EAny);
            }
              }
              else if (xType.IsDatatype) {
            var udt = (UserDefinedType)xType;
            var s = udt.FullName;
            var rc = udt.ResolvedClass;
            if (DafnyOptions.O.IronDafny &&
            !(xType is ArrowType) &&
            rc != null &&
            rc.Module != null &&
            !rc.Module.IsDefaultModule) {
              while (rc.ClonedFrom != null || rc.ExclusiveRefinement != null) {
            if (rc.ClonedFrom != null) {
              rc = (TopLevelDecl)rc.ClonedFrom;
            }
            else {
              Contract.Assert(rc.ExclusiveRefinement != null);
              rc = rc.ExclusiveRefinement;
            }
              }
              s = rc.FullName;
            }
            using (WriteArray()) {
              if (udt.TypeArgs.Count != 0) {
            WriteEAbort("Udt with TypeArgs is not supported"); // bugbug: implement
              }
              else {
            IndDatatypeDecl dcl = rc as IndDatatypeDecl;
            j.WriteValue(KremlinAst.EBufCreateL);
            using (WriteArray()) { // of expr list
                using (WriteArray()) {
                j.WriteValue(KremlinAst.EFlat);
                using (WriteArray()) { // (lident list of (ident * expr))
                  WriteLident(udt);
                  using (WriteArray()) {
                    int i = 0;
                    foreach (var arg in dcl.DefaultCtor.Formals) {
                      if (arg.IsGhost) {
                        continue;
                      }
                      using (WriteArray()) {
                        j.WriteValue(FormalName(arg, i)); // ident
                        WriteDefaultValue(arg.Type);      // expr
                      }
                    }
                  }
                }
              }
            }
              }
            }
              }
              else if (xType.IsTypeParameter) {
            WriteEAbort("BUGBUG Dafny TypeParameter is unsupported");  // bugbug: implement
              }
              else if (xType is SetType) {
            WriteEAbort("BUGBUG Dafny SetType is unsupported");  // bugbug: implement
              }
              else if (xType is MultiSetType) {
            WriteEAbort("BUGBUG Dafny MultiSetType is unsupported");  // bugbug: implement
              }
              else if (xType is SeqType) {
            Type argType = ((SeqType)xType).Arg;
            using (WriteArray()) {
              j.WriteValue(KremlinAst.EAny);
            }
              }
              else if (xType is MapType) {
            WriteEAbort("BUGBUG Dafny MapType is unsupported");  // bugbug: implement
              }
              else if (xType is ArrowType) {
            WriteEAbort("BUGBUG Dafny ArrowType is unsupported");  // bugbug: implement
              }
              else {
            Contract.Assert(false); throw new cce.UnreachableException();  // unexpected type
              }
        }
Example #7
0
    // Check that two resolved types are the same in a similar context (the same type parameters, method, class, etc.)
    // Assumes that prev is in a previous refinement, and next is in some refinement. Note this is not communative.
    public static bool ResolvedTypesAreTheSame(Type prev, Type next) {
      Contract.Requires(prev != null);
      Contract.Requires(next != null);
      prev = prev.NormalizeExpand();
      next = next.NormalizeExpand();
      if (prev is TypeProxy || next is TypeProxy)
        return false;

      if (prev is BoolType) {
        return next is BoolType;
      } else if (prev is CharType) {
        return next is CharType;
      } else if (prev is IntType) {
        if (next is IntType) {
          return (prev is NatType) == (next is NatType);
        } else return false;
      } else if (prev is RealType) {
        return next is RealType;
      } else if (prev is ObjectType) {
        return next is ObjectType;
      } else if (prev is SetType) {
        return next is SetType && ((SetType)prev).Finite == ((SetType)next).Finite &&
          ResolvedTypesAreTheSame(((SetType)prev).Arg, ((SetType)next).Arg);
      } else if (prev is MultiSetType) {
        return next is MultiSetType && ResolvedTypesAreTheSame(((MultiSetType)prev).Arg, ((MultiSetType)next).Arg);
      } else if (prev is MapType) {
        return next is MapType && ((MapType)prev).Finite == ((MapType)next).Finite &&
               ResolvedTypesAreTheSame(((MapType)prev).Domain, ((MapType)next).Domain) && ResolvedTypesAreTheSame(((MapType)prev).Range, ((MapType)next).Range);
      } else if (prev is SeqType) {
        return next is SeqType && ResolvedTypesAreTheSame(((SeqType)prev).Arg, ((SeqType)next).Arg);
      } else if (prev is UserDefinedType) {
        if (!(next is UserDefinedType)) {
          return false;
        }
        UserDefinedType aa = (UserDefinedType)prev;
        UserDefinedType bb = (UserDefinedType)next;
        if (aa.ResolvedClass != null && aa.ResolvedClass.Name == bb.ResolvedClass.Name) {
          // these are both resolved class/datatype types
          Contract.Assert(aa.TypeArgs.Count == bb.TypeArgs.Count);
          for (int i = 0; i < aa.TypeArgs.Count; i++)
            if (!ResolvedTypesAreTheSame(aa.TypeArgs[i], bb.TypeArgs[i]))
              return false;
          return true;
        } else if (aa.ResolvedParam != null && bb.ResolvedParam != null) {
          // these are both resolved type parameters
          Contract.Assert(aa.TypeArgs.Count == 0 && bb.TypeArgs.Count == 0);
          // Note that this is only correct if the two types occur in the same context, ie. both from the same method
          // or class field.
          return aa.ResolvedParam.PositionalIndex == bb.ResolvedParam.PositionalIndex &&
                 aa.ResolvedParam.IsToplevelScope == bb.ResolvedParam.IsToplevelScope;
        } else if (aa.ResolvedParam.IsAbstractTypeDeclaration && bb.ResolvedClass != null) {
          return (aa.ResolvedParam.Name == bb.ResolvedClass.Name);
        } else {
          // something is wrong; either aa or bb wasn't properly resolved, or they aren't the same
          return false;
        }

      } else {
        Contract.Assert(false); throw new cce.UnreachableException();  // unexpected type
      }
    }