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); } }
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); } }