Esempio n. 1
0
        void FunctionDecl(MemberModifiers mmod, bool isWithinAbstractModule, out Function/*!*/ f)
        {
            Contract.Ensures(Contract.ValueAtReturn(out f)!=null);
            Attributes attrs = null;
            IToken/*!*/ id = Token.NoToken;  // to please compiler
            List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
            List<Formal/*!*/> formals = new List<Formal/*!*/>();
            Type/*!*/ returnType = new BoolType();
            List<Expression/*!*/> reqs = new List<Expression/*!*/>();
            List<Expression/*!*/> ens = new List<Expression/*!*/>();
            List<FrameExpression/*!*/> reads = new List<FrameExpression/*!*/>();
            List<Expression/*!*/> decreases;
            Expression body = null;
            bool isPredicate = false; bool isIndPredicate = false; bool isCoPredicate = false;
            bool isFunctionMethod = false;
            IToken bodyStart = Token.NoToken;
            IToken bodyEnd = Token.NoToken;
            IToken signatureEllipsis = null;
            bool missingOpenParen;

            if (la.kind == 38) {
            Get();
            if (la.kind == 84) {
                Get();
                isFunctionMethod = true;
            }
            if (mmod.IsGhost) { SemErr(t, "functions cannot be declared 'ghost' (they are ghost by default)"); }

            while (la.kind == 46) {
                Attribute(ref attrs);
            }
            NoUSIdent(out id);
            if (la.kind == 50 || la.kind == 52) {
                if (la.kind == 52) {
                    GenericParameters(typeArgs);
                }
                Formals(true, isFunctionMethod, formals);
                Expect(21);
                Type(out returnType);
            } else if (la.kind == 59) {
                Get();
                signatureEllipsis = t;
            } else SynErr(153);
            } else if (la.kind == 39) {
            Get();
            isPredicate = true;
            if (la.kind == 84) {
                Get();
                isFunctionMethod = true;
            }
            if (mmod.IsGhost) { SemErr(t, "predicates cannot be declared 'ghost' (they are ghost by default)"); }

            while (la.kind == 46) {
                Attribute(ref attrs);
            }
            NoUSIdent(out id);
            if (StartOf(8)) {
                if (la.kind == 52) {
                    GenericParameters(typeArgs);
                }
                missingOpenParen = true;
                if (la.kind == 50) {
                    Formals(true, isFunctionMethod, formals);
                    missingOpenParen = false;
                }
                if (missingOpenParen) { errors.Warning(t, "with the new support of higher-order functions in Dafny, parentheses-less predicates are no longer supported; in the new syntax, parentheses are required for the declaration and uses of predicates, even if the predicate takes no additional arguments"); }
                if (la.kind == 21) {
                    Get();
                    SemErr(t, "predicates do not have an explicitly declared return type; it is always bool");
                }
            } else if (la.kind == 59) {
                Get();
                signatureEllipsis = t;
            } else SynErr(154);
            } else if (la.kind == 40) {
            Get();
            Expect(39);
            isIndPredicate = true;
            if (mmod.IsGhost) { SemErr(t, "inductive predicates cannot be declared 'ghost' (they are ghost by default)"); }

            while (la.kind == 46) {
                Attribute(ref attrs);
            }
            NoUSIdent(out id);
            if (la.kind == 50 || la.kind == 52) {
                if (la.kind == 52) {
                    GenericParameters(typeArgs);
                }
                Formals(true, isFunctionMethod, formals);
                if (la.kind == 21) {
                    Get();
                    SemErr(t, "inductive predicates do not have an explicitly declared return type; it is always bool");
                }
            } else if (la.kind == 59) {
                Get();
                signatureEllipsis = t;
            } else SynErr(155);
            } else if (la.kind == 42) {
            Get();
            isCoPredicate = true;
            if (mmod.IsGhost) { SemErr(t, "copredicates cannot be declared 'ghost' (they are ghost by default)"); }

            while (la.kind == 46) {
                Attribute(ref attrs);
            }
            NoUSIdent(out id);
            if (la.kind == 50 || la.kind == 52) {
                if (la.kind == 52) {
                    GenericParameters(typeArgs);
                }
                Formals(true, isFunctionMethod, formals);
                if (la.kind == 21) {
                    Get();
                    SemErr(t, "copredicates do not have an explicitly declared return type; it is always bool");
                }
            } else if (la.kind == 59) {
                Get();
                signatureEllipsis = t;
            } else SynErr(156);
            } else SynErr(157);
            decreases = isIndPredicate || isCoPredicate ? null : new List<Expression/*!*/>();
            while (StartOf(9)) {
            FunctionSpec(reqs, reads, ens, decreases);
            }
            if (la.kind == 46) {
            FunctionBody(out body, out bodyStart, out bodyEnd);
            }
            if (!isWithinAbstractModule && DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 && !Attributes.Contains(attrs, "axiom") && !Attributes.Contains(attrs, "imported")) {
              SemErr(t, "a function with an ensures clause must have a body, unless given the :axiom attribute");
            }

            IToken tok = theVerifyThisFile ? id : new IncludeToken(id);
            if (isPredicate) {
              f = new Predicate(tok, id.val, mmod.IsStatic, mmod.IsProtected, !isFunctionMethod, typeArgs, formals,
                            reqs, reads, ens, new Specification<Expression>(decreases, null), body, Predicate.BodyOriginKind.OriginalOrInherited, attrs, signatureEllipsis);
            } else if (isIndPredicate) {
              f = new InductivePredicate(tok, id.val, mmod.IsStatic, mmod.IsProtected, typeArgs, formals,
                                     reqs, reads, ens, body, attrs, signatureEllipsis);
            } else if (isCoPredicate) {
              f = new CoPredicate(tok, id.val, mmod.IsStatic, mmod.IsProtected, typeArgs, formals,
                              reqs, reads, ens, body, attrs, signatureEllipsis);
            } else {
              f = new Function(tok, id.val, mmod.IsStatic, mmod.IsProtected, !isFunctionMethod, typeArgs, formals, returnType,
                           reqs, reads, ens, new Specification<Expression>(decreases, null), body, attrs, signatureEllipsis);
            }
            f.BodyStartTok = bodyStart;
            f.BodyEndTok = bodyEnd;
            theBuiltIns.CreateArrowTypeDecl(formals.Count);
            if (isIndPredicate || isCoPredicate) {
             // also create an arrow type for the corresponding prefix predicate
             theBuiltIns.CreateArrowTypeDecl(formals.Count + 1);
            }
        }
Esempio n. 2
0
        void FunctionDecl(DeclModifierData dmod, bool isWithinAbstractModule, out Function/*!*/ f)
        {
            Contract.Ensures(Contract.ValueAtReturn(out f)!=null);
            Attributes attrs = null;
            IToken/*!*/ id = Token.NoToken;  // to please compiler
            List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
            List<Formal/*!*/> formals = new List<Formal/*!*/>();
            Type/*!*/ returnType = new BoolType();
            List<Expression/*!*/> reqs = new List<Expression/*!*/>();
            List<Expression/*!*/> ens = new List<Expression/*!*/>();
            List<FrameExpression/*!*/> reads = new List<FrameExpression/*!*/>();
            List<Expression/*!*/> decreases;
            Expression body = null;
            bool isPredicate = false; bool isIndPredicate = false; bool isCoPredicate = false;
            bool isFunctionMethod = false;
            IToken bodyStart = Token.NoToken;
            IToken bodyEnd = Token.NoToken;
            IToken signatureEllipsis = null;
            bool missingOpenParen;
            bool isTwoState = false;

            if (la.kind == 44) {
            Get();
            isTwoState = true;
            }
            if (la.kind == 41) {
            Get();
            if (la.kind == 90) {
                Get();
                if (isTwoState) { SemErr(t, "twostate functions are supported only as a ghosts, not as function methods"); }
                else { isFunctionMethod = true; }

            }
            AllowedDeclModifiers allowed = AllowedDeclModifiers.AlreadyGhost | AllowedDeclModifiers.Static;
            if (!isTwoState) { allowed |= AllowedDeclModifiers.Protected; }
            string caption = "Functions";
            if (isFunctionMethod) {
             allowed |= AllowedDeclModifiers.Extern;
             caption = "Function methods";
            }
            CheckDeclModifiers(dmod, caption, allowed);

            while (la.kind == 50) {
                Attribute(ref attrs);
            }
            NoUSIdent(out id);
            if (la.kind == 54 || la.kind == 56) {
                if (la.kind == 56) {
                    GenericParameters(typeArgs);
                }
                Formals(true, isFunctionMethod, isTwoState, formals);
                Expect(22);
                Type(out returnType);
            } else if (la.kind == 63) {
                Get();
                signatureEllipsis = t;
            } else SynErr(171);
            } else if (la.kind == 42) {
            Get();
            isPredicate = true;
            if (la.kind == 90) {
                Get();
                if (isTwoState) { SemErr(t, "twostate predicates are supported only as a ghosts, not as predicate methods"); }
                else { isFunctionMethod = true; }

            }
            AllowedDeclModifiers allowed = AllowedDeclModifiers.AlreadyGhost | AllowedDeclModifiers.Static;
            if (!isTwoState) { allowed |= AllowedDeclModifiers.Protected; }
            string caption = "Predicates";
            if (isFunctionMethod) {
             allowed |= AllowedDeclModifiers.Extern;
             caption = "Predicate methods";
            }
            CheckDeclModifiers(dmod, caption, allowed);

            while (la.kind == 50) {
                Attribute(ref attrs);
            }
            NoUSIdent(out id);
            if (StartOf(11)) {
                if (la.kind == 56) {
                    GenericParameters(typeArgs);
                }
                missingOpenParen = true;
                if (la.kind == 54) {
                    Formals(true, isFunctionMethod, isTwoState, formals);
                    missingOpenParen = false;
                }
                if (missingOpenParen) { errors.Warning(t, "with the new support of higher-order functions in Dafny, parentheses-less predicates are no longer supported; in the new syntax, parentheses are required for the declaration and uses of predicates, even if the predicate takes no additional arguments"); }
                if (la.kind == 22) {
                    Get();
                    SemErr(t, "predicates do not have an explicitly declared return type; it is always bool");
                }
            } else if (la.kind == 63) {
                Get();
                signatureEllipsis = t;
            } else SynErr(172);
            } else if (la.kind == 43) {
            Contract.Assert(!isTwoState);  // the IsFunctionDecl check checks that "twostate" is not followed by "inductive"

            Get();
            Expect(42);
            isIndPredicate = true;
            CheckDeclModifiers(dmod, "Inductive predicates",
             AllowedDeclModifiers.AlreadyGhost | AllowedDeclModifiers.Static | AllowedDeclModifiers.Protected);

            while (la.kind == 50) {
                Attribute(ref attrs);
            }
            NoUSIdent(out id);
            if (la.kind == 54 || la.kind == 56) {
                if (la.kind == 56) {
                    GenericParameters(typeArgs);
                }
                Formals(true, isFunctionMethod, false, formals);
                if (la.kind == 22) {
                    Get();
                    SemErr(t, "inductive predicates do not have an explicitly declared return type; it is always bool");
                }
            } else if (la.kind == 63) {
                Get();
                signatureEllipsis = t;
            } else SynErr(173);
            } else if (la.kind == 46) {
            Contract.Assert(!isTwoState);  // the IsFunctionDecl check checks that "twostate" is not followed by "copredicate"

            Get();
            isCoPredicate = true;
            CheckDeclModifiers(dmod, "Copredicates",
             AllowedDeclModifiers.AlreadyGhost | AllowedDeclModifiers.Static | AllowedDeclModifiers.Protected);

            while (la.kind == 50) {
                Attribute(ref attrs);
            }
            NoUSIdent(out id);
            if (la.kind == 54 || la.kind == 56) {
                if (la.kind == 56) {
                    GenericParameters(typeArgs);
                }
                Formals(true, isFunctionMethod, false, formals);
                if (la.kind == 22) {
                    Get();
                    SemErr(t, "copredicates do not have an explicitly declared return type; it is always bool");
                }
            } else if (la.kind == 63) {
                Get();
                signatureEllipsis = t;
            } else SynErr(174);
            } else SynErr(175);
            decreases = isIndPredicate || isCoPredicate ? null : new List<Expression/*!*/>();
            while (StartOf(12)) {
            FunctionSpec(reqs, reads, ens, decreases);
            }
            if (la.kind == 50) {
            FunctionBody(out body, out bodyStart, out bodyEnd);
            }
            if (!isWithinAbstractModule && DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 &&
               !Attributes.Contains(attrs, "axiom") && !Attributes.Contains(attrs, "imported")) {
              SemErr(t, "a function with an ensures clause must have a body, unless given the :axiom attribute");
            }
            EncodeExternAsAttribute(dmod, ref attrs, id, /* needAxiom */ true);
            IToken tok = theVerifyThisFile ? id : new IncludeToken(id);
            if (isTwoState && isPredicate) {
              f = new TwoStatePredicate(tok, id.val, dmod.IsStatic, typeArgs, formals,
                                    reqs, reads, ens, new Specification<Expression>(decreases, null), body, attrs, signatureEllipsis);
            } else if (isTwoState) {
              f = new TwoStateFunction(tok, id.val, dmod.IsStatic, typeArgs, formals, returnType,
                                   reqs, reads, ens, new Specification<Expression>(decreases, null), body, attrs, signatureEllipsis);
            } else if (isPredicate) {
              f = new Predicate(tok, id.val, dmod.IsStatic, dmod.IsProtected, !isFunctionMethod, typeArgs, formals,
                            reqs, reads, ens, new Specification<Expression>(decreases, null), body, Predicate.BodyOriginKind.OriginalOrInherited, attrs, signatureEllipsis);
            } else if (isIndPredicate) {
              f = new InductivePredicate(tok, id.val, dmod.IsStatic, dmod.IsProtected, typeArgs, formals,
                                     reqs, reads, ens, body, attrs, signatureEllipsis);
            } else if (isCoPredicate) {
              f = new CoPredicate(tok, id.val, dmod.IsStatic, dmod.IsProtected, typeArgs, formals,
                              reqs, reads, ens, body, attrs, signatureEllipsis);
            } else {
              f = new Function(tok, id.val, dmod.IsStatic, dmod.IsProtected, !isFunctionMethod, typeArgs, formals, returnType,
                           reqs, reads, ens, new Specification<Expression>(decreases, null), body, attrs, signatureEllipsis);
            }
            f.BodyStartTok = bodyStart;
            f.BodyEndTok = bodyEnd;
            theBuiltIns.CreateArrowTypeDecl(formals.Count);
            if (isIndPredicate || isCoPredicate) {
             // also create an arrow type for the corresponding prefix predicate
             theBuiltIns.CreateArrowTypeDecl(formals.Count + 1);
            }
        }