Beispiel #1
0
        void MethodDecl(MemberModifiers mmod, bool allowConstructor, bool isWithinAbstractModule, out Method/*!*/ m)
        {
            Contract.Ensures(Contract.ValueAtReturn(out m) !=null);
            IToken/*!*/ id = Token.NoToken;
            bool hasName = false;  IToken keywordToken;
            Attributes attrs = null;
            List<TypeParameter/*!*/>/*!*/ typeArgs = new List<TypeParameter/*!*/>();
            List<Formal/*!*/> ins = new List<Formal/*!*/>();
            List<Formal/*!*/> outs = new List<Formal/*!*/>();
            List<MaybeFreeExpression/*!*/> req = new List<MaybeFreeExpression/*!*/>();
            List<FrameExpression/*!*/> mod = new List<FrameExpression/*!*/>();
            List<MaybeFreeExpression/*!*/> ens = new List<MaybeFreeExpression/*!*/>();
            List<Expression/*!*/> dec = new List<Expression/*!*/>();
            Attributes decAttrs = null;
            Attributes modAttrs = null;
            BlockStmt body = null;
            bool isLemma = false;
            bool isConstructor = false;
            bool isIndLemma = false;
            bool isCoLemma = false;
            IToken signatureEllipsis = null;
            IToken bodyStart = Token.NoToken;
            IToken bodyEnd = Token.NoToken;

            while (!(StartOf(10))) {SynErr(158); Get();}
            switch (la.kind) {
            case 84: {
            Get();
            break;
            }
            case 41: {
            Get();
            isLemma = true;
            break;
            }
            case 85: {
            Get();
            isCoLemma = true;
            break;
            }
            case 86: {
            Get();
            isCoLemma = true;
            errors.Warning(t, "the 'comethod' keyword has been deprecated; it has been renamed to 'colemma'");

            break;
            }
            case 40: {
            Get();
            Expect(41);
            isIndLemma = true;
            break;
            }
            case 87: {
            Get();
            if (allowConstructor) {
             isConstructor = true;
            } else {
             SemErr(t, "constructors are allowed only in classes");
            }

            break;
            }
            default: SynErr(159); break;
            }
            keywordToken = t;
            if (isLemma) {
             if (mmod.IsGhost) {
               SemErr(t, "lemmas cannot be declared 'ghost' (they are automatically 'ghost')");
             }
            } else if (isConstructor) {
             if (mmod.IsGhost) {
               SemErr(t, "constructors cannot be declared 'ghost'");
             }
             if (mmod.IsStatic) {
               SemErr(t, "constructors cannot be declared 'static'");
             }
            } else if (isIndLemma) {
             if (mmod.IsGhost) {
               SemErr(t, "inductive lemmas cannot be declared 'ghost' (they are automatically 'ghost')");
             }
            } else if (isCoLemma) {
             if (mmod.IsGhost) {
               SemErr(t, "colemmas cannot be declared 'ghost' (they are automatically 'ghost')");
             }
            }

            while (la.kind == 46) {
            Attribute(ref attrs);
            }
            if (la.kind == 1) {
            NoUSIdent(out id);
            hasName = true;
            }
            if (!hasName) {
             id = keywordToken;
             if (!isConstructor) {
               SemErr(la, "a method must be given a name (expecting identifier)");
             }
            }

            if (la.kind == 50 || la.kind == 52) {
            if (la.kind == 52) {
                GenericParameters(typeArgs);
            }
            Formals(true, !mmod.IsGhost, ins);
            if (la.kind == 83) {
                Get();
                if (isConstructor) { SemErr(t, "constructors cannot have out-parameters"); }
                Formals(false, !mmod.IsGhost, outs);
            }
            } else if (la.kind == 59) {
            Get();
            signatureEllipsis = t;
            } else SynErr(160);
            while (StartOf(11)) {
            MethodSpec(req, mod, ens, dec, ref decAttrs, ref modAttrs);
            }
            if (la.kind == 46) {
            BlockStmt(out body, out bodyStart, out bodyEnd);
            }
            if (!isWithinAbstractModule && DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 && !Attributes.Contains(attrs, "axiom") && !Attributes.Contains(attrs, "imported") && !Attributes.Contains(attrs, "decl") && theVerifyThisFile) {
              SemErr(t, "a method with an ensures clause must have a body, unless given the :axiom attribute");
            }

            IToken tok = theVerifyThisFile ? id : new IncludeToken(id);
            if (isConstructor) {
             m = new Constructor(tok, hasName ? id.val : "_ctor", typeArgs, ins,
                             req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
            } else if (isIndLemma) {
             m = new InductiveLemma(tok, id.val, mmod.IsStatic, typeArgs, ins, outs,
                                req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
            } else if (isCoLemma) {
             m = new CoLemma(tok, id.val, mmod.IsStatic, typeArgs, ins, outs,
                         req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
            } else if (isLemma) {
             m = new Lemma(tok, id.val, mmod.IsStatic, typeArgs, ins, outs,
                       req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
            } else {
             m = new Method(tok, id.val, mmod.IsStatic, mmod.IsGhost, typeArgs, ins, outs,
                        req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
            }
            m.BodyStartTok = bodyStart;
            m.BodyEndTok = bodyEnd;
        }
Beispiel #2
0
	void MethodDecl(DeclModifierData dmod, bool allowConstructor, bool isWithinAbstractModule, out Method/*!*/ m) {
		Contract.Ensures(Contract.ValueAtReturn(out m) !=null);
		IToken/*!*/ id = Token.NoToken;
		bool hasName = false;  IToken keywordToken;
		Attributes attrs = null;
		List<TypeParameter/*!*/>/*!*/ typeArgs = new List<TypeParameter/*!*/>();
		List<Formal/*!*/> ins = new List<Formal/*!*/>();
		List<Formal/*!*/> outs = new List<Formal/*!*/>();
		List<MaybeFreeExpression/*!*/> req = new List<MaybeFreeExpression/*!*/>();
		List<FrameExpression/*!*/> mod = new List<FrameExpression/*!*/>();
		List<MaybeFreeExpression/*!*/> ens = new List<MaybeFreeExpression/*!*/>();
		List<Expression/*!*/> dec = new List<Expression/*!*/>();
		Attributes decAttrs = null;
		Attributes modAttrs = null;
		BlockStmt body = null;
		bool isLemma = false;
		bool isConstructor = false;
		bool isIndLemma = false;
		bool isCoLemma = false;
		bool isTactic = false;
		IToken signatureEllipsis = null;
		IToken bodyStart = Token.NoToken;
		IToken bodyEnd = Token.NoToken;
		AllowedDeclModifiers allowed = AllowedDeclModifiers.None;
		string caption = "";
		
		while (!(StartOf(12))) {SynErr(172); Get();}
		switch (la.kind) {
		case 89: {
			Get();
			caption = "Methods";
			allowed = AllowedDeclModifiers.Ghost | AllowedDeclModifiers.Static 
			 | AllowedDeclModifiers.Extern; 
			break;
		}
		case 60: {
			Get();
			isTactic = true; caption = "Tactics"; 
			allowed = AllowedDeclModifiers.AlreadyGhost | AllowedDeclModifiers.Static 
			| AllowedDeclModifiers.Protected; 
			break;
		}
		case 41: {
			Get();
			isLemma = true; caption = "Lemmas";
			allowed = AllowedDeclModifiers.AlreadyGhost | AllowedDeclModifiers.Static 
			 | AllowedDeclModifiers.Protected; 
			break;
		}
		case 90: {
			Get();
			isCoLemma = true; caption = "Colemmas";
			allowed = AllowedDeclModifiers.AlreadyGhost | AllowedDeclModifiers.Static 
			 | AllowedDeclModifiers.Protected; 
			break;
		}
		case 91: {
			Get();
			isCoLemma = true; caption = "Comethods";
			allowed = AllowedDeclModifiers.AlreadyGhost | AllowedDeclModifiers.Static 
			 | AllowedDeclModifiers.Protected;
			errors.Warning(t, "the 'comethod' keyword has been deprecated; it has been renamed to 'colemma'");
			
			break;
		}
		case 40: {
			Get();
			Expect(41);
			isIndLemma = true;  caption = "Inductive lemmas";
			allowed = AllowedDeclModifiers.AlreadyGhost | AllowedDeclModifiers.Static;
			break;
		}
		case 92: {
			Get();
			if (allowConstructor) {
			 isConstructor = true;
			} else {
			 SemErr(t, "constructors are allowed only in classes");
			} 
			caption = "Constructors";
			allowed = AllowedDeclModifiers.None;
			
			break;
		}
		default: SynErr(173); break;
		}
		keywordToken = t; 
		CheckDeclModifiers(dmod, caption, allowed); 
		while (la.kind == 46) {
			Attribute(ref attrs);
		}
		if (la.kind == 1) {
			NoUSIdent(out id);
			hasName = true; 
		}
		if (!hasName) {
		 id = keywordToken;
		 if (!isConstructor) {
		   SemErr(la, "a method must be given a name (expecting identifier)");
		 }
		}
		EncodeExternAsAttribute(dmod, ref attrs, id, /* needAxiom */ true);
		
		if (la.kind == 50 || la.kind == 52) {
			if (la.kind == 52) {
				GenericParameters(typeArgs);
			}
			Formals(true, !dmod.IsGhost, ins);
			if (la.kind == 88) {
				Get();
				if (isConstructor) { SemErr(t, "constructors cannot have out-parameters"); } 
				Formals(false, !dmod.IsGhost, outs);
			}
		} else if (la.kind == 59) {
			Get();
			signatureEllipsis = t; 
		} else SynErr(174);
		while (StartOf(13)) {
			MethodSpec(req, mod, ens, dec, ref decAttrs, ref modAttrs);
		}
		if (la.kind == 46) {
			BlockStmt(out body, out bodyStart, out bodyEnd);
		}
		if (!isWithinAbstractModule && DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 && !Attributes.Contains(attrs, "axiom") && !Attributes.Contains(attrs, "imported") && !Attributes.Contains(attrs, "decl") && theVerifyThisFile) {
		  SemErr(t, "a method with an ensures clause must have a body, unless given the :axiom attribute");
		}
		
		IToken tok = theVerifyThisFile ? id : new IncludeToken(id);
		if (isConstructor) {
		 m = new Constructor(tok, hasName ? id.val : "_ctor", typeArgs, ins,
		                     req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
		} else if (isIndLemma) {
		 m = new InductiveLemma(tok, id.val, dmod.IsStatic, typeArgs, ins, outs,
		                        req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
		} else if (isCoLemma) {
		 m = new CoLemma(tok, id.val, dmod.IsStatic, typeArgs, ins, outs,
		                 req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
		} else if (isLemma) {
		 m = new Lemma(tok, id.val, dmod.IsStatic, typeArgs, ins, outs,
		               req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
		} else if(isTactic) {
		 m = new Tactic(tok, id.val, dmod.IsStatic, typeArgs, ins, outs,
		               req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
		
		} else {
		 m = new Method(tok, id.val, dmod.IsStatic, dmod.IsGhost, typeArgs, ins, outs,
		                req, new Specification<FrameExpression>(mod, modAttrs), ens, new Specification<Expression>(dec, decAttrs), body, attrs, signatureEllipsis);
		}
		m.BodyStartTok = bodyStart;
		m.BodyEndTok = bodyEnd;
		
	}