summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Rustan Leino <leino@microsoft.com>2011-05-27 14:15:51 -0700
committerGravatar Rustan Leino <leino@microsoft.com>2011-05-27 14:15:51 -0700
commitb1d98701623bf4cbeb741dbfc6cca892c7ed6459 (patch)
tree279deaef16b320f414c88e2f1aa1e01edd219a00
parent1acd05253ea0fc614ac3e6a612be19a3f3bcf6a4 (diff)
parent803f42612314d2d27f20dfa476bf0ff8ed24d958 (diff)
Merge
-rw-r--r--Dafny/Compiler.cs69
-rw-r--r--Dafny/Dafny.atg557
-rw-r--r--Dafny/DafnyAst.cs422
-rw-r--r--Dafny/Parser.cs1331
-rw-r--r--Dafny/Printer.cs152
-rw-r--r--Dafny/Resolver.cs1049
-rw-r--r--Dafny/Scanner.cs151
-rw-r--r--Dafny/Translator.cs112
-rw-r--r--Test/VSComp2010/Problem1-SumMax.dfy2
-rw-r--r--Test/VSComp2010/Problem2-Invert.dfy6
-rw-r--r--Test/VSComp2010/Problem3-FindZero.dfy10
-rw-r--r--Test/VSComp2010/Problem4-Queens.dfy10
-rw-r--r--Test/VSComp2010/Problem5-DoubleEndedQueue.dfy16
-rw-r--r--Test/VSI-Benchmarks/b1.dfy28
-rw-r--r--Test/VSI-Benchmarks/b2.dfy16
-rw-r--r--Test/VSI-Benchmarks/b3.dfy14
-rw-r--r--Test/VSI-Benchmarks/b4.dfy11
-rw-r--r--Test/VSI-Benchmarks/b5.dfy36
-rw-r--r--Test/VSI-Benchmarks/b6.dfy16
-rw-r--r--Test/VSI-Benchmarks/b7.dfy23
-rw-r--r--Test/VSI-Benchmarks/b8.dfy42
-rw-r--r--Test/dafny0/Answer381
-rw-r--r--Test/dafny0/Basics.dfy67
-rw-r--r--Test/dafny0/Comprehensions.dfy10
-rw-r--r--Test/dafny0/ControlStructures.dfy119
-rw-r--r--Test/dafny0/DTypes.dfy20
-rw-r--r--Test/dafny0/Datatypes.dfy15
-rw-r--r--Test/dafny0/Definedness.dfy4
-rw-r--r--Test/dafny0/FunctionSpecifications.dfy5
-rw-r--r--Test/dafny0/Modules0.dfy36
-rw-r--r--Test/dafny0/Modules1.dfy13
-rw-r--r--Test/dafny0/MultiDimArray.dfy2
-rw-r--r--Test/dafny0/NatTypes.dfy17
-rw-r--r--Test/dafny0/ParseErrors.dfy20
-rw-r--r--Test/dafny0/ResolutionErrors.dfy236
-rw-r--r--Test/dafny0/Simple.dfy18
-rw-r--r--Test/dafny0/SmallTests.dfy29
-rw-r--r--Test/dafny0/Termination.dfy38
-rw-r--r--Test/dafny0/TypeAntecedents.dfy39
-rw-r--r--Test/dafny0/TypeParameters.dfy14
-rw-r--r--Test/dafny0/TypeTests.dfy39
-rw-r--r--Test/dafny0/Use.dfy227
-rw-r--r--Test/dafny0/runtest.bat6
-rw-r--r--Test/dafny1/BinaryTree.dfy33
-rw-r--r--Test/dafny1/ExtensibleArray.dfy22
-rw-r--r--Test/dafny1/FindZero.dfy4
-rw-r--r--Test/dafny1/Induction.dfy21
-rw-r--r--Test/dafny1/MatrixFun.dfy12
-rw-r--r--Test/dafny1/PriorityQueue.dfy8
-rw-r--r--Test/dafny1/Queue.dfy36
-rw-r--r--Test/dafny1/Rippling.dfy220
-rw-r--r--Test/dafny1/SchorrWaite.dfy15
-rw-r--r--Test/dafny1/SeparationLogicList.dfy4
-rw-r--r--Test/dafny1/Substitution.dfy45
-rw-r--r--Test/dafny1/SumOfCubes.dfy22
-rw-r--r--Test/dafny1/TerminationDemos.dfy6
-rw-r--r--Test/dafny1/TreeDatatype.dfy38
-rw-r--r--Test/dafny1/UltraFilter.dfy10
-rw-r--r--Test/dafny1/pow2.dfy8
-rw-r--r--Test/vacid0/Composite.dfy30
-rw-r--r--Test/vacid0/SparseArray.dfy8
-rw-r--r--Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyLanguageService.cs19
62 files changed, 3358 insertions, 2631 deletions
diff --git a/Dafny/Compiler.cs b/Dafny/Compiler.cs
index 6dabace1..82604794 100644
--- a/Dafny/Compiler.cs
+++ b/Dafny/Compiler.cs
@@ -186,15 +186,10 @@ namespace Microsoft.Dafny {
// }
Indent(indent);
wr.Write("public class {0}", DtCtorName(ctor));
- if (dt.TypeArgs.Count != 0 || ctor.TypeArgs.Count != 0) {
+ if (dt.TypeArgs.Count != 0) {
wr.Write("<");
- string sep = "";
if (dt.TypeArgs.Count != 0) {
wr.Write("{0}", TypeParameters(dt.TypeArgs));
- sep = ",";
- }
- if (ctor.TypeArgs.Count != 0) {
- wr.Write("{0}{1}", sep, TypeParameters(ctor.TypeArgs));
}
wr.Write(">");
}
@@ -614,14 +609,9 @@ namespace Microsoft.Dafny {
wr.WriteLine(");");
}
} else if (stmt is BreakStmt) {
- BreakStmt s = (BreakStmt)stmt;
+ var s = (BreakStmt)stmt;
Indent(indent);
- if (s.TargetLabel == null) {
- // use the scoping rules of C#
- wr.WriteLine("break;");
- } else {
- wr.WriteLine("goto after_{0};", s.TargetLabel);
- }
+ wr.WriteLine("goto after_{0};", s.TargetStmt.Labels.UniqueId);
} else if (stmt is ReturnStmt) {
Indent(indent);
wr.WriteLine("return;");
@@ -845,6 +835,13 @@ namespace Microsoft.Dafny {
Indent(indent); wr.WriteLine("}");
}
+ } else if (stmt is ConcreteSyntaxStatement) {
+ var s = (ConcreteSyntaxStatement)stmt;
+ // TODO: Update statements should perform multiple assignments in parallel!
+ foreach (var ss in s.ResolvedStatements) {
+ TrStmt(ss, indent);
+ }
+
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
}
@@ -853,10 +850,6 @@ namespace Microsoft.Dafny {
void TrCallStmt(CallStmt s, string receiverReplacement, int indent) {
Contract.Requires(s != null);
- foreach (VarDecl local in s.NewVars) {
- TrVarDecl(local, false, indent);
- }
-
Contract.Assert(s.Method != null); // follows from the fact that stmt has been successfully resolved
Indent(indent);
if (receiverReplacement != null) {
@@ -929,29 +922,11 @@ namespace Microsoft.Dafny {
}
void TrStmtList(List<Statement/*!*/>/*!*/ stmts, int indent) {Contract.Requires(cce.NonNullElements(stmts));
- List<string/*!*/> currentLabels = null;
foreach (Statement ss in stmts) {
- if (ss is LabelStmt) {
- LabelStmt s = (LabelStmt)ss;
- if (currentLabels == null) {
- currentLabels = new List<string>();
- }
- currentLabels.Add(s.Label);
- } else {
- TrStmt(ss, indent + IndentAmount);
- SpillLabels(currentLabels, indent);
- currentLabels = null;
- }
- }
- SpillLabels(currentLabels, indent);
- }
-
- void SpillLabels(List<string> labels, int indent) {
- Contract.Requires(cce.NonNullElements(labels));
- if (labels != null) {
- foreach (string label in labels) {
- Indent(indent);
- wr.WriteLine("after_{0}: ;", label);
+ TrStmt(ss, indent + IndentAmount);
+ if (ss.Labels != null) {
+ Indent(indent); // labels are not indented as much as the statements
+ wr.WriteLine("after_{0}: ;", ss.Labels.UniqueId);
}
}
}
@@ -965,15 +940,7 @@ namespace Microsoft.Dafny {
Indent(indent);
wr.Write("{0} @{1}", TypeName(s.Type), s.Name);
- if (s.Rhs != null) {
- wr.Write(" = ");
- TrAssignmentRhs(s.Rhs);
- wr.WriteLine(";");
- var tRhs = s.Rhs as TypeRhs;
- if (tRhs != null && tRhs.InitCall != null) {
- TrCallStmt(tRhs.InitCall, s.Name, indent);
- }
- } else if (alwaysInitialize) {
+ if (alwaysInitialize) {
// produce a default value
wr.WriteLine(" = {0};", DefaultValue(s.Type));
} else {
@@ -1444,7 +1411,11 @@ namespace Microsoft.Dafny {
wr.Write(") : (");
TrExpr(e.Els);
wr.Write(")");
-
+
+ } else if (expr is ConcreteSyntaxExpression) {
+ var e = (ConcreteSyntaxExpression)expr;
+ TrExpr(e.ResolvedExpression);
+
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
}
diff --git a/Dafny/Dafny.atg b/Dafny/Dafny.atg
index 388ae8cd..11a2dfed 100644
--- a/Dafny/Dafny.atg
+++ b/Dafny/Dafny.atg
@@ -28,7 +28,6 @@ static Expression/*!*/ dummyExpr = new LiteralExpr(Token.NoToken);
static FrameExpression/*!*/ dummyFrameExpr = new FrameExpression(dummyExpr, null);
static Statement/*!*/ dummyStmt = new ReturnStmt(Token.NoToken);
static Attributes.Argument/*!*/ dummyAttrArg = new Attributes.Argument("dummyAttrArg");
-static Scope<string>/*!*/ parseVarScope = new Scope<string>();
static int anonymousIds = 0;
struct MemberModifiers {
@@ -38,22 +37,6 @@ struct MemberModifiers {
}
// helper routine for parsing call statements
-private static void RecordCallLhs(IdentifierExpr/*!*/ e,
- List<IdentifierExpr/*!*/>/*!*/ lhs,
- List<AutoVarDecl/*!*/>/*!*/ newVars) {
- Contract.Requires(e != null);
- Contract.Requires(cce.NonNullElements(lhs));
- Contract.Requires(cce.NonNullElements(newVars));
- int index = lhs.Count;
- lhs.Add(e);
- if (parseVarScope.Find(e.Name) == null) {
- AutoVarDecl d = new AutoVarDecl(e.tok, e.Name, new InferredTypeProxy(), index);
- newVars.Add(d);
- parseVarScope.Push(e.Name, e.Name);
- }
-}
-
-// helper routine for parsing call statements
private static Expression/*!*/ ConvertToLocal(Expression/*!*/ e)
{
Contract.Requires(e != null);
@@ -284,16 +267,10 @@ DatatypeDecl<ModuleDecl/*!*/ module, out DatatypeDecl/*!*/ dt>
{ Attribute<ref attrs> }
Ident<out id>
[ GenericParameters<typeArgs> ]
- (
- "{" (. bodyStart = t; .)
- { DatatypeMemberDecl<ctors> ";" }
- "}"
- |
- "=" (. bodyStart = t; .)
- DatatypeMemberDecl<ctors>
- { "|" DatatypeMemberDecl<ctors> }
- ";"
- )
+ "=" (. bodyStart = t; .)
+ DatatypeMemberDecl<ctors>
+ { "|" DatatypeMemberDecl<ctors> }
+ ";"
(. dt = new DatatypeDecl(id, id.val, module, typeArgs, ctors, attrs);
dt.BodyStartTok = bodyStart;
dt.BodyEndTok = t;
@@ -304,17 +281,12 @@ DatatypeMemberDecl<.List<DatatypeCtor/*!*/>/*!*/ ctors.>
= (. Contract.Requires(cce.NonNullElements(ctors));
Attributes attrs = null;
IToken/*!*/ id;
- List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
List<Formal/*!*/> formals = new List<Formal/*!*/>();
.)
{ Attribute<ref attrs> }
Ident<out id>
- [ GenericParameters<typeArgs> ]
- (. parseVarScope.PushMarker(); .)
[ FormalsOptionalIds<formals> ]
- (. parseVarScope.PopMarker();
- ctors.Add(new DatatypeCtor(id, id.val, typeArgs, formals, attrs));
- .)
+ (. ctors.Add(new DatatypeCtor(id, id.val, formals, attrs)); .)
.
FieldDecl<.MemberModifiers mmod, List<MemberDecl/*!*/>/*!*/ mm.>
@@ -339,7 +311,6 @@ CouplingInvDecl<.MemberModifiers mmod, List<MemberDecl/*!*/>/*!*/ mm.>
List<IToken/*!*/> ids = new List<IToken/*!*/>();;
IToken/*!*/ id;
Expression/*!*/ e;
- parseVarScope.PushMarker();
.)
"replaces"
(. if (mmod.IsUnlimited) { SemErr(t, "coupling invariants cannot be declared 'unlimited'"); }
@@ -347,15 +318,13 @@ CouplingInvDecl<.MemberModifiers mmod, List<MemberDecl/*!*/>/*!*/ mm.>
if (mmod.IsGhost) { SemErr(t, "coupling invariants cannot be declared 'ghost'"); }
.)
{ Attribute<ref attrs> }
- Ident<out id> (. ids.Add(id); parseVarScope.Push(id.val, id.val); .)
- { "," Ident<out id> (. ids.Add(id); parseVarScope.Push(id.val, id.val); .)
+ Ident<out id> (. ids.Add(id); .)
+ { "," Ident<out id> (. ids.Add(id); .)
}
"by"
Expression<out e>
";"
- (. mm.Add(new CouplingInvariant(ids, e, attrs));
- parseVarScope.PopMarker();
- .)
+ (. mm.Add(new CouplingInvariant(ids, e, attrs)); .)
.
@@ -376,6 +345,15 @@ IdentType<out IToken/*!*/ id, out Type/*!*/ ty>
Type<out ty>
.
+LocalIdentTypeOptional<out VarDecl/*!*/ var, bool isGhost>
+= (. IToken/*!*/ id; Type/*!*/ ty; Type optType = null;
+ .)
+ Ident<out id>
+ [ ":" Type<out ty> (. optType = ty; .)
+ ]
+ (. var = new VarDecl(id, id.val, optType == null ? new InferredTypeProxy() : optType, isGhost); .)
+ .
+
IdentTypeOptional<out BoundVar/*!*/ var>
= (. Contract.Ensures(Contract.ValueAtReturn(out var)!=null); IToken/*!*/ id; Type/*!*/ ty; Type optType = null;
.)
@@ -450,8 +428,7 @@ MethodDecl<MemberModifiers mmod, out Method/*!*/ m>
{ Attribute<ref attrs> }
Ident<out id>
[ GenericParameters<typeArgs> ]
- (. parseVarScope.PushMarker(); .)
- Formals<true, true, ins>
+ Formals<true, !mmod.IsGhost, ins>
[ "returns"
Formals<false, true, outs>
]
@@ -460,8 +437,7 @@ MethodDecl<MemberModifiers mmod, out Method/*!*/ m>
| { MethodSpec<req, mod, ens, dec> } BlockStmt<out bb, out bodyStart, out bodyEnd> (. body = (BlockStmt)bb; .)
)
- (. parseVarScope.PopMarker();
- if (isRefinement)
+ (. if (isRefinement)
m = new MethodRefinement(id, id.val, mmod.IsStatic, mmod.IsGhost, typeArgs, ins, outs, req, mod, ens, dec, body, attrs);
else
m = new Method(id, id.val, mmod.IsStatic, mmod.IsGhost, typeArgs, ins, outs, req, mod, ens, dec, body, attrs);
@@ -492,8 +468,8 @@ Formals<.bool incoming, bool allowGhosts, List<Formal/*!*/>/*!*/ formals.>
= (. Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; bool isGhost; .)
"("
[
- GIdentType<allowGhosts, out id, out ty, out isGhost> (. formals.Add(new Formal(id, id.val, ty, incoming, isGhost)); parseVarScope.Push(id.val, id.val); .)
- { "," GIdentType<allowGhosts, out id, out ty, out isGhost> (. formals.Add(new Formal(id, id.val, ty, incoming, isGhost)); parseVarScope.Push(id.val, id.val); .)
+ GIdentType<allowGhosts, out id, out ty, out isGhost> (. formals.Add(new Formal(id, id.val, ty, incoming, isGhost)); .)
+ { "," GIdentType<allowGhosts, out id, out ty, out isGhost> (. formals.Add(new Formal(id, id.val, ty, incoming, isGhost)); .)
}
]
")"
@@ -503,8 +479,8 @@ FormalsOptionalIds<.List<Formal/*!*/>/*!*/ formals.>
= (. Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; string/*!*/ name; bool isGhost; .)
"("
[
- TypeIdentOptional<out id, out name, out ty, out isGhost> (. formals.Add(new Formal(id, name, ty, true, isGhost)); parseVarScope.Push(name, name); .)
- { "," TypeIdentOptional<out id, out name, out ty, out isGhost> (. formals.Add(new Formal(id, name, ty, true, isGhost)); parseVarScope.Push(name, name); .)
+ TypeIdentOptional<out id, out name, out ty, out isGhost> (. formals.Add(new Formal(id, name, ty, true, isGhost)); .)
+ { "," TypeIdentOptional<out id, out name, out ty, out isGhost> (. formals.Add(new Formal(id, name, ty, true, isGhost)); .)
}
]
")"
@@ -597,8 +573,7 @@ FunctionDecl<MemberModifiers mmod, out Function/*!*/ f>
{ Attribute<ref attrs> }
Ident<out id>
[ GenericParameters<typeArgs> ]
- (. parseVarScope.PushMarker(); .)
- Formals<true, false, formals>
+ Formals<true, isFunctionMethod, formals>
":"
Type<out returnType>
( ";"
@@ -606,8 +581,7 @@ FunctionDecl<MemberModifiers mmod, out Function/*!*/ f>
| { FunctionSpec<reqs, reads, ens, decreases> }
FunctionBody<out bb, out bodyStart, out bodyEnd> (. body = bb; .)
)
- (. parseVarScope.PopMarker();
- f = new Function(id, id.val, mmod.IsStatic, !isFunctionMethod, mmod.IsUnlimited, typeArgs, formals, returnType, reqs, reads, ens, decreases, body, attrs);
+ (. f = new Function(id, id.val, mmod.IsStatic, !isFunctionMethod, mmod.IsUnlimited, typeArgs, formals, returnType, reqs, reads, ens, decreases, body, attrs);
f.BodyStartTok = bodyStart;
f.BodyEndTok = bodyEnd;
.)
@@ -686,18 +660,15 @@ CaseExpression<out MatchCaseExpr/*!*/ c>
List<BoundVar/*!*/> arguments = new List<BoundVar/*!*/>();
Expression/*!*/ body;
.)
- "case" (. x = t; parseVarScope.PushMarker(); .)
+ "case" (. x = t; .)
Ident<out id>
[ "("
- Ident<out arg> (. arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
- parseVarScope.Push(arg.val, arg.val); .)
- { "," Ident<out arg> (. arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
- parseVarScope.Push(arg.val, arg.val); .)
+ Ident<out arg> (. arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy())); .)
+ { "," Ident<out arg> (. arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy())); .)
}
")" ]
"=>"
- MatchOrExpr<out body> (. c = new MatchCaseExpr(x, id.val, arguments, body);
- parseVarScope.PopMarker(); .)
+ MatchOrExpr<out body> (. c = new MatchCaseExpr(x, id.val, arguments, body); .)
.
/* Note, '(' is start of more than one alternative in MatchOrExpr, but the first intentionally hides
@@ -716,95 +687,83 @@ BlockStmt<out Statement/*!*/ block, out IToken bodyStart, out IToken bodyEnd>
= (. Contract.Ensures(Contract.ValueAtReturn(out block) != null);
List<Statement/*!*/> body = new List<Statement/*!*/>();
.)
- (. parseVarScope.PushMarker(); .)
"{" (. bodyStart = t; .)
{ Stmt<body>
}
"}" (. bodyEnd = t;
block = new BlockStmt(bodyStart, body); .)
- (. parseVarScope.PopMarker(); .)
.
Stmt<.List<Statement/*!*/>/*!*/ ss.>
-= (. Contract.Requires(cce.NonNullElements(ss)); Statement/*!*/ s;
- IToken bodyStart, bodyEnd;
+= (. Statement/*!*/ s;
.)
- /* By first reading a sequence of block statements, we avoid problems in the generated parser, despite
- the ambiguity in the grammar. See Note in ConstAtomExpression production.
- */
- { BlockStmt<out s, out bodyStart, out bodyEnd> (. ss.Add(s); .)
- }
- ( OneStmt<out s> (. ss.Add(s); .)
- | VarDeclStmts<ss>
- )
+ OneStmt<out s> (. ss.Add(s); .)
.
OneStmt<out Statement/*!*/ s>
= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; IToken/*!*/ id; string label = null;
s = dummyStmt; /* to please the compiler */
+ IToken bodyStart, bodyEnd;
+ int breakCount;
.)
/* This list does not contain BlockStmt, see comment above in Stmt production. */
- ( AssertStmt<out s>
+ ( BlockStmt<out s, out bodyStart, out bodyEnd>
+ | AssertStmt<out s>
| AssumeStmt<out s>
- | UseStmt<out s>
| PrintStmt<out s>
- | AssignStmt<out s, true>
+ | UpdateStmt<out s>
| HavocStmt<out s>
- | CallStmt<out s>
+ | VarDeclStatement<out s>
| IfStmt<out s>
| WhileStmt<out s>
| MatchStmt<out s>
| ForeachStmt<out s>
| "label" (. x = t; .)
- Ident<out id> ":" (. s = new LabelStmt(x, id.val); .)
- | "break" (. x = t; .)
- [ Ident<out id> (. label = id.val; .)
- ] ";" (. s = new BreakStmt(x, label); .)
+ Ident<out id> ":"
+ OneStmt<out s> (. s.Labels = new LabelNode(x, id.val, s.Labels); .)
+ | "break" (. x = t; breakCount = 1; label = null; .)
+ ( Ident<out id> (. label = id.val; .)
+ | { "break" (. breakCount++; .)
+ }
+ )
+ ";" (. s = label != null ? new BreakStmt(x, label) : new BreakStmt(x, breakCount); .)
| "return" (. x = t; .)
";" (. s = new ReturnStmt(x); .)
)
.
-AssignStmt<out Statement/*!*/ s, bool allowChoose>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x;
- Expression/*!*/ lhs;
- List<Expression> rhs;
- Type ty;
- s = dummyStmt;
- CallStmt initCall = null;
+UpdateStmt<out Statement/*!*/ s>
+= (. List<Expression> lhss = new List<Expression>();
+ List<DeterminedAssignmentRhs> rhss = new List<DeterminedAssignmentRhs>();
+ Expression e; DeterminedAssignmentRhs r;
+ Expression lhs0;
+ IToken x;
.)
- LhsExpr<out lhs>
- ":=" (. x = t; .)
- AssignRhs<out rhs, out ty, out initCall, lhs>
- (. if (ty == null) {
- Contract.Assert(rhs != null);
- Contract.Assert(rhs.Count == 1);
- s = new AssignStmt(x, lhs, rhs[0]);
- if (!allowChoose) {
- var r = rhs[0] as UnaryExpr;
- if (r != null && r.Op == UnaryExpr.Opcode.SetChoose) {
- SemErr("choose operator not allowed as RHS in foreach assignment");
- }
- }
- } else if (rhs == null) {
- s = new AssignStmt(x, lhs, ty, initCall);
- } else {
- s = new AssignStmt(x, lhs, ty, rhs);
- }
- .)
- ";"
+ Lhs<out e> (. x = e.tok; .)
+ ( ";" (. rhss.Add(new ExprRhs(e)); .)
+ | (. lhss.Add(e); lhs0 = e; .)
+ { "," Lhs<out e> (. lhss.Add(e); .)
+ }
+ ":=" (. x = t; .)
+ Rhs<out r, lhs0> (. rhss.Add(r); .)
+ { "," Rhs<out r, lhs0> (. rhss.Add(r); .)
+ }
+ ";"
+ | ":" (. SemErr(t, "invalid statement (did you forget the 'label' keyword?)"); .)
+ )
+ (. s = new UpdateStmt(x, lhss, rhss); .)
.
-AssignRhs<.out List<Expression> ee, out Type ty, out CallStmt initCall, Expression receiverForInitCall.>
-/* ensures ee != null || ty != null; */
-/* ensures ee != null ==> 1 <= ee.Count; */
-/* ensures ty == null ==> 1 == ee.Count; */
-= (. IToken/*!*/ x; Expression/*!*/ e;
- ee = null; ty = null;
- initCall = null;
+Rhs<out DeterminedAssignmentRhs r, Expression receiverForInitCall>
+= (. IToken/*!*/ x, newToken; Expression/*!*/ e;
+ List<Expression> ee = null;
+ Type ty = null;
+ CallStmt initCall = null;
List<Expression> args;
+ r = null; // to please compiler
.)
- ( "new" TypeAndToken<out x, out ty>
+ ( "new" (. newToken = t; .)
+ TypeAndToken<out x, out ty>
[ "[" (. ee = new List<Expression>(); .)
Expressions<ee>
"]" (. // make sure an array class with this dimensionality exists
@@ -813,67 +772,64 @@ AssignRhs<.out List<Expression> ee, out Type ty, out CallStmt initCall, Expressi
| "." Ident<out x>
"(" (. args = new List<Expression/*!*/>(); .)
[ Expressions<args> ]
- ")" (. initCall = new CallStmt(x, new List<AutoVarDecl>(), new List<IdentifierExpr>(),
+ ")" (. initCall = new CallStmt(x, new List<IdentifierExpr>(),
receiverForInitCall, x.val, args); .)
]
- | "choose" (. x = t; .)
- Expression<out e> (. e = new UnaryExpr(x, UnaryExpr.Opcode.SetChoose, e);
- ee = new List<Expression>() { e };
- .)
- | Expression<out e> (. ee = new List<Expression>() { e }; .)
- ) (. if (ee == null && ty == null) { ee = new List<Expression>() { dummyExpr}; } .)
- .
-
-HavocStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ lhs; .)
- "havoc" (. x = t; .)
- LhsExpr<out lhs> ";" (. s = new AssignStmt(x, lhs); .)
- .
+ (. if (ee != null) {
+ r = new TypeRhs(newToken, ty, ee);
+ } else {
+ r = new TypeRhs(newToken, ty, initCall);
+ }
+ .)
-LhsExpr<out Expression/*!*/ e>
-= (.Contract.Ensures(Contract.ValueAtReturn(out e)!=null);.)
- SelectExpression<out e>
- .
+ /* One day, the choose expression should be treated just as a special case of a method call. */
+ | "choose" (. x = t; .)
+ Expression<out e> (. r = new ExprRhs(new UnaryExpr(x, UnaryExpr.Opcode.SetChoose, e)); .)
-VarDeclStmts<.List<Statement/*!*/>/*!*/ ss.>
-= (. Contract.Requires(cce.NonNullElements(ss)); VarDecl/*!*/ d; bool isGhost = false; .)
- [ "ghost" (. isGhost = true; .)
- ]
- "var"
- IdentTypeRhs<out d, isGhost> (. ss.Add(d); parseVarScope.Push(d.Name, d.Name); .)
- { "," IdentTypeRhs<out d, isGhost> (. ss.Add(d); parseVarScope.Push(d.Name, d.Name); .)
- }
- ";"
+ | Expression<out e> (. r = new ExprRhs(e); .)
+ )
.
-IdentTypeRhs<out VarDecl/*!*/ d, bool isGhost>
-= (. Contract.Ensures(Contract.ValueAtReturn(out d) != null); IToken/*!*/ id; Type/*!*/ ty;
- List<Expression> rhs = null; Type newType = null;
- Type optionalType = null; DeterminedAssignmentRhs optionalRhs = null;
- CallStmt initCall = null;
+VarDeclStatement<.out Statement/*!*/ s.>
+= (. IToken x = null, assignTok = null; bool isGhost = false;
+ VarDecl/*!*/ d;
+ DeterminedAssignmentRhs r; Expression lhs0;
+ List<VarDecl> lhss = new List<VarDecl>();
+ List<DeterminedAssignmentRhs> rhss = new List<DeterminedAssignmentRhs>();
.)
- Ident<out id>
- [ ":" Type<out ty> (. optionalType = ty; .)
+ [ "ghost" (. isGhost = true; x = t; .)
]
- [ ":="
- AssignRhs<out rhs, out newType, out initCall, new IdentifierExpr(id, id.val)>
+ "var" (. if (!isGhost) { x = t; } .)
+ LocalIdentTypeOptional<out d, isGhost> (. lhss.Add(d); .)
+ { ","
+ LocalIdentTypeOptional<out d, isGhost> (. lhss.Add(d); .)
+ }
+ [ ":=" (. assignTok = t; lhs0 = new IdentifierExpr(lhss[0].Tok, lhss[0].Name); .)
+ Rhs<out r, lhs0> (. rhss.Add(r); .)
+ { "," Rhs<out r, lhs0> (. rhss.Add(r); .)
+ }
]
- (. if (newType == null && rhs != null) {
- Contract.Assert(rhs.Count == 1);
- optionalRhs = new ExprRhs(rhs[0]);
- } else if (newType != null) {
- if (rhs == null) {
- optionalRhs = new TypeRhs(newType, initCall);
- } else {
- optionalRhs = new TypeRhs(newType, rhs);
+ ";"
+ (. UpdateStmt update;
+ if (rhss.Count == 0) {
+ update = null;
+ } else {
+ var ies = new List<Expression>();
+ foreach (var lhs in lhss) {
+ ies.Add(new AutoGhostIdentifierExpr(lhs.Tok, lhs.Name));
}
- } else if (optionalType == null) {
- optionalType = new InferredTypeProxy();
+ update = new UpdateStmt(assignTok, ies, rhss);
}
- d = new VarDecl(id, id.val, optionalType, isGhost, optionalRhs);
+ s = new VarDeclStmt(x, lhss, update);
.)
.
+HavocStmt<out Statement/*!*/ s>
+= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ lhs; .)
+ "havoc" (. x = t; .)
+ Lhs<out lhs> ";" (. s = new AssignStmt(x, lhs); .)
+ .
+
IfStmt<out Statement/*!*/ ifStmt>
= (. Contract.Ensures(Contract.ValueAtReturn(out ifStmt) != null); IToken/*!*/ x;
Expression guard;
@@ -911,9 +867,7 @@ AlternativeBlock<.out List<GuardedAlternative> alternatives.>
Expression<out e>
"=>"
(. body = new List<Statement>(); .)
- (. parseVarScope.PushMarker(); .)
{ Stmt<body> }
- (. parseVarScope.PopMarker(); .)
(. alternatives.Add(new GuardedAlternative(x, e, body)); .)
}
"}"
@@ -989,85 +943,29 @@ CaseStatement<out MatchCaseStmt/*!*/ c>
List<BoundVar/*!*/> arguments = new List<BoundVar/*!*/>();
List<Statement/*!*/> body = new List<Statement/*!*/>();
.)
- "case" (. x = t; parseVarScope.PushMarker(); .)
+ "case" (. x = t; .)
Ident<out id>
[ "("
- Ident<out arg> (. arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
- parseVarScope.Push(arg.val, arg.val); .)
- { "," Ident<out arg> (. arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
- parseVarScope.Push(arg.val, arg.val); .)
+ Ident<out arg> (. arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy())); .)
+ { "," Ident<out arg> (. arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy())); .)
}
")" ]
"=>"
- (. parseVarScope.PushMarker(); .)
{ Stmt<body> }
- (. parseVarScope.PopMarker(); .)
(. c = new MatchCaseStmt(x, id.val, arguments, body); .)
- (. parseVarScope.PopMarker(); .)
- .
-
-CallStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x, id;
- Expression/*!*/ e;
- List<IdentifierExpr/*!*/> lhs = new List<IdentifierExpr/*!*/>();
- List<AutoVarDecl/*!*/> newVars = new List<AutoVarDecl/*!*/>();
- .)
- "call" (. x = t; .)
- CallStmtSubExpr<out e>
-
- [ "," /* call a,b,c,... := ... */
- (. e = ConvertToLocal(e);
- if (e is IdentifierExpr) {
- RecordCallLhs((IdentifierExpr)e, lhs, newVars);
- } else if (e is FieldSelectExpr) {
- SemErr(e.tok, "each LHS of call statement must be a variable, not a field");
- } else {
- SemErr(e.tok, "each LHS of call statement must be a variable");
- }
- .)
- Ident<out id> (. RecordCallLhs(new IdentifierExpr(id, id.val), lhs, newVars); .)
- { "," Ident<out id> (. RecordCallLhs(new IdentifierExpr(id, id.val), lhs, newVars); .)
- }
- ":="
- CallStmtSubExpr<out e>
-
- | ":=" /* call a := ... */
- (. e = ConvertToLocal(e);
- if (e is IdentifierExpr) {
- RecordCallLhs((IdentifierExpr)e, lhs, newVars);
- } else if (e is FieldSelectExpr) {
- SemErr(e.tok, "each LHS of call statement must be a variable, not a field");
- } else {
- SemErr(e.tok, "each LHS of call statement must be a variable");
- }
- .)
- CallStmtSubExpr<out e>
- ]
- ";"
-
- /* "e" has now been parsed as one of: IdentifierExpr, FunctionCallExpr, FieldSelectExpr.
- It denotes the RHS, so to be legal it must be a FunctionCallExpr. */
- (. if (e is FunctionCallExpr) {
- FunctionCallExpr fce = (FunctionCallExpr)e;
- s = new CallStmt(x, newVars, lhs, fce.Receiver, fce.Name, fce.Args); // this actually does an ownership transfer of fce.Args
- } else {
- SemErr("RHS of call statement must denote a method invocation");
- s = new CallStmt(x, newVars, lhs, dummyExpr, "dummyMethodName", new List<Expression/*!*/>());
- }
- .)
.
/*------------------------------------------------------------------------*/
ForeachStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x, boundVar;
+= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null);
+ IToken/*!*/ x, boundVar;
Type/*!*/ ty;
Expression/*!*/ collection;
Expression/*!*/ range;
List<PredicateStmt/*!*/> bodyPrefix = new List<PredicateStmt/*!*/>();
- AssignStmt bodyAssign = null;
+ Statement bodyAssign = null;
.)
- (. parseVarScope.PushMarker(); .)
"foreach" (. x = t;
range = new LiteralExpr(x, true);
ty = new InferredTypeProxy();
@@ -1075,16 +973,14 @@ ForeachStmt<out Statement/*!*/ s>
"(" Ident<out boundVar>
[ ":" Type<out ty> ]
"in" Expression<out collection>
- (. parseVarScope.Push(boundVar.val, boundVar.val); .)
[ "|" Expression<out range> ]
")"
"{"
{ AssertStmt<out s> (. if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); } .)
| AssumeStmt<out s> (. if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); } .)
- | UseStmt<out s> (. if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); } .)
}
- ( AssignStmt<out s, false> (. if (s is AssignStmt) { bodyAssign = (AssignStmt)s; } .)
- | HavocStmt<out s> (. if (s is AssignStmt) { bodyAssign = (AssignStmt)s; } .)
+ ( UpdateStmt<out s> (. bodyAssign = s; .)
+ | HavocStmt<out s> (. bodyAssign = s; .)
)
"}" (. if (bodyAssign != null) {
s = new ForeachStmt(x, new BoundVar(boundVar, boundVar.val, ty), collection, range, bodyPrefix, bodyAssign);
@@ -1092,7 +988,6 @@ ForeachStmt<out Statement/*!*/ s>
s = dummyStmt; // some error occurred in parsing the bodyAssign
}
.)
- (. parseVarScope.PopMarker(); .)
.
AssertStmt<out Statement/*!*/ s>
@@ -1107,12 +1002,6 @@ AssumeStmt<out Statement/*!*/ s>
Expression<out e> ";" (. s = new AssumeStmt(x, e); .)
.
-UseStmt<out Statement/*!*/ s>
-= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ e; .)
- "use" (. x = t; .)
- Expression<out e> ";" (. s = new UseStmt(x, e); .)
- .
-
PrintStmt<out Statement/*!*/ s>
= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Attributes.Argument/*!*/ arg;
List<Attributes.Argument/*!*/> args = new List<Attributes.Argument/*!*/>();
@@ -1173,12 +1062,72 @@ AndOp = "&&" | '\u2227'.
OrOp = "||" | '\u2228'.
/*------------------------------------------------------------------------*/
-RelationalExpression<out Expression/*!*/ e0>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op; .)
- Term<out e0>
- [ RelOp<out x, out op>
- Term<out e1> (. e0 = new BinaryExpr(x, op, e0, e1); .)
+RelationalExpression<out Expression/*!*/ e>
+= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null);
+ IToken x, firstOpTok = null; Expression e0, e1; BinaryExpr.Opcode op;
+ List<Expression> chain = null;
+ List<BinaryExpr.Opcode> ops = null;
+ int kind = 0; // 0 ("uncommitted") indicates chain of ==, possibly with one !=
+ // 1 ("ascending") indicates chain of ==, <, <=, possibly with one !=
+ // 2 ("descending") indicates chain of ==, >, >=, possibly with one !=
+ // 3 ("illegal") indicates illegal chain
+ bool hasSeenNeq = false;
+ .)
+ Term<out e0> (. e = e0; .)
+ [ RelOp<out x, out op> (. firstOpTok = x; .)
+ Term<out e1> (. e = new BinaryExpr(x, op, e0, e1); .)
+ { (. if (chain == null) {
+ chain = new List<Expression>();
+ ops = new List<BinaryExpr.Opcode>();
+ chain.Add(e0); ops.Add(op); chain.Add(e1);
+ switch (op) {
+ case BinaryExpr.Opcode.Eq:
+ kind = 0; break;
+ case BinaryExpr.Opcode.Neq:
+ kind = 0; hasSeenNeq = true; break;
+ case BinaryExpr.Opcode.Lt:
+ case BinaryExpr.Opcode.Le:
+ kind = 1; break;
+ case BinaryExpr.Opcode.Gt:
+ case BinaryExpr.Opcode.Ge:
+ kind = 2; break;
+ default:
+ kind = 3; break;
+ }
+ }
+ e0 = e1;
+ .)
+ RelOp<out x, out op> (. switch (op) {
+ case BinaryExpr.Opcode.Eq:
+ if (kind == 3) { SemErr(x, "chaining not allowed from the previous operator"); }
+ break;
+ case BinaryExpr.Opcode.Neq:
+ if (hasSeenNeq) { SemErr(x, "a chain cannot have more than one != operator"); }
+ hasSeenNeq = true; break;
+ case BinaryExpr.Opcode.Lt:
+ case BinaryExpr.Opcode.Le:
+ if (kind == 0) { kind = 1; }
+ else if (kind != 1) { SemErr(x, "this operator chain cannot continue with an ascending operator"); }
+ break;
+ case BinaryExpr.Opcode.Gt:
+ case BinaryExpr.Opcode.Ge:
+ if (kind == 0) { kind = 2; }
+ else if (kind != 2) { SemErr(x, "this operator chain cannot continue with a descending operator"); }
+ break;
+ default:
+ SemErr(x, "this operator cannot be part of a chain");
+ kind = 3; break;
+ }
+ .)
+ Term<out e1> (. ops.Add(op); chain.Add(e1);
+ e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, e0, e1));
+ .)
+ }
]
+ (. if (chain != null) {
+ e = new ChainingExpression(firstOpTok, chain, ops, e);
+ }
+ .)
.
RelOp<out IToken/*!*/ x, out BinaryExpr.Opcode op>
@@ -1238,33 +1187,47 @@ UnaryExpression<out Expression/*!*/ e>
UnaryExpression<out e> (. e = new BinaryExpr(x, BinaryExpr.Opcode.Sub, new LiteralExpr(x, 0), e); .)
| NegOp (. x = t; .)
UnaryExpression<out e> (. e = new UnaryExpr(x, UnaryExpr.Opcode.Not, e); .)
- | SelectExpression<out e>
+ | EndlessExpression<out e> /* these have no further suffix */
+ | DottedIdentifiersAndFunction<out e>
+ { Suffix<ref e> }
| ConstAtomExpression<out e>
+ { Suffix<ref e> }
+ )
+ .
+
+Lhs<out Expression e>
+= (. e = null; // to please the compiler
+ .)
+ ( DottedIdentifiersAndFunction<out e>
+ { Suffix<ref e> }
+ | ConstAtomExpression<out e>
+ Suffix<ref e>
+ { Suffix<ref e> }
)
.
NegOp = "!" | '\u00ac'.
-ConstAtomExpression<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x, dtName, id; BigInteger n; List<Expression/*!*/>/*!*/ elements;
- Expression e0, e1;
+/* A ConstAtomExpression is never an l-value. Also, a ConstAtomExpression is never followed by
+ * an open paren (but could very well have a suffix that starts with a period or a square bracket).
+ * (The "Also..." part may change if expressions in Dafny could yield functions.)
+ */
+ConstAtomExpression<out Expression/*!*/ e>
+= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null);
+ IToken/*!*/ x; BigInteger n; List<Expression/*!*/>/*!*/ elements;
e = dummyExpr;
.)
( "false" (. e = new LiteralExpr(t, false); .)
| "true" (. e = new LiteralExpr(t, true); .)
| "null" (. e = new LiteralExpr(t); .)
| Nat<out n> (. e = new LiteralExpr(t, n); .)
- | "#" (. x = t; .)
- Ident<out dtName>
- "."
- Ident<out id> (. elements = new List<Expression/*!*/>(); .)
- [ "("
- [ Expressions<elements> ]
- ")" ] (. e = new DatatypeValue(t, dtName.val, id.val, elements); .)
+ | "this" (. e = new ThisExpr(t); .)
| "fresh" (. x = t; .)
"(" Expression<out e> ")" (. e = new FreshExpr(x, e); .)
| "allocated" (. x = t; .)
"(" Expression<out e> ")" (. e = new AllocatedExpr(x, e); .)
+ | "old" (. x = t; .)
+ "(" Expression<out e> ")" (. e = new OldExpr(x, e); .)
| "|" (. x = t; .)
Expression<out e> (. e = new UnaryExpr(x, UnaryExpr.Opcode.SeqLength, e); .)
"|"
@@ -1274,7 +1237,18 @@ ConstAtomExpression<out Expression/*!*/ e>
| "[" (. x = t; elements = new List<Expression/*!*/>(); .)
[ Expressions<elements> ] (. e = new SeqDisplayExpr(x, elements); .)
"]"
- | "if" (. x = t; .)
+ | "(" (. x = t; .)
+ Expression<out e> (. e = new ParensExpression(x, e); .)
+ ")"
+ )
+ .
+
+EndlessExpression<out Expression e>
+= (. IToken/*!*/ x;
+ Expression e0, e1;
+ e = dummyExpr;
+ .)
+ ( "if" (. x = t; .)
Expression<out e>
"then" Expression<out e0>
"else" Expression<out e1> (. e = new ITEExpr(x, e, e0, e1); .)
@@ -1283,47 +1257,26 @@ ConstAtomExpression<out Expression/*!*/ e>
)
.
-/*------------------------------------------------------------------------*/
-/* returns one of:
- -- IdentifierExpr
- -- FunctionCallExpr
- -- FieldSelectExpr
-*/
-CallStmtSubExpr<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null); e = dummyExpr; .)
- ( IdentOrFuncExpression<out e>
- | ObjectExpression<out e>
- SelectOrCallSuffix<ref e>
- )
- { SelectOrCallSuffix<ref e> }
- .
-
-SelectExpression<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null); e = dummyExpr; .)
- ( IdentOrFuncExpression<out e>
- | ObjectExpression<out e>
- )
- { SelectOrCallSuffix<ref e> }
- .
+/*------------------------------------------------------------------------*/
-IdentOrFuncExpression<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ id; e = dummyExpr; List<Expression/*!*/>/*!*/ args; .)
- Ident<out id>
- [ "(" (. args = new List<Expression/*!*/>(); .)
+DottedIdentifiersAndFunction<out Expression e>
+= (. IToken id; IToken openParen = null;
+ List<Expression> args = null;
+ List<IToken> idents = new List<IToken>();
+ .)
+ Ident<out id> (. idents.Add(id); .)
+ { "."
+ Ident<out id> (. idents.Add(id); .)
+ }
+ [ "(" (. openParen = t; args = new List<Expression>(); .)
[ Expressions<args> ]
- ")" (. e = new FunctionCallExpr(id, id.val, new ImplicitThisExpr(id), args); .)
- ] (. if (e == dummyExpr) {
- if (parseVarScope.Find(id.val) != null) {
- e = new IdentifierExpr(id, id.val);
- } else {
- e = new FieldSelectExpr(id, new ImplicitThisExpr(id), id.val);
- }
- }
- .)
+ ")"
+ ]
+ (. e = new IdentifierSequence(idents, openParen, args); .)
.
-SelectOrCallSuffix<ref Expression/*!*/ e>
+Suffix<ref Expression/*!*/ e>
= (. Contract.Requires(e != null); Contract.Ensures(e!=null); IToken/*!*/ id, x; List<Expression/*!*/>/*!*/ args;
Expression e0 = null; Expression e1 = null; Expression/*!*/ ee; bool anyDots = false;
List<Expression> multipleIndices = null;
@@ -1379,22 +1332,6 @@ SelectOrCallSuffix<ref Expression/*!*/ e>
)
.
-/* ObjectExpression represents those expressions E that could possibly be used in E.f
- or E(...), except Ident. The expression returned is never an lvalue.
-*/
-ObjectExpression<out Expression/*!*/ e>
-= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; e = dummyExpr; .)
- ( "this" (. e = new ThisExpr(t); .)
- | "old" (. x = t; .)
- "("
- Expression<out e>
- ")" (. e = new OldExpr(x, e); .)
- | "("
- Expression<out e>
- ")"
- )
- .
-
/*------------------------------------------------------------------------*/
QuantifierGuts<out Expression/*!*/ q>
@@ -1410,10 +1347,9 @@ QuantifierGuts<out Expression/*!*/ q>
( Forall (. x = t; univ = true; .)
| Exists (. x = t; .)
)
- (. parseVarScope.PushMarker(); .)
- IdentTypeOptional<out bv> (. bvars.Add(bv); parseVarScope.Push(bv.Name, bv.Name); .)
+ IdentTypeOptional<out bv> (. bvars.Add(bv); .)
{ ","
- IdentTypeOptional<out bv> (. bvars.Add(bv); parseVarScope.Push(bv.Name, bv.Name); .)
+ IdentTypeOptional<out bv> (. bvars.Add(bv); .)
}
{ AttributeOrTrigger<ref attrs, ref trigs> }
[ "|"
@@ -1426,7 +1362,6 @@ QuantifierGuts<out Expression/*!*/ q>
} else {
q = new ExistsExpr(x, bvars, range, body, trigs, attrs);
}
- parseVarScope.PopMarker();
.)
.
@@ -1443,10 +1378,9 @@ ComprehensionExpr<out Expression/*!*/ q>
Expression body = null;
.)
"set" (. x = t; .)
- (. parseVarScope.PushMarker(); .)
- IdentTypeOptional<out bv> (. bvars.Add(bv); parseVarScope.Push(bv.Name, bv.Name); .)
+ IdentTypeOptional<out bv> (. bvars.Add(bv); .)
{ ","
- IdentTypeOptional<out bv> (. bvars.Add(bv); parseVarScope.Push(bv.Name, bv.Name); .)
+ IdentTypeOptional<out bv> (. bvars.Add(bv); .)
}
"|" Expression<out range>
[
@@ -1455,7 +1389,6 @@ ComprehensionExpr<out Expression/*!*/ q>
]
(. if (body == null && bvars.Count != 1) { SemErr(t, "a set comprehension with more than one bound variable must have a term expression"); }
q = new SetComprehension(x, bvars, range, body);
- parseVarScope.PopMarker();
.)
.
diff --git a/Dafny/DafnyAst.cs b/Dafny/DafnyAst.cs
index f0a58293..b650b655 100644
--- a/Dafny/DafnyAst.cs
+++ b/Dafny/DafnyAst.cs
@@ -707,6 +707,7 @@ namespace Microsoft.Dafny {
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(cce.NonNullElements(Ctors));
+ Contract.Invariant(1 <= Ctors.Count);
}
public DatatypeCtor DefaultCtor; // set during resolution
@@ -719,34 +720,27 @@ namespace Microsoft.Dafny {
Contract.Requires(module != null);
Contract.Requires(cce.NonNullElements(typeArgs));
Contract.Requires(cce.NonNullElements(ctors));
+ Contract.Invariant(1 <= ctors.Count);
Ctors = ctors;
-
}
}
public class DatatypeCtor : Declaration, TypeParameter.ParentType {
- public readonly List<TypeParameter/*!*/>/*!*/ TypeArgs;
public readonly List<Formal/*!*/>/*!*/ Formals;
[ContractInvariantMethod]
void ObjectInvariant() {
- Contract.Invariant(cce.NonNullElements(TypeArgs));
Contract.Invariant(cce.NonNullElements(Formals));
}
// TODO: One could imagine having a precondition on datatype constructors
public DatatypeDecl EnclosingDatatype; // filled in during resolution
- public DatatypeCtor(IToken/*!*/ tok, string/*!*/ name, [Captured] List<TypeParameter/*!*/>/*!*/ typeArgs,
- [Captured] List<Formal/*!*/>/*!*/ formals,
- Attributes attributes)
+ public DatatypeCtor(IToken/*!*/ tok, string/*!*/ name, [Captured] List<Formal/*!*/>/*!*/ formals, Attributes attributes)
: base(tok, name, attributes) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
- Contract.Requires(cce.NonNullElements(typeArgs));
Contract.Requires(cce.NonNullElements(formals));
- this.TypeArgs = typeArgs;
this.Formals = formals;
-
}
public string FullName {
@@ -760,12 +754,14 @@ namespace Microsoft.Dafny {
}
public abstract class MemberDecl : Declaration {
+ public readonly bool IsStatic;
public ClassDecl EnclosingClass; // filled in during resolution
- public MemberDecl(IToken tok, string name, Attributes attributes)
+ public MemberDecl(IToken tok, string name, bool isStatic, Attributes attributes)
: base(tok, name, attributes) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
+ IsStatic = isStatic;
}
/// <summary>
/// Returns className+"."+memberName. Available only after resolution.
@@ -797,7 +793,7 @@ namespace Microsoft.Dafny {
}
public Field(IToken tok, string name, bool isGhost, bool isMutable, Type type, Attributes attributes)
- : base(tok, name, attributes) {
+ : base(tok, name, false, attributes) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(type != null);
@@ -832,13 +828,10 @@ namespace Microsoft.Dafny {
public CouplingInvariant(List<IToken/*!*/>/*!*/ toks, Expression/*!*/ expr, Attributes attributes)
- : base(toks[0], "_coupling_invariant" + getNames(toks), attributes) {
+ : base(toks[0], "_coupling_invariant" + getNames(toks), false, attributes) {
Contract.Requires(toks.Count > 0);
Expr = expr;
Toks = toks;
-
-
-
}
private static string getNames(List<IToken> toks) {
@@ -909,9 +902,6 @@ namespace Microsoft.Dafny {
throw new NotImplementedException();
}
}
-
-
-
}
public abstract class NonglobalVariable : IVariable {
@@ -1018,7 +1008,6 @@ namespace Microsoft.Dafny {
}
public class Function : MemberDecl, TypeParameter.ParentType {
- public readonly bool IsStatic;
public readonly bool IsGhost; // functions are "ghost" by default; a non-ghost function is called a "function method"
public readonly bool IsUnlimited;
public bool IsRecursive; // filled in during resolution
@@ -1045,7 +1034,7 @@ namespace Microsoft.Dafny {
public Function(IToken tok, string name, bool isStatic, bool isGhost, bool isUnlimited, [Captured] List<TypeParameter/*!*/>/*!*/ typeArgs,
[Captured] List<Formal/*!*/>/*!*/ formals, Type/*!*/ resultType, List<Expression/*!*/>/*!*/ req, List<FrameExpression/*!*/>/*!*/ reads,
List<Expression/*!*/>/*!*/ ens, List<Expression/*!*/>/*!*/ decreases, Expression body, Attributes attributes)
- : base(tok, name, attributes) {
+ : base(tok, name, isStatic, attributes) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
@@ -1056,7 +1045,6 @@ namespace Microsoft.Dafny {
Contract.Requires(cce.NonNullElements(reads));
Contract.Requires(cce.NonNullElements(ens));
Contract.Requires(cce.NonNullElements(decreases));
- this.IsStatic = isStatic;
this.IsGhost = isGhost;
this.IsUnlimited = isUnlimited;
this.TypeArgs = typeArgs;
@@ -1072,7 +1060,6 @@ namespace Microsoft.Dafny {
}
public class Method : MemberDecl, TypeParameter.ParentType {
- public readonly bool IsStatic;
public readonly bool IsGhost;
public readonly List<TypeParameter/*!*/>/*!*/ TypeArgs;
public readonly List<Formal/*!*/>/*!*/ Ins;
@@ -1103,7 +1090,7 @@ namespace Microsoft.Dafny {
[Captured] List<Expression/*!*/>/*!*/ decreases,
[Captured] BlockStmt body,
Attributes attributes)
- : base(tok, name, attributes) {
+ : base(tok, name, isStatic, attributes) {
Contract.Requires(tok != null);
Contract.Requires(name != null);
Contract.Requires(cce.NonNullElements(typeArgs));
@@ -1113,7 +1100,6 @@ namespace Microsoft.Dafny {
Contract.Requires(cce.NonNullElements(mod));
Contract.Requires(cce.NonNullElements(ens));
Contract.Requires(cce.NonNullElements(decreases));
- this.IsStatic = isStatic;
this.IsGhost = isGhost;
this.TypeArgs = typeArgs;
this.Ins = ins;
@@ -1156,6 +1142,8 @@ namespace Microsoft.Dafny {
public abstract class Statement {
public readonly IToken Tok;
+ public LabelNode Labels; // mutable during resolution
+
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(Tok != null);
@@ -1168,7 +1156,25 @@ namespace Microsoft.Dafny {
}
}
- public abstract class PredicateStmt : Statement {
+ public class LabelNode
+ {
+ public readonly IToken Tok;
+ public readonly string Label;
+ public readonly int UniqueId;
+ public readonly LabelNode Next;
+ static int nodes = 0;
+
+ public LabelNode(IToken tok, string label, LabelNode next) {
+ Contract.Requires(tok != null);
+ Tok = tok;
+ Label = label;
+ Next = next;
+ UniqueId = nodes++;
+ }
+ }
+
+ public abstract class PredicateStmt : Statement
+ {
[Peer]
public readonly Expression Expr;
[ContractInvariantMethod]
@@ -1209,49 +1215,6 @@ namespace Microsoft.Dafny {
}
}
- public class UseStmt : PredicateStmt {
- [Captured]
- public UseStmt(IToken/*!*/ tok, Expression/*!*/ expr)
- : base(tok, expr) {
- Contract.Requires(tok != null);
- Contract.Requires(expr != null);
- Contract.Ensures(cce.Owner.Same(this, expr));
-
- }
- [Peer]
- private FunctionCallExpr fce;
- /// <summary>
- /// This method assumes the statement has been successfully resolved.
- /// </summary>
- //[Pure(false)]
- public FunctionCallExpr FunctionCallExpr {
- get {
- Contract.Ensures(Contract.Result<FunctionCallExpr>() != null);
-
- if (fce == null) {
- Expression expr = Expr;
- while (true) {
- cce.LoopInvariant(cce.Owner.Same(this, expr));
-
- if (expr is OldExpr) {
- expr = ((OldExpr)expr).E;
- } else {
- break;
- }
- }
- Contract.Assume(expr is FunctionCallExpr);
- fce = (FunctionCallExpr)expr;
- }
- return fce;
- }
- }
- public bool EvalInOld {
- get {
- return Expr is OldExpr;
- }
- }
- }
-
public class PrintStmt : Statement {
public readonly List<Attributes.Argument/*!*/>/*!*/ Args;
[ContractInvariantMethod]
@@ -1268,31 +1231,25 @@ namespace Microsoft.Dafny {
}
}
- public class LabelStmt : Statement {
- public readonly string Label;
+ public class BreakStmt : Statement {
+ public readonly string TargetLabel;
+ public readonly int BreakCount;
+ public Statement TargetStmt; // filled in during resolution
[ContractInvariantMethod]
void ObjectInvariant() {
- Contract.Invariant(Label != null);
+ Contract.Invariant(TargetLabel == null || 1 <= BreakCount);
}
- public LabelStmt(IToken/*!*/ tok, string/*!*/ label)
+ public BreakStmt(IToken tok, string targetLabel)
: base(tok) {
Contract.Requires(tok != null);
- Contract.Requires(label != null);
- this.Label = label;
-
+ this.TargetLabel = targetLabel;
}
- }
-
- public class BreakStmt : Statement {
- public readonly string TargetLabel;
- public Statement TargetStmt; // filled in during resolution
-
- public BreakStmt(IToken tok, string targetLabel)
+ public BreakStmt(IToken tok, int breakCount)
: base(tok) {
Contract.Requires(tok != null);
- this.TargetLabel = targetLabel;
-
+ Contract.Requires(1 <= breakCount);
+ this.BreakCount = breakCount;
}
}
@@ -1300,7 +1257,6 @@ namespace Microsoft.Dafny {
public ReturnStmt(IToken tok)
: base(tok) {
Contract.Requires(tok != null);
-
}
}
@@ -1311,7 +1267,9 @@ namespace Microsoft.Dafny {
}
public abstract class DeterminedAssignmentRhs : AssignmentRhs {
- internal DeterminedAssignmentRhs() {
+ public readonly IToken Tok;
+ internal DeterminedAssignmentRhs(IToken tok) {
+ Tok = tok;
}
}
@@ -1322,7 +1280,9 @@ namespace Microsoft.Dafny {
Contract.Invariant(Expr != null);
}
- public ExprRhs(Expression expr) {
+ public ExprRhs(Expression expr)
+ : base(expr.tok)
+ {
Contract.Requires(expr != null);
Expr = expr;
}
@@ -1341,16 +1301,22 @@ namespace Microsoft.Dafny {
Contract.Invariant(ArrayDimensions == null || InitCall == null);
}
- public TypeRhs(Type type) {
+ public TypeRhs(IToken tok, Type type)
+ : base(tok)
+ {
Contract.Requires(type != null);
EType = type;
}
- public TypeRhs(Type type, CallStmt initCall) {
+ public TypeRhs(IToken tok, Type type, CallStmt initCall)
+ : base(tok)
+ {
Contract.Requires(type != null);
EType = type;
InitCall = initCall;
}
- public TypeRhs(Type type, List<Expression> arrayDimensions) {
+ public TypeRhs(IToken tok, Type type, List<Expression> arrayDimensions)
+ : base(tok)
+ {
Contract.Requires(type != null);
Contract.Requires(arrayDimensions != null && 1 <= arrayDimensions.Count);
EType = type;
@@ -1370,10 +1336,96 @@ namespace Microsoft.Dafny {
}
}
+ public class CallRhs : DeterminedAssignmentRhs
+ {
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(Receiver != null);
+ Contract.Invariant(MethodName != null);
+ Contract.Invariant(cce.NonNullElements(Args));
+ }
+
+ public readonly Expression/*!*/ Receiver;
+ public readonly string/*!*/ MethodName;
+ public readonly List<Expression/*!*/>/*!*/ Args;
+ public Method Method; // filled in by resolution
+
+ public CallRhs(IToken tok, Expression/*!*/ receiver, string/*!*/ methodName, List<Expression/*!*/>/*!*/ args)
+ : base(tok)
+ {
+ Contract.Requires(tok != null);
+ Contract.Requires(receiver != null);
+ Contract.Requires(methodName != null);
+ Contract.Requires(cce.NonNullElements(args));
+
+ this.Receiver = receiver;
+ this.MethodName = methodName;
+ this.Args = args;
+ }
+ public override bool CanAffectPreviouslyKnownExpressions {
+ get {
+ foreach (var mod in Method.Mod) {
+ if (!(mod.E is ThisExpr)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ }
+
public class HavocRhs : AssignmentRhs {
public override bool CanAffectPreviouslyKnownExpressions { get { return false; } }
}
+ public abstract class ConcreteSyntaxStatement : Statement
+ {
+ public List<Statement> ResolvedStatements = new List<Statement>(); // contents filled in during resolution
+ public ConcreteSyntaxStatement(IToken tok)
+ : base(tok) {
+ }
+ }
+
+ public class VarDeclStmt : ConcreteSyntaxStatement
+ {
+ public readonly List<VarDecl> Lhss;
+ public readonly UpdateStmt Update;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(Lhss));
+ }
+
+ public VarDeclStmt(IToken tok, List<VarDecl> lhss, UpdateStmt update)
+ : base(tok)
+ {
+ Contract.Requires(lhss != null);
+
+ Lhss = lhss;
+ Update = update;
+ }
+ }
+
+ public class UpdateStmt : ConcreteSyntaxStatement
+ {
+ public readonly List<Expression> Lhss;
+ public readonly List<DeterminedAssignmentRhs> Rhss;
+ [ContractInvariantMethod]
+ void ObjectInvariant() {
+ Contract.Invariant(cce.NonNullElements(Lhss));
+ Contract.Invariant(cce.NonNullElements(Rhss));
+ }
+ public UpdateStmt(IToken tok, List<Expression> lhss, List<DeterminedAssignmentRhs> rhss)
+ : base(tok)
+ {
+ Contract.Requires(tok != null);
+ Contract.Requires(cce.NonNullElements(lhss));
+ Contract.Requires(cce.NonNullElements(rhss));
+ Contract.Requires(lhss.Count != 0 || rhss.Count == 1);
+ Lhss = lhss;
+ Rhss = rhss;
+ }
+ }
+
public class AssignStmt : Statement {
public readonly Expression/*!*/ Lhs;
public readonly AssignmentRhs/*!*/ Rhs;
@@ -1383,6 +1435,15 @@ namespace Microsoft.Dafny {
Contract.Invariant(Rhs != null);
}
+ public AssignStmt(IToken tok, Expression lhs, DeterminedAssignmentRhs rhs)
+ : base(tok) {
+ Contract.Requires(tok != null);
+ Contract.Requires(lhs != null);
+ Contract.Requires(rhs != null);
+ this.Lhs = lhs;
+ this.Rhs = rhs;
+ }
+#if OLD_STUFF
public AssignStmt(IToken tok, Expression lhs, Expression rhs)
: base(tok) { // ordinary assignment statement
Contract.Requires(tok != null);
@@ -1408,6 +1469,7 @@ namespace Microsoft.Dafny {
this.Lhs = lhs;
this.Rhs = new TypeRhs(type, arrayDimensions);
}
+#endif
public AssignStmt(IToken tok, Expression lhs)
: base(tok) { // havoc
Contract.Requires(tok != null);
@@ -1422,7 +1484,18 @@ namespace Microsoft.Dafny {
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(name != null);
- Contract.Invariant(OptionalType != null || Rhs != null);
+ Contract.Invariant(OptionalType != null);
+ }
+
+ public VarDecl(IToken tok, string name, Type type, bool isGhost)
+ : base(tok) {
+ Contract.Requires(tok != null);
+ Contract.Requires(name != null);
+ Contract.Requires(type != null); // can be a proxy, though
+
+ this.name = name;
+ this.OptionalType = type;
+ this.IsGhost = isGhost;
}
public string/*!*/ Name {
@@ -1469,32 +1542,6 @@ namespace Microsoft.Dafny {
return base.IsGhost;
}
}
-
- public readonly DeterminedAssignmentRhs Rhs;
-
- public VarDecl(IToken tok, string name, Type type, bool isGhost, DeterminedAssignmentRhs rhs)
- : base(tok) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Contract.Requires(type != null || rhs != null);
-
- this.name = name;
- this.OptionalType = type;
- this.IsGhost = isGhost;
- this.Rhs = rhs;
-
- }
- }
-
- public class AutoVarDecl : VarDecl {
- public readonly int Index;
- public AutoVarDecl(IToken tok, string name, Type type, int index)
- : base(tok, name, type, false, null) {
- Contract.Requires(tok != null);
- Contract.Requires(name != null);
- Index = index;
-
- }
/// <summary>
/// This method retrospectively makes the VarDecl a ghost. It is to be used only during resolution.
/// </summary>
@@ -1508,34 +1555,29 @@ namespace Microsoft.Dafny {
void ObjectInvariant() {
Contract.Invariant(Receiver != null);
Contract.Invariant(MethodName != null);
- Contract.Invariant(cce.NonNullElements(NewVars));
Contract.Invariant(cce.NonNullElements(Lhs));
Contract.Invariant(cce.NonNullElements(Args));
}
- public readonly List<AutoVarDecl/*!*/>/*!*/ NewVars;
public readonly List<IdentifierExpr/*!*/>/*!*/ Lhs;
public readonly Expression/*!*/ Receiver;
public readonly string/*!*/ MethodName;
public readonly List<Expression/*!*/>/*!*/ Args;
public Method Method; // filled in by resolution
- public CallStmt(IToken tok, List<AutoVarDecl/*!*/>/*!*/ newVars, List<IdentifierExpr/*!*/>/*!*/ lhs, Expression/*!*/ receiver,
+ public CallStmt(IToken tok, List<IdentifierExpr/*!*/>/*!*/ lhs, Expression/*!*/ receiver,
string/*!*/ methodName, List<Expression/*!*/>/*!*/ args)
: base(tok) {
Contract.Requires(tok != null);
- Contract.Requires(cce.NonNullElements(newVars));
Contract.Requires(cce.NonNullElements(lhs));
Contract.Requires(receiver != null);
Contract.Requires(methodName != null);
Contract.Requires(cce.NonNullElements(args));
- this.NewVars = newVars;
this.Lhs = lhs;
this.Receiver = receiver;
this.MethodName = methodName;
this.Args = args;
-
}
}
@@ -1673,32 +1715,31 @@ namespace Microsoft.Dafny {
public readonly Expression/*!*/ Collection;
public readonly Expression/*!*/ Range;
public readonly List<PredicateStmt/*!*/>/*!*/ BodyPrefix;
- public readonly AssignStmt/*!*/ BodyAssign;
+ public readonly Statement GivenBody; // used only until resolution; afterwards, use BodyAssign
+ public AssignStmt/*!*/ BodyAssign; // filled in during resolution
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(BoundVar != null);
Contract.Invariant(Collection != null);
Contract.Invariant(Range != null);
Contract.Invariant(cce.NonNullElements(BodyPrefix));
- Contract.Invariant(BodyAssign != null);
+ Contract.Invariant(GivenBody != null);
}
-
public ForeachStmt(IToken tok, BoundVar boundVar, Expression collection, Expression range,
- List<PredicateStmt/*!*/>/*!*/ bodyPrefix, AssignStmt bodyAssign)
+ List<PredicateStmt/*!*/>/*!*/ bodyPrefix, Statement givenBody)
: base(tok) {
Contract.Requires(tok != null);
Contract.Requires(boundVar != null);
Contract.Requires(collection != null);
Contract.Requires(range != null);
Contract.Requires(cce.NonNullElements(bodyPrefix));
- Contract.Requires(bodyAssign != null);
+ Contract.Requires(givenBody != null);
this.BoundVar = boundVar;
this.Collection = collection;
this.Range = range;
this.BodyPrefix = bodyPrefix;
- this.BodyAssign = bodyAssign;
-
+ this.GivenBody = givenBody;
}
}
@@ -1795,6 +1836,19 @@ namespace Microsoft.Dafny {
Contract.Invariant(tok != null);
}
+ public Expression Resolved {
+ get {
+ Contract.Requires(type != null); // should be called only on resolved expressions; this approximates that precondition
+ Expression r = this;
+ while (true) {
+ var rr = r as ConcreteSyntaxExpression;
+ if (rr == null) { break; }
+ r = rr.ResolvedExpression;
+ }
+ return r;
+ }
+ }
+
protected Type type;
public Type Type { // filled in during resolution
[Verify(false)] // TODO: how do we allow Type.get to modify type and still be [Pure]?
@@ -1836,11 +1890,33 @@ namespace Microsoft.Dafny {
this.tok = tok;
}
+ /// <summary>
+ /// Returns the non-null subexpressions of the Expression.
+ /// </summary>
public virtual IEnumerable<Expression> SubExpressions {
get { yield break; }
}
}
+ /// <summary>
+ /// Instances of this class are introduced during resolution to indicate that a static method or function has
+ /// been invoked without specifying a receiver (that is, by just giving the name of the enclosing class).
+ /// </summary>
+ public class StaticReceiverExpr : LiteralExpr
+ {
+ public StaticReceiverExpr(IToken tok, ClassDecl cl)
+ : base(tok) // constructs a LiteralExpr representing the 'null' literal
+ {
+ Contract.Requires(tok != null);
+ Contract.Requires(cl != null);
+ var typeArgs = new List<Type>();
+ foreach (var ta in cl.TypeArgs) {
+ typeArgs.Add(new InferredTypeProxy());
+ }
+ Type = new UserDefinedType(tok, cl.Name, cl, typeArgs);
+ }
+ }
+
public class LiteralExpr : Expression {
public readonly object Value;
@@ -1899,7 +1975,6 @@ namespace Microsoft.Dafny {
Contract.Invariant(cce.NonNullElements(InferredTypeArgs));
}
-
public DatatypeValue(IToken tok, string datatypeName, string memberName, [Captured] List<Expression/*!*/>/*!*/ arguments)
: base(tok) {
Contract.Requires(cce.NonNullElements(arguments));
@@ -1948,6 +2023,18 @@ namespace Microsoft.Dafny {
}
}
+ /// <summary>
+ /// If an "AutoGhostIdentifierExpr" is used as the out-parameter of a ghost method or
+ /// a method with a ghost parameter, resolution will change the .Var's .IsGhost to true
+ /// automatically. This class is intended to be used only as a communicate between the
+ /// parser and parts of the resolver.
+ /// </summary>
+ public class AutoGhostIdentifierExpr : IdentifierExpr
+ {
+ public AutoGhostIdentifierExpr(IToken tok, string name)
+ : base(tok, name) { }
+ }
+
public abstract class DisplayExpression : Expression {
public readonly List<Expression/*!*/>/*!*/ Elements;
[ContractInvariantMethod]
@@ -2047,7 +2134,7 @@ namespace Microsoft.Dafny {
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(Array != null);
- Contract.Invariant(Indices != null && cce.NonNullElements(Indices));
+ Contract.Invariant(cce.NonNullElements(Indices));
Contract.Invariant(1 <= Indices.Count);
}
@@ -2055,7 +2142,7 @@ namespace Microsoft.Dafny {
: base(tok) {
Contract.Requires(tok != null);
Contract.Requires(array != null);
- Contract.Requires(indices == null && cce.NonNullElements(indices) && 1 <= indices.Count);
+ Contract.Requires(cce.NonNullElements(indices) && 1 <= indices.Count);
Array = array;
Indices = indices;
@@ -2414,6 +2501,8 @@ namespace Microsoft.Dafny {
public List<BoundedPool> Bounds; // initialized and filled in by resolver
// invariant Bounds == null || Bounds.Count == BoundVars.Count;
+ public List<BoundVar> MissingBounds; // filled in during resolution; remains "null" if bounds can be found
+ // invariant Bounds == null || MissingBounds == null;
public ComprehensionExpr(IToken/*!*/ tok, List<BoundVar/*!*/>/*!*/ bvars, Expression range, Expression/*!*/ term, Attributes attrs)
: base(tok) {
@@ -2707,7 +2796,6 @@ namespace Microsoft.Dafny {
public readonly string FieldName;
public Field Field; // filled in during resolution (but is null if FieldName is)
-
public FrameExpression(Expression e, string fieldName) {
Contract.Requires(e != null);
Contract.Requires(!(e is WildcardExpr) || fieldName == null);
@@ -2716,4 +2804,68 @@ namespace Microsoft.Dafny {
FieldName = fieldName;
}
}
-} \ No newline at end of file
+
+ /// <summary>
+ /// This class represents a piece of concrete syntax in the parse tree. During resolution,
+ /// it gets "replaced" by the expression in "ResolvedExpression".
+ /// </summary>
+ public abstract class ConcreteSyntaxExpression : Expression
+ {
+ public Expression ResolvedExpression; // filled in during resolution; after resolution, manipulation of "this" should proceed as with manipulating "this.ResolvedExpression"
+ public ConcreteSyntaxExpression(IToken tok)
+ : base(tok) {
+ }
+ public override IEnumerable<Expression> SubExpressions {
+ get {
+ if (ResolvedExpression != null) {
+ yield return ResolvedExpression;
+ }
+ }
+ }
+ }
+
+ public class ParensExpression : ConcreteSyntaxExpression
+ {
+ public readonly Expression E;
+ public ParensExpression(IToken tok, Expression e)
+ : base(tok) {
+ E = e;
+ }
+ }
+
+ public class ChainingExpression : ConcreteSyntaxExpression
+ {
+ public readonly List<Expression> Operands;
+ public readonly List<BinaryExpr.Opcode> Operators;
+ public readonly Expression E;
+ public ChainingExpression(IToken tok, List<Expression> operands, List<BinaryExpr.Opcode> operators, Expression desugaring)
+ : base(tok) {
+ Contract.Requires(tok != null);
+ Contract.Requires(operands != null);
+ Contract.Requires(operators != null);
+ Contract.Requires(desugaring != null);
+ Contract.Requires(operators.Count == operators.Count + 1);
+
+ Operands = operands;
+ Operators = operators;
+ E = desugaring;
+ }
+ }
+
+ public class IdentifierSequence : ConcreteSyntaxExpression
+ {
+ public readonly List<IToken> Tokens;
+ public readonly IToken OpenParen;
+ public readonly List<Expression> Arguments;
+ public IdentifierSequence(List<IToken> tokens, IToken openParen, List<Expression> args)
+ : base(tokens[0]) {
+ Contract.Requires(tokens != null && 1 <= tokens.Count);
+ /* "args" is null to indicate the absence of a parenthesized suffix */
+ Contract.Requires(args == null || openParen != null);
+
+ Tokens = tokens;
+ OpenParen = openParen;
+ Arguments = args;
+ }
+ }
+}
diff --git a/Dafny/Parser.cs b/Dafny/Parser.cs
index aa02c796..840344bd 100644
--- a/Dafny/Parser.cs
+++ b/Dafny/Parser.cs
@@ -20,7 +20,7 @@ public class Parser {
public const int _digits = 2;
public const int _arrayToken = 3;
public const int _string = 4;
- public const int maxT = 107;
+ public const int maxT = 104;
const bool T = true;
const bool x = false;
@@ -41,7 +41,6 @@ static Expression/*!*/ dummyExpr = new LiteralExpr(Token.NoToken);
static FrameExpression/*!*/ dummyFrameExpr = new FrameExpression(dummyExpr, null);
static Statement/*!*/ dummyStmt = new ReturnStmt(Token.NoToken);
static Attributes.Argument/*!*/ dummyAttrArg = new Attributes.Argument("dummyAttrArg");
-static Scope<string>/*!*/ parseVarScope = new Scope<string>();
static int anonymousIds = 0;
struct MemberModifiers {
@@ -51,22 +50,6 @@ struct MemberModifiers {
}
// helper routine for parsing call statements
-private static void RecordCallLhs(IdentifierExpr/*!*/ e,
- List<IdentifierExpr/*!*/>/*!*/ lhs,
- List<AutoVarDecl/*!*/>/*!*/ newVars) {
- Contract.Requires(e != null);
- Contract.Requires(cce.NonNullElements(lhs));
- Contract.Requires(cce.NonNullElements(newVars));
- int index = lhs.Count;
- lhs.Add(e);
- if (parseVarScope.Find(e.Name) == null) {
- AutoVarDecl d = new AutoVarDecl(e.tok, e.Name, new InferredTypeProxy(), index);
- newVars.Add(d);
- parseVarScope.Push(e.Name, e.Name);
- }
-}
-
-// helper routine for parsing call statements
private static Expression/*!*/ ConvertToLocal(Expression/*!*/ e)
{
Contract.Requires(e != null);
@@ -362,24 +345,14 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
if (la.kind == 23) {
GenericParameters(typeArgs);
}
- if (la.kind == 7) {
- Get();
- bodyStart = t;
- while (la.kind == 1 || la.kind == 7) {
- DatatypeMemberDecl(ctors);
- Expect(15);
- }
- Expect(8);
- } else if (la.kind == 16) {
+ Expect(15);
+ bodyStart = t;
+ DatatypeMemberDecl(ctors);
+ while (la.kind == 16) {
Get();
- bodyStart = t;
DatatypeMemberDecl(ctors);
- while (la.kind == 17) {
- Get();
- DatatypeMemberDecl(ctors);
- }
- Expect(15);
- } else SynErr(108);
+ }
+ Expect(17);
dt = new DatatypeDecl(id, id.val, module, typeArgs, ctors, attrs);
dt.BodyStartTok = bodyStart;
dt.BodyEndTok = t;
@@ -414,7 +387,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
mm.Add(m);
} else if (la.kind == 20) {
CouplingInvDecl(mmod, mm);
- } else SynErr(109);
+ } else SynErr(105);
}
void GenericParameters(List<TypeParameter/*!*/>/*!*/ typeArgs) {
@@ -450,7 +423,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
IdentType(out id, out ty);
mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs));
}
- Expect(15);
+ Expect(17);
}
void FunctionDecl(MemberModifiers mmod, out Function/*!*/ f) {
@@ -483,11 +456,10 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
if (la.kind == 23) {
GenericParameters(typeArgs);
}
- parseVarScope.PushMarker();
- Formals(true, false, formals);
+ Formals(true, isFunctionMethod, formals);
Expect(22);
Type(out returnType);
- if (la.kind == 15) {
+ if (la.kind == 17) {
Get();
while (StartOf(3)) {
FunctionSpec(reqs, reads, ens, decreases);
@@ -498,8 +470,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
}
FunctionBody(out bb, out bodyStart, out bodyEnd);
body = bb;
- } else SynErr(110);
- parseVarScope.PopMarker();
+ } else SynErr(106);
f = new Function(id, id.val, mmod.IsStatic, !isFunctionMethod, mmod.IsUnlimited, typeArgs, formals, returnType, reqs, reads, ens, decreases, body, attrs);
f.BodyStartTok = bodyStart;
f.BodyEndTok = bodyEnd;
@@ -527,7 +498,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
} else if (la.kind == 10) {
Get();
isRefinement = true;
- } else SynErr(111);
+ } else SynErr(107);
if (mmod.IsUnlimited) { SemErr(t, "methods cannot be declared 'unlimited'"); }
while (la.kind == 7) {
@@ -537,13 +508,12 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
if (la.kind == 23) {
GenericParameters(typeArgs);
}
- parseVarScope.PushMarker();
- Formals(true, true, ins);
+ Formals(true, !mmod.IsGhost, ins);
if (la.kind == 26) {
Get();
Formals(false, true, outs);
}
- if (la.kind == 15) {
+ if (la.kind == 17) {
Get();
while (StartOf(5)) {
MethodSpec(req, mod, ens, dec);
@@ -554,10 +524,9 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
}
BlockStmt(out bb, out bodyStart, out bodyEnd);
body = (BlockStmt)bb;
- } else SynErr(112);
- parseVarScope.PopMarker();
+ } else SynErr(108);
if (isRefinement)
- m = new MethodRefinement(id, id.val, mmod.IsStatic, mmod.IsGhost, typeArgs, ins, outs, req, mod, ens, dec, body, attrs);
+ m = new MethodRefinement(id, id.val, mmod.IsStatic, mmod.IsGhost, typeArgs, ins, outs, req, mod, ens, dec, body, attrs);
else
m = new Method(id, id.val, mmod.IsStatic, mmod.IsGhost, typeArgs, ins, outs, req, mod, ens, dec, body, attrs);
m.BodyStartTok = bodyStart;
@@ -571,7 +540,6 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
List<IToken/*!*/> ids = new List<IToken/*!*/>();;
IToken/*!*/ id;
Expression/*!*/ e;
- parseVarScope.PushMarker();
Expect(20);
if (mmod.IsUnlimited) { SemErr(t, "coupling invariants cannot be declared 'unlimited'"); }
@@ -582,41 +550,32 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
Attribute(ref attrs);
}
Ident(out id);
- ids.Add(id); parseVarScope.Push(id.val, id.val);
+ ids.Add(id);
while (la.kind == 19) {
Get();
Ident(out id);
- ids.Add(id); parseVarScope.Push(id.val, id.val);
+ ids.Add(id);
}
Expect(21);
Expression(out e);
- Expect(15);
- mm.Add(new CouplingInvariant(ids, e, attrs));
- parseVarScope.PopMarker();
-
+ Expect(17);
+ mm.Add(new CouplingInvariant(ids, e, attrs));
}
void DatatypeMemberDecl(List<DatatypeCtor/*!*/>/*!*/ ctors) {
Contract.Requires(cce.NonNullElements(ctors));
Attributes attrs = null;
IToken/*!*/ id;
- List<TypeParameter/*!*/> typeArgs = new List<TypeParameter/*!*/>();
List<Formal/*!*/> formals = new List<Formal/*!*/>();
while (la.kind == 7) {
Attribute(ref attrs);
}
Ident(out id);
- if (la.kind == 23) {
- GenericParameters(typeArgs);
- }
- parseVarScope.PushMarker();
if (la.kind == 32) {
FormalsOptionalIds(formals);
}
- parseVarScope.PopMarker();
- ctors.Add(new DatatypeCtor(id, id.val, typeArgs, formals, attrs));
-
+ ctors.Add(new DatatypeCtor(id, id.val, formals, attrs));
}
void FormalsOptionalIds(List<Formal/*!*/>/*!*/ formals) {
@@ -624,11 +583,11 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
Expect(32);
if (StartOf(7)) {
TypeIdentOptional(out id, out name, out ty, out isGhost);
- formals.Add(new Formal(id, name, ty, true, isGhost)); parseVarScope.Push(name, name);
+ formals.Add(new Formal(id, name, ty, true, isGhost));
while (la.kind == 19) {
Get();
TypeIdentOptional(out id, out name, out ty, out isGhost);
- formals.Add(new Formal(id, name, ty, true, isGhost)); parseVarScope.Push(name, name);
+ formals.Add(new Formal(id, name, ty, true, isGhost));
}
}
Expect(33);
@@ -661,6 +620,18 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
TypeAndToken(out tok, out ty);
}
+ void LocalIdentTypeOptional(out VarDecl/*!*/ var, bool isGhost) {
+ IToken/*!*/ id; Type/*!*/ ty; Type optType = null;
+
+ Ident(out id);
+ if (la.kind == 22) {
+ Get();
+ Type(out ty);
+ optType = ty;
+ }
+ var = new VarDecl(id, id.val, optType == null ? new InferredTypeProxy() : optType, isGhost);
+ }
+
void IdentTypeOptional(out BoundVar/*!*/ var) {
Contract.Ensures(Contract.ValueAtReturn(out var)!=null); IToken/*!*/ id; Type/*!*/ ty; Type optType = null;
@@ -748,7 +719,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
ReferenceType(out tok, out ty);
break;
}
- default: SynErr(113); break;
+ default: SynErr(109); break;
}
}
@@ -757,11 +728,11 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, List<ModuleDecl/*!
Expect(32);
if (la.kind == 1 || la.kind == 11) {
GIdentType(allowGhosts, out id, out ty, out isGhost);
- formals.Add(new Formal(id, id.val, ty, incoming, isGhost)); parseVarScope.Push(id.val, id.val);
+ formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
while (la.kind == 19) {
Get();
GIdentType(allowGhosts, out id, out ty, out isGhost);
- formals.Add(new Formal(id, id.val, ty, incoming, isGhost)); parseVarScope.Push(id.val, id.val);
+ formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
}
}
Expect(33);
@@ -783,7 +754,7 @@ List<Expression/*!*/>/*!*/ decreases) {
mod.Add(fe);
}
}
- Expect(15);
+ Expect(17);
} else if (la.kind == 28 || la.kind == 29 || la.kind == 30) {
if (la.kind == 28) {
Get();
@@ -792,26 +763,25 @@ List<Expression/*!*/>/*!*/ decreases) {
if (la.kind == 29) {
Get();
Expression(out e);
- Expect(15);
+ Expect(17);
req.Add(new MaybeFreeExpression(e, isFree));
} else if (la.kind == 30) {
Get();
Expression(out e);
- Expect(15);
+ Expect(17);
ens.Add(new MaybeFreeExpression(e, isFree));
- } else SynErr(114);
+ } else SynErr(110);
} else if (la.kind == 31) {
Get();
Expressions(decreases);
- Expect(15);
- } else SynErr(115);
+ Expect(17);
+ } else SynErr(111);
}
void BlockStmt(out Statement/*!*/ block, out IToken bodyStart, out IToken bodyEnd) {
Contract.Ensures(Contract.ValueAtReturn(out block) != null);
List<Statement/*!*/> body = new List<Statement/*!*/>();
- parseVarScope.PushMarker();
Expect(7);
bodyStart = t;
while (StartOf(9)) {
@@ -820,7 +790,6 @@ List<Expression/*!*/>/*!*/ decreases) {
Expect(8);
bodyEnd = t;
block = new BlockStmt(bodyStart, body);
- parseVarScope.PopMarker();
}
void FrameExpression(out FrameExpression/*!*/ fe) {
@@ -886,7 +855,7 @@ List<Expression/*!*/>/*!*/ decreases) {
GenericInstantiation(gt);
}
ty = new UserDefinedType(tok, tok.val, gt);
- } else SynErr(116);
+ } else SynErr(112);
}
void FunctionSpec(List<Expression/*!*/>/*!*/ reqs, List<FrameExpression/*!*/>/*!*/ reads, List<Expression/*!*/>/*!*/ ens, List<Expression/*!*/>/*!*/ decreases) {
@@ -895,7 +864,7 @@ List<Expression/*!*/>/*!*/ decreases) {
if (la.kind == 29) {
Get();
Expression(out e);
- Expect(15);
+ Expect(17);
reqs.Add(e);
} else if (la.kind == 41) {
Get();
@@ -908,17 +877,17 @@ List<Expression/*!*/>/*!*/ decreases) {
reads.Add(fe);
}
}
- Expect(15);
+ Expect(17);
} else if (la.kind == 30) {
Get();
Expression(out e);
- Expect(15);
+ Expect(17);
ens.Add(e);
} else if (la.kind == 31) {
Get();
Expressions(decreases);
- Expect(15);
- } else SynErr(117);
+ Expect(17);
+ } else SynErr(113);
}
void FunctionBody(out Expression/*!*/ e, out IToken bodyStart, out IToken bodyEnd) {
@@ -929,7 +898,7 @@ List<Expression/*!*/>/*!*/ decreases) {
MatchExpression(out e);
} else if (StartOf(8)) {
Expression(out e);
- } else SynErr(118);
+ } else SynErr(114);
Expect(8);
bodyEnd = t;
}
@@ -941,7 +910,7 @@ List<Expression/*!*/>/*!*/ decreases) {
fe = new FrameExpression(new WildcardExpr(t), null);
} else if (StartOf(8)) {
FrameExpression(out fe);
- } else SynErr(119);
+ } else SynErr(115);
}
void PossiblyWildExpression(out Expression/*!*/ e) {
@@ -952,7 +921,7 @@ List<Expression/*!*/>/*!*/ decreases) {
e = new WildcardExpr(t);
} else if (StartOf(8)) {
Expression(out e);
- } else SynErr(120);
+ } else SynErr(116);
}
void MatchExpression(out Expression/*!*/ e) {
@@ -975,25 +944,22 @@ List<Expression/*!*/>/*!*/ decreases) {
Expression/*!*/ body;
Expect(45);
- x = t; parseVarScope.PushMarker();
+ x = t;
Ident(out id);
if (la.kind == 32) {
Get();
Ident(out arg);
- arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
- parseVarScope.Push(arg.val, arg.val);
+ arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
while (la.kind == 19) {
Get();
Ident(out arg);
- arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
- parseVarScope.Push(arg.val, arg.val);
+ arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
}
Expect(33);
}
Expect(46);
MatchOrExpr(out body);
- c = new MatchCaseExpr(x, id.val, arguments, body);
- parseVarScope.PopMarker();
+ c = new MatchCaseExpr(x, id.val, arguments, body);
}
void MatchOrExpr(out Expression/*!*/ e) {
@@ -1006,153 +972,96 @@ List<Expression/*!*/>/*!*/ decreases) {
MatchExpression(out e);
} else if (StartOf(8)) {
Expression(out e);
- } else SynErr(121);
+ } else SynErr(117);
}
void Stmt(List<Statement/*!*/>/*!*/ ss) {
- Contract.Requires(cce.NonNullElements(ss)); Statement/*!*/ s;
- IToken bodyStart, bodyEnd;
+ Statement/*!*/ s;
- while (la.kind == 7) {
- BlockStmt(out s, out bodyStart, out bodyEnd);
- ss.Add(s);
- }
- if (StartOf(11)) {
- OneStmt(out s);
- ss.Add(s);
- } else if (la.kind == 11 || la.kind == 18) {
- VarDeclStmts(ss);
- } else SynErr(122);
+ OneStmt(out s);
+ ss.Add(s);
}
void OneStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; IToken/*!*/ id; string label = null;
s = dummyStmt; /* to please the compiler */
+ IToken bodyStart, bodyEnd;
+ int breakCount;
- switch (la.kind) {
- case 64: {
+ if (la.kind == 7) {
+ BlockStmt(out s, out bodyStart, out bodyEnd);
+ } else if (la.kind == 63) {
AssertStmt(out s);
- break;
- }
- case 65: {
+ } else if (la.kind == 64) {
AssumeStmt(out s);
- break;
- }
- case 66: {
- UseStmt(out s);
- break;
- }
- case 67: {
+ } else if (la.kind == 65) {
PrintStmt(out s);
- break;
- }
- case 1: case 32: case 99: case 100: {
- AssignStmt(out s, true);
- break;
- }
- case 56: {
+ } else if (StartOf(11)) {
+ UpdateStmt(out s);
+ } else if (la.kind == 56) {
HavocStmt(out s);
- break;
- }
- case 61: {
- CallStmt(out s);
- break;
- }
- case 57: {
+ } else if (la.kind == 11 || la.kind == 18) {
+ VarDeclStatement(out s);
+ } else if (la.kind == 57) {
IfStmt(out s);
- break;
- }
- case 59: {
+ } else if (la.kind == 59) {
WhileStmt(out s);
- break;
- }
- case 44: {
+ } else if (la.kind == 44) {
MatchStmt(out s);
- break;
- }
- case 62: {
+ } else if (la.kind == 61) {
ForeachStmt(out s);
- break;
- }
- case 47: {
+ } else if (la.kind == 47) {
Get();
x = t;
Ident(out id);
Expect(22);
- s = new LabelStmt(x, id.val);
- break;
- }
- case 48: {
+ OneStmt(out s);
+ s.Labels = new LabelNode(x, id.val, s.Labels);
+ } else if (la.kind == 48) {
Get();
- x = t;
+ x = t; breakCount = 1; label = null;
if (la.kind == 1) {
Ident(out id);
label = id.val;
- }
- Expect(15);
- s = new BreakStmt(x, label);
- break;
- }
- case 49: {
+ } else if (la.kind == 17 || la.kind == 48) {
+ while (la.kind == 48) {
+ Get();
+ breakCount++;
+ }
+ } else SynErr(118);
+ Expect(17);
+ s = label != null ? new BreakStmt(x, label) : new BreakStmt(x, breakCount);
+ } else if (la.kind == 49) {
Get();
x = t;
- Expect(15);
+ Expect(17);
s = new ReturnStmt(x);
- break;
- }
- default: SynErr(123); break;
- }
- }
-
- void VarDeclStmts(List<Statement/*!*/>/*!*/ ss) {
- Contract.Requires(cce.NonNullElements(ss)); VarDecl/*!*/ d; bool isGhost = false;
- if (la.kind == 11) {
- Get();
- isGhost = true;
- }
- Expect(18);
- IdentTypeRhs(out d, isGhost);
- ss.Add(d); parseVarScope.Push(d.Name, d.Name);
- while (la.kind == 19) {
- Get();
- IdentTypeRhs(out d, isGhost);
- ss.Add(d); parseVarScope.Push(d.Name, d.Name);
- }
- Expect(15);
+ } else SynErr(119);
}
void AssertStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ e;
- Expect(64);
+ Expect(63);
x = t;
Expression(out e);
- Expect(15);
+ Expect(17);
s = new AssertStmt(x, e);
}
void AssumeStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ e;
- Expect(65);
+ Expect(64);
x = t;
Expression(out e);
- Expect(15);
+ Expect(17);
s = new AssumeStmt(x, e);
}
- void UseStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ e;
- Expect(66);
- x = t;
- Expression(out e);
- Expect(15);
- s = new UseStmt(x, e);
- }
-
void PrintStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Attributes.Argument/*!*/ arg;
List<Attributes.Argument/*!*/> args = new List<Attributes.Argument/*!*/>();
- Expect(67);
+ Expect(65);
x = t;
AttributeArg(out arg);
args.Add(arg);
@@ -1161,102 +1070,98 @@ List<Expression/*!*/>/*!*/ decreases) {
AttributeArg(out arg);
args.Add(arg);
}
- Expect(15);
+ Expect(17);
s = new PrintStmt(x, args);
}
- void AssignStmt(out Statement/*!*/ s, bool allowChoose) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x;
- Expression/*!*/ lhs;
- List<Expression> rhs;
- Type ty;
- s = dummyStmt;
- CallStmt initCall = null;
-
- LhsExpr(out lhs);
- Expect(50);
- x = t;
- AssignRhs(out rhs, out ty, out initCall, lhs);
- if (ty == null) {
- Contract.Assert(rhs != null);
- Contract.Assert(rhs.Count == 1);
- s = new AssignStmt(x, lhs, rhs[0]);
- if (!allowChoose) {
- var r = rhs[0] as UnaryExpr;
- if (r != null && r.Op == UnaryExpr.Opcode.SetChoose) {
- SemErr("choose operator not allowed as RHS in foreach assignment");
- }
- }
- } else if (rhs == null) {
- s = new AssignStmt(x, lhs, ty, initCall);
- } else {
- s = new AssignStmt(x, lhs, ty, rhs);
- }
+ void UpdateStmt(out Statement/*!*/ s) {
+ List<Expression> lhss = new List<Expression>();
+ List<DeterminedAssignmentRhs> rhss = new List<DeterminedAssignmentRhs>();
+ Expression e; DeterminedAssignmentRhs r;
+ Expression lhs0;
+ IToken x;
- Expect(15);
+ Lhs(out e);
+ x = e.tok;
+ if (la.kind == 17) {
+ Get();
+ rhss.Add(new ExprRhs(e));
+ } else if (la.kind == 19 || la.kind == 50) {
+ lhss.Add(e); lhs0 = e;
+ while (la.kind == 19) {
+ Get();
+ Lhs(out e);
+ lhss.Add(e);
+ }
+ Expect(50);
+ x = t;
+ Rhs(out r, lhs0);
+ rhss.Add(r);
+ while (la.kind == 19) {
+ Get();
+ Rhs(out r, lhs0);
+ rhss.Add(r);
+ }
+ Expect(17);
+ } else if (la.kind == 22) {
+ Get();
+ SemErr(t, "invalid statement (did you forget the 'label' keyword?)");
+ } else SynErr(120);
+ s = new UpdateStmt(x, lhss, rhss);
}
void HavocStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; Expression/*!*/ lhs;
Expect(56);
x = t;
- LhsExpr(out lhs);
- Expect(15);
+ Lhs(out lhs);
+ Expect(17);
s = new AssignStmt(x, lhs);
}
- void CallStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x, id;
- Expression/*!*/ e;
- List<IdentifierExpr/*!*/> lhs = new List<IdentifierExpr/*!*/>();
- List<AutoVarDecl/*!*/> newVars = new List<AutoVarDecl/*!*/>();
+ void VarDeclStatement(out Statement/*!*/ s) {
+ IToken x = null, assignTok = null; bool isGhost = false;
+ VarDecl/*!*/ d;
+ DeterminedAssignmentRhs r; Expression lhs0;
+ List<VarDecl> lhss = new List<VarDecl>();
+ List<DeterminedAssignmentRhs> rhss = new List<DeterminedAssignmentRhs>();
- Expect(61);
- x = t;
- CallStmtSubExpr(out e);
- if (la.kind == 19 || la.kind == 50) {
- if (la.kind == 19) {
- Get();
- e = ConvertToLocal(e);
- if (e is IdentifierExpr) {
- RecordCallLhs((IdentifierExpr)e, lhs, newVars);
- } else if (e is FieldSelectExpr) {
- SemErr(e.tok, "each LHS of call statement must be a variable, not a field");
- } else {
- SemErr(e.tok, "each LHS of call statement must be a variable");
- }
-
- Ident(out id);
- RecordCallLhs(new IdentifierExpr(id, id.val), lhs, newVars);
- while (la.kind == 19) {
- Get();
- Ident(out id);
- RecordCallLhs(new IdentifierExpr(id, id.val), lhs, newVars);
- }
- Expect(50);
- CallStmtSubExpr(out e);
- } else {
+ if (la.kind == 11) {
+ Get();
+ isGhost = true; x = t;
+ }
+ Expect(18);
+ if (!isGhost) { x = t; }
+ LocalIdentTypeOptional(out d, isGhost);
+ lhss.Add(d);
+ while (la.kind == 19) {
+ Get();
+ LocalIdentTypeOptional(out d, isGhost);
+ lhss.Add(d);
+ }
+ if (la.kind == 50) {
+ Get();
+ assignTok = t; lhs0 = new IdentifierExpr(lhss[0].Tok, lhss[0].Name);
+ Rhs(out r, lhs0);
+ rhss.Add(r);
+ while (la.kind == 19) {
Get();
- e = ConvertToLocal(e);
- if (e is IdentifierExpr) {
- RecordCallLhs((IdentifierExpr)e, lhs, newVars);
- } else if (e is FieldSelectExpr) {
- SemErr(e.tok, "each LHS of call statement must be a variable, not a field");
- } else {
- SemErr(e.tok, "each LHS of call statement must be a variable");
- }
-
- CallStmtSubExpr(out e);
+ Rhs(out r, lhs0);
+ rhss.Add(r);
}
}
- Expect(15);
- if (e is FunctionCallExpr) {
- FunctionCallExpr fce = (FunctionCallExpr)e;
- s = new CallStmt(x, newVars, lhs, fce.Receiver, fce.Name, fce.Args); // this actually does an ownership transfer of fce.Args
+ Expect(17);
+ UpdateStmt update;
+ if (rhss.Count == 0) {
+ update = null;
} else {
- SemErr("RHS of call statement must denote a method invocation");
- s = new CallStmt(x, newVars, lhs, dummyExpr, "dummyMethodName", new List<Expression/*!*/>());
+ var ies = new List<Expression>();
+ foreach (var lhs in lhss) {
+ ies.Add(new AutoGhostIdentifierExpr(lhs.Tok, lhs.Name));
+ }
+ update = new UpdateStmt(assignTok, ies, rhss);
}
+ s = new VarDeclStmt(x, lhss, update);
}
@@ -1283,13 +1188,13 @@ List<Expression/*!*/>/*!*/ decreases) {
} else if (la.kind == 7) {
BlockStmt(out s, out bodyStart, out bodyEnd);
els = s;
- } else SynErr(124);
+ } else SynErr(121);
}
ifStmt = new IfStmt(x, guard, thn, els);
} else if (la.kind == 7) {
AlternativeBlock(out alternatives);
ifStmt = new AlternativeStmt(x, alternatives);
- } else SynErr(125);
+ } else SynErr(122);
}
void WhileStmt(out Statement/*!*/ stmt) {
@@ -1314,7 +1219,7 @@ List<Expression/*!*/>/*!*/ decreases) {
LoopSpec(out invariants, out decreases);
AlternativeBlock(out alternatives);
stmt = new AlternativeLoopStmt(x, invariants, decreases, alternatives);
- } else SynErr(126);
+ } else SynErr(123);
}
void MatchStmt(out Statement/*!*/ s) {
@@ -1334,15 +1239,15 @@ List<Expression/*!*/>/*!*/ decreases) {
}
void ForeachStmt(out Statement/*!*/ s) {
- Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x, boundVar;
+ Contract.Ensures(Contract.ValueAtReturn(out s) != null);
+ IToken/*!*/ x, boundVar;
Type/*!*/ ty;
Expression/*!*/ collection;
Expression/*!*/ range;
List<PredicateStmt/*!*/> bodyPrefix = new List<PredicateStmt/*!*/>();
- AssignStmt bodyAssign = null;
+ Statement bodyAssign = null;
- parseVarScope.PushMarker();
- Expect(62);
+ Expect(61);
x = t;
range = new LiteralExpr(x, true);
ty = new InferredTypeProxy();
@@ -1353,34 +1258,30 @@ List<Expression/*!*/>/*!*/ decreases) {
Get();
Type(out ty);
}
- Expect(63);
+ Expect(62);
Expression(out collection);
- parseVarScope.Push(boundVar.val, boundVar.val);
- if (la.kind == 17) {
+ if (la.kind == 16) {
Get();
Expression(out range);
}
Expect(33);
Expect(7);
- while (la.kind == 64 || la.kind == 65 || la.kind == 66) {
- if (la.kind == 64) {
+ while (la.kind == 63 || la.kind == 64) {
+ if (la.kind == 63) {
AssertStmt(out s);
if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); }
- } else if (la.kind == 65) {
- AssumeStmt(out s);
- if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); }
} else {
- UseStmt(out s);
+ AssumeStmt(out s);
if (s is PredicateStmt) { bodyPrefix.Add((PredicateStmt)s); }
}
}
- if (StartOf(13)) {
- AssignStmt(out s, false);
- if (s is AssignStmt) { bodyAssign = (AssignStmt)s; }
+ if (StartOf(11)) {
+ UpdateStmt(out s);
+ bodyAssign = s;
} else if (la.kind == 56) {
HavocStmt(out s);
- if (s is AssignStmt) { bodyAssign = (AssignStmt)s; }
- } else SynErr(127);
+ bodyAssign = s;
+ } else SynErr(124);
Expect(8);
if (bodyAssign != null) {
s = new ForeachStmt(x, new BoundVar(boundVar, boundVar.val, ty), collection, range, bodyPrefix, bodyAssign);
@@ -1388,22 +1289,36 @@ List<Expression/*!*/>/*!*/ decreases) {
s = dummyStmt; // some error occurred in parsing the bodyAssign
}
- parseVarScope.PopMarker();
}
- void LhsExpr(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e)!=null);
- SelectExpression(out e);
+ void Lhs(out Expression e) {
+ e = null; // to please the compiler
+
+ if (la.kind == 1) {
+ DottedIdentifiersAndFunction(out e);
+ while (la.kind == 52 || la.kind == 54) {
+ Suffix(ref e);
+ }
+ } else if (StartOf(13)) {
+ ConstAtomExpression(out e);
+ Suffix(ref e);
+ while (la.kind == 52 || la.kind == 54) {
+ Suffix(ref e);
+ }
+ } else SynErr(125);
}
- void AssignRhs(out List<Expression> ee, out Type ty, out CallStmt initCall, Expression receiverForInitCall) {
- IToken/*!*/ x; Expression/*!*/ e;
- ee = null; ty = null;
- initCall = null;
+ void Rhs(out DeterminedAssignmentRhs r, Expression receiverForInitCall) {
+ IToken/*!*/ x, newToken; Expression/*!*/ e;
+ List<Expression> ee = null;
+ Type ty = null;
+ CallStmt initCall = null;
List<Expression> args;
+ r = null; // to please compiler
if (la.kind == 51) {
Get();
+ newToken = t;
TypeAndToken(out x, out ty);
if (la.kind == 52 || la.kind == 54) {
if (la.kind == 52) {
@@ -1422,66 +1337,25 @@ List<Expression/*!*/>/*!*/ decreases) {
Expressions(args);
}
Expect(33);
- initCall = new CallStmt(x, new List<AutoVarDecl>(), new List<IdentifierExpr>(),
+ initCall = new CallStmt(x, new List<IdentifierExpr>(),
receiverForInitCall, x.val, args);
}
}
+ if (ee != null) {
+ r = new TypeRhs(newToken, ty, ee);
+ } else {
+ r = new TypeRhs(newToken, ty, initCall);
+ }
+
} else if (la.kind == 55) {
Get();
x = t;
Expression(out e);
- e = new UnaryExpr(x, UnaryExpr.Opcode.SetChoose, e);
- ee = new List<Expression>() { e };
-
+ r = new ExprRhs(new UnaryExpr(x, UnaryExpr.Opcode.SetChoose, e));
} else if (StartOf(8)) {
Expression(out e);
- ee = new List<Expression>() { e };
- } else SynErr(128);
- if (ee == null && ty == null) { ee = new List<Expression>() { dummyExpr}; }
- }
-
- void SelectExpression(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null); e = dummyExpr;
- if (la.kind == 1) {
- IdentOrFuncExpression(out e);
- } else if (la.kind == 32 || la.kind == 99 || la.kind == 100) {
- ObjectExpression(out e);
- } else SynErr(129);
- while (la.kind == 52 || la.kind == 54) {
- SelectOrCallSuffix(ref e);
- }
- }
-
- void IdentTypeRhs(out VarDecl/*!*/ d, bool isGhost) {
- Contract.Ensures(Contract.ValueAtReturn(out d) != null); IToken/*!*/ id; Type/*!*/ ty;
- List<Expression> rhs = null; Type newType = null;
- Type optionalType = null; DeterminedAssignmentRhs optionalRhs = null;
- CallStmt initCall = null;
-
- Ident(out id);
- if (la.kind == 22) {
- Get();
- Type(out ty);
- optionalType = ty;
- }
- if (la.kind == 50) {
- Get();
- AssignRhs(out rhs, out newType, out initCall, new IdentifierExpr(id, id.val));
- }
- if (newType == null && rhs != null) {
- Contract.Assert(rhs.Count == 1);
- optionalRhs = new ExprRhs(rhs[0]);
- } else if (newType != null) {
- if (rhs == null) {
- optionalRhs = new TypeRhs(newType, initCall);
- } else {
- optionalRhs = new TypeRhs(newType, rhs);
- }
- } else if (optionalType == null) {
- optionalType = new InferredTypeProxy();
- }
- d = new VarDecl(id, id.val, optionalType, isGhost, optionalRhs);
-
+ r = new ExprRhs(e);
+ } else SynErr(126);
}
void Guard(out Expression e) {
@@ -1493,7 +1367,7 @@ List<Expression/*!*/>/*!*/ decreases) {
} else if (StartOf(8)) {
Expression(out ee);
e = ee;
- } else SynErr(130);
+ } else SynErr(127);
Expect(33);
}
@@ -1510,11 +1384,9 @@ List<Expression/*!*/>/*!*/ decreases) {
Expression(out e);
Expect(46);
body = new List<Statement>();
- parseVarScope.PushMarker();
while (StartOf(9)) {
Stmt(body);
}
- parseVarScope.PopMarker();
alternatives.Add(new GuardedAlternative(x, e, body));
}
Expect(8);
@@ -1535,7 +1407,7 @@ List<Expression/*!*/>/*!*/ decreases) {
Expect(60);
Expression(out e);
invariants.Add(new MaybeFreeExpression(e, isFree));
- Expect(15);
+ Expect(17);
} else {
Get();
PossiblyWildExpression(out e);
@@ -1545,7 +1417,7 @@ List<Expression/*!*/>/*!*/ decreases) {
PossiblyWildExpression(out e);
decreases.Add(e);
}
- Expect(15);
+ Expect(17);
}
}
}
@@ -1557,42 +1429,24 @@ List<Expression/*!*/>/*!*/ decreases) {
List<Statement/*!*/> body = new List<Statement/*!*/>();
Expect(45);
- x = t; parseVarScope.PushMarker();
+ x = t;
Ident(out id);
if (la.kind == 32) {
Get();
Ident(out arg);
- arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
- parseVarScope.Push(arg.val, arg.val);
+ arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
while (la.kind == 19) {
Get();
Ident(out arg);
- arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
- parseVarScope.Push(arg.val, arg.val);
+ arguments.Add(new BoundVar(arg, arg.val, new InferredTypeProxy()));
}
Expect(33);
}
Expect(46);
- parseVarScope.PushMarker();
while (StartOf(9)) {
Stmt(body);
}
- parseVarScope.PopMarker();
c = new MatchCaseStmt(x, id.val, arguments, body);
- parseVarScope.PopMarker();
- }
-
- void CallStmtSubExpr(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null); e = dummyExpr;
- if (la.kind == 1) {
- IdentOrFuncExpression(out e);
- } else if (la.kind == 32 || la.kind == 99 || la.kind == 100) {
- ObjectExpression(out e);
- SelectOrCallSuffix(ref e);
- } else SynErr(131);
- while (la.kind == 52 || la.kind == 54) {
- SelectOrCallSuffix(ref e);
- }
}
void AttributeArg(out Attributes.Argument/*!*/ arg) {
@@ -1603,13 +1457,13 @@ List<Expression/*!*/>/*!*/ decreases) {
} else if (StartOf(8)) {
Expression(out e);
arg = new Attributes.Argument(e);
- } else SynErr(132);
+ } else SynErr(128);
}
void EquivExpression(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
ImpliesExpression(out e0);
- while (la.kind == 68 || la.kind == 69) {
+ while (la.kind == 66 || la.kind == 67) {
EquivOp();
x = t;
ImpliesExpression(out e1);
@@ -1620,7 +1474,7 @@ List<Expression/*!*/>/*!*/ decreases) {
void ImpliesExpression(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
LogicalExpression(out e0);
- if (la.kind == 70 || la.kind == 71) {
+ if (la.kind == 68 || la.kind == 69) {
ImpliesOp();
x = t;
ImpliesExpression(out e1);
@@ -1629,23 +1483,23 @@ List<Expression/*!*/>/*!*/ decreases) {
}
void EquivOp() {
- if (la.kind == 68) {
+ if (la.kind == 66) {
Get();
- } else if (la.kind == 69) {
+ } else if (la.kind == 67) {
Get();
- } else SynErr(133);
+ } else SynErr(129);
}
void LogicalExpression(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
RelationalExpression(out e0);
if (StartOf(14)) {
- if (la.kind == 72 || la.kind == 73) {
+ if (la.kind == 70 || la.kind == 71) {
AndOp();
x = t;
RelationalExpression(out e1);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1);
- while (la.kind == 72 || la.kind == 73) {
+ while (la.kind == 70 || la.kind == 71) {
AndOp();
x = t;
RelationalExpression(out e1);
@@ -1656,7 +1510,7 @@ List<Expression/*!*/>/*!*/ decreases) {
x = t;
RelationalExpression(out e1);
e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1);
- while (la.kind == 74 || la.kind == 75) {
+ while (la.kind == 72 || la.kind == 73) {
OrOp();
x = t;
RelationalExpression(out e1);
@@ -1667,43 +1521,108 @@ List<Expression/*!*/>/*!*/ decreases) {
}
void ImpliesOp() {
- if (la.kind == 70) {
+ if (la.kind == 68) {
Get();
- } else if (la.kind == 71) {
+ } else if (la.kind == 69) {
Get();
- } else SynErr(134);
+ } else SynErr(130);
}
- void RelationalExpression(out Expression/*!*/ e0) {
- Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op;
+ void RelationalExpression(out Expression/*!*/ e) {
+ Contract.Ensures(Contract.ValueAtReturn(out e) != null);
+ IToken x, firstOpTok = null; Expression e0, e1; BinaryExpr.Opcode op;
+ List<Expression> chain = null;
+ List<BinaryExpr.Opcode> ops = null;
+ int kind = 0; // 0 ("uncommitted") indicates chain of ==, possibly with one !=
+ // 1 ("ascending") indicates chain of ==, <, <=, possibly with one !=
+ // 2 ("descending") indicates chain of ==, >, >=, possibly with one !=
+ // 3 ("illegal") indicates illegal chain
+ bool hasSeenNeq = false;
+
Term(out e0);
+ e = e0;
if (StartOf(15)) {
RelOp(out x, out op);
+ firstOpTok = x;
Term(out e1);
- e0 = new BinaryExpr(x, op, e0, e1);
+ e = new BinaryExpr(x, op, e0, e1);
+ while (StartOf(15)) {
+ if (chain == null) {
+ chain = new List<Expression>();
+ ops = new List<BinaryExpr.Opcode>();
+ chain.Add(e0); ops.Add(op); chain.Add(e1);
+ switch (op) {
+ case BinaryExpr.Opcode.Eq:
+ kind = 0; break;
+ case BinaryExpr.Opcode.Neq:
+ kind = 0; hasSeenNeq = true; break;
+ case BinaryExpr.Opcode.Lt:
+ case BinaryExpr.Opcode.Le:
+ kind = 1; break;
+ case BinaryExpr.Opcode.Gt:
+ case BinaryExpr.Opcode.Ge:
+ kind = 2; break;
+ default:
+ kind = 3; break;
+ }
+ }
+ e0 = e1;
+
+ RelOp(out x, out op);
+ switch (op) {
+ case BinaryExpr.Opcode.Eq:
+ if (kind == 3) { SemErr(x, "chaining not allowed from the previous operator"); }
+ break;
+ case BinaryExpr.Opcode.Neq:
+ if (hasSeenNeq) { SemErr(x, "a chain cannot have more than one != operator"); }
+ hasSeenNeq = true; break;
+ case BinaryExpr.Opcode.Lt:
+ case BinaryExpr.Opcode.Le:
+ if (kind == 0) { kind = 1; }
+ else if (kind != 1) { SemErr(x, "this operator chain cannot continue with an ascending operator"); }
+ break;
+ case BinaryExpr.Opcode.Gt:
+ case BinaryExpr.Opcode.Ge:
+ if (kind == 0) { kind = 2; }
+ else if (kind != 2) { SemErr(x, "this operator chain cannot continue with a descending operator"); }
+ break;
+ default:
+ SemErr(x, "this operator cannot be part of a chain");
+ kind = 3; break;
+ }
+
+ Term(out e1);
+ ops.Add(op); chain.Add(e1);
+ e = new BinaryExpr(x, BinaryExpr.Opcode.And, e, new BinaryExpr(x, op, e0, e1));
+
+ }
}
+ if (chain != null) {
+ e = new ChainingExpression(firstOpTok, chain, ops, e);
+ }
+
}
void AndOp() {
- if (la.kind == 72) {
+ if (la.kind == 70) {
Get();
- } else if (la.kind == 73) {
+ } else if (la.kind == 71) {
Get();
- } else SynErr(135);
+ } else SynErr(131);
}
void OrOp() {
- if (la.kind == 74) {
+ if (la.kind == 72) {
Get();
- } else if (la.kind == 75) {
+ } else if (la.kind == 73) {
Get();
- } else SynErr(136);
+ } else SynErr(132);
}
void Term(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op;
Factor(out e0);
- while (la.kind == 85 || la.kind == 86) {
+ while (la.kind == 83 || la.kind == 84) {
AddOp(out x, out op);
Factor(out e1);
e0 = new BinaryExpr(x, op, e0, e1);
@@ -1713,7 +1632,7 @@ List<Expression/*!*/>/*!*/ decreases) {
void RelOp(out IToken/*!*/ x, out BinaryExpr.Opcode op) {
Contract.Ensures(Contract.ValueAtReturn(out x) != null); x = Token.NoToken; op = BinaryExpr.Opcode.Add/*(dummy)*/;
switch (la.kind) {
- case 76: {
+ case 74: {
Get();
x = t; op = BinaryExpr.Opcode.Eq;
break;
@@ -1728,59 +1647,59 @@ List<Expression/*!*/>/*!*/ decreases) {
x = t; op = BinaryExpr.Opcode.Gt;
break;
}
- case 77: {
+ case 75: {
Get();
x = t; op = BinaryExpr.Opcode.Le;
break;
}
- case 78: {
+ case 76: {
Get();
x = t; op = BinaryExpr.Opcode.Ge;
break;
}
- case 79: {
+ case 77: {
Get();
x = t; op = BinaryExpr.Opcode.Neq;
break;
}
- case 80: {
+ case 78: {
Get();
x = t; op = BinaryExpr.Opcode.Disjoint;
break;
}
- case 63: {
+ case 62: {
Get();
x = t; op = BinaryExpr.Opcode.In;
break;
}
- case 81: {
+ case 79: {
Get();
x = t; op = BinaryExpr.Opcode.NotIn;
break;
}
- case 82: {
+ case 80: {
Get();
x = t; op = BinaryExpr.Opcode.Neq;
break;
}
- case 83: {
+ case 81: {
Get();
x = t; op = BinaryExpr.Opcode.Le;
break;
}
- case 84: {
+ case 82: {
Get();
x = t; op = BinaryExpr.Opcode.Ge;
break;
}
- default: SynErr(137); break;
+ default: SynErr(133); break;
}
}
void Factor(out Expression/*!*/ e0) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op;
UnaryExpression(out e0);
- while (la.kind == 42 || la.kind == 87 || la.kind == 88) {
+ while (la.kind == 42 || la.kind == 85 || la.kind == 86) {
MulOp(out x, out op);
UnaryExpression(out e1);
e0 = new BinaryExpr(x, op, e0, e1);
@@ -1789,32 +1708,40 @@ List<Expression/*!*/>/*!*/ decreases) {
void AddOp(out IToken/*!*/ x, out BinaryExpr.Opcode op) {
Contract.Ensures(Contract.ValueAtReturn(out x) != null); x = Token.NoToken; op=BinaryExpr.Opcode.Add/*(dummy)*/;
- if (la.kind == 85) {
+ if (la.kind == 83) {
Get();
x = t; op = BinaryExpr.Opcode.Add;
- } else if (la.kind == 86) {
+ } else if (la.kind == 84) {
Get();
x = t; op = BinaryExpr.Opcode.Sub;
- } else SynErr(138);
+ } else SynErr(134);
}
void UnaryExpression(out Expression/*!*/ e) {
Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; e = dummyExpr;
- if (la.kind == 86) {
+ if (la.kind == 84) {
Get();
x = t;
UnaryExpression(out e);
e = new BinaryExpr(x, BinaryExpr.Opcode.Sub, new LiteralExpr(x, 0), e);
- } else if (la.kind == 89 || la.kind == 90) {
+ } else if (la.kind == 87 || la.kind == 88) {
NegOp();
x = t;
UnaryExpression(out e);
e = new UnaryExpr(x, UnaryExpr.Opcode.Not, e);
- } else if (StartOf(13)) {
- SelectExpression(out e);
} else if (StartOf(16)) {
+ EndlessExpression(out e);
+ } else if (la.kind == 1) {
+ DottedIdentifiersAndFunction(out e);
+ while (la.kind == 52 || la.kind == 54) {
+ Suffix(ref e);
+ }
+ } else if (StartOf(13)) {
ConstAtomExpression(out e);
- } else SynErr(139);
+ while (la.kind == 52 || la.kind == 54) {
+ Suffix(ref e);
+ }
+ } else SynErr(135);
}
void MulOp(out IToken/*!*/ x, out BinaryExpr.Opcode op) {
@@ -1822,40 +1749,163 @@ List<Expression/*!*/>/*!*/ decreases) {
if (la.kind == 42) {
Get();
x = t; op = BinaryExpr.Opcode.Mul;
- } else if (la.kind == 87) {
+ } else if (la.kind == 85) {
Get();
x = t; op = BinaryExpr.Opcode.Div;
- } else if (la.kind == 88) {
+ } else if (la.kind == 86) {
Get();
x = t; op = BinaryExpr.Opcode.Mod;
- } else SynErr(140);
+ } else SynErr(136);
}
void NegOp() {
- if (la.kind == 89) {
+ if (la.kind == 87) {
+ Get();
+ } else if (la.kind == 88) {
+ Get();
+ } else SynErr(137);
+ }
+
+ void EndlessExpression(out Expression e) {
+ IToken/*!*/ x;
+ Expression e0, e1;
+ e = dummyExpr;
+
+ if (la.kind == 57) {
Get();
- } else if (la.kind == 90) {
+ x = t;
+ Expression(out e);
+ Expect(96);
+ Expression(out e0);
+ Expect(58);
+ Expression(out e1);
+ e = new ITEExpr(x, e, e0, e1);
+ } else if (StartOf(17)) {
+ QuantifierGuts(out e);
+ } else if (la.kind == 37) {
+ ComprehensionExpr(out e);
+ } else SynErr(138);
+ }
+
+ void DottedIdentifiersAndFunction(out Expression e) {
+ IToken id; IToken openParen = null;
+ List<Expression> args = null;
+ List<IToken> idents = new List<IToken>();
+
+ Ident(out id);
+ idents.Add(id);
+ while (la.kind == 54) {
Get();
+ Ident(out id);
+ idents.Add(id);
+ }
+ if (la.kind == 32) {
+ Get();
+ openParen = t; args = new List<Expression>();
+ if (StartOf(8)) {
+ Expressions(args);
+ }
+ Expect(33);
+ }
+ e = new IdentifierSequence(idents, openParen, args);
+ }
+
+ void Suffix(ref Expression/*!*/ e) {
+ Contract.Requires(e != null); Contract.Ensures(e!=null); IToken/*!*/ id, x; List<Expression/*!*/>/*!*/ args;
+ Expression e0 = null; Expression e1 = null; Expression/*!*/ ee; bool anyDots = false;
+ List<Expression> multipleIndices = null;
+ bool func = false;
+
+ if (la.kind == 54) {
+ Get();
+ Ident(out id);
+ if (la.kind == 32) {
+ Get();
+ args = new List<Expression/*!*/>(); func = true;
+ if (StartOf(8)) {
+ Expressions(args);
+ }
+ Expect(33);
+ e = new FunctionCallExpr(id, id.val, e, args);
+ }
+ if (!func) { e = new FieldSelectExpr(id, e, id.val); }
+ } else if (la.kind == 52) {
+ Get();
+ x = t;
+ if (StartOf(8)) {
+ Expression(out ee);
+ e0 = ee;
+ if (la.kind == 97) {
+ Get();
+ anyDots = true;
+ if (StartOf(8)) {
+ Expression(out ee);
+ e1 = ee;
+ }
+ } else if (la.kind == 50) {
+ Get();
+ Expression(out ee);
+ e1 = ee;
+ } else if (la.kind == 19 || la.kind == 53) {
+ while (la.kind == 19) {
+ Get();
+ Expression(out ee);
+ if (multipleIndices == null) {
+ multipleIndices = new List<Expression>();
+ multipleIndices.Add(e0);
+ }
+ multipleIndices.Add(ee);
+
+ }
+ } else SynErr(139);
+ } else if (la.kind == 97) {
+ Get();
+ Expression(out ee);
+ anyDots = true; e1 = ee;
+ } else SynErr(140);
+ if (multipleIndices != null) {
+ e = new MultiSelectExpr(x, e, multipleIndices);
+ // make sure an array class with this dimensionality exists
+ UserDefinedType tmp = theBuiltIns.ArrayType(x, multipleIndices.Count, new IntType(), true);
+ } else {
+ if (!anyDots && e0 == null) {
+ /* a parsing error occurred */
+ e0 = dummyExpr;
+ }
+ Contract.Assert(anyDots || e0 != null);
+ if (anyDots) {
+ Contract.Assert(e0 != null || e1 != null);
+ e = new SeqSelectExpr(x, false, e, e0, e1);
+ } else if (e1 == null) {
+ Contract.Assert(e0 != null);
+ e = new SeqSelectExpr(x, true, e, e0, null);
+ } else {
+ Contract.Assert(e0 != null);
+ e = new SeqUpdateExpr(x, e, e0, e1);
+ }
+ }
+
+ Expect(53);
} else SynErr(141);
}
void ConstAtomExpression(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x, dtName, id; BigInteger n; List<Expression/*!*/>/*!*/ elements;
- Expression e0, e1;
+ Contract.Ensures(Contract.ValueAtReturn(out e) != null);
+ IToken/*!*/ x; BigInteger n; List<Expression/*!*/>/*!*/ elements;
e = dummyExpr;
switch (la.kind) {
- case 91: {
+ case 89: {
Get();
e = new LiteralExpr(t, false);
break;
}
- case 92: {
+ case 90: {
Get();
e = new LiteralExpr(t, true);
break;
}
- case 93: {
+ case 91: {
Get();
e = new LiteralExpr(t);
break;
@@ -1865,24 +1915,12 @@ List<Expression/*!*/>/*!*/ decreases) {
e = new LiteralExpr(t, n);
break;
}
- case 94: {
+ case 92: {
Get();
- x = t;
- Ident(out dtName);
- Expect(54);
- Ident(out id);
- elements = new List<Expression/*!*/>();
- if (la.kind == 32) {
- Get();
- if (StartOf(8)) {
- Expressions(elements);
- }
- Expect(33);
- }
- e = new DatatypeValue(t, dtName.val, id.val, elements);
+ e = new ThisExpr(t);
break;
}
- case 95: {
+ case 93: {
Get();
x = t;
Expect(32);
@@ -1891,7 +1929,7 @@ List<Expression/*!*/>/*!*/ decreases) {
e = new FreshExpr(x, e);
break;
}
- case 96: {
+ case 94: {
Get();
x = t;
Expect(32);
@@ -1900,12 +1938,21 @@ List<Expression/*!*/>/*!*/ decreases) {
e = new AllocatedExpr(x, e);
break;
}
- case 17: {
+ case 95: {
+ Get();
+ x = t;
+ Expect(32);
+ Expression(out e);
+ Expect(33);
+ e = new OldExpr(x, e);
+ break;
+ }
+ case 16: {
Get();
x = t;
Expression(out e);
e = new UnaryExpr(x, UnaryExpr.Opcode.SeqLength, e);
- Expect(17);
+ Expect(16);
break;
}
case 7: {
@@ -1928,23 +1975,12 @@ List<Expression/*!*/>/*!*/ decreases) {
Expect(53);
break;
}
- case 57: {
+ case 32: {
Get();
x = t;
Expression(out e);
- Expect(97);
- Expression(out e0);
- Expect(58);
- Expression(out e1);
- e = new ITEExpr(x, e, e0, e1);
- break;
- }
- case 101: case 102: case 103: case 104: {
- QuantifierGuts(out e);
- break;
- }
- case 37: {
- ComprehensionExpr(out e);
+ e = new ParensExpression(x, e);
+ Expect(33);
break;
}
default: SynErr(142); break;
@@ -1972,25 +2008,24 @@ List<Expression/*!*/>/*!*/ decreases) {
Expression range = null;
Expression/*!*/ body;
- if (la.kind == 101 || la.kind == 102) {
+ if (la.kind == 98 || la.kind == 99) {
Forall();
x = t; univ = true;
- } else if (la.kind == 103 || la.kind == 104) {
+ } else if (la.kind == 100 || la.kind == 101) {
Exists();
x = t;
} else SynErr(143);
- parseVarScope.PushMarker();
IdentTypeOptional(out bv);
- bvars.Add(bv); parseVarScope.Push(bv.Name, bv.Name);
+ bvars.Add(bv);
while (la.kind == 19) {
Get();
IdentTypeOptional(out bv);
- bvars.Add(bv); parseVarScope.Push(bv.Name, bv.Name);
+ bvars.Add(bv);
}
while (la.kind == 7) {
AttributeOrTrigger(ref attrs, ref trigs);
}
- if (la.kind == 17) {
+ if (la.kind == 16) {
Get();
Expression(out range);
}
@@ -2001,7 +2036,6 @@ List<Expression/*!*/>/*!*/ decreases) {
} else {
q = new ExistsExpr(x, bvars, range, body, trigs, attrs);
}
- parseVarScope.PopMarker();
}
@@ -2015,160 +2049,38 @@ List<Expression/*!*/>/*!*/ decreases) {
Expect(37);
x = t;
- parseVarScope.PushMarker();
IdentTypeOptional(out bv);
- bvars.Add(bv); parseVarScope.Push(bv.Name, bv.Name);
+ bvars.Add(bv);
while (la.kind == 19) {
Get();
IdentTypeOptional(out bv);
- bvars.Add(bv); parseVarScope.Push(bv.Name, bv.Name);
+ bvars.Add(bv);
}
- Expect(17);
+ Expect(16);
Expression(out range);
- if (la.kind == 105 || la.kind == 106) {
+ if (la.kind == 102 || la.kind == 103) {
QSep();
Expression(out body);
}
if (body == null && bvars.Count != 1) { SemErr(t, "a set comprehension with more than one bound variable must have a term expression"); }
q = new SetComprehension(x, bvars, range, body);
- parseVarScope.PopMarker();
-
- }
-
- void IdentOrFuncExpression(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ id; e = dummyExpr; List<Expression/*!*/>/*!*/ args;
- Ident(out id);
- if (la.kind == 32) {
- Get();
- args = new List<Expression/*!*/>();
- if (StartOf(8)) {
- Expressions(args);
- }
- Expect(33);
- e = new FunctionCallExpr(id, id.val, new ImplicitThisExpr(id), args);
- }
- if (e == dummyExpr) {
- if (parseVarScope.Find(id.val) != null) {
- e = new IdentifierExpr(id, id.val);
- } else {
- e = new FieldSelectExpr(id, new ImplicitThisExpr(id), id.val);
- }
- }
}
- void ObjectExpression(out Expression/*!*/ e) {
- Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; e = dummyExpr;
- if (la.kind == 99) {
- Get();
- e = new ThisExpr(t);
- } else if (la.kind == 100) {
- Get();
- x = t;
- Expect(32);
- Expression(out e);
- Expect(33);
- e = new OldExpr(x, e);
- } else if (la.kind == 32) {
- Get();
- Expression(out e);
- Expect(33);
- } else SynErr(144);
- }
-
- void SelectOrCallSuffix(ref Expression/*!*/ e) {
- Contract.Requires(e != null); Contract.Ensures(e!=null); IToken/*!*/ id, x; List<Expression/*!*/>/*!*/ args;
- Expression e0 = null; Expression e1 = null; Expression/*!*/ ee; bool anyDots = false;
- List<Expression> multipleIndices = null;
- bool func = false;
-
- if (la.kind == 54) {
- Get();
- Ident(out id);
- if (la.kind == 32) {
- Get();
- args = new List<Expression/*!*/>(); func = true;
- if (StartOf(8)) {
- Expressions(args);
- }
- Expect(33);
- e = new FunctionCallExpr(id, id.val, e, args);
- }
- if (!func) { e = new FieldSelectExpr(id, e, id.val); }
- } else if (la.kind == 52) {
- Get();
- x = t;
- if (StartOf(8)) {
- Expression(out ee);
- e0 = ee;
- if (la.kind == 98) {
- Get();
- anyDots = true;
- if (StartOf(8)) {
- Expression(out ee);
- e1 = ee;
- }
- } else if (la.kind == 50) {
- Get();
- Expression(out ee);
- e1 = ee;
- } else if (la.kind == 19 || la.kind == 53) {
- while (la.kind == 19) {
- Get();
- Expression(out ee);
- if (multipleIndices == null) {
- multipleIndices = new List<Expression>();
- multipleIndices.Add(e0);
- }
- multipleIndices.Add(ee);
-
- }
- } else SynErr(145);
- } else if (la.kind == 98) {
- Get();
- Expression(out ee);
- anyDots = true; e1 = ee;
- } else SynErr(146);
- if (multipleIndices != null) {
- e = new MultiSelectExpr(x, e, multipleIndices);
- // make sure an array class with this dimensionality exists
- UserDefinedType tmp = theBuiltIns.ArrayType(x, multipleIndices.Count, new IntType(), true);
- } else {
- if (!anyDots && e0 == null) {
- /* a parsing error occurred */
- e0 = dummyExpr;
- }
- Contract.Assert(anyDots || e0 != null);
- if (anyDots) {
- Contract.Assert(e0 != null || e1 != null);
- e = new SeqSelectExpr(x, false, e, e0, e1);
- } else if (e1 == null) {
- Contract.Assert(e0 != null);
- e = new SeqSelectExpr(x, true, e, e0, null);
- } else {
- Contract.Assert(e0 != null);
- e = new SeqUpdateExpr(x, e, e0, e1);
- }
- }
-
- Expect(53);
- } else SynErr(147);
- }
-
void Forall() {
- if (la.kind == 101) {
+ if (la.kind == 98) {
Get();
- } else if (la.kind == 102) {
+ } else if (la.kind == 99) {
Get();
- } else SynErr(148);
+ } else SynErr(144);
}
void Exists() {
- if (la.kind == 103) {
+ if (la.kind == 100) {
Get();
- } else if (la.kind == 104) {
+ } else if (la.kind == 101) {
Get();
- } else SynErr(149);
+ } else SynErr(145);
}
void AttributeOrTrigger(ref Attributes attrs, ref Triggers trigs) {
@@ -2181,16 +2093,16 @@ List<Expression/*!*/>/*!*/ decreases) {
es = new List<Expression/*!*/>();
Expressions(es);
trigs = new Triggers(es, trigs);
- } else SynErr(150);
+ } else SynErr(146);
Expect(8);
}
void QSep() {
- if (la.kind == 105) {
+ if (la.kind == 102) {
Get();
- } else if (la.kind == 106) {
+ } else if (la.kind == 103) {
Get();
- } else SynErr(151);
+ } else SynErr(147);
}
void AttributeBody(ref Attributes attrs) {
@@ -2201,7 +2113,7 @@ List<Expression/*!*/>/*!*/ decreases) {
Expect(22);
Expect(1);
aName = t.val;
- if (StartOf(17)) {
+ if (StartOf(18)) {
AttributeArg(out aArg);
aArgs.Add(aArg);
while (la.kind == 19) {
@@ -2225,24 +2137,25 @@ List<Expression/*!*/>/*!*/ decreases) {
}
static readonly bool[,]/*!*/ set = {
- {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,T,x,x, x,T,T,T, T,T,T,x, x,x,T,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,T,T, T,T,x,x, x,x,T,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,T,x,T, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,T,T,x, x,x,x,T, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,T,T,T, T,T,T,T, T,x,x,T, T,T,T,T, T,x,x,x, x},
- {x,T,x,x, x,x,x,T, x,x,x,T, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, T,T,x,x, x,x,x,x, T,T,x,T, x,T,T,x, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x},
- {x,T,T,x, x,x,x,T, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,T,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,T,T,T, T,T,T,T, T,x,x,T, T,T,T,T, T,x,x,x, x},
- {x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, T,T,x,x, x,x,x,x, T,T,x,T, x,T,T,x, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, T,T,T,T, T,T,T,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x},
- {x,x,T,x, x,x,x,T, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, T,x,x,x, x,T,T,T, T,x,x,x, x},
- {x,T,T,x, T,x,x,T, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,T,T,T, T,T,T,T, T,x,x,T, T,T,T,T, T,x,x,x, x}
+ {T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,T,x,x, x,T,T,T, T,T,T,x, x,x,T,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,x,x,x, x,x,T,T, T,T,x,x, x,x,T,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,T,x,T, x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,T,T,x, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, T,T,T,T, T,T,T,T, x,x,T,T, T,T,x,x, x,x},
+ {x,T,T,x, x,x,x,T, x,x,x,T, x,x,x,x, T,x,T,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, T,T,x,x, T,x,x,x, T,T,x,T, x,T,x,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x},
+ {x,T,T,x, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,T,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, T,T,T,T, T,T,T,T, x,x,T,T, T,T,x,x, x,x},
+ {x,T,T,x, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,x,T,x, x,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,T,T, T,T,T,T, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,x,x, x,x},
+ {x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,x,x, x,x},
+ {x,T,T,x, T,x,x,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,T, T,T,T,T, T,T,T,T, x,x,T,T, T,T,x,x, x,x}
};
} // end Parser
@@ -2282,9 +2195,9 @@ public class Errors {
case 12: s = "\"static\" expected"; break;
case 13: s = "\"unlimited\" expected"; break;
case 14: s = "\"datatype\" expected"; break;
- case 15: s = "\";\" expected"; break;
- case 16: s = "\"=\" expected"; break;
- case 17: s = "\"|\" expected"; break;
+ case 15: s = "\"=\" expected"; break;
+ case 16: s = "\"|\" expected"; break;
+ case 17: s = "\";\" expected"; break;
case 18: s = "\"var\" expected"; break;
case 19: s = "\",\" expected"; break;
case 20: s = "\"replaces\" expected"; break;
@@ -2328,97 +2241,93 @@ public class Errors {
case 58: s = "\"else\" expected"; break;
case 59: s = "\"while\" expected"; break;
case 60: s = "\"invariant\" expected"; break;
- case 61: s = "\"call\" expected"; break;
- case 62: s = "\"foreach\" expected"; break;
- case 63: s = "\"in\" expected"; break;
- case 64: s = "\"assert\" expected"; break;
- case 65: s = "\"assume\" expected"; break;
- case 66: s = "\"use\" expected"; break;
- case 67: s = "\"print\" expected"; break;
- case 68: s = "\"<==>\" expected"; break;
- case 69: s = "\"\\u21d4\" expected"; break;
- case 70: s = "\"==>\" expected"; break;
- case 71: s = "\"\\u21d2\" expected"; break;
- case 72: s = "\"&&\" expected"; break;
- case 73: s = "\"\\u2227\" expected"; break;
- case 74: s = "\"||\" expected"; break;
- case 75: s = "\"\\u2228\" expected"; break;
- case 76: s = "\"==\" expected"; break;
- case 77: s = "\"<=\" expected"; break;
- case 78: s = "\">=\" expected"; break;
- case 79: s = "\"!=\" expected"; break;
- case 80: s = "\"!!\" expected"; break;
- case 81: s = "\"!in\" expected"; break;
- case 82: s = "\"\\u2260\" expected"; break;
- case 83: s = "\"\\u2264\" expected"; break;
- case 84: s = "\"\\u2265\" expected"; break;
- case 85: s = "\"+\" expected"; break;
- case 86: s = "\"-\" expected"; break;
- case 87: s = "\"/\" expected"; break;
- case 88: s = "\"%\" expected"; break;
- case 89: s = "\"!\" expected"; break;
- case 90: s = "\"\\u00ac\" expected"; break;
- case 91: s = "\"false\" expected"; break;
- case 92: s = "\"true\" expected"; break;
- case 93: s = "\"null\" expected"; break;
- case 94: s = "\"#\" expected"; break;
- case 95: s = "\"fresh\" expected"; break;
- case 96: s = "\"allocated\" expected"; break;
- case 97: s = "\"then\" expected"; break;
- case 98: s = "\"..\" expected"; break;
- case 99: s = "\"this\" expected"; break;
- case 100: s = "\"old\" expected"; break;
- case 101: s = "\"forall\" expected"; break;
- case 102: s = "\"\\u2200\" expected"; break;
- case 103: s = "\"exists\" expected"; break;
- case 104: s = "\"\\u2203\" expected"; break;
- case 105: s = "\"::\" expected"; break;
- case 106: s = "\"\\u2022\" expected"; break;
- case 107: s = "??? expected"; break;
- case 108: s = "invalid DatatypeDecl"; break;
- case 109: s = "invalid ClassMemberDecl"; break;
- case 110: s = "invalid FunctionDecl"; break;
- case 111: s = "invalid MethodDecl"; break;
- case 112: s = "invalid MethodDecl"; break;
- case 113: s = "invalid TypeAndToken"; break;
- case 114: s = "invalid MethodSpec"; break;
- case 115: s = "invalid MethodSpec"; break;
- case 116: s = "invalid ReferenceType"; break;
- case 117: s = "invalid FunctionSpec"; break;
- case 118: s = "invalid FunctionBody"; break;
- case 119: s = "invalid PossiblyWildFrameExpression"; break;
- case 120: s = "invalid PossiblyWildExpression"; break;
- case 121: s = "invalid MatchOrExpr"; break;
- case 122: s = "invalid Stmt"; break;
- case 123: s = "invalid OneStmt"; break;
- case 124: s = "invalid IfStmt"; break;
- case 125: s = "invalid IfStmt"; break;
- case 126: s = "invalid WhileStmt"; break;
- case 127: s = "invalid ForeachStmt"; break;
- case 128: s = "invalid AssignRhs"; break;
- case 129: s = "invalid SelectExpression"; break;
- case 130: s = "invalid Guard"; break;
- case 131: s = "invalid CallStmtSubExpr"; break;
- case 132: s = "invalid AttributeArg"; break;
- case 133: s = "invalid EquivOp"; break;
- case 134: s = "invalid ImpliesOp"; break;
- case 135: s = "invalid AndOp"; break;
- case 136: s = "invalid OrOp"; break;
- case 137: s = "invalid RelOp"; break;
- case 138: s = "invalid AddOp"; break;
- case 139: s = "invalid UnaryExpression"; break;
- case 140: s = "invalid MulOp"; break;
- case 141: s = "invalid NegOp"; break;
+ case 61: s = "\"foreach\" expected"; break;
+ case 62: s = "\"in\" expected"; break;
+ case 63: s = "\"assert\" expected"; break;
+ case 64: s = "\"assume\" expected"; break;
+ case 65: s = "\"print\" expected"; break;
+ case 66: s = "\"<==>\" expected"; break;
+ case 67: s = "\"\\u21d4\" expected"; break;
+ case 68: s = "\"==>\" expected"; break;
+ case 69: s = "\"\\u21d2\" expected"; break;
+ case 70: s = "\"&&\" expected"; break;
+ case 71: s = "\"\\u2227\" expected"; break;
+ case 72: s = "\"||\" expected"; break;
+ case 73: s = "\"\\u2228\" expected"; break;
+ case 74: s = "\"==\" expected"; break;
+ case 75: s = "\"<=\" expected"; break;
+ case 76: s = "\">=\" expected"; break;
+ case 77: s = "\"!=\" expected"; break;
+ case 78: s = "\"!!\" expected"; break;
+ case 79: s = "\"!in\" expected"; break;
+ case 80: s = "\"\\u2260\" expected"; break;
+ case 81: s = "\"\\u2264\" expected"; break;
+ case 82: s = "\"\\u2265\" expected"; break;
+ case 83: s = "\"+\" expected"; break;
+ case 84: s = "\"-\" expected"; break;
+ case 85: s = "\"/\" expected"; break;
+ case 86: s = "\"%\" expected"; break;
+ case 87: s = "\"!\" expected"; break;
+ case 88: s = "\"\\u00ac\" expected"; break;
+ case 89: s = "\"false\" expected"; break;
+ case 90: s = "\"true\" expected"; break;
+ case 91: s = "\"null\" expected"; break;
+ case 92: s = "\"this\" expected"; break;
+ case 93: s = "\"fresh\" expected"; break;
+ case 94: s = "\"allocated\" expected"; break;
+ case 95: s = "\"old\" expected"; break;
+ case 96: s = "\"then\" expected"; break;
+ case 97: s = "\"..\" expected"; break;
+ case 98: s = "\"forall\" expected"; break;
+ case 99: s = "\"\\u2200\" expected"; break;
+ case 100: s = "\"exists\" expected"; break;
+ case 101: s = "\"\\u2203\" expected"; break;
+ case 102: s = "\"::\" expected"; break;
+ case 103: s = "\"\\u2022\" expected"; break;
+ case 104: s = "??? expected"; break;
+ case 105: s = "invalid ClassMemberDecl"; break;
+ case 106: s = "invalid FunctionDecl"; break;
+ case 107: s = "invalid MethodDecl"; break;
+ case 108: s = "invalid MethodDecl"; break;
+ case 109: s = "invalid TypeAndToken"; break;
+ case 110: s = "invalid MethodSpec"; break;
+ case 111: s = "invalid MethodSpec"; break;
+ case 112: s = "invalid ReferenceType"; break;
+ case 113: s = "invalid FunctionSpec"; break;
+ case 114: s = "invalid FunctionBody"; break;
+ case 115: s = "invalid PossiblyWildFrameExpression"; break;
+ case 116: s = "invalid PossiblyWildExpression"; break;
+ case 117: s = "invalid MatchOrExpr"; break;
+ case 118: s = "invalid OneStmt"; break;
+ case 119: s = "invalid OneStmt"; break;
+ case 120: s = "invalid UpdateStmt"; break;
+ case 121: s = "invalid IfStmt"; break;
+ case 122: s = "invalid IfStmt"; break;
+ case 123: s = "invalid WhileStmt"; break;
+ case 124: s = "invalid ForeachStmt"; break;
+ case 125: s = "invalid Lhs"; break;
+ case 126: s = "invalid Rhs"; break;
+ case 127: s = "invalid Guard"; break;
+ case 128: s = "invalid AttributeArg"; break;
+ case 129: s = "invalid EquivOp"; break;
+ case 130: s = "invalid ImpliesOp"; break;
+ case 131: s = "invalid AndOp"; break;
+ case 132: s = "invalid OrOp"; break;
+ case 133: s = "invalid RelOp"; break;
+ case 134: s = "invalid AddOp"; break;
+ case 135: s = "invalid UnaryExpression"; break;
+ case 136: s = "invalid MulOp"; break;
+ case 137: s = "invalid NegOp"; break;
+ case 138: s = "invalid EndlessExpression"; break;
+ case 139: s = "invalid Suffix"; break;
+ case 140: s = "invalid Suffix"; break;
+ case 141: s = "invalid Suffix"; break;
case 142: s = "invalid ConstAtomExpression"; break;
case 143: s = "invalid QuantifierGuts"; break;
- case 144: s = "invalid ObjectExpression"; break;
- case 145: s = "invalid SelectOrCallSuffix"; break;
- case 146: s = "invalid SelectOrCallSuffix"; break;
- case 147: s = "invalid SelectOrCallSuffix"; break;
- case 148: s = "invalid Forall"; break;
- case 149: s = "invalid Exists"; break;
- case 150: s = "invalid AttributeOrTrigger"; break;
- case 151: s = "invalid QSep"; break;
+ case 144: s = "invalid Forall"; break;
+ case 145: s = "invalid Exists"; break;
+ case 146: s = "invalid AttributeOrTrigger"; break;
+ case 147: s = "invalid QSep"; break;
default: s = "error " + n; break;
}
diff --git a/Dafny/Printer.cs b/Dafny/Printer.cs
index 2dd2724f..5ee2f0c9 100644
--- a/Dafny/Printer.cs
+++ b/Dafny/Printer.cs
@@ -152,16 +152,17 @@ namespace Microsoft.Dafny {
Contract.Requires(dt != null);
Indent(indent);
PrintClassMethodHelper("datatype", dt.Attributes, dt.Name, dt.TypeArgs);
- if (dt.Ctors.Count == 0) {
- wr.WriteLine(" { }");
- } else {
- wr.WriteLine(" {");
- int ind = indent + IndentAmount;
- foreach (DatatypeCtor ctor in dt.Ctors) {
- PrintCtor(ctor, ind);
+ wr.Write(" = ");
+ string sep = "";
+ foreach (DatatypeCtor ctor in dt.Ctors) {
+ wr.Write(sep);
+ PrintClassMethodHelper("", ctor.Attributes, ctor.Name, new List<TypeParameter>());
+ if (ctor.Formals.Count != 0) {
+ PrintFormals(ctor.Formals);
}
- Indent(indent); wr.WriteLine("}");
+ sep = " | ";
}
+ wr.WriteLine(";");
}
public void PrintAttributes(Attributes a) {
@@ -245,16 +246,6 @@ namespace Microsoft.Dafny {
}
}
- public void PrintCtor(DatatypeCtor ctor, int indent) {
- Contract.Requires(ctor != null);
- Indent(indent);
- PrintClassMethodHelper("", ctor.Attributes, ctor.Name, ctor.TypeArgs);
- if (ctor.Formals.Count != 0) {
- PrintFormals(ctor.Formals);
- }
- wr.WriteLine(";");
- }
-
// ----------------------------- PrintMethod -----------------------------
const int IndentAmount = 2;
@@ -396,6 +387,13 @@ namespace Microsoft.Dafny {
/// </summary>
public void PrintStatement(Statement stmt, int indent) {
Contract.Requires(stmt != null);
+ for (LabelNode label = stmt.Labels; label != null; label = label.Next) {
+ if (label.Label != null) {
+ wr.WriteLine("label {0}:", label.Label);
+ Indent(indent);
+ }
+ }
+
if (stmt is AssertStmt) {
wr.Write("assert ");
PrintExpression(((AssertStmt)stmt).Expr);
@@ -406,26 +404,23 @@ namespace Microsoft.Dafny {
PrintExpression(((AssumeStmt)stmt).Expr);
wr.Write(";");
- } else if (stmt is UseStmt) {
- wr.Write("use ");
- PrintExpression(((UseStmt)stmt).Expr);
- wr.Write(";");
-
} else if (stmt is PrintStmt) {
PrintStmt s = (PrintStmt)stmt;
wr.Write("print");
PrintAttributeArgs(s.Args);
wr.Write(";");
- } else if (stmt is LabelStmt) {
- wr.Write("label {0}:", ((LabelStmt)stmt).Label);
-
} else if (stmt is BreakStmt) {
BreakStmt s = (BreakStmt)stmt;
- if (s.TargetLabel == null) {
- wr.Write("break;");
- } else {
+ if (s.TargetLabel != null) {
wr.Write("break {0};", s.TargetLabel);
+ } else {
+ string sep = "";
+ for (int i = 0; i < s.BreakCount; i++) {
+ wr.Write("{0}break", sep);
+ sep = " ";
+ }
+ wr.Write(";");
}
} else if (stmt is ReturnStmt) {
@@ -449,13 +444,7 @@ namespace Microsoft.Dafny {
wr.Write("ghost ");
}
wr.Write("var {0}", s.Name);
- if (s.OptionalType != null) {
- PrintType(": ", s.OptionalType);
- }
- if (s.Rhs != null) {
- wr.Write(" := ");
- PrintDeterminedRhs(s.Rhs);
- }
+ PrintType(": ", s.OptionalType);
wr.Write(";");
} else if (stmt is CallStmt) {
@@ -470,7 +459,7 @@ namespace Microsoft.Dafny {
}
wr.Write(" := ");
}
- if (!(s.Receiver is ThisExpr)) {
+ if (!(s.Receiver is ImplicitThisExpr)) {
PrintExpr(s.Receiver, 0x70, false, false, -1);
wr.Write(".");
}
@@ -554,7 +543,7 @@ namespace Microsoft.Dafny {
wr.WriteLine();
}
Indent(ind);
- PrintStatement(s.BodyAssign, ind);
+ PrintStatement(s.GivenBody, ind);
wr.WriteLine();
Indent(indent);
wr.Write("}");
@@ -584,8 +573,49 @@ namespace Microsoft.Dafny {
}
}
Indent(indent);
- wr.WriteLine("}");
-
+ wr.Write("}");
+
+ } else if (stmt is UpdateStmt) {
+ var s = (UpdateStmt)stmt;
+ string sep = "";
+ foreach (var lhs in s.Lhss) {
+ wr.Write(sep);
+ PrintExpression(lhs);
+ sep = ", ";
+ }
+ if (s.Lhss.Count != 0) {
+ sep = " := ";
+ }
+ foreach (var rhs in s.Rhss) {
+ wr.Write(sep);
+ PrintDeterminedRhs(rhs);
+ sep = ", ";
+ }
+ wr.Write(";");
+
+ } else if (stmt is VarDeclStmt) {
+ var s = (VarDeclStmt)stmt;
+ if (s.Lhss[0].IsGhost) {
+ wr.Write("ghost ");
+ }
+ wr.Write("var ");
+ string sep = "";
+ foreach (var lhs in s.Lhss) {
+ wr.Write("{0}{1}", sep, lhs.Name);
+ PrintType(": ", lhs.OptionalType);
+ sep = ", ";
+ }
+ if (s.Update != null) {
+ wr.Write(" := ");
+ sep = "";
+ foreach (var rhs in s.Update.Rhss) {
+ wr.Write(sep);
+ PrintDeterminedRhs(rhs);
+ sep = ", ";
+ }
+ }
+ wr.Write(";");
+
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
}
@@ -829,12 +859,12 @@ namespace Microsoft.Dafny {
FunctionCallExpr e = (FunctionCallExpr)expr;
// determine if parens are needed
int opBindingStrength = 0x70;
- bool parensNeeded = !(e.Receiver is ThisExpr) &&
+ bool parensNeeded = !(e.Receiver is ImplicitThisExpr) &&
opBindingStrength < contextBindingStrength ||
(fragileContext && opBindingStrength == contextBindingStrength);
if (parensNeeded) { wr.Write("("); }
- if (!(e.Receiver is ThisExpr)) {
+ if (!(e.Receiver is ImplicitThisExpr)) {
PrintExpr(e.Receiver, opBindingStrength, false, false, -1);
wr.Write(".");
}
@@ -949,7 +979,25 @@ namespace Microsoft.Dafny {
PrintExpr(e.E1, opBindingStrength, fragileRightContext, parensNeeded || isRightmost, -1);
}
if (parensNeeded) { wr.Write(")"); }
-
+
+ } else if (expr is ChainingExpression) {
+ var e = (ChainingExpression)expr;
+ // determine if parens are needed
+ int opBindingStrength = 0x30;
+ int opBS = opBindingStrength & 0xF8;
+ int ctxtBS = contextBindingStrength & 0xF8;
+ bool parensNeeded = opBS < ctxtBS ||
+ (opBS == ctxtBS && (opBindingStrength != contextBindingStrength || fragileContext));
+
+ if (parensNeeded) { wr.Write("("); }
+ PrintExpr(e.Operands[0], opBindingStrength, true, false, -1);
+ for (int i = 0; i < e.Operators.Count; i++) {
+ string op = BinaryExpr.OpcodeString(e.Operators[i]);
+ wr.Write(" {0} ", op);
+ PrintExpr(e.Operands[i+1], opBindingStrength, true, i == e.Operators.Count - 1 && (parensNeeded || isRightmost), -1);
+ }
+ if (parensNeeded) { wr.Write(")"); }
+
} else if (expr is QuantifierExpr) {
QuantifierExpr e = (QuantifierExpr)expr;
bool parensNeeded = !isRightmost;
@@ -1016,6 +1064,24 @@ namespace Microsoft.Dafny {
PrintExpression(ite.Els);
if (parensNeeded) { wr.Write(")"); }
+ } else if (expr is ParensExpression) {
+ var e = (ParensExpression)expr;
+ // printing of parentheses is done optimally, not according to the parentheses in the given program
+ PrintExpr(e.E, contextBindingStrength, fragileContext, isRightmost, indent);
+
+ } else if (expr is IdentifierSequence) {
+ var e = (IdentifierSequence)expr;
+ string sep = "";
+ foreach (var id in e.Tokens) {
+ wr.Write("{0}{1}", sep, id.val);
+ sep = ".";
+ }
+ if (e.Arguments != null) {
+ wr.Write("(");
+ PrintExpressionList(e.Arguments);
+ wr.Write(")");
+ }
+
} else if (expr is MatchExpr) {
Contract.Assert(false); throw new cce.UnreachableException(); // MatchExpr is an extended expression and should be printed only using PrintExtendedExpr
} else {
diff --git a/Dafny/Resolver.cs b/Dafny/Resolver.cs
index 3549d0db..96907777 100644
--- a/Dafny/Resolver.cs
+++ b/Dafny/Resolver.cs
@@ -48,6 +48,7 @@ namespace Microsoft.Dafny {
readonly Dictionary<string/*!*/,TopLevelDecl/*!*/>/*!*/ classes = new Dictionary<string/*!*/,TopLevelDecl/*!*/>();
readonly Dictionary<ClassDecl/*!*/,Dictionary<string/*!*/,MemberDecl/*!*/>/*!*/>/*!*/ classMembers = new Dictionary<ClassDecl/*!*/,Dictionary<string/*!*/,MemberDecl/*!*/>/*!*/>();
readonly Dictionary<DatatypeDecl/*!*/,Dictionary<string/*!*/,DatatypeCtor/*!*/>/*!*/>/*!*/ datatypeCtors = new Dictionary<DatatypeDecl/*!*/,Dictionary<string/*!*/,DatatypeCtor/*!*/>/*!*/>();
+ readonly Dictionary<string/*!*/, Tuple<DatatypeCtor, bool>> allDatatypeCtors = new Dictionary<string, Tuple<DatatypeCtor, bool>>();
readonly Graph<ModuleDecl/*!*/>/*!*/ importGraph = new Graph<ModuleDecl/*!*/>();
public Resolver(Program prog) {
@@ -205,6 +206,15 @@ namespace Microsoft.Dafny {
Error(ctor, "Duplicate datatype constructor name: {0}", ctor.Name);
} else {
ctors.Add(ctor.Name, ctor);
+ // also register the constructor name globally
+ Tuple<DatatypeCtor, bool> pair;
+ if (allDatatypeCtors.TryGetValue(ctor.Name, out pair)) {
+ // mark it as a duplicate
+ allDatatypeCtors[ctor.Name] = new Tuple<DatatypeCtor, bool>(pair.Item1, true);
+ } else {
+ // add new
+ allDatatypeCtors.Add(ctor.Name, new Tuple<DatatypeCtor, bool>(ctor, false));
+ }
}
}
}
@@ -267,6 +277,8 @@ namespace Microsoft.Dafny {
readonly Scope<TypeParameter>/*!*/ allTypeParameters = new Scope<TypeParameter>();
readonly Scope<IVariable>/*!*/ scope = new Scope<IVariable>();
readonly Scope<Statement>/*!*/ labeledStatements = new Scope<Statement>();
+ readonly List<Statement> loopStack = new List<Statement>(); // the enclosing loops (from which it is possible to break out)
+ readonly Dictionary<Statement, bool> inSpecOnlyContext = new Dictionary<Statement, bool>(); // invariant: domain contain union of the domains of "labeledStatements" and "loopStack"
/// <summary>
/// Assumes type parameters have already been pushed
@@ -411,7 +423,7 @@ namespace Microsoft.Dafny {
inv.Formals.Add(formal);
scope.Push(inv.Toks[i].val, formal);
}
- ResolveExpression(inv.Expr, false, true);
+ ResolveExpression(inv.Expr, false);
scope.PopMarker();
}
} else {
@@ -433,7 +445,6 @@ namespace Microsoft.Dafny {
ctor.EnclosingDatatype = dt;
allTypeParameters.PushMarker();
- ResolveTypeParameters(ctor.TypeArgs, true, ctor);
ResolveCtorSignature(ctor);
allTypeParameters.PopMarker();
@@ -524,16 +535,16 @@ namespace Microsoft.Dafny {
void ResolveAttributes(Attributes attrs, bool twoState) {
// order does not matter for resolution, so resolve them in reverse order
for (; attrs != null; attrs = attrs.Prev) {
- ResolveAttributeArgs(attrs.Args, twoState, true);
+ ResolveAttributeArgs(attrs.Args, twoState);
}
}
- void ResolveAttributeArgs(List<Attributes.Argument/*!*/>/*!*/ args, bool twoState, bool specContext) {
+ void ResolveAttributeArgs(List<Attributes.Argument/*!*/>/*!*/ args, bool twoState) {
Contract.Requires(args != null);
foreach (Attributes.Argument aa in args) {
Contract.Assert(aa != null);
if (aa.E != null) {
- ResolveExpression(aa.E, twoState, specContext);
+ ResolveExpression(aa.E, twoState);
}
}
}
@@ -542,7 +553,7 @@ namespace Microsoft.Dafny {
// order does not matter for resolution, so resolve them in reverse order
for (; trigs != null; trigs = trigs.Prev) {
foreach (Expression e in trigs.Terms) {
- ResolveExpression(e, twoState, true);
+ ResolveExpression(e, twoState);
}
}
}
@@ -603,7 +614,7 @@ namespace Microsoft.Dafny {
scope.Push(p.Name, p);
}
foreach (Expression r in f.Req) {
- ResolveExpression(r, false, true);
+ ResolveExpression(r, false);
Contract.Assert(r.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(r.Type, Type.Bool)) {
Error(r, "Precondition must be a boolean (got {0})", r.Type);
@@ -613,19 +624,22 @@ namespace Microsoft.Dafny {
ResolveFrameExpression(fr, "reads");
}
foreach (Expression r in f.Ens) {
- ResolveExpression(r, false, true); // since this is a function, the postcondition is still a one-state predicate
+ ResolveExpression(r, false); // since this is a function, the postcondition is still a one-state predicate
Contract.Assert(r.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(r.Type, Type.Bool)) {
Error(r, "Postcondition must be a boolean (got {0})", r.Type);
}
}
foreach (Expression r in f.Decreases) {
- ResolveExpression(r, false, true);
+ ResolveExpression(r, false);
// any type is fine
}
if (f.Body != null) {
List<IVariable> matchVarContext = new List<IVariable>(f.Formals);
- ResolveExpression(f.Body, false, f.IsGhost, matchVarContext);
+ ResolveExpression(f.Body, false, matchVarContext);
+ if (!f.IsGhost) {
+ CheckIsNonGhost(f.Body);
+ }
Contract.Assert(f.Body.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(f.Body.Type, f.ResultType)) {
Error(f, "Function body type mismatch (expected {0}, got {1})", f.ResultType, f.Body.Type);
@@ -638,7 +652,7 @@ namespace Microsoft.Dafny {
void ResolveFrameExpression(FrameExpression fe, string kind) {
Contract.Requires(fe != null);
Contract.Requires(kind != null);
- ResolveExpression(fe.E, false, true);
+ ResolveExpression(fe.E, false);
Type t = fe.E.Type;
Contract.Assert(t != null); // follows from postcondition of ResolveExpression
if (t is CollectionType) {
@@ -707,7 +721,7 @@ namespace Microsoft.Dafny {
// Start resolving specification...
foreach (MaybeFreeExpression e in m.Req) {
- ResolveExpression(e.E, false, true);
+ ResolveExpression(e.E, false);
Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.E.Type, Type.Bool)) {
Error(e.E, "Precondition must be a boolean (got {0})", e.E.Type);
@@ -717,7 +731,7 @@ namespace Microsoft.Dafny {
ResolveFrameExpression(fe, "modifies");
}
foreach (Expression e in m.Decreases) {
- ResolveExpression(e, false, true);
+ ResolveExpression(e, false);
// any type is fine
}
@@ -730,7 +744,7 @@ namespace Microsoft.Dafny {
// ... continue resolving specification
foreach (MaybeFreeExpression e in m.Ens) {
- ResolveExpression(e.E, true, true);
+ ResolveExpression(e.E, true);
Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.E.Type, Type.Bool)) {
Error(e.E, "Postcondition must be a boolean (got {0})", e.E.Type);
@@ -1106,28 +1120,18 @@ namespace Microsoft.Dafny {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected restricted-proxy type
}
}
-
+
+ /// <summary>
+ /// "specContextOnly" means that the statement must be erasable, that is, it should be okay to omit it
+ /// at run time. That means it must not have any side effects on non-ghost variables, for example.
+ /// </summary>
public void ResolveStatement(Statement stmt, bool specContextOnly, Method method) {
Contract.Requires(stmt != null);
Contract.Requires(method != null);
- Contract.Requires(!(stmt is LabelStmt)); // these should be handled inside lists of statements
- if (stmt is UseStmt) {
- UseStmt s = (UseStmt)stmt;
- s.IsGhost = true;
- ResolveExpression(s.Expr, true, true);
- Contract.Assert(s.Expr.Type != null); // follows from postcondition of ResolveExpression
- Expression expr = s.Expr;
- while (true) {
- if (expr is OldExpr) {
- expr = ((OldExpr)expr).E;
- } else {
- break;
- }
- }
- } else if (stmt is PredicateStmt) {
+ if (stmt is PredicateStmt) {
PredicateStmt s = (PredicateStmt)stmt;
s.IsGhost = true;
- ResolveExpression(s.Expr, true, true);
+ ResolveExpression(s.Expr, true);
Contract.Assert(s.Expr.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(s.Expr.Type, Type.Bool)) {
Error(s.Expr, "condition is expected to be of type {0}, but is {1}", Type.Bool, s.Expr.Type);
@@ -1135,48 +1139,176 @@ namespace Microsoft.Dafny {
} else if (stmt is PrintStmt) {
PrintStmt s = (PrintStmt)stmt;
- ResolveAttributeArgs(s.Args, false, false);
+ ResolveAttributeArgs(s.Args, false);
if (specContextOnly) {
Error(stmt, "print statement is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
}
} else if (stmt is BreakStmt) {
- BreakStmt s = (BreakStmt)stmt;
+ var s = (BreakStmt)stmt;
if (s.TargetLabel != null) {
Statement target = labeledStatements.Find(s.TargetLabel);
if (target == null) {
Error(s, "break label is undefined or not in scope: {0}", s.TargetLabel);
} else {
s.TargetStmt = target;
+ bool targetIsLoop = target is WhileStmt || target is AlternativeLoopStmt;
+ if (specContextOnly && !s.TargetStmt.IsGhost && !inSpecOnlyContext[s.TargetStmt]) {
+ Error(stmt, "ghost-context break statement is not allowed to break out of non-ghost " + (targetIsLoop ? "loop" : "structure"));
+ }
+ }
+ } else {
+ if (loopStack.Count < s.BreakCount) {
+ Error(s, "trying to break out of more loop levels than there are enclosing loops");
+ } else {
+ Statement target = loopStack[loopStack.Count - s.BreakCount];
+ if (target.Labels == null) {
+ // make sure there is a label, because the compiler and translator will want to see a unique ID
+ target.Labels = new LabelNode(target.Tok, null, null);
+ }
+ s.TargetStmt = target;
+ if (specContextOnly && !target.IsGhost && !inSpecOnlyContext[target]) {
+ Error(stmt, "ghost-context break statement is not allowed to break out of non-ghost loop");
+ }
}
- }
- if (specContextOnly) {
- Error(stmt, "break statement is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
}
} else if (stmt is ReturnStmt) {
- if (specContextOnly) {
+ if (specContextOnly && !method.IsGhost) {
Error(stmt, "return statement is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
}
+
+ } else if (stmt is UpdateStmt) {
+ var s = (UpdateStmt)stmt;
+ int prevErrorCount = ErrorCount;
+ // First, resolve all LHS's and expression-looking RHS's. When resolving these, allow ghosts for now, but enforce restrictions later.
+ foreach (var lhs in s.Lhss) {
+ if (lhs is SeqSelectExpr) {
+ ResolveSeqSelectExpr((SeqSelectExpr)lhs, true, true);
+ } else {
+ ResolveExpression(lhs, true);
+ }
+ }
+ IToken firstEffectfulRhs = null;
+ CallRhs callRhs = null;
+ foreach (var rhs in s.Rhss) {
+ bool isEffectful;
+ if (rhs is TypeRhs) {
+ ResolveTypeRhs((TypeRhs)rhs, stmt, specContextOnly, method);
+ isEffectful = true;
+ } else {
+ var er = (ExprRhs)rhs;
+ if (er.Expr is IdentifierSequence) {
+ var cRhs = ResolveIdentifierSequence((IdentifierSequence)er.Expr, true, true);
+ isEffectful = cRhs != null;
+ callRhs = callRhs ?? cRhs;
+ } else if (er.Expr is FunctionCallExpr) {
+ var cRhs = ResolveFunctionCallExpr((FunctionCallExpr)er.Expr, true, true);
+ isEffectful = cRhs != null;
+ callRhs = callRhs ?? cRhs;
+ } else {
+ ResolveExpression(er.Expr, true);
+ isEffectful = false;
+ }
+ }
+ if (isEffectful && firstEffectfulRhs == null) {
+ firstEffectfulRhs = rhs.Tok;
+ }
+ }
+ // check for duplicate identifiers on the left (full duplication checking for references and the like is done during verification)
+ Dictionary<string, object> lhsNameSet = new Dictionary<string, object>();
+ foreach (var lhs in s.Lhss) {
+ var ie = lhs.Resolved as IdentifierExpr;
+ if (ie != null) {
+ if (lhsNameSet.ContainsKey(ie.Name)) {
+ Error(s, "Duplicate variable in left-hand side of call statement: {0}", ie.Name);
+ } else {
+ lhsNameSet.Add(ie.Name, null);
+ }
+ }
+ }
+ // figure out what kind of UpdateStmt this is
+ if (firstEffectfulRhs == null) {
+ if (s.Lhss.Count == 0) {
+ Contract.Assert(s.Rhss.Count == 1); // guaranteed by the parser
+ Error(s, "expected method call, found expression");
+ } else if (s.Lhss.Count != s.Rhss.Count) {
+ Error(s, "the number of left-hand sides ({0}) and right-hand sides ({1}) must match for a multi-assignment", s.Lhss.Count, s.Rhss.Count);
+ } else if (ErrorCount == prevErrorCount) {
+ for (int i = 0; i < s.Lhss.Count; i++) {
+ var a = new AssignStmt(s.Tok, s.Lhss[i].Resolved, s.Rhss[i]);
+ s.ResolvedStatements.Add(a);
+ }
+ if (s.Lhss.Count != 1) {
+ Error(s, "multi-assignments not yet supported"); // TODO
+ }
+ }
+ } else {
+ // if there was an effectful RHS, that must be the only RHS
+ if (s.Rhss.Count != 1) {
+ Error(firstEffectfulRhs, "an update statement is allowed an effectful RHS only if there is just one RHS");
+ } else if (callRhs == null) {
+ // must be a single TypeRhs
+ if (s.Lhss.Count != 1) {
+ Contract.Assert(2 <= s.Lhss.Count); // the parser allows 0 Lhss only if the whole statement looks like an expression (not a TypeRhs)
+ Error(s.Lhss[1].tok, "the number of left-hand sides ({0}) and right-hand sides ({1}) must match for a multi-assignment", s.Lhss.Count, s.Rhss.Count);
+ } else if (ErrorCount == prevErrorCount) {
+ var a = new AssignStmt(s.Tok, s.Lhss[0].Resolved, s.Rhss[0]);
+ s.ResolvedStatements.Add(a);
+ }
+ } else {
+ // a call statement
+ if (ErrorCount == prevErrorCount) {
+ var idLhss = new List<IdentifierExpr>();
+ foreach (var ll in s.Lhss) {
+ var ie = ll.Resolved as IdentifierExpr; // TODO: the CallStmt should handle all LHS's, not just identifier expressions
+ if (ie == null) {
+ Error(ll, "actual out-parameters of calls must be variables, not fields");
+ } else {
+ idLhss.Add(ie);
+ }
+ }
+ var a = new CallStmt(callRhs.Tok, idLhss, callRhs.Receiver, callRhs.MethodName, callRhs.Args);
+ s.ResolvedStatements.Add(a);
+ }
+ }
+ }
+
+ foreach (var a in s.ResolvedStatements) {
+ ResolveStatement(a, specContextOnly, method);
+ }
+
+ } else if (stmt is VarDeclStmt) {
+ var s = (VarDeclStmt)stmt;
+ foreach (var vd in s.Lhss) {
+ ResolveStatement(vd, specContextOnly, method);
+ s.ResolvedStatements.Add(vd);
+ }
+ if (s.Update != null) {
+ ResolveStatement(s.Update, specContextOnly, method);
+ s.ResolvedStatements.Add(s.Update);
+ }
+
} else if (stmt is AssignStmt) {
AssignStmt s = (AssignStmt)stmt;
int prevErrorCount = ErrorCount;
if (s.Lhs is SeqSelectExpr) {
- ResolveSeqSelectExpr((SeqSelectExpr)s.Lhs, true, false, true);
+ ResolveSeqSelectExpr((SeqSelectExpr)s.Lhs, true, true); // allow ghosts for now, tighted up below
} else {
- ResolveExpression(s.Lhs, true, true); // allow ghosts for now, but see FieldSelectExpr LHS case below
+ ResolveExpression(s.Lhs, true); // allow ghosts for now, tighted up below
}
bool lhsResolvedSuccessfully = ErrorCount == prevErrorCount;
Contract.Assert(s.Lhs.Type != null); // follows from postcondition of ResolveExpression
// check that LHS denotes a mutable variable or a field
bool lvalueIsGhost = false;
- if (s.Lhs is IdentifierExpr) {
- IVariable var = ((IdentifierExpr)s.Lhs).Var;
+ var lhs = s.Lhs.Resolved;
+ if (lhs is IdentifierExpr) {
+ IVariable var = ((IdentifierExpr)lhs).Var;
if (var == null) {
// the LHS didn't resolve correctly; some error would already have been reported
} else {
- lvalueIsGhost = var.IsGhost;
+ lvalueIsGhost = var.IsGhost || method.IsGhost;
if (!var.IsMutable) {
Error(stmt, "LHS of assignment must denote a mutable variable or field");
}
@@ -1184,8 +1316,8 @@ namespace Microsoft.Dafny {
Error(stmt, "Assignment to non-ghost variable is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
}
}
- } else if (s.Lhs is FieldSelectExpr) {
- FieldSelectExpr fse = (FieldSelectExpr)s.Lhs;
+ } else if (lhs is FieldSelectExpr) {
+ var fse = (FieldSelectExpr)lhs;
if (fse.Field != null) { // otherwise, an error was reported above
lvalueIsGhost = fse.Field.IsGhost;
if (!lvalueIsGhost) {
@@ -1203,24 +1335,24 @@ namespace Microsoft.Dafny {
Error(stmt, "LHS of assignment does not denote a mutable field");
}
}
- } else if (s.Lhs is SeqSelectExpr) {
- SeqSelectExpr lhs = (SeqSelectExpr)s.Lhs;
+ } else if (lhs is SeqSelectExpr) {
+ var slhs = (SeqSelectExpr)lhs;
// LHS is fine, provided the "sequence" is really an array
if (lhsResolvedSuccessfully) {
- Contract.Assert(lhs.Seq.Type != null);
+ Contract.Assert(slhs.Seq.Type != null);
Type elementType = new InferredTypeProxy();
- if (!UnifyTypes(lhs.Seq.Type, builtIns.ArrayType(1, elementType))) {
- Error(lhs.Seq, "LHS of array assignment must denote an array element (found {0})", lhs.Seq.Type);
+ if (!UnifyTypes(slhs.Seq.Type, builtIns.ArrayType(1, elementType))) {
+ Error(slhs.Seq, "LHS of array assignment must denote an array element (found {0})", slhs.Seq.Type);
}
if (specContextOnly) {
Error(stmt, "Assignment to array element is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
}
- if (!lhs.SelectOne && !(s.Rhs is ExprRhs)) {
+ if (!slhs.SelectOne && !(s.Rhs is ExprRhs)) {
Error(stmt, "Assignment to range of array elements must have a simple expression RHS; try using a temporary local variable");
}
}
- } else if (s.Lhs is MultiSelectExpr) {
+ } else if (lhs is MultiSelectExpr) {
if (specContextOnly) {
Error(stmt, "Assignment to array element is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)");
}
@@ -1231,22 +1363,37 @@ namespace Microsoft.Dafny {
s.IsGhost = lvalueIsGhost;
Type lhsType = s.Lhs.Type;
- if (s.Lhs is SeqSelectExpr && !((SeqSelectExpr)s.Lhs).SelectOne) {
+ if (lhs is SeqSelectExpr && !((SeqSelectExpr)lhs).SelectOne) {
Contract.Assert(lhsType.IsArrayType);
lhsType = UserDefinedType.ArrayElementType(lhsType);
}
if (s.Rhs is ExprRhs) {
ExprRhs rr = (ExprRhs)s.Rhs;
- ResolveExpression(rr.Expr, true, lvalueIsGhost);
+ ResolveExpression(rr.Expr, true);
+ if (!lvalueIsGhost) {
+ CheckIsNonGhost(rr.Expr);
+ }
Contract.Assert(rr.Expr.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(lhsType, rr.Expr.Type)) {
- Error(stmt, "RHS (of type {0}) not assignable to LHS (of type {1})", rr.Expr.Type, s.Lhs.Type);
+ Error(stmt, "RHS (of type {0}) not assignable to LHS (of type {1})", rr.Expr.Type, lhsType);
}
} else if (s.Rhs is TypeRhs) {
TypeRhs rr = (TypeRhs)s.Rhs;
Type t = ResolveTypeRhs(rr, stmt, lvalueIsGhost, method);
+ if (!lvalueIsGhost) {
+ if (rr.ArrayDimensions != null) {
+ foreach (var dim in rr.ArrayDimensions) {
+ CheckIsNonGhost(dim);
+ }
+ }
+ if (rr.InitCall != null) {
+ foreach (var arg in rr.InitCall.Args) {
+ CheckIsNonGhost(arg);
+ }
+ }
+ }
if (!UnifyTypes(lhsType, t)) {
- Error(stmt, "type {0} is not assignable to LHS (of type {1})", t, s.Lhs.Type);
+ Error(stmt, "type {0} is not assignable to LHS (of type {1})", t, lhsType);
}
} else if (s.Rhs is HavocRhs) {
// nothing else to do
@@ -1260,25 +1407,6 @@ namespace Microsoft.Dafny {
ResolveType(stmt.Tok, s.OptionalType);
s.type = s.OptionalType;
}
- if (s.Rhs != null) {
- Type rhsType;
- if (s.Rhs is ExprRhs) {
- ExprRhs rr = (ExprRhs)s.Rhs;
- ResolveExpression(rr.Expr, true, s.IsGhost);
- Contract.Assert(rr.Expr.Type != null); // follows from postcondition of ResolveExpression
- rhsType = rr.Expr.Type;
- } else if (s.Rhs is TypeRhs) {
- TypeRhs rr = (TypeRhs)s.Rhs;
- rhsType = ResolveTypeRhs(rr, stmt, s.IsGhost, method);
- } else {
- Contract.Assert(false); throw new cce.UnreachableException(); // unexpected RHS
- }
- if (s.OptionalType == null) {
- s.type = rhsType;
- } else if (!UnifyTypes(s.OptionalType, rhsType)) {
- Error(stmt, "initialization RHS (of type {0}) not assignable to variable (of type {1})", rhsType, s.OptionalType);
- }
- }
// now that the declaration has been processed, add the name to the scope
if (!scope.Push(s.Name, s)) {
Error(s, "Duplicate local-variable name: {0}", s.Name);
@@ -1302,7 +1430,7 @@ namespace Microsoft.Dafny {
bool branchesAreSpecOnly = specContextOnly;
if (s.Guard != null) {
int prevErrorCount = ErrorCount;
- ResolveExpression(s.Guard, true, true);
+ ResolveExpression(s.Guard, true);
Contract.Assert(s.Guard.Type != null); // follows from postcondition of ResolveExpression
bool successfullyResolved = ErrorCount == prevErrorCount;
if (!UnifyTypes(s.Guard.Type, Type.Bool)) {
@@ -1320,14 +1448,14 @@ namespace Microsoft.Dafny {
} else if (stmt is AlternativeStmt) {
var s = (AlternativeStmt)stmt;
- s.IsGhost = ResolveAlternatives(s.Alternatives, specContextOnly, method);
+ s.IsGhost = ResolveAlternatives(s.Alternatives, specContextOnly, null, method);
} else if (stmt is WhileStmt) {
WhileStmt s = (WhileStmt)stmt;
bool bodyMustBeSpecOnly = specContextOnly;
if (s.Guard != null) {
int prevErrorCount = ErrorCount;
- ResolveExpression(s.Guard, true, true);
+ ResolveExpression(s.Guard, true);
Contract.Assert(s.Guard.Type != null); // follows from postcondition of ResolveExpression
bool successfullyResolved = ErrorCount == prevErrorCount;
if (!UnifyTypes(s.Guard.Type, Type.Bool)) {
@@ -1338,34 +1466,39 @@ namespace Microsoft.Dafny {
}
}
foreach (MaybeFreeExpression inv in s.Invariants) {
- ResolveExpression(inv.E, true, true);
+ ResolveExpression(inv.E, true);
Contract.Assert(inv.E.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(inv.E.Type, Type.Bool)) {
Error(inv.E, "invariant is expected to be of type {0}, but is {1}", Type.Bool, inv.E.Type);
}
}
foreach (Expression e in s.Decreases) {
- ResolveExpression(e, true, true);
+ ResolveExpression(e, true);
if (bodyMustBeSpecOnly && e is WildcardExpr) {
Error(e, "'decreases *' is not allowed on ghost loops");
}
// any type is fine
}
s.IsGhost = bodyMustBeSpecOnly;
+ loopStack.Add(s); // push
+ if (s.Labels == null) { // otherwise, "s" is already in "inSpecOnlyContext" map
+ inSpecOnlyContext.Add(s, specContextOnly);
+ }
ResolveStatement(s.Body, bodyMustBeSpecOnly, method);
+ loopStack.RemoveAt(loopStack.Count-1); // pop
} else if (stmt is AlternativeLoopStmt) {
var s = (AlternativeLoopStmt)stmt;
- s.IsGhost = ResolveAlternatives(s.Alternatives, specContextOnly, method);
+ s.IsGhost = ResolveAlternatives(s.Alternatives, specContextOnly, s, method);
foreach (MaybeFreeExpression inv in s.Invariants) {
- ResolveExpression(inv.E, true, true);
+ ResolveExpression(inv.E, true);
Contract.Assert(inv.E.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(inv.E.Type, Type.Bool)) {
Error(inv.E, "invariant is expected to be of type {0}, but is {1}", Type.Bool, inv.E.Type);
}
}
foreach (Expression e in s.Decreases) {
- ResolveExpression(e, true, true);
+ ResolveExpression(e, true);
if (s.IsGhost && e is WildcardExpr) {
Error(e, "'decreases *' is not allowed on ghost loops");
}
@@ -1375,7 +1508,7 @@ namespace Microsoft.Dafny {
} else if (stmt is ForeachStmt) {
ForeachStmt s = (ForeachStmt)stmt;
- ResolveExpression(s.Collection, true, true);
+ ResolveExpression(s.Collection, true);
Contract.Assert(s.Collection.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(s.Collection.Type, new CollectionTypeProxy(s.BoundVar.Type))) {
Error(s.Collection, "The type is expected to be a collection of {0} (instead got {1})", s.BoundVar.Type, s.Collection.Type);
@@ -1387,7 +1520,7 @@ namespace Microsoft.Dafny {
ResolveType(s.BoundVar.tok, s.BoundVar.Type);
int prevErrorCount = ErrorCount;
- ResolveExpression(s.Range, true, true);
+ ResolveExpression(s.Range, true);
Contract.Assert(s.Range.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(s.Range.Type, Type.Bool)) {
Error(s.Range, "range condition is expected to be of type {0}, but is {1}", Type.Bool, s.Range.Type);
@@ -1401,14 +1534,29 @@ namespace Microsoft.Dafny {
bool specOnly = specContextOnly ||
(successfullyResolvedCollectionAndRange && (UsesSpecFeatures(s.Collection) || UsesSpecFeatures(s.Range)));
s.IsGhost = specOnly;
- ResolveStatement(s.BodyAssign, specOnly, method);
+ ResolveStatement(s.GivenBody, specOnly, method);
// check for correct usage of BoundVar in LHS and RHS of this assignment
- FieldSelectExpr lhs = s.BodyAssign.Lhs as FieldSelectExpr;
- IdentifierExpr obj = lhs == null ? null : lhs.Obj as IdentifierExpr;
- if (obj != null && obj.Var == s.BoundVar) {
- // exemplary!
+ if (s.GivenBody is AssignStmt) {
+ s.BodyAssign = (AssignStmt)s.GivenBody;
+ } else if (s.GivenBody is ConcreteSyntaxStatement) {
+ var css = (ConcreteSyntaxStatement)s.GivenBody;
+ if (css.ResolvedStatements.Count == 1 && css.ResolvedStatements[0] is AssignStmt) {
+ s.BodyAssign = (AssignStmt)css.ResolvedStatements[0];
+ }
+ }
+ if (s.BodyAssign == null) {
+ Error(s, "update statement inside foreach must be a single assignment statement");
} else {
- Error(s, "assignment inside foreach must assign to a field of the bound variable of the foreach statement");
+ FieldSelectExpr lhs = s.BodyAssign.Lhs as FieldSelectExpr;
+ IdentifierExpr obj = lhs == null ? null : lhs.Obj as IdentifierExpr;
+ if (obj == null || obj.Var != s.BoundVar) {
+ Error(s, "assignment inside foreach must assign to a field of the bound variable of the foreach statement");
+ } else {
+ var rhs = s.BodyAssign.Rhs as ExprRhs;
+ if (rhs != null && rhs.Expr is UnaryExpr && ((UnaryExpr)rhs.Expr).Op == UnaryExpr.Opcode.SetChoose) {
+ Error(s, "foreach statement does not support 'choose' statements");
+ }
+ }
}
scope.PopMarker();
@@ -1417,7 +1565,7 @@ namespace Microsoft.Dafny {
MatchStmt s = (MatchStmt)stmt;
bool bodyIsSpecOnly = specContextOnly;
int prevErrorCount = ErrorCount;
- ResolveExpression(s.Source, true, true);
+ ResolveExpression(s.Source, true);
Contract.Assert(s.Source.Type != null); // follows from postcondition of ResolveExpression
bool successfullyResolved = ErrorCount == prevErrorCount;
if (!specContextOnly && successfullyResolved) {
@@ -1432,7 +1580,7 @@ namespace Microsoft.Dafny {
}
Dictionary<string,DatatypeCtor> ctors;
if (dtd == null) {
- Error(s.Source, "the type of the match source expression must be a datatype");
+ Error(s.Source, "the type of the match source expression must be a datatype (instead found {0})", s.Source.Type);
ctors = null;
} else {
Contract.Assert(sourceType != null); // dtd and sourceType are set together above
@@ -1467,12 +1615,6 @@ namespace Microsoft.Dafny {
}
}
scope.PushMarker();
- if (ctor != null) {
- // add the constructor's own type parameters to the substitution map
- foreach (TypeParameter p in ctor.TypeArgs) {
- subst.Add(p, new ParamTypeProxy(p));
- }
- }
int i = 0;
foreach (BoundVar v in mc.Arguments) {
if (!scope.Push(v.Name, v)) {
@@ -1513,7 +1655,7 @@ namespace Microsoft.Dafny {
}
}
- bool ResolveAlternatives(List<GuardedAlternative> alternatives, bool specContextOnly, Method method) {
+ bool ResolveAlternatives(List<GuardedAlternative> alternatives, bool specContextOnly, AlternativeLoopStmt loopToCatchBreaks, Method method) {
Contract.Requires(alternatives != null);
Contract.Requires(method != null);
@@ -1521,7 +1663,7 @@ namespace Microsoft.Dafny {
// first, resolve the guards, which tells us whether or not the entire statement is a ghost statement
foreach (var alternative in alternatives) {
int prevErrorCount = ErrorCount;
- ResolveExpression(alternative.Guard, true, true);
+ ResolveExpression(alternative.Guard, true);
Contract.Assert(alternative.Guard.Type != null); // follows from postcondition of ResolveExpression
bool successfullyResolved = ErrorCount == prevErrorCount;
if (!UnifyTypes(alternative.Guard.Type, Type.Bool)) {
@@ -1531,6 +1673,13 @@ namespace Microsoft.Dafny {
isGhost = isGhost || UsesSpecFeatures(alternative.Guard);
}
}
+
+ if (loopToCatchBreaks != null) {
+ loopStack.Add(loopToCatchBreaks); // push
+ if (loopToCatchBreaks.Labels == null) { // otherwise, "loopToCatchBreak" is already in "inSpecOnlyContext" map
+ inSpecOnlyContext.Add(loopToCatchBreaks, specContextOnly);
+ }
+ }
foreach (var alternative in alternatives) {
scope.PushMarker();
foreach (Statement ss in alternative.Body) {
@@ -1538,6 +1687,10 @@ namespace Microsoft.Dafny {
}
scope.PopMarker();
}
+ if (loopToCatchBreaks != null) {
+ loopStack.RemoveAt(loopStack.Count - 1); // pop
+ }
+
return isGhost;
}
@@ -1548,7 +1701,7 @@ namespace Microsoft.Dafny {
// resolve receiver, unless told otherwise
if (receiverType == null) {
- ResolveReceiver(s.Receiver, true, false);
+ ResolveReceiver(s.Receiver, true);
Contract.Assert(s.Receiver.Type != null); // follows from postcondition of ResolveExpression
receiverType = s.Receiver.Type;
}
@@ -1569,19 +1722,10 @@ namespace Microsoft.Dafny {
}
}
- // resolve any local variables declared here
- foreach (AutoVarDecl local in s.NewVars) {
- // first, fix up the local variables to be ghost variable if the corresponding formal out-parameter is a ghost
- if (s.IsGhost || callee != null && local.Index < callee.Outs.Count && callee.Outs[local.Index].IsGhost) {
- local.MakeGhost();
- }
- ResolveStatement(local, specContextOnly, method);
- }
-
// resolve left-hand side
Dictionary<string, object> lhsNameSet = new Dictionary<string, object>();
foreach (IdentifierExpr lhs in s.Lhs) {
- ResolveExpression(lhs, true, true);
+ ResolveExpression(lhs, true);
if (lhsNameSet.ContainsKey(lhs.Name)) {
Error(s, "Duplicate variable in left-hand side of call statement: {0}", lhs.Name);
} else {
@@ -1589,10 +1733,16 @@ namespace Microsoft.Dafny {
}
}
// resolve arguments
+ if (!s.IsGhost) {
+ CheckIsNonGhost(s.Receiver);
+ }
int j = 0;
foreach (Expression e in s.Args) {
bool allowGhost = s.IsGhost || callee == null || callee.Ins.Count <= j || callee.Ins[j].IsGhost;
- ResolveExpression(e, true, allowGhost);
+ ResolveExpression(e, true);
+ if (!allowGhost) {
+ CheckIsNonGhost(e);
+ }
j++;
}
@@ -1612,11 +1762,15 @@ namespace Microsoft.Dafny {
if (callee.IsStatic) {
Error(s.Tok, "a method called as an initialization method must not be 'static'");
}
- } else if (!scope.AllowInstance && !callee.IsStatic && s.Receiver is ThisExpr) {
- // The call really needs an instance, but that instance is given as 'this', which is not
- // available in this context. For more details, see comment in the resolution of a
- // FunctionCallExpr.
- Error(s.Receiver, "'this' is not allowed in a 'static' context");
+ } else if (!callee.IsStatic) {
+ if (!scope.AllowInstance && s.Receiver is ThisExpr) {
+ // The call really needs an instance, but that instance is given as 'this', which is not
+ // available in this context. For more details, see comment in the resolution of a
+ // FunctionCallExpr.
+ Error(s.Receiver, "'this' is not allowed in a 'static' context");
+ } else if (s.Receiver is StaticReceiverExpr) {
+ Error(s.Receiver, "call to instance method requires an instance");
+ }
}
// build the type substitution map
Dictionary<TypeParameter, Type> subst = new Dictionary<TypeParameter, Type>();
@@ -1639,7 +1793,11 @@ namespace Microsoft.Dafny {
if (!UnifyTypes(cce.NonNull(lhs.Type), st)) {
Error(s, "incorrect type of method out-parameter {0} (expected {1}, got {2})", i, st, lhs.Type);
} else if (!specContextOnly && !cce.NonNull(lhs.Var).IsGhost && (s.IsGhost || callee.Outs[i].IsGhost)) {
- Error(s, "actual out-parameter {0} is required to be a ghost variable", i);
+ if (lhs is AutoGhostIdentifierExpr && lhs.Var is VarDecl) {
+ ((VarDecl)lhs.Var).MakeGhost();
+ } else {
+ Error(s, "actual out-parameter {0} is required to be a ghost variable", i);
+ }
}
}
@@ -1660,55 +1818,65 @@ namespace Microsoft.Dafny {
}
}
}
-
+
void ResolveBlockStatement(BlockStmt blockStmt, bool specContextOnly, Method method)
{
Contract.Requires(blockStmt != null);
Contract.Requires(method != null);
- int labelsToPop = 0;
+
foreach (Statement ss in blockStmt.Body) {
- if (ss is LabelStmt) {
- LabelStmt ls = (LabelStmt)ss;
- labeledStatements.PushMarker();
- bool b = labeledStatements.Push(ls.Label, ls);
- Contract.Assert(b); // since we just pushed a marker, we expect the Push to succeed
- labelsToPop++;
- } else {
- ResolveStatement(ss, specContextOnly, method);
- for (; 0 < labelsToPop; labelsToPop--) { labeledStatements.PopMarker(); }
+ labeledStatements.PushMarker();
+ // push labels
+ for (var lnode = ss.Labels; lnode != null; lnode = lnode.Next) {
+ Contract.Assert(lnode.Label != null); // LabelNode's with .Label==null are added only during resolution of the break statements with 'stmt' as their target, which hasn't happened yet
+ var prev = labeledStatements.Find(lnode.Label);
+ if (prev == ss) {
+ Error(lnode.Tok, "duplicate label");
+ } else if (prev != null) {
+ Error(lnode.Tok, "label shadows an enclosing label");
+ } else {
+ bool b = labeledStatements.Push(lnode.Label, ss);
+ Contract.Assert(b); // since we just checked for duplicates, we expect the Push to succeed
+ if (lnode == ss.Labels) { // add it only once
+ inSpecOnlyContext.Add(ss, specContextOnly);
+ }
+ }
}
+ ResolveStatement(ss, specContextOnly, method);
+ labeledStatements.PopMarker();
}
- for (; 0 < labelsToPop; labelsToPop--) { labeledStatements.PopMarker(); }
}
- Type ResolveTypeRhs(TypeRhs rr, Statement stmt, bool specContext, Method method) {
+ Type ResolveTypeRhs(TypeRhs rr, Statement stmt, bool specContextOnly, Method method) {
Contract.Requires(rr != null);
Contract.Requires(stmt != null);
Contract.Requires(method != null);
Contract.Ensures(Contract.Result<Type>() != null);
- ResolveType(stmt.Tok, rr.EType);
- if (rr.ArrayDimensions == null) {
- if (!rr.EType.IsRefType) {
- Error(stmt, "new can be applied only to reference types (got {0})", rr.EType);
- } else if (rr.InitCall != null) {
- ResolveCallStmt(rr.InitCall, specContext, method, rr.EType);
- }
- rr.Type = rr.EType;
- } else {
- int i = 0;
- if (rr.EType.IsSubrangeType) {
- Error(stmt, "sorry, cannot instantiate 'array' type with a subrange type");
- }
- foreach (Expression dim in rr.ArrayDimensions) {
- Contract.Assert(dim != null);
- ResolveExpression(dim, true, specContext);
- if (!UnifyTypes(dim.Type, Type.Int)) {
- Error(stmt, "new must use an integer expression for the array size (got {0} for index {1})", dim.Type, i);
+ if (rr.Type == null) {
+ ResolveType(stmt.Tok, rr.EType);
+ if (rr.ArrayDimensions == null) {
+ if (!rr.EType.IsRefType) {
+ Error(stmt, "new can be applied only to reference types (got {0})", rr.EType);
+ } else if (rr.InitCall != null) {
+ ResolveCallStmt(rr.InitCall, specContextOnly, method, rr.EType);
}
- i++;
+ rr.Type = rr.EType;
+ } else {
+ int i = 0;
+ if (rr.EType.IsSubrangeType) {
+ Error(stmt, "sorry, cannot instantiate 'array' type with a subrange type");
+ }
+ foreach (Expression dim in rr.ArrayDimensions) {
+ Contract.Assert(dim != null);
+ ResolveExpression(dim, true);
+ if (!UnifyTypes(dim.Type, Type.Int)) {
+ Error(stmt, "new must use an integer expression for the array size (got {0} for index {1})", dim.Type, i);
+ }
+ i++;
+ }
+ rr.Type = builtIns.ArrayType(rr.ArrayDimensions.Count, rr.EType);
}
- rr.Type = builtIns.ArrayType(rr.ArrayDimensions.Count, rr.EType);
}
return rr.Type;
}
@@ -1821,11 +1989,11 @@ namespace Microsoft.Dafny {
/// <summary>
/// "twoState" implies that "old" and "fresh" expressions are allowed
/// </summary>
- void ResolveExpression(Expression expr, bool twoState, bool specContext) {
- ResolveExpression(expr, twoState, specContext, null);
+ void ResolveExpression(Expression expr, bool twoState) {
+ ResolveExpression(expr, twoState, null);
}
- void ResolveExpression(Expression expr, bool twoState, bool specContext, List<IVariable> matchVarContext) {
+ void ResolveExpression(Expression expr, bool twoState, List<IVariable> matchVarContext) {
Contract.Requires(expr != null);
Contract.Requires(currentClass != null);
Contract.Ensures(expr.Type != null);
@@ -1838,8 +2006,24 @@ namespace Microsoft.Dafny {
// and it cannot be determined what the type of expr is, then it is fine to leave expr.Type as null. In that case, the end
// of this method will assign proxy type to the expression, which reduces the number of error messages that are produced
// while type checking the rest of the program.
-
- if (expr is LiteralExpr) {
+
+ if (expr is ParensExpression) {
+ var e = (ParensExpression)expr;
+ ResolveExpression(e.E, twoState);
+ e.ResolvedExpression = e.E;
+ e.Type = e.E.Type;
+
+ } else if (expr is ChainingExpression) {
+ var e = (ChainingExpression)expr;
+ ResolveExpression(e.E, twoState);
+ e.ResolvedExpression = e.E;
+ e.Type = e.E.Type;
+
+ } else if (expr is IdentifierSequence) {
+ var e = (IdentifierSequence)expr;
+ ResolveIdentifierSequence(e, twoState, false);
+
+ } else if (expr is LiteralExpr) {
LiteralExpr e = (LiteralExpr)expr;
if (e.Value == null) {
e.Type = new ObjectTypeProxy();
@@ -1853,7 +2037,7 @@ namespace Microsoft.Dafny {
} else if (expr is ThisExpr) {
if (!scope.AllowInstance) {
- Error(expr, "'this' is not allowed in a 'class' context");
+ Error(expr, "'this' is not allowed in a 'static' context");
}
expr.Type = GetThisType(expr.tok, currentClass); // do this regardless of scope.AllowInstance, for better error reporting
@@ -1864,9 +2048,6 @@ namespace Microsoft.Dafny {
Error(expr, "Identifier does not denote a local variable, parameter, or bound variable: {0}", e.Name);
} else {
expr.Type = e.Var.Type;
- if (!specContext && e.Var.IsGhost) {
- Error(expr, "ghost variables are allowed only in specification contexts");
- }
}
} else if (expr is DatatypeValue) {
@@ -1899,17 +2080,11 @@ namespace Microsoft.Dafny {
if (ctor.Formals.Count != dtv.Arguments.Count) {
Error(expr.tok, "wrong number of arguments to datatype constructor {0} (found {1}, expected {2})", dtv.DatatypeName, dtv.Arguments.Count, ctor.Formals.Count);
}
- // add the constructor's own type parameters to the substitution map
- foreach (TypeParameter p in ctor.TypeArgs) {
- Type t = new ParamTypeProxy(p);
- dtv.InferredTypeArgs.Add(t);
- subst.Add(p, t);
- }
}
int j = 0;
foreach (Expression arg in dtv.Arguments) {
Formal formal = ctor != null && j < ctor.Formals.Count ? ctor.Formals[j] : null;
- ResolveExpression(arg, twoState, specContext || (formal != null && formal.IsGhost));
+ ResolveExpression(arg, twoState);
Contract.Assert(arg.Type != null); // follows from postcondition of ResolveExpression
if (formal != null) {
Type st = SubstType(formal.Type, subst);
@@ -1925,7 +2100,7 @@ namespace Microsoft.Dafny {
DisplayExpression e = (DisplayExpression)expr;
Type elementType = new InferredTypeProxy();
foreach (Expression ee in e.Elements) {
- ResolveExpression(ee, twoState, specContext);
+ ResolveExpression(ee, twoState);
Contract.Assert(ee.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(elementType, ee.Type)) {
Error(ee, "All elements of display must be of the same type (got {0}, but type of previous elements is {1})", ee.Type, elementType);
@@ -1939,7 +2114,7 @@ namespace Microsoft.Dafny {
} else if (expr is FieldSelectExpr) {
FieldSelectExpr e = (FieldSelectExpr)expr;
- ResolveExpression(e.Obj, twoState, specContext);
+ ResolveExpression(e.Obj, twoState);
Contract.Assert(e.Obj.Type != null); // follows from postcondition of ResolveExpression
UserDefinedType ctype;
MemberDecl member = ResolveMember(expr.tok, e.Obj.Type, e.FieldName, out ctype);
@@ -1950,25 +2125,25 @@ namespace Microsoft.Dafny {
} else {
Contract.Assert(ctype != null && ctype.ResolvedClass != null); // follows from postcondition of ResolveMember
e.Field = (Field)member;
+ if (e.Obj is StaticReceiverExpr) {
+ Error(expr, "a field must be selected via an object, not just a class name");
+ }
// build the type substitution map
Dictionary<TypeParameter,Type> subst = new Dictionary<TypeParameter,Type>();
for (int i = 0; i < ctype.TypeArgs.Count; i++) {
subst.Add(ctype.ResolvedClass.TypeArgs[i], ctype.TypeArgs[i]);
}
e.Type = SubstType(e.Field.Type, subst);
- if (!specContext && e.Field.IsGhost) {
- Error(expr, "ghost fields are allowed only in specification contexts");
- }
}
} else if (expr is SeqSelectExpr) {
SeqSelectExpr e = (SeqSelectExpr)expr;
- ResolveSeqSelectExpr(e, twoState, specContext, false);
+ ResolveSeqSelectExpr(e, twoState, false);
} else if (expr is MultiSelectExpr) {
MultiSelectExpr e = (MultiSelectExpr)expr;
- ResolveExpression(e.Array, twoState, specContext);
+ ResolveExpression(e.Array, twoState);
Contract.Assert(e.Array.Type != null); // follows from postcondition of ResolveExpression
Type elementType = new InferredTypeProxy();
if (!UnifyTypes(e.Array.Type, builtIns.ArrayType(e.Indices.Count, elementType))) {
@@ -1977,7 +2152,7 @@ namespace Microsoft.Dafny {
int i = 0;
foreach (Expression idx in e.Indices) {
Contract.Assert(idx != null);
- ResolveExpression(idx, twoState, specContext);
+ ResolveExpression(idx, twoState);
Contract.Assert(idx.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(idx.Type, Type.Int)) {
Error(idx, "array selection requires integer indices (got {0} for index {1})", idx.Type, i);
@@ -1989,19 +2164,19 @@ namespace Microsoft.Dafny {
} else if (expr is SeqUpdateExpr) {
SeqUpdateExpr e = (SeqUpdateExpr)expr;
bool seqErr = false;
- ResolveExpression(e.Seq, twoState, specContext);
+ ResolveExpression(e.Seq, twoState);
Contract.Assert(e.Seq.Type != null); // follows from postcondition of ResolveExpression
Type elementType = new InferredTypeProxy();
if (!UnifyTypes(e.Seq.Type, new SeqType(elementType))) {
Error(expr, "sequence update requires a sequence (got {0})", e.Seq.Type);
seqErr = true;
}
- ResolveExpression(e.Index, twoState, specContext);
+ ResolveExpression(e.Index, twoState);
Contract.Assert(e.Index.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.Index.Type, Type.Int)) {
Error(e.Index, "sequence update requires integer index (got {0})", e.Index.Type);
}
- ResolveExpression(e.Value, twoState, specContext);
+ ResolveExpression(e.Value, twoState);
Contract.Assert(e.Value.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.Value.Type, elementType)) {
Error(e.Value, "sequence update requires the value to have the element type of the sequence (got {0})", e.Value.Type);
@@ -2012,93 +2187,22 @@ namespace Microsoft.Dafny {
} else if (expr is FunctionCallExpr) {
FunctionCallExpr e = (FunctionCallExpr)expr;
- ResolveReceiver(e.Receiver, twoState, specContext);
- Contract.Assert(e.Receiver.Type != null); // follows from postcondition of ResolveExpression
- UserDefinedType ctype;
- MemberDecl member = ResolveMember(expr.tok, e.Receiver.Type, e.Name, out ctype);
- if (member == null) {
- // error has already been reported by ResolveMember
- } else if (!(member is Function)) {
- Error(expr, "member {0} in class {1} does not refer to a function", e.Name, cce.NonNull(ctype).Name);
- } else {
- Function function = (Function)member;
- e.Function = function;
- if (!specContext && function.IsGhost) {
- Error(expr, "function calls are allowed only in specification contexts (consider declaring the function a 'function method')");
- }
- if (function.Formals.Count != e.Args.Count) {
- Error(expr, "wrong number of function arguments (got {0}, expected {1})", e.Args.Count, function.Formals.Count);
- } else {
- Contract.Assert(ctype != null); // follows from postcondition of ResolveMember
- if (!scope.AllowInstance && !function.IsStatic && e.Receiver is ThisExpr) {
- // The call really needs an instance, but that instance is given as 'this', which is not
- // available in this context. In most cases, occurrences of 'this' inside e.Receiver would
- // have been caught in the recursive call to resolve e.Receiver, but not the specific case
- // of e.Receiver being 'this' (explicitly or implicitly), for that case needs to be allowed
- // in the event that a class function calls another class function (and note that we need the
- // type of the receiver in order to find the method, so we could not have made this check
- // earlier).
- Error(e.Receiver, "'this' is not allowed in a 'static' context");
- }
- // build the type substitution map
- Dictionary<TypeParameter,Type> subst = new Dictionary<TypeParameter,Type>();
- for (int i = 0; i < ctype.TypeArgs.Count; i++) {
- subst.Add(cce.NonNull(ctype.ResolvedClass).TypeArgs[i], ctype.TypeArgs[i]);
- }
- foreach (TypeParameter p in function.TypeArgs) {
- subst.Add(p, new ParamTypeProxy(p));
- }
- // type check the arguments
- for (int i = 0; i < function.Formals.Count; i++) {
- Expression farg = e.Args[i];
- ResolveExpression(farg, twoState, specContext);
- Contract.Assert(farg.Type != null); // follows from postcondition of ResolveExpression
- Type s = SubstType(function.Formals[i].Type, subst);
- if (!UnifyTypes(farg.Type, s)) {
- Error(expr, "incorrect type of function argument {0} (expected {1}, got {2})", i, s, farg.Type);
- }
- }
- expr.Type = SubstType(function.ResultType, subst);
- }
-
- // Resolution termination check
- if (currentFunction != null && currentFunction.EnclosingClass != null && function.EnclosingClass != null) {
- ModuleDecl callerModule = currentFunction.EnclosingClass.Module;
- ModuleDecl calleeModule = function.EnclosingClass.Module;
- if (callerModule == calleeModule) {
- // intra-module call; this is allowed; add edge in module's call graph
- callerModule.CallGraph.AddEdge(currentFunction, function);
- if (currentFunction == function) {
- currentFunction.IsRecursive = true; // self recursion (mutual recursion is determined elsewhere)
- }
- } else if (calleeModule.IsDefaultModule) {
- // all is fine: everything implicitly imports the default module
- } else if (importGraph.Reaches(callerModule, calleeModule)) {
- // all is fine: the callee is downstream of the caller
- } else {
- Error(expr, "inter-module calls must follow the module import relation (so module {0} must transitively import {1})", callerModule.Name, calleeModule.Name);
- }
- }
- }
+ ResolveFunctionCallExpr(e, twoState, false);
} else if (expr is OldExpr) {
OldExpr e = (OldExpr)expr;
if (!twoState) {
Error(expr, "old expressions are not allowed in this context");
- } else if (!specContext) {
- Error(expr, "old expressions are allowed only in specification and ghost contexts");
}
- ResolveExpression(e.E, twoState, specContext);
+ ResolveExpression(e.E, twoState);
expr.Type = e.E.Type;
} else if (expr is FreshExpr) {
FreshExpr e = (FreshExpr)expr;
if (!twoState) {
Error(expr, "fresh expressions are not allowed in this context");
- } else if (!specContext) {
- Error(expr, "fresh expressions are allowed only in specification and ghost contexts");
}
- ResolveExpression(e.E, twoState, specContext);
+ ResolveExpression(e.E, twoState);
// the type of e.E must be either an object or a collection of objects
Type t = e.E.Type;
Contract.Assert(t != null); // follows from postcondition of ResolveExpression
@@ -2116,16 +2220,13 @@ namespace Microsoft.Dafny {
} else if (expr is AllocatedExpr) {
AllocatedExpr e = (AllocatedExpr)expr;
- ResolveExpression(e.E, twoState, specContext);
- if (!specContext) {
- Error(expr, "allocated expressions are allowed only in specification and ghost contexts");
- }
+ ResolveExpression(e.E, twoState);
// e.E can be of any type
expr.Type = Type.Bool;
} else if (expr is UnaryExpr) {
UnaryExpr e = (UnaryExpr)expr;
- ResolveExpression(e.E, twoState, specContext);
+ ResolveExpression(e.E, twoState);
Contract.Assert(e.E.Type != null); // follows from postcondition of ResolveExpression
switch (e.Op) {
case UnaryExpr.Opcode.Not:
@@ -2153,9 +2254,9 @@ namespace Microsoft.Dafny {
} else if (expr is BinaryExpr) {
BinaryExpr e = (BinaryExpr)expr;
- ResolveExpression(e.E0, twoState, specContext);
+ ResolveExpression(e.E0, twoState);
Contract.Assert(e.E0.Type != null); // follows from postcondition of ResolveExpression
- ResolveExpression(e.E1, twoState, specContext);
+ ResolveExpression(e.E1, twoState);
Contract.Assert(e.E1.Type != null); // follows from postcondition of ResolveExpression
switch (e.Op) {
case BinaryExpr.Opcode.Iff:
@@ -2197,9 +2298,6 @@ namespace Microsoft.Dafny {
if (!UnifyTypes(e.E1.Type, new DatatypeProxy())) {
Error(expr, "arguments to rank comparison must be datatypes (instead of {0})", e.E1.Type);
}
- if (!specContext) {
- Error(expr, "rank comparisons are allowed only in specification and ghost contexts");
- }
expr.Type = Type.Bool;
} else {
bool err = false;
@@ -2229,9 +2327,6 @@ namespace Microsoft.Dafny {
if (!UnifyTypes(e.E1.Type, new DatatypeProxy())) {
Error(expr, "arguments to rank comparison must be datatypes (instead of {0})", e.E1.Type);
}
- if (!specContext) {
- Error(expr, "rank comparisons are allowed only in specification and ghost contexts");
- }
expr.Type = Type.Bool;
} else {
bool err = false;
@@ -2287,13 +2382,13 @@ namespace Microsoft.Dafny {
ResolveType(v.tok, v.Type);
}
if (e.Range != null) {
- ResolveExpression(e.Range, twoState, specContext);
+ ResolveExpression(e.Range, twoState);
Contract.Assert(e.Range.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.Range.Type, Type.Bool)) {
Error(expr, "range of quantifier must be of type bool (instead got {0})", e.Range.Type);
}
}
- ResolveExpression(e.Term, twoState, specContext);
+ ResolveExpression(e.Term, twoState);
Contract.Assert(e.Term.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.Term.Type, Type.Bool)) {
Error(expr, "body of quantifier must be of type bool (instead got {0})", e.Term.Type);
@@ -2306,7 +2401,11 @@ namespace Microsoft.Dafny {
expr.Type = Type.Bool;
if (prevErrorCount == ErrorCount) {
- e.Bounds = DiscoverBounds(e.tok, e.BoundVars, e.LogicalBody(), e is ExistsExpr, specContext ? null : "quantifiers in non-ghost contexts must be compilable");
+ var missingBounds = new List<BoundVar>();
+ e.Bounds = DiscoverBounds(e.tok, e.BoundVars, e.LogicalBody(), e is ExistsExpr, missingBounds);
+ if (missingBounds.Count != 0) {
+ e.MissingBounds = missingBounds;
+ }
}
} else if (expr is SetComprehension) {
@@ -2319,12 +2418,12 @@ namespace Microsoft.Dafny {
}
ResolveType(v.tok, v.Type);
}
- ResolveExpression(e.Range, twoState, specContext);
+ ResolveExpression(e.Range, twoState);
Contract.Assert(e.Range.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.Range.Type, Type.Bool)) {
Error(expr, "range of comprehension must be of type bool (instead got {0})", e.Range.Type);
}
- ResolveExpression(e.Term, twoState, specContext);
+ ResolveExpression(e.Term, twoState);
Contract.Assert(e.Term.Type != null); // follows from postcondition of ResolveExpression
ResolveAttributes(e.Attributes, twoState);
@@ -2332,7 +2431,14 @@ namespace Microsoft.Dafny {
expr.Type = new SetType(e.Term.Type);
if (prevErrorCount == ErrorCount) {
- e.Bounds = DiscoverBounds(e.tok, e.BoundVars, e.Range, true, "a set comprehension must produce a finite set");
+ var missingBounds = new List<BoundVar>();
+ e.Bounds = DiscoverBounds(e.tok, e.BoundVars, e.Range, true, missingBounds);
+ if (missingBounds.Count != 0) {
+ e.MissingBounds = missingBounds;
+ foreach (var bv in e.MissingBounds) {
+ Error(expr, "a set comprehension must produce a finite set, but Dafny's heuristics can't figure out how to produce a bounded set of values for '{0}'", bv.Name);
+ }
+ }
}
} else if (expr is WildcardExpr) {
@@ -2340,11 +2446,11 @@ namespace Microsoft.Dafny {
} else if (expr is ITEExpr) {
ITEExpr e = (ITEExpr)expr;
- ResolveExpression(e.Test, twoState, specContext);
+ ResolveExpression(e.Test, twoState);
Contract.Assert(e.Test.Type != null); // follows from postcondition of ResolveExpression
- ResolveExpression(e.Thn, twoState, specContext);
+ ResolveExpression(e.Thn, twoState);
Contract.Assert(e.Thn.Type != null); // follows from postcondition of ResolveExpression
- ResolveExpression(e.Els, twoState, specContext);
+ ResolveExpression(e.Els, twoState);
Contract.Assert(e.Els.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.Test.Type, Type.Bool)) {
Error(expr, "guard condition in if-then-else expression must be a boolean (instead got {0})", e.Test.Type);
@@ -2358,7 +2464,7 @@ namespace Microsoft.Dafny {
} else if (expr is MatchExpr) {
MatchExpr me = (MatchExpr)expr;
Contract.Assert(!twoState); // currently, match expressions are allowed only at the outermost level of function bodies
- ResolveExpression(me.Source, twoState, specContext);
+ ResolveExpression(me.Source, twoState);
Contract.Assert(me.Source.Type != null); // follows from postcondition of ResolveExpression
UserDefinedType sourceType = null;
DatatypeDecl dtd = null;
@@ -2370,14 +2476,14 @@ namespace Microsoft.Dafny {
Dictionary<string,DatatypeCtor> ctors;
IVariable goodMatchVariable = null;
if (dtd == null) {
- Error(me.Source, "the type of the match source expression must be a datatype");
+ Error(me.Source, "the type of the match source expression must be a datatype (instead found {0})", me.Source.Type);
ctors = null;
} else {
Contract.Assert(sourceType != null); // dtd and sourceType are set together above
ctors = datatypeCtors[dtd];
Contract.Assert(ctors != null); // dtd should have been inserted into datatypeCtors during a previous resolution stage
- IdentifierExpr ie = me.Source as IdentifierExpr;
+ IdentifierExpr ie = me.Source.Resolved as IdentifierExpr;
if (ie == null || !(ie.Var is Formal || ie.Var is BoundVar)) {
Error(me.Source.tok, "match source expression must be a formal parameter of the enclosing function or an enclosing match expression");
} else if (!matchVarContext.Contains(ie.Var)) {
@@ -2414,12 +2520,6 @@ namespace Microsoft.Dafny {
}
}
scope.PushMarker();
- if (ctor != null) {
- // add the constructor's own type parameters to the substitution map
- foreach (TypeParameter p in ctor.TypeArgs) {
- subst.Add(p, new ParamTypeProxy(p));
- }
- }
int i = 0;
foreach (BoundVar v in mc.Arguments) {
if (!scope.Push(v.Name, v)) {
@@ -2441,7 +2541,7 @@ namespace Microsoft.Dafny {
innerMatchVarContext.Remove(goodMatchVariable); // this variable is no longer available for matching
}
innerMatchVarContext.AddRange(mc.Arguments);
- ResolveExpression(mc.Body, twoState, specContext, innerMatchVarContext);
+ ResolveExpression(mc.Body, twoState, innerMatchVarContext);
Contract.Assert(mc.Body.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(expr.Type, mc.Body.Type)) {
Error(mc.Body.tok, "type of case bodies do not agree (found {0}, previous types {1})", mc.Body.Type, expr.Type);
@@ -2472,19 +2572,341 @@ namespace Microsoft.Dafny {
}
/// <summary>
+ /// Generate an error for every non-ghost feature used in "expr".
+ /// Requires "expr" to have been successfully resolved.
+ /// </summary>
+ void CheckIsNonGhost(Expression expr) {
+ Contract.Requires(expr != null);
+ Contract.Requires(currentClass != null);
+ Contract.Requires(expr.Type != null); // this check approximates the requirement that "expr" be resolved
+
+ if (expr is IdentifierExpr) {
+ var e = (IdentifierExpr)expr;
+ if (e.Var != null && e.Var.IsGhost) {
+ Error(expr, "ghost variables are allowed only in specification contexts");
+ return;
+ }
+
+ } else if (expr is FieldSelectExpr) {
+ var e = (FieldSelectExpr)expr;
+ if (e.Field != null && e.Field.IsGhost) {
+ Error(expr, "ghost fields are allowed only in specification contexts");
+ return;
+ }
+
+ } else if (expr is FunctionCallExpr) {
+ var e = (FunctionCallExpr)expr;
+ if (e.Function != null && e.Function.IsGhost) {
+ Error(expr, "function calls are allowed only in specification contexts (consider declaring the function a 'function method')");
+ return;
+ }
+ // function is okay, so check all NON-ghost arguments
+ CheckIsNonGhost(e.Receiver);
+ for (int i = 0; i < e.Function.Formals.Count; i++) {
+ if (!e.Function.Formals[i].IsGhost) {
+ CheckIsNonGhost(e.Args[i]);
+ }
+ }
+ return;
+
+ } else if (expr is DatatypeValue) {
+ var e = (DatatypeValue)expr;
+ // check all NON-ghost arguments
+ for (int i = 0; i < e.Ctor.Formals.Count; i++) {
+ if (!e.Ctor.Formals[i].IsGhost) {
+ CheckIsNonGhost(e.Arguments[i]);
+ }
+ }
+ return;
+
+ } else if (expr is OldExpr) {
+ Error(expr, "old expressions are allowed only in specification and ghost contexts");
+ return;
+
+ } else if (expr is FreshExpr) {
+ Error(expr, "fresh expressions are allowed only in specification and ghost contexts");
+ return;
+
+ } else if (expr is AllocatedExpr) {
+ Error(expr, "allocated expressions are allowed only in specification and ghost contexts");
+ return;
+
+ } else if (expr is BinaryExpr) {
+ var e = (BinaryExpr)expr;
+ switch (e.ResolvedOp) {
+ case BinaryExpr.ResolvedOpcode.RankGt:
+ case BinaryExpr.ResolvedOpcode.RankLt:
+ Error(expr, "rank comparisons are allowed only in specification and ghost contexts");
+ return;
+ default:
+ break;
+ }
+
+ } else if (expr is QuantifierExpr) {
+ var e = (QuantifierExpr)expr;
+ if (e.MissingBounds != null) {
+ foreach (var bv in e.MissingBounds) {
+ Error(expr, "quantifiers in non-ghost contexts must be compilable, but Dafny's heuristics can't figure out how to produce a bounded set of values for '{0}'", bv.Name);
+ }
+ return;
+ }
+ }
+
+ foreach (var ee in expr.SubExpressions) {
+ CheckIsNonGhost(ee);
+ }
+ }
+
+ /// <summary>
+ /// If "!allowMethodCall" or if what is being called does not refer to a method, resolves "e" and returns "null".
+ /// Otherwise (that is, if "allowMethodCall" and what is being called refers to a method), resolves the receiver
+ /// of "e" but NOT the arguments, and returns a CallRhs corresponding to the call.
+ /// </summary>
+ CallRhs ResolveFunctionCallExpr(FunctionCallExpr e, bool twoState, bool allowMethodCall) {
+ ResolveReceiver(e.Receiver, twoState);
+ Contract.Assert(e.Receiver.Type != null); // follows from postcondition of ResolveExpression
+ UserDefinedType ctype;
+ MemberDecl member = ResolveMember(e.tok, e.Receiver.Type, e.Name, out ctype);
+ if (member == null) {
+ // error has already been reported by ResolveMember
+ } else if (allowMethodCall && member is Method) {
+ // it's a method
+ return new CallRhs(e.tok, e.Receiver, e.Name, e.Args);
+ } else if (!(member is Function)) {
+ Error(e, "member {0} in class {1} does not refer to a function", e.Name, cce.NonNull(ctype).Name);
+ } else {
+ Function function = (Function)member;
+ e.Function = function;
+ if (e.Receiver is StaticReceiverExpr && !function.IsStatic) {
+ Error(e, "an instance function must be selected via an object, not just a class name");
+ }
+ if (function.Formals.Count != e.Args.Count) {
+ Error(e, "wrong number of function arguments (got {0}, expected {1})", e.Args.Count, function.Formals.Count);
+ } else {
+ Contract.Assert(ctype != null); // follows from postcondition of ResolveMember
+ if (!function.IsStatic) {
+ if (!scope.AllowInstance && e.Receiver is ThisExpr) {
+ // The call really needs an instance, but that instance is given as 'this', which is not
+ // available in this context. In most cases, occurrences of 'this' inside e.Receiver would
+ // have been caught in the recursive call to resolve e.Receiver, but not the specific case
+ // of e.Receiver being 'this' (explicitly or implicitly), for that case needs to be allowed
+ // in the event that a static function calls another static function (and note that we need the
+ // type of the receiver in order to find the method, so we could not have made this check
+ // earlier).
+ Error(e.Receiver, "'this' is not allowed in a 'static' context");
+ } else if (e.Receiver is StaticReceiverExpr) {
+ Error(e.Receiver, "call to instance function requires an instance");
+ }
+ }
+ // build the type substitution map
+ Dictionary<TypeParameter, Type> subst = new Dictionary<TypeParameter, Type>();
+ for (int i = 0; i < ctype.TypeArgs.Count; i++) {
+ subst.Add(cce.NonNull(ctype.ResolvedClass).TypeArgs[i], ctype.TypeArgs[i]);
+ }
+ foreach (TypeParameter p in function.TypeArgs) {
+ subst.Add(p, new ParamTypeProxy(p));
+ }
+ // type check the arguments
+ for (int i = 0; i < function.Formals.Count; i++) {
+ Expression farg = e.Args[i];
+ ResolveExpression(farg, twoState);
+ Contract.Assert(farg.Type != null); // follows from postcondition of ResolveExpression
+ Type s = SubstType(function.Formals[i].Type, subst);
+ if (!UnifyTypes(farg.Type, s)) {
+ Error(e, "incorrect type of function argument {0} (expected {1}, got {2})", i, s, farg.Type);
+ }
+ }
+ e.Type = SubstType(function.ResultType, subst);
+ }
+
+ // Resolution termination check
+ if (currentFunction != null && currentFunction.EnclosingClass != null && function.EnclosingClass != null) {
+ ModuleDecl callerModule = currentFunction.EnclosingClass.Module;
+ ModuleDecl calleeModule = function.EnclosingClass.Module;
+ if (callerModule == calleeModule) {
+ // intra-module call; this is allowed; add edge in module's call graph
+ callerModule.CallGraph.AddEdge(currentFunction, function);
+ if (currentFunction == function) {
+ currentFunction.IsRecursive = true; // self recursion (mutual recursion is determined elsewhere)
+ }
+ } else if (calleeModule.IsDefaultModule) {
+ // all is fine: everything implicitly imports the default module
+ } else if (importGraph.Reaches(callerModule, calleeModule)) {
+ // all is fine: the callee is downstream of the caller
+ } else {
+ Error(e, "inter-module calls must follow the module import relation (so module {0} must transitively import {1})", callerModule.Name, calleeModule.Name);
+ }
+ }
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// If "!allowMethodCall", or if "e" does not designate a method call, resolves "e" and returns "null".
+ /// Otherwise, resolves all sub-parts of "e" and returns a (resolved) CallRhs expression representing the call.
+ /// </summary>
+ CallRhs ResolveIdentifierSequence(IdentifierSequence e, bool twoState, bool allowMethodCall) {
+ // Look up "id" as follows:
+ // - local variable, parameter, or bound variable (if this clashes with something of interest, one can always rename the local variable locally)
+ // - type name (class or datatype)
+ // - unambiguous constructor name of a datatype (if two constructors have the same name, an error message is produced here)
+ // - field name (with implicit receiver) (if the field is ocluded by anything above, one can use an explicit "this.")
+ // Note, at present, modules do not give rise to new namespaces, which is something that should
+ // be changed in the language when modules are given more attention.
+ Expression r = null; // resolved version of e
+ CallRhs call = null;
+
+ TopLevelDecl decl;
+ Tuple<DatatypeCtor, bool> pair;
+ Dictionary<string, MemberDecl> members;
+ MemberDecl member;
+ var id = e.Tokens[0];
+ if (scope.Find(id.val) != null) {
+ // ----- root is a local variable, parameter, or bound variable
+ r = new IdentifierExpr(id, id.val);
+ ResolveExpression(r, twoState);
+ r = ResolveSuffix(r, e, 1, twoState, allowMethodCall, out call);
+
+ } else if (classes.TryGetValue(id.val, out decl)) {
+ if (e.Tokens.Count == 1 && e.Arguments == null) {
+ Error(id, "name of type ('{0}') is used as a variable", id.val);
+ } else if (e.Tokens.Count == 1 && e.Arguments != null) {
+ Error(id, "name of type ('{0}') is used as a function", id.val);
+ // resolve the arguments nonetheless
+ foreach (var arg in e.Arguments) {
+ ResolveExpression(arg, twoState);
+ }
+ } else if (decl is ClassDecl) {
+ // ----- root is a class
+ var cd = (ClassDecl)decl;
+ r = ResolveSuffix(new StaticReceiverExpr(id, cd), e, 1, twoState, allowMethodCall, out call);
+
+ } else {
+ // ----- root is a datatype
+ var dt = (DatatypeDecl)decl; // otherwise, unexpected TopLevelDecl
+ var args = (e.Tokens.Count == 2 ? e.Arguments : null) ?? new List<Expression>();
+ r = new DatatypeValue(id, id.val, e.Tokens[1].val, args);
+ ResolveExpression(r, twoState);
+ if (e.Tokens.Count != 2) {
+ r = ResolveSuffix(r, e, 2, twoState, allowMethodCall, out call);
+ }
+ }
+
+ } else if (allDatatypeCtors.TryGetValue(id.val, out pair)) {
+ // ----- root is a datatype constructor
+ if (pair.Item2) {
+ // there is more than one constructor with this name
+ Error(id, "the name '{0}' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, '{1}.{0}')", id.val, pair.Item1.EnclosingDatatype.Name);
+ } else {
+ var args = (e.Tokens.Count == 1 ? e.Arguments : null) ?? new List<Expression>();
+ r = new DatatypeValue(id, pair.Item1.EnclosingDatatype.Name, id.val, args);
+ ResolveExpression(r, twoState);
+ if (e.Tokens.Count != 1) {
+ r = ResolveSuffix(r, e, 1, twoState, allowMethodCall, out call);
+ }
+ }
+
+ } else if (classMembers.TryGetValue(currentClass, out members) && members.TryGetValue(id.val, out member)) {
+ // ----- field, function, or method
+ Expression receiver;
+ if (member.IsStatic) {
+ receiver = new StaticReceiverExpr(id, currentClass);
+ } else {
+ if (!scope.AllowInstance) {
+ Error(id, "'this' is not allowed in a 'static' context");
+ // nevertheless, set "receiver" to a value so we can continue resolution
+ }
+ receiver = new ImplicitThisExpr(id);
+ receiver.Type = GetThisType(id, currentClass); // resolve here
+ }
+ r = ResolveSuffix(receiver, e, 0, twoState, allowMethodCall, out call);
+
+ } else {
+ Error(id, "unresolved identifier: {0}", id.val);
+ // resolve arguments, if any
+ if (e.Arguments != null) {
+ foreach (var arg in e.Arguments) {
+ ResolveExpression(arg, twoState);
+ }
+ }
+ }
+
+ if (r != null) {
+ e.ResolvedExpression = r;
+ e.Type = r.Type;
+ }
+ return call;
+ }
+
+ /// <summary>
+ /// Given resolved expression "r" and unresolved expressions e.Tokens[p..] and e.Arguments.
+ /// Returns a resolved version of the expression:
+ /// r . e.Tokens[p] . e.Tokens[p+1] ... . e.Tokens[e.Tokens.Count-1] ( e.Arguments )
+ /// Except, if "allowMethodCall" is "true" and the would-be-returned value designates a method
+ /// call, instead returns null and returns "call" as a non-null value.
+ /// </summary>
+ Expression ResolveSuffix(Expression r, IdentifierSequence e, int p, bool twoState, bool allowMethodCall, out CallRhs call) {
+ Contract.Requires(r != null);
+ Contract.Requires(e != null);
+ Contract.Requires(0 <= p && p <= e.Tokens.Count);
+ Contract.Ensures((Contract.Result<Expression>() != null && Contract.ValueAtReturn(out call) == null) ||
+ (allowMethodCall && Contract.Result<Expression>() == null && Contract.ValueAtReturn(out call) != null));
+
+ call = null;
+ int nonCallArguments = e.Arguments == null ? e.Tokens.Count : e.Tokens.Count - 1;
+ for (; p < nonCallArguments; p++) {
+ r = new FieldSelectExpr(e.Tokens[p], r, e.Tokens[p].val);
+ ResolveExpression(r, twoState);
+ }
+
+ if (p < e.Tokens.Count) {
+ Contract.Assert(e.Arguments != null);
+
+ Dictionary<string, MemberDecl> members;
+ MemberDecl member;
+ UserDefinedType receiverType = UserDefinedType.DenotesClass(r.Type);
+ if (allowMethodCall &&
+ receiverType != null &&
+ classMembers.TryGetValue((ClassDecl)receiverType.ResolvedClass, out members) &&
+ members.TryGetValue(e.Tokens[p].val, out member) &&
+ member is Method) {
+ // method
+ call = new CallRhs(e.Tokens[p], r, e.Tokens[p].val, e.Arguments);
+ r = null;
+ } else {
+ r = new FunctionCallExpr(e.Tokens[p], e.Tokens[p].val, r, e.Arguments);
+ ResolveExpression(r, twoState);
+ }
+ } else if (e.Arguments != null) {
+ Contract.Assert(p == e.Tokens.Count);
+ Error(e.OpenParen, "non-function expression is called with parameters");
+ // resolve the arguments nonetheless
+ foreach (var arg in e.Arguments) {
+ ResolveExpression(arg, twoState);
+ }
+ }
+ return r;
+ }
+
+ /// <summary>
/// Tries to find a bounded pool for each of the bound variables "bvars" of "expr". If this process
- /// fails, then "null" is returned and:
- /// if "errorMessage" is non-null, then appropriate error messages are reported and "null" is returned;
- /// if "errorMessage" is null, no error messages are reported.
+ /// fails, then "null" is returned and the bound variables for which the process fails are added to "missingBounds".
/// Requires "e" to be successfully resolved.
/// </summary>
- List<QuantifierExpr.BoundedPool> DiscoverBounds(IToken tok, List<BoundVar> bvars, Expression expr, bool polarity, string errorMessage) {
+ List<QuantifierExpr.BoundedPool> DiscoverBounds(IToken tok, List<BoundVar> bvars, Expression expr, bool polarity, List<BoundVar> missingBounds) {
Contract.Requires(tok != null);
Contract.Requires(bvars != null);
+ Contract.Requires(missingBounds != null);
Contract.Requires(expr.Type != null); // a sanity check (but not a complete proof) that "e" has been resolved
- Contract.Ensures(Contract.Result<List<QuantifierExpr.BoundedPool>>().Count == bvars.Count);
+ Contract.Ensures(
+ (Contract.Result<List<QuantifierExpr.BoundedPool>>() != null &&
+ Contract.Result<List<QuantifierExpr.BoundedPool>>().Count == bvars.Count &&
+ Contract.OldValue(missingBounds.Count) == missingBounds.Count) ||
+ (Contract.Result<List<QuantifierExpr.BoundedPool>>() == null &&
+ Contract.OldValue(missingBounds.Count) < missingBounds.Count));
var bounds = new List<QuantifierExpr.BoundedPool>();
+ bool foundError = false;
for (int j = 0; j < bvars.Count; j++) {
var bv = bvars[j];
if (bv.Type is BoolType) {
@@ -2553,14 +2975,12 @@ namespace Microsoft.Dafny {
CHECK_NEXT_CONJUNCT: ;
}
// we have checked every conjunct in the range expression and still have not discovered good bounds
- if (errorMessage != null) {
- Error(tok, "{0}, but Dafny's heuristics can't figure out how to produce a bounded set of values for '{1}'", errorMessage, bv.Name);
- }
- return null;
+ missingBounds.Add(bv); // record failing bound variable
+ foundError = true;
}
CHECK_NEXT_BOUND_VARIABLE: ; // should goto here only if the bound for the current variable has been discovered (otherwise, return with null from this method)
}
- return bounds;
+ return foundError ? null : bounds;
}
/// <summary>
@@ -2569,6 +2989,7 @@ namespace Microsoft.Dafny {
/// The new "e0 op e1" is equivalent to the old "e0 op e1".
/// One of "e0" and "e1" is the identifier "boundVars[bvi]"; the return value is either 0 or 1, and indicates which.
/// The other of "e0" and "e1" is an expression whose free variables are not among "boundVars[bvi..]".
+ /// Ensures that the resulting "e0" and "e1" are not ConcreteSyntaxExpression's.
/// </summary>
int SanitizeForBoundDiscovery(List<BoundVar> boundVars, int bvi, BinaryExpr.ResolvedOpcode op, ref Expression e0, ref Expression e1)
{
@@ -2577,8 +2998,12 @@ namespace Microsoft.Dafny {
Contract.Requires(boundVars != null);
Contract.Requires(0 <= bvi && bvi < boundVars.Count);
Contract.Ensures(Contract.Result<int>() < 2);
+ Contract.Ensures(!(Contract.ValueAtReturn(out e0) is ConcreteSyntaxExpression));
+ Contract.Ensures(!(Contract.ValueAtReturn(out e1) is ConcreteSyntaxExpression));
var bv = boundVars[bvi];
+ e0 = e0.Resolved;
+ e1 = e1.Resolved;
// make an initial assessment of where bv is; to continue, we need bv to appear in exactly one operand
var fv0 = FreeVariables(e0);
@@ -2616,10 +3041,10 @@ namespace Microsoft.Dafny {
} else if (bin.ResolvedOp == BinaryExpr.ResolvedOpcode.Add) {
// Change "A+B op C" into either "A op C-B" or "B op C-A", depending on where we find bv among A and B.
if (!FreeVariables(bin.E1).Contains(bv)) {
- thisSide = bin.E0;
+ thisSide = bin.E0.Resolved;
thatSide = new BinaryExpr(bin.tok, BinaryExpr.Opcode.Sub, thatSide, bin.E1);
} else {
- thisSide = bin.E1;
+ thisSide = bin.E1.Resolved;
thatSide = new BinaryExpr(bin.tok, BinaryExpr.Opcode.Sub, thatSide, bin.E0);
}
((BinaryExpr)thatSide).ResolvedOp = BinaryExpr.ResolvedOpcode.Sub;
@@ -2629,14 +3054,14 @@ namespace Microsoft.Dafny {
// Change "A-B op C" in a similar way.
if (!FreeVariables(bin.E1).Contains(bv)) {
// change to "A op C+B"
- thisSide = bin.E0;
+ thisSide = bin.E0.Resolved;
thatSide = new BinaryExpr(bin.tok, BinaryExpr.Opcode.Add, thatSide, bin.E1);
((BinaryExpr)thatSide).ResolvedOp = BinaryExpr.ResolvedOpcode.Add;
} else {
// In principle, change to "-B op C-A" and then to "B dualOp A-C". But since we don't want
// to change "op", we instead end with "A-C op B" and switch the mapping of thisSide/thatSide
// to e0/e1 (by inverting "whereIsBv").
- thisSide = bin.E1;
+ thisSide = bin.E1.Resolved;
thatSide = new BinaryExpr(bin.tok, BinaryExpr.Opcode.Sub, bin.E0, thatSide);
((BinaryExpr)thatSide).ResolvedOp = BinaryExpr.ResolvedOpcode.Sub;
whereIsBv = 1 - whereIsBv;
@@ -2689,6 +3114,7 @@ namespace Microsoft.Dafny {
/// inequality is never returned and the comparisons > and >= are never returned; the negation of
/// a common equality or disequality is rewritten analogously.
/// Requires "expr" to be successfully resolved.
+ /// Ensures that what is returned is not a ConcreteSyntaxExpression.
/// </summary>
IEnumerable<Expression> NormalizedConjuncts(Expression expr, bool polarity) {
// We consider 5 cases. To describe them, define P(e)=Conjuncts(e,true) and N(e)=Conjuncts(e,false).
@@ -2700,6 +3126,7 @@ namespace Microsoft.Dafny {
// So for ==>, we have:
// * X ==> Y P(_) = P(!X || Y) = (!X || Y) = (X ==> Y)
// N(_) = N(!X || Y) = N(!X),N(Y) = P(X),N(Y)
+ expr = expr.Resolved;
// Binary expressions
var b = expr as BinaryExpr;
@@ -2850,7 +3277,7 @@ namespace Microsoft.Dafny {
}
}
- void ResolveReceiver(Expression expr, bool twoState, bool specContext)
+ void ResolveReceiver(Expression expr, bool twoState)
{
Contract.Requires(expr != null);
Contract.Requires(currentClass != null);
@@ -2861,14 +3288,19 @@ namespace Microsoft.Dafny {
// making sure 'this' does not really get used when it's not available.
expr.Type = GetThisType(expr.tok, currentClass);
} else {
- ResolveExpression(expr, twoState, specContext);
+ ResolveExpression(expr, twoState);
}
}
- void ResolveSeqSelectExpr(SeqSelectExpr e, bool twoState, bool specContext, bool allowNonUnitArraySelection) {
+ void ResolveSeqSelectExpr(SeqSelectExpr e, bool twoState, bool allowNonUnitArraySelection) {
Contract.Requires(e != null);
+ if (e.Type != null) {
+ // already resolved
+ return;
+ }
+
bool seqErr = false;
- ResolveExpression(e.Seq, twoState, specContext);
+ ResolveExpression(e.Seq, twoState);
Contract.Assert(e.Seq.Type != null); // follows from postcondition of ResolveExpression
Type elementType = new InferredTypeProxy();
Type expectedType;
@@ -2882,14 +3314,14 @@ namespace Microsoft.Dafny {
seqErr = true;
}
if (e.E0 != null) {
- ResolveExpression(e.E0, twoState, specContext);
+ ResolveExpression(e.E0, twoState);
Contract.Assert(e.E0.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.E0.Type, Type.Int)) {
Error(e.E0, "sequence/array selection requires integer indices (got {0})", e.E0.Type);
}
}
if (e.E1 != null) {
- ResolveExpression(e.E1, twoState, specContext);
+ ResolveExpression(e.E1, twoState);
Contract.Assert(e.E1.Type != null); // follows from postcondition of ResolveExpression
if (!UnifyTypes(e.E1.Type, Type.Int)) {
Error(e.E1, "sequence/array selection requires integer indices (got {0})", e.E1.Type);
@@ -3075,6 +3507,9 @@ namespace Microsoft.Dafny {
return true;
}
return Contract.Exists( me.Cases,mc=> UsesSpecFeatures(mc.Body));
+ } else if (expr is ConcreteSyntaxExpression) {
+ var e = (ConcreteSyntaxExpression)expr;
+ return e.ResolvedExpression != null && UsesSpecFeatures(e.ResolvedExpression);
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
}
@@ -3087,8 +3522,8 @@ namespace Microsoft.Dafny {
[ContractInvariantMethod]
void ObjectInvariant()
{
- Contract.Invariant(names != null);
- Contract.Invariant(things != null);
+ Contract.Invariant(names != null);
+ Contract.Invariant(things != null);
Contract.Invariant(names.Count == things.Count);
Contract.Invariant(-1 <= scopeSizeWhereInstancesWereDisallowed && scopeSizeWhereInstancesWereDisallowed <= names.Count);
}
@@ -3123,7 +3558,7 @@ namespace Microsoft.Dafny {
}
}
- // Pushes name-->var association and returns "true", if name has not already been pushed since the last marker.
+ // Pushes name-->thing association and returns "true", if name has not already been pushed since the last marker.
// If name already has been pushed since the last marker, does nothing and returns "false".
public bool Push(string name, Thing thing) {
Contract.Requires(name != null);
diff --git a/Dafny/Scanner.cs b/Dafny/Scanner.cs
index 817df6cd..083c0c0c 100644
--- a/Dafny/Scanner.cs
+++ b/Dafny/Scanner.cs
@@ -211,8 +211,8 @@ public class UTF8Buffer: Buffer {
public class Scanner {
const char EOL = '\n';
const int eofSym = 0; /* pdt */
- const int maxT = 107;
- const int noSym = 107;
+ const int maxT = 104;
+ const int noSym = 104;
[ContractInvariantMethod]
@@ -259,26 +259,26 @@ public class Scanner {
start[97] = 10;
start[123] = 17;
start[125] = 18;
+ start[61] = 57;
+ start[124] = 58;
start[59] = 19;
- start[61] = 58;
- start[124] = 59;
start[44] = 20;
- start[58] = 60;
- start[60] = 61;
- start[62] = 62;
+ start[58] = 59;
+ start[60] = 60;
+ start[62] = 61;
start[40] = 21;
start[41] = 22;
start[42] = 23;
start[96] = 24;
start[91] = 27;
start[93] = 28;
- start[46] = 63;
+ start[46] = 62;
start[8660] = 31;
start[8658] = 33;
start[38] = 34;
start[8743] = 36;
start[8744] = 38;
- start[33] = 64;
+ start[33] = 63;
start[8800] = 44;
start[8804] = 45;
start[8805] = 46;
@@ -287,10 +287,9 @@ public class Scanner {
start[47] = 49;
start[37] = 50;
start[172] = 51;
- start[35] = 52;
- start[8704] = 54;
- start[8707] = 55;
- start[8226] = 57;
+ start[8704] = 53;
+ start[8707] = 54;
+ start[8226] = 56;
start[Buffer.EOF] = -1;
}
@@ -526,23 +525,21 @@ public class Scanner {
case "else": t.kind = 58; break;
case "while": t.kind = 59; break;
case "invariant": t.kind = 60; break;
- case "call": t.kind = 61; break;
- case "foreach": t.kind = 62; break;
- case "in": t.kind = 63; break;
- case "assert": t.kind = 64; break;
- case "assume": t.kind = 65; break;
- case "use": t.kind = 66; break;
- case "print": t.kind = 67; break;
- case "false": t.kind = 91; break;
- case "true": t.kind = 92; break;
- case "null": t.kind = 93; break;
- case "fresh": t.kind = 95; break;
- case "allocated": t.kind = 96; break;
- case "then": t.kind = 97; break;
- case "this": t.kind = 99; break;
- case "old": t.kind = 100; break;
- case "forall": t.kind = 101; break;
- case "exists": t.kind = 103; break;
+ case "foreach": t.kind = 61; break;
+ case "in": t.kind = 62; break;
+ case "assert": t.kind = 63; break;
+ case "assume": t.kind = 64; break;
+ case "print": t.kind = 65; break;
+ case "false": t.kind = 89; break;
+ case "true": t.kind = 90; break;
+ case "null": t.kind = 91; break;
+ case "this": t.kind = 92; break;
+ case "fresh": t.kind = 93; break;
+ case "allocated": t.kind = 94; break;
+ case "old": t.kind = 95; break;
+ case "then": t.kind = 96; break;
+ case "forall": t.kind = 98; break;
+ case "exists": t.kind = 100; break;
default: break;
}
}
@@ -648,7 +645,7 @@ public class Scanner {
case 18:
{t.kind = 8; break;}
case 19:
- {t.kind = 15; break;}
+ {t.kind = 17; break;}
case 20:
{t.kind = 19; break;}
case 21:
@@ -671,103 +668,101 @@ public class Scanner {
if (ch == '>') {AddCh(); goto case 30;}
else {goto case 0;}
case 30:
- {t.kind = 68; break;}
+ {t.kind = 66; break;}
case 31:
- {t.kind = 69; break;}
+ {t.kind = 67; break;}
case 32:
- {t.kind = 70; break;}
+ {t.kind = 68; break;}
case 33:
- {t.kind = 71; break;}
+ {t.kind = 69; break;}
case 34:
if (ch == '&') {AddCh(); goto case 35;}
else {goto case 0;}
case 35:
- {t.kind = 72; break;}
+ {t.kind = 70; break;}
case 36:
- {t.kind = 73; break;}
+ {t.kind = 71; break;}
case 37:
- {t.kind = 74; break;}
+ {t.kind = 72; break;}
case 38:
- {t.kind = 75; break;}
+ {t.kind = 73; break;}
case 39:
- {t.kind = 78; break;}
+ {t.kind = 76; break;}
case 40:
- {t.kind = 79; break;}
+ {t.kind = 77; break;}
case 41:
- {t.kind = 80; break;}
+ {t.kind = 78; break;}
case 42:
if (ch == 'n') {AddCh(); goto case 43;}
else {goto case 0;}
case 43:
- {t.kind = 81; break;}
+ {t.kind = 79; break;}
case 44:
- {t.kind = 82; break;}
+ {t.kind = 80; break;}
case 45:
- {t.kind = 83; break;}
+ {t.kind = 81; break;}
case 46:
- {t.kind = 84; break;}
+ {t.kind = 82; break;}
case 47:
- {t.kind = 85; break;}
+ {t.kind = 83; break;}
case 48:
- {t.kind = 86; break;}
+ {t.kind = 84; break;}
case 49:
- {t.kind = 87; break;}
+ {t.kind = 85; break;}
case 50:
- {t.kind = 88; break;}
+ {t.kind = 86; break;}
case 51:
- {t.kind = 90; break;}
+ {t.kind = 88; break;}
case 52:
- {t.kind = 94; break;}
+ {t.kind = 97; break;}
case 53:
- {t.kind = 98; break;}
+ {t.kind = 99; break;}
case 54:
- {t.kind = 102; break;}
+ {t.kind = 101; break;}
case 55:
- {t.kind = 104; break;}
+ {t.kind = 102; break;}
case 56:
- {t.kind = 105; break;}
+ {t.kind = 103; break;}
case 57:
- {t.kind = 106; break;}
+ recEnd = pos; recKind = 15;
+ if (ch == '>') {AddCh(); goto case 25;}
+ else if (ch == '=') {AddCh(); goto case 64;}
+ else {t.kind = 15; break;}
case 58:
recEnd = pos; recKind = 16;
- if (ch == '>') {AddCh(); goto case 25;}
- else if (ch == '=') {AddCh(); goto case 65;}
+ if (ch == '|') {AddCh(); goto case 37;}
else {t.kind = 16; break;}
case 59:
- recEnd = pos; recKind = 17;
- if (ch == '|') {AddCh(); goto case 37;}
- else {t.kind = 17; break;}
- case 60:
recEnd = pos; recKind = 22;
if (ch == '=') {AddCh(); goto case 26;}
- else if (ch == ':') {AddCh(); goto case 56;}
+ else if (ch == ':') {AddCh(); goto case 55;}
else {t.kind = 22; break;}
- case 61:
+ case 60:
recEnd = pos; recKind = 23;
- if (ch == '=') {AddCh(); goto case 66;}
+ if (ch == '=') {AddCh(); goto case 65;}
else {t.kind = 23; break;}
- case 62:
+ case 61:
recEnd = pos; recKind = 24;
if (ch == '=') {AddCh(); goto case 39;}
else {t.kind = 24; break;}
- case 63:
+ case 62:
recEnd = pos; recKind = 54;
- if (ch == '.') {AddCh(); goto case 53;}
+ if (ch == '.') {AddCh(); goto case 52;}
else {t.kind = 54; break;}
- case 64:
- recEnd = pos; recKind = 89;
+ case 63:
+ recEnd = pos; recKind = 87;
if (ch == '=') {AddCh(); goto case 40;}
else if (ch == '!') {AddCh(); goto case 41;}
else if (ch == 'i') {AddCh(); goto case 42;}
- else {t.kind = 89; break;}
- case 65:
- recEnd = pos; recKind = 76;
+ else {t.kind = 87; break;}
+ case 64:
+ recEnd = pos; recKind = 74;
if (ch == '>') {AddCh(); goto case 32;}
- else {t.kind = 76; break;}
- case 66:
- recEnd = pos; recKind = 77;
+ else {t.kind = 74; break;}
+ case 65:
+ recEnd = pos; recKind = 75;
if (ch == '=') {AddCh(); goto case 29;}
- else {t.kind = 77; break;}
+ else {t.kind = 75; break;}
}
t.val = new String(tval, 0, tlen);
diff --git a/Dafny/Translator.cs b/Dafny/Translator.cs
index f224f35e..54a51d11 100644
--- a/Dafny/Translator.cs
+++ b/Dafny/Translator.cs
@@ -506,7 +506,7 @@ namespace Microsoft.Dafny {
Contract.Requires(me != null);
Contract.Requires(layerOffset == 0 || layerOffset == 1);
- IVariable formal = ((IdentifierExpr)me.Source).Var; // correctness of casts follows from what resolution checks
+ IVariable formal = ((IdentifierExpr)me.Source.Resolved).Var; // correctness of casts follows from what resolution checks
foreach (MatchCaseExpr mc in me.Cases) {
Contract.Assert(mc.Ctor != null); // the field is filled in by resolution
Specialization s = new Specialization(formal, mc, prev);
@@ -1546,6 +1546,9 @@ namespace Microsoft.Dafny {
total = BplAnd(total, Bpl.Expr.Imp(test, IsTotal(e.Thn, etran)));
total = BplAnd(total, Bpl.Expr.Imp(Bpl.Expr.Not(test), IsTotal(e.Els, etran)));
return total;
+ } else if (expr is ConcreteSyntaxExpression) {
+ var e = (ConcreteSyntaxExpression)expr;
+ return IsTotal(e.ResolvedExpression, etran);
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
}
@@ -1676,6 +1679,9 @@ namespace Microsoft.Dafny {
total = BplAnd(total, Bpl.Expr.Imp(test, CanCallAssumption(e.Thn, etran)));
total = BplAnd(total, Bpl.Expr.Imp(Bpl.Expr.Not(test), CanCallAssumption(e.Els, etran)));
return total;
+ } else if (expr is ConcreteSyntaxExpression) {
+ var e = (ConcreteSyntaxExpression)expr;
+ return CanCallAssumption(e.ResolvedExpression, etran);
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
}
@@ -1878,7 +1884,7 @@ namespace Microsoft.Dafny {
Dictionary<IVariable,Expression> substMap = new Dictionary<IVariable,Expression>();
for (int i = 0; i < e.Function.Formals.Count; i++) {
Formal p = e.Function.Formals[i];
- VarDecl local = new VarDecl(p.tok, p.Name, p.Type, p.IsGhost, null);
+ VarDecl local = new VarDecl(p.tok, p.Name, p.Type, p.IsGhost);
local.type = local.OptionalType; // resolve local here
IdentifierExpr ie = new IdentifierExpr(local.Tok, local.UniqueName);
ie.Var = local; ie.Type = ie.Var.Type; // resolve ie here
@@ -2010,7 +2016,7 @@ namespace Microsoft.Dafny {
var e = (ComprehensionExpr)expr;
Dictionary<IVariable,Expression> substMap = new Dictionary<IVariable,Expression>();
foreach (BoundVar bv in e.BoundVars) {
- VarDecl local = new VarDecl(bv.tok, bv.Name, bv.Type, bv.IsGhost, null);
+ VarDecl local = new VarDecl(bv.tok, bv.Name, bv.Type, bv.IsGhost);
local.type = local.OptionalType; // resolve local here
IdentifierExpr ie = new IdentifierExpr(local.Tok, local.UniqueName);
ie.Var = local; ie.Type = ie.Var.Type; // resolve ie here
@@ -2083,7 +2089,11 @@ namespace Microsoft.Dafny {
}
builder.Add(ifCmd);
result = null;
-
+
+ } else if (expr is ConcreteSyntaxExpression) {
+ var e = (ConcreteSyntaxExpression)expr;
+ CheckWellformedWithResult(e.ResolvedExpression, options, result, resultType, locals, builder, etran);
+
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression
}
@@ -2889,7 +2899,6 @@ namespace Microsoft.Dafny {
Contract.Requires(etran != null);
Contract.Requires(currentMethod != null && predef != null);
Contract.Ensures(Contract.Result<Bpl.StmtList>() != null);
-
return TrStmt2StmtList(new Bpl.StmtListBuilder(), block, locals, etran);
}
@@ -2902,7 +2911,6 @@ namespace Microsoft.Dafny {
Contract.Requires(etran != null);
Contract.Requires(currentMethod != null && predef != null);
Contract.Ensures(Contract.Result<Bpl.StmtList>() != null);
-
TrStmt(block, builder, locals, etran);
return builder.Collect(block.Tok); // TODO: would be nice to have an end-curly location for "block"
@@ -2936,12 +2944,6 @@ namespace Microsoft.Dafny {
AssumeStmt s = (AssumeStmt)stmt;
TrStmt_CheckWellformed(s.Expr, builder, locals, etran, false);
builder.Add(new Bpl.AssumeCmd(stmt.Tok, etran.TrExpr(s.Expr)));
- } else if (stmt is UseStmt) {
- AddComment(builder, stmt, "use statement");
- UseStmt s = (UseStmt)stmt;
- // Skip the definedness check. This makes the 'use' statement easier to use and it has no executable analog anyhow
- // TrStmt_CheckWellformed(s.Expr, builder, locals, etran);
- builder.Add(new Bpl.AssumeCmd(stmt.Tok, (s.EvalInOld ? etran.Old : etran).TrUseExpr(s.FunctionCallExpr)));
} else if (stmt is PrintStmt) {
AddComment(builder, stmt, "print statement");
PrintStmt s = (PrintStmt)stmt;
@@ -2951,19 +2953,17 @@ namespace Microsoft.Dafny {
}
}
- } else if (stmt is LabelStmt) {
- AddComment(builder, stmt, "label statement"); // TODO: ouch, comments probably mess up what the label labels in the Boogie program
- builder.AddLabelCmd(((LabelStmt)stmt).Label);
} else if (stmt is BreakStmt) {
AddComment(builder, stmt, "break statement");
- builder.Add(new Bpl.BreakCmd(stmt.Tok, ((BreakStmt)stmt).TargetLabel)); // TODO: handle name clashes of labels
+ var s = (BreakStmt)stmt;
+ builder.Add(new GotoCmd(s.Tok, new StringSeq("after_" + s.TargetStmt.Labels.UniqueId)));
} else if (stmt is ReturnStmt) {
AddComment(builder, stmt, "return statement");
builder.Add(new Bpl.ReturnCmd(stmt.Tok));
} else if (stmt is AssignStmt) {
AddComment(builder, stmt, "assignment statement");
AssignStmt s = (AssignStmt)stmt;
- TrAssignment(stmt.Tok, s.Lhs, s.Rhs, builder, locals, etran);
+ TrAssignment(stmt.Tok, s.Lhs.Resolved, s.Rhs, builder, locals, etran);
} else if (stmt is VarDecl) {
AddComment(builder, stmt, "var-declaration statement");
VarDecl s = (VarDecl)stmt;
@@ -2971,19 +2971,16 @@ namespace Microsoft.Dafny {
Bpl.Expr wh = GetWhereClause(stmt.Tok, new Bpl.IdentifierExpr(stmt.Tok, s.UniqueName, varType), s.Type, etran);
Bpl.LocalVariable var = new Bpl.LocalVariable(stmt.Tok, new Bpl.TypedIdent(stmt.Tok, s.UniqueName, varType, wh));
locals.Add(var);
- if (s.Rhs != null) {
- IdentifierExpr ide = new IdentifierExpr(stmt.Tok, var.Name); // allocate an expression for the assignment LHS...
- ide.Var = s; ide.Type = s.Type; // ... and resolve it right here
- TrAssignment(stmt.Tok, ide, s.Rhs, builder, locals, etran);
- }
} else if (stmt is CallStmt) {
- CallStmt s = (CallStmt)stmt;
- TrCallStmt(s, builder, locals, etran, null);
+ TrCallStmt((CallStmt)stmt, builder, locals, etran, null);
} else if (stmt is BlockStmt) {
foreach (Statement ss in ((BlockStmt)stmt).Body) {
TrStmt(ss, builder, locals, etran);
+ if (ss.Labels != null) {
+ builder.AddLabelCmd("after_" + ss.Labels.UniqueId);
+ }
}
} else if (stmt is IfStmt) {
AddComment(builder, stmt, "if statement");
@@ -3107,16 +3104,9 @@ namespace Microsoft.Dafny {
Bpl.Expr q = new Bpl.ForallExpr(ps.Expr.tok, new Bpl.VariableSeq(oVar), Bpl.Expr.Imp(oInS, eIsTotal));
builder.Add(AssertNS(ps.Expr.tok, q, "assume condition must be well defined")); // totality check
} else {
- Contract.Assert(ps is UseStmt);
- // no totality check (see UseStmt case above)
- }
- Bpl.Expr enchilada; // the whole enchilada
- if (ps is UseStmt) {
- UseStmt us = (UseStmt)ps;
- enchilada = (us.EvalInOld ? etran.Old : etran).TrUseExpr(us.FunctionCallExpr);
- } else {
- enchilada = etran.TrExpr(ps.Expr);
+ Contract.Assert(false);
}
+ Bpl.Expr enchilada = etran.TrExpr(ps.Expr); // the whole enchilada
Bpl.Expr qEnchilada = new Bpl.ForallExpr(ps.Expr.tok, new Bpl.VariableSeq(oVar), Bpl.Expr.Imp(oInS, enchilada));
builder.Add(new Bpl.AssumeCmd(ps.Expr.tok, qEnchilada));
}
@@ -3223,6 +3213,13 @@ namespace Microsoft.Dafny {
Contract.Assert(ifCmd != null); // follows from the fact that s.Cases.Count + s.MissingCases.Count != 0.
builder.Add(ifCmd);
+ } else if (stmt is ConcreteSyntaxStatement) {
+ var s = (ConcreteSyntaxStatement)stmt;
+ // TODO: Update statements should perform multiple assignments in parallel!
+ foreach (var ss in s.ResolvedStatements) {
+ TrStmt(ss, builder, locals, etran);
+ }
+
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
}
@@ -3249,7 +3246,7 @@ namespace Microsoft.Dafny {
locals.Add(preLoopHeapVar);
Bpl.IdentifierExpr preLoopHeap = new Bpl.IdentifierExpr(s.Tok, preLoopHeapVar);
ExpressionTranslator etranPreLoop = new ExpressionTranslator(this, predef, preLoopHeap);
- builder.Add(Bpl.Cmd.SimpleAssign(s.Tok, preLoopHeap, etran.HeapExpr)); // TODO: does this screw up labeled breaks for this loop?
+ builder.Add(Bpl.Cmd.SimpleAssign(s.Tok, preLoopHeap, etran.HeapExpr));
List<Bpl.Expr> initDecr = null;
if (!Contract.Exists(theDecreases, e => e is WildcardExpr)) {
@@ -3422,9 +3419,6 @@ namespace Microsoft.Dafny {
Contract.Requires(etran != null);
Expression receiver = actualReceiver == null ? s.Receiver : new BoogieWrapper(actualReceiver);
- foreach (VarDecl local in s.NewVars) {
- TrStmt(local, builder, locals, etran);
- }
AddComment(builder, s, actualReceiver == null ? "call statement" : "init call statement");
Bpl.ExprSeq ins = new Bpl.ExprSeq();
Contract.Assert(s.Method != null); // follows from the fact that stmt has been successfully resolved
@@ -3439,7 +3433,7 @@ namespace Microsoft.Dafny {
Dictionary<IVariable, Expression> substMap = new Dictionary<IVariable, Expression>();
for (int i = 0; i < s.Method.Ins.Count; i++) {
Formal p = s.Method.Ins[i];
- VarDecl local = new VarDecl(p.tok, p.Name, p.Type, p.IsGhost, null);
+ VarDecl local = new VarDecl(p.tok, p.Name, p.Type, p.IsGhost);
local.type = local.OptionalType; // resolve local here
IdentifierExpr ie = new IdentifierExpr(local.Tok, local.UniqueName);
ie.Var = local; ie.Type = ie.Var.Type; // resolve ie here
@@ -3896,6 +3890,7 @@ namespace Microsoft.Dafny {
{
Contract.Requires(tok != null);
Contract.Requires(lhs != null);
+ Contract.Requires(!(lhs is ConcreteSyntaxExpression));
Contract.Requires(rhs != null);
Contract.Requires(builder != null);
Contract.Requires(cce.NonNullElements(locals));
@@ -4636,7 +4631,11 @@ namespace Microsoft.Dafny {
Bpl.Expr thn = TrExpr(e.Thn);
Bpl.Expr els = TrExpr(e.Els);
return new NAryExpr(expr.tok, new IfThenElse(expr.tok), new ExprSeq(g, thn, els));
-
+
+ } else if (expr is ConcreteSyntaxExpression) {
+ var e = (ConcreteSyntaxExpression)expr;
+ return TrExpr(e.ResolvedExpression);
+
} else if (expr is BoxingCastExpr) {
BoxingCastExpr e = (BoxingCastExpr)expr;
return CondApplyBox(e.tok, TrExpr(e.E), e.FromType, e.ToType);
@@ -4720,30 +4719,6 @@ namespace Microsoft.Dafny {
translator.FunctionCall(tok, BuiltinFunction.SeqSameUntil, null, e0, e1, len0));
}
- public Bpl.Expr TrUseExpr(FunctionCallExpr e)
- {
- Contract.Requires(e != null); Contract.Requires(e.Function != null && e.Type != null);
- Contract.Ensures(Contract.Result<Bpl.Expr>() != null);
-
- Function fn = e.Function;
- Bpl.ExprSeq args = new Bpl.ExprSeq();
- args.Add(HeapExpr);
- if (!fn.IsStatic) {
- args.Add(TrExpr(e.Receiver));
- }
- foreach (Expression ee in e.Args) {
- args.Add(TrExpr(ee));
- }
- Bpl.Expr f0 = new Bpl.NAryExpr(e.tok, new Bpl.FunctionCall(new Bpl.IdentifierExpr(e.tok, fn.FullName, translator.TrType(e.Type))), args);
- Bpl.Expr f1;
- if (fn.IsRecursive && !fn.IsUnlimited) {
- f1 = new Bpl.NAryExpr(e.tok, new Bpl.FunctionCall(new Bpl.IdentifierExpr(e.tok, FunctionName(fn, 0), translator.TrType(e.Type))), args);
- } else {
- f1 = f0;
- }
- return Bpl.Expr.Eq(f0, f1);
- }
-
public Bpl.Expr CondApplyBox(IToken tok, Bpl.Expr e, Type fromType, Type toType) {
Contract.Requires(tok != null);
Contract.Requires(e != null);
@@ -5301,6 +5276,10 @@ namespace Microsoft.Dafny {
return true;
}
+ } else if (expr is ConcreteSyntaxExpression) {
+ var e = (ConcreteSyntaxExpression)expr;
+ return TrSplitExpr(e.ResolvedExpression, splits, expandFunctions, etran);
+
} else if (expr is BinaryExpr) {
var bin = (BinaryExpr)expr;
if (bin.ResolvedOp == BinaryExpr.ResolvedOpcode.And) {
@@ -5665,6 +5644,9 @@ namespace Microsoft.Dafny {
return VarOccursInArgumentToRecursiveFunction(e.Test, n, null) || // test is not "elevated"
VarOccursInArgumentToRecursiveFunction(e.Thn, n, p) || // but the two branches are
VarOccursInArgumentToRecursiveFunction(e.Els, n, p);
+ } else if (expr is ConcreteSyntaxExpression) {
+ var e = (ConcreteSyntaxExpression)expr;
+ return VarOccursInArgumentToRecursiveFunction(e.ResolvedExpression, n, p);
} else if (expr is BoxingCastExpr) {
var e = (BoxingCastExpr)expr;
return VarOccursInArgumentToRecursiveFunction(e.E, n, p);
@@ -5858,6 +5840,10 @@ namespace Microsoft.Dafny {
if (test != e.Test || thn != e.Thn || els != e.Els) {
newExpr = new ITEExpr(expr.tok, test, thn, els);
}
+
+ } else if (expr is ConcreteSyntaxExpression) {
+ var e = (ConcreteSyntaxExpression)expr;
+ return Substitute(e.ResolvedExpression, receiverReplacement, substMap);
}
if (newExpr == null) {
diff --git a/Test/VSComp2010/Problem1-SumMax.dfy b/Test/VSComp2010/Problem1-SumMax.dfy
index 1b105ac1..3db9bf72 100644
--- a/Test/VSComp2010/Problem1-SumMax.dfy
+++ b/Test/VSComp2010/Problem1-SumMax.dfy
@@ -38,6 +38,6 @@ method Main()
a[7] := 1;
a[8] := 10;
a[9] := 6;
- call s, m := M(10, a);
+ var s, m := M(10, a);
print "N = ", a.Length, " sum = ", s, " max = ", m, "\n";
}
diff --git a/Test/VSComp2010/Problem2-Invert.dfy b/Test/VSComp2010/Problem2-Invert.dfy
index bf6aca37..2a262d70 100644
--- a/Test/VSComp2010/Problem2-Invert.dfy
+++ b/Test/VSComp2010/Problem2-Invert.dfy
@@ -61,11 +61,11 @@ method Main()
a[8] := 5;
a[9] := 6;
var b := new int[10];
- call M(10, a, b);
+ M(10, a, b);
print "a:\n";
- call PrintArray(a);
+ PrintArray(a);
print "b:\n";
- call PrintArray(b);
+ PrintArray(b);
}
method PrintArray(a: array<int>)
diff --git a/Test/VSComp2010/Problem3-FindZero.dfy b/Test/VSComp2010/Problem3-FindZero.dfy
index 03e6bdfe..3d24255d 100644
--- a/Test/VSComp2010/Problem3-FindZero.dfy
+++ b/Test/VSComp2010/Problem3-FindZero.dfy
@@ -82,11 +82,11 @@ static method Search(ll: Node) returns (r: int)
method Main()
{
var list: Node := null;
- call list := list.Cons(0, list);
- call list := list.Cons(5, list);
- call list := list.Cons(0, list);
- call list := list.Cons(8, list);
- call r := Search(list);
+ list := list.Cons(0, list);
+ list := list.Cons(5, list);
+ list := list.Cons(0, list);
+ list := list.Cons(8, list);
+ var r := Search(list);
print "Search returns ", r, "\n";
assert r == 1;
}
diff --git a/Test/VSComp2010/Problem4-Queens.dfy b/Test/VSComp2010/Problem4-Queens.dfy
index ef084674..2f21b7a1 100644
--- a/Test/VSComp2010/Problem4-Queens.dfy
+++ b/Test/VSComp2010/Problem4-Queens.dfy
@@ -39,7 +39,7 @@ method Search(N: int) returns (success: bool, board: seq<int>)
==>
(exists p :: 0 <= p && p < N && !IsConsistent(B, p)));
{
- call success, board := SearchAux(N, []);
+ success, board := SearchAux(N, []);
}
// Given a board, this function says whether or not the queen placed in column 'pos'
@@ -110,7 +110,7 @@ method SearchAux(N: int, boardSoFar: seq<int>) returns (success: bool, newBoard:
// Thus, we meet the precondition of 'SearchAux' on 'candidateBoard', so let's search
// for a solution that extends 'candidateBoard'.
- call s, b := SearchAux(N, candidateBoard);
+ var s, b := SearchAux(N, candidateBoard);
if (s) {
// The recursive call to 'SearchAux' found consistent positions for all remaining columns
newBoard := b;
@@ -137,11 +137,11 @@ method SearchAux(N: int, boardSoFar: seq<int>) returns (success: bool, newBoard:
method Main()
{
- call s, b := Search(2);
+ var s, b := Search(2);
print "N=2 returns ", s, "\n";
- call s, b := Search(4);
+ s, b := Search(4);
print "N=4 returns ", s, "\n";
- call PrintSeq(b);
+ PrintSeq(b);
}
method PrintSeq(b: seq<int>)
diff --git a/Test/VSComp2010/Problem5-DoubleEndedQueue.dfy b/Test/VSComp2010/Problem5-DoubleEndedQueue.dfy
index df8cb1b7..0e141927 100644
--- a/Test/VSComp2010/Problem5-DoubleEndedQueue.dfy
+++ b/Test/VSComp2010/Problem5-DoubleEndedQueue.dfy
@@ -46,8 +46,8 @@ class AmortizedQueue<T> {
front := f;
rear := r;
} else {
- call rr := r.Reverse();
- call ff := f.Concat(rr);
+ var rr := r.Reverse();
+ var ff := f.Concat(rr);
front := ff;
rear := new LinkedList<T>.Init();
@@ -75,7 +75,7 @@ class AmortizedQueue<T> {
requires Valid();
ensures r != null && r.Valid() && r.List == List + [item];
{
- call rr := rear.Cons(item);
+ var rr := rear.Cons(item);
r := new AmortizedQueue<T>.InitFromPieces(front, rr);
}
}
@@ -133,8 +133,8 @@ class LinkedList<T> {
if (length == 0) {
r := end;
} else {
- call c := tail.Concat(end);
- call r := c.Cons(head);
+ var c := tail.Concat(end);
+ r := c.Cons(head);
}
}
@@ -148,10 +148,10 @@ class LinkedList<T> {
if (length == 0) {
r := this;
} else {
- call r := tail.Reverse();
+ r := tail.Reverse();
var e := new LinkedList<T>.Init();
- call e := e.Cons(head);
- call r := r.Concat(e);
+ e := e.Cons(head);
+ r := r.Concat(e);
}
}
diff --git a/Test/VSI-Benchmarks/b1.dfy b/Test/VSI-Benchmarks/b1.dfy
index cd4a18c2..3bd2bf43 100644
--- a/Test/VSI-Benchmarks/b1.dfy
+++ b/Test/VSI-Benchmarks/b1.dfy
@@ -35,37 +35,37 @@ method Mul(x: int, y: int) returns (r: int)
if (x == 0) {
r := 0;
} else if (x < 0) {
- call r := Mul(-x, y);
+ r := Mul(-x, y);
r := -r;
} else {
- call r := Mul(x-1, y);
- call r := Add(r, y);
+ r := Mul(x-1, y);
+ r := Add(r, y);
}
}
// ---------------------------
method Main() {
- call TestAdd(3, 180);
- call TestAdd(3, -180);
- call TestAdd(0, 1);
+ TestAdd(3, 180);
+ TestAdd(3, -180);
+ TestAdd(0, 1);
- call TestMul(3, 180);
- call TestMul(3, -180);
- call TestMul(180, 3);
- call TestMul(-180, 3);
- call TestMul(0, 1);
- call TestMul(1, 0);
+ TestMul(3, 180);
+ TestMul(3, -180);
+ TestMul(180, 3);
+ TestMul(-180, 3);
+ TestMul(0, 1);
+ TestMul(1, 0);
}
method TestAdd(x: int, y: int) {
print x, " + ", y, " = ";
- call z := Add(x, y);
+ var z := Add(x, y);
print z, "\n";
}
method TestMul(x: int, y: int) {
print x, " * ", y, " = ";
- call z := Mul(x, y);
+ var z := Mul(x, y);
print z, "\n";
}
diff --git a/Test/VSI-Benchmarks/b2.dfy b/Test/VSI-Benchmarks/b2.dfy
index 6c6f11b3..3046621b 100644
--- a/Test/VSI-Benchmarks/b2.dfy
+++ b/Test/VSI-Benchmarks/b2.dfy
@@ -38,13 +38,13 @@ method Main() {
a[2] := -2;
a[3] := 0;
a[4] := 25;
- call TestSearch(a, 4);
- call TestSearch(a, -8);
- call TestSearch(a, -2);
- call TestSearch(a, 0);
- call TestSearch(a, 23);
- call TestSearch(a, 25);
- call TestSearch(a, 27);
+ TestSearch(a, 4);
+ TestSearch(a, -8);
+ TestSearch(a, -2);
+ TestSearch(a, 0);
+ TestSearch(a, 23);
+ TestSearch(a, 25);
+ TestSearch(a, 27);
}
method TestSearch(a: array<int>, key: int)
@@ -52,6 +52,6 @@ method TestSearch(a: array<int>, key: int)
requires (forall i, j :: 0 <= i && i < j && j < a.Length ==> a[i] <= a[j]);
{
var b := new Benchmark2;
- call r := b.BinarySearch(a, key);
+ var r := b.BinarySearch(a, key);
print "Looking for key=", key, ", result=", r, "\n";
}
diff --git a/Test/VSI-Benchmarks/b3.dfy b/Test/VSI-Benchmarks/b3.dfy
index 3f30c4b5..3de94555 100644
--- a/Test/VSI-Benchmarks/b3.dfy
+++ b/Test/VSI-Benchmarks/b3.dfy
@@ -87,10 +87,10 @@ class Benchmark3 {
invariant (forall i :: 0 <= i && i < |perm| ==> r.contents[i] == old(q.contents)[perm[i]]);
invariant (forall i :: 0 <= i && i < |p| ==> q.contents[i] == old(q.contents)[p[i]]);
{
- call m,k := RemoveMin(q);
+ var m,k := RemoveMin(q);
perm := perm + [p[k]]; //adds index of min to perm
p := p[k+1..] + p[..k]; //remove index of min from p
- call r.Enqueue(m);
+ r.Enqueue(m);
pperm := pperm[k+1..|p|+1] + pperm[..k] + pperm[|p|+1..] + [pperm[k]];
}
}
@@ -116,8 +116,8 @@ class Benchmark3 {
invariant 0 <= k && k < |old(q.contents)| && old(q.contents)[k] == m;
invariant (forall i :: 0<= i && i < j ==> m <= old(q.contents)[i]); //m is min so far
{
- call x:= q.Dequeue();
- call q.Enqueue(x);
+ var x := q.Dequeue();
+ q.Enqueue(x);
if (x < m) { k := j; m := x; }
j := j+1;
}
@@ -127,11 +127,11 @@ class Benchmark3 {
invariant j <= k;
invariant q.contents == old(q.contents)[j..] + old(q.contents)[..j];
{
- call x := q.Dequeue();
- call q.Enqueue(x);
+ var x := q.Dequeue();
+ q.Enqueue(x);
j := j+1;
}
- call m:= q.Dequeue();
+ m := q.Dequeue();
}
}
diff --git a/Test/VSI-Benchmarks/b4.dfy b/Test/VSI-Benchmarks/b4.dfy
index ebaeab84..b70ff4d0 100644
--- a/Test/VSI-Benchmarks/b4.dfy
+++ b/Test/VSI-Benchmarks/b4.dfy
@@ -54,7 +54,7 @@ class Map<Key,Value> {
ensures !present ==> key !in Keys;
ensures present ==> (exists i :: 0 <= i && i < |Keys| && Keys[i] == key && Values[i] == val);
{
- call p, n, prev := FindIndex(key);
+ var p, n, prev := FindIndex(key);
if (p == null) {
present := false;
} else {
@@ -74,7 +74,7 @@ class Map<Key,Value> {
Keys[j] == old(Keys)[j] && Values[j] == old(Values)[j]));
ensures key !in old(Keys) ==> Keys == [key] + old(Keys) && Values == [val] + old(Values);
{
- call p, n, prev := FindIndex(key);
+ var p, n, prev := FindIndex(key);
if (p == null) {
var h := new Node<Key,Value>;
h.key := key; h.val := val; h.next := head;
@@ -88,7 +88,7 @@ class Map<Key,Value> {
}
}
- method Remove(key: Key)
+ method Remove(key: Key)// returns (ghost h: int)
requires Valid();
modifies Repr;
ensures Valid() && fresh(Repr - old(Repr));
@@ -107,10 +107,13 @@ class Map<Key,Value> {
Keys[h..] == old(Keys)[h+1..] &&
Values[h..] == old(Values)[h+1..]);
{
- call p, n, prev := FindIndex(key);
+ var p, n, prev := FindIndex(key);
if (p != null) {
Keys := Keys[..n] + Keys[n+1..];
Values := Values[..n] + Values[n+1..];
+ assert Keys[n..] == old(Keys)[n+1..];
+ assert Values[n..] == old(Values)[n+1..];
+
nodes := nodes[..n] + nodes[n+1..];
if (prev == null) {
head := head.next;
diff --git a/Test/VSI-Benchmarks/b5.dfy b/Test/VSI-Benchmarks/b5.dfy
index d9bd36f5..cd132ef3 100644
--- a/Test/VSI-Benchmarks/b5.dfy
+++ b/Test/VSI-Benchmarks/b5.dfy
@@ -98,9 +98,9 @@ class Queue<T> {
ensures Valid() && fresh(footprint - old(footprint));
ensures contents == old(contents)[1..] + old(contents)[..1];
{
- call t := Front();
- call Dequeue();
- call Enqueue(t);
+ var t := Front();
+ Dequeue();
+ Enqueue(t);
}
method RotateAny()
@@ -112,9 +112,9 @@ class Queue<T> {
ensures (exists i :: 0 <= i && i <= |contents| &&
contents == old(contents)[i..] + old(contents)[..i]);
{
- call t := Front();
- call Dequeue();
- call Enqueue(t);
+ var t := Front();
+ Dequeue();
+ Enqueue(t);
}
}
@@ -152,18 +152,18 @@ class Main<U> {
var q0 := new Queue<T>.Init();
var q1 := new Queue<T>.Init();
- call q0.Enqueue(t);
- call q0.Enqueue(u);
+ q0.Enqueue(t);
+ q0.Enqueue(u);
- call q1.Enqueue(v);
+ q1.Enqueue(v);
assert |q0.contents| == 2;
- call w := q0.Front();
+ var w := q0.Front();
assert w == t;
- call q0.Dequeue();
+ q0.Dequeue();
- call w := q0.Front();
+ w := q0.Front();
assert w == u;
assert |q0.contents| == 1;
@@ -179,18 +179,18 @@ class Main<U> {
ensures fresh(q0.footprint - old(q0.footprint));
ensures fresh(q1.footprint - old(q1.footprint));
{
- call q0.Enqueue(t);
- call q0.Enqueue(u);
+ q0.Enqueue(t);
+ q0.Enqueue(u);
- call q1.Enqueue(v);
+ q1.Enqueue(v);
assert |q0.contents| == 2;
- call w := q0.Front();
+ var w := q0.Front();
assert w == t;
- call q0.Dequeue();
+ q0.Dequeue();
- call w := q0.Front();
+ w := q0.Front();
assert w == u;
assert |q0.contents| == 1;
diff --git a/Test/VSI-Benchmarks/b6.dfy b/Test/VSI-Benchmarks/b6.dfy
index 13086f28..fda9ca74 100644
--- a/Test/VSI-Benchmarks/b6.dfy
+++ b/Test/VSI-Benchmarks/b6.dfy
@@ -107,14 +107,14 @@ class Client
method Main()
{
var c := new Collection<int>.Init();
- call c.Add(33);
- call c.Add(45);
- call c.Add(78);
+ c.Add(33);
+ c.Add(45);
+ c.Add(78);
var s := [];
- call iter := c.GetIterator();
- call b := iter.MoveNext();
+ var iter := c.GetIterator();
+ var b := iter.MoveNext();
while (b)
invariant iter.Valid() && b == iter.HasCurrent() && fresh(iter.footprint);
@@ -123,13 +123,13 @@ class Client
invariant iter.c == c;
decreases |c.elements| - iter.pos;
{
- call x := iter.GetCurrent();
+ var x := iter.GetCurrent();
s := s + [x];
- call b := iter.MoveNext();
+ b := iter.MoveNext();
}
assert s == c.elements; //verifies that the iterator returns the correct things
- call c.Add(100);
+ c.Add(100);
}
}
diff --git a/Test/VSI-Benchmarks/b7.dfy b/Test/VSI-Benchmarks/b7.dfy
index 2304e602..f34f5c00 100644
--- a/Test/VSI-Benchmarks/b7.dfy
+++ b/Test/VSI-Benchmarks/b7.dfy
@@ -119,33 +119,34 @@ class Client {
method Main()
{
var rd := new Stream;
- call rd.Open();
+ rd.Open();
var q := new Queue<int>;
while (true)
invariant rd.Valid() && fresh(rd.footprint) && fresh(q);
decreases |rd.stream|;
{
- call eos := rd.AtEndOfStream();
+ var eos := rd.AtEndOfStream();
if (eos) {
break;
}
- call ch := rd.GetChar();
- call q.Enqueue(ch);
+ var ch := rd.GetChar();
+ q.Enqueue(ch);
}
- call rd.Close();
- call q,perm := Sort(q);
+ rd.Close();
+ var perm;
+ q,perm := Sort(q);
- var wr:= new Stream;
- call wr.Create();
+ var wr := new Stream;
+ wr.Create();
while (0 < |q.contents|)
invariant wr.Valid() && fresh(wr.footprint) && fresh(q) && q !in wr.footprint;
{
- call ch := q.Dequeue();
- call wr.PutChar(ch);
+ var ch := q.Dequeue();
+ wr.PutChar(ch);
}
- call wr.Close();
+ wr.Close();
}
}
diff --git a/Test/VSI-Benchmarks/b8.dfy b/Test/VSI-Benchmarks/b8.dfy
index 3438d6e0..0c9d1186 100644
--- a/Test/VSI-Benchmarks/b8.dfy
+++ b/Test/VSI-Benchmarks/b8.dfy
@@ -46,7 +46,7 @@ class Glossary {
method Main()
{
var rs:= new ReaderStream;
- call rs.Open();
+ rs.Open();
var glossary := new Map<Word,seq<Word>>.Init();
var q := new Queue<Word>.Init();
@@ -60,21 +60,22 @@ class Glossary {
invariant q.contents == glossary.keys;
decreases *; // we leave out the decreases clause - unbounded stream
{
- call term,definition := readDefinition(rs);
+ var term,definition := readDefinition(rs);
if (term == null) {
break;
}
- call present, d := glossary.Find(term);
+ var present, d := glossary.Find(term);
if (!present) {
- call glossary.Add(term,definition);
- call q.Enqueue(term);
+ glossary.Add(term,definition);
+ q.Enqueue(term);
}
}
- call rs.Close();
- call q,p := Sort(q);
+ rs.Close();
+ var p;
+ q,p := Sort(q);
var wr := new WriterStream;
- call wr.Create();
+ wr.Create();
while (0 < |q.contents|)
invariant wr.Valid() && fresh(wr.footprint);
@@ -84,12 +85,12 @@ class Glossary {
invariant q !in wr.footprint;
invariant (forall k :: k in q.contents ==> k in glossary.keys);
{
- call term := q.Dequeue();
- call present,definition := glossary.Find(term);
+ var term := q.Dequeue();
+ var present,definition := glossary.Find(term);
assert present;
// write term with a html anchor
- call wr.PutWordInsideTag(term, term);
+ wr.PutWordInsideTag(term, term);
var i := 0;
var qcon := q.contents;
@@ -103,19 +104,20 @@ class Glossary {
invariant (forall k :: k in q.contents ==> k in glossary.keys);
{
var w := definition[i];
- call present, d := glossary.Find(w);
+ var d;
+ present, d := glossary.Find(w);
if (present)
{
- call wr. PutWordInsideHyperlink(w, w);
+ wr. PutWordInsideHyperlink(w, w);
}
else
{
- call wr. PutWord(w);
+ wr. PutWord(w);
}
i:= i +1;
}
}
- call wr.Close();
+ wr.Close();
}
@@ -125,7 +127,7 @@ class Glossary {
ensures rs.Valid() && fresh(rs.footprint - old(rs.footprint));
ensures term != null ==> null !in definition;
{
- call term := rs.GetWord();
+ term := rs.GetWord();
if (term != null)
{
definition := [];
@@ -134,7 +136,7 @@ class Glossary {
invariant null !in definition;
decreases *; // we leave out the decreases clause - unbounded stream
{
- call w := rs.GetWord();
+ var w := rs.GetWord();
if (w == null)
{
break;
@@ -273,7 +275,7 @@ class Map<Key,Value> {
ensures present ==> (exists i :: 0 <= i && i < |keys| &&
keys[i] == key && values[i] == val);
{
- call j := FindIndex(key);
+ var j := FindIndex(key);
if (j == -1) {
present := false;
} else {
@@ -292,7 +294,7 @@ class Map<Key,Value> {
(forall j :: 0 <= j && j < |values| && i != j ==> keys[j] == old(keys)[j] && values[j] == old(values)[j]));
ensures key !in old(keys) ==> keys == old(keys) + [key] && values == old(values) + [val];
{
- call j := FindIndex(key);
+ var j := FindIndex(key);
if (j == -1) {
keys := keys + [key];
values := values + [val];
@@ -321,7 +323,7 @@ class Map<Key,Value> {
keys[h..] == old(keys)[h+1..] &&
values[h..] == old(values)[h+1..]);
{
- call j := FindIndex(key);
+ var j := FindIndex(key);
if (0 <= j) {
keys := keys[..j] + keys[j+1..];
values := values[..j] + values[j+1..];
diff --git a/Test/dafny0/Answer b/Test/dafny0/Answer
index 0ce74a98..b8d94b06 100644
--- a/Test/dafny0/Answer
+++ b/Test/dafny0/Answer
@@ -22,10 +22,10 @@ class MyClass<T, U> {
} else {
this.x := x + 0;
}
- call t, u, v := M(true, lotsaObjects);
+ t, u, v := M(true, lotsaObjects);
var to: MyClass<T,U>;
- call to, u, v := M(true, lotsaObjects);
- call to, u, v := to.M(true, lotsaObjects);
+ to, u, v := this.M(true, lotsaObjects);
+ to, u, v := to.M(true, lotsaObjects);
assert v[x] != null ==> null !in v[2 .. x][1..][5 := v[this.x]][..10];
}
}
@@ -46,16 +46,9 @@ class MyClass<T, U> {
}
}
-datatype List<T> {
- Nil;
- Cons(T, List<T>);
-}
+datatype List<T> = Nil | Cons(T, List<T>);
-datatype WildData {
- Something;
- JustAboutAnything<G, H>(G, myName: set<H>, int, WildData);
- More(List<int>);
-}
+datatype WildData = Something | JustAboutAnything(bool, myName: set<int>, int, WildData) | More(List<int>);
class C {
var w: WildData;
@@ -65,32 +58,31 @@ class C {
Dafny program verifier finished with 0 verified, 0 errors
-------------------- TypeTests.dfy --------------------
-TypeTests.dfy(95,9): Error: sorry, cannot instantiate collection type with a subrange type
+TypeTests.dfy(84,9): Error: sorry, cannot instantiate collection type with a subrange type
TypeTests.dfy(4,13): Error: incorrect type of function argument 0 (expected C, got D)
TypeTests.dfy(4,13): Error: incorrect type of function argument 1 (expected D, got C)
TypeTests.dfy(5,13): Error: incorrect type of function argument 0 (expected C, got int)
TypeTests.dfy(5,13): Error: incorrect type of function argument 1 (expected D, got int)
-TypeTests.dfy(11,4): Error: incorrect type of method in-parameter 0 (expected int, got bool)
-TypeTests.dfy(12,4): Error: incorrect type of method out-parameter 0 (expected int, got C)
-TypeTests.dfy(12,4): Error: incorrect type of method out-parameter 1 (expected C, got int)
-TypeTests.dfy(20,9): Error: because of cyclic dependencies among constructor argument types, no instances of datatype 'Nothing' can be constructed
-TypeTests.dfy(23,9): Error: because of cyclic dependencies among constructor argument types, no instances of datatype 'NeverendingList' can be constructed
-TypeTests.dfy(55,9): Error: Assignment to array element is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)
-TypeTests.dfy(64,6): Error: Duplicate local-variable name: z
-TypeTests.dfy(66,6): Error: Duplicate local-variable name: x
-TypeTests.dfy(69,8): Error: Duplicate local-variable name: x
-TypeTests.dfy(72,6): Error: Duplicate local-variable name: y
-TypeTests.dfy(79,17): Error: member F in class C does not refer to a method
-TypeTests.dfy(80,17): Error: a method called as an initialization method must not have any result arguments
-TypeTests.dfy(89,10): Error: Assignment to range of array elements must have a simple expression RHS; try using a temporary local variable
-TypeTests.dfy(90,2): Error: Assignment to range of array elements must have a simple expression RHS; try using a temporary local variable
-TypeTests.dfy(96,9): Error: sorry, cannot instantiate type parameter with a subrange type
-TypeTests.dfy(97,6): Error: sorry, cannot instantiate 'array' type with a subrange type
-TypeTests.dfy(98,6): Error: sorry, cannot instantiate 'array' type with a subrange type
-22 resolution/type errors detected in TypeTests.dfy
+TypeTests.dfy(11,15): Error: incorrect type of method in-parameter 0 (expected int, got bool)
+TypeTests.dfy(12,11): Error: incorrect type of method out-parameter 0 (expected int, got C)
+TypeTests.dfy(12,11): Error: incorrect type of method out-parameter 1 (expected C, got int)
+TypeTests.dfy(18,9): Error: because of cyclic dependencies among constructor argument types, no instances of datatype 'NeverendingList' can be constructed
+TypeTests.dfy(44,9): Error: Assignment to array element is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)
+TypeTests.dfy(53,6): Error: Duplicate local-variable name: z
+TypeTests.dfy(55,6): Error: Duplicate local-variable name: x
+TypeTests.dfy(58,8): Error: Duplicate local-variable name: x
+TypeTests.dfy(61,6): Error: Duplicate local-variable name: y
+TypeTests.dfy(68,17): Error: member F in class C does not refer to a method
+TypeTests.dfy(69,17): Error: a method called as an initialization method must not have any result arguments
+TypeTests.dfy(78,10): Error: Assignment to range of array elements must have a simple expression RHS; try using a temporary local variable
+TypeTests.dfy(79,2): Error: Assignment to range of array elements must have a simple expression RHS; try using a temporary local variable
+TypeTests.dfy(85,9): Error: sorry, cannot instantiate type parameter with a subrange type
+TypeTests.dfy(86,8): Error: sorry, cannot instantiate 'array' type with a subrange type
+TypeTests.dfy(87,8): Error: sorry, cannot instantiate 'array' type with a subrange type
+21 resolution/type errors detected in TypeTests.dfy
-------------------- NatTypes.dfy --------------------
-NatTypes.dfy(7,10): Error: value assigned to a nat must be non-negative
+NatTypes.dfy(7,5): Error: value assigned to a nat must be non-negative
Execution trace:
(0,0): anon0
NatTypes.dfy(31,5): Error: value assigned to a nat must be non-negative
@@ -114,16 +106,16 @@ NatTypes.dfy(54,16): Error: assertion violation
Execution trace:
(0,0): anon0
(0,0): anon3_Then
-NatTypes.dfy(71,16): Error: assertion violation
+NatTypes.dfy(68,16): Error: assertion violation
Execution trace:
(0,0): anon0
(0,0): anon5_Else
(0,0): anon6_Then
-NatTypes.dfy(89,9): Error: value assigned to a nat must be non-negative
+NatTypes.dfy(86,16): Error: value assigned to a nat must be non-negative
Execution trace:
(0,0): anon0
(0,0): anon3_Then
-NatTypes.dfy(104,45): Error: value assigned to a nat must be non-negative
+NatTypes.dfy(101,45): Error: value assigned to a nat must be non-negative
Execution trace:
(0,0): anon6_Else
(0,0): anon7_Else
@@ -160,11 +152,11 @@ Execution trace:
(0,0): anon0
(0,0): anon4_Else
(0,0): anon3
-SmallTests.dfy(129,7): Error: call may violate caller's modifies clause
+SmallTests.dfy(129,9): Error: call may violate caller's modifies clause
Execution trace:
(0,0): anon0
(0,0): anon3_Then
-SmallTests.dfy(131,7): Error: call may violate caller's modifies clause
+SmallTests.dfy(131,9): Error: call may violate caller's modifies clause
Execution trace:
(0,0): anon0
(0,0): anon3_Else
@@ -192,14 +184,14 @@ Execution trace:
(0,0): anon6
(0,0): anon14_Then
(0,0): anon11
-SmallTests.dfy(272,24): Error BP5002: A precondition for this call might not hold.
-SmallTests.dfy(250,30): Related location: This is the precondition that might not hold.
+SmallTests.dfy(271,24): Error BP5002: A precondition for this call might not hold.
+SmallTests.dfy(249,30): Related location: This is the precondition that might not hold.
Execution trace:
(0,0): anon0
- SmallTests.dfy(267,19): anon3_Else
+ SmallTests.dfy(266,19): anon3_Else
(0,0): anon2
-SmallTests.dfy(307,3): Error BP5003: A postcondition might not hold on this return path.
-SmallTests.dfy(301,11): Related location: This is the postcondition that might not hold.
+SmallTests.dfy(306,3): Error BP5003: A postcondition might not hold on this return path.
+SmallTests.dfy(300,11): Related location: This is the postcondition that might not hold.
Execution trace:
(0,0): anon0
(0,0): anon18_Else
@@ -379,7 +371,7 @@ Execution trace:
Dafny program verifier finished with 23 verified, 34 errors
-------------------- FunctionSpecifications.dfy --------------------
-FunctionSpecifications.dfy(31,13): Error: possible violation of function postcondition
+FunctionSpecifications.dfy(28,13): Error: possible violation of function postcondition
Execution trace:
(0,0): anon10_Else
(0,0): anon11_Else
@@ -387,13 +379,13 @@ Execution trace:
(0,0): anon13_Else
(0,0): anon7
(0,0): anon9
-FunctionSpecifications.dfy(40,24): Error: possible violation of function postcondition
+FunctionSpecifications.dfy(37,24): Error: possible violation of function postcondition
Execution trace:
(0,0): anon12_Else
(0,0): anon15_Else
(0,0): anon16_Then
(0,0): anon11
-FunctionSpecifications.dfy(53,11): Error: cannot prove termination; try supplying a decreases clause
+FunctionSpecifications.dfy(50,11): Error: cannot prove termination; try supplying a decreases clause
Execution trace:
(0,0): anon0
(0,0): anon9_Then
@@ -402,11 +394,57 @@ Execution trace:
Dafny program verifier finished with 3 verified, 3 errors
-------------------- ResolutionErrors.dfy --------------------
+ResolutionErrors.dfy(39,13): Error: 'this' is not allowed in a 'static' context
+ResolutionErrors.dfy(100,9): Error: ghost variables are allowed only in specification contexts
+ResolutionErrors.dfy(101,9): Error: function calls are allowed only in specification contexts (consider declaring the function a 'function method')
+ResolutionErrors.dfy(105,11): Error: ghost variables are allowed only in specification contexts
+ResolutionErrors.dfy(106,9): Error: actual out-parameter 0 is required to be a ghost variable
+ResolutionErrors.dfy(113,15): Error: ghost variables are allowed only in specification contexts
+ResolutionErrors.dfy(117,23): Error: ghost variables are allowed only in specification contexts
+ResolutionErrors.dfy(124,4): Error: ghost variables are allowed only in specification contexts
+ResolutionErrors.dfy(128,21): Error: ghost variables are allowed only in specification contexts
+ResolutionErrors.dfy(129,35): Error: ghost variables are allowed only in specification contexts
+ResolutionErrors.dfy(138,9): Error: only ghost methods can be called from this context
+ResolutionErrors.dfy(144,16): Error: 'decreases *' is not allowed on ghost loops
+ResolutionErrors.dfy(185,27): Error: ghost-context break statement is not allowed to break out of non-ghost structure
+ResolutionErrors.dfy(208,12): Error: ghost-context break statement is not allowed to break out of non-ghost loop
+ResolutionErrors.dfy(220,12): Error: trying to break out of more loop levels than there are enclosing loops
+ResolutionErrors.dfy(224,12): Error: ghost-context break statement is not allowed to break out of non-ghost loop
+ResolutionErrors.dfy(229,8): Error: return statement is not allowed in this context (because this is a ghost method or because the statement is guarded by a specification-only expression)
ResolutionErrors.dfy(10,16): Error: 'decreases *' is not allowed on ghost loops
ResolutionErrors.dfy(22,11): Error: array selection requires an array2 (got array3<T>)
ResolutionErrors.dfy(23,12): Error: sequence/array selection requires a sequence or array (got array3<T>)
ResolutionErrors.dfy(24,11): Error: array selection requires an array4 (got array<T>)
-4 resolution/type errors detected in ResolutionErrors.dfy
+ResolutionErrors.dfy(45,14): Error: a field must be selected via an object, not just a class name
+ResolutionErrors.dfy(46,7): Error: unresolved identifier: F
+ResolutionErrors.dfy(47,14): Error: an instance function must be selected via an object, not just a class name
+ResolutionErrors.dfy(47,7): Error: call to instance function requires an instance
+ResolutionErrors.dfy(48,7): Error: unresolved identifier: G
+ResolutionErrors.dfy(50,7): Error: unresolved identifier: M
+ResolutionErrors.dfy(51,7): Error: call to instance method requires an instance
+ResolutionErrors.dfy(52,7): Error: unresolved identifier: N
+ResolutionErrors.dfy(55,8): Error: non-function expression is called with parameters
+ResolutionErrors.dfy(56,14): Error: member z does not exist in class Global
+ResolutionErrors.dfy(75,12): Error: the name 'Benny' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, 'Abc.Benny')
+ResolutionErrors.dfy(80,12): Error: the name 'David' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, 'Abc.David')
+ResolutionErrors.dfy(81,12): Error: the name 'David' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, 'Abc.David')
+ResolutionErrors.dfy(83,12): Error: the name 'David' denotes a datatype constructor, but does not do so uniquely; add an explicit qualification (for example, 'Abc.David')
+ResolutionErrors.dfy(85,12): Error: wrong number of arguments to datatype constructor Abc (found 2, expected 1)
+ResolutionErrors.dfy(247,4): Error: label shadows an enclosing label
+ResolutionErrors.dfy(252,2): Error: duplicate label
+38 resolution/type errors detected in ResolutionErrors.dfy
+
+-------------------- ParseErrors.dfy --------------------
+ParseErrors.dfy(4,19): error: a chain cannot have more than one != operator
+ParseErrors.dfy(6,37): error: this operator chain cannot continue with a descending operator
+ParseErrors.dfy(7,38): error: this operator chain cannot continue with an ascending operator
+ParseErrors.dfy(12,24): error: this operator chain cannot continue with a descending operator
+ParseErrors.dfy(14,18): error: this operator cannot be part of a chain
+ParseErrors.dfy(15,18): error: this operator cannot be part of a chain
+ParseErrors.dfy(16,19): error: this operator cannot be part of a chain
+ParseErrors.dfy(17,18): error: this operator cannot be part of a chain
+ParseErrors.dfy(18,18): error: chaining not allowed from the previous operator
+9 parse errors detected in ParseErrors.dfy
-------------------- Array.dfy --------------------
Array.dfy(10,12): Error: assignment may update an array element not in the enclosing method's modifies clause
@@ -498,11 +536,11 @@ Dafny program verifier finished with 7 verified, 1 error
Modules0.dfy(7,8): Error: Duplicate name of top-level declaration: T
Modules0.dfy(13,7): Error: module T named among imports does not exist
Modules0.dfy(24,7): Error: import graph contains a cycle: H -> I -> J -> G
-Modules0.dfy(51,6): Error: inter-module calls must follow the module import relation (so module X2 must transitively import YY)
-Modules0.dfy(62,6): Error: inter-module calls must follow the module import relation (so module X1 must transitively import X2)
-Modules0.dfy(72,6): Error: inter-module calls must follow the module import relation (so module X0 must transitively import X1)
-Modules0.dfy(91,4): Error: inter-module calls must follow the module import relation (so module _default must transitively import YY)
-Modules0.dfy(116,16): Error: ghost variables are allowed only in specification contexts
+Modules0.dfy(51,8): Error: inter-module calls must follow the module import relation (so module X2 must transitively import YY)
+Modules0.dfy(62,9): Error: inter-module calls must follow the module import relation (so module X1 must transitively import X2)
+Modules0.dfy(72,9): Error: inter-module calls must follow the module import relation (so module X0 must transitively import X1)
+Modules0.dfy(91,6): Error: inter-module calls must follow the module import relation (so module _default must transitively import YY)
+Modules0.dfy(116,11): Error: ghost variables are allowed only in specification contexts
Modules0.dfy(130,11): Error: old expressions are allowed only in specification and ghost contexts
Modules0.dfy(131,11): Error: fresh expressions are allowed only in specification and ghost contexts
Modules0.dfy(132,11): Error: allocated expressions are allowed only in specification and ghost contexts
@@ -511,10 +549,10 @@ Modules0.dfy(187,12): Error: match source expression 'l' has already been used a
13 resolution/type errors detected in Modules0.dfy
-------------------- Modules1.dfy --------------------
-Modules1.dfy(55,3): Error: decreases expression must be bounded below by 0
+Modules1.dfy(52,3): Error: decreases expression must be bounded below by 0
Execution trace:
(0,0): anon0
-Modules1.dfy(61,3): Error: failure to decrease termination measure
+Modules1.dfy(58,3): Error: failure to decrease termination measure
Execution trace:
(0,0): anon0
@@ -540,6 +578,22 @@ Execution trace:
Dafny program verifier finished with 6 verified, 1 error
+-------------------- Basics.dfy --------------------
+Basics.dfy(66,42): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ (0,0): anon13_Then
+ (0,0): anon14_Then
+ (0,0): anon15_Then
+ Basics.dfy(66,72): anon16_Else
+ (0,0): anon8
+ Basics.dfy(66,82): anon17_Else
+ (0,0): anon10
+ Basics.dfy(66,95): anon18_Else
+ (0,0): anon12
+
+Dafny program verifier finished with 8 verified, 1 error
+
-------------------- ControlStructures.dfy --------------------
ControlStructures.dfy(5,3): Error: missing case in case statement: Blue
Execution trace:
@@ -577,103 +631,178 @@ ControlStructures.dfy(72,3): Error: alternative cases fail to cover all possibil
Execution trace:
(0,0): anon0
(0,0): anon5_Else
-
-Dafny program verifier finished with 15 verified, 6 errors
+ControlStructures.dfy(218,18): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ ControlStructures.dfy(197,3): anon62_LoopHead
+ (0,0): anon62_LoopBody
+ ControlStructures.dfy(197,3): anon63_Else
+ (0,0): anon3
+ ControlStructures.dfy(197,3): anon64_Else
+ (0,0): anon5
+ ControlStructures.dfy(201,5): anon65_LoopHead
+ (0,0): anon65_LoopBody
+ ControlStructures.dfy(201,5): anon66_Else
+ (0,0): anon8
+ ControlStructures.dfy(201,5): anon67_Else
+ (0,0): anon10
+ (0,0): anon71_Then
+ ControlStructures.dfy(213,9): anon72_LoopHead
+ (0,0): anon72_LoopBody
+ ControlStructures.dfy(213,9): anon73_Else
+ (0,0): anon20
+ (0,0): anon74_Then
+ (0,0): anon29
+ControlStructures.dfy(235,21): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ ControlStructures.dfy(197,3): anon62_LoopHead
+ (0,0): anon62_LoopBody
+ ControlStructures.dfy(197,3): anon63_Else
+ (0,0): anon3
+ ControlStructures.dfy(197,3): anon64_Else
+ (0,0): anon5
+ ControlStructures.dfy(201,5): anon65_LoopHead
+ (0,0): anon65_LoopBody
+ ControlStructures.dfy(201,5): anon66_Else
+ (0,0): anon8
+ ControlStructures.dfy(201,5): anon67_Else
+ (0,0): anon10
+ (0,0): anon71_Then
+ ControlStructures.dfy(213,9): anon72_LoopHead
+ (0,0): anon72_LoopBody
+ ControlStructures.dfy(213,9): anon73_Else
+ (0,0): anon20
+ ControlStructures.dfy(213,9): anon74_Else
+ (0,0): anon22
+ (0,0): anon75_Then
+ (0,0): after_4
+ ControlStructures.dfy(224,7): anon77_LoopHead
+ (0,0): anon77_LoopBody
+ ControlStructures.dfy(224,7): anon78_Else
+ (0,0): anon33
+ ControlStructures.dfy(224,7): anon79_Else
+ (0,0): anon35
+ (0,0): anon81_Then
+ (0,0): anon38
+ (0,0): after_9
+ (0,0): anon86_Then
+ (0,0): anon53
+ControlStructures.dfy(238,30): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ ControlStructures.dfy(197,3): anon62_LoopHead
+ (0,0): anon62_LoopBody
+ ControlStructures.dfy(197,3): anon63_Else
+ (0,0): anon3
+ ControlStructures.dfy(197,3): anon64_Else
+ (0,0): anon5
+ ControlStructures.dfy(201,5): anon65_LoopHead
+ (0,0): anon65_LoopBody
+ ControlStructures.dfy(201,5): anon66_Else
+ (0,0): anon8
+ ControlStructures.dfy(201,5): anon67_Else
+ (0,0): anon10
+ (0,0): anon68_Then
+ (0,0): after_5
+ (0,0): anon87_Then
+ (0,0): anon88_Then
+ (0,0): anon58
+ControlStructures.dfy(241,17): Error: assertion violation
+Execution trace:
+ (0,0): anon0
+ ControlStructures.dfy(197,3): anon62_LoopHead
+ (0,0): anon62_LoopBody
+ ControlStructures.dfy(197,3): anon63_Else
+ (0,0): anon3
+ ControlStructures.dfy(197,3): anon64_Else
+ (0,0): anon5
+ ControlStructures.dfy(201,5): anon65_LoopHead
+ (0,0): anon65_LoopBody
+ ControlStructures.dfy(201,5): anon66_Else
+ (0,0): anon8
+ ControlStructures.dfy(201,5): anon67_Else
+ (0,0): anon10
+ (0,0): anon71_Then
+ ControlStructures.dfy(213,9): anon72_LoopHead
+ (0,0): anon72_LoopBody
+ ControlStructures.dfy(213,9): anon73_Else
+ (0,0): anon20
+ ControlStructures.dfy(213,9): anon74_Else
+ (0,0): anon22
+ (0,0): anon75_Then
+ (0,0): after_4
+ ControlStructures.dfy(224,7): anon77_LoopHead
+ (0,0): anon77_LoopBody
+ ControlStructures.dfy(224,7): anon78_Else
+ (0,0): anon33
+ ControlStructures.dfy(224,7): anon79_Else
+ (0,0): anon35
+ (0,0): anon82_Then
+ (0,0): anon85_Then
+ (0,0): after_8
+ (0,0): anon89_Then
+ (0,0): anon61
+
+Dafny program verifier finished with 18 verified, 10 errors
-------------------- Termination.dfy --------------------
-Termination.dfy(102,3): Error: cannot prove termination; try supplying a decreases clause for the loop
+Termination.dfy(100,3): Error: cannot prove termination; try supplying a decreases clause for the loop
Execution trace:
(0,0): anon0
- Termination.dfy(102,3): anon7_LoopHead
+ Termination.dfy(100,3): anon7_LoopHead
(0,0): anon7_LoopBody
- Termination.dfy(102,3): anon8_Else
+ Termination.dfy(100,3): anon8_Else
(0,0): anon3
- Termination.dfy(102,3): anon9_Else
+ Termination.dfy(100,3): anon9_Else
(0,0): anon5
-Termination.dfy(110,3): Error: cannot prove termination; try supplying a decreases clause for the loop
+Termination.dfy(108,3): Error: cannot prove termination; try supplying a decreases clause for the loop
Execution trace:
(0,0): anon0
- Termination.dfy(110,3): anon9_LoopHead
+ Termination.dfy(108,3): anon9_LoopHead
(0,0): anon9_LoopBody
- Termination.dfy(110,3): anon10_Else
+ Termination.dfy(108,3): anon10_Else
(0,0): anon11_Then
(0,0): anon5
- Termination.dfy(110,3): anon12_Else
+ Termination.dfy(108,3): anon12_Else
(0,0): anon7
-Termination.dfy(119,3): Error: decreases expression might not decrease
+Termination.dfy(117,3): Error: decreases expression might not decrease
Execution trace:
(0,0): anon0
- Termination.dfy(119,3): anon9_LoopHead
+ Termination.dfy(117,3): anon9_LoopHead
(0,0): anon9_LoopBody
- Termination.dfy(119,3): anon10_Else
+ Termination.dfy(117,3): anon10_Else
(0,0): anon11_Then
(0,0): anon5
- Termination.dfy(119,3): anon12_Else
+ Termination.dfy(117,3): anon12_Else
(0,0): anon7
-Termination.dfy(120,17): Error: decreases expression must be bounded below by 0 at end of loop iteration
+Termination.dfy(118,17): Error: decreases expression must be bounded below by 0 at end of loop iteration
Execution trace:
(0,0): anon0
- Termination.dfy(119,3): anon9_LoopHead
+ Termination.dfy(117,3): anon9_LoopHead
(0,0): anon9_LoopBody
- Termination.dfy(119,3): anon10_Else
+ Termination.dfy(117,3): anon10_Else
(0,0): anon11_Then
(0,0): anon5
- Termination.dfy(119,3): anon12_Else
+ Termination.dfy(117,3): anon12_Else
(0,0): anon7
-Termination.dfy(248,36): Error: cannot prove termination; try supplying a decreases clause
+Termination.dfy(246,35): Error: cannot prove termination; try supplying a decreases clause
Execution trace:
(0,0): anon6_Else
(0,0): anon7_Else
(0,0): anon8_Then
-Termination.dfy(288,3): Error: decreases expression might not decrease
+Termination.dfy(286,3): Error: decreases expression might not decrease
Execution trace:
(0,0): anon0
- Termination.dfy(288,3): anon10_LoopHead
+ Termination.dfy(286,3): anon10_LoopHead
(0,0): anon10_LoopBody
- Termination.dfy(288,3): anon11_Else
- Termination.dfy(288,3): anon12_Else
+ Termination.dfy(286,3): anon11_Else
+ Termination.dfy(286,3): anon12_Else
(0,0): anon13_Else
(0,0): anon8
Dafny program verifier finished with 44 verified, 6 errors
--------------------- Use.dfy --------------------
-Use.dfy(16,18): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Use.dfy(26,18): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Use.dfy(35,18): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Use.dfy(54,12): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Use.dfy(84,17): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Use.dfy(126,23): Error: assertion violation
-Execution trace:
- (0,0): anon0
-Use.dfy(151,12): Error: assertion violation
-Use.dfy(143,5): Related location: Related location
-Execution trace:
- (0,0): anon0
-Use.dfy(160,12): Error: assertion violation
-Use.dfy(143,5): Related location: Related location
-Execution trace:
- (0,0): anon0
-Use.dfy(169,12): Error: assertion violation
-Use.dfy(143,5): Related location: Related location
-Execution trace:
- (0,0): anon0
-Use.dfy(213,19): Error: assertion violation
-Execution trace:
- (0,0): anon0
-
-Dafny program verifier finished with 39 verified, 10 errors
-
-------------------- DTypes.dfy --------------------
DTypes.dfy(15,14): Error: assertion violation
Execution trace:
@@ -681,20 +810,20 @@ Execution trace:
DTypes.dfy(53,18): Error: assertion violation
Execution trace:
(0,0): anon0
-DTypes.dfy(123,13): Error: assertion violation
-DTypes.dfy(94,3): Related location: Related location
+DTypes.dfy(117,13): Error: assertion violation
+DTypes.dfy(89,30): Related location: Related location
Execution trace:
(0,0): anon0
-DTypes.dfy(129,13): Error: assertion violation
-DTypes.dfy(93,3): Related location: Related location
+DTypes.dfy(123,13): Error: assertion violation
+DTypes.dfy(89,20): Related location: Related location
Execution trace:
(0,0): anon0
-DTypes.dfy(139,12): Error: assertion violation
-DTypes.dfy(134,6): Related location: Related location
-DTypes.dfy(93,3): Related location: Related location
+DTypes.dfy(133,12): Error: assertion violation
+DTypes.dfy(128,6): Related location: Related location
+DTypes.dfy(89,20): Related location: Related location
Execution trace:
(0,0): anon0
-DTypes.dfy(160,13): Error: assertion violation
+DTypes.dfy(154,12): Error: assertion violation
Execution trace:
(0,0): anon0
(0,0): anon5_Then
@@ -746,7 +875,7 @@ Execution trace:
Dafny program verifier finished with 33 verified, 5 errors
-------------------- Datatypes.dfy --------------------
-Datatypes.dfy(82,20): Error: assertion violation
+Datatypes.dfy(79,20): Error: assertion violation
Execution trace:
(0,0): anon0
(0,0): anon20_Else
@@ -760,11 +889,11 @@ Execution trace:
Dafny program verifier finished with 17 verified, 1 error
-------------------- TypeAntecedents.dfy --------------------
-TypeAntecedents.dfy(34,13): Error: assertion violation
+TypeAntecedents.dfy(32,13): Error: assertion violation
Execution trace:
(0,0): anon0
-TypeAntecedents.dfy(60,1): Error BP5003: A postcondition might not hold on this return path.
-TypeAntecedents.dfy(59,15): Related location: This is the postcondition that might not hold.
+TypeAntecedents.dfy(55,1): Error BP5003: A postcondition might not hold on this return path.
+TypeAntecedents.dfy(54,15): Related location: This is the postcondition that might not hold.
Execution trace:
(0,0): anon0
(0,0): anon15_Then
@@ -776,7 +905,7 @@ Execution trace:
(0,0): anon20_Then
(0,0): anon21_Then
(0,0): anon14
-TypeAntecedents.dfy(68,16): Error: assertion violation
+TypeAntecedents.dfy(63,16): Error: assertion violation
Execution trace:
(0,0): anon0
(0,0): anon15_Else
diff --git a/Test/dafny0/Basics.dfy b/Test/dafny0/Basics.dfy
new file mode 100644
index 00000000..c02f2c45
--- /dev/null
+++ b/Test/dafny0/Basics.dfy
@@ -0,0 +1,67 @@
+class Global {
+ static function G(x: int): int { x+x }
+ static method N(x: int) returns (ghost r: int)
+ ensures r == Global.G(x);
+ {
+ if {
+ case true => r := G(x+0);
+ case true =>
+ var g: Global;
+ r := g.G(x);
+ case true =>
+ var g: Global := null;
+ r := g.G(x);
+ case true =>
+ r := Global.G(x);
+ }
+ }
+}
+
+method TestCalls(k: nat) {
+ var g: Global, h: Global;
+ assume g != h;
+ ghost var r: int;
+ ghost var s := Global.G(k);
+
+// r := Global.N(k);
+// assert r == s;
+
+ r := g.N(k);
+ assert r == s;
+ r := h.N(k);
+ assert r == s;
+
+ g := null;
+ r := g.N(k);
+ assert r == s;
+
+// r := Global.N(r);
+ if (k == 0) {
+ assert r == s;
+ } else {
+// assert r == s; // error: G(k) and G(k+k) are different
+ }
+}
+
+// ---------- chaining operators ------------------------------------
+
+function UpTruth(j: int, k: int): bool
+ requires 10 <= j < 180 < 220 <= k;
+{
+ 0 < 2 <= 2 < j != 200 < k < k + 1
+}
+
+function DownTruth(j: int, k: int): bool
+ requires k >= 220 > 180 > j >= 10;
+{
+ k + 1 > k > 200 != j > 2 >= 2 > 0
+}
+
+method ChallengeTruth(j: int, k: int)
+ requires 80 <= j < 150 && 250 <= k < 1000;
+{
+ assert UpTruth(j, k);
+ assert DownTruth(j, k);
+ // but this is not equally true:
+ assert j <= j + k != k + j + 1 < k+k+j <=/*this is the error*/ j+j+k < k+k+j+j == 2*k + 2*j == 2*(k+j);
+}
diff --git a/Test/dafny0/Comprehensions.dfy b/Test/dafny0/Comprehensions.dfy
index 8629a418..d53fb6a5 100644
--- a/Test/dafny0/Comprehensions.dfy
+++ b/Test/dafny0/Comprehensions.dfy
@@ -16,14 +16,14 @@ function method Id(x: int): int { x } // for triggering
method Main()
{
var q := set i,j | 0 <= i && i < 10 && 0 <= j && j < 3 :: i+j;
- call PrintSet(q);
+ PrintSet(q);
q := set b: bool | true :: if b then 3 else 7;
- call PrintSet(q);
+ PrintSet(q);
var m := set k | k in q :: 2*k;
- call PrintSet(m);
- call PrintSet(set k | k in q && k % 2 == 0);
+ PrintSet(m);
+ PrintSet(set k | k in q && k % 2 == 0);
var sq := [30, 40, 20];
- call PrintSet(set k, i | k in sq && 0 <= i && i < k && i % 7 == 0 :: k + i);
+ PrintSet(set k, i | k in sq && 0 <= i && i < k && i % 7 == 0 :: k + i);
var bb := forall k, i | k in sq && 0 <= i && i < k && i % 7 == 0 :: k + i == 17;
}
diff --git a/Test/dafny0/ControlStructures.dfy b/Test/dafny0/ControlStructures.dfy
index 35d939d3..5012e003 100644
--- a/Test/dafny0/ControlStructures.dfy
+++ b/Test/dafny0/ControlStructures.dfy
@@ -9,7 +9,7 @@ method M0(d: D)
}
method M1(d: D)
- requires d != #D.Blue;
+ requires d != D.Blue;
{
match (d) { // error: missing case: Purple
case Green =>
@@ -18,7 +18,7 @@ method M1(d: D)
}
method M2(d: D)
- requires d != #D.Blue && d != #D.Purple;
+ requires d != D.Blue && d != D.Purple;
{
match (d) {
case Green =>
@@ -27,9 +27,9 @@ method M2(d: D)
}
method M3(d: D)
- requires d == #D.Green;
+ requires d == D.Green;
{
- if (d != #D.Green) {
+ if (d != D.Green) {
match (d) {
// nothing here
}
@@ -37,9 +37,9 @@ method M3(d: D)
}
method M4(d: D)
- requires d == #D.Green || d == #D.Red;
+ requires d == D.Green || d == D.Red;
{
- if (d != #D.Green) {
+ if (d != D.Green) {
match (d) { // error: missing case Red
// nothing here
}
@@ -56,7 +56,7 @@ function F0(d: D): int
function F1(d: D, x: int): int
requires x < 100;
- requires d == #D.Red ==> x == 200; // (an impossibility, given the first precondition, so d != Red)
+ requires d == D.Red ==> x == 200; // (an impossibility, given the first precondition, so d != Red)
{
match (d)
case Purple => 80
@@ -135,3 +135,108 @@ method B(x: int) returns (r: int)
r := r - 1;
}
}
+
+// --------------- breaks ---------------
+
+method TheBreaker_AllGood(M: int, N: int, O: int)
+{
+ var a, b, c, d, e;
+ var i := 0;
+ while (i < M)
+ {
+ var j := 0;
+ label InnerHasLabel:
+ while (j < N)
+ {
+ var u := 2000;
+ label MyLabelBlock:
+ label MyLabelBlockAgain:
+ if (*) {
+ a := 15; break;
+ } else if (*) {
+ b := 12; break break;
+ } else if (*) {
+ c := 21; break InnerHasLabel;
+ } else if (*) {
+ while (u < 10000) {
+ u := u + 3;
+ if (*) { u := 1998; break MyLabelBlock; }
+ if (*) { u := 1998; break MyLabelBlockAgain; }
+ }
+ assert 10000 <= u;
+ u := 1998;
+ } else {
+ u := u - 2;
+ }
+ assert u == 1998;
+ var k := 0;
+ while
+ decreases O - k;
+ {
+ case k < O && k % 2 == 0 =>
+ d := 187; break;
+ case k < O =>
+ if (*) { e := 4; break InnerHasLabel; }
+ if (*) { e := 7; break; }
+ if (*) { e := 37; break break break; }
+ k := k + 1;
+ }
+ assert O <= k || d == 187 || e == 7;
+ j := j + 1;
+ }
+ assert N <= j || a == 15 || c == 21 || e == 4;
+ i := i + 1;
+ }
+ assert M <= i || b == 12 || e == 37;
+}
+
+method TheBreaker_SomeBad(M: int, N: int, O: int)
+{
+ var a, b, c, d, e;
+ var i := 0;
+ while (i < M)
+ {
+ var j := 0;
+ label InnerHasLabel:
+ while (j < N)
+ {
+ var u := 2000;
+ label MyLabelBlock:
+ label MyLabelBlockAgain:
+ if (*) {
+ a := 15; break;
+ } else if (*) {
+ b := 12; break break;
+ } else if (*) {
+ c := 21; break InnerHasLabel;
+ } else if (*) {
+ while (u < 10000) {
+ u := u + 3;
+ if (*) { u := 1998; break MyLabelBlock; }
+ if (*) { u := 1998; break MyLabelBlockAgain; }
+ }
+ assert u < 2000; // error (and no way to get past this assert statement)
+ } else {
+ u := u - 2;
+ }
+ assert u == 1998;
+ var k := 0;
+ while
+ decreases O - k;
+ {
+ case k < O && k % 2 == 0 =>
+ d := 187; break;
+ case k < O =>
+ if (*) { e := 4; break InnerHasLabel; }
+ if (*) { e := 7; break; }
+ if (*) { e := 37; break break break; }
+ k := k + 1;
+ }
+ assert O <= k || e == 7; // error: d == 187
+ j := j + 1;
+ }
+ assert N <= j || c == 21 || e == 4; // error: a == 15
+ i := i + 1;
+ }
+ assert M <= i || b == 12; // error: e == 37
+}
diff --git a/Test/dafny0/DTypes.dfy b/Test/dafny0/DTypes.dfy
index 2f59db73..55d107c5 100644
--- a/Test/dafny0/DTypes.dfy
+++ b/Test/dafny0/DTypes.dfy
@@ -74,13 +74,10 @@ class Node { }
class CP<T,U> {
}
-datatype Data {
- Lemon;
- Kiwi(int);
-}
+datatype Data = Lemon | Kiwi(int);
function G(d: Data): int
- requires d != #Data.Lemon;
+ requires d != Data.Lemon;
{
match d
case Lemon => G(d)
@@ -89,10 +86,7 @@ function G(d: Data): int
// -------- some things about induction ---------------------------------
-datatype Tree<T> {
- Leaf(T);
- Branch(Tree<T>, Tree<T>);
-}
+datatype Tree<T> = Leaf(T) | Branch(Tree<T>, Tree<T>);
class DatatypeInduction<T> {
function LeafCount<G>(tree: Tree<G>): int
@@ -144,19 +138,19 @@ class DatatypeInduction<T> {
method IntegerInduction_Succeeds(a: array<int>)
requires a != null;
requires a.Length == 0 || a[0] == 0;
- requires (forall j :: 1 <= j && j < a.Length ==> a[j] == a[j-1]+2*j-1);
+ requires forall j :: 1 <= j && j < a.Length ==> a[j] == a[j-1]+2*j-1;
{
// The following assertion can be proved by induction:
- assert (forall n {:induction} :: 0 <= n && n < a.Length ==> a[n] == n*n);
+ assert forall n {:induction} :: 0 <= n && n < a.Length ==> a[n] == n*n;
}
method IntegerInduction_Fails(a: array<int>)
requires a != null;
requires a.Length == 0 || a[0] == 0;
- requires (forall j :: 1 <= j && j < a.Length ==> a[j] == a[j-1]+2*j-1);
+ requires forall j :: 1 <= j && j < a.Length ==> a[j] == a[j-1]+2*j-1;
{
// ...but the induction heuristics don't recognize the situation as one where
// applying induction would be profitable:
- assert (forall n :: 0 <= n && n < a.Length ==> a[n] == n*n); // error reported
+ assert forall n :: 0 <= n && n < a.Length ==> a[n] == n*n; // error reported
}
}
diff --git a/Test/dafny0/Datatypes.dfy b/Test/dafny0/Datatypes.dfy
index 998b20bc..99e5e920 100644
--- a/Test/dafny0/Datatypes.dfy
+++ b/Test/dafny0/Datatypes.dfy
@@ -1,7 +1,4 @@
-datatype List<T> {
- Nil;
- Cons(T, List<T>);
-}
+datatype List<T> = Nil | Cons(T, List<T>);
class Node {
var data: int;
@@ -19,14 +16,14 @@ class Node {
method Init()
modifies this;
- ensures Repr(#List.Nil);
+ ensures Repr(Nil);
{
next := null;
}
method Add(d: int, L: List<int>) returns (r: Node)
requires Repr(L);
- ensures r != null && r.Repr(#List.Cons(d, L));
+ ensures r != null && r.Repr(Cons(d, L));
{
r := new Node;
r.data := d;
@@ -49,14 +46,14 @@ class AnotherNode {
}
method Create() returns (n: AnotherNode)
- ensures Repr(n, #List.Nil);
+ ensures Repr(n, Nil);
{
n := null;
}
method Add(n: AnotherNode, d: int, L: List<int>) returns (r: AnotherNode)
requires Repr(n, L);
- ensures Repr(r, #List.Cons(d, L));
+ ensures Repr(r, Cons(d, L));
{
r := new AnotherNode;
r.data := d;
@@ -117,7 +114,7 @@ class NestedMatchExpr {
method TestNesting0()
{
var x := 5;
- var list := #List.Cons(3, #List.Cons(6, #List.Nil));
+ var list := Cons(3, Cons(6, Nil));
assert Cadr(list, x) == 6;
match (list) {
case Nil => assert false;
diff --git a/Test/dafny0/Definedness.dfy b/Test/dafny0/Definedness.dfy
index 255b38e3..92ac0793 100644
--- a/Test/dafny0/Definedness.dfy
+++ b/Test/dafny0/Definedness.dfy
@@ -180,12 +180,12 @@ class StatementTwoShoes {
method V(s: set<StatementTwoShoes>, a: int, b: int)
modifies s;
{
- use G(12 / b); // fine, because there are no welldefinedness checks on use statements
+
foreach (m in s | m.x < 200) // s may contain null, but the foreach excludes null
{
assume 0 <= m.x;
assert m.x < 1000;
- use G(5 / m.x); // fine, because there are no welldefinedness checks on use statements
+
m.x := m.x + 1;
}
foreach (m in s + {F(a)}) // error: collection expression may not be well defined (fn precondition)
diff --git a/Test/dafny0/FunctionSpecifications.dfy b/Test/dafny0/FunctionSpecifications.dfy
index 21ce5468..13171c47 100644
--- a/Test/dafny0/FunctionSpecifications.dfy
+++ b/Test/dafny0/FunctionSpecifications.dfy
@@ -6,10 +6,7 @@ function Fib(n: int): int
Fib(n-2) + Fib(n-1)
}
-datatype List {
- Nil;
- Cons(int, List);
-}
+datatype List = Nil | Cons(int, List);
function Sum(a: List): int
ensures 0 <= Sum(a);
diff --git a/Test/dafny0/Modules0.dfy b/Test/dafny0/Modules0.dfy
index 59052ac2..c14aece6 100644
--- a/Test/dafny0/Modules0.dfy
+++ b/Test/dafny0/Modules0.dfy
@@ -38,17 +38,17 @@ module J imports G, M {
module X2 imports X1 {
class MyClass2 {
method Down(x1: MyClass1, x0: MyClass0) {
- call x1.Down(x0);
+ x1.Down(x0);
}
method WayDown(x0: MyClass0, g: ClassG) {
- call x0.Down();
- call g.T(); // allowed, because this follows import relation
+ x0.Down();
+ g.T(); // allowed, because this follows import relation
var t := g.TFunc(); // allowed, because this follows import relation
}
method Up() {
}
method Somewhere(y: MyClassY) {
- call y.M(); // error: does not follow import relation
+ y.M(); // error: does not follow import relation
}
}
}
@@ -56,10 +56,10 @@ module X2 imports X1 {
module X1 imports X0 {
class MyClass1 {
method Down(x0: MyClass0) {
- call x0.Down();
+ x0.Down();
}
method Up(x2: MyClass2) {
- call x2.Up(); // error: does not follow import relation
+ x2.Up(); // error: does not follow import relation
}
}
}
@@ -69,7 +69,7 @@ module X0 {
method Down() {
}
method Up(x1: MyClass1, x2: MyClass2) {
- call x1.Up(x2); // error: does not follow import relation
+ x1.Up(x2); // error: does not follow import relation
}
}
}
@@ -78,7 +78,7 @@ module YY {
class MyClassY {
method M() { }
method P(g: ClassG) {
- call g.T(); // allowed, because this follows import relation
+ g.T(); // allowed, because this follows import relation
var t := g.TFunc(); // allowed, because this follows import relation
}
}
@@ -88,20 +88,20 @@ class ClassG {
method T() { }
function method TFunc(): int { 10 }
method V(y: MyClassY) {
- call y.M(); // error: does not follow import relation
+ y.M(); // error: does not follow import relation
}
}
method Ping() {
- call Pong(); // allowed: intra-module call
+ Pong(); // allowed: intra-module call
}
method Pong() {
- call Ping(); // allowed: intra-module call
+ Ping(); // allowed: intra-module call
}
method ProcG(g: ClassG) {
- call g.T(); // allowed: intra-module call
+ g.T(); // allowed: intra-module call
var t := g.TFunc(); // allowed: intra-module call
}
@@ -111,11 +111,11 @@ class Ghosty {
method Caller() {
var x := 3;
ghost var y := 3;
- call Callee(x, y); // fine
- call Callee(x, x); // fine
- call Callee(y, x); // error: cannot pass in ghost to a physical formal
- call Theorem(x); // fine
- call Theorem(y); // fine, because it's a ghost method
+ Callee(x, y); // fine
+ Callee(x, x); // fine
+ Callee(y, x); // error: cannot pass in ghost to a physical formal
+ Theorem(x); // fine
+ Theorem(y); // fine, because it's a ghost method
}
method Callee(a: int, ghost b: int) { }
ghost method Theorem(a: int) { }
@@ -138,7 +138,7 @@ method SpecialFunctions()
// ---------------------- illegal match expressions ---------------
-datatype Tree { Nil; Cons(int, Tree, Tree); }
+datatype Tree = Nil | Cons(int, Tree, Tree);
function NestedMatch0(tree: Tree): int
{
diff --git a/Test/dafny0/Modules1.dfy b/Test/dafny0/Modules1.dfy
index cfefa7fa..ad17c7d8 100644
--- a/Test/dafny0/Modules1.dfy
+++ b/Test/dafny0/Modules1.dfy
@@ -5,10 +5,7 @@ module A imports B {
decreases 5, 4, 3;
{ z.G() } // fine; this goes to a different module
}
- datatype Y {
- Cons(int, Y);
- Empty;
- }
+ datatype Y = Cons(int, Y) | Empty;
}
class C {
@@ -37,7 +34,7 @@ method Proc0(x: int)
decreases x;
{
if (0 <= x) {
- call Proc1(x - 1);
+ Proc1(x - 1);
}
}
@@ -45,18 +42,18 @@ method Proc1(x: int)
decreases x;
{
if (0 <= x) {
- call Proc0(x - 1);
+ Proc0(x - 1);
}
}
method Botch0(x: int)
decreases x;
{
- call Botch1(x - 1); // error: failure to keep termination metric bounded
+ Botch1(x - 1); // error: failure to keep termination metric bounded
}
method Botch1(x: int)
decreases x;
{
- call Botch0(x); // error: failure to decrease termination metric
+ Botch0(x); // error: failure to decrease termination metric
}
diff --git a/Test/dafny0/MultiDimArray.dfy b/Test/dafny0/MultiDimArray.dfy
index ba5dc9da..ff30ef8a 100644
--- a/Test/dafny0/MultiDimArray.dfy
+++ b/Test/dafny0/MultiDimArray.dfy
@@ -74,7 +74,7 @@ class A {
var s := z[1,2,4]; // first three powers of 2 (tra-la-la)
var some: A;
f[i,j,k] := some;
- call M3(i-1, j, k);
+ M3(i-1, j, k);
assert s == z[1,2,4];
if (*) {
assert f[i,j,k] == some; // error: the recursive call may have modified any element in 'f'
diff --git a/Test/dafny0/NatTypes.dfy b/Test/dafny0/NatTypes.dfy
index 6b7ce9b9..53d3bf03 100644
--- a/Test/dafny0/NatTypes.dfy
+++ b/Test/dafny0/NatTypes.dfy
@@ -3,8 +3,8 @@ method M(n: nat) {
}
method Main() {
- call M(25);
- call M(-25); // error: cannot pass -25 as a nat
+ M(25);
+ M(-25); // error: cannot pass -25 as a nat
}
var f: nat;
@@ -34,7 +34,7 @@ method CheckField(x: nat, y: int)
method Generic<T>(i: int, t0: T, t1: T) returns (r: T) {
if (0 < i) {
var n: nat := 5;
- call j := Generic(i-1, n, -4);
+ var j := Generic(i-1, n, -4);
assert 0 <= j; // error: the result is an int, not a nat
var q := FenEric(n, -4);
assert 0 <= q; // error: the result is an int, not a nat
@@ -44,10 +44,10 @@ method Generic<T>(i: int, t0: T, t1: T) returns (r: T) {
function method FenEric<T>(t0: T, t1: T): T;
-datatype Pair<T> { Pr(T, T); }
+datatype Pair<T> = Pr(T, T);
method K(n: nat, i: int) {
- match (#Pair.Pr(n, i)) {
+ match (Pair.Pr(n, i)) {
case Pr(k, l) =>
assert k == n; // fine: although the type of k is int, we know it's equal to n
assert 0 <= k;
@@ -55,17 +55,14 @@ method K(n: nat, i: int) {
}
}
-datatype List<T> {
- Nil;
- Cons(nat, T, List<T>);
-}
+datatype List<T> = Nil | Cons(nat, T, List<T>);
method MatchIt(list: List<object>) returns (k: nat)
{
match (list) {
case Nil =>
case Cons(n, extra, tail) =>
- call w := MatchIt(tail);
+ var w := MatchIt(tail);
assert 0 <= w;
assert 0 <= n; // fine
assert 0 <= n - 10; // error: possible assertion failure
diff --git a/Test/dafny0/ParseErrors.dfy b/Test/dafny0/ParseErrors.dfy
new file mode 100644
index 00000000..d6f3005d
--- /dev/null
+++ b/Test/dafny0/ParseErrors.dfy
@@ -0,0 +1,20 @@
+// ---------------------- chaining operators -----------------------------------
+
+method TestChaining0(j: int, k: int, m: int)
+ requires j != k != m; // error: cannot have more than one != per chain
+ requires j == k == m; // dandy
+ requires j < k == m == m+1 != m+2 >= 100; // error: cannot mix < and >=
+ requires j >= k == m == m-1 != m-2 < 100; // error: cannot mix >= and <
+{
+}
+
+method TestChaining1<T>(s: set<T>, t: set<T>, u: set<T>, x: T, SuperSet: set<set<T>>)
+ requires s <= t <= u >= s+u; // error: cannot mix <= and >=
+ ensures s <= u;
+ ensures s !! t !! u; // error: !! is not chaining (but it would be nice if it were)
+ ensures x in s in SuperSet; // error: 'in' is not chaining
+ ensures x !in s in SuperSet; // error: 'in' is not chaining
+ ensures x in s !in SuperSet; // error: 'in' is not chaining
+ ensures x in s == t; // error: 'in' is not chaining
+{
+}
diff --git a/Test/dafny0/ResolutionErrors.dfy b/Test/dafny0/ResolutionErrors.dfy
index 5ec0cc4c..cacc34be 100644
--- a/Test/dafny0/ResolutionErrors.dfy
+++ b/Test/dafny0/ResolutionErrors.dfy
@@ -8,18 +8,248 @@ method GhostDivergentLoop()
ghost var i := 0;
while (i < 2)
decreases *; // error: not allowed on a ghost loop
- invariant i <= 2;
- invariant (forall j :: 0 <= j && j < i ==> a[j] > 0);
+ invariant i <= 2;
+ invariant (forall j :: 0 <= j && j < i ==> a[j] > 0);
{
i := 0;
}
assert a[1] != a[1]; // ...for then this would incorrectly verify
}
-method M<T>(a: array3<T>, b: array<T>, m: int, n: int)
+method ManyIndices<T>(a: array3<T>, b: array<T>, m: int, n: int)
{
// the following invalid expressions were once incorrectly resolved:
var x := a[m, n]; // error
var y := a[m]; // error
var z := b[m, n, m, n]; // error
}
+
+// -------- name resolution
+
+class Global {
+ var X: int;
+ function method F(x: int): int { x }
+ static function method G(x: int): int { x }
+ method M(x: int) returns (r: int)
+ {
+ r := x + X;
+ }
+ static method N(x: int) returns (r: int)
+ {
+ r := x + X; // error: cannot access instance field X from static method
+ }
+}
+
+method TestNameResolution0() {
+ var z: int;
+ z := Global.X; // error: X is an instance field
+ z := F(2); // error: cannot resolve F
+ z := Global.F(2); // error: invocation of instance function requires an instance
+ z := G(2); // error: cannot resolve G
+ z := Global.G(2);
+ z := M(2); // error: cannot resolve M
+ z := Global.M(2); // error: call to instance method requires an instance
+ z := N(1); // error: cannot resolve N
+ z := Global.N(1);
+
+ z := z(5); // error: using local as if it were a function
+ z := Global.z; // error: class Global does not have a member z
+
+ var Global: Global; // a local variable with the name 'Global'
+ z := Global.X; // this means the instance field X of the object stored in the local variable 'Global'
+ var gg: Global := null;
+ var y := gg.G(5);
+ y := gg.N(5);
+}
+
+datatype Abc = Abel | Benny | Cecilia(y: int) | David(x: int) | Eleanor;
+datatype Xyz = Alberta | Benny | Constantine(y: int) | David(x: int);
+datatype Rst = David(x: int, y: int);
+
+function Tuv(arg0: Abc, arg1: bool): int { 10 }
+var Eleanor: bool;
+
+method TestNameResolution1() {
+ var a0 := Abel;
+ var a1 := Alberta;
+ var b0 := Benny; // error: there's more than one constructor with the name Benny; needs qualification
+ var b1 := Abc.Benny;
+ var b2 := Xyz.Benny;
+ var Benny := 15; // introduce a local variable with the name 'Benny'
+ var b3 := Benny;
+ var d0 := David(20); // error: constructor name David is ambiguous
+ var d1 := David; // error: constructor name David is ambiguous (never mind that the signature does
+ // not match either of them)
+ var d2 := David(20, 40); // error: constructor name Davis is ambiguous (never mind that the given
+ // parameters match the signature of only one of those constructors)
+ var d3 := Abc.David(20, 40); // error: wrong number of parameters
+ var d4 := Rst.David(20, 40);
+ var e := Eleanor;
+ assert Tuv(e, this.Eleanor) == 10;
+}
+
+// --------------- ghost tests -------------------------------------
+
+datatype GhostDt =
+ Nil(ghost extraInfo: int) |
+ Cons(data: int, tail: GhostDt, ghost moreInfo: int);
+
+class GhostTests {
+ method M(dt: GhostDt) returns (r: int) {
+ ghost var g := 5;
+ r := g; // error: RHS is ghost, LHS is not
+ r := F(18, g); // error: RHS is a ghost and will not be available at run time
+ r := G(20, g); // it's fine to pass a ghost as a parameter to a non-ghost, because
+ // only the ghost goes away during compilation
+ r := N(22, g); // ditto
+ r := N(g, 22); // error: passing in 'g' as non-ghost parameter
+ r := P(24, 22); // error: 'P' is ghost, but its result is assigned to a non-ghost
+
+ match (dt) {
+ case Nil(gg) =>
+ case Cons(dd, tt, gg) =>
+ r := G(dd, dd); // fine
+ r := G(dd, gg); // fine
+ r := G(gg, gg); // error: cannot pass ghost 'gg' as non-ghost parameter to 'G'
+ }
+ var dd;
+ dd := GhostDt.Nil(g); // fine
+ dd := GhostDt.Cons(g, dt, 2); // error: cannot pass 'g' as non-ghost parameter
+ ghost var dtg := GhostDt.Cons(g, dt, 2); // fine, since result is ghost
+ }
+ function F(x: int, y: int): int {
+ y
+ }
+ function method G(x: int, ghost y: int): int {
+ y // error: cannot return a ghost from a non-ghost function
+ }
+ function method H(dt: GhostDt): int {
+ match dt
+ case Nil(gg) => gg // error: cannot return a ghost from a non-ghost function
+ case Cons(dd, tt, gg) => dd + gg // error: ditto
+ }
+ method N(x: int, ghost y: int) returns (r: int) {
+ r := x;
+ }
+ ghost method P(x: int, y: int) returns (r: int) {
+ ghost var g := 5;
+ r := y; // allowed, since the entire method is ghost
+ r := r + g; // fine, for the same reason
+ r := N(20, 20); // error: call to non-ghost method from ghost method is not okay
+ }
+ ghost method NiceTry()
+ ensures false;
+ {
+ while (true)
+ decreases *; // error: not allowed in ghost context
+ {
+ }
+ }
+ ghost method BreaksAreFineHere(t: int)
+ {
+ var n := 0;
+ ghost var k := 0;
+ while (true)
+ invariant n <= 112;
+ decreases 112 - n;
+ {
+ label MyStructure: {
+ if (k % 17 == 0) { break MyStructure; } // this is fine, because it's a ghost method
+ k := k + 1;
+ }
+ label MyOtherStructure:
+ if (k % 17 == 0) {
+ break MyOtherStructure;
+ } else {
+ k := k + 1;
+ }
+
+ if (n == 112) {
+ break;
+ } else if (n == t) {
+ return;
+ }
+ n := n + 1;
+ }
+ }
+ method BreakMayNotBeFineHere(ghost t: int)
+ {
+ var n := 0;
+ ghost var k := 0;
+ var p := 0;
+ while (true)
+ invariant n <= 112;
+ decreases 112 - n;
+ {
+ label MyStructure: {
+ if (k % 17 == 0) { break MyStructure; } // error: break from ghost to non-ghost point
+ k := k + 1;
+ }
+ label MyOtherStructure:
+ if (k % 17 == 0) {
+ break MyOtherStructure; // this break is fine
+ } else {
+ k := k + 1;
+ }
+
+ var dontKnow;
+ if (n == 112) {
+ ghost var m := 0;
+ label LoopLabel0:
+ label LoopLabel1:
+ while (m < 200) {
+ if (m % 103 == 0) {
+ if {
+ case true => break; // fine, since this breaks out of the enclosing ghost loop
+ case true => break LoopLabel0; // fine
+ case true => break LoopLabel1; // fine
+ }
+ } else if (m % 101 == 0) {
+ break break; // error: break out of non-ghost loop from ghost context
+ }
+ m := m + 3;
+ }
+ break;
+ } else if (dontKnow == 708) {
+ var q := 0;
+ while (q < 1) {
+ label IfNest:
+ if (p == 67) {
+ break break; // fine, since this is not a ghost context
+ } else if (*) {
+ break break break; // error: tries to break out of more loop levels than there are
+ } else if (*) {
+ break break; // fine, since this is not a ghost context
+ } else if (k == 67) {
+ break break; // error, because this is a ghost context
+ }
+ q := q + 1;
+ }
+ } else if (n == t) {
+ return; // error: this is a ghost context trying to return from a non-ghost method
+ }
+ n := n + 1;
+ p := p + 1;
+ }
+ }
+}
+
+method DuplicateLabels(n: int) {
+ var x;
+ if (n < 7) {
+ label DuplicateLabel: x := x + 1;
+ } else {
+ label DuplicateLabel: x := x + 1;
+ }
+ label DuplicateLabel: x := x + 1;
+ label DuplicateLabel: {
+ label AnotherLabel:
+ label DuplicateLabel: // error: duplicate label
+ label OneMoreTime:
+ x := x + 1;
+ }
+ label DuplicateLabel:
+ label DuplicateLabel: // error: duplicate label
+ x := x + 1;
+ label DuplicateLabel: x := x + 1;
+}
diff --git a/Test/dafny0/Simple.dfy b/Test/dafny0/Simple.dfy
index d8c8d91d..ac3a4792 100644
--- a/Test/dafny0/Simple.dfy
+++ b/Test/dafny0/Simple.dfy
@@ -20,10 +20,10 @@ class MyClass<T,U> {
} else {
this.x := x + 0;
}
- call t, u, v := M(true, lotsaObjects);
+ t, u, v := M(true, lotsaObjects);
var to: MyClass<T,U>;
- call to, u, v := this.M(true, lotsaObjects);
- call to, u, v := to.M(true, lotsaObjects);
+ to, u, v := this.M(true, lotsaObjects);
+ to, u, v := to.M(true, lotsaObjects);
assert v[x] != null ==> null !in v[2..x][1..][5 := v[this.x]][..10];
}
}
@@ -39,16 +39,12 @@ class MyClass<T,U> {
// some datatype stuff:
-datatype List<T> {
- Nil;
- Cons(T, List<T>);
-}
+datatype List<T> = Nil | Cons(T, List<T>);
-datatype WildData {
- Something();
- JustAboutAnything<G,H>(G, myName: set<H>, int, WildData);
+datatype WildData =
+ Something() |
+ JustAboutAnything(bool, myName: set<int>, int, WildData) |
More(List<int>);
-}
class C {
var w: WildData;
diff --git a/Test/dafny0/SmallTests.dfy b/Test/dafny0/SmallTests.dfy
index 7cbabcd7..ac7286e9 100644
--- a/Test/dafny0/SmallTests.dfy
+++ b/Test/dafny0/SmallTests.dfy
@@ -109,11 +109,11 @@ class Modifies {
method B(p: Modifies)
modifies this;
{
- call A(this);
+ A(this);
if (p == this) {
- call p.A(p);
+ p.A(p);
}
- call A(p); // error: may violate modifies clause
+ A(p); // error: may violate modifies clause
}
method C(b: bool)
@@ -126,9 +126,9 @@ class Modifies {
requires p != null;
{
if (y == 3) {
- call p.C(true); // error: may violate modifies clause
+ p.C(true); // error: may violate modifies clause
} else {
- call p.C(false); // error: may violation modifies clause (the check is done without regard
+ p.C(false); // error: may violation modifies clause (the check is done without regard
// for the postcondition, which also makes sense, since there may, in
// principle, be other fields of the object that are not constrained by the
// postcondition)
@@ -138,7 +138,7 @@ class Modifies {
method E()
modifies this;
{
- call A(null); // allowed
+ A(null); // allowed
}
method F(s: set<Modifies>)
@@ -164,7 +164,7 @@ class Modifies {
foreach (m in s) {
m.x := m.x + 1;
}
- call F(s);
+ F(s);
}
foreach (m in s) {
assert m.x < m.x + 10; // nothing wrong with asserting something
@@ -211,27 +211,26 @@ class AllocatedTests {
assert allocated(6);
assert allocated(6);
assert allocated(null);
- assert allocated(#Lindgren.HerrNilsson);
+ assert allocated(Lindgren.HerrNilsson);
match (d) {
case Pippi(n) => assert allocated(n);
case Longstocking(q, dd) => assert allocated(q); assert allocated(dd);
case HerrNilsson => assert old(allocated(d));
}
- var ls := #Lindgren.Longstocking([], d);
+ var ls := Lindgren.Longstocking([], d);
assert allocated(ls);
assert old(allocated(ls));
- assert old(allocated(#Lindgren.Longstocking([r], d)));
- assert old(allocated(#Lindgren.Longstocking([n], d))); // error, because n was not allocated initially
+ assert old(allocated(Lindgren.Longstocking([r], d)));
+ assert old(allocated(Lindgren.Longstocking([n], d))); // error, because n was not allocated initially
}
}
-datatype Lindgren {
- Pippi(Node);
- Longstocking(seq<object>, Lindgren);
+datatype Lindgren =
+ Pippi(Node) |
+ Longstocking(seq<object>, Lindgren) |
HerrNilsson;
-}
// --------------------------------------------------
diff --git a/Test/dafny0/Termination.dfy b/Test/dafny0/Termination.dfy
index 226eadbe..d4d1dfcf 100644
--- a/Test/dafny0/Termination.dfy
+++ b/Test/dafny0/Termination.dfy
@@ -28,8 +28,8 @@ class Termination {
}
method Lex() {
- call x := Update();
- call y := Update();
+ var x := Update();
+ var y := Update();
while (!(x == 0 && y == 0))
invariant 0 <= x && 0 <= y;
decreases x, y;
@@ -38,7 +38,7 @@ class Termination {
y := y - 1;
} else {
x := x - 1;
- call y := Update();
+ y := Update();
}
}
}
@@ -79,22 +79,20 @@ class Termination {
method Q<T>(list: List<T>) {
var l := list;
- while (l != #List.Nil)
+ while (l != List.Nil)
decreases l;
{
- call x, l := Traverse(l);
+ var x;
+ x, l := Traverse(l);
}
}
method Traverse<T>(a: List<T>) returns (val: T, b: List<T>);
- requires a != #List.Nil;
- ensures a == #List.Cons(val, b);
+ requires a != List.Nil;
+ ensures a == List.Cons(val, b);
}
-datatype List<T> {
- Nil;
- Cons(T, List<T>);
-}
+datatype List<T> = Nil | Cons(T, List<T>);
method FailureToProveTermination0(N: int)
{
@@ -204,7 +202,7 @@ method OuterOld(a: int)
decreases a, true;
{
count := count + 1;
- call InnerOld(a, count);
+ InnerOld(a, count);
}
method InnerOld(a: int, b: int)
@@ -213,9 +211,9 @@ method InnerOld(a: int, b: int)
{
count := count + 1;
if (b == 0 && 1 <= a) {
- call OuterOld(a - 1);
+ OuterOld(a - 1);
} else if (1 <= b) {
- call InnerOld(a, b - 1);
+ InnerOld(a, b - 1);
}
}
@@ -225,7 +223,7 @@ method Outer(a: int)
modifies this;
{
count := count + 1;
- call Inner(a, count);
+ Inner(a, count);
}
method Inner(a: int, b: int)
@@ -233,9 +231,9 @@ method Inner(a: int, b: int)
{
count := count + 1;
if (b == 0 && 1 <= a) {
- call Outer(a - 1);
+ Outer(a - 1);
} else if (1 <= b) {
- call Inner(a, b - 1);
+ Inner(a, b - 1);
}
}
@@ -245,7 +243,7 @@ function Zipper0<T>(a: List<T>, b: List<T>): List<T>
{
match a
case Nil => b
- case Cons(x, c) => #List.Cons(x, Zipper0(b, c)) // error: cannot prove termination
+ case Cons(x, c) => List.Cons(x, Zipper0(b, c)) // error: cannot prove termination
}
function Zipper1<T>(a: List<T>, b: List<T>, k: bool): List<T>
@@ -253,7 +251,7 @@ function Zipper1<T>(a: List<T>, b: List<T>, k: bool): List<T>
{
match a
case Nil => b
- case Cons(x, c) => #List.Cons(x, Zipper1(b, c, !k))
+ case Cons(x, c) => List.Cons(x, Zipper1(b, c, !k))
}
function Zipper2<T>(a: List<T>, b: List<T>): List<T>
@@ -262,7 +260,7 @@ function Zipper2<T>(a: List<T>, b: List<T>): List<T>
{
match a
case Nil => b
- case Cons(x, c) => #List.Cons(x, Zipper2(b, c))
+ case Cons(x, c) => List.Cons(x, Zipper2(b, c))
}
// -------------------------- test translation of while (*) -----------------
diff --git a/Test/dafny0/TypeAntecedents.dfy b/Test/dafny0/TypeAntecedents.dfy
index 6fe86493..2bedd37d 100644
--- a/Test/dafny0/TypeAntecedents.dfy
+++ b/Test/dafny0/TypeAntecedents.dfy
@@ -1,20 +1,18 @@
// -------- This is an example of what was once logically (although not trigger-ly) unsound ---
-datatype Wrapper<T> {
- Wrap(T);
-}
-datatype Unit { It; }
-datatype Color { Yellow; Blue; }
+datatype Wrapper<T> = Wrap(T);
+datatype Unit = It;
+datatype Color = Yellow | Blue;
function F(a: Wrapper<Unit>): bool
- ensures a == #Wrapper.Wrap(#Unit.It);
+ ensures a == Wrapper.Wrap(Unit.It);
{
match a
case Wrap(u) => G(u)
}
function G(u: Unit): bool
- ensures u == #Unit.It;
+ ensures u == Unit.It;
{
match u
case It => true
@@ -23,19 +21,19 @@ function G(u: Unit): bool
method BadLemma(c0: Color, c1: Color)
ensures c0 == c1;
{
- var w0 := #Wrapper.Wrap(c0);
- var w1 := #Wrapper.Wrap(c1);
+ var w0 := Wrapper.Wrap(c0);
+ var w1 := Wrapper.Wrap(c1);
// Manually, add the following assertions in Boogie. (These would
// be ill-typed in Dafny.)
- // assert _default.F($Heap, this, w0#6);
- // assert _default.F($Heap, this, w1#7);
+ // assert _default.F($Heap, this, w#06);
+ // assert _default.F($Heap, this, w#17);
assert w0 == w1; // this would be bad news (it should be reported as an error)
}
method Main() {
- call BadLemma(#Color.Yellow, #Color.Blue);
+ BadLemma(Color.Yellow, Color.Blue);
assert false; // this shows how things can really go wrong if BadLemma verified successfully
}
@@ -49,10 +47,7 @@ class MyClass {
function H(): int { 5 }
}
-datatype List {
- Nil;
- Cons(MyClass, List);
-}
+datatype List = Nil | Cons(MyClass, List);
method M(list: List, S: set<MyClass>) returns (ret: int)
modifies S;
@@ -68,7 +63,7 @@ method M(list: List, S: set<MyClass>) returns (ret: int)
assert false; // error
}
}
- call k := N();
+ var k := N();
assert k.H() == 5;
ghost var l := NF();
assert l != null ==> l.H() == 5;
@@ -82,9 +77,9 @@ method M(list: List, S: set<MyClass>) returns (ret: int)
// note, the definedness problem in the next line sits inside an unreachable branch
assert (forall t: MyClass :: t != null ==> (if t.H() == 5 then true else 10 / 0 == 3));
- assert TakesADatatype(#List.Nil) == 12;
- assert TakesADatatype(#List.Cons(null, #List.Nil)) == 12;
- assert AlsoTakesADatatype(#GenData.Pair(false, true)) == 17;
+ assert TakesADatatype(List.Nil) == 12;
+ assert TakesADatatype(List.Cons(null, List.Nil)) == 12;
+ assert AlsoTakesADatatype(GenData.Pair(false, true)) == 17;
}
method N() returns (k: MyClass)
@@ -97,8 +92,6 @@ function NF(): MyClass;
function TakesADatatype(a: List): int { 12 }
-datatype GenData<T> {
- Pair(T, T);
-}
+datatype GenData<T> = Pair(T, T);
function AlsoTakesADatatype<U>(p: GenData<U>): int { 17 }
diff --git a/Test/dafny0/TypeParameters.dfy b/Test/dafny0/TypeParameters.dfy
index a044341e..a3698dc0 100644
--- a/Test/dafny0/TypeParameters.dfy
+++ b/Test/dafny0/TypeParameters.dfy
@@ -13,7 +13,7 @@ class C<U> {
method Main(u: U)
{
var t := F(3,u) && F(this,u);
- call kz := M(t,u);
+ var kz := M(t,u);
assert kz && (G() || !G());
}
@@ -30,14 +30,14 @@ class SetTest {
method Good()
{
var s := {2, 5, 3};
- call t := Add(s, 7);
+ var t := Add(s, 7);
assert {5,7,2,3} == t;
}
method Bad()
{
var s := {2, 50, 3};
- call t := Add(s, 7);
+ var t := Add(s, 7);
assert {5,7,2,3} == t; // error
}
}
@@ -52,14 +52,14 @@ class SequenceTest {
method Good()
{
var s := [2, 5, 3];
- call t := Add(s, 7);
+ var t := Add(s, 7);
assert [2,5,3,7] == t;
}
method Bad()
{
var s := [2, 5, 3];
- call t := Add(s, 7);
+ var t := Add(s, 7);
assert [2,5,7,3] == t || [2,5,3] == t; // error
}
}
@@ -92,7 +92,7 @@ class CClient {
}
c.x := 5;
c.x := c.x;
- call z := c.M(c, 17);
+ var z := c.M(c, 17);
assert z == c.x;
}
}
@@ -170,7 +170,7 @@ method TyKn_Main(k0: TyKn_K) {
assert c.x != null ==> c.x.F() == 176; // the Dafny encoding needs the canCall mechanism to verify this
assert c.G() != null ==> c.G().F() == 176; // ditto
- call k2 := c.M();
+ var k2 := c.M();
assert k2 != null ==> k2.F() == 176; // the canCall mechanism does the trick here, but so does the encoding
// via k2's where clause
}
diff --git a/Test/dafny0/TypeTests.dfy b/Test/dafny0/TypeTests.dfy
index 792c8fac..9df11a67 100644
--- a/Test/dafny0/TypeTests.dfy
+++ b/Test/dafny0/TypeTests.dfy
@@ -1,49 +1,38 @@
class C {
function F(c: C, d: D): bool { true }
method M(x: int) returns (y: int, c: C)
- requires F(#D.A, this); // 2 errors
+ requires F(D.A, this); // 2 errors
requires F(4, 5); // 2 errors
- requires F(this, #D.A); // good
+ requires F(this, D.A); // good
{ }
method Caller()
{
- call m,n := M(true); // error on in-parameter
- call n,m := M(m); // 2 errors on out-parameters
+ var m,n := M(true); // error on in-parameter
+ n,m := M(m); // 2 errors on out-parameters
}
}
-datatype D {
- A;
-}
-
-datatype Nothing { // error: no grounding constructor
-}
+datatype D = A;
-datatype NeverendingList { // error: no grounding constructor
- Cons(int, NeverendingList);
-}
+datatype NeverendingList = Cons(int, NeverendingList); // error: no grounding constructor
-datatype MutuallyRecursiveDataType<T> {
- FromANumber(int); // this is the base case
+datatype MutuallyRecursiveDataType<T> =
+ FromANumber(int) | // this is the base case
Else(TheCounterpart<T>, C);
-}
-datatype TheCounterpart<T> {
- TreeLike(TheCounterpart<T>, TheCounterpart<T>);
+datatype TheCounterpart<T> =
+ TreeLike(TheCounterpart<T>, TheCounterpart<T>) |
More(MutuallyRecursiveDataType<T>);
-}
// these 'ReverseOrder_' order tests may be called white-box unit tests
-datatype ReverseOrder_MutuallyRecursiveDataType<T> {
- FromANumber(int); // this is the base case
+datatype ReverseOrder_MutuallyRecursiveDataType<T> =
+ FromANumber(int) | // this is the base case
Else(ReverseOrder_TheCounterpart<T>, C);
-}
-datatype ReverseOrder_TheCounterpart<T> {
- TreeLike(ReverseOrder_TheCounterpart<T>, ReverseOrder_TheCounterpart<T>);
+datatype ReverseOrder_TheCounterpart<T> =
+ TreeLike(ReverseOrder_TheCounterpart<T>, ReverseOrder_TheCounterpart<T>) |
More(ReverseOrder_MutuallyRecursiveDataType<T>);
-}
// ---------------------
diff --git a/Test/dafny0/Use.dfy b/Test/dafny0/Use.dfy
deleted file mode 100644
index 502c4222..00000000
--- a/Test/dafny0/Use.dfy
+++ /dev/null
@@ -1,227 +0,0 @@
-class T {
- var x: int;
-
- function F(y: int): int
- decreases false;
- {
- 2*y + (if 1 < 0 then FEntry(y) else 0)
- }
- function FEntry(y: int): int decreases true; { F(y) }
-
- method M(s: set<T>) {
- use F(4);
- use F(5);
- assert F(5) == 10;
- assert F(7) == 14;
- assert F(72) == 14; // error (just plain wrong)
- }
-
- function FF(y: int): int
- {
- FEntry(y)
- }
-
- method MM() {
- assert F(5) == 10;
- assert FF(6) == 12; // error (definition of F not engaged)
-
- assert F(7) == 14;
- assert FF(7) == 14; // now the inner definition of F has already been engaged
-
- use F(8);
- assert FF(8) == 16; // same here
-
- use FF(9);
- assert FF(9) == 18; // error (definition of F not engaged; the use of FF does not help)
- }
-
- function G(y: int): bool decreases false;
- {
- 0 <= y || (1 < 0 && GG(y))
- }
- unlimited function GG(y: int): bool decreases true;
- {
- G(y)
- }
-
- method N(s: set<T>) {
- use G(4);
- use G(5);
- use G(-5);
- assert GG(5);
- assert !GG(-5);
- assert GG(7); // fine (the assert expands GG to G, then the definition of G kicks in)
- assert !GG(-7); // error (the negation disables the expansion of GG in the assert)
- }
-
- function H(): int
- reads this; decreases false;
- {
- x + (if 1 < 0 then HH() else 0)
- }
- unlimited function HH(): int
- reads this; decreases true;
- {
- H()
- }
-
- method Q0()
- modifies this;
- {
- var t := x;
- use H();
- assert HH() == t;
-
- x := x + 1;
- assert old(HH()) == t;
- }
-
- method Q1()
- modifies this;
- {
- x := x + 1;
- use H();
- assert HH() == old(HH()) + 1; // error: does not know what old(H()) is
- }
-
- method Q2()
- modifies this;
- {
- use H();
- x := x + 1;
- use H();
- assert HH() == old(HH()) + 1;
- }
-
- method Q3()
- modifies this;
- {
- x := x + 1;
- use H();
- use old(H());
- assert HH() == old(HH()) + 1;
- }
-
- method Q4(other: T)
- requires other != null && other != this;
- modifies other;
- {
- other.x := other.x + 1;
- assert HH() == old(HH()); // frame axiom for H still works
- }
-
- method Q5(other: T)
- requires other != null && other != this;
- modifies this;
- {
- x := x + 1;
- assert other.HH() == old(other.HH()); // frame axiom for H still works
- }
-
- method Q6(other: T)
- requires other != null;
- modifies this;
- {
- x := x + 1;
- assert other.HH() == old(other.HH()); // error: 'other' may equal 'this', in which
- // case nothing is known about how H() changed
- }
-
- function K(): bool
- reads this; decreases 0;
- {
- x <= 100 || (1 < 0 && KKK())
- }
- function KK(): bool
- reads this; decreases 1;
- {
- K()
- }
- unlimited function KKK(): bool
- reads this; decreases 2;
- {
- KK()
- }
-
- method R0()
- requires KKK(); // this expands to both KKK() and KK(); the def. of KK() expands to K#limited
- modifies this;
- {
- x := x - 1;
- assert KKK(); // error (does not know exact definition of K from the initial state)
- }
-
- method R1()
- requires KKK(); // this expands to both KKK() and KK(); the def. of KK() expands to K#limited
- modifies this;
- {
- use K(); // this equates K#limited and K, so the exact value of K() in the pre-state is now known
- x := x - 1;
- assert KKK(); // error: the assert expands KKK to KK, definition of KK expands K#limited (but not to K)
- }
-
- method R2()
- requires KKK(); // this expands to both KKK() and KK(); the def. of KK() expands to K#limited (but not K)
- modifies this;
- {
- x := x - 1;
- use K(); // this equates K#limited and K in the present state
- assert KKK(); // error: the connection with the pre-state K is not known
- }
-
- method R3()
- requires KKK(); // this expands to both KKK() and KK(); the def. of KK() expands to K#limited (but not K)
- modifies this;
- {
- use K(); // this equates K#limited and K, so the pre-state K() is known
- x := x - 1;
- use K(); // this equates K#limited and K in the present state
- assert KKK(); // thar it is: this expands to both KKK and KK, and the def. of KK expands to K#limited
- }
-}
-
-class Recursive {
- function Gauss(n: int): int
- requires 0 <= n;
- decreases n;
- {
- if n == 0 then 0 else Gauss(n-1) + n
- }
-
- ghost method G(n: int)
- requires 0 <= n;
- ensures Gauss(n) == (n+1)*n / 2;
- {
- var k := 0;
- while (k < n)
- invariant k <= n;
- invariant Gauss(k) == (k+1)*k / 2;
- {
- k := k + 1;
- }
- }
-
- function Fib(n: int): int
- requires 0 <= n;
- decreases n;
- {
- if n < 2 then n else Fib(n-2) + Fib(n-1)
- }
-
- method F0()
- {
- assert Fib(3) == 2; // error (does not know about Fib for the recursive calls)
- }
-
- method F1()
- {
- assert Fib(0) == 0;
- assert Fib(3) == 2; // now it knows
- }
-
- method F2()
- {
- use Fib(0);
- assert Fib(3) == 2; // now it knows, too
- }
-}
diff --git a/Test/dafny0/runtest.bat b/Test/dafny0/runtest.bat
index 16bc0e2b..aed9ee8a 100644
--- a/Test/dafny0/runtest.bat
+++ b/Test/dafny0/runtest.bat
@@ -12,11 +12,11 @@ for %%f in (Simple.dfy) do (
)
for %%f in (TypeTests.dfy NatTypes.dfy SmallTests.dfy Definedness.dfy
- FunctionSpecifications.dfy ResolutionErrors.dfy
+ FunctionSpecifications.dfy ResolutionErrors.dfy ParseErrors.dfy
Array.dfy MultiDimArray.dfy NonGhostQuantifiers.dfy AdvancedLHS.dfy
Modules0.dfy Modules1.dfy BadFunction.dfy
- Comprehensions.dfy ControlStructures.dfy
- Termination.dfy Use.dfy DTypes.dfy
+ Comprehensions.dfy Basics.dfy ControlStructures.dfy
+ Termination.dfy DTypes.dfy
TypeParameters.dfy Datatypes.dfy TypeAntecedents.dfy SplitExpr.dfy
Refinement.dfy RefinementErrors.dfy) do (
echo.
diff --git a/Test/dafny1/BinaryTree.dfy b/Test/dafny1/BinaryTree.dfy
index b4980d4b..88b06605 100644
--- a/Test/dafny1/BinaryTree.dfy
+++ b/Test/dafny1/BinaryTree.dfy
@@ -32,7 +32,7 @@ class IntSet {
if (root == null) {
present := false;
} else {
- call present := root.Find(x);
+ present := root.Find(x);
}
}
@@ -42,7 +42,7 @@ class IntSet {
ensures Valid() && fresh(Repr - old(Repr));
ensures Contents == old(Contents) + {x};
{
- call t := InsertHelper(x, root);
+ var t := InsertHelper(x, root);
root := t;
Contents := root.Contents;
Repr := root.Repr + {this};
@@ -64,12 +64,12 @@ class IntSet {
} else {
if (x < n.data) {
assert n.right == null || n.right.Valid();
- call t := InsertHelper(x, n.left);
+ var t := InsertHelper(x, n.left);
n.left := t;
n.Repr := n.Repr + n.left.Repr;
} else {
assert n.left == null || n.left.Valid();
- call t := InsertHelper(x, n.right);
+ var t := InsertHelper(x, n.right);
n.right := t;
n.Repr := n.Repr + n.right.Repr;
}
@@ -85,7 +85,7 @@ class IntSet {
ensures Contents == old(Contents) - {x};
{
if (root != null) {
- call newRoot := root.Remove(x);
+ var newRoot := root.Remove(x);
root := newRoot;
if (root == null) {
Contents := {};
@@ -152,9 +152,9 @@ class Node {
if (x == data) {
present := true;
} else if (left != null && x < data) {
- call present := left.Find(x);
+ present := left.Find(x);
} else if (right != null && data < x) {
- call present := right.Find(x);
+ present := right.Find(x);
} else {
present := false;
}
@@ -171,12 +171,12 @@ class Node {
{
node := this;
if (left != null && x < data) {
- call t := left.Remove(x);
+ var t := left.Remove(x);
left := t;
Contents := Contents - {x};
if (left != null) { Repr := Repr + left.Repr; }
} else if (right != null && data < x) {
- call t := right.Remove(x);
+ var t := right.Remove(x);
right := t;
Contents := Contents - {x};
if (right != null) { Repr := Repr + right.Repr; }
@@ -189,7 +189,7 @@ class Node {
node := left;
} else {
// rotate
- call min, r := right.RemoveMin();
+ var min, r := right.RemoveMin();
data := min; right := r;
Contents := Contents - {x};
if (right != null) { Repr := Repr + right.Repr; }
@@ -211,7 +211,8 @@ class Node {
min := data;
node := right;
} else {
- call min, t := left.RemoveMin();
+ var t;
+ min, t := left.RemoveMin();
left := t;
node := this;
Contents := Contents - {min};
@@ -225,9 +226,9 @@ class Main {
{
var s := new IntSet.Init();
- call s.Insert(12);
- call s.Insert(24);
- call present := s.Find(x);
+ s.Insert(12);
+ s.Insert(24);
+ var present := s.Find(x);
assert present <==> x == 12 || x == 24;
}
@@ -235,8 +236,8 @@ class Main {
requires s != null && s.Valid();
modifies s.Repr;
{
- call s.Insert(x);
- call s.Insert(24);
+ s.Insert(x);
+ s.Insert(24);
assert old(s.Contents) - {x,24} == s.Contents - {x,24};
}
}
diff --git a/Test/dafny1/ExtensibleArray.dfy b/Test/dafny1/ExtensibleArray.dfy
index 089a72c4..2dc49cd9 100644
--- a/Test/dafny1/ExtensibleArray.dfy
+++ b/Test/dafny1/ExtensibleArray.dfy
@@ -57,7 +57,7 @@ class ExtensibleArray<T> {
if (M <= i) {
t := elements[i - M];
} else {
- call arr := more.Get(i / 256);
+ var arr := more.Get(i / 256);
t := arr[i % 256];
}
}
@@ -72,7 +72,7 @@ class ExtensibleArray<T> {
if (M <= i) {
elements[i - M] := t;
} else {
- call arr := more.Get(i / 256);
+ var arr := more.Get(i / 256);
arr[i % 256] := t;
}
Contents := Contents[i := t];
@@ -94,7 +94,7 @@ class ExtensibleArray<T> {
Repr := Repr + {more} + more.Repr;
}
// "elements" is full, so move it into "more" and allocate a new array
- call more.Append(elements);
+ more.Append(elements);
Repr := Repr + more.Repr;
M := M + 256;
elements := new T[256];
@@ -113,14 +113,14 @@ method Main() {
invariant a.Valid() && fresh(a.Repr);
invariant |a.Contents| == n;
{
- call a.Append(n);
+ a.Append(n);
n := n + 1;
}
- call k := a.Get(570); print k, "\n";
- call k := a.Get(0); print k, "\n";
- call k := a.Get(1000); print k, "\n";
- call a.Set(1000, 23);
- call k := a.Get(0); print k, "\n";
- call k := a.Get(1000); print k, "\n";
- call k := a.Get(66000); print k, "\n";
+ var k := a.Get(570); print k, "\n";
+ k := a.Get(0); print k, "\n";
+ k := a.Get(1000); print k, "\n";
+ a.Set(1000, 23);
+ k := a.Get(0); print k, "\n";
+ k := a.Get(1000); print k, "\n";
+ k := a.Get(66000); print k, "\n";
}
diff --git a/Test/dafny1/FindZero.dfy b/Test/dafny1/FindZero.dfy
index cff8b934..76e67205 100644
--- a/Test/dafny1/FindZero.dfy
+++ b/Test/dafny1/FindZero.dfy
@@ -9,7 +9,7 @@ method FindZero(a: array<int>) returns (r: int)
invariant forall i :: 0 <= i && i < n && i < a.Length ==> a[i] != 0;
{
if (a[n] == 0) { r := n; return; }
- call Lemma(a, n, a[n]);
+ Lemma(a, n, a[n]);
n := n + a[n];
}
r := -1;
@@ -25,6 +25,6 @@ ghost method Lemma(a: array<int>, k: int, m: int)
{
if (0 < m && k < a.Length) {
assert a[k] != 0;
- call Lemma(a, k+1, m-1);
+ Lemma(a, k+1, m-1);
}
}
diff --git a/Test/dafny1/Induction.dfy b/Test/dafny1/Induction.dfy
index 7c7d3baf..15cc1ffe 100644
--- a/Test/dafny1/Induction.dfy
+++ b/Test/dafny1/Induction.dfy
@@ -24,8 +24,8 @@ class IntegerInduction {
ensures SumOfCubes(n) == Gauss(n) * Gauss(n);
{
if (n != 0) {
- call Theorem0(n-1);
- call Lemma(n-1);
+ Theorem0(n-1);
+ Lemma(n-1);
}
}
@@ -33,7 +33,7 @@ class IntegerInduction {
requires 0 <= n;
ensures 2 * Gauss(n) == n*(n+1);
{
- if (n != 0) { call Lemma(n-1); }
+ if (n != 0) { Lemma(n-1); }
}
// Here is another proof. It states the lemma as part of the theorem, and
@@ -45,7 +45,7 @@ class IntegerInduction {
ensures 2 * Gauss(n) == n*(n+1);
{
if (n != 0) {
- call Theorem1(n-1);
+ Theorem1(n-1);
}
}
@@ -64,7 +64,7 @@ class IntegerInduction {
ensures SumOfCubes(n) == Gauss(n) * Gauss(n);
{
if (n != 0) {
- call Theorem2(n-1);
+ Theorem2(n-1);
assert (forall m :: 0 <= m ==> 2 * Gauss(m) == m*(m+1));
}
@@ -84,7 +84,7 @@ class IntegerInduction {
ensures SumOfCubes(n) == GaussWithPost(n) * GaussWithPost(n);
{
if (n != 0) {
- call Theorem3(n-1);
+ Theorem3(n-1);
}
}
@@ -112,7 +112,7 @@ class IntegerInduction {
if (*) {
assert (forall m :: 0 <= m ==> SumOfCubes(m) == GaussWithPost(m) * GaussWithPost(m));
} else {
- call Theorem4();
+ Theorem4();
}
}
@@ -136,10 +136,7 @@ class IntegerInduction {
}
}
-datatype Tree<T> {
- Leaf(T);
- Branch(Tree<T>, Tree<T>);
-}
+datatype Tree<T> = Leaf(T) | Branch(Tree<T>, Tree<T>);
class DatatypeInduction<T> {
function LeafCount<T>(tree: Tree<T>): int
@@ -182,7 +179,7 @@ function FooD(n: nat, d: D): int
{
match d
case Nothing =>
- if n == 0 then 10 else FooD(n-1, #D.Something(d))
+ if n == 0 then 10 else FooD(n-1, D.Something(d))
case Something(next) =>
if n < 100 then n + 12 else FooD(n-13, next)
}
diff --git a/Test/dafny1/MatrixFun.dfy b/Test/dafny1/MatrixFun.dfy
index 86ad451d..81b3f4c9 100644
--- a/Test/dafny1/MatrixFun.dfy
+++ b/Test/dafny1/MatrixFun.dfy
@@ -64,20 +64,20 @@ method Main()
B[0,0] := true; B[0,1] := false; B[0,2] := false; B[0,3] := true; B[0,4] := false;
B[1,0] := true; B[1,1] := true; B[1,2] := true; B[1,3] := true; B[1,4] := false;
print "Before:\n";
- call PrintMatrix(B);
- call MirrorImage(B);
+ PrintMatrix(B);
+ MirrorImage(B);
print "Mirror image:\n";
- call PrintMatrix(B);
+ PrintMatrix(B);
var A := new int[3,3];
A[0,0] := 5; A[0,1] := 7; A[0,2] := 9;
A[1,0] := 6; A[1,1] := 2; A[1,2] := 3;
A[2,0] := 7; A[2,1] := 1; A[2,2] := 0;
print "Before:\n";
- call PrintMatrix(A);
- call Flip(A);
+ PrintMatrix(A);
+ Flip(A);
print "Flip:\n";
- call PrintMatrix(A);
+ PrintMatrix(A);
}
method PrintMatrix<T>(m: array2<T>)
diff --git a/Test/dafny1/PriorityQueue.dfy b/Test/dafny1/PriorityQueue.dfy
index db1c60fa..6e19ab8f 100644
--- a/Test/dafny1/PriorityQueue.dfy
+++ b/Test/dafny1/PriorityQueue.dfy
@@ -41,7 +41,7 @@ class PriorityQueue {
{
n := n + 1;
a[n] := x;
- call SiftUp(n);
+ SiftUp(n);
}
method SiftUp(k: int)
@@ -76,7 +76,7 @@ class PriorityQueue {
x := a[1];
a[1] := a[n];
n := n - 1;
- call SiftDown(1);
+ SiftDown(1);
}
method SiftDown(k: int)
@@ -156,7 +156,7 @@ class PriorityQueue_Alternative {
{
n := n + 1;
a[n] := x;
- call SiftUp();
+ SiftUp();
}
method SiftUp()
@@ -189,7 +189,7 @@ class PriorityQueue_Alternative {
x := a[1];
a[1] := a[n];
n := n - 1;
- call SiftDown();
+ SiftDown();
}
method SiftDown()
diff --git a/Test/dafny1/Queue.dfy b/Test/dafny1/Queue.dfy
index 0ee953e1..bfb588be 100644
--- a/Test/dafny1/Queue.dfy
+++ b/Test/dafny1/Queue.dfy
@@ -48,9 +48,9 @@ class Queue<T> {
ensures Valid() && fresh(footprint - old(footprint));
ensures contents == old(contents)[1..] + old(contents)[..1];
{
- call t := Front();
- call Dequeue();
- call Enqueue(t);
+ var t := Front();
+ Dequeue();
+ Enqueue(t);
}
method RotateAny()
@@ -62,9 +62,9 @@ class Queue<T> {
ensures (exists i :: 0 <= i && i <= |contents| &&
contents == old(contents)[i..] + old(contents)[..i]);
{
- call t := Front();
- call Dequeue();
- call Enqueue(t);
+ var t := Front();
+ Dequeue();
+ Enqueue(t);
}
method IsEmpty() returns (isEmpty: bool)
@@ -152,18 +152,18 @@ class Main<U> {
var q0 := new Queue<T>.Init();
var q1 := new Queue<T>.Init();
- call q0.Enqueue(t);
- call q0.Enqueue(u);
+ q0.Enqueue(t);
+ q0.Enqueue(u);
- call q1.Enqueue(v);
+ q1.Enqueue(v);
assert |q0.contents| == 2;
- call w := q0.Front();
+ var w := q0.Front();
assert w == t;
- call q0.Dequeue();
+ q0.Dequeue();
- call w := q0.Front();
+ w := q0.Front();
assert w == u;
assert |q0.contents| == 1;
@@ -179,18 +179,18 @@ class Main<U> {
ensures fresh(q0.footprint - old(q0.footprint));
ensures fresh(q1.footprint - old(q1.footprint));
{
- call q0.Enqueue(t);
- call q0.Enqueue(u);
+ q0.Enqueue(t);
+ q0.Enqueue(u);
- call q1.Enqueue(v);
+ q1.Enqueue(v);
assert |q0.contents| == 2;
- call w := q0.Front();
+ var w := q0.Front();
assert w == t;
- call q0.Dequeue();
+ q0.Dequeue();
- call w := q0.Front();
+ w := q0.Front();
assert w == u;
assert |q0.contents| == 1;
diff --git a/Test/dafny1/Rippling.dfy b/Test/dafny1/Rippling.dfy
index d5b3862b..fdce6dc7 100644
--- a/Test/dafny1/Rippling.dfy
+++ b/Test/dafny1/Rippling.dfy
@@ -1,29 +1,29 @@
// Datatypes
-datatype Bool { False; True; }
+datatype Bool = False | True;
-datatype Nat { Zero; Suc(Nat); }
+datatype Nat = Zero | Suc(Nat);
-datatype List { Nil; Cons(Nat, List); }
+datatype List = Nil | Cons(Nat, List);
-datatype Pair { Pair(Nat, Nat); }
+datatype Pair = Pair(Nat, Nat);
-datatype PList { PNil; PCons(Pair, PList); }
+datatype PList = PNil | PCons(Pair, PList);
-datatype Tree { Leaf; Node(Tree, Nat, Tree); }
+datatype Tree = Leaf | Node(Tree, Nat, Tree);
// Boolean functions
function not(b: Bool): Bool
{
match b
- case False => #Bool.True
- case True => #Bool.False
+ case False => True
+ case True => False
}
function and(a: Bool, b: Bool): Bool
{
- if a == #Bool.True && b == #Bool.True then #Bool.True else #Bool.False
+ if a == True && b == True then True else False
}
// Natural number functions
@@ -32,13 +32,13 @@ function add(x: Nat, y: Nat): Nat
{
match x
case Zero => y
- case Suc(w) => #Nat.Suc(add(w, y))
+ case Suc(w) => Suc(add(w, y))
}
function minus(x: Nat, y: Nat): Nat
{
match x
- case Zero => #Nat.Zero
+ case Zero => Zero
case Suc(a) => match y
case Zero => x
case Suc(b) => minus(a, b)
@@ -48,38 +48,38 @@ function eq(x: Nat, y: Nat): Bool
{
match x
case Zero => (match y
- case Zero => #Bool.True
- case Suc(b) => #Bool.False)
+ case Zero => True
+ case Suc(b) => False)
case Suc(a) => (match y
- case Zero => #Bool.False
+ case Zero => False
case Suc(b) => eq(a, b))
}
function leq(x: Nat, y: Nat): Bool
{
match x
- case Zero => #Bool.True
+ case Zero => True
case Suc(a) => match y
- case Zero => #Bool.False
+ case Zero => False
case Suc(b) => leq(a, b)
}
function less(x: Nat, y: Nat): Bool
{
match y
- case Zero => #Bool.False
+ case Zero => False
case Suc(b) => match x
- case Zero => #Bool.True
+ case Zero => True
case Suc(a) => less(a, b)
}
function min(x: Nat, y: Nat): Nat
{
match x
- case Zero => #Nat.Zero
+ case Zero => Zero
case Suc(a) => match y
- case Zero => #Nat.Zero
- case Suc(b) => #Nat.Suc(min(a, b))
+ case Zero => Zero
+ case Suc(b) => Suc(min(a, b))
}
function max(x: Nat, y: Nat): Nat
@@ -88,7 +88,7 @@ function max(x: Nat, y: Nat): Nat
case Zero => y
case Suc(a) => match y
case Zero => x
- case Suc(b) => #Nat.Suc(max(a, b))
+ case Suc(b) => Suc(max(a, b))
}
// List functions
@@ -97,22 +97,22 @@ function concat(xs: List, ys: List): List
{
match xs
case Nil => ys
- case Cons(x,tail) => #List.Cons(x, concat(tail, ys))
+ case Cons(x,tail) => Cons(x, concat(tail, ys))
}
function mem(x: Nat, xs: List): Bool
{
match xs
- case Nil => #Bool.False
- case Cons(y, ys) => if x == y then #Bool.True else mem(x, ys)
+ case Nil => False
+ case Cons(y, ys) => if x == y then True else mem(x, ys)
}
function delete(n: Nat, xs: List): List
{
match xs
- case Nil => #List.Nil
+ case Nil => Nil
case Cons(y, ys) =>
- if y == n then delete(n, ys) else #List.Cons(y, delete(n, ys))
+ if y == n then delete(n, ys) else Cons(y, delete(n, ys))
}
function drop(n: Nat, xs: List): List
@@ -120,38 +120,38 @@ function drop(n: Nat, xs: List): List
match n
case Zero => xs
case Suc(m) => match xs
- case Nil => #List.Nil
+ case Nil => Nil
case Cons(x, tail) => drop(m, tail)
}
function take(n: Nat, xs: List): List
{
match n
- case Zero => #List.Nil
+ case Zero => Nil
case Suc(m) => match xs
- case Nil => #List.Nil
- case Cons(x, tail) => #List.Cons(x, take(m, tail))
+ case Nil => Nil
+ case Cons(x, tail) => Cons(x, take(m, tail))
}
function len(xs: List): Nat
{
match xs
- case Nil => #Nat.Zero
- case Cons(y, ys) => #Nat.Suc(len(ys))
+ case Nil => Zero
+ case Cons(y, ys) => Suc(len(ys))
}
function count(x: Nat, xs: List): Nat
{
match xs
- case Nil => #Nat.Zero
+ case Nil => Zero
case Cons(y, ys) =>
- if x == y then #Nat.Suc(count(x, ys)) else count(x, ys)
+ if x == y then Suc(count(x, ys)) else count(x, ys)
}
function last(xs: List): Nat
{
match xs
- case Nil => #Nat.Zero
+ case Nil => Zero
case Cons(y, ys) => match ys
case Nil => y
case Cons(z, zs) => last(ys)
@@ -160,39 +160,39 @@ function last(xs: List): Nat
function mapF(xs: List): List
{
match xs
- case Nil => #List.Nil
- case Cons(y, ys) => #List.Cons(HardcodedUninterpretedFunction(y), mapF(ys))
+ case Nil => Nil
+ case Cons(y, ys) => Cons(HardcodedUninterpretedFunction(y), mapF(ys))
}
function HardcodedUninterpretedFunction(n: Nat): Nat;
function takeWhileAlways(hardcodedResultOfP: Bool, xs: List): List
{
match xs
- case Nil => #List.Nil
+ case Nil => Nil
case Cons(y, ys) =>
- if whilePredicate(hardcodedResultOfP, y) == #Bool.True
- then #List.Cons(y, takeWhileAlways(hardcodedResultOfP, ys))
- else #List.Nil
+ if whilePredicate(hardcodedResultOfP, y) == True
+ then Cons(y, takeWhileAlways(hardcodedResultOfP, ys))
+ else Nil
}
function whilePredicate(result: Bool, arg: Nat): Bool { result }
function dropWhileAlways(hardcodedResultOfP: Bool, xs: List): List
{
match xs
- case Nil => #List.Nil
+ case Nil => Nil
case Cons(y, ys) =>
- if whilePredicate(hardcodedResultOfP, y) == #Bool.True
+ if whilePredicate(hardcodedResultOfP, y) == True
then dropWhileAlways(hardcodedResultOfP, ys)
- else #List.Cons(y, ys)
+ else Cons(y, ys)
}
function filterP(xs: List): List
{
match xs
- case Nil => #List.Nil
+ case Nil => Nil
case Cons(y, ys) =>
- if HardcodedUninterpretedPredicate(y) == #Bool.True
- then #List.Cons(y, filterP(ys))
+ if HardcodedUninterpretedPredicate(y) == True
+ then Cons(y, filterP(ys))
else filterP(ys)
}
function HardcodedUninterpretedPredicate(n: Nat): Bool;
@@ -200,37 +200,37 @@ function HardcodedUninterpretedPredicate(n: Nat): Bool;
function insort(n: Nat, xs: List): List
{
match xs
- case Nil => #List.Cons(n, #List.Nil)
+ case Nil => Cons(n, Nil)
case Cons(y, ys) =>
- if leq(n, y) == #Bool.True
- then #List.Cons(n, #List.Cons(y, ys))
- else #List.Cons(y, ins(n, ys))
+ if leq(n, y) == True
+ then Cons(n, Cons(y, ys))
+ else Cons(y, ins(n, ys))
}
function ins(n: Nat, xs: List): List
{
match xs
- case Nil => #List.Cons(n, #List.Nil)
+ case Nil => Cons(n, Nil)
case Cons(y, ys) =>
- if less(n, y) == #Bool.True
- then #List.Cons(n, #List.Cons(y, ys))
- else #List.Cons(y, ins(n, ys))
+ if less(n, y) == True
+ then Cons(n, Cons(y, ys))
+ else Cons(y, ins(n, ys))
}
function ins1(n: Nat, xs: List): List
{
match xs
- case Nil => #List.Cons(n, #List.Nil)
+ case Nil => Cons(n, Nil)
case Cons(y, ys) =>
if n == y
- then #List.Cons(y, ys)
- else #List.Cons(y, ins1(n, ys))
+ then Cons(y, ys)
+ else Cons(y, ins1(n, ys))
}
function sort(xs: List): List
{
match xs
- case Nil => #List.Nil
+ case Nil => Nil
case Cons(y, ys) => insort(y, sort(ys))
}
@@ -239,17 +239,17 @@ function sort(xs: List): List
function zip(a: List, b: List): PList
{
match a
- case Nil => #PList.PNil
+ case Nil => PNil
case Cons(x, xs) => match b
- case Nil => #PList.PNil
- case Cons(y, ys) => #PList.PCons(#Pair.Pair(x, y), zip(xs, ys))
+ case Nil => PNil
+ case Cons(y, ys) => PCons(Pair.Pair(x, y), zip(xs, ys))
}
function zipConcat(x: Nat, xs: List, more: List): PList
{
match more
- case Nil => #PList.PNil
- case Cons(y, ys) => #PList.PCons(#Pair.Pair(x, y), zip(xs, ys))
+ case Nil => PNil
+ case Cons(y, ys) => PCons(Pair.Pair(x, y), zip(xs, ys))
}
// Binary tree functions
@@ -257,15 +257,15 @@ function zipConcat(x: Nat, xs: List, more: List): PList
function height(t: Tree): Nat
{
match t
- case Leaf => #Nat.Zero
- case Node(l, x, r) => #Nat.Suc(max(height(l), height(r)))
+ case Leaf => Zero
+ case Node(l, x, r) => Suc(max(height(l), height(r)))
}
function mirror(t: Tree): Tree
{
match t
- case Leaf => #Tree.Leaf
- case Node(l, x, r) => #Tree.Node(mirror(r), x, mirror(l))
+ case Leaf => Leaf
+ case Node(l, x, r) => Node(mirror(r), x, mirror(l))
}
// The theorems to be proved
@@ -281,24 +281,24 @@ ghost method P2()
}
ghost method P3()
- ensures (forall n, xs, ys :: leq(count(n, xs), count(n, concat(xs, ys))) == #Bool.True);
+ ensures (forall n, xs, ys :: leq(count(n, xs), count(n, concat(xs, ys))) == True);
{
}
ghost method P4()
- ensures (forall n, xs :: add(#Nat.Suc(#Nat.Zero), count(n, xs)) == count(n, #List.Cons(n, xs)));
+ ensures (forall n, xs :: add(Suc(Zero), count(n, xs)) == count(n, Cons(n, xs)));
{
}
ghost method P5()
ensures (forall n, xs, x ::
- add(#Nat.Suc(#Nat.Zero), count(n, xs)) == count(n, #List.Cons(x, xs))
+ add(Suc(Zero), count(n, xs)) == count(n, Cons(x, xs))
==> n == x);
{
}
ghost method P6()
- ensures (forall m, n :: minus(n, add(n, m)) == #Nat.Zero);
+ ensures (forall m, n :: minus(n, add(n, m)) == Zero);
{
}
@@ -318,12 +318,12 @@ ghost method P9()
}
ghost method P10()
- ensures (forall m :: minus(m, m) == #Nat.Zero);
+ ensures (forall m :: minus(m, m) == Zero);
{
}
ghost method P11()
- ensures (forall xs :: drop(#Nat.Zero, xs) == xs);
+ ensures (forall xs :: drop(Zero, xs) == xs);
{
}
@@ -333,7 +333,7 @@ ghost method P12()
}
ghost method P13()
- ensures (forall n, x, xs :: drop(#Nat.Suc(n), #List.Cons(x, xs)) == drop(n, xs));
+ ensures (forall n, x, xs :: drop(Suc(n), Cons(x, xs)) == drop(n, xs));
{
}
@@ -343,22 +343,22 @@ ghost method P14()
}
ghost method P15()
- ensures (forall x, xs :: len(ins(x, xs)) == #Nat.Suc(len(xs)));
+ ensures (forall x, xs :: len(ins(x, xs)) == Suc(len(xs)));
{
}
ghost method P16()
- ensures (forall x, xs :: xs == #List.Nil ==> last(#List.Cons(x, xs)) == x);
+ ensures (forall x, xs :: xs == Nil ==> last(Cons(x, xs)) == x);
{
}
ghost method P17()
- ensures (forall n :: leq(n, #Nat.Zero) == #Bool.True <==> n == #Nat.Zero);
+ ensures (forall n :: leq(n, Zero) == True <==> n == Zero);
{
}
ghost method P18()
- ensures (forall i, m :: less(i, #Nat.Suc(add(i, m))) == #Bool.True);
+ ensures (forall i, m :: less(i, Suc(add(i, m))) == True);
{
}
@@ -371,15 +371,15 @@ ghost method P20()
ensures (forall xs :: len(sort(xs)) == len(xs));
{
// proving this theorem requires an additional lemma:
- assert (forall k, ks :: len(ins(k, ks)) == len(#List.Cons(k, ks)));
+ assert (forall k, ks :: len(ins(k, ks)) == len(Cons(k, ks)));
// ...and one manually introduced case study:
assert (forall ys ::
- sort(ys) == #List.Nil ||
- (exists z, zs :: sort(ys) == #List.Cons(z, zs)));
+ sort(ys) == Nil ||
+ (exists z, zs :: sort(ys) == Cons(z, zs)));
}
ghost method P21()
- ensures (forall n, m :: leq(n, add(n, m)) == #Bool.True);
+ ensures (forall n, m :: leq(n, add(n, m)) == True);
{
}
@@ -394,37 +394,37 @@ ghost method P23()
}
ghost method P24()
- ensures (forall a, b :: max(a, b) == a <==> leq(b, a) == #Bool.True);
+ ensures (forall a, b :: max(a, b) == a <==> leq(b, a) == True);
{
}
ghost method P25()
- ensures (forall a, b :: max(a, b) == b <==> leq(a, b) == #Bool.True);
+ ensures (forall a, b :: max(a, b) == b <==> leq(a, b) == True);
{
}
ghost method P26()
- ensures (forall x, xs, ys :: mem(x, xs) == #Bool.True ==> mem(x, concat(xs, ys)) == #Bool.True);
+ ensures (forall x, xs, ys :: mem(x, xs) == True ==> mem(x, concat(xs, ys)) == True);
{
}
ghost method P27()
- ensures (forall x, xs, ys :: mem(x, ys) == #Bool.True ==> mem(x, concat(xs, ys)) == #Bool.True);
+ ensures (forall x, xs, ys :: mem(x, ys) == True ==> mem(x, concat(xs, ys)) == True);
{
}
ghost method P28()
- ensures (forall x, xs :: mem(x, concat(xs, #List.Cons(x, #List.Nil))) == #Bool.True);
+ ensures (forall x, xs :: mem(x, concat(xs, Cons(x, Nil))) == True);
{
}
ghost method P29()
- ensures (forall x, xs :: mem(x, ins1(x, xs)) == #Bool.True);
+ ensures (forall x, xs :: mem(x, ins1(x, xs)) == True);
{
}
ghost method P30()
- ensures (forall x, xs :: mem(x, ins(x, xs)) == #Bool.True);
+ ensures (forall x, xs :: mem(x, ins(x, xs)) == True);
{
}
@@ -439,43 +439,43 @@ ghost method P32()
}
ghost method P33()
- ensures (forall a, b :: min(a, b) == a <==> leq(a, b) == #Bool.True);
+ ensures (forall a, b :: min(a, b) == a <==> leq(a, b) == True);
{
}
ghost method P34()
- ensures (forall a, b :: min(a, b) == b <==> leq(b, a) == #Bool.True);
+ ensures (forall a, b :: min(a, b) == b <==> leq(b, a) == True);
{
}
ghost method P35()
- ensures (forall xs :: dropWhileAlways(#Bool.False, xs) == xs);
+ ensures (forall xs :: dropWhileAlways(False, xs) == xs);
{
}
ghost method P36()
- ensures (forall xs :: takeWhileAlways(#Bool.True, xs) == xs);
+ ensures (forall xs :: takeWhileAlways(True, xs) == xs);
{
}
ghost method P37()
- ensures (forall x, xs :: not(mem(x, delete(x, xs))) == #Bool.True);
+ ensures (forall x, xs :: not(mem(x, delete(x, xs))) == True);
{
}
ghost method P38()
- ensures (forall n, xs :: count(n, concat(xs, #List.Cons(n, #List.Nil))) == #Nat.Suc(count(n, xs)));
+ ensures (forall n, xs :: count(n, concat(xs, Cons(n, Nil))) == Suc(count(n, xs)));
{
}
ghost method P39()
ensures (forall n, x, xs ::
- add(count(n, #List.Cons(x, #List.Nil)), count(n, xs)) == count(n, #List.Cons(x, xs)));
+ add(count(n, Cons(x, Nil)), count(n, xs)) == count(n, Cons(x, xs)));
{
}
ghost method P40()
- ensures (forall xs :: take(#Nat.Zero, xs) == #List.Nil);
+ ensures (forall xs :: take(Zero, xs) == Nil);
{
}
@@ -485,7 +485,7 @@ ghost method P41()
}
ghost method P42()
- ensures (forall n, x, xs :: take(#Nat.Suc(n), #List.Cons(x, xs)) == #List.Cons(x, take(n, xs)));
+ ensures (forall n, x, xs :: take(Suc(n), Cons(x, xs)) == Cons(x, take(n, xs)));
{
}
@@ -496,19 +496,19 @@ ghost method P43(p: Bool)
}
ghost method P44()
- ensures (forall x, xs, ys :: zip(#List.Cons(x, xs), ys) == zipConcat(x, xs, ys));
+ ensures (forall x, xs, ys :: zip(Cons(x, xs), ys) == zipConcat(x, xs, ys));
{
}
ghost method P45()
ensures (forall x, xs, y, ys ::
- zip(#List.Cons(x, xs), #List.Cons(y, ys)) ==
- #PList.PCons(#Pair.Pair(x, y), zip(xs, ys)));
+ zip(Cons(x, xs), Cons(y, ys)) ==
+ PCons(Pair.Pair(x, y), zip(xs, ys)));
{
}
ghost method P46()
- ensures (forall ys :: zip(#List.Nil, ys) == #PList.PNil);
+ ensures (forall ys :: zip(Nil, ys) == PNil);
{
}
@@ -530,27 +530,27 @@ ghost method P54()
}
ghost method P65()
- ensures (forall i, m :: less(i, #Nat.Suc(add(m, i))) == #Bool.True);
+ ensures (forall i, m :: less(i, Suc(add(m, i))) == True);
{
if (*) {
// the proof of this theorem follows from two lemmas:
- assert (forall i, m :: less(i, #Nat.Suc(add(i, m))) == #Bool.True);
+ assert (forall i, m :: less(i, Suc(add(i, m))) == True);
assert (forall m, n :: add(m, n) == add(n, m));
} else {
// a different way to prove it uses the following lemma:
- assert (forall x,y :: add(x, #Nat.Suc(y)) == #Nat.Suc(add(x,y)));
+ assert (forall x,y :: add(x, Suc(y)) == Suc(add(x,y)));
}
}
ghost method P67()
- ensures (forall m, n :: leq(n, add(m, n)) == #Bool.True);
+ ensures (forall m, n :: leq(n, add(m, n)) == True);
{
if (*) {
// the proof of this theorem follows from two lemmas:
- assert (forall m, n :: leq(n, add(n, m)) == #Bool.True);
+ assert (forall m, n :: leq(n, add(n, m)) == True);
assert (forall m, n :: add(m, n) == add(n, m));
} else {
// a different way to prove it uses the following lemma:
- assert (forall x,y :: add(x, #Nat.Suc(y)) == #Nat.Suc(add(x,y)));
+ assert (forall x,y :: add(x, Suc(y)) == Suc(add(x,y)));
}
}
diff --git a/Test/dafny1/SchorrWaite.dfy b/Test/dafny1/SchorrWaite.dfy
index 0d69b1b8..8da32b05 100644
--- a/Test/dafny1/SchorrWaite.dfy
+++ b/Test/dafny1/SchorrWaite.dfy
@@ -10,6 +10,8 @@ class Node {
ghost var pathFromRoot: Path;
}
+datatype Path = Empty | Extend(Path, Node);
+
class Main {
method RecursiveMark(root: Node, ghost S: set<Node>)
requires root in S;
@@ -26,7 +28,7 @@ class Main {
n.childrenVisited == old(n.childrenVisited) &&
n.children == old(n.children));
{
- call RecursiveMarkWorker(root, S, {});
+ RecursiveMarkWorker(root, S, {});
}
method RecursiveMarkWorker(root: Node, ghost S: set<Node>, ghost stackNodes: set<Node>)
@@ -67,7 +69,7 @@ class Main {
{
var c := root.children[i];
if (c != null) {
- call RecursiveMarkWorker(c, S, stackNodes + {root});
+ RecursiveMarkWorker(c, S, stackNodes + {root});
}
i := i + 1;
}
@@ -182,7 +184,7 @@ class Main {
{
var t := root;
var p: Node := null; // parent of t in original graph
- ghost var path := #Path.Empty;
+ ghost var path := Path.Empty;
t.marked := true;
t.pathFromRoot := path;
ghost var stackNodes := [];
@@ -256,7 +258,7 @@ class Main {
t.children := t.children[..t.childrenVisited] + [p] + t.children[t.childrenVisited + 1..];
p := t;
stackNodes := stackNodes + [t];
- path := #Path.Extend(path, t);
+ path := Path.Extend(path, t);
t := newT;
t.marked := true;
t.pathFromRoot := path;
@@ -265,8 +267,3 @@ class Main {
}
}
}
-
-datatype Path {
- Empty;
- Extend(Path, Node);
-}
diff --git a/Test/dafny1/SeparationLogicList.dfy b/Test/dafny1/SeparationLogicList.dfy
index 7828a54e..56a64bd6 100644
--- a/Test/dafny1/SeparationLogicList.dfy
+++ b/Test/dafny1/SeparationLogicList.dfy
@@ -28,7 +28,7 @@ class Node<T> {
l.next := null;
S := {l};
} else {
- call l, S := Cons(x, null, [], {});
+ l, S := Cons(x, null, [], {});
}
}
@@ -75,7 +75,7 @@ class ListNode<T> {
l.Repr := {l};
l.Contents := [x];
} else {
- call l := Cons(x, null);
+ l := Cons(x, null);
}
}
diff --git a/Test/dafny1/Substitution.dfy b/Test/dafny1/Substitution.dfy
index 8d51bdd1..ad39e3f2 100644
--- a/Test/dafny1/Substitution.dfy
+++ b/Test/dafny1/Substitution.dfy
@@ -1,27 +1,23 @@
-datatype List {
- Nil;
- Cons(Expr, List);
-}
+datatype List = Nil | Cons(Expr, List);
-datatype Expr {
- Const(int);
- Var(int);
+datatype Expr =
+ Const(int) |
+ Var(int) |
Nary(int, List);
-}
static function Subst(e: Expr, v: int, val: int): Expr
{
match e
case Const(c) => e
- case Var(x) => if x == v then #Expr.Const(val) else e
- case Nary(op, args) => #Expr.Nary(op, SubstList(args, v, val))
+ case Var(x) => if x == v then Expr.Const(val) else e
+ case Nary(op, args) => Expr.Nary(op, SubstList(args, v, val))
}
static function SubstList(l: List, v: int, val: int): List
{
match l
case Nil => l
- case Cons(e, tail) => #List.Cons(Subst(e, v, val), SubstList(tail, v, val))
+ case Cons(e, tail) => Cons(Subst(e, v, val), SubstList(tail, v, val))
}
static ghost method Theorem(e: Expr, v: int, val: int)
@@ -31,7 +27,7 @@ static ghost method Theorem(e: Expr, v: int, val: int)
case Const(c) =>
case Var(x) =>
case Nary(op, args) =>
- call Lemma(args, v, val);
+ Lemma(args, v, val);
}
}
@@ -41,26 +37,25 @@ static ghost method Lemma(l: List, v: int, val: int)
match l {
case Nil =>
case Cons(e, tail) =>
- call Theorem(e, v, val);
- call Lemma(tail, v, val);
+ Theorem(e, v, val);
+ Lemma(tail, v, val);
}
}
// -------------------------------
-datatype Expression {
- Const(int);
- Var(int);
+datatype Expression =
+ Const(int) |
+ Var(int) |
Nary(int, seq<Expression>);
-}
static function Substitute(e: Expression, v: int, val: int): Expression
decreases e;
{
match e
case Const(c) => e
- case Var(x) => if x == v then #Expression.Const(val) else e
- case Nary(op, args) => #Expression.Nary(op, SubstSeq(e, args, v, val))
+ case Var(x) => if x == v then Expression.Const(val) else e
+ case Nary(op, args) => Expression.Nary(op, SubstSeq(e, args, v, val))
}
static function SubstSeq(/*ghost*/ parent: Expression,
@@ -80,11 +75,11 @@ static ghost method TheoremSeq(e: Expression, v: int, val: int)
case Var(x) =>
case Nary(op, args) =>
ghost var seArgs := SubstSeq(e, args, v, val);
- call LemmaSeq(e, args, v, val);
+ LemmaSeq(e, args, v, val);
ghost var se := Substitute(e, v, val);
ghost var seArgs2 := SubstSeq(se, seArgs, v, val);
- call LemmaSeq(se, seArgs, v, val);
+ LemmaSeq(se, seArgs, v, val);
var N := |args|;
var j := 0;
@@ -92,14 +87,14 @@ static ghost method TheoremSeq(e: Expression, v: int, val: int)
invariant j <= N;
invariant (forall k :: 0 <= k && k < j ==> seArgs2[k] == seArgs[k]);
{
- call TheoremSeq(args[j], v, val);
+ TheoremSeq(args[j], v, val);
j := j + 1;
}
assert seArgs == seArgs2;
}
}
-static ghost method LemmaSeq(ghost parent: Expression, ghost q: seq<Expression>, v: int, val: int)
+static ghost method LemmaSeq(parent: Expression, q: seq<Expression>, v: int, val: int)
requires (forall a :: a in q ==> a < parent);
ensures |SubstSeq(parent, q, v, val)| == |q|;
ensures (forall k :: 0 <= k && k < |q| ==>
@@ -107,6 +102,6 @@ static ghost method LemmaSeq(ghost parent: Expression, ghost q: seq<Expression>,
{
if (q == []) {
} else {
- call LemmaSeq(parent, q[..|q|-1], v, val);
+ LemmaSeq(parent, q[..|q|-1], v, val);
}
}
diff --git a/Test/dafny1/SumOfCubes.dfy b/Test/dafny1/SumOfCubes.dfy
index 2fecaee5..7ed7ce9b 100644
--- a/Test/dafny1/SumOfCubes.dfy
+++ b/Test/dafny1/SumOfCubes.dfy
@@ -10,19 +10,19 @@ class SumOfCubes {
requires 0 <= n && n <= m;
ensures r == SumEmUp(n, m);
{
- call a := SocuFromZero(m);
- call b := SocuFromZero(n);
+ var a := SocuFromZero(m);
+ var b := SocuFromZero(n);
r := a - b;
- call Lemma0(n, m);
+ Lemma0(n, m);
}
static method SocuFromZero(k: int) returns (r: int)
requires 0 <= k;
ensures r == SumEmUp(0, k);
{
- call g := Gauss(k);
+ var g := Gauss(k);
r := g * g;
- call Lemma1(k);
+ Lemma1(k);
}
ghost static method Lemma0(n: int, m: int)
@@ -36,9 +36,9 @@ class SumOfCubes {
{
k := k + 1;
}
- call Lemma3(0, n);
- call Lemma3(n, k);
- call Lemma3(0, k);
+ Lemma3(0, n);
+ Lemma3(n, k);
+ Lemma3(0, k);
}
static function GSum(k: int): int
@@ -52,7 +52,7 @@ class SumOfCubes {
ensures r == GSum(k);
{
r := k * (k - 1) / 2;
- call Lemma2(k);
+ Lemma2(k);
}
ghost static method Lemma1(k: int)
@@ -64,10 +64,10 @@ class SumOfCubes {
invariant i <= k;
invariant SumEmDown(0, i) == GSum(i) * GSum(i);
{
- call Lemma2(i);
+ Lemma2(i);
i := i + 1;
}
- call Lemma3(0, k);
+ Lemma3(0, k);
}
ghost static method Lemma2(k: int)
diff --git a/Test/dafny1/TerminationDemos.dfy b/Test/dafny1/TerminationDemos.dfy
index 49f5a075..0aa36a10 100644
--- a/Test/dafny1/TerminationDemos.dfy
+++ b/Test/dafny1/TerminationDemos.dfy
@@ -58,10 +58,10 @@ class Ackermann {
if (m == 0) {
r := n + 1;
} else if (n == 0) {
- call r := ComputeAck(m - 1, 1);
+ r := ComputeAck(m - 1, 1);
} else {
- call s := ComputeAck(m, n - 1);
- call r := ComputeAck(m - 1, s);
+ var s := ComputeAck(m, n - 1);
+ r := ComputeAck(m - 1, s);
}
}
}
diff --git a/Test/dafny1/TreeDatatype.dfy b/Test/dafny1/TreeDatatype.dfy
index f576850e..a94283e6 100644
--- a/Test/dafny1/TreeDatatype.dfy
+++ b/Test/dafny1/TreeDatatype.dfy
@@ -1,68 +1,56 @@
// ------------------ generic list, non-generic tree
-datatype List<T> {
- Nil;
- Cons(T, List<T>);
-}
+datatype List<T> = Nil | Cons(T, List<T>);
-datatype Tree {
- Node(int, List<Tree>);
-}
+datatype Tree = Node(int, List<Tree>);
static function Inc(t: Tree): Tree
{
match t
- case Node(n, children) => #Tree.Node(n+1, ForestInc(children))
+ case Node(n, children) => Tree.Node(n+1, ForestInc(children))
}
static function ForestInc(forest: List<Tree>): List<Tree>
{
match forest
case Nil => forest
- case Cons(tree, tail) => #List.Cons(Inc(tree), ForestInc(tail))
+ case Cons(tree, tail) => List.Cons(Inc(tree), ForestInc(tail))
}
// ------------------ generic list, generic tree (but GInc defined only for GTree<int>
-datatype GTree<T> {
- Node(T, List<GTree<T>>);
-}
+datatype GTree<T> = Node(T, List<GTree<T>>);
static function GInc(t: GTree<int>): GTree<int>
{
match t
- case Node(n, children) => #GTree.Node(n+1, GForestInc(children))
+ case Node(n, children) => GTree.Node(n+1, GForestInc(children))
}
static function GForestInc(forest: List<GTree<int>>): List<GTree<int>>
{
match forest
case Nil => forest
- case Cons(tree, tail) => #List.Cons(GInc(tree), GForestInc(tail))
+ case Cons(tree, tail) => List.Cons(GInc(tree), GForestInc(tail))
}
// ------------------ non-generic structures
-datatype TreeList {
- Nil;
- Cons(OneTree, TreeList);
-}
+datatype TreeList = Nil | Cons(OneTree, TreeList);
-datatype OneTree {
- Node(int, TreeList);
-}
+datatype OneTree = Node(int, TreeList);
static function XInc(t: OneTree): OneTree
{
match t
- case Node(n, children) => #OneTree.Node(n+1, XForestInc(children))
+ case Node(n, children) => OneTree.Node(n+1, XForestInc(children))
}
static function XForestInc(forest: TreeList): TreeList
{
match forest
case Nil => forest
- case Cons(tree, tail) => #TreeList.Cons(XInc(tree), XForestInc(tail))
+ case Cons(tree, tail) => TreeList.Cons(XInc(tree), XForestInc(tail))
}
// ------------------ fun with recursive functions
@@ -77,7 +65,7 @@ function len<T>(l: List<T>): int
function SingletonList<T>(h: T): List<T>
ensures len(SingletonList(h)) == 1;
{
- #List.Cons(h, #List.Nil)
+ List.Cons(h, List.Nil)
}
function Append<T>(a: List<T>, b: List<T>): List<T>
@@ -85,7 +73,7 @@ function Append<T>(a: List<T>, b: List<T>): List<T>
{
match a
case Nil => b
- case Cons(h,t) => #List.Cons(h, Append(t, b))
+ case Cons(h,t) => List.Cons(h, Append(t, b))
}
function Rotate<T>(n: int, l: List<T>): List<T>
diff --git a/Test/dafny1/UltraFilter.dfy b/Test/dafny1/UltraFilter.dfy
index 61e86836..189ff2b5 100644
--- a/Test/dafny1/UltraFilter.dfy
+++ b/Test/dafny1/UltraFilter.dfy
@@ -22,9 +22,9 @@ class UltraFilter<G> {
{
if (M !in f) {
// instantiate 'g' with the following 'h'
- call h := H(f, S, M);
- call Lemma_HIsFilter(h, f, S, M);
- call Lemma_FHOrdering0(h, f, S, M);
+ var h := H(f, S, M);
+ Lemma_HIsFilter(h, f, S, M);
+ Lemma_FHOrdering0(h, f, S, M);
}
}
@@ -44,9 +44,9 @@ class UltraFilter<G> {
// call Lemma_H1(h, f, S, M, *, *);
assume (forall C, D :: C in h && D in h ==> C * D in h);
- call Lemma_H2(h, f, S, M);
+ Lemma_H2(h, f, S, M);
- call Lemma_H3(h, f, S, M);
+ Lemma_H3(h, f, S, M);
}
method Lemma_H0(h: set<set<G>>, f: set<set<G>>, S: set<G>, M: set<G>, A: set<G>, B: set<G>)
diff --git a/Test/dafny1/pow2.dfy b/Test/dafny1/pow2.dfy
index 52cddaac..c7e4bc63 100644
--- a/Test/dafny1/pow2.dfy
+++ b/Test/dafny1/pow2.dfy
@@ -36,7 +36,7 @@ ghost method Lemma(n: int)
ensures pow2_slow(n) == Square(pow2_slow(n/2));
{
if (n != 0) {
- call Lemma(n-2);
+ Lemma(n-2);
}
}
@@ -46,9 +46,9 @@ ghost method Theorem(n: int)
{
if (n == 0) {
} else if (IsEven(n)) {
- call Lemma(n);
- call Theorem(n/2);
+ Lemma(n);
+ Theorem(n/2);
} else {
- call Theorem(n-1);
+ Theorem(n-1);
}
}
diff --git a/Test/vacid0/Composite.dfy b/Test/vacid0/Composite.dfy
index 95ad12fa..ed376931 100644
--- a/Test/vacid0/Composite.dfy
+++ b/Test/vacid0/Composite.dfy
@@ -44,7 +44,7 @@ class Composite {
{
var delta := x - val;
val := x;
- call Adjust(delta, S, S);
+ Adjust(delta, S, S);
}
method Add(ghost S: set<Composite>, child: Composite, ghost U: set<Composite>)
@@ -73,7 +73,7 @@ class Composite {
right := child;
}
child.parent := this;
- call Adjust(child.sum, S, S+U);
+ Adjust(child.sum, S, S+U);
}
method Dislodge(ghost S: set<Composite>)
@@ -97,7 +97,7 @@ class Composite {
p.right := null;
}
var delta := -sum;
- call p.Adjust(delta, S - {this}, S);
+ p.Adjust(delta, S - {this}, S);
}
}
@@ -138,35 +138,35 @@ method Main()
var c0 := new Composite.Init(57);
var c1 := new Composite.Init(12);
- call c0.Add({c0}, c1, {c1});
+ c0.Add({c0}, c1, {c1});
var c2 := new Composite.Init(48);
var c3 := new Composite.Init(48);
- call c2.Add({c2}, c3, {c3});
- call c0.Add({c0,c1}, c2, {c2,c3});
+ c2.Add({c2}, c3, {c3});
+ c0.Add({c0,c1}, c2, {c2,c3});
ghost var S := {c0, c1, c2, c3};
- call c1.Update(100, S);
- call c2.Update(102, S);
+ c1.Update(100, S);
+ c2.Update(102, S);
- call c2.Dislodge(S);
- call c2.Update(496, S);
- call c0.Update(0, S);
+ c2.Dislodge(S);
+ c2.Update(496, S);
+ c0.Update(0, S);
}
method Harness() {
var a := new Composite.Init(5);
var b := new Composite.Init(7);
- call a.Add({a}, b, {b});
+ a.Add({a}, b, {b});
assert a.sum == 12;
- call b.Update(17, {a,b});
+ b.Update(17, {a,b});
assert a.sum == 22;
var c := new Composite.Init(10);
- call b.Add({a,b}, c, {c});
- call b.Dislodge({a,b,c});
+ b.Add({a,b}, c, {c});
+ b.Dislodge({a,b,c});
assert b.sum == 27;
}
diff --git a/Test/vacid0/SparseArray.dfy b/Test/vacid0/SparseArray.dfy
index 2c217264..989ddfc6 100644
--- a/Test/vacid0/SparseArray.dfy
+++ b/Test/vacid0/SparseArray.dfy
@@ -37,11 +37,9 @@ class SparseArray<T> {
ensures |Contents| == N && this.zero == zero;
ensures (forall x :: x in Contents ==> x == zero);
{
- var aa;
- var ii;
- call aa := AllocateArray(N); this.a := aa;
- call ii := AllocateArray(N); this.b := ii;
- call ii := AllocateArray(N); this.c := ii;
+ var aa := AllocateArray(N); this.a := aa;
+ var bb := AllocateArray(N); this.b := bb;
+ bb := AllocateArray(N); this.c := bb;
this.n := 0;
// initialize ghost variable Contents to a sequence of length N containing only zero's,
diff --git a/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyLanguageService.cs b/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyLanguageService.cs
index aed73699..b9a0ca22 100644
--- a/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyLanguageService.cs
+++ b/Util/VS2010/Dafny/DafnyLanguageService/Integration/IronyLanguageService.cs
@@ -172,9 +172,26 @@ namespace Demo
//string result = reader.ReadToEnd();
//Console.Write(result);
- for (string line = reader.ReadLine(); !String.IsNullOrEmpty(line); line = reader.ReadLine()) {
+ for (string line = reader.ReadLine(); line != null; line = reader.ReadLine()) {
// the lines of interest have the form "filename(line,col): some_error_label: error_message"
// where "some_error_label" is "Error" or "syntax error" or "Error BP5003" or "Related location"
+ if (line.Equals("")) continue;
+ if (line.StartsWith("Dafny program verifier finished with") && line.Contains("time out"))
+ {
+ try
+ {
+ AddErrorBecauseOfToolProblems(req, "Verification timed out.");
+ }
+ catch (System.FormatException)
+ {
+ continue;
+ }
+ catch (System.OverflowException)
+ {
+ continue;
+ }
+ continue;
+ }
string message;
int n = line.IndexOf("): ", 2); // we start at 2, to avoid problems with "C:\..."
if (n == -1) {