Пример #1
0
 private void IdentifyClass(ClassDecl classDecl)
 {
     _allMethods[classDecl.Module].Add(classDecl, new List<Method>());
     foreach (var member in classDecl.Members)
         if (member is Method) {
             _allMethods[classDecl.Module][classDecl].Add((Method) member);
             _allRemovableTypes.AddMember(member);
         }
 }
Пример #2
0
        public override AstNode VisitClassDecl(ClassDecl ast)
        {
            if (ast.BaseClass.TypeName != null)
            {
                //resolve base class
                var baseTypeName = ast.BaseClass.TypeName.Content;

                if (!m_types.Contains(baseTypeName))
                {
                    m_errorManager.AddError(c_SE_TypeNameMissing, ast.BaseClass.TypeName.Span, baseTypeName);

                    //leave ast.BaseClass.Type empty
                }
                else
                {
                    var type = m_types[baseTypeName] as CodeClassType;

                    Debug.Assert(type != null);

                    if (type.IsStatic)
                    {
                        m_errorManager.AddError(c_SE_StaticBaseType, ast.BaseClass.TypeName.Span, baseTypeName);
                    }

                    ast.BaseClass.Type = type;
                    (ast.Type as CodeClassType).BaseType = type;
                }
            }

            //resolve member decl types

            //fields
            foreach (var field in ast.Fields)
            {
                field.FieldInfo = new Field() { DeclaringType = ast.Type };
                Visit(field);
            }

            //methods
            foreach (var method in ast.Methods)
            {
                method.MethodInfo = new Method() { DeclaringType = ast.Type };
                Visit(method);
            }

            return ast;
        }
Пример #3
0
        public override AstNode VisitClassDecl(ClassDecl ast)
        {
            var name = ast.Name.Value;

            if (m_types.Contains(name))
            {
                m_errorManager.AddError(c_SE_TypeNameDuplicates, ast.Name.Span, name);
                return ast;
            }

            var classType = new CodeClassType() { Name = name };

            m_types.Add(classType);
            ast.Type = classType;

            return ast;
        }
Пример #4
0
        private void FindRemovableTypesInMethod(Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
        {
            if (method.Body == null)
            {
                return;
            }
            var block = method.Body;

            foreach (var statement in block.Body)
            {
                FindRemovableTypesInStatement(statement, block, method, wildCardParent, classDecl);
            }
        }
Пример #5
0
 internal TypeValue(ClassDecl declaration)
 {
     QualifiedName = declaration.QualifiedName;
     Declaration   = declaration;
 }
Пример #6
0
 private void CheckClassesAreRefinements(ClassDecl nw, ClassDecl d) {
   if (nw.TypeArgs.Count != d.TypeArgs.Count) {
     reporter.Error(MessageSource.RefinementTransformer, nw, "a refining class ({0}) must have the same number of type parameters", nw.Name);
   } else {
     var map = new Dictionary<string, MemberDecl>();
     foreach (var mem in nw.Members) {
       map.Add(mem.Name, mem);
     }
     foreach (var m in d.Members) {
       MemberDecl newMem;
       if (map.TryGetValue(m.Name, out newMem)) {
         if (m.HasStaticKeyword != newMem.HasStaticKeyword) {
           reporter.Error(MessageSource.RefinementTransformer, newMem, "member {0} must {1}", m.Name, m.HasStaticKeyword ? "be static" : "not be static");
         }
         if (m is Field) {
           if (newMem is Field) {
             var newField = (Field)newMem;
             if (!ResolvedTypesAreTheSame(newField.Type, ((Field)m).Type))
               reporter.Error(MessageSource.RefinementTransformer, newMem, "field must be refined by a field with the same type (got {0}, expected {1})", newField.Type, ((Field)m).Type);
             if (m.IsGhost || !newField.IsGhost)
               reporter.Error(MessageSource.RefinementTransformer, newField, "a field re-declaration ({0}) must be to ghostify the field", newField.Name, nw.Name);
           } else {
             reporter.Error(MessageSource.RefinementTransformer, newMem, "a field declaration ({1}) must be replaced by a field in the refinement base (not {0})", newMem.Name, nw.Name);
           }
         } else if (m is Method) {
           if (newMem is Method) {
             CheckMethodsAreRefinements((Method)newMem, (Method)m);
           } else {
             reporter.Error(MessageSource.RefinementTransformer, newMem, "method must be refined by a method");
           }
         } else if (m is Function) {
           if (newMem is Function) {
             CheckFunctionsAreRefinements((Function)newMem, (Function)m);
           } else {
             reporter.Error(MessageSource.RefinementTransformer, newMem, "{0} must be refined by a {0}", m.WhatKind);
           }
         }
       } else {
         reporter.Error(MessageSource.RefinementTransformer, nw is DefaultClassDecl ? nw.Module.tok : nw.tok, "refining {0} must have member {1}", nw is DefaultClassDecl ? "module" : "class", m.Name);
       }
     }
   }
 }
Пример #7
0
        private void CompileMethod(ClassDecl c, Method m)
        {
            Contract.Assert(c != null);
              Contract.Assert(m != null);
              Contract.Assert(m.Body != null);

              VarTracker.Clear();

              if (m.TypeArgs.Count != 0) {
            // Template expansion isn't supported
            j.WriteComment("BUGBUG: Type args not supported:  omitting method " + m.FullCompileName);
            return;
              }

              if (IsUnsupportedMethod(m.Name, m.Outs, m.Ins)) {
            return;
              }

              using (WriteArray()) {
            j.WriteValue(KremlinAst.DFunction);
            using (WriteArray()) { // of (CallingConvention.t option * flag list * typ * lident * binder list * expr)
              WriteDefaultCallingConvention();
              using (WriteArray()) { // empty flag list
              }
              WriteMethodReturnType(m.Outs); // typ
              WriteLident(m); // lident
              using (WriteArray()) { // start of binder list
            WriteFormals(m.Ins);
              }
              using (WriteArray()) {
            j.WriteValue(KremlinAst.ESequence);
            using (WriteArray()) {
              List<Formal> Outs = new List<Formal>(m.Outs);
              if (!(m is Constructor)) {
                WriteEPushFrame();
              }
              foreach (Formal p in Outs) { // bugbug: this now needs to be hoisted out and made recursive
                if (!p.IsGhost) {
                  // ELet v in { Stmt
                  j.WriteStartArray();
                  j.WriteValue(KremlinAst.ELet);
                  j.WriteStartArray();
                  WriteBinder(p, p.Name, true); // lident
                  WriteDefaultValue(p.Type);    // = default
                  VarTracker.Push(p);
                  // "in" is the contents that follow
                  j.WriteStartArray();
                  j.WriteValue(KremlinAst.ESequence);
                  j.WriteStartArray();
                  WriteEUnit();
                }
              }
              if (m.IsTailRecursive) {
                // Note that Dafny conservatively flags functions as possibly-tail-recursive.  This does not acutally
                // indicate the function is tail recursive, or even recursive.
                j.WriteComment("WARNING: IsTailRecursive not supported but the method may not recurse"); // bugbug: implement
              }
              Contract.Assert(enclosingMethod == null);
              enclosingMethod = m;
              TrStmtList(m.Body.Body);
              Contract.Assert(enclosingMethod == m);
              enclosingMethod = null;
              if (!(m is Constructor)) {
                WriteEPopFrame();
              }
              if (m.Outs.Count != 0) {
                var ReturnValue = m.Outs[0];
                WriteEBound(ReturnValue);
              }
              Outs.Reverse();
              foreach (var l in Outs) {
                VarTracker.Pop(l);
                j.WriteEndArray(); // Closing out the expr list in the ESequence
                j.WriteEndArray(); // Closing out the array aboce ESequence
                j.WriteEndArray(); // Closing out the list of binder * expr * expr
                j.WriteEndArray(); // Closing out the array above ELet
              }
            }
              }
            }
              }
        }
Пример #8
0
 public override void Visit(ClassDecl classDeclaration)
 {
     VisitTopLevelDeclarationWithMembers(classDeclaration, () => base.Visit(classDeclaration));
 }
Пример #9
0
 private void FindRemovableTypesInIfStmt(IfStmt ifstmt, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     FindRemovableTypesInStatement(ifstmt.Thn, ifstmt, method, wildCardParent, classDecl);
     FindRemovableTypesInStatement(ifstmt.Els, ifstmt, method, wildCardParent, classDecl);
 }
Пример #10
0
 /// <summary>
 /// Tries to get class and return in second parameter.
 /// </summary>
 /// <param name="className">Class name</param>
 /// <param name="declaration">out parameter with result</param>
 /// <returns>true if class exists</returns>
 public bool TryGetClass(QualifiedName className, out ClassDecl declaration)
 {
     return(nativeObjects.TryGetValue(className, out declaration));
 }
Пример #11
0
 private void FindRemovableTypesInStatement(Statement statement, Statement parent, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     if (statement is AssertStmt)
         FindRemovableTypesInAssertStmt((AssertStmt) statement, parent, method);
     else if (statement is BlockStmt)
         FindRemovableTypesInBlockStmt((BlockStmt) statement, method, wildCardParent, classDecl);
     else if (statement is IfStmt)
         FindRemovableTypesInIfStmt((IfStmt) statement, method, wildCardParent, classDecl);
     else if (statement is LoopStmt)
         FindRemovableTypesInLoopStmt((LoopStmt) statement, method, wildCardParent, classDecl);
     else if (statement is MatchStmt)
         FindRemovableTypesInMatchStmt((MatchStmt) statement, method, wildCardParent, classDecl);
     else if (statement is ForallStmt)
         FindRemovableTypesInForallStmt((ForallStmt) statement, method, wildCardParent, classDecl);
     else if (statement is CalcStmt)
         FindRemovableTypesInCalcStmt((CalcStmt) statement, parent, method, wildCardParent, classDecl);
     else if (statement is UpdateStmt)
         FindRemovableTypesInUpdateStmt((UpdateStmt) statement, parent, method, classDecl);
 }
Пример #12
0
        private void FindRemovableTypesInCalcStmt(CalcStmt calc, Statement parent, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
        {
            Wrap<Statement> calcWrap = null;
            if (parent is BlockStmt)
                calcWrap = new Wrap<Statement>(calc, ((BlockStmt)parent).Body);
            else if (parent is MatchStmt) {
                var matchStmt = (MatchStmt) parent;
                foreach (var matchCase in matchStmt.Cases) {
                    if (!matchCase.Body.Contains(calc)) continue;
                    calcWrap = new Wrap<Statement>(calc, matchCase.Body);
                    break;
                }
                if (calcWrap == null) throw  new Exception("Calc not found!");
            }
            else {
                throw new Exception("Calc not found!");
            }

            _allRemovableTypes.AddCalc(calcWrap, method);
            foreach (var hint in calc.Hints) {
                FindRemovableTypesInStatement(hint, calc, method, wildCardParent, classDecl); // This will check the inside of the hint - it will ID anything that can be shortened inside it.
            }

        }
Пример #13
0
 public ASTDiff(ClassDecl src, ClassDecl tgt, bool exploreExpr = true)
 {
     this.src = new ASTClassNode(src, null, exploreExpr);
     this.tgt = new ASTClassNode(tgt, null, exploreExpr);
 }
Пример #14
0
 private void FindRemovableTypesInMethod(Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     if (method.Body == null) return;
     var block = method.Body;
     foreach (var statement in block.Body)
         FindRemovableTypesInStatement(statement, block, method, wildCardParent, classDecl);
 }
Пример #15
0
 public ASTClassNode(ClassDecl Class, ASTNode parent, bool exploreExpr = true) : base(parent)
 {
     this.Class       = Class;
     this.exploreExpr = exploreExpr;
     initHeight();
 }
Пример #16
0
        static SymbolDecl[] ParseSymbolInternal(string[] tokens, ref int index)
        {
            if (CppParser.Token(tokens, ref index, "public") || CppParser.Token(tokens, ref index, "protected") || CppParser.Token(tokens, ref index, "private"))
            {
                index--;
                return(null);
            }
            TemplateDecl templateDecl = null;

            if (CppParser.Token(tokens, ref index, "template"))
            {
                templateDecl = new TemplateDecl
                {
                    TypeParameters = new List <TypeParameterDecl>(),
                    Specialization = new List <TypeDecl>(),
                };
                CppParser.EnsureToken(tokens, ref index, "<");
                if (!CppParser.Token(tokens, ref index, ">"))
                {
                    while (true)
                    {
                        string token = null;
                        CppParser.SkipUntilInTemplate(tokens, ref index, out token, ",", ">", "=");

                        index -= 2;
                        templateDecl.TypeParameters.Add(new TypeParameterDecl
                        {
                            Name = CppParser.EnsureId(tokens, ref index),
                        });
                        index++;

                        if (token == "=")
                        {
                            CppParser.SkipUntilInTemplate(tokens, ref index, out token, ",", ">");
                        }

                        if (token == ">")
                        {
                            break;
                        }
                    }
                }
            }

            if (CppParser.Token(tokens, ref index, "friend"))
            {
                int    oldIndex = index - 1;
                string token    = null;
                CppParser.SkipUntil(tokens, ref index, out token, ";", "{");
                if (token == ";")
                {
                    return(null);
                }
                else
                {
                    index         = oldIndex;
                    tokens[index] = "static";
                }
            }

            if (CppParser.Token(tokens, ref index, "namespace"))
            {
                if (templateDecl != null)
                {
                    throw new ArgumentException("Failed to parse.");
                }
                var decl = new NamespaceDecl();
                decl.Name = CppParser.EnsureId(tokens, ref index);

                CppParser.EnsureToken(tokens, ref index, "{");
                ParseSymbols(tokens, ref index, decl);
                CppParser.EnsureToken(tokens, ref index, "}");

                return(new SymbolDecl[] { decl });
            }
            else if (CppParser.Token(tokens, ref index, "using"))
            {
                if (CppParser.Token(tokens, ref index, "namespace"))
                {
                    if (templateDecl != null)
                    {
                        throw new ArgumentException("Failed to parse.");
                    }
                    var decl = new UsingNamespaceDecl();
                    decl.Path = new List <string>();
                    decl.Path.Add(CppParser.EnsureId(tokens, ref index));

                    while (!CppParser.Token(tokens, ref index, ";"))
                    {
                        CppParser.EnsureToken(tokens, ref index, ":");
                        CppParser.EnsureToken(tokens, ref index, ":");
                        decl.Path.Add(CppParser.EnsureId(tokens, ref index));
                    }

                    return(new SymbolDecl[] { decl });
                }
                else
                {
                    string name = null;
                    if (CppParser.Id(tokens, ref index, out name))
                    {
                        if (templateDecl != null)
                        {
                            if (CppParser.Token(tokens, ref index, "<"))
                            {
                                while (true)
                                {
                                    templateDecl.Specialization.Add(CppTypeParser.EnsureTypeWithoutNameInTemplate(tokens, ref index));
                                    if (CppParser.Token(tokens, ref index, ">"))
                                    {
                                        break;
                                    }
                                    CppParser.EnsureToken(tokens, ref index, ",");
                                }
                            }
                        }
                        if (CppParser.Token(tokens, ref index, "="))
                        {
                            SymbolDecl decl = new TypedefDecl
                            {
                                Name = name,
                                Type = CppTypeParser.EnsureTypeWithoutName(tokens, ref index),
                            };
                            CppParser.EnsureToken(tokens, ref index, ";");

                            if (templateDecl != null)
                            {
                                templateDecl.Element = decl;
                                decl = templateDecl;
                            }
                            return(new SymbolDecl[] { decl });
                        }
                    }
                    if (templateDecl != null)
                    {
                        throw new ArgumentException("Failed to parse.");
                    }
                    CppParser.SkipUntil(tokens, ref index, ";");
                }
            }
            else if (CppParser.Token(tokens, ref index, "typedef"))
            {
                if (templateDecl != null)
                {
                    throw new ArgumentException("Failed to parse.");
                }
                string name = null;
                var    type = CppTypeParser.EnsureTypeWithName(tokens, ref index, out name);
                CppParser.EnsureToken(tokens, ref index, ";");

                var decl = new TypedefDecl();
                decl.Name = name;
                decl.Type = type;
                return(new SymbolDecl[] { decl });
            }
            else if (CppParser.Token(tokens, ref index, "enum"))
            {
                if (templateDecl != null)
                {
                    throw new ArgumentException("Failed to parse.");
                }
                bool   enumClass = CppParser.Token(tokens, ref index, "class");
                string name      = CppParser.EnsureId(tokens, ref index);
                if (CppParser.Token(tokens, ref index, ":"))
                {
                    CppTypeParser.EnsureTypeWithoutName(tokens, ref index);
                }
                if (!CppParser.Token(tokens, ref index, ";"))
                {
                    CppParser.EnsureToken(tokens, ref index, "{");
                    var decl = new EnumDecl
                    {
                        Name      = name,
                        EnumClass = enumClass,
                        Children  = new List <SymbolDecl>(),
                    };

                    while (true)
                    {
                        if (CppParser.Token(tokens, ref index, "}"))
                        {
                            break;
                        }

                        string document = null;
                        while (index < tokens.Length && tokens[index].Length >= 3 && tokens[index].StartsWith("///"))
                        {
                            var line = tokens[index];
                            if (document == null)
                            {
                                document = "";
                            }
                            document += line.StartsWith("/// ") || line.StartsWith("///\t")
                                ? line.Substring(4)
                                : line.Substring(3);
                            document += "\r\n";
                            index++;
                        }
                        decl.Children.Add(new EnumItemDecl
                        {
                            Name     = CppParser.EnsureId(tokens, ref index),
                            Document = document,
                        });

                        string token = null;
                        CppParser.SkipUntil(tokens, ref index, out token, ",", "}");
                        if (token == "}")
                        {
                            break;
                        }
                    }

                    if (CppParser.Id(tokens, ref index, out name))
                    {
                        var varDecl = new VarDecl
                        {
                            Static = false,
                            Name   = name,
                            Type   = new RefTypeDecl
                            {
                                Name = decl.Name,
                            },
                        };
                        CppParser.EnsureToken(tokens, ref index, ";");
                        return(new SymbolDecl[] { decl, varDecl });
                    }
                    else
                    {
                        CppParser.EnsureToken(tokens, ref index, ";");
                        return(new SymbolDecl[] { decl });
                    }
                }
            }
            else if (CppParser.Token(tokens, ref index, "struct") || CppParser.Token(tokens, ref index, "class") || CppParser.Token(tokens, ref index, "union"))
            {
                if (CppParser.Token(tokens, ref index, "{"))
                {
                    if (tokens[index - 2] == "class")
                    {
                        throw new ArgumentException("Failed to parse.");
                    }

                    var decl = new GroupedFieldDecl
                    {
                        Grouping = tokens[index - 2] == "struct" ? Grouping.Struct : Grouping.Union,
                    };
                    ParseSymbols(tokens, ref index, decl);
                    CppParser.EnsureToken(tokens, ref index, "}");
                    CppParser.EnsureToken(tokens, ref index, ";");
                    return(new SymbolDecl[] { decl });
                }
                else
                {
                    string name = CppParser.EnsureId(tokens, ref index);
                    if (!CppParser.Token(tokens, ref index, ";"))
                    {
                        var classDecl = new ClassDecl
                        {
                            ClassType =
                                tokens[index - 2] == "struct" ? ClassType.Struct :
                                tokens[index - 2] == "class" ? ClassType.Class :
                                ClassType.Union,
                            BaseTypes = new List <BaseTypeDecl>(),
                            Name      = name,
                        };

                        if (templateDecl != null)
                        {
                            if (CppParser.Token(tokens, ref index, "<"))
                            {
                                if (!CppParser.Token(tokens, ref index, ">"))
                                {
                                    while (true)
                                    {
                                        int oldIndex = index;
                                        templateDecl.Specialization.Add(CppTypeParser.EnsureTypeWithoutNameInTemplate(tokens, ref index));
                                        if (CppParser.Token(tokens, ref index, ">"))
                                        {
                                            break;
                                        }
                                        CppParser.EnsureToken(tokens, ref index, ",");
                                    }
                                }
                            }
                        }

                        CppParser.Token(tokens, ref index, "abstract");
                        if (CppParser.Token(tokens, ref index, ":"))
                        {
                            while (true)
                            {
                                Access access = classDecl.ClassType == ClassType.Class ? Access.Private : Access.Public;
                                CppParser.Token(tokens, ref index, "virtual");
                                if (CppParser.Token(tokens, ref index, "private"))
                                {
                                    access = Access.Private;
                                }
                                else if (CppParser.Token(tokens, ref index, "protected"))
                                {
                                    access = Access.Protected;
                                }
                                else if (CppParser.Token(tokens, ref index, "public"))
                                {
                                    access = Access.Public;
                                }
                                CppParser.Token(tokens, ref index, "virtual");
                                classDecl.BaseTypes.Add(new BaseTypeDecl
                                {
                                    Access = access,
                                    Type   = CppTypeParser.EnsureTypeWithoutName(tokens, ref index),
                                });
                                if (!CppParser.Token(tokens, ref index, ","))
                                {
                                    break;
                                }
                            }
                        }

                        CppParser.EnsureToken(tokens, ref index, "{");
                        while (true)
                        {
                            if (CppParser.Token(tokens, ref index, "}"))
                            {
                                break;
                            }

                            Access access = classDecl.ClassType == ClassType.Class ? Access.Private : Access.Public;
                            if (CppParser.Token(tokens, ref index, "private"))
                            {
                                access = Access.Private;
                                CppParser.EnsureToken(tokens, ref index, ":");
                            }
                            else if (CppParser.Token(tokens, ref index, "protected"))
                            {
                                access = Access.Protected;
                                CppParser.EnsureToken(tokens, ref index, ":");
                            }
                            else if (CppParser.Token(tokens, ref index, "public"))
                            {
                                access = Access.Public;
                                CppParser.EnsureToken(tokens, ref index, ":");
                            }
                            ParseSymbols(tokens, ref index, classDecl, access);
                        }

                        SymbolDecl decl = classDecl;
                        if (templateDecl != null)
                        {
                            templateDecl.Element = decl;
                            decl = templateDecl;
                        }

                        if (CppParser.Id(tokens, ref index, out name))
                        {
                            var varDecl = new VarDecl
                            {
                                Static = false,
                                Name   = name,
                                Type   = new RefTypeDecl
                                {
                                    Name = classDecl.Name,
                                },
                            };
                            CppParser.EnsureToken(tokens, ref index, ";");
                            return(new SymbolDecl[] { decl, varDecl });
                        }
                        else
                        {
                            CppParser.EnsureToken(tokens, ref index, ";");
                            return(new SymbolDecl[] { decl });
                        }
                    }
                }
            }
            else if (!CppParser.Token(tokens, ref index, ";"))
            {
                Function function = Function.Function;
                {
                    int    oldIndex = index;
                    string name     = null;
                    if (CppParser.Id(tokens, ref index, out name))
                    {
                        if (CppParser.Token(tokens, ref index, "("))
                        {
                            CppParser.SkipUntil(tokens, ref index, ")");
                            if (CppParser.Token(tokens, ref index, ";") || CppParser.Token(tokens, ref index, "=") || CppParser.Token(tokens, ref index, ":") || CppParser.Token(tokens, ref index, "{"))
                            {
                                function = Function.Constructor;
                            }
                        }
                        index = oldIndex;
                    }
                    else if (CppParser.Token(tokens, ref index, "~"))
                    {
                        function = Function.Destructor;
                    }
                }

                if (function == Function.Function)
                {
                    Virtual virtualFunction = Virtual.Normal;
                    CppParser.Token(tokens, ref index, "extern");
                    CppParser.Token(tokens, ref index, "mutable");
                    if (CppParser.Token(tokens, ref index, "virtual"))
                    {
                        virtualFunction = Virtual.Virtual;
                    }
                    else if (CppParser.Token(tokens, ref index, "static"))
                    {
                        virtualFunction = Virtual.Static;
                    }
                    CppParser.Token(tokens, ref index, "inline");
                    CppParser.Token(tokens, ref index, "__forceinline");

                    if (CppParser.Token(tokens, ref index, "operator"))
                    {
                        TypeDecl returnType = null;
                        {
                            int oldIndex = index;
                            CppParser.SkipUntilInTemplate(tokens, ref index, "(");
                            int modify = --index;

                            tokens[modify] = "$";
                            index          = oldIndex;
                            returnType     = CppTypeParser.EnsureTypeWithoutName(tokens, ref index);
                            if (index != modify)
                            {
                                throw new ArgumentException("Failed to parse.");
                            }
                            tokens[modify] = "(";
                        }
                        var decl = new FuncDecl
                        {
                            Virtual  = Virtual.Normal,
                            Name     = "operator",
                            Function = function,
                        };

                        TypeDecl          functionType      = null;
                        Action <TypeDecl> continuation      = null;
                        CallingConvention callingConvention = CallingConvention.Default;
                        CppTypeParser.ParseTypeContinueAfterName(tokens, ref index, ref callingConvention, out functionType, out continuation);
                        continuation(returnType);
                        decl.Type = functionType;

                        if (!CppParser.Token(tokens, ref index, ";"))
                        {
                            CppParser.EnsureToken(tokens, ref index, "{");
                            CppParser.SkipUntil(tokens, ref index, "}");
                        }

                        if (templateDecl != null)
                        {
                            templateDecl.Element = decl;
                            return(new SymbolDecl[] { templateDecl });
                        }
                        else
                        {
                            return(new SymbolDecl[] { decl });
                        }
                    }
                    else
                    {
                        string   name = null;
                        TypeDecl type = null;
                        if (CppTypeParser.ParseType(tokens, ref index, out type, out name))
                        {
                            if (name == null)
                            {
                                throw new ArgumentException("Failed to parse.");
                            }

                            if (type is FunctionTypeDecl)
                            {
                                if (CppParser.Token(tokens, ref index, "="))
                                {
                                    if (CppParser.Token(tokens, ref index, "0"))
                                    {
                                        virtualFunction = Virtual.Abstract;
                                    }
                                    else
                                    {
                                        CppParser.EnsureToken(tokens, ref index, "default", "delete");
                                    }
                                }

                                var decl = new FuncDecl
                                {
                                    Virtual  = virtualFunction,
                                    Name     = name,
                                    Type     = type,
                                    Function = Function.Function,
                                };

                                {
                                    var funcType   = (FunctionTypeDecl)type;
                                    var returnType = funcType.ReturnType as RefTypeDecl;
                                    if (returnType != null && returnType.Name == "auto")
                                    {
                                        if (CppParser.Token(tokens, ref index, "-"))
                                        {
                                            CppParser.EnsureToken(tokens, ref index, ">");

                                            TypeDecl newReturnType = CppTypeParser.EnsureTypeWithoutName(tokens, ref index);
                                            funcType.ReturnType = newReturnType;
                                        }
                                    }

                                    if (!CppParser.Token(tokens, ref index, ";"))
                                    {
                                        CppParser.EnsureToken(tokens, ref index, "{");
                                        CppParser.SkipUntil(tokens, ref index, "}");
                                    }
                                }

                                if (templateDecl != null)
                                {
                                    templateDecl.Element = decl;
                                    return(new SymbolDecl[] { templateDecl });
                                }
                                else
                                {
                                    return(new SymbolDecl[] { decl });
                                }
                            }
                            else
                            {
                                if (virtualFunction != Virtual.Normal && virtualFunction != Virtual.Static)
                                {
                                    throw new ArgumentException("Failed to parse.");
                                }
                                if (CppParser.Token(tokens, ref index, "="))
                                {
                                    CppParser.SkipUntil(tokens, ref index, ";");
                                }
                                else if (CppParser.Token(tokens, ref index, "{"))
                                {
                                    CppParser.SkipUntil(tokens, ref index, "}");
                                }
                                else
                                {
                                    CppParser.EnsureToken(tokens, ref index, ";");
                                }

                                if (!(type is ClassMemberTypeDecl))
                                {
                                    var decl = new VarDecl
                                    {
                                        Static = virtualFunction == Virtual.Static,
                                        Name   = name,
                                        Type   = type,
                                    };
                                    return(new SymbolDecl[] { decl });
                                }
                            }
                        }
                    }
                }
                else
                {
                    var decl = new FuncDecl
                    {
                        Virtual  = Virtual.Normal,
                        Name     = (function == Function.Constructor ? "" : "~") + CppParser.EnsureId(tokens, ref index),
                        Function = function,
                    };

                    TypeDecl          functionType      = null;
                    Action <TypeDecl> continuation      = null;
                    CallingConvention callingConvention = CallingConvention.Default;
                    CppTypeParser.ParseTypeContinueAfterName(tokens, ref index, ref callingConvention, out functionType, out continuation);
                    continuation(new RefTypeDecl
                    {
                        Name = "void"
                    });
                    decl.Type = functionType;

                    if (CppParser.Token(tokens, ref index, "="))
                    {
                        CppParser.EnsureToken(tokens, ref index, "default", "delete");
                    }

                    if (!CppParser.Token(tokens, ref index, ";"))
                    {
                        if (CppParser.Token(tokens, ref index, ":"))
                        {
                            do
                            {
                                CppTypeParser.EnsureMiniType(tokens, ref index);
                                if (CppParser.Token(tokens, ref index, "("))
                                {
                                    CppParser.SkipUntil(tokens, ref index, ")");
                                }
                                else if (CppParser.Token(tokens, ref index, "{"))
                                {
                                    CppParser.SkipUntil(tokens, ref index, "}");
                                }
                                else
                                {
                                    throw new ArgumentException("Failed to parse.");
                                }
                            }while (CppParser.Token(tokens, ref index, ","));
                        }
                        CppParser.EnsureToken(tokens, ref index, "{");
                        CppParser.SkipUntil(tokens, ref index, "}");
                    }

                    if (templateDecl != null)
                    {
                        templateDecl.Element = decl;
                        return(new SymbolDecl[] { templateDecl });
                    }
                    else
                    {
                        return(new SymbolDecl[] { decl });
                    }
                }
            }
            return(null);
        }
Пример #17
0
 protected override BlockTargetWriter CreateClass(TargetWriter wr, ClassDecl cl)
 {
     return(CreateInternalClass(wr, cl.CompileName));
 }
Пример #18
0
        private void FindRemovableTypesInCalcStmt(CalcStmt calc, Statement parent, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
        {
            Wrap <Statement> calcWrap = null;

            if (parent is BlockStmt)
            {
                calcWrap = new Wrap <Statement>(calc, ((BlockStmt)parent).Body);
            }
            else if (parent is MatchStmt)
            {
                var matchStmt = (MatchStmt)parent;
                foreach (var matchCase in matchStmt.Cases)
                {
                    if (!matchCase.Body.Contains(calc))
                    {
                        continue;
                    }
                    calcWrap = new Wrap <Statement>(calc, matchCase.Body);
                    break;
                }
                if (calcWrap == null)
                {
                    throw  new Exception("Calc not found!");
                }
            }
            else
            {
                throw new Exception("Calc not found!");
            }

            _allRemovableTypes.AddCalc(calcWrap, method);
            foreach (var hint in calc.Hints)
            {
                FindRemovableTypesInStatement(hint, calc, method, wildCardParent, classDecl); // This will check the inside of the hint - it will ID anything that can be shortened inside it.
            }
        }
Пример #19
0
 private void FindRemovableTypesInForallStmt(ForallStmt forall, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     FindRemovableTypesInStatement(forall.Body, forall, method, wildCardParent, classDecl);
 }
Пример #20
0
 private void FindRemovableTypesInMatchStmt(MatchStmt match, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     foreach (var matchCase in match.Cases)
     {
         foreach (var stmt in matchCase.Body)
         {
             FindRemovableTypesInStatement(stmt, match, method, wildCardParent, classDecl);
         }
     }
 }
Пример #21
0
 private void FindRemovableTypesInMatchStmt(MatchStmt match, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     foreach (var matchCase in match.Cases)
         foreach (var stmt in matchCase.Body)
             FindRemovableTypesInStatement(stmt, match, method, wildCardParent, classDecl);
 }
Пример #22
0
 private void FindRemovableTypesInUpdateStmt(UpdateStmt updateStmt, List <Statement> parent, Method method, ClassDecl classDecl)
 {
     foreach (var expr in updateStmt.Rhss)
     {
         if (!IsAssignmentLemmaCall(expr, classDecl))
         {
             continue;
         }
         _allRemovableTypes.AddLemmaCall(new Wrap <Statement>(updateStmt, parent), method);
     }
 }
Пример #23
0
 private void FindRemovableTypesInLoopStmt(LoopStmt loopStmt, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     GetLoopInvariants(loopStmt, method);
     IdentifyRemovableDecreasesTypesInLoop(loopStmt, method, ref wildCardParent);
     if (!(loopStmt is WhileStmt)) return;
     var whileStmt = (WhileStmt) loopStmt;
     FindRemovableTypesInStatement(whileStmt.Body, loopStmt, method, wildCardParent, classDecl);
 }
Пример #24
0
        bool WriteClassStruct(ClassDecl c, bool forCompanionClass)
        {
            Contract.Requires(c != null);

              // Don't write out a struct with no members, as it isn't valid C
              if (c.InheritedMembers.Count == 0) {
            bool HasNoMembers = true;
            foreach (MemberDecl member in c.Members) {
              if (member is Field) {
            var f = (Field)member;
            if (f.IsGhost || forCompanionClass) {
              // emit nothing
            }
            else {
              HasNoMembers = false;
              break;
            }
              }
            }
            if (HasNoMembers) {
              j.WriteComment("Not writing class struct " + c.FullCompileName + " as it has no non-ghost members");
              return false;
            }
              }

              using (WriteArray()) {
            j.WriteValue(KremlinAst.DTypeFlat); // of (lident * (ident * (typ * bool)) list)
            using (WriteArray()) {
              WriteLident(c.FullName);
              using (WriteArray()) { // list
            foreach (var member in c.InheritedMembers) {
              Contract.Assert(!member.IsGhost && !member.IsStatic);  // only non-ghost instance members should ever be added to .InheritedMembers
              j.WriteComment("Inherited member");
              using (WriteArray()) {
                if (member is Field) {
                  var f = (Field)member;
                  using (WriteArray()) { // (ident * (typ * bool))
                    j.WriteValue(f.Name);
                    using (WriteArray()) {
                      WriteTypeName(f.Type);
                      j.WriteValue(true); // mutable
                    }
                  }
                }
              }
            }

            foreach (MemberDecl member in c.Members) {
              if (member is Field) {
                var f = (Field)member;
                if (f.IsGhost || forCompanionClass) {
                  // emit nothing
                }
                else if (c is TraitDecl) {
                  WriteToken(member.tok);
                  j.WriteComment("BUGBUG TraitDecl not supported: " + f.CompileName); // bugbug: implement
                }
                else {
                  using (WriteArray()) { // (ident * (typ * bool))
                    j.WriteValue(f.Name);
                    using (WriteArray()) {
                      WriteTypeName(f.Type);
                      j.WriteValue(true);
                    }
                  }
                }
              }
            }
              }
            }
              }

              return true;
        }
Пример #25
0
 private void FindRemovableTypesInIfStmt(IfStmt ifstmt, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     FindRemovableTypesInStatement(ifstmt.Thn, ifstmt, method, wildCardParent, classDecl);
     FindRemovableTypesInStatement(ifstmt.Els, ifstmt, method, wildCardParent, classDecl);
 }
Пример #26
0
    private void CompileMethod(ClassDecl c, int indent, Method m, TextWriter wr) {
      Indent(indent, wr);
      wr.Write("public {0}void @{1}", m.IsStatic ? "static " : "", m.CompileName);
      if (m.TypeArgs.Count != 0) {
        wr.Write("<{0}>", TypeParameters(m.TypeArgs));
      }
      wr.Write("(");
      int nIns = WriteFormals("", m.Ins, wr);
      WriteFormals(nIns == 0 ? "" : ", ", m.Outs, wr);
      wr.WriteLine(")");
      Indent(indent, wr); wr.WriteLine("{");
      foreach (Formal p in m.Outs) {
        if (!p.IsGhost) {
          Indent(indent + IndentAmount, wr);
          wr.WriteLine("@{0} = {1};", p.CompileName, DefaultValue(p.Type, wr));
        }
      }
      if (m.Body == null) {
        Error("Method {0} has no body", wr, m.FullName);
      } else {
        if (m.IsTailRecursive) {
          if (!m.IsStatic) {
            Indent(indent + IndentAmount, wr); wr.WriteLine("var _this = this;");
          }
          Indent(indent, wr); wr.WriteLine("TAIL_CALL_START: ;");
        }
        Contract.Assert(enclosingMethod == null);
        enclosingMethod = m;
        TrStmtList(m.Body.Body, indent, wr);
        Contract.Assert(enclosingMethod == m);
        enclosingMethod = null;
      }
      Indent(indent, wr); wr.WriteLine("}");

      // allow the Main method to be an instance method
      if (IsMain(m) && (!m.IsStatic || m.CompileName != "Main")) {
        Indent(indent, wr);
        wr.WriteLine("public static void Main(string[] args) {");
        if (!m.IsStatic) {
          Contract.Assert(m.EnclosingClass == c);
          Indent(indent + IndentAmount, wr);
          wr.Write("@{0} b = new @{0}", c.CompileName);
          if (c.TypeArgs.Count != 0) {
            // instantiate every parameter, it doesn't particularly matter how
            wr.Write("<");
            string sep = "";
            for (int i = 0; i < c.TypeArgs.Count; i++) {
              wr.Write("{0}int", sep);
              sep = ", ";
            }
            wr.Write(">");
          }
          wr.WriteLine("();");
          Indent(indent + IndentAmount, wr); wr.WriteLine("b.@{0}();", m.CompileName);
        } else {
          Indent(indent + IndentAmount, wr); wr.WriteLine("@{0}();", m.CompileName);
        }
        Indent(indent, wr); wr.WriteLine("}");
      }
    }
Пример #27
0
 private void FindRemovableTypesInBlockStmt(BlockStmt blockStmt, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     foreach (var stmt in blockStmt.Body)
         FindRemovableTypesInStatement(stmt, blockStmt, method, wildCardParent, classDecl);
 }
Пример #28
0
 public void SetDefaultClass(ClassDecl c)
 {
     defaultClass = c;
 }
Пример #29
0
 private void FindRemovableTypesInUpdateStmt(UpdateStmt updateStmt, List<Statement> parent, Method method, ClassDecl classDecl)
 {
     foreach (var expr in updateStmt.Rhss) {
         if (!IsAssignmentLemmaCall(expr, classDecl)) continue;
         _allRemovableTypes.AddLemmaCall(new Wrap<Statement>(updateStmt, parent), method);
     }
 }
Пример #30
0
 void SymbolDecl.IVisitor.Visit(ClassDecl decl)
 {
     EntryDecl(decl);
 }
Пример #31
0
 private void FindRemovableTypesInUpdateStmt(UpdateStmt updateStmt, Statement parent, Method method, ClassDecl classDecl)
 {
     if (parent is BlockStmt) {
         var blockStmt = (BlockStmt) parent;
         FindRemovableTypesInUpdateStmt(updateStmt, blockStmt.Body, method, classDecl);
     }
     else if (parent is MatchStmt) {
         var matchStmt = (MatchStmt) parent;
         foreach (var matchCase in matchStmt.Cases) {
             if (!matchCase.Body.Contains(updateStmt)) continue;
             FindRemovableTypesInUpdateStmt(updateStmt, matchCase.Body, method, classDecl);
             break;
         }
     }
 }
        ClassDecl MergeClass(ClassDecl nw, ClassDecl prev)
        {
            CheckAgreement_TypeParameters(nw.tok, prev.TypeArgs, nw.TypeArgs, nw.Name, "class");

              nw.Attributes = refinementCloner.MergeAttributes(prev.Attributes, nw.Attributes);

              // Create a simple name-to-member dictionary.  Ignore any duplicates at this time.
              var declaredNames = new Dictionary<string, int>();
              for (int i = 0; i < nw.Members.Count; i++) {
            var member = nw.Members[i];
            if (!declaredNames.ContainsKey(member.Name)) {
              declaredNames.Add(member.Name, i);
            }

            if (prev.IsDefaultClass && refinedSigOpened.StaticMembers.ContainsKey(member.Name) &&
              !RefinedSig.StaticMembers.ContainsKey(member.Name)) {
            reporter.Error(MessageSource.RefinementTransformer, member.tok, "Base module {0} imports {1} from an opened import, so it cannot be overridden. Give this declaration a unique name to disambiguate.", RefinedSig.ModuleDef.Name, member.Name);
            }
              }

              // Merge the declarations of prev into the declarations of m
              foreach (var member in prev.Members) {
            int index;
            if (!declaredNames.TryGetValue(member.Name, out index)) {
              var nwMember = refinementCloner.CloneMember(member);
              nwMember.RefinementBase = member;
              nw.Members.Add(nwMember);
            } else {
              var nwMember = nw.Members[index];
              if (nwMember is Field) {
            if (member is Field && TypesAreSyntacticallyEqual(((Field)nwMember).Type, ((Field)member).Type)) {
              if (member.IsGhost || !nwMember.IsGhost)
                reporter.Error(MessageSource.RefinementTransformer, nwMember, "a field re-declaration ({0}) must be to ghostify the field", nwMember.Name, nw.Name);
            } else {
              reporter.Error(MessageSource.RefinementTransformer, nwMember, "a field declaration ({0}) in a refining class ({1}) must replace a field in the refinement base", nwMember.Name, nw.Name);
            }
            nwMember.RefinementBase = member;

              } else if (nwMember is Function) {
            var f = (Function)nwMember;
            bool isPredicate = f is Predicate;
            bool isIndPredicate = f is InductivePredicate;
            bool isCoPredicate = f is CoPredicate;
            if (!(member is Function) ||
              (isPredicate && !(member is Predicate)) ||
              (isIndPredicate && !(member is InductivePredicate)) ||
              (isCoPredicate && !(member is CoPredicate)) ||
              (f is TwoStatePredicate && !(member is TwoStatePredicate)) ||
              (f is TwoStateFunction && (!(member is TwoStateFunction) || member is TwoStatePredicate))) {
              reporter.Error(MessageSource.RefinementTransformer, nwMember, "a {0} declaration ({1}) can only refine a {0}", f.WhatKind, nwMember.Name);
            } else if (f.IsProtected != ((Function)member).IsProtected) {
              reporter.Error(MessageSource.RefinementTransformer, f, "a {0} in a refinement module must be declared 'protected' if and only if the refined {0} is", f.WhatKind);
            } else {
              var prevFunction = (Function)member;
              if (f.Req.Count != 0) {
                reporter.Error(MessageSource.RefinementTransformer, f.Req[0].tok, "a refining {0} is not allowed to add preconditions", f.WhatKind);
              }
              if (f.Reads.Count != 0) {
                reporter.Error(MessageSource.RefinementTransformer, f.Reads[0].E.tok, "a refining {0} is not allowed to extend the reads clause", f.WhatKind);
              }
              if (f.Decreases.Expressions.Count != 0) {
                reporter.Error(MessageSource.RefinementTransformer, f.Decreases.Expressions[0].tok, "decreases clause on refining {0} not supported", f.WhatKind);
              }

              if (prevFunction.HasStaticKeyword != f.HasStaticKeyword) {
                reporter.Error(MessageSource.RefinementTransformer, f, "a function in a refining module cannot be changed from static to non-static or vice versa: {0}", f.Name);
              }
              if (!prevFunction.IsGhost && f.IsGhost) {
                reporter.Error(MessageSource.RefinementTransformer, f, "a function method cannot be changed into a (ghost) function in a refining module: {0}", f.Name);
              } else if (prevFunction.IsGhost && !f.IsGhost && prevFunction.Body != null) {
                reporter.Error(MessageSource.RefinementTransformer, f, "a function can be changed into a function method in a refining module only if the function has not yet been given a body: {0}", f.Name);
              }
              if (f.SignatureIsOmitted) {
                Contract.Assert(f.TypeArgs.Count == 0);
                Contract.Assert(f.Formals.Count == 0);
                reporter.Info(MessageSource.RefinementTransformer, f.SignatureEllipsis, Printer.FunctionSignatureToString(prevFunction));
              } else {
                CheckAgreement_TypeParameters(f.tok, prevFunction.TypeArgs, f.TypeArgs, f.Name, "function");
                CheckAgreement_Parameters(f.tok, prevFunction.Formals, f.Formals, f.Name, "function", "parameter");
                if (!TypesAreSyntacticallyEqual(prevFunction.ResultType, f.ResultType)) {
                  reporter.Error(MessageSource.RefinementTransformer, f, "the result type of function '{0}' ({1}) differs from the result type of the corresponding function in the module it refines ({2})", f.Name, f.ResultType, prevFunction.ResultType);
                }
              }

              Expression moreBody = null;
              Expression replacementBody = null;
              if (prevFunction.Body == null) {
                replacementBody = f.Body;
              } else if (f.Body != null) {
                if (isPredicate && f.IsProtected) {
                  moreBody = f.Body;
                } else if (isPredicate) {
                  reporter.Error(MessageSource.RefinementTransformer, nwMember, "a refining predicate is not allowed to extend/change the body unless it is declared 'protected'");
                } else {
                  reporter.Error(MessageSource.RefinementTransformer, nwMember, "a refining function is not allowed to extend/change the body");
                }
              }
              var newF = CloneFunction(f.tok, prevFunction, f.IsGhost, f.Ens, moreBody, replacementBody, prevFunction.Body == null, f.Attributes);
              newF.RefinementBase = member;
              nw.Members[index] = newF;
            }

              } else {
            var m = (Method)nwMember;
            if (!(member is Method)) {
              reporter.Error(MessageSource.RefinementTransformer, nwMember, "a method declaration ({0}) can only refine a method", nwMember.Name);
            } else {
              var prevMethod = (Method)member;
              if (m.Req.Count != 0) {
                reporter.Error(MessageSource.RefinementTransformer, m.Req[0].E.tok, "a refining method is not allowed to add preconditions");
              }
              if (m.Mod.Expressions.Count != 0) {
                reporter.Error(MessageSource.RefinementTransformer, m.Mod.Expressions[0].E.tok, "a refining method is not allowed to extend the modifies clause");
              }
              // If the previous method was not specified with "decreases *", then the new method is not allowed to provide any "decreases" clause.
              // Any "decreases *" clause is not inherited, so if the previous method was specified with "decreases *", then the new method needs
              // to either redeclare "decreases *", provided a termination-checking "decreases" clause, or give no "decreases" clause and thus
              // get a default "decreases" loop.
              Specification<Expression> decreases;
              if (m.Decreases.Expressions.Count == 0) {
                // inherited whatever the previous loop used
                decreases = refinementCloner.CloneSpecExpr(prevMethod.Decreases);
              } else {
                if (!Contract.Exists(prevMethod.Decreases.Expressions, e => e is WildcardExpr)) {
                  // If the previous loop was not specified with "decreases *", then the new loop is not allowed to provide any "decreases" clause.
                  reporter.Error(MessageSource.RefinementTransformer, m.Decreases.Expressions[0].tok, "decreases clause on refining method not supported, unless the refined method was specified with 'decreases *'");
                }
                decreases = m.Decreases;
              }
              if (prevMethod.HasStaticKeyword != m.HasStaticKeyword) {
                reporter.Error(MessageSource.RefinementTransformer, m, "a method in a refining module cannot be changed from static to non-static or vice versa: {0}", m.Name);
              }
              if (prevMethod.IsGhost && !m.IsGhost) {
                reporter.Error(MessageSource.RefinementTransformer, m, "a method cannot be changed into a ghost method in a refining module: {0}", m.Name);
              } else if (!prevMethod.IsGhost && m.IsGhost) {
                reporter.Error(MessageSource.RefinementTransformer, m, "a ghost method cannot be changed into a non-ghost method in a refining module: {0}", m.Name);
              }
              if (m.SignatureIsOmitted) {
                Contract.Assert(m.TypeArgs.Count == 0);
                Contract.Assert(m.Ins.Count == 0);
                Contract.Assert(m.Outs.Count == 0);
                reporter.Info(MessageSource.RefinementTransformer, m.SignatureEllipsis, Printer.MethodSignatureToString(prevMethod));
              } else {
                CheckAgreement_TypeParameters(m.tok, prevMethod.TypeArgs, m.TypeArgs, m.Name, "method");
                CheckAgreement_Parameters(m.tok, prevMethod.Ins, m.Ins, m.Name, "method", "in-parameter");
                CheckAgreement_Parameters(m.tok, prevMethod.Outs, m.Outs, m.Name, "method", "out-parameter");
              }
              currentMethod = m;
              var replacementBody = m.BodyForRefinement;
              if (replacementBody != null) {
                if (prevMethod.BodyForRefinement == null) {
                  // cool
                } else {
                  replacementBody = MergeBlockStmt(replacementBody, prevMethod.BodyForRefinement);
                }
              }
              var newM = CloneMethod(prevMethod, m.Ens, decreases, replacementBody, prevMethod.BodyForRefinement == null, m.Attributes);
              newM.RefinementBase = member;
              nw.Members[index] = newM;
            }
              }
            }
              }

              return nw;
        }
Пример #33
0
 private bool IsAssignmentLemmaCall(AssignmentRhs expr, ClassDecl classDecl)
 {
     var exprRhs = expr as ExprRhs;
     if (exprRhs == null) return false;
     if (!(exprRhs.Expr is ApplySuffix)) return false;
     return IsCallToGhost((ApplySuffix) exprRhs.Expr, classDecl);
 }
Пример #34
0
 private void FindRemovableTypesInStatement(Statement statement, Statement parent, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     if (statement is AssertStmt)
     {
         FindRemovableTypesInAssertStmt((AssertStmt)statement, parent, method);
     }
     else if (statement is BlockStmt)
     {
         FindRemovableTypesInBlockStmt((BlockStmt)statement, method, wildCardParent, classDecl);
     }
     else if (statement is IfStmt)
     {
         FindRemovableTypesInIfStmt((IfStmt)statement, method, wildCardParent, classDecl);
     }
     else if (statement is LoopStmt)
     {
         FindRemovableTypesInLoopStmt((LoopStmt)statement, method, wildCardParent, classDecl);
     }
     else if (statement is MatchStmt)
     {
         FindRemovableTypesInMatchStmt((MatchStmt)statement, method, wildCardParent, classDecl);
     }
     else if (statement is ForallStmt)
     {
         FindRemovableTypesInForallStmt((ForallStmt)statement, method, wildCardParent, classDecl);
     }
     else if (statement is CalcStmt)
     {
         FindRemovableTypesInCalcStmt((CalcStmt)statement, parent, method, wildCardParent, classDecl);
     }
     else if (statement is UpdateStmt)
     {
         FindRemovableTypesInUpdateStmt((UpdateStmt)statement, parent, method, classDecl);
     }
 }
Пример #35
0
        private bool IsCallToGhost(SuffixExpr expr, ClassDecl classDecl)
        {
            var name = "";
            var nameSeg = expr.Lhs as NameSegment;
            if (nameSeg != null)
                name = nameSeg.Name;

            // Look through all the methods within the current scope and return whether it is ghost or not
            return (from method in _allMethods[classDecl.Module][classDecl] where method.Name == name select method.IsGhost).FirstOrDefault();
        }
Пример #36
0
 private void FindRemovableTypesInForallStmt(ForallStmt forall, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     FindRemovableTypesInStatement(forall.Body, forall, method, wildCardParent, classDecl);
 }
 public override void Visit(ClassDecl o)
 {
 }
Пример #38
0
        private void FindRemovableTypesInLoopStmt(LoopStmt loopStmt, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
        {
            GetLoopInvariants(loopStmt, method);
            IdentifyRemovableDecreasesTypesInLoop(loopStmt, method, ref wildCardParent);
            if (!(loopStmt is WhileStmt))
            {
                return;
            }
            var whileStmt = (WhileStmt)loopStmt;

            FindRemovableTypesInStatement(whileStmt.Body, loopStmt, method, wildCardParent, classDecl);
        }
Пример #39
0
        void ClassDecl(ModuleDefinition/*!*/ module, out ClassDecl/*!*/ c)
        {
            Contract.Requires(module != null);
            Contract.Ensures(Contract.ValueAtReturn(out c) != null);
            IToken/*!*/ id;
            Type trait = null;
            List<Type>/*!*/ traits = new List<Type>();
            Attributes attrs = null;
            List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
            List<MemberDecl/*!*/> members = new List<MemberDecl/*!*/>();
            IToken bodyStart;

            while (!(la.kind == 0 || la.kind == 70)) {SynErr(141); Get();}
            Expect(70);
            while (la.kind == 46) {
            Attribute(ref attrs);
            }
            NoUSIdent(out id);
            if (la.kind == 52) {
            GenericParameters(typeArgs);
            }
            if (la.kind == 71) {
            Get();
            Type(out trait);
            traits.Add(trait);
            while (la.kind == 22) {
                Get();
                Type(out trait);
                traits.Add(trait);
            }
            }
            Expect(46);
            bodyStart = t;
            while (StartOf(2)) {
            ClassMemberDecl(members, true, false, false);
            }
            Expect(47);
            c = new ClassDecl(id, id.val, module, typeArgs, members, attrs, traits);
            c.BodyStartTok = bodyStart;
            c.BodyEndTok = t;
        }
Пример #40
0
 private void FindRemovableTypesInBlockStmt(BlockStmt blockStmt, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl)
 {
     foreach (var stmt in blockStmt.Body)
     {
         FindRemovableTypesInStatement(stmt, blockStmt, method, wildCardParent, classDecl);
     }
 }
Пример #41
0
 public virtual void Visit(ClassDecl classDecl)
 {
 }
Пример #42
0
 private void FindRemovableTypesInUpdateStmt(UpdateStmt updateStmt, Statement parent, Method method, ClassDecl classDecl)
 {
     if (parent is BlockStmt)
     {
         var blockStmt = (BlockStmt)parent;
         FindRemovableTypesInUpdateStmt(updateStmt, blockStmt.Body, method, classDecl);
     }
     else if (parent is MatchStmt)
     {
         var matchStmt = (MatchStmt)parent;
         foreach (var matchCase in matchStmt.Cases)
         {
             if (!matchCase.Body.Contains(updateStmt))
             {
                 continue;
             }
             FindRemovableTypesInUpdateStmt(updateStmt, matchCase.Body, method, classDecl);
             break;
         }
     }
 }
Пример #43
0
    public void Compile()
    {
        Util.Assert(!isPrinting);
        string        name       = FunName(DafnySpec.SimpleName(typeApply.AppName()));
        string        fullName   = FunName(DafnySpec.SimpleName(typeApply.AppFullName()));
        bool          isAxiom    = Attributes.Contains(function.Attributes, "axiom");
        bool          isPrivate  = Attributes.Contains(function.Attributes, "private");
        bool          hidden     = Attributes.Contains(function.Attributes, "opaque");
        bool          isHeap     = DafnySpec.IsHeapFunction(function);
        List <string> heapParams = isHeap ? new List <string> {
            "$absMem:[int][int]int"
        } : new List <string>();
        List <string> heapArgs = isHeap ? new List <string> {
            "$absMem"
        } : new List <string>();
        var formals = function.Formals;
        var reads   = function.Reads.Where(e => e.Field != null).ToList().ConvertAll(e =>
                                                                                     new Formal(e.tok, e.FieldName, e.Field.Type, true, e.Field.IsGhost));

        formals = reads.Concat(formals).ToList();
        if (hidden && formals.Count == 0)
        {
            formals = new List <Formal> {
                new Formal(function.tok, "___dummy", Type.Bool, true, true)
            };
        }
        if (hidden && !function.Name.EndsWith("_FULL"))
        {
            ClassDecl cls  = (ClassDecl)function.EnclosingClass;
            Function  full = (Function)cls.Members.Find(m => m.Name == "#" + function.Name + "_FULL");
            dafnySpec.Compile_Function(full, typeApply.typeArgs);
        }
        bool   isFull     = hidden && function.Name.EndsWith("_FULL");
        string unfullName = isFull ? name.Substring(0, name.Length - "__FULL".Length)
                            .Replace("#", "").Replace("____HASH", "") : null;

        string        argsNoRec = String.Join(", ", heapArgs.Concat(formals.Select(f => GhostVar(f.Name))));
        List <RtlExp> reqsNoRec = minVerify ? new List <RtlExp>() : function.Req.ConvertAll(e => GhostExpression(e, true));
        List <RtlExp> enssNoRec = minVerify ? new List <RtlExp>() : function.Ens.ConvertAll(e => GhostExpression(e, true));

        AddTypeWellFormed(reqsNoRec, formals);
        AddTypeWellFormed(enssNoRec, name + "(" + argsNoRec + ")", function.IsGhost, function.ResultType);
        if (function.Body != null && !minVerify)
        {
            recFunName      = name;
            stmtExprEnabled = true;
            GhostExpression(function.Body);
            function.IsRecursive = recCalls.Count != 0;
            stmtExprEnabled      = false;
            stmts      = new List <RtlStmt>();
            recCalls   = new List <List <RtlExp> >();
            recFunName = null;
        }
        if (function.IsRecursive)
        {
            recFunName = name;
        }
        stmts           = new List <RtlStmt>();
        stmtExprEnabled = true;
        var            bodyDecls = PushForall();
        RtlExp         body      = (function.Body == null || minVerify) ? null : GhostExpression(function.Body);
        List <RtlStmt> bodyStmts = stmts;

        PopForall();
        stmtExprEnabled = false;
        stmts           = new List <RtlStmt>();
        string parms = String.Join(", ", heapParams.Concat(
                                       formals.Select(f => GhostVar(f.Name) + ":" + TypeString(AppType(f.Type)))));
        string args = String.Join(", ", heapArgs.Concat(
                                      formals.Select(f => GhostVar(f.Name))));
        string        sep       = (heapArgs.Count + formals.Count != 0) ? ", " : "";
        string        ret       = TypeString(AppType(function.ResultType));
        string        recName   = "rec_" + name;
        string        decreases = null;
        List <RtlExp> reqs      = minVerify ? new List <RtlExp>() : function.Req.ConvertAll(e => GhostExpression(e, true));
        List <RtlExp> enss      = minVerify ? new List <RtlExp>() : function.Ens.ConvertAll(e => GhostExpression(e, true));

        AddTypeWellFormed(reqs, formals);
        AddTypeWellFormed(enss, name + "(" + args + ")", function.IsGhost, function.ResultType);
        string reqConjunct = "(true" + String.Concat(reqs.Select(e => " && (" + e + ")")) + ")";
        string ensConjunct = "(true" + String.Concat(enss.Select(e => " && (" + e + ")")) + ")";

        Util.Assert(!isPrinting);
        if (function.IsRecursive && function.Body != null && !minVerify)
        {
            decreases = DecreasesExp(function);
        }
        List <RtlExp> enssRec = null;

        if (function.IsRecursive && (!hidden || isFull) && body != null && !minVerify)
        {
            enssRec = function.Ens.ConvertAll(e => GhostExpression(e, true));
        }
        isPrinting = true;
        var fiWriter = isPrivate ? writer : iwriter;

        if (function.IsRecursive && function.Body != null && !minVerify)
        {
            iwriter.WriteLine("function decreases0_" + name + "(" + parms + "):int { " + decreases + " }");
            iwriter.WriteLine("function decreases_" + name + "(" + parms + "):int { if decreases0_"
                              + name + "(" + args + ") < 0 then 0 else 1 + decreases0_" + name + "(" + args + ") }");
            iwriter.WriteLine("function " + recName + "(__decreases:int, __unroll:int" + sep + parms
                              + "):" + ret + ";");
            fiWriter.WriteLine("function implementation{" + FunName("unroll") + "(__unroll), "
                               + recName + "(__decreases, __unroll" + sep + args + ")} "
                               + recName + "(__decreases:int, __unroll:int" + sep + parms + "):" + ret);
            fiWriter.WriteLine("{");
            fiWriter.WriteLine("    " + body.ToString());
            fiWriter.WriteLine("}");
        }
        iwriter.WriteLine("function " + name + "(" + parms + "):" + ret + ";");
        if (hidden && !isFull && !minVerify)
        {
            iwriter.WriteLine("function unhide_" + name + "(" + parms + "):bool { true }");
            fiWriter.WriteLine("function implementation{unhide_" + name + "(" + args + ")} "
                               + name + "(" + parms + "):" + ret);
            fiWriter.WriteLine("{");
            fiWriter.WriteLine("    " + fullName + "(" + args + ")");
            fiWriter.WriteLine("}");
            iwriter.WriteLine("atomic ghost procedure "
                              + GhostProcName("reveal__" + DafnySpec.SimpleName(typeApply.AppName())) + "();");
            string forall = "forall " + parms + "::" + name + "(" + args + ") == "
                            + fullName + "(" + args + ")";
            iwriter.WriteLine("    ensures (" + forall + ");");
            writer.WriteLine("implementation "
                             + GhostProcName("reveal__" + DafnySpec.SimpleName(typeApply.AppName())) + "()");
            writer.WriteLine("{");
            writer.WriteLine("    " + forall);
            writer.WriteLine("    {");
            writer.WriteLine("        assert unhide_" + name + "(" + args + ");");
            writer.WriteLine("    }");
            writer.WriteLine("}");
        }
        if (body != null && (!hidden || isFull))
        {
            fiWriter.WriteLine("function implementation{" + name + "(" + args + ")" + "} " + name
                               + "(" + parms + "):" + ret);
            fiWriter.WriteLine("{");
            if (function.IsRecursive)
            {
                fiWriter.WriteLine("    " + recName + "(decreases_" + name + "(" + args + "), 0" + sep + args + ")");
            }
            else
            {
                fiWriter.WriteLine("    " + body.ToString());
            }
            fiWriter.WriteLine("}");
        }
        if (function.IsRecursive && (!hidden || isFull) && body != null && !minVerify)
        {
            AddTypeWellFormed(enssRec, recName + "(__decreases, __unroll" + sep + args + ")",
                              function.IsGhost, function.ResultType);
            string ensRecConjunct = "(true" + String.Concat(enssRec.Select(e => " && (" + e + ")")) + ")";
            iwriter.WriteLine("atomic ghost procedure lemma_unroll2_" + recName
                              + "(__decreases:int, __unroll:int, __unroll2:int" + sep + parms + ");");
            iwriter.WriteLine("    requires __decreases == decreases_" + name + "(" + args + ");");
            iwriter.WriteLine("    ensures  " + reqConjunct + " ==> " + ensRecConjunct + " && "
                              + recName + "(__decreases, __unroll" + sep + args + ") == "
                              + recName + "(__decreases, __unroll2" + sep + args + ");");

            writer.WriteLine("implementation lemma_unroll2_" + recName
                             + "(__decreases:int, __unroll:int, __unroll2:int" + sep + parms + ")");
            writer.WriteLine("{");
            writer.WriteLine("    " + bodyDecls);
            writer.WriteLine("    assert fun_unroll(__unroll) && fun_unroll(__unroll2);");
            dafnySpec.WriteLemmas(writer, this, visibleModules, function.Attributes);
            writer.WriteLine("    if (" + reqConjunct + ")");
            writer.WriteLine("    {");
            bodyStmts.ForEach(s => writer.WriteLine("    " + s));
            writer.WriteLine("    }");
            foreach (List <RtlExp> recArgs in recCalls)
            {
                string rec_args     = String.Join(", ", recArgs);
                string rec_decrease = "decreases_" + name + "(" + rec_args + ")";
                writer.WriteLine("    if (0 <= " + rec_decrease + " && " + rec_decrease + " < __decreases)");
                writer.WriteLine("    {");
                writer.WriteLine("        call lemma_unroll2_" + recName + "(" + rec_decrease
                                 + ", __unroll + 1, __unroll2 + 1" + sep + rec_args + ");");
                writer.WriteLine("    }");
            }
            writer.WriteLine("}");
            string unroll_args  = "decreases_" + name + "(" + args + "), __unroll";
            string unroll_args0 = "decreases_" + name + "(" + args + "), 0";
            string unroll       = recName + "(" + unroll_args + sep + args + ")";
            string unroll0      = recName + "(" + unroll_args0 + sep + args + ")";


            var    lwriter   = isPrivate ? writer : iwriter;
            string recForall = "forall __unroll:int" + sep + parms + "::"
                               + "{fun_unroll(__unroll), " + unroll + "} "
                               + reqConjunct + " ==> fun_unroll(__unroll) ==> " + unroll + " == " + body;
            lwriter.WriteLine("atomic ghost procedure lemma_unroll_" + recName + "();");
            lwriter.WriteLine("    ensures  (" + recForall + ");");
            writer.WriteLine("implementation lemma_unroll_" + recName + "()");
            writer.WriteLine("{");
            dafnySpec.WriteLemmas(writer, this, visibleModules, function.Attributes);
            writer.WriteLine("    " + recForall);
            writer.WriteLine("    {");
            writer.WriteLine("    " + bodyDecls);
            writer.WriteLine("    if (" + reqConjunct + ")");
            writer.WriteLine("    {");
            bodyStmts.ForEach(s => writer.WriteLine("    " + s));
            writer.WriteLine("    }");
            writer.WriteLine("    }");
            writer.WriteLine("}");
            dafnySpec.AddLemma(new LemmaCall((isPrivate ? "private##" : "") + moduleName,
                                             visibleElementType,
                                             "call lemma_unroll_" + recName + "();",
                                             false));

            Func <string, string> forall = s => "forall __unroll:int" + sep + parms + "::"
                                           + "{" + s + unroll + "} "
                                           + "{fun_unroll__all(__unroll), " + unroll + "} "
                                           + reqConjunct + " ==> " + unroll + " == " + name + "(" + args + ") && " + ensConjunct;
            iwriter.WriteLine("atomic ghost procedure lemma_unroll_" + name + "();");
            iwriter.WriteLine("    ensures  (" + forall(unroll0 + ", ") + ");");
            writer.WriteLine("implementation lemma_unroll_" + name + "()");
            writer.WriteLine("{");
            dafnySpec.WriteLemmas(writer, this, visibleModules, function.Attributes);
            writer.WriteLine("    " + forall(""));
            writer.WriteLine("    {");
            writer.WriteLine("        call lemma_unroll2_" + recName + "("
                             + unroll_args + ", 0" + sep + args + ");");
            writer.WriteLine("        if (" + reqConjunct + ")");
            writer.WriteLine("        {");
            enss.ForEach(e => writer.WriteLine("            assert " + e + ";"));
            writer.WriteLine("        }");
            writer.WriteLine("    }");
            writer.WriteLine("}");
            dafnySpec.AddLemma(new LemmaCall(moduleName, visibleElementType,
                                             "call lemma_unroll_" + name + "();", false));
        }
        else if (enssNoRec.Count > 0 && !minVerify)
        {
            string reqConjunctNoRec = "(true" + String.Concat(reqsNoRec.Select(e => " && (" + e + ")")) + ")";
            string ensConjunctNoRec = "(true" + String.Concat(enssNoRec.Select(e => " && (" + e + ")")) + ")";
            iwriter.WriteLine("function trigger_" + name + "(" + parms + "):bool { true }");
            iwriter.WriteLine("atomic ghost procedure lemma_fun_ensures_" + name + "();");
            string forallNoRec = "forall " + parms
                                 + "::{" + name + "(" + argsNoRec + ")}"
                                 + (isFull ? ("{" + unfullName + "(" + argsNoRec + ")}") : "")
                                 + "{trigger_" + name + "(" + argsNoRec + ")}"
                                 + "trigger_" + name + "(" + argsNoRec + ") ==> "
                                 + reqConjunctNoRec + " ==> " + ensConjunctNoRec;
            iwriter.WriteLine("    ensures (" + forallNoRec + ");");
            if (body != null || hidden || isAxiom)
            {
                writer.WriteLine("implementation lemma_fun_ensures_" + name + "()");
                writer.WriteLine("{");
                dafnySpec.WriteLemmas(writer, this, visibleModules, function.Attributes);
                writer.WriteLine("    " + forallNoRec);
                writer.WriteLine("    {");
                writer.WriteLine("        " + bodyDecls);
                writer.WriteLine("        if (" + reqConjunct + ")");
                writer.WriteLine("        {");
                if (isAxiom)
                {
                    writer.WriteLine("        // dummy lemma body for axiom");
                }
                else
                {
                    bodyStmts.ForEach(s => writer.WriteLine("            " + s));
                }
                writer.WriteLine("        }");
                if (hidden && !isFull)
                {
                    writer.WriteLine("        assert unhide_" + name + "(" + argsNoRec + ");");
                }
                if (hidden && isFull)
                {
                    writer.WriteLine("        assert unhide_" + unfullName + "(" + argsNoRec + ");");
                }
                writer.WriteLine("        if (" + reqConjunct + ")");
                writer.WriteLine("        {");
                enssNoRec.ForEach(e => writer.WriteLine("            assert " + e + ";"));
                writer.WriteLine("        }");
                writer.WriteLine("    }");
                writer.WriteLine("}");
            }
            dafnySpec.AddLemma(new LemmaCall(moduleName, visibleElementType,
                                             "call lemma_fun_ensures_" + name + "();", false));
        }
        isPrinting = false;
    }
Пример #44
0
 public void PrintClass(ClassDecl c, int indent, string fileBeingPrinted) {
   Contract.Requires(c != null);
   Indent(indent);
   PrintClassMethodHelper((c is TraitDecl) ? "trait" : "class", c.Attributes, c.Name, c.TypeArgs);
   string sep = " extends ";
   foreach (var trait in c.TraitsTyp) {
     wr.Write(sep);
     PrintType(trait);
     sep = ", ";
   }
   if (c.Members.Count == 0) {
     wr.WriteLine(" { }");
   } else {
     wr.WriteLine(" {");
     PrintMembers(c.Members, indent + IndentAmount, fileBeingPrinted);
     Indent(indent);
     wr.WriteLine("}");
   }
 }
Пример #45
0
 private void FindRemovableTypesInClass(ClassDecl classDecl)
 {
     foreach (var member in classDecl.Members) {
         FindRemovableTypesInMember(member, classDecl);
     }
 }
Пример #46
0
        public override AstNode VisitClassDecl(ClassDecl ast)
        {
            m_currentType = GetClrType(ast.Type) as TypeBuilder;

            foreach (var method in ast.Methods)
            {
                Visit(method);
            }

            GetClrCtor(ast.Type);

            m_currentType.CreateType();

            return ast;
        }
Пример #47
0
 private void FindRemovableTypesInMember(MemberDecl member, ClassDecl classDecl)
 {
     if (member is Tactic) return;
     WildCardDecreases wildCardParent = null; // The parent of the current wildCard we are tracking
     FindDecreasesTypesInMember(member, ref wildCardParent);
     var method = member as Method;
     if (method != null)
         FindRemovableTypesInMethod(method, wildCardParent, classDecl);
 }
Пример #48
0
        void CompileClassMembers(ClassDecl c)
        {
            Contract.Requires(c != null);

              // For C#, Dafny generates a C# class containing base members, class
              // fields, methods, and functions all together.
              //
              // For Kremlin, a class will generate a struct (a Kremlin DTypeFlat)
              // followed by functions (Kremlin DFunction), with explicit "this"
              // parameters.

              bool forCompanionClass = false; // bugbug: implement

              // Generate the DTypeFlat struct representing the class
              if (!WriteClassStruct(c, forCompanionClass)) {
            // No class struct was written because it has no non-ghost members
            foreach (var member in c.InheritedMembers) {
              Contract.Assert(!member.IsGhost && !member.IsStatic);  // only non-ghost instance members should ever be added to .InheritedMembers
            }
            bool HasNoMembers = true;
            foreach (MemberDecl member in c.Members) {
              if (!(member is Field) && !member.IsGhost) {
            HasNoMembers = false;
            break;
              }
            }
            if (HasNoMembers) {
              // Skip the class if it is entirely ghost
              return;
            }
              }
              UserDefinedType thisType = UserDefinedType.FromTopLevelDecl(c.tok, c);

              foreach (var member in c.InheritedMembers) {
            Contract.Assert(!member.IsGhost && !member.IsStatic);  // only non-ghost instance members should ever be added to .InheritedMembers
            using (WriteArray()) {
              if (member is Field) {
            // Do nothing - WriteClassStruct already handled this case
              } else if (member is Function) {
            var f = (Function)member;
            Contract.Assert(f.Body != null);
            WriteToken(member.tok);
            j.WriteComment("BUGBUG Function unsupported: " + f.CompileName); // bugbug: implement
              }
              else if (member is Method) {
            var method = (Method)member;
            Contract.Assert(method.Body != null);
            WriteToken(member.tok);
            j.WriteComment("BUGBUG Method unsupported: " + method.CompileName); // bugbug: implement
              }
              else {
            Contract.Assert(false);  // unexpected member
              }
            }
              }
              foreach (MemberDecl member in c.Members) {
            if (member is Field) {
              // Do nothing - WriteClassStruct already handled this case
            }
            else if (member is Function) {
              var f = (Function)member;
              if (f.Body == null && !(c is TraitDecl && !f.IsStatic)) {
            // A (ghost or non-ghost) function must always have a body, except if it's an instance function in a trait.
            if (forCompanionClass /* || Attributes.Contains(f.Attributes, "axiom") */) {
              // suppress error message (in the case of "forCompanionClass", the non-forCompanionClass call will produce the error message)
            } else {
              // The C# backend ignores functions that are axioms.  But for
              // the Spartan scenario, treat these as extern functions.
              WriteToken(member.tok);
              CompileExternalFunction(f);
            }
              } else if (f.IsGhost) {
            // nothing to compile, but we do check for assumes
            if (f.Body == null) {
              Contract.Assert(c is TraitDecl && !f.IsStatic);
            } else {
              var v = new CheckHasNoAssumes_VisitorJ(this, j);
              v.Visit(f.Body);
            }
              } else if (c is TraitDecl && !forCompanionClass) {
            // include it, unless it's static
            if (!f.IsStatic) {
              WriteToken(member.tok);
              j.WriteComment("BUGBUG TraitDecl in function is unsupported: " + f.FullName); // bugbug: implement
            }
              } else if (forCompanionClass && !f.IsStatic) {
            // companion classes only has static members
              } else {
            WriteToken(member.tok);
            enclosingThis = (f.IsStatic) ? null : new BoundVar(c.tok, ThisName, thisType);
            CompileFunction(f);
            enclosingThis = null;
              }
            } else if (member is Method) {
              var m = (Method)member;
              if (m.Body == null && !(c is TraitDecl && !m.IsStatic)) {
            // A (ghost or non-ghost) method must always have a body, except if it's an instance method in a trait.
            if (forCompanionClass /* || Attributes.Contains(m.Attributes, "axiom") */ ) {
              // suppress error message (in the case of "forCompanionClass", the non-forCompanionClass call will produce the error message)
            } else {
              // The C# backend ignores functions that are axioms.  But for
              // the Spartan scenario, treat these as extern functions.
              WriteToken(member.tok);
              CompileExternalMethod(c, m);
            }
              } else if (m.IsGhost) {
            // nothing to compile, but we do check for assumes
            if (m.Body == null) {
              Contract.Assert(c is TraitDecl && !m.IsStatic);
            } else {
              var v = new CheckHasNoAssumes_VisitorJ(this, j);
              v.Visit(m.Body);
            }
              } else if (c is TraitDecl && !forCompanionClass) {
            // include it, unless it's static
            if (!m.IsStatic) {
              j.WriteComment("BUGBUG TraitDecl not supported: " + m.CompileName); // bugbug: implement
            }
              } else if (forCompanionClass && !m.IsStatic) {
            // companion classes only has static members
              } else {
            WriteToken(member.tok);
            enclosingThis = (m.IsStatic) ? null : new BoundVar(c.tok, ThisName, thisType);
            CompileMethod(c, m);
            enclosingThis = null;
              }
            } else {
              Contract.Assert(false); throw new cce.UnreachableException();  // unexpected member
            }
              }
        }
 public override void PreVisit(ClassDecl classDecl)
 {
     this.FunctionScope      = new SymbolTable();
     this.ClassInstanceScope = this.GlobalScope.Get(classDecl.ClassName, Classification.Class).Link;
 }
Пример #50
0
        // Compile a method with no body
        private void CompileExternalMethod(ClassDecl c, Method m)
        {
            Contract.Assert(c != null);
              Contract.Assert(m != null);
              Contract.Assert(m.Body == null);

              if (m.TypeArgs.Count != 0) {
            // Template expansion isn't supported
            j.WriteComment("BUGBUG: Type args not supported:  omitting method " + m.FullCompileName);
            return;
              }

              List<Tuple<Type, string>> typeList = new List<Tuple<Type, string>>();
              if (enclosingThis != null) {
            typeList.Add(Tuple.Create(enclosingThis.Type, ThisName));
              }
              foreach (Formal p in m.Ins) {
            if (!p.IsGhost) {
              typeList.Add(Tuple.Create(p.Type, p.Name));
            }
              }
              bool HasAnOut = false;
              foreach (Formal p in m.Outs) {
            if (!p.IsGhost) {
              typeList.Add(Tuple.Create(p.Type, p.Name));
              HasAnOut = true;
            }
              }
              if (!HasAnOut) {
            typeList.Add(new Tuple<Type, string>(null, ""));
              }

              WriteExternal(m, typeList);
        }
Пример #51
0
	void ClassDecl(DeclModifierData dmodClass, ModuleDefinition/*!*/ module, out ClassDecl/*!*/ c) {
		Contract.Requires(module != null);
		Contract.Ensures(Contract.ValueAtReturn(out c) != null);
		IToken/*!*/ id;
		Type trait = null;
		List<Type>/*!*/ traits = new List<Type>();
		Attributes attrs = null;
		List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
		List<MemberDecl/*!*/> members = new List<MemberDecl/*!*/>();
		IToken bodyStart;
		CheckDeclModifiers(dmodClass, "Classes", AllowedDeclModifiers.Extern);
		DeclModifierData dmod; 
		
		while (!(la.kind == 0 || la.kind == 80)) {SynErr(155); Get();}
		Expect(80);
		while (la.kind == 46) {
			Attribute(ref attrs);
		}
		NoUSIdent(out id);
		EncodeExternAsAttribute(dmodClass, ref attrs, id, /* needAxiom */ false); 
		if (la.kind == 52) {
			GenericParameters(typeArgs);
		}
		if (la.kind == 78) {
			Get();
			Type(out trait);
			traits.Add(trait); 
			while (la.kind == 22) {
				Get();
				Type(out trait);
				traits.Add(trait); 
			}
		}
		Expect(46);
		bodyStart = t;  
		while (StartOf(4)) {
			dmod = new DeclModifierData(); 
			while (StartOf(2)) {
				DeclModifier(ref dmod);
			}
			ClassMemberDecl(dmod, members, true, false, false);
		}
		Expect(47);
		c = new ClassDecl(id, id.val, module, typeArgs, members, attrs, traits);
		c.BodyStartTok = bodyStart;
		c.BodyEndTok = t;
		
	}
Пример #52
0
 void CompileClassMembers(ClassDecl c, bool forCompanionClass, int indent, TextWriter wr) {
   Contract.Requires(c != null);
   Contract.Requires(!forCompanionClass || c is TraitDecl);
   Contract.Requires(0 <= indent);
   foreach (var member in c.InheritedMembers) {
     Contract.Assert(!member.IsGhost && !member.IsStatic);  // only non-ghost instance members should ever be added to .InheritedMembers
     if (member is Field) {
       var f = (Field)member;
       // every field is inherited
       Indent(indent, wr);
       wr.WriteLine("public {0} @_{1};", TypeName(f.Type, wr), f.CompileName);
       wr.Write("public {0} @{1}", TypeName(f.Type, wr), f.CompileName);
       wr.WriteLine(" {");
       wr.WriteLine(" get { ");
       wr.Write("return this.@_{0};", f.CompileName);
       wr.WriteLine("}");
       wr.WriteLine(" set { ");
       wr.WriteLine("this.@_{0} = value;", f.CompileName);
       wr.WriteLine("}");
       wr.WriteLine("}");
     } else if (member is Function) {
       var f = (Function)member;
       Contract.Assert(f.Body != null);
       CompileFunction(indent, f, wr);
     } else if (member is Method) {
       var method = (Method)member;
       Contract.Assert(method.Body != null);
       CompileMethod(c, indent, method, wr);
     } else {
       Contract.Assert(false);  // unexpected member
     }
   }
   foreach (MemberDecl member in c.Members) {
     if (member is Field) {
       var f = (Field)member;
       if (f.IsGhost || forCompanionClass) {
         // emit nothing
       } else if (c is TraitDecl) {
         Indent(indent, wr);
         wr.Write("{0} @{1}", TypeName(f.Type, wr), f.CompileName);
         wr.WriteLine(" { get; set; }");
       } else {
         Indent(indent, wr);
         wr.WriteLine("public {0} @{1} = {2};", TypeName(f.Type, wr), f.CompileName, DefaultValue(f.Type, wr));
       }
     } else if (member is Function) {
       var f = (Function)member;
       if (f.Body == null && !(c is TraitDecl && !f.IsStatic)) {
         // A (ghost or non-ghost) function must always have a body, except if it's an instance function in a trait.
         if (forCompanionClass || Attributes.Contains(f.Attributes, "axiom")) {
           // suppress error message (in the case of "forCompanionClass", the non-forCompanionClass call will produce the error message)
         } else {
           Error("Function {0} has no body", wr, f.FullName);
         }
       } else if (f.IsGhost) {
         // nothing to compile, but we do check for assumes
         if (f.Body == null) {
           Contract.Assert(c is TraitDecl && !f.IsStatic);
         } else {
           var v = new CheckHasNoAssumes_Visitor(this, wr);
           v.Visit(f.Body);
         }
       } else if (c is TraitDecl && !forCompanionClass) {
         // include it, unless it's static
         if (!f.IsStatic) {
           Indent(indent, wr);
           wr.Write("{0} @{1}", TypeName(f.ResultType, wr), f.CompileName);
           wr.Write("(");
           WriteFormals("", f.Formals, wr);
           wr.WriteLine(");");
         }
       } else if (forCompanionClass && !f.IsStatic) {
         // companion classes only has static members
       } else {
         CompileFunction(indent, f, wr);
       }
     } else if (member is Method) {
       var m = (Method)member;
       if (m.Body == null && !(c is TraitDecl && !m.IsStatic)) {
         // A (ghost or non-ghost) method must always have a body, except if it's an instance method in a trait.
         if (forCompanionClass || Attributes.Contains(m.Attributes, "axiom")) {
           // suppress error message (in the case of "forCompanionClass", the non-forCompanionClass call will produce the error message)
         } else {
           Error("Method {0} has no body", wr, m.FullName);
         }
       } else if (m.IsGhost) {
         // nothing to compile, but we do check for assumes
         if (m.Body == null) {
           Contract.Assert(c is TraitDecl && !m.IsStatic);
         } else {
           var v = new CheckHasNoAssumes_Visitor(this, wr);
           v.Visit(m.Body);
         }
       } else if (c is TraitDecl && !forCompanionClass) {
         // include it, unless it's static
         if (!m.IsStatic) {
           Indent(indent, wr);
           wr.Write("void @{0}", m.CompileName);
           wr.Write("(");
           int nIns = WriteFormals("", m.Ins, wr);
           WriteFormals(nIns == 0 ? "" : ", ", m.Outs, wr);
           wr.WriteLine(");");
         }
       } else if (forCompanionClass && !m.IsStatic) {
         // companion classes only has static members
       } else {
         CompileMethod(c, indent, m, wr);
       }
     } else {
       Contract.Assert(false); throw new cce.UnreachableException();  // unexpected member
     }
   }
 }
 public override void Leave(ClassDecl o)
 {
     JumpUpInScope();
     SetClass(null);
 }
Пример #54
0
        public override AstNode VisitClassDecl(ClassDecl ast)
        {
            m_currentType = ast.Type as CodeClassType;

            foreach (var method in ast.Methods)
            {
                Visit(method);
            }

            return ast;
        }
Пример #55
0
 public virtual AstNode VisitClassDecl(ClassDecl ast)
 {
     return(ast);
 }