summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorGravatar Dan Rosén <danr@chalmers.se>2014-07-07 17:24:46 -0700
committerGravatar Dan Rosén <danr@chalmers.se>2014-07-07 17:24:46 -0700
commit661faf59f8e1003cdbf339260d1293e8dd77f2df (patch)
tree37e11e8a86658fe4d69b38572f3b6fadd8d287c9 /Source
parent8de9fcae1a91acce9a1e59f292f05a95c81b3dbc (diff)
parent93d9965a347b1a6ad70007822f01c2b032ea5436 (diff)
Merge
Diffstat (limited to 'Source')
-rw-r--r--Source/Dafny.sln12
-rw-r--r--Source/Dafny/Cloner.cs22
-rw-r--r--Source/Dafny/Compiler.cs26
-rw-r--r--Source/Dafny/Dafny.atg227
-rw-r--r--Source/Dafny/DafnyAst.cs282
-rw-r--r--Source/Dafny/Parser.cs684
-rw-r--r--Source/Dafny/Printer.cs68
-rw-r--r--Source/Dafny/Resolver.cs109
-rw-r--r--Source/Dafny/Scanner.cs108
-rw-r--r--Source/Dafny/Translator.cs435
-rw-r--r--Source/DafnyDriver/DafnyDriver.cs20
-rw-r--r--Source/DafnyDriver/DafnyDriver.csproj2
-rw-r--r--Source/DafnyExtension/DafnyDriver.cs38
-rw-r--r--Source/DafnyExtension/MenuProxy.cs15
-rw-r--r--Source/DafnyExtension/TokenTagger.cs84
-rw-r--r--Source/DafnyExtension/source.extension.vsixmanifest2
-rw-r--r--Source/DafnyMenu/DafnyMenu.vsct11
-rw-r--r--Source/DafnyMenu/DafnyMenuPackage.cs40
-rw-r--r--Source/DafnyMenu/PkgCmdID.cs1
-rw-r--r--Source/DafnyMenu/source.extension.vsixmanifest2
20 files changed, 1489 insertions, 699 deletions
diff --git a/Source/Dafny.sln b/Source/Dafny.sln
index 034dfd7b..40e71952 100644
--- a/Source/Dafny.sln
+++ b/Source/Dafny.sln
@@ -1,6 +1,6 @@

-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DafnyDriver", "DafnyDriver\DafnyDriver.csproj", "{63400D1F-05B2-453E-9592-1EAB74B2C9CC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DafnyPipeline", "Dafny\DafnyPipeline.csproj", "{FE44674A-1633-4917-99F4-57635E6FA740}"
@@ -28,8 +28,8 @@ Global
{63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Debug|.NET.Build.0 = Debug|Any CPU
{63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Debug|Mixed Platforms.ActiveCfg = Checked|Any CPU
+ {63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Debug|Mixed Platforms.Build.0 = Checked|Any CPU
{63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Release|.NET.ActiveCfg = Release|Any CPU
{63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63400D1F-05B2-453E-9592-1EAB74B2C9CC}.Release|Any CPU.Build.0 = Release|Any CPU
@@ -45,8 +45,8 @@ Global
{FE44674A-1633-4917-99F4-57635E6FA740}.Debug|.NET.Build.0 = Debug|Any CPU
{FE44674A-1633-4917-99F4-57635E6FA740}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE44674A-1633-4917-99F4-57635E6FA740}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FE44674A-1633-4917-99F4-57635E6FA740}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {FE44674A-1633-4917-99F4-57635E6FA740}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {FE44674A-1633-4917-99F4-57635E6FA740}.Debug|Mixed Platforms.ActiveCfg = Checked|Any CPU
+ {FE44674A-1633-4917-99F4-57635E6FA740}.Debug|Mixed Platforms.Build.0 = Checked|Any CPU
{FE44674A-1633-4917-99F4-57635E6FA740}.Release|.NET.ActiveCfg = Release|Any CPU
{FE44674A-1633-4917-99F4-57635E6FA740}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE44674A-1633-4917-99F4-57635E6FA740}.Release|Any CPU.Build.0 = Release|Any CPU
diff --git a/Source/Dafny/Cloner.cs b/Source/Dafny/Cloner.cs
index 699d73d1..99da0774 100644
--- a/Source/Dafny/Cloner.cs
+++ b/Source/Dafny/Cloner.cs
@@ -30,6 +30,9 @@ namespace Microsoft.Dafny
if (d is ArbitraryTypeDecl) {
var dd = (ArbitraryTypeDecl)d;
return new ArbitraryTypeDecl(Tok(dd.tok), dd.Name, m, dd.EqualitySupport, CloneAttributes(dd.Attributes));
+ } else if (d is TupleTypeDecl) {
+ var dd = (TupleTypeDecl)d;
+ return new TupleTypeDecl(dd.Dims, dd.Module);
} else if (d is IndDatatypeDecl) {
var dd = (IndDatatypeDecl)d;
var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
@@ -61,18 +64,13 @@ namespace Microsoft.Dafny
body, CloneAttributes(dd.Attributes), dd.SignatureEllipsis);
return iter;
} else if (d is ClassDecl) {
+ var dd = (ClassDecl)d;
+ var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
+ var mm = dd.Members.ConvertAll(CloneMember);
if (d is DefaultClassDecl) {
- var dd = (ClassDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var mm = dd.Members.ConvertAll(CloneMember);
- var cl = new DefaultClassDecl(m, mm);
- return cl;
+ return new DefaultClassDecl(m, mm);
} else {
- var dd = (ClassDecl)d;
- var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
- var mm = dd.Members.ConvertAll(CloneMember);
- var cl = new ClassDecl(Tok(dd.tok), dd.Name, m, tps, mm, CloneAttributes(dd.Attributes));
- return cl;
+ return new ClassDecl(Tok(dd.tok), dd.Name, m, tps, mm, CloneAttributes(dd.Attributes));
}
} else if (d is ModuleDecl) {
if (d is LiteralModuleDecl) {
@@ -355,7 +353,7 @@ namespace Microsoft.Dafny
} else if (expr is MatchExpr) {
var e = (MatchExpr)expr;
return new MatchExpr(Tok(e.tok), CloneExpr(e.Source),
- e.Cases.ConvertAll(c => new MatchCaseExpr(Tok(c.tok), c.Id, c.Arguments.ConvertAll(CloneBoundVar), CloneExpr(c.Body))));
+ e.Cases.ConvertAll(c => new MatchCaseExpr(Tok(c.tok), c.Id, c.Arguments.ConvertAll(CloneBoundVar), CloneExpr(c.Body))), e.UsesOptionalBraces);
} else if (expr is NegationExpression) {
var e = (NegationExpression)expr;
@@ -478,7 +476,7 @@ namespace Microsoft.Dafny
} else if (stmt is MatchStmt) {
var s = (MatchStmt)stmt;
r = new MatchStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Source),
- s.Cases.ConvertAll(c => new MatchCaseStmt(Tok(c.tok), c.Id, c.Arguments.ConvertAll(CloneBoundVar), c.Body.ConvertAll(CloneStmt))));
+ s.Cases.ConvertAll(c => new MatchCaseStmt(Tok(c.tok), c.Id, c.Arguments.ConvertAll(CloneBoundVar), c.Body.ConvertAll(CloneStmt))), s.UsesOptionalBraces);
} else if (stmt is AssignSuchThatStmt) {
var s = (AssignSuchThatStmt)stmt;
diff --git a/Source/Dafny/Compiler.cs b/Source/Dafny/Compiler.cs
index f5e8ff30..fcf8a2ca 100644
--- a/Source/Dafny/Compiler.cs
+++ b/Source/Dafny/Compiler.cs
@@ -107,6 +107,10 @@ namespace Microsoft.Dafny {
indent += IndentAmount;
}
foreach (TopLevelDecl d in m.TopLevelDecls) {
+ bool compileIt = true;
+ if (Attributes.ContainsBool(d.Attributes, "compile", ref compileIt) && !compileIt) {
+ continue;
+ }
wr.WriteLine();
if (d is ArbitraryTypeDecl) {
var at = (ArbitraryTypeDecl)d;
@@ -130,16 +134,16 @@ namespace Microsoft.Dafny {
// public T x; // yield-parameter
// public int y; // yield-parameter
// IEnumerator<object> _iter;
- //
+ //
// public void _MyIteratorExample(T q) {
// this.q = q;
// _iter = TheIterator();
// }
- //
+ //
// public void MoveNext(out bool more) {
// more =_iter.MoveNext();
// }
- //
+ //
// private IEnumerator<object> TheIterator() {
// // the translation of the body of the iterator, with each "yield" turning into a "yield return null;"
// yield break;
@@ -411,7 +415,12 @@ namespace Microsoft.Dafny {
if (dt is IndDatatypeDecl) {
Indent(ind); wr.WriteLine("public override string ToString() {");
- string nm = (dt.Module.IsDefaultModule ? "" : dt.Module.CompileName + ".") + dt.CompileName + "." + ctor.CompileName;
+ string nm;
+ if (dt is TupleTypeDecl) {
+ nm = "";
+ } else {
+ nm = (dt.Module.IsDefaultModule ? "" : dt.Module.CompileName + ".") + dt.CompileName + "." + ctor.CompileName;
+ }
Indent(ind + IndentAmount); wr.WriteLine("string s = \"{0}\";", nm);
if (ctor.Formals.Count != 0) {
Indent(ind + IndentAmount); wr.WriteLine("s += \"(\";");
@@ -538,7 +547,7 @@ namespace Microsoft.Dafny {
}
}
wr.Write(")");
-
+
wr.WriteLine(";");
Indent(ind + 2 * IndentAmount);
wr.WriteLine("}");
@@ -584,7 +593,7 @@ namespace Microsoft.Dafny {
Indent(ind);
wr.WriteLine("}");
}
-
+
// destructors
foreach (var ctor in dt.Ctors) {
foreach (var arg in ctor.Formals) {
@@ -1019,6 +1028,11 @@ namespace Microsoft.Dafny {
if (s.AssumeToken != null) {
compiler.Error("an assume statement cannot be compiled (line {0})", s.AssumeToken.line);
}
+ } else if (stmt is ForallStmt) {
+ var s = (ForallStmt)stmt;
+ if (s.Body == null) {
+ compiler.Error("a forall statement without a body cannot be compiled (line {0})", stmt.Tok.line);
+ }
}
}
}
diff --git a/Source/Dafny/Dafny.atg b/Source/Dafny/Dafny.atg
index 74aa4abd..c8f410c9 100644
--- a/Source/Dafny/Dafny.atg
+++ b/Source/Dafny/Dafny.atg
@@ -81,7 +81,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, ModuleDecl module,
parser.Parse();
return parser.errors.count;
}
-public Parser(Scanner/*!*/ scanner, Errors/*!*/ errors, ModuleDecl module, BuiltIns builtIns, bool verifyThisFile=true)
+public Parser(Scanner/*!*/ scanner, Errors/*!*/ errors, ModuleDecl module, BuiltIns builtIns, bool verifyThisFile=true)
: this(scanner, errors) // the real work
{
// initialize readonly fields
@@ -130,6 +130,14 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
(e is FunctionCallExpr ||
(e is IdentifierSequence && ((IdentifierSequence)e).OpenParen != null));
}
+
+bool CloseOptionalParen(bool usesOptionalParen) {
+ return usesOptionalParen && la.kind == _closeparen;
+}
+
+bool CloseOptionalBrace(bool usesOptionalBrace) {
+ return usesOptionalBrace && la.kind == _rbrace;
+}
/*--------------------------------------------------------------------------*/
CHARACTERS
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
@@ -172,6 +180,7 @@ TOKENS
lbrace = '{'.
rbrace = '}'.
openparen = '('.
+ closeparen = ')'.
star = '*'.
notIn = "!in" CONTEXT (nonidchar).
COMMENTS FROM "/*" TO "*/" NESTED
@@ -197,9 +206,9 @@ Dafny
includedFile = Path.Combine(basePath, includedFile);
fullPath = Path.GetFullPath(includedFile);
}
- defaultModule.Includes.Add(new Include(t, includedFile, fullPath));
+ defaultModule.Includes.Add(new Include(t, includedFile, fullPath));
}
- .)
+ .)
}
{ SubModuleDecl<defaultModule, out submodule> (. defaultModule.TopLevelDecls.Add(submodule); .)
| ClassDecl<defaultModule, out c> (. defaultModule.TopLevelDecls.Add(c); .)
@@ -226,7 +235,7 @@ Dafny
.
SubModuleDecl<ModuleDefinition parent, out ModuleDecl submodule>
= (. ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt; ArbitraryTypeDecl at; IteratorDecl iter;
- Attributes attrs = null; IToken/*!*/ id;
+ Attributes attrs = null; IToken/*!*/ id;
List<MemberDecl/*!*/> namedModuleDefaultClassMembers = new List<MemberDecl>();;
List<IToken> idRefined = null, idPath = null, idAssignment = null;
ModuleDefinition module;
@@ -238,8 +247,8 @@ SubModuleDecl<ModuleDefinition parent, out ModuleDecl submodule>
( [ "abstract" (. isAbstract = true; .) ]
"module"
{ Attribute<ref attrs> }
- NoUSIdent<out id>
-
+ NoUSIdent<out id>
+
[ "refines" QualifiedName<out idRefined> ] (. module = new ModuleDefinition(id, id.val, isAbstract, false, idRefined == null ? null : idRefined, parent, attrs, false); .)
"{" (. module.BodyStartTok = t; .)
{ SubModuleDecl<module, out sm> (. module.TopLevelDecls.Add(sm); .)
@@ -252,15 +261,15 @@ SubModuleDecl<ModuleDefinition parent, out ModuleDecl submodule>
"}" (. module.BodyEndTok = t;
module.TopLevelDecls.Add(new DefaultClassDecl(module, namedModuleDefaultClassMembers));
submodule = new LiteralModuleDecl(module, parent); .)
- |
+ |
"import" ["opened" (.opened = true;.)]
- NoUSIdent<out id>
+ NoUSIdent<out id>
[ "=" QualifiedName<out idPath>
(. submodule = new AliasModuleDecl(idPath, id, parent, opened); .)
| "as" QualifiedName<out idPath> ["default" QualifiedName<out idAssignment> ]
(. submodule = new ModuleFacadeDecl(idPath, id, parent, idAssignment, opened); .)
]
- [ SYNC ";"
+ [ SYNC ";"
// This semi-colon used to be required, but it seems silly to have it.
// To stage the transition toward not having it at all, let's make it optional for now. Then,
// in a next big version of Dafny, including the following warning message:
@@ -342,7 +351,7 @@ DatatypeDecl<ModuleDefinition/*!*/ module, out DatatypeDecl/*!*/ dt>
"=" (. bodyStart = t; .)
DatatypeMemberDecl<ctors>
{ "|" DatatypeMemberDecl<ctors> }
- [ SYNC ";"
+ [ SYNC ";"
// This semi-colon used to be required, but it seems silly to have it.
// To stage the transition toward not having it at all, let's make it optional for now. Then,
// in a next big version of Dafny, including the following warning message:
@@ -394,7 +403,7 @@ ArbitraryTypeDecl<ModuleDefinition/*!*/ module, out ArbitraryTypeDecl at>
NoUSIdent<out id>
[ "(" "==" ")" (. eqSupport = TypeParameter.EqualitySupportValue.Required; .)
] (. at = new ArbitraryTypeDecl(id, id.val, module, eqSupport, attrs); .)
- [ SYNC ";"
+ [ SYNC ";"
// This semi-colon used to be required, but it seems silly to have it.
// To stage the transition toward not having it at all, let's make it optional for now. Then,
// in a next big version of Dafny, including the following warning message:
@@ -618,7 +627,7 @@ MethodDecl<MemberModifiers mmod, bool allowConstructor, out Method/*!*/ m>
{ MethodSpec<req, mod, ens, dec, ref decAttrs, ref modAttrs> }
[ BlockStmt<out body, out bodyStart, out bodyEnd>
]
- (.
+ (.
if (Attributes.Contains(attrs, "axiom") && !mmod.IsGhost && !isLemma) {
SemErr(t, "only ghost methods can have the :axiom attribute");
}
@@ -730,8 +739,9 @@ Type<out Type/*!*/ ty>
TypeAndToken<out tok, out ty>
.
TypeAndToken<out IToken/*!*/ tok, out Type/*!*/ ty>
-= (. Contract.Ensures(Contract.ValueAtReturn(out tok)!=null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null); tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
- List<Type/*!*/>/*!*/ gt;
+= (. Contract.Ensures(Contract.ValueAtReturn(out tok)!=null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
+ tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
+ List<Type> gt;
.)
( "bool" (. tok = t; .)
| "nat" (. tok = t; ty = new NatType(); .)
@@ -765,30 +775,38 @@ TypeAndToken<out IToken/*!*/ tok, out Type/*!*/ ty>
ty = new MapType(gt[0], gt[1]);
}
.)
+ | "(" (. tok = t; gt = new List<Type>(); .)
+ [ Type<out ty> (. gt.Add(ty); .)
+ { "," Type<out ty> (. gt.Add(ty); .)
+ }
+ ]
+ ")" (. if (gt.Count == 1) {
+ // just return the type 'ty'
+ } else {
+ // make sure the nullary tuple type exists
+ var dims = gt.Count;
+ var tmp = theBuiltIns.TupleType(tok, dims, true);
+ ty = new UserDefinedType(tok, BuiltIns.TupleTypeName(dims), gt, new List<IToken>());
+ }
+ .)
| ReferenceType<out tok, out ty>
)
.
ReferenceType<out IToken/*!*/ tok, out Type/*!*/ ty>
= (. Contract.Ensures(Contract.ValueAtReturn(out tok) != null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
- List<Type/*!*/>/*!*/ gt;
+ List<Type> gt;
List<IToken> path;
.)
( "object" (. tok = t; ty = new ObjectType(); .)
- | arrayToken (. tok = t; gt = new List<Type/*!*/>(); .)
- GenericInstantiation<gt> (. if (gt.Count != 1) {
- SemErr("array type expects exactly one type argument");
- }
- int dims = 1;
- if (tok.val.Length != 5) {
- dims = int.Parse(tok.val.Substring(5));
- }
- ty = theBuiltIns.ArrayType(tok, dims, gt[0], true);
+ | arrayToken (. tok = t; gt = new List<Type>(); .)
+ [ GenericInstantiation<gt> ] (. int dims = tok.val.Length == 5 ? 1 : int.Parse(tok.val.Substring(5));
+ ty = theBuiltIns.ArrayType(tok, dims, gt, true);
.)
- | Ident<out tok> (. gt = new List<Type/*!*/>();
+ | Ident<out tok> (. gt = new List<Type>();
path = new List<IToken>(); .)
{ (. path.Add(tok); .)
- "." Ident<out tok>
+ "." Ident<out tok>
}
[ GenericInstantiation<gt> ] (. ty = (tok.val == "real") ? (Type)Microsoft.Dafny.Type.Real : new UserDefinedType(tok, tok.val, gt, path); .)
)
@@ -1009,7 +1027,7 @@ OneStmt<out Statement/*!*/ s>
SYNC
";" (. s = label != null ? new BreakStmt(x, t, label) : new BreakStmt(x, t, breakCount); .)
| ReturnStmt<out s>
- | SkeletonStmt<out s>
+ | SkeletonStmt<out s>
)
.
@@ -1023,7 +1041,7 @@ SkeletonStmt<out Statement s>
Ident<out tok> (. names.Add(tok); .)
{"," Ident<out tok> (. names.Add(tok); .)
}
- ":="
+ ":="
Expression<out e, false> (. exprs.Add(e); .)
{"," Expression<out e, false> (. exprs.Add(e); .)
}
@@ -1031,7 +1049,7 @@ SkeletonStmt<out Statement s>
SemErr(whereTok, exprs.Count < names.Count ? "not enough expressions" : "too many expressions");
names = null; exprs = null;
}
- .)
+ .)
]
";"
(. s = new SkeletonStatement(dotdotdot, t, names, exprs); .)
@@ -1111,7 +1129,7 @@ Rhs<out AssignmentRhs r, Expression receiverForInitCall>
[ "[" (. ee = new List<Expression>(); .)
Expressions<ee>
"]" (. // make sure an array class with this dimensionality exists
- UserDefinedType tmp = theBuiltIns.ArrayType(x, ee.Count, new IntType(), true);
+ var tmp = theBuiltIns.ArrayType(ee.Count, new IntType(), true);
.)
| (. x = null; args = new List<Expression/*!*/>(); .)
[ "." Ident<out x> ]
@@ -1332,14 +1350,20 @@ Guard<out Expression e> /* null represents demonic-choice */
MatchStmt<out Statement/*!*/ s>
= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null);
Token x; Expression/*!*/ e; MatchCaseStmt/*!*/ c;
- List<MatchCaseStmt/*!*/> cases = new List<MatchCaseStmt/*!*/>(); .)
+ List<MatchCaseStmt/*!*/> cases = new List<MatchCaseStmt/*!*/>();
+ bool usesOptionalBrace = false;
+ .)
"match" (. x = t; .)
Expression<out e, true>
- "{"
+ [ "{" (. usesOptionalBrace = true; .)
+ ]
{ CaseStatement<out c> (. cases.Add(c); .)
}
- "}"
- (. s = new MatchStmt(x, t, e, cases); .)
+ ( IF(CloseOptionalBrace(usesOptionalBrace))
+ "}"
+ | (. if (usesOptionalBrace) { SemErr(t, "expecting close curly brace"); } .)
+ )
+ (. s = new MatchStmt(x, t, e, cases, usesOptionalBrace); .)
.
CaseStatement<out MatchCaseStmt/*!*/ c>
= (. Contract.Ensures(Contract.ValueAtReturn(out c) != null);
@@ -1417,10 +1441,11 @@ ForallStmt<out Statement/*!*/ s>
var ens = new List<MaybeFreeExpression/*!*/>();
bool isFree;
Expression/*!*/ e;
- BlockStmt/*!*/ block;
+ BlockStmt block = null;
IToken bodyStart, bodyEnd;
+ IToken tok = Token.NoToken;
.)
- ( "forall" (. x = t; .)
+ ( "forall" (. x = t; tok = x; .)
| "parallel" (. x = t;
errors.Warning(t, "the 'parallel' keyword has been deprecated; the comprehension statement now uses the keyword 'forall' (and the parentheses around the bound variables are now optional)");
.)
@@ -1435,16 +1460,27 @@ ForallStmt<out Statement/*!*/ s>
(. if (bvars == null) { bvars = new List<BoundVar>(); }
if (range == null) { range = new LiteralExpr(x, true); }
.)
- ( ")" (. if (!usesOptionalParen) { SemErr(t, "found but didn't expect a close parenthesis"); } .)
+ ( IF(CloseOptionalParen(usesOptionalParen))
+ ")"
| (. if (usesOptionalParen) { SemErr(t, "expecting close parenthesis"); } .)
)
{ (. isFree = false; .)
[ "free" (. isFree = true; .)
]
- "ensures" Expression<out e, false> ";" (. ens.Add(new MaybeFreeExpression(e, isFree)); .)
+ "ensures" Expression<out e, false> (. ens.Add(new MaybeFreeExpression(e, isFree)); .)
+ ";" (. tok = t; .)
}
- BlockStmt<out block, out bodyStart, out bodyEnd>
- (. s = new ForallStmt(x, block.EndTok, bvars, attrs, range, ens, block); .)
+ [ BlockStmt<out block, out bodyStart, out bodyEnd>
+ ]
+ (. if (DafnyOptions.O.DisallowSoundnessCheating && block == null && 0 < ens.Count) {
+ SemErr(t, "a forall statement with an ensures clause must have a body");
+ }
+
+ if (block != null) {
+ tok = block.EndTok;
+ }
+ s = new ForallStmt(x, tok, bvars, attrs, range, ens, block);
+ .)
.
ModifyStmt<out Statement s>
@@ -1478,9 +1514,9 @@ ModifyStmt<out Statement s>
CalcStmt<out Statement/*!*/ s>
= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null);
Token x;
- CalcStmt.CalcOp/*!*/ op, calcOp = Microsoft.Dafny.CalcStmt.DefaultOp, resOp = Microsoft.Dafny.CalcStmt.DefaultOp;
+ CalcStmt.CalcOp/*!*/ op, calcOp = Microsoft.Dafny.CalcStmt.DefaultOp, resOp = Microsoft.Dafny.CalcStmt.DefaultOp;
var lines = new List<Expression/*!*/>();
- var hints = new List<BlockStmt/*!*/>();
+ var hints = new List<BlockStmt/*!*/>();
CalcStmt.CalcOp stepOp;
var stepOps = new List<CalcStmt.CalcOp>();
CalcStmt.CalcOp maybeOp;
@@ -1494,7 +1530,7 @@ CalcStmt<out Statement/*!*/ s>
if (maybeOp == null) {
SemErr(opTok, "the main operator of a calculation must be transitive");
}
- resOp = calcOp;
+ resOp = calcOp;
.)
]
"{"
@@ -1522,8 +1558,8 @@ CalcStmt<out Statement/*!*/ s>
if (lines.Count > 0) {
// Repeat the last line to create a dummy line for the dangling hint
lines.Add(lines[lines.Count - 1]);
- }
- s = new CalcStmt(x, t, calcOp, lines, hints, stepOps, resOp);
+ }
+ s = new CalcStmt(x, t, calcOp, lines, hints, stepOps, resOp);
.)
.
CalcOp<out IToken x, out CalcStmt.CalcOp/*!*/ op>
@@ -1543,9 +1579,9 @@ CalcOp<out IToken x, out CalcStmt.CalcOp/*!*/ op>
| '\u2265' (. x = t; binOp = BinaryExpr.Opcode.Ge; .)
| EquivOp (. x = t; binOp = BinaryExpr.Opcode.Iff; .)
| ImpliesOp (. x = t; binOp = BinaryExpr.Opcode.Imp; .)
- | ExpliesOp (. x = t; binOp = BinaryExpr.Opcode.Exp; .)
+ | ExpliesOp (. x = t; binOp = BinaryExpr.Opcode.Exp; .)
)
- (.
+ (.
if (k == null) {
op = new Microsoft.Dafny.CalcStmt.BinaryCalcOp(binOp);
} else {
@@ -1555,7 +1591,7 @@ CalcOp<out IToken x, out CalcStmt.CalcOp/*!*/ op>
.
Hint<out BlockStmt s>
= (. Contract.Ensures(Contract.ValueAtReturn(out s) != null); // returns an empty block statement if the hint is empty
- var subhints = new List<Statement/*!*/>();
+ var subhints = new List<Statement/*!*/>();
IToken bodyStart, bodyEnd;
BlockStmt/*!*/ block;
Statement/*!*/ calc;
@@ -1565,7 +1601,7 @@ Hint<out BlockStmt s>
{ BlockStmt<out block, out bodyStart, out bodyEnd> (. endTok = block.EndTok; subhints.Add(block); .)
| CalcStmt<out calc> (. endTok = calc.EndTok; subhints.Add(calc); .)
}
- (. s = new BlockStmt(x, endTok, subhints); // if the hint is empty x is the first token of the next line, but it doesn't matter cause the block statement is just used as a container
+ (. s = new BlockStmt(x, endTok, subhints); // if the hint is empty x is the first token of the next line, but it doesn't matter cause the block statement is just used as a container
.)
.
/*------------------------------------------------------------------------*/
@@ -1745,7 +1781,7 @@ RelOp<out IToken/*!*/ x, out BinaryExpr.Opcode op, out Expression k>
[ "#" "[" Expression<out k, true> "]" ]
| "in" (. x = t; op = BinaryExpr.Opcode.In; .)
| notIn (. x = t; op = BinaryExpr.Opcode.NotIn; .)
- | /* The next operator is "!!", but we have to scan it as two "!", since the scanner is gready
+ | /* The next operator is "!!", but we have to scan it as two "!", since the scanner is gready
so if "!!" is a valid token, we won't be able to scan it as two "!" when needed: */
"!" (. x = t; y = Token.NoToken; .)
[ "!" (. y = t; .)
@@ -1849,25 +1885,51 @@ ConstAtomExpression<out Expression e>
| "|" (. x = t; .)
Expression<out e, true> (. e = new UnaryExpr(x, UnaryExpr.Opcode.SeqLength, e); .)
"|"
- | "(" (. x = t; .)
- Expression<out e, true> (. e = new ParensExpression(x, e); .)
- ")"
- | "real" (. x = t; .)
- "(" (. IToken openParen = t; .)
- Expression<out e, true>
- ")" (. IToken classTok = new Token(t.line, t.col); classTok.val = "Real";
- IToken fnTok = new Token(t.line, t.col); fnTok.val = "IntToReal";
- //e = new IdentifierSequence(new List<IToken>() { classTok, fnTok }, openParen, new List<Expression/*!*/>() { e });
- e = new FunctionCallExpr(x, "IntToReal", new StaticReceiverExpr(x, theBuiltIns.RealClass), openParen, new List<Expression/*!*/>() { e });
- .)
- | "int" (. x = t; .)
- "(" (. IToken openParen = t; .)
- Expression<out e, true>
- ")" (. IToken classTok = new Token(t.line, t.col); classTok.val = "Real";
- IToken fnTok = new Token(t.line, t.col); fnTok.val = "RealToInt";
- //e = new IdentifierSequence(new List<IToken>() { classTok, fnTok }, openParen, new List<Expression/*!*/>() { e });
- e = new FunctionCallExpr(x, "RealToInt", new StaticReceiverExpr(x, theBuiltIns.RealClass), openParen, new List<Expression/*!*/>() { e });
- .)
+ | ParensExpression<out e>
+ | "real" (. x = t; .)
+ "(" (. IToken openParen = t; .)
+ Expression<out e, true>
+ ")" (. IToken classTok = new Token(t.line, t.col); classTok.val = "Real";
+ IToken fnTok = new Token(t.line, t.col); fnTok.val = "IntToReal";
+ //e = new IdentifierSequence(new List<IToken>() { classTok, fnTok }, openParen, new List<Expression/*!*/>() { e });
+ e = new FunctionCallExpr(x, "IntToReal", new StaticReceiverExpr(x, theBuiltIns.RealClass), openParen, new List<Expression/*!*/>() { e });
+ .)
+ | "int" (. x = t; .)
+ "(" (. IToken openParen = t; .)
+ Expression<out e, true>
+ ")" (. IToken classTok = new Token(t.line, t.col); classTok.val = "Real";
+ IToken fnTok = new Token(t.line, t.col); fnTok.val = "RealToInt";
+ //e = new IdentifierSequence(new List<IToken>() { classTok, fnTok }, openParen, new List<Expression/*!*/>() { e });
+ e = new FunctionCallExpr(x, "RealToInt", new StaticReceiverExpr(x, theBuiltIns.RealClass), openParen, new List<Expression/*!*/>() { e });
+ .)
+ )
+ .
+ParensExpression<out Expression e>
+= (. IToken x;
+ List<Expression> args = null;
+ .)
+ "(" (. x = t; e = null; .)
+ ( ")" (. // unit
+ // make sure the nullary tuple type exists
+ var tmp = theBuiltIns.TupleType(x, 0, true);
+ e = new DatatypeValue(x, BuiltIns.TupleTypeName(0), BuiltIns.TupleTypeCtorName, new List<Expression>());
+ .)
+ | Expression<out e, true>
+ { "," (. if (args == null) {
+ args = new List<Expression>();
+ args.Add(e); // add the first argument, which was parsed above
+ }
+ .)
+ Expression<out e, true> (. args.Add(e); .)
+ }
+ ")" (. if (args == null) {
+ e = new ParensExpression(x, e);
+ } else {
+ // make sure the corresponding tuple type exists
+ var tmp = theBuiltIns.TupleType(x, args.Count, true);
+ e = new DatatypeValue(x, BuiltIns.TupleTypeName(args.Count), BuiltIns.TupleTypeCtorName, args);
+ }
+ .)
)
.
DisplayExpr<out Expression e>
@@ -2006,15 +2068,22 @@ NamedExpr<out Expression e, bool allowSemi>
MatchExpression<out Expression e, bool allowSemi>
= (. Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; MatchCaseExpr/*!*/ c;
List<MatchCaseExpr/*!*/> cases = new List<MatchCaseExpr/*!*/>();
+ bool usesOptionalBrace = false;
.)
"match" (. x = t; .)
Expression<out e, allowSemi>
+ [ "{" (. usesOptionalBrace = true; .)
+ ]
/* Note: The following gives rise to a '"case" is start & successor of deletable structure' error,
but it's okay, because we want this closer match expression to bind as much as possible--use
parens around it to limit its scope. */
{ CaseExpression<out c, allowSemi> (. cases.Add(c); .)
}
- (. e = new MatchExpr(x, e, cases); .)
+ ( IF(CloseOptionalBrace(usesOptionalBrace))
+ "}"
+ | (. if (usesOptionalBrace) { SemErr(t, "expecting close curly brace"); } .)
+ )
+ (. e = new MatchExpr(x, e, cases, usesOptionalBrace); .)
.
CaseExpression<out MatchCaseExpr c, bool allowSemi>
= (. Contract.Ensures(Contract.ValueAtReturn(out c) != null); IToken/*!*/ x, id;
@@ -2051,10 +2120,10 @@ CasePattern<out CasePattern pat>
// later if resolution finds the CasePattern to denote a parameter-less constructor), because this
// (in particular, bv.IsGhost) is the place where a LetExpr records whether or not the "ghost"
// keyword was used in the declaration.
- pat = new CasePattern(bv.tok, bv);
+ pat = new CasePattern(bv.tok, bv);
.)
)
-
+
.
/*------------------------------------------------------------------------*/
DottedIdentifiersAndFunction<out Expression e>
@@ -2108,9 +2177,9 @@ Suffix<ref Expression e>
multipleLengths = new List<Expression>();
multipleLengths.Add(e0);
}
- takeRest = true;
+ takeRest = true;
.)
- [Expression<out ee, true> (. multipleLengths.Add(ee);
+ [Expression<out ee, true> (. multipleLengths.Add(ee);
takeRest = false;
.)
]
@@ -2130,7 +2199,7 @@ Suffix<ref Expression e>
(. 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);
+ var tmp = theBuiltIns.ArrayType(multipleIndices.Count, new IntType(), true);
} else {
if (!anyDots && e0 == null) {
/* a parsing error occurred */
@@ -2310,7 +2379,7 @@ IdentOrDigitsSuffix<out IToken x, out IToken y>
// Identifier, disallowing leading underscores
NoUSIdent<out IToken/*!*/ x>
= (. Contract.Ensures(Contract.ValueAtReturn(out x) != null); .)
- ident (. x = t;
+ ident (. x = t;
if (x.val.StartsWith("_")) {
SemErr("cannot declare identifier beginning with underscore");
}
@@ -2320,7 +2389,7 @@ NoUSIdent<out IToken/*!*/ x>
// Identifier, disallowing leading underscores, except possibly the "wildcard" identifier "_"
WildIdent<out IToken/*!*/ x, bool allowWildcardId>
= (. Contract.Ensures(Contract.ValueAtReturn(out x) != null); .)
- ident (. x = t;
+ ident (. x = t;
if (x.val.StartsWith("_")) {
if (allowWildcardId && x.val.Length == 1) {
t.val = "_v" + anonymousIds++;
@@ -2341,7 +2410,7 @@ Nat<out BigInteger n>
n = BigInteger.Zero;
}
.)
- |hexdigits
+ |hexdigits
(. try {
// note: leading 0 required when parsing positive hex numbers
n = BigInteger.Parse("0" + t.val.Substring(2), System.Globalization.NumberStyles.HexNumber);
@@ -2361,7 +2430,7 @@ Dec<out Basetypes.BigDec d>
SemErr("incorrectly formatted number");
d = Basetypes.BigDec.ZERO;
}
- .)
+ .)
)
.
END Dafny.
diff --git a/Source/Dafny/DafnyAst.cs b/Source/Dafny/DafnyAst.cs
index 754ae8bc..67806193 100644
--- a/Source/Dafny/DafnyAst.cs
+++ b/Source/Dafny/DafnyAst.cs
@@ -88,16 +88,18 @@ namespace Microsoft.Dafny {
{
public readonly ModuleDefinition SystemModule = new ModuleDefinition(Token.NoToken, "_System", false, false, null, null, null, true);
Dictionary<int, ClassDecl> arrayTypeDecls = new Dictionary<int, ClassDecl>();
+ Dictionary<int, TupleTypeDecl> tupleTypeDecls = new Dictionary<int, TupleTypeDecl>();
public readonly ClassDecl ObjectDecl;
public readonly ClassDecl RealClass;
//public readonly Function RealToInt;
//public readonly Function IntToReal;
public BuiltIns() {
// create class 'object'
- ObjectDecl = new ClassDecl(Token.NoToken, "object", SystemModule, new List<TypeParameter>(), new List<MemberDecl>(), null);
+ ObjectDecl = new ClassDecl(Token.NoToken, "object", SystemModule, new List<TypeParameter>(), new List<MemberDecl>(), DontCompile());
SystemModule.TopLevelDecls.Add(ObjectDecl);
// add one-dimensional arrays, since they may arise during type checking
- UserDefinedType tmp = ArrayType(Token.NoToken, 1, Type.Int, true);
+ // Arrays of other dimensions may be added during parsing as the parser detects the need for these
+ UserDefinedType tmp = ArrayType(1, Type.Int, true);
// add real number functions
Function RealToInt = new Function(Token.NoToken, "RealToInt", true, true, new List<TypeParameter>(), Token.NoToken,
new List<Formal> { new Formal(Token.NoToken, "x", Type.Real, true, true) }, Type.Int, new List<Expression>(),
@@ -108,28 +110,35 @@ namespace Microsoft.Dafny {
new List<FrameExpression>(), new List<Expression>(), new Specification<Expression>(new List<Expression>(), null),
null, null, Token.NoToken);
RealClass = new ClassDecl(Token.NoToken, "Real", SystemModule, new List<TypeParameter>(),
- new List<MemberDecl>() { RealToInt, IntToReal }, null);
+ new List<MemberDecl>() { RealToInt, IntToReal }, DontCompile());
RealToInt.EnclosingClass = RealClass;
IntToReal.EnclosingClass = RealClass;
RealToInt.IsBuiltin = true;
IntToReal.IsBuiltin = true;
SystemModule.TopLevelDecls.Add(RealClass);
+ // Note, in addition to these types, the _System module contains tuple types. These tuple types are added to SystemModule
+ // by the parser as the parser detects the need for these.
}
- public UserDefinedType ArrayType(int dims, Type arg) {
- return ArrayType(Token.NoToken, dims, arg, false);
+ private Attributes DontCompile() {
+ var flse = new Attributes.Argument(Token.NoToken, Expression.CreateBoolLiteral(Token.NoToken, false));
+ return new Attributes("compile", new List<Attributes.Argument>() { flse }, null);
}
- public UserDefinedType ArrayType(IToken tok, int dims, Type arg, bool allowCreationOfNewClass) {
- Contract.Requires(tok != null);
+
+ public UserDefinedType ArrayType(int dims, Type arg, bool allowCreationOfNewClass = false) {
Contract.Requires(1 <= dims);
Contract.Requires(arg != null);
+ return ArrayType(Token.NoToken, dims, new List<Type>() { arg }, allowCreationOfNewClass);
+ }
+ public UserDefinedType ArrayType(IToken tok, int dims, List<Type> typeArgs, bool allowCreationOfNewClass) {
+ Contract.Requires(tok != null);
+ Contract.Requires(1 <= dims);
+ Contract.Requires(typeArgs != null);
Contract.Ensures(Contract.Result<UserDefinedType>() != null);
- List<Type> typeArgs = new List<Type>();
- typeArgs.Add(arg);
UserDefinedType udt = new UserDefinedType(tok, ArrayClassName(dims), typeArgs, null);
if (allowCreationOfNewClass && !arrayTypeDecls.ContainsKey(dims)) {
- ArrayClassDecl arrayClass = new ArrayClassDecl(dims, SystemModule);
+ ArrayClassDecl arrayClass = new ArrayClassDecl(dims, SystemModule, DontCompile());
for (int d = 0; d < dims; d++) {
string name = dims == 1 ? "Length" : "Length" + d;
string compiledName = dims == 1 ? "Length" : "GetLength(" + d + ")";
@@ -152,6 +161,30 @@ namespace Microsoft.Dafny {
return "array" + dims;
}
}
+
+ public TupleTypeDecl TupleType(IToken tok, int dims, bool allowCreationOfNewType) {
+ Contract.Requires(tok != null);
+ Contract.Requires(0 <= dims);
+ Contract.Ensures(Contract.Result<TupleTypeDecl>() != null);
+
+ TupleTypeDecl tt;
+ if (!tupleTypeDecls.TryGetValue(dims, out tt)) {
+ Contract.Assume(allowCreationOfNewType); // the parser should ensure that all needed tuple types exist by the time of resolution
+ tt = new TupleTypeDecl(dims, SystemModule);
+ tupleTypeDecls.Add(dims, tt);
+ SystemModule.TopLevelDecls.Add(tt);
+ }
+ return tt;
+ }
+ public static string TupleTypeName(int dims) {
+ Contract.Requires(0 <= dims);
+ return "_tuple#" + dims;
+ }
+ public static bool IsTupleTypeName(string s) {
+ Contract.Requires(s != null);
+ return s.StartsWith("_tuple#");
+ }
+ public const string TupleTypeCtorName = "_#Make"; // the printer wants this name to be uniquely recognizable
}
public class Attributes {
@@ -553,9 +586,9 @@ namespace Microsoft.Dafny {
}
public class MapType : CollectionType
{
- public Type Range {
- get { return range; }
- set {
+ public Type Range {
+ get { return range; }
+ set {
range = Range;
TypeArgs = new List<Type> { Arg, range };
}
@@ -573,7 +606,7 @@ namespace Microsoft.Dafny {
}
public Type Domain {
get { return Arg; }
- set {
+ set {
TypeArgs = new List<Type> { Domain, range };
}
}
@@ -679,7 +712,7 @@ namespace Microsoft.Dafny {
else
this.Path = new List<IToken>();
}
-
+
/// <summary>
/// This constructor constructs a resolved type parameter
/// </summary>
@@ -694,7 +727,7 @@ namespace Microsoft.Dafny {
this.Path = new List<IToken>();
}
- public UserDefinedType(TypeParameter tp)
+ public UserDefinedType(TypeParameter tp)
: this(tp.tok, tp.Name, tp)
{
Contract.Requires(tp != null);
@@ -736,8 +769,11 @@ namespace Microsoft.Dafny {
[Pure]
public override string TypeName(ModuleDefinition context) {
Contract.Ensures(Contract.Result<string>() != null);
- if (ResolvedParam != null) {
+ /* if (ResolvedParam != null) {
return ResolvedParam.FullName();
+ } else */
+ if (BuiltIns.IsTupleTypeName(Name)) {
+ return "(" + Util.Comma(",", TypeArgs, ty => ty.TypeName(context)) + ")";
} else {
string s = "";
foreach (var t in Path) {
@@ -923,7 +959,7 @@ namespace Microsoft.Dafny {
/// Domain and Range refer to the types of the indexing operation. That is, in A[i],
/// i is of type Domain and A[i] is of type Range.
/// Arg is either Domain or Range, depending on what type it is. Arg is the type
- /// one would use in an expression "x in C", whereas
+ /// one would use in an expression "x in C", whereas
/// This proxy stands for one of:
/// seq(T) Domain,Range,Arg := int,T,T
/// multiset(T) Domain,Range,Arg := T,int,T
@@ -1050,7 +1086,7 @@ namespace Microsoft.Dafny {
EqualitySupport = equalitySupport;
}
- public TypeParameter(IToken tok, string name, int positionalIndex, ParentType parent)
+ public TypeParameter(IToken tok, string name, int positionalIndex, ParentType parent)
: this(tok, name)
{
PositionalIndex = positionalIndex;
@@ -1107,7 +1143,7 @@ namespace Microsoft.Dafny {
public ModuleDecl CompileRoot;
public readonly List<IToken> CompilePath;
public ModuleSignature OriginalSignature;
-
+
public ModuleFacadeDecl(List<IToken> path, IToken name, ModuleDefinition parent, List<IToken> compilePath, bool opened)
: base(name, name.val, parent, opened) {
Path = path;
@@ -1117,7 +1153,7 @@ namespace Microsoft.Dafny {
}
public class ModuleSignature {
-
+
public readonly Dictionary<string, TopLevelDecl> TopLevels = new Dictionary<string, TopLevelDecl>();
public readonly Dictionary<string, Tuple<DatatypeCtor, bool>> Ctors = new Dictionary<string, Tuple<DatatypeCtor, bool>>();
public readonly Dictionary<string, MemberDecl> StaticMembers = new Dictionary<string, MemberDecl>();
@@ -1138,15 +1174,15 @@ namespace Microsoft.Dafny {
} else return false;
} else return false;
}
-
-
+
+
}
public class ModuleDefinition : TopLevelDecl {
public readonly List<IToken> RefinementBaseName; // null if no refinement base
public ModuleDecl RefinementBaseRoot; // filled in early during resolution, corresponds to RefinementBaseName[0]
public ModuleDefinition RefinementBase; // filled in during resolution (null if no refinement base)
public List<Include> Includes;
-
+
public readonly List<TopLevelDecl> TopLevelDecls = new List<TopLevelDecl>(); // filled in by the parser; readonly after that
public readonly Graph<ICallable> CallGraph = new Graph<ICallable>(); // filled in during resolution
public int Height; // height in the topological sorting of modules; filled in during resolution
@@ -1396,10 +1432,10 @@ namespace Microsoft.Dafny {
public class ArrayClassDecl : ClassDecl {
public readonly int Dims;
- public ArrayClassDecl(int dims, ModuleDefinition module)
+ public ArrayClassDecl(int dims, ModuleDefinition module, Attributes attrs)
: base(Token.NoToken, BuiltIns.ArrayClassName(dims), module,
new List<TypeParameter>(new TypeParameter[]{new TypeParameter(Token.NoToken, "arg")}),
- new List<MemberDecl>(), null)
+ new List<MemberDecl>(), attrs)
{
Contract.Requires(1 <= dims);
Contract.Requires(module != null);
@@ -1408,7 +1444,8 @@ namespace Microsoft.Dafny {
}
}
- public abstract class DatatypeDecl : TopLevelDecl {
+ public abstract class DatatypeDecl : TopLevelDecl
+ {
public readonly List<DatatypeCtor> Ctors;
[ContractInvariantMethod]
void ObjectInvariant() {
@@ -1454,6 +1491,52 @@ namespace Microsoft.Dafny {
}
}
+ public class TupleTypeDecl : IndDatatypeDecl
+ {
+ public readonly int Dims;
+ /// <summary>
+ /// Construct a resolved built-in tuple type with "dim" arguments. "systemModule" is expected to be the _System module.
+ /// </summary>
+ public TupleTypeDecl(int dims, ModuleDefinition systemModule)
+ : this(systemModule, CreateTypeParameters(dims)) {
+ Contract.Requires(0 <= dims);
+ Contract.Requires(systemModule != null);
+ }
+ private TupleTypeDecl(ModuleDefinition systemModule, List<TypeParameter> typeArgs)
+ : base(Token.NoToken, BuiltIns.TupleTypeName(typeArgs.Count), systemModule, typeArgs, CreateConstructors(typeArgs), null) {
+ Contract.Requires(systemModule != null);
+ Contract.Requires(typeArgs != null);
+ Dims = typeArgs.Count;
+ foreach (var ctor in Ctors) {
+ ctor.EnclosingDatatype = this; // resolve here
+ DefaultCtor = ctor;
+ TypeParametersUsedInConstructionByDefaultCtor = new bool[typeArgs.Count];
+ for (int i = 0; i < typeArgs.Count; i++) {
+ TypeParametersUsedInConstructionByDefaultCtor[i] = true;
+ }
+ }
+ }
+ private static List<TypeParameter> CreateTypeParameters(int dims) {
+ Contract.Requires(0 <= dims);
+ var ts = new List<TypeParameter>();
+ for (int i = 0; i < dims; i++) {
+ ts.Add(new TypeParameter(Token.NoToken, "T" + i));
+ }
+ return ts;
+ }
+ private static List<DatatypeCtor> CreateConstructors(List<TypeParameter> typeArgs) {
+ Contract.Requires(typeArgs != null);
+ var formals = new List<Formal>();
+ for (int i = 0; i < typeArgs.Count; i++) {
+ var tp = typeArgs[i];
+ var f = new Formal(Token.NoToken, i.ToString(), new UserDefinedType(Token.NoToken, tp.Name, tp), true, false);
+ formals.Add(f);
+ }
+ var ctor = new DatatypeCtor(Token.NoToken, BuiltIns.TupleTypeCtorName, formals, null);
+ return new List<DatatypeCtor>() { ctor };
+ }
+ }
+
public class CoDatatypeDecl : DatatypeDecl
{
public CoDatatypeDecl SscRepr; // filled in during resolution
@@ -1496,7 +1579,7 @@ namespace Microsoft.Dafny {
}
public string FullName {
- get {
+ get {
Contract.Ensures(Contract.Result<string>() != null);
Contract.Assume(EnclosingDatatype != null);
@@ -1561,9 +1644,9 @@ namespace Microsoft.Dafny {
public class NoContext : ICodeContext
{
public readonly ModuleDefinition Module;
- public NoContext(ModuleDefinition module)
+ public NoContext(ModuleDefinition module)
{
- this.Module = module;
+ this.Module = module;
}
bool ICodeContext.IsGhost { get { return true; } }
bool ICodeContext.IsStatic { get { Contract.Assume(false, "should not be called on NoContext"); throw new cce.UnreachableException(); } }
@@ -1959,7 +2042,7 @@ namespace Microsoft.Dafny {
}
return UniqueName;
}
- static char[] specialChars = new char[] { '\'', '_', '?', '\\' };
+ static char[] specialChars = new char[] { '\'', '_', '?', '\\', '#' };
public static string CompilerizeName(string nm) {
if ('0' <= nm[0] && nm[0] <= '9') {
// the identifier is one that consists of just digits
@@ -1983,6 +2066,7 @@ namespace Microsoft.Dafny {
case '_': name += "__"; break;
case '?': name += "_q"; break;
case '\\': name += "_b"; break;
+ case '#': name += "_h"; break;
default:
Contract.Assume(false); // unexpected character
break;
@@ -3240,7 +3324,7 @@ namespace Microsoft.Dafny {
Contract.Invariant(MethodName != null);
Contract.Invariant(cce.NonNullElements(Lhs));
Contract.Invariant(cce.NonNullElements(Args));
- Contract.Invariant(TypeArgumentSubstitutions == null ||
+ Contract.Invariant(TypeArgumentSubstitutions == null ||
Contract.ForAll(Method.TypeArgs, tp => TypeArgumentSubstitutions.ContainsKey(tp)));
}
@@ -3248,8 +3332,8 @@ namespace Microsoft.Dafny {
public Expression Receiver; // non-null after resolution
public readonly string MethodName;
public readonly List<Expression> Args;
- public Dictionary<TypeParameter, Type> TypeArgumentSubstitutions;
- // create, initialized, and used by resolution
+ public Dictionary<TypeParameter, Type> TypeArgumentSubstitutions;
+ // create, initialized, and used by resolution
// (could be deleted once all of resolution is done)
// That's not going to work! It should never be deleted!
public Method Method; // filled in by resolution
@@ -3560,7 +3644,6 @@ namespace Microsoft.Dafny {
Contract.Invariant(Range != null);
Contract.Invariant(BoundVars.Count != 0 || LiteralExpr.IsTrue(Range));
Contract.Invariant(Ens != null);
- Contract.Invariant(Body != null);
}
public ForallStmt(IToken tok, IToken endTok, List<BoundVar> boundVars, Attributes attrs, Expression range, List<MaybeFreeExpression> ens, Statement body)
@@ -3571,7 +3654,6 @@ namespace Microsoft.Dafny {
Contract.Requires(range != null);
Contract.Requires(boundVars.Count != 0 || LiteralExpr.IsTrue(range));
Contract.Requires(cce.NonNullElements(ens));
- Contract.Requires(body != null);
this.BoundVars = boundVars;
this.Attributes = attrs;
this.Range = range;
@@ -3605,7 +3687,9 @@ namespace Microsoft.Dafny {
public override IEnumerable<Statement> SubStatements {
get {
- yield return Body;
+ if (Body != null) {
+ yield return Body;
+ }
}
}
public override IEnumerable<Expression> SubExpressions {
@@ -3686,8 +3770,8 @@ namespace Microsoft.Dafny {
public static bool ValidOp(BinaryExpr.Opcode op) {
return
op == BinaryExpr.Opcode.Eq || op == BinaryExpr.Opcode.Neq
- || op == BinaryExpr.Opcode.Lt || op == BinaryExpr.Opcode.Le
- || op == BinaryExpr.Opcode.Gt || op == BinaryExpr.Opcode.Ge
+ || op == BinaryExpr.Opcode.Lt || op == BinaryExpr.Opcode.Le
+ || op == BinaryExpr.Opcode.Gt || op == BinaryExpr.Opcode.Ge
|| LogicOp(op);
}
@@ -3713,7 +3797,7 @@ namespace Microsoft.Dafny {
var op2 = other.Op;
if (op1 == BinaryExpr.Opcode.Neq || op2 == BinaryExpr.Opcode.Neq)
return op2 == BinaryExpr.Opcode.Eq;
- if (op1 == op2)
+ if (op1 == op2)
return true;
if (LogicOp(op1) || LogicOp(op2))
return op2 == BinaryExpr.Opcode.Eq ||
@@ -3805,7 +3889,7 @@ namespace Microsoft.Dafny {
public readonly List<Expression> Steps; // expressions li op l<i + 1>, filled in during resolution (last step is dummy)
public Expression Result; // expression l0 ResultOp ln, filled in during resolution
- public static readonly CalcOp DefaultOp = new BinaryCalcOp(BinaryExpr.Opcode.Eq);
+ public static readonly CalcOp DefaultOp = new BinaryCalcOp(BinaryExpr.Opcode.Eq);
[ContractInvariantMethod]
void ObjectInvariant()
@@ -3847,7 +3931,7 @@ namespace Microsoft.Dafny {
} else {
this.ResultOp = resultOp;
}
- this.Steps = new List<Expression>();
+ this.Steps = new List<Expression>();
this.Result = null;
}
@@ -3916,8 +4000,9 @@ namespace Microsoft.Dafny {
public readonly Expression Source;
public readonly List<MatchCaseStmt> Cases;
public readonly List<DatatypeCtor> MissingCases = new List<DatatypeCtor>(); // filled in during resolution
+ public readonly bool UsesOptionalBraces;
- public MatchStmt(IToken tok, IToken endTok, Expression source, [Captured] List<MatchCaseStmt> cases)
+ public MatchStmt(IToken tok, IToken endTok, Expression source, [Captured] List<MatchCaseStmt> cases, bool usesOptionalBraces)
: base(tok, endTok) {
Contract.Requires(tok != null);
Contract.Requires(endTok != null);
@@ -3925,6 +4010,7 @@ namespace Microsoft.Dafny {
Contract.Requires(cce.NonNullElements(cases));
this.Source = source;
this.Cases = cases;
+ this.UsesOptionalBraces = usesOptionalBraces;
}
public override IEnumerable<Statement> SubStatements {
@@ -4014,7 +4100,7 @@ namespace Microsoft.Dafny {
Contract.Requires(endTok != null);
NameReplacements = nameReplacements;
ExprReplacements = exprReplacements;
-
+
}
public override IEnumerable<Statement> SubStatements {
get {
@@ -4185,6 +4271,20 @@ namespace Microsoft.Dafny {
}
/// <summary>
+ /// Create a resolved expression of the form "e0 + e1"
+ /// </summary>
+ public static Expression CreateAdd(Expression e0, Expression e1) {
+ Contract.Requires(e0 != null);
+ Contract.Requires(e1 != null);
+ Contract.Requires((e0.Type is IntType && e1.Type is IntType) || (e0.Type is RealType && e1.Type is RealType));
+ Contract.Ensures(Contract.Result<Expression>() != null);
+ var s = new BinaryExpr(e0.tok, BinaryExpr.Opcode.Add, e0, e1);
+ s.ResolvedOp = BinaryExpr.ResolvedOpcode.Add; // resolve here
+ s.Type = e0.Type; // resolve here
+ return s;
+ }
+
+ /// <summary>
/// Create a resolved expression of the form "e0 - e1"
/// </summary>
public static Expression CreateSubtract(Expression e0, Expression e1) {
@@ -4209,12 +4309,8 @@ namespace Microsoft.Dafny {
if (n == 0) {
return e;
}
- var nn = new LiteralExpr(e.tok, n);
- nn.Type = Type.Int;
- var p = new BinaryExpr(e.tok, BinaryExpr.Opcode.Add, e, nn);
- p.ResolvedOp = BinaryExpr.ResolvedOpcode.Add;
- p.Type = Type.Int;
- return p;
+ var nn = CreateIntLiteral(e.tok, n);
+ return CreateAdd(e, nn);
}
/// <summary>
@@ -4228,11 +4324,8 @@ namespace Microsoft.Dafny {
if (n == 0) {
return e;
}
- var nn = Expression.CreateIntLiteral(e.tok, n);
- var p = new BinaryExpr(e.tok, BinaryExpr.Opcode.Sub, e, nn);
- p.ResolvedOp = BinaryExpr.ResolvedOpcode.Sub;
- p.Type = Type.Int;
- return p;
+ var nn = CreateIntLiteral(e.tok, n);
+ return CreateSubtract(e, nn);
}
/// <summary>
@@ -4252,7 +4345,7 @@ namespace Microsoft.Dafny {
/// <summary>
/// Create a resolved expression for a bool b
- /// </summary>
+ /// </summary>
public static Expression CreateBoolLiteral(IToken tok, bool b) {
Contract.Requires(tok != null);
var lit = new LiteralExpr(tok, b);
@@ -4296,6 +4389,26 @@ namespace Microsoft.Dafny {
return s;
}
+ public static Expression CreateEq(Expression e0, Expression e1, Type ty) {
+ Contract.Requires(e0 != null);
+ Contract.Requires(e1 != null);
+ Contract.Requires(ty != null);
+ var eq = new BinaryExpr(e0.tok, BinaryExpr.Opcode.Eq, e0, e1);
+ if (ty is SetType) {
+ eq.ResolvedOp = BinaryExpr.ResolvedOpcode.SetEq;
+ } else if (ty is SeqType) {
+ eq.ResolvedOp = BinaryExpr.ResolvedOpcode.SeqEq;
+ } else if (ty is MultiSetType) {
+ eq.ResolvedOp = BinaryExpr.ResolvedOpcode.InMultiSet;
+ } else if (ty is MapType) {
+ eq.ResolvedOp = BinaryExpr.ResolvedOpcode.MapEq;
+ } else {
+ eq.ResolvedOp = BinaryExpr.ResolvedOpcode.EqCommon;
+ }
+ eq.type = Type.Bool;
+ return eq;
+ }
+
/// <summary>
/// Create a resolved expression of the form "e0 && e1"
/// </summary>
@@ -4357,7 +4470,7 @@ namespace Microsoft.Dafny {
Contract.Ensures(Contract.Result<MatchCaseExpr>() != null);
ResolvedCloner cloner = new ResolvedCloner();
- var newVars = old_case.Arguments.ConvertAll(cloner.CloneBoundVar);
+ var newVars = old_case.Arguments.ConvertAll(cloner.CloneBoundVar);
new_body = VarSubstituter(old_case.Arguments.ConvertAll<NonglobalVariable>(x=>(NonglobalVariable)x), newVars, new_body);
var new_case = new MatchCaseExpr(old_case.tok, old_case.Id, newVars, new_body);
@@ -4367,15 +4480,15 @@ namespace Microsoft.Dafny {
}
/// <summary>
- /// Create a match expression with a resolved type
+ /// Create a match expression with a resolved type
/// </summary>
public static Expression CreateMatch(IToken tok, Expression src, List<MatchCaseExpr> cases, Type type) {
- MatchExpr e = new MatchExpr(tok, src, cases);
+ MatchExpr e = new MatchExpr(tok, src, cases, false);
e.Type = type; // resolve here
return e;
}
-
+
/// <summary>
/// Create a let expression with a resolved type and fresh variables
/// </summary>
@@ -4415,22 +4528,33 @@ namespace Microsoft.Dafny {
}
body = VarSubstituter(expr.BoundVars.ConvertAll<NonglobalVariable>(x=>(NonglobalVariable)x), newVars, body);
-
+
QuantifierExpr q;
if (forall) {
q = new ForallExpr(expr.tok, new List<TypeParameter>(), newVars, expr.Range, body, expr.Attributes);
} else {
q = new ExistsExpr(expr.tok, new List<TypeParameter>(), newVars, expr.Range, body, expr.Attributes);
- }
+ }
q.Type = Type.Bool;
- return q;
+ return q;
+ }
+
+ /// <summary>
+ /// Create a resolved IdentifierExpr (whose token is that of the variable)
+ /// </summary>
+ public static Expression CreateIdentExpr(IVariable v) {
+ Contract.Requires(v != null);
+ var e = new IdentifierExpr(v.Tok, v.Name);
+ e.Var = v; // resolve here
+ e.type = v.Type; // resolve here
+ return e;
}
public static Expression VarSubstituter(List<NonglobalVariable> oldVars, List<BoundVar> newVars, Expression e) {
Contract.Requires(oldVars != null && newVars != null);
Contract.Requires(oldVars.Count == newVars.Count);
-
+
Dictionary<IVariable, Expression/*!*/> substMap = new Dictionary<IVariable, Expression>();
Dictionary<TypeParameter, Type> typeMap = new Dictionary<TypeParameter, Type>();
@@ -4455,7 +4579,7 @@ namespace Microsoft.Dafny {
{
public readonly Type UnresolvedType;
- public StaticReceiverExpr(IToken tok, Type t)
+ public StaticReceiverExpr(IToken tok, Type t)
: base(tok) {
Contract.Requires(tok != null);
Contract.Requires(t != null);
@@ -4525,7 +4649,7 @@ namespace Microsoft.Dafny {
this.Value = b;
}
}
-
+
public class DatatypeValue : Expression {
public readonly string DatatypeName;
public readonly string MemberName;
@@ -4540,7 +4664,7 @@ namespace Microsoft.Dafny {
Contract.Invariant(cce.NonNullElements(Arguments));
Contract.Invariant(cce.NonNullElements(InferredTypeArgs));
Contract.Invariant(
- Ctor == null ||
+ Ctor == null ||
InferredTypeArgs.Count == Ctor.EnclosingDatatype.TypeArgs.Count);
}
@@ -4638,7 +4762,7 @@ namespace Microsoft.Dafny {
Contract.Requires(cce.NonNullElements(elements));
}
}
-
+
public class MultiSetDisplayExpr : DisplayExpression {
public MultiSetDisplayExpr(IToken tok, List<Expression> elements) : base(tok, elements) {
Contract.Requires(tok != null);
@@ -4800,7 +4924,7 @@ namespace Microsoft.Dafny {
public readonly Expression Receiver;
public readonly IToken OpenParen; // can be null if Args.Count == 0
public readonly List<Expression> Args;
- public Dictionary<TypeParameter, Type> TypeArgumentSubstitutions;
+ public Dictionary<TypeParameter, Type> TypeArgumentSubstitutions;
// created, initialized, and used by resolution (and also used by translation)
public enum CoCallResolution {
No,
@@ -4822,7 +4946,7 @@ namespace Microsoft.Dafny {
Function == null || TypeArgumentSubstitutions == null ||
Contract.ForAll(
Function.TypeArgs,
- a => TypeArgumentSubstitutions.ContainsKey(a)) &&
+ a => TypeArgumentSubstitutions.ContainsKey(a)) &&
Contract.ForAll(
TypeArgumentSubstitutions.Keys,
a => Function.TypeArgs.Contains(a) || Function.EnclosingClass.TypeArgs.Contains(a)));
@@ -5052,6 +5176,18 @@ namespace Microsoft.Dafny {
public ResolvedOpcode ResolvedOp_PossiblyStillUndetermined { // offer a way to return _theResolveOp -- for experts only!
get { return _theResolvedOp; }
}
+ public static bool IsEqualityOp(ResolvedOpcode op) {
+ switch (op) {
+ case ResolvedOpcode.EqCommon:
+ case ResolvedOpcode.SetEq:
+ case ResolvedOpcode.SeqEq:
+ case ResolvedOpcode.MultiSetEq:
+ case ResolvedOpcode.MapEq:
+ return true;
+ default:
+ return false;
+ }
+ }
public static Opcode ResolvedOp2SyntacticOp(ResolvedOpcode rop) {
switch (rop) {
@@ -5610,6 +5746,7 @@ namespace Microsoft.Dafny {
public readonly Expression Source;
public readonly List<MatchCaseExpr> Cases;
public readonly List<DatatypeCtor> MissingCases = new List<DatatypeCtor>(); // filled in during resolution
+ public readonly bool UsesOptionalBraces;
[ContractInvariantMethod]
void ObjectInvariant() {
@@ -5618,13 +5755,14 @@ namespace Microsoft.Dafny {
Contract.Invariant(cce.NonNullElements(MissingCases));
}
- public MatchExpr(IToken tok, Expression source, [Captured] List<MatchCaseExpr> cases)
+ public MatchExpr(IToken tok, Expression source, [Captured] List<MatchCaseExpr> cases, bool usesOptionalBraces)
: base(tok) {
Contract.Requires(tok != null);
Contract.Requires(source != null);
Contract.Requires(cce.NonNullElements(cases));
this.Source = source;
this.Cases = cases;
+ this.UsesOptionalBraces = usesOptionalBraces;
}
public override IEnumerable<Expression> SubExpressions {
@@ -5807,7 +5945,7 @@ namespace Microsoft.Dafny {
public class MaybeFreeExpression {
public readonly Expression E;
public readonly bool IsFree;
-
+
[ContractInvariantMethod]
void ObjectInvariant() {
Contract.Invariant(E != null);
diff --git a/Source/Dafny/Parser.cs b/Source/Dafny/Parser.cs
index bc89b6f1..750c04d0 100644
--- a/Source/Dafny/Parser.cs
+++ b/Source/Dafny/Parser.cs
@@ -25,8 +25,9 @@ public class Parser {
public const int _lbrace = 9;
public const int _rbrace = 10;
public const int _openparen = 11;
- public const int _star = 12;
- public const int _notIn = 13;
+ public const int _closeparen = 12;
+ public const int _star = 13;
+ public const int _notIn = 14;
public const int maxT = 126;
const bool T = true;
@@ -107,7 +108,7 @@ public static int Parse (string/*!*/ s, string/*!*/ filename, ModuleDecl module,
parser.Parse();
return parser.errors.count;
}
-public Parser(Scanner/*!*/ scanner, Errors/*!*/ errors, ModuleDecl module, BuiltIns builtIns, bool verifyThisFile=true)
+public Parser(Scanner/*!*/ scanner, Errors/*!*/ errors, ModuleDecl module, BuiltIns builtIns, bool verifyThisFile=true)
: this(scanner, errors) // the real work
{
// initialize readonly fields
@@ -156,6 +157,14 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
(e is FunctionCallExpr ||
(e is IdentifierSequence && ((IdentifierSequence)e).OpenParen != null));
}
+
+bool CloseOptionalParen(bool usesOptionalParen) {
+ return usesOptionalParen && la.kind == _closeparen;
+}
+
+bool CloseOptionalBrace(bool usesOptionalBrace) {
+ return usesOptionalBrace && la.kind == _rbrace;
+}
/*--------------------------------------------------------------------------*/
@@ -236,7 +245,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
// theModule should be a DefaultModuleDecl (actually, the singular DefaultModuleDecl)
Contract.Assert(defaultModule != null);
- while (la.kind == 14) {
+ while (la.kind == 15) {
Get();
Expect(6);
{
@@ -248,28 +257,28 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
includedFile = Path.Combine(basePath, includedFile);
fullPath = Path.GetFullPath(includedFile);
}
- defaultModule.Includes.Add(new Include(t, includedFile, fullPath));
+ defaultModule.Includes.Add(new Include(t, includedFile, fullPath));
}
}
while (StartOf(1)) {
switch (la.kind) {
- case 15: case 16: case 18: {
+ case 16: case 17: case 19: {
SubModuleDecl(defaultModule, out submodule);
defaultModule.TopLevelDecls.Add(submodule);
break;
}
- case 23: {
+ case 24: {
ClassDecl(defaultModule, out c);
defaultModule.TopLevelDecls.Add(c);
break;
}
- case 26: case 27: {
+ case 27: case 28: {
DatatypeDecl(defaultModule, out dt);
defaultModule.TopLevelDecls.Add(dt);
break;
}
- case 31: {
+ case 32: {
ArbitraryTypeDecl(defaultModule, out at);
defaultModule.TopLevelDecls.Add(at);
break;
@@ -279,7 +288,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
defaultModule.TopLevelDecls.Add(iter);
break;
}
- case 24: case 25: case 29: case 40: case 41: case 42: case 43: case 44: case 62: case 63: case 64: {
+ case 25: case 26: case 30: case 40: case 41: case 42: case 43: case 44: case 62: case 63: case 64: {
ClassMemberDecl(membersDefaultClass, false);
break;
}
@@ -302,7 +311,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
void SubModuleDecl(ModuleDefinition parent, out ModuleDecl submodule) {
ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt; ArbitraryTypeDecl at; IteratorDecl iter;
- Attributes attrs = null; IToken/*!*/ id;
+ Attributes attrs = null; IToken/*!*/ id;
List<MemberDecl/*!*/> namedModuleDefaultClassMembers = new List<MemberDecl>();;
List<IToken> idRefined = null, idPath = null, idAssignment = null;
ModuleDefinition module;
@@ -311,17 +320,17 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
bool isAbstract = false;
bool opened = false;
- if (la.kind == 15 || la.kind == 16) {
- if (la.kind == 15) {
+ if (la.kind == 16 || la.kind == 17) {
+ if (la.kind == 16) {
Get();
isAbstract = true;
}
- Expect(16);
+ Expect(17);
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
- if (la.kind == 17) {
+ if (la.kind == 18) {
Get();
QualifiedName(out idRefined);
}
@@ -330,22 +339,22 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
module.BodyStartTok = t;
while (StartOf(1)) {
switch (la.kind) {
- case 15: case 16: case 18: {
+ case 16: case 17: case 19: {
SubModuleDecl(module, out sm);
module.TopLevelDecls.Add(sm);
break;
}
- case 23: {
+ case 24: {
ClassDecl(module, out c);
module.TopLevelDecls.Add(c);
break;
}
- case 26: case 27: {
+ case 27: case 28: {
DatatypeDecl(module, out dt);
module.TopLevelDecls.Add(dt);
break;
}
- case 31: {
+ case 32: {
ArbitraryTypeDecl(module, out at);
module.TopLevelDecls.Add(at);
break;
@@ -355,7 +364,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
module.TopLevelDecls.Add(iter);
break;
}
- case 24: case 25: case 29: case 40: case 41: case 42: case 43: case 44: case 62: case 63: case 64: {
+ case 25: case 26: case 30: case 40: case 41: case 42: case 43: case 44: case 62: case 63: case 64: {
ClassMemberDecl(namedModuleDefaultClassMembers, false);
break;
}
@@ -365,22 +374,22 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
module.BodyEndTok = t;
module.TopLevelDecls.Add(new DefaultClassDecl(module, namedModuleDefaultClassMembers));
submodule = new LiteralModuleDecl(module, parent);
- } else if (la.kind == 18) {
+ } else if (la.kind == 19) {
Get();
- if (la.kind == 19) {
+ if (la.kind == 20) {
Get();
opened = true;
}
NoUSIdent(out id);
- if (la.kind == 20 || la.kind == 21) {
- if (la.kind == 20) {
+ if (la.kind == 21 || la.kind == 22) {
+ if (la.kind == 21) {
Get();
QualifiedName(out idPath);
submodule = new AliasModuleDecl(idPath, id, parent, opened);
} else {
Get();
QualifiedName(out idPath);
- if (la.kind == 22) {
+ if (la.kind == 23) {
Get();
QualifiedName(out idAssignment);
}
@@ -409,8 +418,8 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
List<MemberDecl/*!*/> members = new List<MemberDecl/*!*/>();
IToken bodyStart;
- while (!(la.kind == 0 || la.kind == 23)) {SynErr(129); Get();}
- Expect(23);
+ while (!(la.kind == 0 || la.kind == 24)) {SynErr(129); Get();}
+ Expect(24);
while (la.kind == 9) {
Attribute(ref attrs);
}
@@ -440,10 +449,10 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
IToken bodyStart = Token.NoToken; // dummy assignment
bool co = false;
- while (!(la.kind == 0 || la.kind == 26 || la.kind == 27)) {SynErr(130); Get();}
- if (la.kind == 26) {
+ while (!(la.kind == 0 || la.kind == 27 || la.kind == 28)) {SynErr(130); Get();}
+ if (la.kind == 27) {
Get();
- } else if (la.kind == 27) {
+ } else if (la.kind == 28) {
Get();
co = true;
} else SynErr(131);
@@ -454,10 +463,10 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
if (la.kind == 38) {
GenericParameters(typeArgs);
}
- Expect(20);
+ Expect(21);
bodyStart = t;
DatatypeMemberDecl(ctors);
- while (la.kind == 28) {
+ while (la.kind == 29) {
Get();
DatatypeMemberDecl(ctors);
}
@@ -480,15 +489,15 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
Attributes attrs = null;
var eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
- Expect(31);
+ Expect(32);
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (la.kind == 11) {
Get();
- Expect(32);
Expect(33);
+ Expect(12);
eqSupport = TypeParameter.EqualitySupportValue.Required;
}
at = new ArbitraryTypeDecl(id, id.val, module, eqSupport, attrs);
@@ -569,8 +578,8 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
Function/*!*/ f;
MemberModifiers mmod = new MemberModifiers();
- while (la.kind == 24 || la.kind == 25) {
- if (la.kind == 24) {
+ while (la.kind == 25 || la.kind == 26) {
+ if (la.kind == 25) {
Get();
mmod.IsGhost = true;
} else {
@@ -578,7 +587,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
mmod.IsStatic = true;
}
}
- if (la.kind == 29) {
+ if (la.kind == 30) {
FieldDecl(mmod, mm);
} else if (la.kind == 62 || la.kind == 63 || la.kind == 64) {
FunctionDecl(mmod, out f);
@@ -598,7 +607,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
void NoUSIdent(out IToken/*!*/ x) {
Contract.Ensures(Contract.ValueAtReturn(out x) != null);
Expect(1);
- x = t;
+ x = t;
if (x.val.StartsWith("_")) {
SemErr("cannot declare identifier beginning with underscore");
}
@@ -669,19 +678,19 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
if (la.kind == 11) {
Get();
- Expect(32);
Expect(33);
+ Expect(12);
eqSupport = TypeParameter.EqualitySupportValue.Required;
}
typeArgs.Add(new TypeParameter(id, id.val, eqSupport));
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
NoUSIdent(out id);
eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
if (la.kind == 11) {
Get();
- Expect(32);
Expect(33);
+ Expect(12);
eqSupport = TypeParameter.EqualitySupportValue.Required;
}
typeArgs.Add(new TypeParameter(id, id.val, eqSupport));
@@ -694,8 +703,8 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
Attributes attrs = null;
IToken/*!*/ id; Type/*!*/ ty;
- while (!(la.kind == 0 || la.kind == 29)) {SynErr(138); Get();}
- Expect(29);
+ while (!(la.kind == 0 || la.kind == 30)) {SynErr(138); Get();}
+ Expect(30);
if (mmod.IsStatic) { SemErr(t, "fields cannot be declared 'static'"); }
while (la.kind == 9) {
@@ -703,7 +712,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
}
FIdentType(out id, out ty);
mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs));
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
FIdentType(out id, out ty);
mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs));
@@ -984,13 +993,13 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
if (StartOf(9)) {
TypeIdentOptional(out id, out name, out ty, out isGhost);
formals.Add(new Formal(id, name, ty, true, isGhost));
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
TypeIdentOptional(out id, out name, out ty, out isGhost);
formals.Add(new Formal(id, name, ty, true, isGhost));
}
}
- Expect(33);
+ Expect(12);
}
void FIdentType(out IToken/*!*/ id, out Type/*!*/ ty) {
@@ -1011,7 +1020,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
Contract.Ensures(Contract.ValueAtReturn(out id)!=null);
Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
isGhost = false;
- if (la.kind == 24) {
+ if (la.kind == 25) {
Get();
if (allowGhostKeyword) { isGhost = true; } else { SemErr(t, "formal cannot be declared 'ghost' in this context"); }
}
@@ -1028,7 +1037,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
void WildIdent(out IToken/*!*/ x, bool allowWildcardId) {
Contract.Ensures(Contract.ValueAtReturn(out x) != null);
Expect(1);
- x = t;
+ x = t;
if (x.val.StartsWith("_")) {
if (allowWildcardId && x.val.Length == 1) {
t.val = "_v" + anonymousIds++;
@@ -1074,7 +1083,7 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
Contract.Ensures(Contract.ValueAtReturn(out identName)!=null);
string name = null; id = Token.NoToken; ty = new BoolType()/*dummy*/; isGhost = false;
- if (la.kind == 24) {
+ if (la.kind == 25) {
Get();
isGhost = true;
}
@@ -1106,8 +1115,9 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
}
void TypeAndToken(out IToken/*!*/ tok, out Type/*!*/ ty) {
- Contract.Ensures(Contract.ValueAtReturn(out tok)!=null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null); tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
- List<Type/*!*/>/*!*/ gt;
+ Contract.Ensures(Contract.ValueAtReturn(out tok)!=null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
+ tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
+ List<Type> gt;
switch (la.kind) {
case 52: {
@@ -1186,6 +1196,30 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
break;
}
+ case 11: {
+ Get();
+ tok = t; gt = new List<Type>();
+ if (StartOf(10)) {
+ Type(out ty);
+ gt.Add(ty);
+ while (la.kind == 31) {
+ Get();
+ Type(out ty);
+ gt.Add(ty);
+ }
+ }
+ Expect(12);
+ if (gt.Count == 1) {
+ // just return the type 'ty'
+ } else {
+ // make sure the nullary tuple type exists
+ var dims = gt.Count;
+ var tmp = theBuiltIns.TupleType(tok, dims, true);
+ ty = new UserDefinedType(tok, BuiltIns.TupleTypeName(dims), gt, new List<IToken>());
+ }
+
+ break;
+ }
case 1: case 5: case 60: {
ReferenceType(out tok, out ty);
break;
@@ -1198,16 +1232,16 @@ bool SemiFollowsCall(bool allowSemi, Expression e) {
Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; bool isGhost;
Expect(11);
openParen = t;
- if (la.kind == 1 || la.kind == 24) {
+ if (la.kind == 1 || la.kind == 25) {
GIdentType(allowGhostKeyword, out id, out ty, out isGhost);
formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
GIdentType(allowGhostKeyword, out id, out ty, out isGhost);
formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
}
}
- Expect(33);
+ Expect(12);
}
void IteratorSpec(List<FrameExpression/*!*/>/*!*/ reads, List<FrameExpression/*!*/>/*!*/ mod, List<Expression/*!*/> decreases,
@@ -1225,7 +1259,7 @@ ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs) {
if (StartOf(12)) {
FrameExpression(out fe);
reads.Add(fe);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
FrameExpression(out fe);
reads.Add(fe);
@@ -1241,7 +1275,7 @@ ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs) {
if (StartOf(12)) {
FrameExpression(out fe);
mod.Add(fe);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
FrameExpression(out fe);
mod.Add(fe);
@@ -1323,7 +1357,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (StartOf(12)) {
FrameExpression(out fe);
mod.Add(fe);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
FrameExpression(out fe);
mod.Add(fe);
@@ -1410,7 +1444,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
decreases.Add(e);
}
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
PossiblyWildExpression(out e);
if (!allowWildcard && e is WildcardExpr) {
@@ -1427,7 +1461,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expect(38);
Type(out ty);
gt.Add(ty);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Type(out ty);
gt.Add(ty);
@@ -1438,7 +1472,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void ReferenceType(out IToken/*!*/ tok, out Type/*!*/ ty) {
Contract.Ensures(Contract.ValueAtReturn(out tok) != null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
- List<Type/*!*/>/*!*/ gt;
+ List<Type> gt;
List<IToken> path;
if (la.kind == 60) {
@@ -1446,20 +1480,16 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
tok = t; ty = new ObjectType();
} else if (la.kind == 5) {
Get();
- tok = t; gt = new List<Type/*!*/>();
- GenericInstantiation(gt);
- if (gt.Count != 1) {
- SemErr("array type expects exactly one type argument");
- }
- int dims = 1;
- if (tok.val.Length != 5) {
- dims = int.Parse(tok.val.Substring(5));
+ tok = t; gt = new List<Type>();
+ if (la.kind == 38) {
+ GenericInstantiation(gt);
}
- ty = theBuiltIns.ArrayType(tok, dims, gt[0], true);
+ int dims = tok.val.Length == 5 ? 1 : int.Parse(tok.val.Substring(5));
+ ty = theBuiltIns.ArrayType(tok, dims, gt, true);
} else if (la.kind == 1) {
Ident(out tok);
- gt = new List<Type/*!*/>();
+ gt = new List<Type>();
path = new List<IToken>();
while (la.kind == 61) {
path.Add(tok);
@@ -1490,7 +1520,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (StartOf(17)) {
PossiblyWildFrameExpression(out fe);
reads.Add(fe);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
PossiblyWildFrameExpression(out fe);
reads.Add(fe);
@@ -1528,7 +1558,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void PossiblyWildFrameExpression(out FrameExpression/*!*/ fe) {
Contract.Ensures(Contract.ValueAtReturn(out fe) != null); fe = dummyFrameExpr;
- if (la.kind == 12) {
+ if (la.kind == 13) {
Get();
fe = new FrameExpression(t, new WildcardExpr(t), null);
} else if (StartOf(12)) {
@@ -1539,7 +1569,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void PossiblyWildExpression(out Expression/*!*/ e) {
Contract.Ensures(Contract.ValueAtReturn(out e)!=null);
e = dummyExpr;
- if (la.kind == 12) {
+ if (la.kind == 13) {
Get();
e = new WildcardExpr(t);
} else if (StartOf(16)) {
@@ -1580,11 +1610,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
PrintStmt(out s);
break;
}
- case 1: case 2: case 3: case 4: case 11: case 28: case 54: case 55: case 113: case 114: case 115: case 116: case 117: case 118: {
+ case 1: case 2: case 3: case 4: case 11: case 29: case 54: case 55: case 113: case 114: case 115: case 116: case 117: case 118: {
UpdateStmt(out s);
break;
}
- case 24: case 29: {
+ case 25: case 30: {
VarDeclStatement(out s);
break;
}
@@ -1708,7 +1738,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t;
AttributeArg(out arg, false);
args.Add(arg);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
AttributeArg(out arg, false);
args.Add(arg);
@@ -1735,9 +1765,9 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
Expect(8);
endTok = t; rhss.Add(new ExprRhs(e, attrs));
- } else if (la.kind == 30 || la.kind == 69 || la.kind == 71) {
+ } else if (la.kind == 31 || la.kind == 69 || la.kind == 71) {
lhss.Add(e); lhs0 = e;
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Lhs(out e);
lhss.Add(e);
@@ -1747,7 +1777,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t;
Rhs(out r, lhs0);
rhss.Add(r);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Rhs(out r, lhs0);
rhss.Add(r);
@@ -1790,18 +1820,18 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Attributes attrs = null;
IToken endTok;
- if (la.kind == 24) {
+ if (la.kind == 25) {
Get();
isGhost = true; x = t;
}
- Expect(29);
+ Expect(30);
if (!isGhost) { x = t; }
while (la.kind == 9) {
Attribute(ref attrs);
}
LocalIdentTypeOptional(out d, isGhost);
lhss.Add(d); d.Attributes = attrs; attrs = null;
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
while (la.kind == 9) {
Attribute(ref attrs);
@@ -1817,7 +1847,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Rhs(out r, lhs0);
rhss.Add(r);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Rhs(out r, lhs0);
rhss.Add(r);
@@ -1954,17 +1984,26 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void MatchStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null);
Token x; Expression/*!*/ e; MatchCaseStmt/*!*/ c;
- List<MatchCaseStmt/*!*/> cases = new List<MatchCaseStmt/*!*/>();
+ List<MatchCaseStmt/*!*/> cases = new List<MatchCaseStmt/*!*/>();
+ bool usesOptionalBrace = false;
+
Expect(82);
x = t;
Expression(out e, true);
- Expect(9);
+ if (la.kind == 9) {
+ Get();
+ usesOptionalBrace = true;
+ }
while (la.kind == 78) {
CaseStatement(out c);
cases.Add(c);
}
- Expect(10);
- s = new MatchStmt(x, t, e, cases);
+ if (CloseOptionalBrace(usesOptionalBrace)) {
+ Expect(10);
+ } else if (StartOf(21)) {
+ if (usesOptionalBrace) { SemErr(t, "expecting close curly brace"); }
+ } else SynErr(187);
+ s = new MatchStmt(x, t, e, cases, usesOptionalBrace);
}
void ForallStmt(out Statement/*!*/ s) {
@@ -1977,18 +2016,19 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
var ens = new List<MaybeFreeExpression/*!*/>();
bool isFree;
Expression/*!*/ e;
- BlockStmt/*!*/ block;
+ BlockStmt block = null;
IToken bodyStart, bodyEnd;
+ IToken tok = Token.NoToken;
if (la.kind == 85) {
Get();
- x = t;
+ x = t; tok = x;
} else if (la.kind == 86) {
Get();
x = t;
errors.Warning(t, "the 'parallel' keyword has been deprecated; the comprehension statement now uses the keyword 'forall' (and the parentheses around the bound variables are now optional)");
- } else SynErr(187);
+ } else SynErr(188);
if (la.kind == 11) {
Get();
usesOptionalParen = true;
@@ -2002,12 +2042,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (bvars == null) { bvars = new List<BoundVar>(); }
if (range == null) { range = new LiteralExpr(x, true); }
- if (la.kind == 33) {
- Get();
- if (!usesOptionalParen) { SemErr(t, "found but didn't expect a close parenthesis"); }
- } else if (la.kind == 9 || la.kind == 46 || la.kind == 48) {
+ if (CloseOptionalParen(usesOptionalParen)) {
+ Expect(12);
+ } else if (StartOf(22)) {
if (usesOptionalParen) { SemErr(t, "expecting close parenthesis"); }
- } else SynErr(188);
+ } else SynErr(189);
while (la.kind == 46 || la.kind == 48) {
isFree = false;
if (la.kind == 46) {
@@ -2016,19 +2055,30 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
Expect(48);
Expression(out e, false);
- Expect(8);
ens.Add(new MaybeFreeExpression(e, isFree));
+ Expect(8);
+ tok = t;
+ }
+ if (la.kind == 9) {
+ BlockStmt(out block, out bodyStart, out bodyEnd);
}
- BlockStmt(out block, out bodyStart, out bodyEnd);
- s = new ForallStmt(x, block.EndTok, bvars, attrs, range, ens, block);
+ if (DafnyOptions.O.DisallowSoundnessCheating && block == null && 0 < ens.Count) {
+ SemErr(t, "a forall statement with an ensures clause must have a body");
+ }
+
+ if (block != null) {
+ tok = block.EndTok;
+ }
+ s = new ForallStmt(x, tok, bvars, attrs, range, ens, block);
+
}
void CalcStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null);
Token x;
- CalcStmt.CalcOp/*!*/ op, calcOp = Microsoft.Dafny.CalcStmt.DefaultOp, resOp = Microsoft.Dafny.CalcStmt.DefaultOp;
+ CalcStmt.CalcOp/*!*/ op, calcOp = Microsoft.Dafny.CalcStmt.DefaultOp, resOp = Microsoft.Dafny.CalcStmt.DefaultOp;
var lines = new List<Expression/*!*/>();
- var hints = new List<BlockStmt/*!*/>();
+ var hints = new List<BlockStmt/*!*/>();
CalcStmt.CalcOp stepOp;
var stepOps = new List<CalcStmt.CalcOp>();
CalcStmt.CalcOp maybeOp;
@@ -2039,13 +2089,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expect(88);
x = t;
- if (StartOf(21)) {
+ if (StartOf(23)) {
CalcOp(out opTok, out calcOp);
maybeOp = calcOp.ResultOp(calcOp); // guard against non-transitive calcOp (like !=)
if (maybeOp == null) {
SemErr(opTok, "the main operator of a calculation must be transitive");
}
- resOp = calcOp;
+ resOp = calcOp;
}
Expect(9);
@@ -2053,7 +2103,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expression(out e, false);
lines.Add(e); stepOp = calcOp; danglingOperator = null;
Expect(8);
- if (StartOf(21)) {
+ if (StartOf(23)) {
CalcOp(out opTok, out op);
maybeOp = resOp.ResultOp(op);
if (maybeOp == null) {
@@ -2078,8 +2128,8 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (lines.Count > 0) {
// Repeat the last line to create a dummy line for the dangling hint
lines.Add(lines[lines.Count - 1]);
- }
- s = new CalcStmt(x, t, calcOp, lines, hints, stepOps, resOp);
+ }
+ s = new CalcStmt(x, t, calcOp, lines, hints, stepOps, resOp);
}
@@ -2095,11 +2145,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
while (IsAttribute()) {
Attribute(ref attrs);
}
- if (StartOf(22)) {
+ if (StartOf(24)) {
if (StartOf(12)) {
FrameExpression(out fe);
mod.Add(fe);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
FrameExpression(out fe);
mod.Add(fe);
@@ -2112,10 +2162,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (la.kind == 9) {
BlockStmt(out body, out bodyStart, out endTok);
} else if (la.kind == 8) {
- while (!(la.kind == 0 || la.kind == 8)) {SynErr(189); Get();}
+ while (!(la.kind == 0 || la.kind == 8)) {SynErr(190); Get();}
Get();
endTok = t;
- } else SynErr(190);
+ } else SynErr(191);
s = new ModifyStmt(tok, endTok, mod, attrs, body);
if (ellipsisToken != null) {
s = new SkeletonStatement(s, ellipsisToken, null);
@@ -2135,11 +2185,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 51) {
Get();
returnTok = t; isYield = true;
- } else SynErr(191);
- if (StartOf(23)) {
+ } else SynErr(192);
+ if (StartOf(25)) {
Rhs(out r, null);
rhss = new List<AssignmentRhs>(); rhss.Add(r);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Rhs(out r, null);
rhss.Add(r);
@@ -2166,7 +2216,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
names = new List<IToken>(); exprs = new List<Expression>(); whereTok = t;
Ident(out tok);
names.Add(tok);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Ident(out tok);
names.Add(tok);
@@ -2174,7 +2224,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expect(69);
Expression(out e, false);
exprs.Add(e);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Expression(out e, false);
exprs.Add(e);
@@ -2208,7 +2258,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
ee = new List<Expression>();
Expressions(ee);
Expect(75);
- UserDefinedType tmp = theBuiltIns.ArrayType(x, ee.Count, new IntType(), true);
+ var tmp = theBuiltIns.ArrayType(ee.Count, new IntType(), true);
} else {
x = null; args = new List<Expression/*!*/>();
@@ -2220,7 +2270,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (StartOf(16)) {
Expressions(args);
}
- Expect(33);
+ Expect(12);
}
}
if (ee != null) {
@@ -2231,13 +2281,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
r = new TypeRhs(newToken, ty);
}
- } else if (la.kind == 12) {
+ } else if (la.kind == 13) {
Get();
r = new HavocRhs(t);
} else if (StartOf(16)) {
Expression(out e, false);
r = new ExprRhs(e);
- } else SynErr(192);
+ } else SynErr(193);
while (la.kind == 9) {
Attribute(ref attrs);
}
@@ -2252,20 +2302,20 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
while (la.kind == 61 || la.kind == 74) {
Suffix(ref e);
}
- } else if (StartOf(24)) {
+ } else if (StartOf(26)) {
ConstAtomExpression(out e);
Suffix(ref e);
while (la.kind == 61 || la.kind == 74) {
Suffix(ref e);
}
- } else SynErr(193);
+ } else SynErr(194);
}
void Expressions(List<Expression/*!*/>/*!*/ args) {
Contract.Requires(cce.NonNullElements(args)); Expression/*!*/ e;
Expression(out e, true);
args.Add(e);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Expression(out e, true);
args.Add(e);
@@ -2296,18 +2346,18 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void Guard(out Expression e) {
Expression/*!*/ ee; e = null;
- if (la.kind == 12) {
+ if (la.kind == 13) {
Get();
e = null;
} else if (IsParenStar()) {
Expect(11);
+ Expect(13);
Expect(12);
- Expect(33);
e = null;
} else if (StartOf(16)) {
Expression(out ee, true);
e = ee;
- } else SynErr(194);
+ } else SynErr(195);
}
void LoopSpec(out List<MaybeFreeExpression/*!*/> invariants, out List<Expression/*!*/> decreases, out List<FrameExpression/*!*/> mod, ref Attributes decAttrs, ref Attributes modAttrs) {
@@ -2317,23 +2367,23 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
decreases = new List<Expression/*!*/>();
mod = null;
- while (StartOf(25)) {
+ while (StartOf(27)) {
if (la.kind == 46 || la.kind == 81) {
Invariant(out invariant);
- while (!(la.kind == 0 || la.kind == 8)) {SynErr(195); Get();}
+ while (!(la.kind == 0 || la.kind == 8)) {SynErr(196); Get();}
Expect(8);
invariants.Add(invariant);
} else if (la.kind == 49) {
- while (!(la.kind == 0 || la.kind == 49)) {SynErr(196); Get();}
+ while (!(la.kind == 0 || la.kind == 49)) {SynErr(197); Get();}
Get();
while (IsAttribute()) {
Attribute(ref decAttrs);
}
DecreasesList(decreases, true);
- while (!(la.kind == 0 || la.kind == 8)) {SynErr(197); Get();}
+ while (!(la.kind == 0 || la.kind == 8)) {SynErr(198); Get();}
Expect(8);
} else {
- while (!(la.kind == 0 || la.kind == 45)) {SynErr(198); Get();}
+ while (!(la.kind == 0 || la.kind == 45)) {SynErr(199); Get();}
Get();
while (IsAttribute()) {
Attribute(ref modAttrs);
@@ -2342,13 +2392,13 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (StartOf(12)) {
FrameExpression(out fe);
mod.Add(fe);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
FrameExpression(out fe);
mod.Add(fe);
}
}
- while (!(la.kind == 0 || la.kind == 8)) {SynErr(199); Get();}
+ while (!(la.kind == 0 || la.kind == 8)) {SynErr(200); Get();}
Expect(8);
}
}
@@ -2356,7 +2406,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void Invariant(out MaybeFreeExpression/*!*/ invariant) {
bool isFree = false; Expression/*!*/ e; List<string> ids = new List<string>(); invariant = null; Attributes attrs = null;
- while (!(la.kind == 0 || la.kind == 46 || la.kind == 81)) {SynErr(200); Get();}
+ while (!(la.kind == 0 || la.kind == 46 || la.kind == 81)) {SynErr(201); Get();}
if (la.kind == 46) {
Get();
isFree = true;
@@ -2383,12 +2433,12 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
IdentTypeOptional(out bv);
arguments.Add(bv);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
IdentTypeOptional(out bv);
arguments.Add(bv);
}
- Expect(33);
+ Expect(12);
}
Expect(79);
while (StartOf(14)) {
@@ -2405,7 +2455,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (StartOf(16)) {
Expression(out e, allowSemi);
arg = new Attributes.Argument(t, e);
- } else SynErr(201);
+ } else SynErr(202);
}
void QuantifierDomain(out List<BoundVar> bvars, out Attributes attrs, out Expression range) {
@@ -2416,7 +2466,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
IdentTypeOptional(out bv);
bvars.Add(bv);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
IdentTypeOptional(out bv);
bvars.Add(bv);
@@ -2424,7 +2474,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
while (IsAttribute()) {
Attribute(ref attrs);
}
- if (la.kind == 28) {
+ if (la.kind == 29) {
Get();
Expression(out range, true);
}
@@ -2436,7 +2486,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = null;
switch (la.kind) {
- case 32: {
+ case 33: {
Get();
x = t; binOp = BinaryExpr.Opcode.Eq;
if (la.kind == 89) {
@@ -2502,7 +2552,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t; binOp = BinaryExpr.Opcode.Exp;
break;
}
- default: SynErr(202); break;
+ default: SynErr(203); break;
}
if (k == null) {
op = new Microsoft.Dafny.CalcStmt.BinaryCalcOp(binOp);
@@ -2514,7 +2564,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void Hint(out BlockStmt s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); // returns an empty block statement if the hint is empty
- var subhints = new List<Statement/*!*/>();
+ var subhints = new List<Statement/*!*/>();
IToken bodyStart, bodyEnd;
BlockStmt/*!*/ block;
Statement/*!*/ calc;
@@ -2530,7 +2580,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
endTok = calc.EndTok; subhints.Add(calc);
}
}
- s = new BlockStmt(x, endTok, subhints); // if the hint is empty x is the first token of the next line, but it doesn't matter cause the block statement is just used as a container
+ s = new BlockStmt(x, endTok, subhints); // if the hint is empty x is the first token of the next line, but it doesn't matter cause the block statement is just used as a container
}
@@ -2539,7 +2589,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 97) {
Get();
- } else SynErr(203);
+ } else SynErr(204);
}
void ImpliesOp() {
@@ -2547,7 +2597,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 99) {
Get();
- } else SynErr(204);
+ } else SynErr(205);
}
void ExpliesOp() {
@@ -2555,7 +2605,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 101) {
Get();
- } else SynErr(205);
+ } else SynErr(206);
}
void EquivExpression(out Expression e0, bool allowSemi) {
@@ -2572,7 +2622,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void ImpliesExpliesExpression(out Expression e0, bool allowSemi) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
LogicalExpression(out e0, allowSemi);
- if (StartOf(26)) {
+ if (StartOf(28)) {
if (la.kind == 98 || la.kind == 99) {
ImpliesOp();
x = t;
@@ -2596,7 +2646,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
void LogicalExpression(out Expression e0, bool allowSemi) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
RelationalExpression(out e0, allowSemi);
- if (StartOf(27)) {
+ if (StartOf(29)) {
if (la.kind == 102 || la.kind == 103) {
AndOp();
x = t;
@@ -2650,7 +2700,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Term(out e0, allowSemi);
e = e0;
- if (StartOf(28)) {
+ if (StartOf(30)) {
RelOp(out x, out op, out k);
firstOpTok = x;
Term(out e1, allowSemi);
@@ -2663,7 +2713,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
e = new TernaryExpr(x, op == BinaryExpr.Opcode.Eq ? TernaryExpr.Opcode.PrefixEqOp : TernaryExpr.Opcode.PrefixNeqOp, k, e0, e1);
}
- while (StartOf(28)) {
+ while (StartOf(30)) {
if (chain == null) {
chain = new List<Expression>();
ops = new List<BinaryExpr.Opcode>();
@@ -2740,7 +2790,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 103) {
Get();
- } else SynErr(206);
+ } else SynErr(207);
}
void OrOp() {
@@ -2748,7 +2798,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 105) {
Get();
- } else SynErr(207);
+ } else SynErr(208);
}
void Term(out Expression e0, bool allowSemi) {
@@ -2768,7 +2818,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
k = null;
switch (la.kind) {
- case 32: {
+ case 33: {
Get();
x = t; op = BinaryExpr.Opcode.Eq;
if (la.kind == 89) {
@@ -2815,7 +2865,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t; op = BinaryExpr.Opcode.In;
break;
}
- case 13: {
+ case 14: {
Get();
x = t; op = BinaryExpr.Opcode.NotIn;
break;
@@ -2853,14 +2903,14 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t; op = BinaryExpr.Opcode.Ge;
break;
}
- default: SynErr(208); break;
+ default: SynErr(209); break;
}
}
void Factor(out Expression e0, bool allowSemi) {
Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; BinaryExpr.Opcode op;
UnaryExpression(out e0, allowSemi);
- while (la.kind == 12 || la.kind == 110 || la.kind == 111) {
+ while (la.kind == 13 || la.kind == 110 || la.kind == 111) {
MulOp(out x, out op);
UnaryExpression(out e1, allowSemi);
e0 = new BinaryExpr(x, op, e0, e1);
@@ -2875,7 +2925,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 109) {
Get();
x = t; op = BinaryExpr.Opcode.Sub;
- } else SynErr(209);
+ } else SynErr(210);
}
void UnaryExpression(out Expression e, bool allowSemi) {
@@ -2895,7 +2945,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
e = new UnaryExpr(x, UnaryExpr.Opcode.Not, e);
break;
}
- case 24: case 29: case 56: case 66: case 72: case 76: case 82: case 83: case 85: case 88: case 121: case 122: case 123: {
+ case 25: case 30: case 56: case 66: case 72: case 76: case 82: case 83: case 85: case 88: case 121: case 122: case 123: {
EndlessExpression(out e, allowSemi);
break;
}
@@ -2930,25 +2980,25 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
} else if (la.kind == 1) {
MapComprehensionExpr(x, out e, allowSemi);
- } else if (StartOf(29)) {
+ } else if (StartOf(31)) {
SemErr("map must be followed by literal in brackets or comprehension.");
- } else SynErr(210);
+ } else SynErr(211);
break;
}
- case 2: case 3: case 4: case 11: case 28: case 54: case 55: case 113: case 114: case 115: case 116: case 117: case 118: {
+ case 2: case 3: case 4: case 11: case 29: case 54: case 55: case 113: case 114: case 115: case 116: case 117: case 118: {
ConstAtomExpression(out e);
while (la.kind == 61 || la.kind == 74) {
Suffix(ref e);
}
break;
}
- default: SynErr(211); break;
+ default: SynErr(212); break;
}
}
void MulOp(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 == 12) {
+ if (la.kind == 13) {
Get();
x = t; op = BinaryExpr.Opcode.Mul;
} else if (la.kind == 110) {
@@ -2957,7 +3007,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 111) {
Get();
x = t; op = BinaryExpr.Opcode.Mod;
- } else SynErr(212);
+ } else SynErr(213);
}
void NegOp() {
@@ -2965,7 +3015,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 112) {
Get();
- } else SynErr(213);
+ } else SynErr(214);
}
void EndlessExpression(out Expression e, bool allowSemi) {
@@ -3004,7 +3054,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
e = new StmtExpr(s.Tok, s, e);
break;
}
- case 24: case 29: {
+ case 25: case 30: {
LetExpr(out e, allowSemi);
break;
}
@@ -3012,7 +3062,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
NamedExpr(out e, allowSemi);
break;
}
- default: SynErr(214); break;
+ default: SynErr(215); break;
}
}
@@ -3044,7 +3094,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (StartOf(16)) {
Expressions(args);
}
- Expect(33);
+ Expect(12);
}
e = new IdentifierSequence(idents, openParen, args);
}
@@ -3078,7 +3128,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (StartOf(16)) {
Expressions(args);
}
- Expect(33);
+ Expect(12);
e = new FunctionCallExpr(id, id.val, e, openParen, args);
}
if (!func) { e = new ExprDotName(id, e, id.val); }
@@ -3106,17 +3156,17 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
multipleLengths = new List<Expression>();
multipleLengths.Add(e0);
}
- takeRest = true;
+ takeRest = true;
if (StartOf(16)) {
Expression(out ee, true);
- multipleLengths.Add(ee);
+ multipleLengths.Add(ee);
takeRest = false;
}
}
- } else if (la.kind == 30 || la.kind == 75) {
- while (la.kind == 30) {
+ } else if (la.kind == 31 || la.kind == 75) {
+ while (la.kind == 31) {
Get();
Expression(out ee, true);
if (multipleIndices == null) {
@@ -3126,7 +3176,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
multipleIndices.Add(ee);
}
- } else SynErr(215);
+ } else SynErr(216);
} else if (la.kind == 120) {
Get();
anyDots = true;
@@ -3134,11 +3184,11 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expression(out ee, true);
e1 = ee;
}
- } else SynErr(216);
+ } else SynErr(217);
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);
+ var tmp = theBuiltIns.ArrayType(multipleIndices.Count, new IntType(), true);
} else {
if (!anyDots && e0 == null) {
/* a parsing error occurred */
@@ -3175,7 +3225,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
Expect(75);
- } else SynErr(217);
+ } else SynErr(218);
}
void DisplayExpr(out Expression e) {
@@ -3199,7 +3249,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
e = new SeqDisplayExpr(x, elements);
Expect(75);
- } else SynErr(218);
+ } else SynErr(219);
}
void MultiSetExpr(out Expression e) {
@@ -3222,10 +3272,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t; elements = new List<Expression/*!*/>();
Expression(out e, true);
e = new MultiSetFormingExpr(x, e);
- Expect(33);
- } else if (StartOf(30)) {
+ Expect(12);
+ } else if (StartOf(32)) {
SemErr("multiset must be followed by multiset literal or expression to coerce in parentheses.");
- } else SynErr(219);
+ } else SynErr(220);
}
void MapDisplayExpr(IToken/*!*/ mapToken, out Expression e) {
@@ -3250,7 +3300,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
IdentTypeOptional(out bv);
bvars.Add(bv);
- if (la.kind == 28) {
+ if (la.kind == 29) {
Get();
Expression(out range, true);
}
@@ -3301,7 +3351,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t;
Expect(11);
Expression(out e, true);
- Expect(33);
+ Expect(12);
e = new FreshExpr(x, e);
break;
}
@@ -3310,24 +3360,20 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t;
Expect(11);
Expression(out e, true);
- Expect(33);
+ Expect(12);
e = new OldExpr(x, e);
break;
}
- case 28: {
+ case 29: {
Get();
x = t;
Expression(out e, true);
e = new UnaryExpr(x, UnaryExpr.Opcode.SeqLength, e);
- Expect(28);
+ Expect(29);
break;
}
case 11: {
- Get();
- x = t;
- Expression(out e, true);
- e = new ParensExpression(x, e);
- Expect(33);
+ ParensExpression(out e);
break;
}
case 55: {
@@ -3336,10 +3382,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expect(11);
IToken openParen = t;
Expression(out e, true);
- Expect(33);
+ Expect(12);
IToken classTok = new Token(t.line, t.col); classTok.val = "Real";
IToken fnTok = new Token(t.line, t.col); fnTok.val = "IntToReal";
- //e = new IdentifierSequence(new List<IToken>() { classTok, fnTok }, openParen, new List<Expression/*!*/>() { e });
+ //e = new IdentifierSequence(new List<IToken>() { classTok, fnTok }, openParen, new List<Expression/*!*/>() { e });
e = new FunctionCallExpr(x, "IntToReal", new StaticReceiverExpr(x, theBuiltIns.RealClass), openParen, new List<Expression/*!*/>() { e });
break;
@@ -3350,15 +3396,15 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expect(11);
IToken openParen = t;
Expression(out e, true);
- Expect(33);
+ Expect(12);
IToken classTok = new Token(t.line, t.col); classTok.val = "Real";
IToken fnTok = new Token(t.line, t.col); fnTok.val = "RealToInt";
- //e = new IdentifierSequence(new List<IToken>() { classTok, fnTok }, openParen, new List<Expression/*!*/>() { e });
+ //e = new IdentifierSequence(new List<IToken>() { classTok, fnTok }, openParen, new List<Expression/*!*/>() { e });
e = new FunctionCallExpr(x, "RealToInt", new StaticReceiverExpr(x, theBuiltIns.RealClass), openParen, new List<Expression/*!*/>() { e });
break;
}
- default: SynErr(220); break;
+ default: SynErr(221); break;
}
}
@@ -3383,7 +3429,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
n = BigInteger.Zero;
}
- } else SynErr(221);
+ } else SynErr(222);
}
void Dec(out Basetypes.BigDec d) {
@@ -3398,6 +3444,41 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
+ void ParensExpression(out Expression e) {
+ IToken x;
+ List<Expression> args = null;
+
+ Expect(11);
+ x = t; e = null;
+ if (la.kind == 12) {
+ Get();
+ var tmp = theBuiltIns.TupleType(x, 0, true);
+ e = new DatatypeValue(x, BuiltIns.TupleTypeName(0), BuiltIns.TupleTypeCtorName, new List<Expression>());
+
+ } else if (StartOf(16)) {
+ Expression(out e, true);
+ while (la.kind == 31) {
+ Get();
+ if (args == null) {
+ args = new List<Expression>();
+ args.Add(e); // add the first argument, which was parsed above
+ }
+
+ Expression(out e, true);
+ args.Add(e);
+ }
+ Expect(12);
+ if (args == null) {
+ e = new ParensExpression(x, e);
+ } else {
+ // make sure the corresponding tuple type exists
+ var tmp = theBuiltIns.TupleType(x, args.Count, true);
+ e = new DatatypeValue(x, BuiltIns.TupleTypeName(args.Count), BuiltIns.TupleTypeCtorName, args);
+ }
+
+ } else SynErr(223);
+ }
+
void MapLiteralExpressions(out List<ExpressionPair> elements) {
Expression/*!*/ d, r;
elements = new List<ExpressionPair/*!*/>();
@@ -3405,7 +3486,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expect(69);
Expression(out r, true);
elements.Add(new ExpressionPair(d,r));
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Expression(out d, true);
Expect(69);
@@ -3419,21 +3500,31 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 125) {
Get();
- } else SynErr(222);
+ } else SynErr(224);
}
void MatchExpression(out Expression e, bool allowSemi) {
Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; MatchCaseExpr/*!*/ c;
List<MatchCaseExpr/*!*/> cases = new List<MatchCaseExpr/*!*/>();
+ bool usesOptionalBrace = false;
Expect(82);
x = t;
Expression(out e, allowSemi);
+ if (la.kind == 9) {
+ Get();
+ usesOptionalBrace = true;
+ }
while (la.kind == 78) {
CaseExpression(out c, allowSemi);
cases.Add(c);
}
- e = new MatchExpr(x, e, cases);
+ if (CloseOptionalBrace(usesOptionalBrace)) {
+ Expect(10);
+ } else if (StartOf(31)) {
+ if (usesOptionalBrace) { SemErr(t, "expecting close curly brace"); }
+ } else SynErr(225);
+ e = new MatchExpr(x, e, cases, usesOptionalBrace);
}
void QuantifierGuts(out Expression q, bool allowSemi) {
@@ -3450,7 +3541,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
} else if (la.kind == 122 || la.kind == 123) {
Exists();
x = t;
- } else SynErr(223);
+ } else SynErr(226);
QuantifierDomain(out bvars, out attrs, out range);
QSep();
Expression(out body, allowSemi);
@@ -3474,12 +3565,12 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
x = t;
IdentTypeOptional(out bv);
bvars.Add(bv);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
IdentTypeOptional(out bv);
bvars.Add(bv);
}
- Expect(28);
+ Expect(29);
Expression(out range, allowSemi);
if (la.kind == 124 || la.kind == 125) {
QSep();
@@ -3498,7 +3589,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
AssumeStmt(out s);
} else if (la.kind == 88) {
CalcStmt(out s);
- } else SynErr(224);
+ } else SynErr(227);
}
void LetExpr(out Expression e, bool allowSemi) {
@@ -3510,17 +3601,17 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
bool exact = true;
e = dummyExpr;
- if (la.kind == 24) {
+ if (la.kind == 25) {
Get();
isGhost = true; x = t;
}
- Expect(29);
+ Expect(30);
if (!isGhost) { x = t; }
CasePattern(out pat);
if (isGhost) { pat.Vars.Iter(bv => bv.IsGhost = true); }
letLHSs.Add(pat);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
CasePattern(out pat);
if (isGhost) { pat.Vars.Iter(bv => bv.IsGhost = true); }
@@ -3538,10 +3629,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
}
- } else SynErr(225);
+ } else SynErr(228);
Expression(out e, false);
letRHSs.Add(e);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
Expression(out e, false);
letRHSs.Add(e);
@@ -3577,19 +3668,19 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
if (la.kind == 1) {
CasePattern(out pat);
arguments.Add(pat);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
CasePattern(out pat);
arguments.Add(pat);
}
}
- Expect(33);
+ Expect(12);
pat = new CasePattern(id, id.val, arguments);
} else if (la.kind == 1) {
IdentTypeOptional(out bv);
- pat = new CasePattern(bv.tok, bv);
+ pat = new CasePattern(bv.tok, bv);
- } else SynErr(226);
+ } else SynErr(229);
}
void CaseExpression(out MatchCaseExpr c, bool allowSemi) {
@@ -3605,12 +3696,12 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
IdentTypeOptional(out bv);
arguments.Add(bv);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
IdentTypeOptional(out bv);
arguments.Add(bv);
}
- Expect(33);
+ Expect(12);
}
Expect(79);
Expression(out body, allowSemi);
@@ -3622,7 +3713,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 121) {
Get();
- } else SynErr(227);
+ } else SynErr(230);
}
void Exists() {
@@ -3630,7 +3721,7 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Get();
} else if (la.kind == 123) {
Get();
- } else SynErr(228);
+ } else SynErr(231);
}
void AttributeBody(ref Attributes attrs) {
@@ -3641,10 +3732,10 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
Expect(7);
Expect(1);
aName = t.val;
- if (StartOf(31)) {
+ if (StartOf(33)) {
AttributeArg(out aArg, true);
aArgs.Add(aArg);
- while (la.kind == 30) {
+ while (la.kind == 31) {
Get();
AttributeArg(out aArg, true);
aArgs.Add(aArg);
@@ -3666,38 +3757,40 @@ List<Expression/*!*/>/*!*/ decreases, ref Attributes decAttrs, ref Attributes mo
}
static readonly bool[,]/*!*/ set = {
- {T,T,T,T, T,x,x,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,T, T,x,T,T, T,T,x,x, x,x,T,x, x,T,x,x, T,T,T,T, T,T,T,T, T,T,T,T, x,x,T,T, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, T,x,x,x, T,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,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,T, T,x,T,x, x,x,x,T, T,T,T,T, x,T,x,T, x,x,T,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,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, T,T,x,x, x,T,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,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},
+ {T,T,T,T, T,x,x,x, T,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, T,T,x,T, T,T,T,x, x,x,T,x, x,T,x,x, T,T,T,T, T,T,T,T, T,T,T,T, x,x,T,T, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, T,x,x,x, T,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,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, T,T,x,T, x,x,x,x, T,T,T,T, T,x,T,x, T,x,T,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,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,T,T,x, x,x,T,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,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,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, x,x,x,x, x,x,x,x, x,x,x,x, 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},
- {T,x,x,x, x,x,x,x, x,T,T,T, x,x,x,T, T,x,T,x, x,x,x,T, T,T,T,T, x,T,x,T, x,x,T,x, x,x,T,x, T,T,T,T, T,x,x,T, T,T,T,x, x,x,x,x, x,x,x,x, x,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, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, 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,T,T,T, x,x,x,x, T,T,x,T, x,x,x,x, T,T,T,T, T,x,T,x, T,x,T,x, x,x,T,x, T,T,T,T, T,x,x,T, T,T,T,x, x,x,x,x, x,x,x,x, x,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, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,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},
{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, 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,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,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,T,T,x, x,T,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, 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,x,x,x, x,x,x,x},
- {x,T,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, 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,x,x,x, x,x,x,x},
+ {x,T,T,x, x,T,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,x,x,x, 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,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,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,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, 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,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,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,T,T,T, T,x,x,x, x,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, T,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,T,T, T,T,x,T, x,x,x,x, x,T,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
+ {x,T,T,T, 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,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,x,T, x,x,x,x, x,T,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, 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,x, x,x,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,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,T,T,T, T,x,x,x, x,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, T,T,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,T, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, T,x,x,x, T,x,x,x, T,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,T,T,T, T,T,T,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, x,x,x,x, x,x,x,x, x,T,x,x, x,T,T,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,T, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, T,x,x,x, T,x,x,x, T,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,T,T,T, 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,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,T,T,T, T,x,x,x, x,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, T,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,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
- {x,T,T,T, T,x,x,x, x,T,x,T, T,x,x,x, x,x,x,x, x,x,x,x, T,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,T,T, T,T,x,T, x,x,x,x, x,T,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
- {T,T,T,T, T,x,x,x, x,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, T,T,x,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,T, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, T,x,x,x, T,x,x,x, T,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,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x},
- {x,T,T,T, T,x,x,x, x,T,x,T, T,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, T,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,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
- {x,T,T,T, T,x,x,x, x,T,x,T, T,x,x,x, x,x,x,x, x,x,x,x, T,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,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, 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,x, x,x,x,x, x,x,x,x, x,x,x,x, T,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,T,T, T,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,T,T,T, T,x,x,x, x,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, T,x,x,x, T,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,T,T, T,T,x,T, x,x,x,x, x,T,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
- {x,T,T,T, T,x,x,x, x,T,x,T, T,x,x,x, x,x,x,x, x,x,x,x, T,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,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,T,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
- {x,x,T,T, T,x,x,x, x,x,x,T, 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,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,T,T,T, T,T,T,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, x,x,x,x, x,x,x,x, x,T,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,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
+ {x,T,T,T, T,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,T,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,T,T, T,T,x,T, x,x,x,x, x,T,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
+ {T,T,T,T, 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,T,T,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,T, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, T,x,x,x, T,x,x,x, T,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,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,T,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
+ {x,T,T,T, T,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,T,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,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
+ {x,T,T,T, T,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,T,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,x,T,T, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, T,x,x,x, T,x,T,x, T,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,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x},
+ {x,T,T,T, T,x,x,x, x,T,T,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,T,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,T,x, T,x,x,T, x,x,T,T, x,x,x,x, x,x,x,x, x,x,T,T, x,x,T,x, T,x,x,x, T,x,T,x, T,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,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,T,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,T,T, T,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,T,T,T, 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,T,T,x, x,x,x,x, x,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, T,T,x,T, x,x,x,x, x,T,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
+ {x,T,T,T, T,x,x,x, x,T,x,T, x,T,x,x, x,x,x,x, x,x,x,x, x,T,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,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,T,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x},
+ {x,x,T,T, T,x,x,x, x,x,x,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,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,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,T,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,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, x,x,x,x, x,x,x,x, x,x,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, x,x,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,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,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,T,T, T,T,T,T, 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,T, T,T,T,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, T,T,x,x, x,T,T,T, x,x,x,x, x,T,T,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,x,x, x,x,x,T, x,T,T,T, x,T,x,x, x,x,x,x, x,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,x,x,x, x,x,x,T, T,x,x,x, T,T,x,x},
- {x,x,x,x, x,x,x,T, T,T,T,x, T,T,x,x, x,x,x,x, x,x,x,x, x,x,x,x, T,x,T,x, T,T,x,x, x,T,T,T, x,x,x,x, x,T,T,x, T,T,x,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,x,x, x,T,x,x, x,x,T,T, x,T,T,T, x,T,x,x, x,x,x,x, x,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,x,x,x, x,x,x,T, T,x,x,x, T,T,x,x},
- {x,T,T,T, T,x,T,x, x,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, T,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,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, 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,T,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,T,T, T,T,T,T, 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,T,T,T, T,x,x,T, T,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,T,T, x,T,x,x, x,T,T,T, x,x,x,x, x,T,T,x, T,T,x,T, x,x,T,T, x,x,x,x, x,x,x,x, x,T,T,T, x,T,T,x, T,x,x,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,T,T,T, T,T,T,T, T,x,x,x, T,T,x,x},
+ {x,T,T,T, T,x,x,T, T,T,T,T, T,T,T,x, x,x,x,x, x,x,x,x, x,T,x,x, x,T,T,T, x,T,x,x, x,T,T,T, x,x,x,x, x,T,T,x, T,T,x,T, x,x,T,T, x,x,x,x, x,T,x,x, x,T,T,T, x,T,T,x, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,x,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T, x,T,T,T, T,T,T,T, T,x,x,x, T,T,x,x},
+ {x,T,T,T, T,x,T,x, x,T,x,T, x,x,x,x, x,x,x,x, x,x,x,x, x,T,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,T,T, T,T,x,T, x,x,x,x, x,x,T,x, x,x,x,x, T,x,T,x, T,x,x,x, x,x,T,T, x,T,x,x, T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,T, x,T,x,x, T,T,T,T, T,T,T,x, x,T,T,T, x,x,x,x}
};
} // end Parser
@@ -3734,28 +3827,28 @@ public class Errors {
case 9: s = "lbrace expected"; break;
case 10: s = "rbrace expected"; break;
case 11: s = "openparen expected"; break;
- case 12: s = "star expected"; break;
- case 13: s = "notIn expected"; break;
- case 14: s = "\"include\" expected"; break;
- case 15: s = "\"abstract\" expected"; break;
- case 16: s = "\"module\" expected"; break;
- case 17: s = "\"refines\" expected"; break;
- case 18: s = "\"import\" expected"; break;
- case 19: s = "\"opened\" expected"; break;
- case 20: s = "\"=\" expected"; break;
- case 21: s = "\"as\" expected"; break;
- case 22: s = "\"default\" expected"; break;
- case 23: s = "\"class\" expected"; break;
- case 24: s = "\"ghost\" expected"; break;
- case 25: s = "\"static\" expected"; break;
- case 26: s = "\"datatype\" expected"; break;
- case 27: s = "\"codatatype\" expected"; break;
- case 28: s = "\"|\" expected"; break;
- case 29: s = "\"var\" expected"; break;
- case 30: s = "\",\" expected"; break;
- case 31: s = "\"type\" expected"; break;
- case 32: s = "\"==\" expected"; break;
- case 33: s = "\")\" expected"; break;
+ case 12: s = "closeparen expected"; break;
+ case 13: s = "star expected"; break;
+ case 14: s = "notIn expected"; break;
+ case 15: s = "\"include\" expected"; break;
+ case 16: s = "\"abstract\" expected"; break;
+ case 17: s = "\"module\" expected"; break;
+ case 18: s = "\"refines\" expected"; break;
+ case 19: s = "\"import\" expected"; break;
+ case 20: s = "\"opened\" expected"; break;
+ case 21: s = "\"=\" expected"; break;
+ case 22: s = "\"as\" expected"; break;
+ case 23: s = "\"default\" expected"; break;
+ case 24: s = "\"class\" expected"; break;
+ case 25: s = "\"ghost\" expected"; break;
+ case 26: s = "\"static\" expected"; break;
+ case 27: s = "\"datatype\" expected"; break;
+ case 28: s = "\"codatatype\" expected"; break;
+ case 29: s = "\"|\" expected"; break;
+ case 30: s = "\"var\" expected"; break;
+ case 31: s = "\",\" expected"; break;
+ case 32: s = "\"type\" expected"; break;
+ case 33: s = "\"==\" expected"; break;
case 34: s = "\"iterator\" expected"; break;
case 35: s = "\"yields\" expected"; break;
case 36: s = "\"returns\" expected"; break;
@@ -3909,48 +4002,51 @@ public class Errors {
case 184: s = "invalid IfStmt"; break;
case 185: s = "invalid WhileStmt"; break;
case 186: s = "invalid WhileStmt"; break;
- case 187: s = "invalid ForallStmt"; break;
+ case 187: s = "invalid MatchStmt"; break;
case 188: s = "invalid ForallStmt"; break;
- case 189: s = "this symbol not expected in ModifyStmt"; break;
- case 190: s = "invalid ModifyStmt"; break;
- case 191: s = "invalid ReturnStmt"; break;
- case 192: s = "invalid Rhs"; break;
- case 193: s = "invalid Lhs"; break;
- case 194: s = "invalid Guard"; break;
- case 195: s = "this symbol not expected in LoopSpec"; break;
+ case 189: s = "invalid ForallStmt"; break;
+ case 190: s = "this symbol not expected in ModifyStmt"; break;
+ case 191: s = "invalid ModifyStmt"; break;
+ case 192: s = "invalid ReturnStmt"; break;
+ case 193: s = "invalid Rhs"; break;
+ case 194: s = "invalid Lhs"; break;
+ case 195: s = "invalid Guard"; break;
case 196: s = "this symbol not expected in LoopSpec"; break;
case 197: s = "this symbol not expected in LoopSpec"; break;
case 198: s = "this symbol not expected in LoopSpec"; break;
case 199: s = "this symbol not expected in LoopSpec"; break;
- case 200: s = "this symbol not expected in Invariant"; break;
- case 201: s = "invalid AttributeArg"; break;
- case 202: s = "invalid CalcOp"; break;
- case 203: s = "invalid EquivOp"; break;
- case 204: s = "invalid ImpliesOp"; break;
- case 205: s = "invalid ExpliesOp"; break;
- case 206: s = "invalid AndOp"; break;
- case 207: s = "invalid OrOp"; break;
- case 208: s = "invalid RelOp"; break;
- case 209: s = "invalid AddOp"; break;
- case 210: s = "invalid UnaryExpression"; break;
+ case 200: s = "this symbol not expected in LoopSpec"; break;
+ case 201: s = "this symbol not expected in Invariant"; break;
+ case 202: s = "invalid AttributeArg"; break;
+ case 203: s = "invalid CalcOp"; break;
+ case 204: s = "invalid EquivOp"; break;
+ case 205: s = "invalid ImpliesOp"; break;
+ case 206: s = "invalid ExpliesOp"; break;
+ case 207: s = "invalid AndOp"; break;
+ case 208: s = "invalid OrOp"; break;
+ case 209: s = "invalid RelOp"; break;
+ case 210: s = "invalid AddOp"; break;
case 211: s = "invalid UnaryExpression"; break;
- case 212: s = "invalid MulOp"; break;
- case 213: s = "invalid NegOp"; break;
- case 214: s = "invalid EndlessExpression"; break;
- case 215: s = "invalid Suffix"; break;
+ case 212: s = "invalid UnaryExpression"; break;
+ case 213: s = "invalid MulOp"; break;
+ case 214: s = "invalid NegOp"; break;
+ case 215: s = "invalid EndlessExpression"; break;
case 216: s = "invalid Suffix"; break;
case 217: s = "invalid Suffix"; break;
- case 218: s = "invalid DisplayExpr"; break;
- case 219: s = "invalid MultiSetExpr"; break;
- case 220: s = "invalid ConstAtomExpression"; break;
- case 221: s = "invalid Nat"; break;
- case 222: s = "invalid QSep"; break;
- case 223: s = "invalid QuantifierGuts"; break;
- case 224: s = "invalid StmtInExpr"; break;
- case 225: s = "invalid LetExpr"; break;
- case 226: s = "invalid CasePattern"; break;
- case 227: s = "invalid Forall"; break;
- case 228: s = "invalid Exists"; break;
+ case 218: s = "invalid Suffix"; break;
+ case 219: s = "invalid DisplayExpr"; break;
+ case 220: s = "invalid MultiSetExpr"; break;
+ case 221: s = "invalid ConstAtomExpression"; break;
+ case 222: s = "invalid Nat"; break;
+ case 223: s = "invalid ParensExpression"; break;
+ case 224: s = "invalid QSep"; break;
+ case 225: s = "invalid MatchExpression"; break;
+ case 226: s = "invalid QuantifierGuts"; break;
+ case 227: s = "invalid StmtInExpr"; break;
+ case 228: s = "invalid LetExpr"; break;
+ case 229: s = "invalid CasePattern"; break;
+ case 230: s = "invalid Forall"; break;
+ case 231: s = "invalid Exists"; break;
default: s = "error " + n; break;
}
diff --git a/Source/Dafny/Printer.cs b/Source/Dafny/Printer.cs
index 706f751c..3a0ab21c 100644
--- a/Source/Dafny/Printer.cs
+++ b/Source/Dafny/Printer.cs
@@ -48,7 +48,7 @@ namespace Microsoft.Dafny {
Contract.Requires(expr != null);
using (var wr = new System.IO.StringWriter()) {
var pr = new Printer(wr);
- pr.PrintExtendedExpr(expr, 0, true, false);
+ pr.PrintExtendedExpr(expr, 0, true, false);
return wr.ToString();
}
}
@@ -565,7 +565,7 @@ namespace Microsoft.Dafny {
}
}
- internal void PrintSpec(string kind, List<MaybeFreeExpression> ee, int indent) {
+ internal void PrintSpec(string kind, List<MaybeFreeExpression> ee, int indent, bool newLine = true) {
Contract.Requires(kind != null);
Contract.Requires(ee != null);
foreach (MaybeFreeExpression e in ee)
@@ -582,7 +582,11 @@ namespace Microsoft.Dafny {
wr.Write(" ");
PrintExpression(e.E, true);
- wr.WriteLine(";");
+ if (newLine) {
+ wr.WriteLine(";");
+ } else {
+ wr.Write(";");
+ }
}
}
@@ -735,10 +739,12 @@ namespace Microsoft.Dafny {
wr.Write(" ");
} else {
wr.WriteLine();
- PrintSpec("ensures", s.Ens, indent + IndentAmount);
+ PrintSpec("ensures", s.Ens, indent + IndentAmount, s.Body != null);
Indent(indent);
}
- PrintStatement(s.Body, indent);
+ if (s.Body != null) {
+ PrintStatement(s.Body, indent);
+ }
} else if (stmt is ModifyStmt) {
var s = (ModifyStmt)stmt;
@@ -789,9 +795,12 @@ namespace Microsoft.Dafny {
MatchStmt s = (MatchStmt)stmt;
wr.Write("match ");
PrintExpression(s.Source, false);
- wr.WriteLine(" {");
- int caseInd = indent + IndentAmount;
+ if (s.UsesOptionalBraces) {
+ wr.Write(" {");
+ }
+ int caseInd = indent + (s.UsesOptionalBraces ? IndentAmount : 0);
foreach (MatchCaseStmt mc in s.Cases) {
+ wr.WriteLine();
Indent(caseInd);
wr.Write("case {0}", mc.Id);
if (mc.Arguments.Count != 0) {
@@ -802,15 +811,18 @@ namespace Microsoft.Dafny {
}
wr.Write(")");
}
- wr.WriteLine(" =>");
+ wr.Write(" =>");
foreach (Statement bs in mc.Body) {
+ wr.WriteLine();
Indent(caseInd + IndentAmount);
PrintStatement(bs, caseInd + IndentAmount);
- wr.WriteLine();
}
}
- Indent(indent);
- wr.Write("}");
+ if (s.UsesOptionalBraces) {
+ wr.WriteLine();
+ Indent(indent);
+ wr.Write("}");
+ }
} else if (stmt is ConcreteUpdateStatement) {
var s = (ConcreteUpdateStatement)stmt;
@@ -1082,15 +1094,18 @@ namespace Microsoft.Dafny {
} else if (expr is MatchExpr) {
var e = (MatchExpr)expr;
Indent(indent);
- var parensNeeded = !isRightmost;
+ var parensNeeded = !isRightmost && !e.UsesOptionalBraces;
if (parensNeeded) { wr.Write("("); }
wr.Write("match ");
PrintExpression(e.Source, isRightmost && e.Cases.Count == 0, false);
- if (parensNeeded && e.Cases.Count == 0) { wr.WriteLine(")"); } else { wr.WriteLine(); }
+ if (e.UsesOptionalBraces) { wr.WriteLine(" {"); }
+ else if (parensNeeded && e.Cases.Count == 0) { wr.WriteLine(")"); }
+ else { wr.WriteLine(); }
int i = 0;
+ int ind = indent + (e.UsesOptionalBraces ? IndentAmount : 0);
foreach (var mc in e.Cases) {
bool isLastCase = i == e.Cases.Count - 1;
- Indent(indent);
+ Indent(ind);
wr.Write("case {0}", mc.Id);
if (mc.Arguments.Count != 0) {
string sep = "(";
@@ -1101,9 +1116,13 @@ namespace Microsoft.Dafny {
wr.Write(")");
}
wr.WriteLine(" =>");
- PrintExtendedExpr(mc.Body, indent + IndentAmount, isLastCase, isLastCase && (parensNeeded || endWithCloseParen));
+ PrintExtendedExpr(mc.Body, ind + IndentAmount, isLastCase, isLastCase && (parensNeeded || endWithCloseParen));
i++;
}
+ if (e.UsesOptionalBraces) {
+ Indent(indent);
+ wr.WriteLine("}");
+ }
} else if (expr is ParensExpression) {
PrintExtendedExpr(((ParensExpression)expr).E, indent, isRightmost, endWithCloseParen);
} else {
@@ -1184,9 +1203,16 @@ namespace Microsoft.Dafny {
wr.Write(((IdentifierExpr)expr).Name);
} else if (expr is DatatypeValue) {
- DatatypeValue dtv = (DatatypeValue)expr;
- wr.Write("#{0}.{1}", dtv.DatatypeName, dtv.MemberName);
- if (dtv.Arguments.Count != 0) {
+ var dtv = (DatatypeValue)expr;
+ bool printParens;
+ if (dtv.MemberName == BuiltIns.TupleTypeCtorName) {
+ // we're looking at a tuple, whose printed constructor name is essentially the empty string
+ printParens = true;
+ } else {
+ wr.Write("{0}.{1}", dtv.DatatypeName, dtv.MemberName);
+ printParens = dtv.Arguments.Count != 0;
+ }
+ if (printParens) {
wr.Write("(");
PrintExpressionList(dtv.Arguments, false);
wr.Write(")");
@@ -1651,10 +1677,11 @@ namespace Microsoft.Dafny {
} else if (expr is MatchExpr) {
var e = (MatchExpr)expr;
- var parensNeeded = !isRightmost;
+ var parensNeeded = !isRightmost && !e.UsesOptionalBraces;
if (parensNeeded) { wr.Write("("); }
wr.Write("match ");
PrintExpression(e.Source, isRightmost && e.Cases.Count == 0, !parensNeeded && isFollowedBySemicolon);
+ if (e.UsesOptionalBraces) { wr.Write(" {"); }
int i = 0;
foreach (var mc in e.Cases) {
bool isLastCase = i == e.Cases.Count - 1;
@@ -1671,7 +1698,8 @@ namespace Microsoft.Dafny {
PrintExpression(mc.Body, isRightmost && isLastCase, !parensNeeded && isFollowedBySemicolon);
i++;
}
- if (parensNeeded) { wr.Write(")"); }
+ if (e.UsesOptionalBraces) { wr.Write(" }"); }
+ else if (parensNeeded) { wr.Write(")"); }
} else if (expr is BoxingCastExpr) {
// this is not expected for a parsed program, but we may be called for /trace purposes in the translator
diff --git a/Source/Dafny/Resolver.cs b/Source/Dafny/Resolver.cs
index c1cbd61a..7115a95f 100644
--- a/Source/Dafny/Resolver.cs
+++ b/Source/Dafny/Resolver.cs
@@ -192,16 +192,17 @@ namespace Microsoft.Dafny
var refinementTransformer = new RefinementTransformer(this, AdditionalInformationReporter, prog);
rewriters.Add(refinementTransformer);
rewriters.Add(new AutoContractsRewriter());
- var opaqueRewriter = new OpaqueFunctionRewriter();
+ var opaqueRewriter = new OpaqueFunctionRewriter();
rewriters.Add(new AutoReqFunctionRewriter(this, opaqueRewriter));
rewriters.Add(opaqueRewriter);
systemNameInfo = RegisterTopLevelDecls(prog.BuiltIns.SystemModule, false);
+ prog.CompileModules.Add(prog.BuiltIns.SystemModule);
foreach (var decl in sortedDecls) {
if (decl is LiteralModuleDecl) {
// The declaration is a literal module, so it has members and such that we need
// to resolve. First we do refinement transformation. Then we construct the signature
- // of the module. This is the public, externally visible signature. Then we add in
+ // of the module. This is the public, externally visible signature. Then we add in
// everything that the system defines, as well as any "import" (i.e. "opened" modules)
// directives (currently not supported, but this is where we would do it.) This signature,
// which is only used while resolving the members of the module is stored in the (basically)
@@ -894,7 +895,7 @@ namespace Microsoft.Dafny
formals.AddRange(cop.Formals.ConvertAll(cloner.CloneFormal));
List<TypeParameter> tyvars = cop.TypeArgs.ConvertAll(cloner.CloneTypeParam);
-
+
/*
Dictionary<TypeParameter, Type> su = new Dictionary<TypeParameter, Type>();
for (int i = 0; i < tyvars.Count; i++) {
@@ -907,12 +908,12 @@ namespace Microsoft.Dafny
// create prefix predicate
cop.PrefixPredicate = new PrefixPredicate(cop.tok, extraName, cop.IsStatic,
tyvars, cop.OpenParen, k, formals,
- cop.Req.ConvertAll(cloner.CloneExpr),
- cop.Reads.ConvertAll(cloner.CloneFrameExpr),
+ cop.Req.ConvertAll(cloner.CloneExpr),
+ cop.Reads.ConvertAll(cloner.CloneFrameExpr),
cop.Ens.ConvertAll(cloner.CloneExpr),
new Specification<Expression>(new List<Expression>() { new IdentifierExpr(cop.tok, k.Name) }, null),
- cop.Body,
- null,
+ cop.Body,
+ null,
cop);
extraMember = cop.PrefixPredicate;
// In the call graph, add an edge from P# to P, since this will have the desired effect of detecting unwanted cycles.
@@ -1035,6 +1036,9 @@ namespace Microsoft.Dafny
if (d is ArbitraryTypeDecl) {
var dd = (ArbitraryTypeDecl)d;
return new ArbitraryTypeDecl(dd.tok, dd.Name, m, dd.EqualitySupport, null);
+ } else if (d is TupleTypeDecl) {
+ var dd = (TupleTypeDecl)d;
+ return new TupleTypeDecl(dd.Dims, dd.Module);
} else if (d is IndDatatypeDecl) {
var dd = (IndDatatypeDecl)d;
var tps = dd.TypeArgs.ConvertAll(CloneTypeParam);
@@ -1353,7 +1357,7 @@ namespace Microsoft.Dafny
} else if (expr is MatchExpr) {
var e = (MatchExpr)expr;
return new MatchExpr(e.tok, CloneExpr(e.Source),
- e.Cases.ConvertAll(c => new MatchCaseExpr(c.tok, c.Id, c.Arguments.ConvertAll(CloneBoundVar), CloneExpr(c.Body))));
+ e.Cases.ConvertAll(c => new MatchCaseExpr(c.tok, c.Id, c.Arguments.ConvertAll(CloneBoundVar), CloneExpr(c.Body))), e.UsesOptionalBraces);
} else if (expr is NegationExpression) {
var e = (NegationExpression)expr;
@@ -1949,7 +1953,7 @@ namespace Microsoft.Dafny
foreach (var p in e.TypeArgumentSubstitutions) {
if (p.Value.Normalize() is TypeProxy) {
Error(e.tok, "type variable '{0}' in the function call to '{1}' could not determined{2}", p.Key.Name, e.Name,
- (e.Name.Contains("reveal_") || e.Name.Contains("_FULL"))
+ (e.Name.Contains("reveal_") || e.Name.Contains("_FULL"))
? ". If you are making an opaque function, make sure that the function can be called."
: ""
);
@@ -1985,7 +1989,7 @@ namespace Microsoft.Dafny
return CheckTypeIsDetermined(tok, ((MapType)t).Range, what, aggressive) &&
CheckTypeIsDetermined(tok, ((MapType)t).Domain, what, aggressive);
} else if (aggressive && t is CollectionType) {
- return CheckTypeIsDetermined(tok, ((CollectionType)t).Arg, what, aggressive);
+ return CheckTypeIsDetermined(tok, ((CollectionType)t).Arg, what, aggressive);
} else if (aggressive && t is UserDefinedType) {
return t.TypeArgs.All(rg => CheckTypeIsDetermined(tok, rg, what, aggressive));
} else {
@@ -2011,7 +2015,7 @@ namespace Microsoft.Dafny
/// Note, the current implementation is rather conservative in its analysis; upon need, the
/// algorithm could be improved.
/// In the current implementation, "enclosingMethod" is not allowed to be a mutually recursive method.
- ///
+ ///
/// The incoming value of "tailCall" is not used, but it's nevertheless a 'ref' parameter to allow the
/// body to return the incoming value or to omit assignments to it.
/// If the return value is CanBeFollowedByAnything, "tailCall" is unchanged.
@@ -2141,7 +2145,10 @@ namespace Microsoft.Dafny
}
} else if (stmt is ForallStmt) {
var s = (ForallStmt)stmt;
- var status = CheckTailRecursive(s.Body, enclosingMethod, ref tailCall, reportErrors);
+ var status = TailRecursionStatus.NotTailRecursive;
+ if (s.Body != null) {
+ status = CheckTailRecursive(s.Body, enclosingMethod, ref tailCall, reportErrors);
+ }
if (status != TailRecursionStatus.CanBeFollowedByAnything) {
if (status == TailRecursionStatus.NotTailRecursive) {
// an error has already been reported
@@ -2848,13 +2855,13 @@ namespace Microsoft.Dafny
/// datatype has some value that can be constructed from datatypes in lower stratospheres only.
/// The algorithm used here is quadratic in the number of datatypes in the SCC. Since that number is
/// deemed to be rather small, this seems okay.
- ///
+ ///
/// As a side effect of this checking, the DefaultCtor field is filled in (for every inductive datatype
/// that passes the check). It may be that several constructors could be used as the default, but
/// only the first one encountered as recorded. This particular choice is slightly more than an
/// implementation detail, because it affects how certain cycles among inductive datatypes (having
/// to do with the types used to instantiate type parameters of datatypes) are used.
- ///
+ ///
/// The role of the SCC here is simply to speed up this method. It would still be correct if the
/// equivalence classes in the given SCC were unions of actual SCC's. In particular, this method
/// would still work if "dependencies" consisted of one large SCC containing all the inductive
@@ -3079,7 +3086,7 @@ namespace Microsoft.Dafny
if (!allTypeParameters.Push(tp.Name, tp) && emitErrors) {
Error(tp, "Duplicate type-parameter name: {0}", tp.Name);
}
- }
+ }
}
/// <summary>
@@ -3302,8 +3309,9 @@ namespace Microsoft.Dafny
void ResolveCtorSignature(DatatypeCtor ctor, List<TypeParameter> dtTypeArguments) {
Contract.Requires(ctor != null);
Contract.Requires(dtTypeArguments != null);
+ ResolveTypeOption option = dtTypeArguments.Count == 0 ? new ResolveTypeOption(ctor) : new ResolveTypeOption(ResolveTypeOptionEnum.AllowPrefix);
foreach (Formal p in ctor.Formals) {
- ResolveType(p.tok, p.Type, ResolveTypeOptionEnum.AllowExact, dtTypeArguments);
+ ResolveType(p.tok, p.Type, option, dtTypeArguments);
}
}
@@ -3551,7 +3559,7 @@ namespace Microsoft.Dafny
iter.Member_MoveNext.Decreases.Attributes = iter.Decreases.Attributes;
}
- // Like the ResolveTypeOptionEnum, but iff the case of AllowPrefixExtend, it also
+ // Like the ResolveTypeOptionEnum, but iff the case of AllowPrefixExtend, it also
// contains a pointer to its Parent class, to fill in default type parameters properly.
public class ResolveTypeOption
{
@@ -3592,10 +3600,6 @@ namespace Microsoft.Dafny
/// </summary>
InferTypeProxies,
/// <summary>
- /// if exactly defaultTypeArguments.Count type arguments are needed, use defaultTypeArguments
- /// </summary>
- AllowExact,
- /// <summary>
/// if at most defaultTypeArguments.Count type arguments are needed, use a prefix of defaultTypeArguments
/// </summary>
AllowPrefix,
@@ -3610,7 +3614,7 @@ namespace Microsoft.Dafny
/// See ResolveTypeOption for a description of the option/defaultTypeArguments parameters.
/// </summary>
public void ResolveType(IToken tok, Type type, ResolveTypeOptionEnum eopt, List<TypeParameter> defaultTypeArguments) {
- Contract.Requires(eopt != ResolveTypeOptionEnum.AllowPrefixExtend);
+ Contract.Requires(eopt != ResolveTypeOptionEnum.AllowPrefixExtend);
ResolveType(tok, type, new ResolveTypeOption(eopt), defaultTypeArguments);
}
@@ -3717,7 +3721,7 @@ namespace Microsoft.Dafny
} else {
Error(t.tok, "Type parameter expects no type arguments: {0}", t.Name);
}
- } else if (t.ResolvedClass == null) { // this test is because 'array' is already resolved; TODO: an alternative would be to pre-populate 'classes' with built-in references types like 'array' (and perhaps in the future 'string')
+ } else {
TopLevelDecl d = null;
int j;
@@ -3797,9 +3801,12 @@ namespace Microsoft.Dafny
for (int i = 0; i < n; i++) {
typeArgs.Add(new InferredTypeProxy());
}
+ /*
} else if (option.Opt == ResolveTypeOptionEnum.AllowExact && defaultTypeArguments.Count != n) {
// the number of default arguments is not exactly what we need, so don't add anything
} else if (option.Opt == ResolveTypeOptionEnum.AllowPrefix && defaultTypeArguments.Count < n) {
+ */
+ } else if (option.Opt == ResolveTypeOptionEnum.AllowPrefix && defaultTypeArguments.Count < n) {
// there aren't enough default arguments, so don't do anything
} else {
// we'll add arguments
@@ -4074,7 +4081,7 @@ namespace Microsoft.Dafny
// set(Arg) or multiset(Arg) or seq(Arg) or map(Arg, anyRange)
// pb is:
// seq(Arg) or multiset(Arg) or map(Domain, Arg), or
- // if AllowArray, array(Arg)
+ // if AllowArray, array(Arg)
// Their intersection is:
if (ib.AllowArray) {
var c = new IndexableTypeProxy(ib.Domain, ib.Range, ib.Arg, false);
@@ -4587,14 +4594,16 @@ namespace Microsoft.Dafny
}
s.IsGhost = bodyMustBeSpecOnly;
- // clear the labels for the duration of checking the body, because break statements are not allowed to leave a forall statement
- var prevLblStmts = labeledStatements;
- var prevLoopStack = loopStack;
- labeledStatements = new Scope<Statement>();
- loopStack = new List<Statement>();
- ResolveStatement(s.Body, bodyMustBeSpecOnly, codeContext);
- labeledStatements = prevLblStmts;
- loopStack = prevLoopStack;
+ if (s.Body != null) {
+ // clear the labels for the duration of checking the body, because break statements are not allowed to leave a forall statement
+ var prevLblStmts = labeledStatements;
+ var prevLoopStack = loopStack;
+ labeledStatements = new Scope<Statement>();
+ loopStack = new List<Statement>();
+ ResolveStatement(s.Body, bodyMustBeSpecOnly, codeContext);
+ labeledStatements = prevLblStmts;
+ loopStack = prevLoopStack;
+ }
scope.PopMarker();
if (prevErrorCount == ErrorCount) {
@@ -4631,9 +4640,11 @@ namespace Microsoft.Dafny
}
}
}
- CheckForallStatementBodyRestrictions(s.Body, s.Kind);
+ if (s.Body != null) {
+ CheckForallStatementBodyRestrictions(s.Body, s.Kind);
+ }
}
-
+
} else if (stmt is ModifyStmt) {
var s = (ModifyStmt)stmt;
ResolveAttributes(s.Mod.Attributes, true, codeContext);
@@ -4662,14 +4673,14 @@ namespace Microsoft.Dafny
if (!UnifyTypes(e0.Type, e1.Type)) {
Error(e1, "all lines in a calculation must have the same type (got {0} after {1})", e1.Type, e0.Type);
} else {
- var step = s.StepOps[i - 1].StepExpr(e0, e1); // Use custom line operator
+ var step = s.StepOps[i - 1].StepExpr(e0, e1); // Use custom line operator
ResolveExpression(step, true, codeContext);
- s.Steps.Add(step);
+ s.Steps.Add(step);
}
e0 = e1;
}
}
-
+
// clear the labels for the duration of checking the hints, because break statements are not allowed to leave a forall statement
var prevLblStmts = labeledStatements;
var prevLoopStack = loopStack;
@@ -4680,7 +4691,7 @@ namespace Microsoft.Dafny
CheckHintRestrictions(h);
}
labeledStatements = prevLblStmts;
- loopStack = prevLoopStack;
+ loopStack = prevLoopStack;
}
if (prevErrorCount == ErrorCount && s.Lines.Count > 0) {
@@ -4690,8 +4701,8 @@ namespace Microsoft.Dafny
s.Result = CalcStmt.DefaultOp.StepExpr(Expression.CreateIntLiteral(s.Tok, 0), Expression.CreateIntLiteral(s.Tok, 0));
}
ResolveExpression(s.Result, true, codeContext);
- Contract.Assert(s.Result != null);
- Contract.Assert(prevErrorCount != ErrorCount || s.Steps.Count == s.Hints.Count);
+ Contract.Assert(s.Result != null);
+ Contract.Assert(prevErrorCount != ErrorCount || s.Steps.Count == s.Hints.Count);
} else if (stmt is MatchStmt) {
MatchStmt s = (MatchStmt)stmt;
@@ -5417,7 +5428,7 @@ namespace Microsoft.Dafny
Contract.Assert(false); // unexpected kind
break;
}
-
+
} else if (stmt is CalcStmt) {
// cool
@@ -5536,7 +5547,7 @@ namespace Microsoft.Dafny
Contract.Assert(false); // unexpected kind
break;
}
-
+
} else if (stmt is CalcStmt) {
var s = (CalcStmt)stmt;
foreach (var h in s.Hints) {
@@ -6080,10 +6091,10 @@ namespace Microsoft.Dafny
}
else if (e.Seq.Type is UserDefinedType && ((UserDefinedType)e.Seq.Type).IsDatatype)
- {
+ {
DatatypeDecl dt = ((UserDefinedType)e.Seq.Type).AsDatatype;
- if (!(e.Index is IdentifierSequence || (e.Index is LiteralExpr && ((LiteralExpr)e.Index).Value is BigInteger)))
+ if (!(e.Index is IdentifierSequence || (e.Index is LiteralExpr && ((LiteralExpr)e.Index).Value is BigInteger)))
{
Error(expr, "datatype updates must be to datatype destructors");
} else {
@@ -6464,7 +6475,7 @@ namespace Microsoft.Dafny
bool _val = true;
bool typeQuantifier = Attributes.ContainsBool(e.Attributes, "typeQuantifier", ref _val);
allTypeParameters.PushMarker();
- ResolveTypeParameters(e.TypeArgs, true, e);
+ ResolveTypeParameters(e.TypeArgs, true, e);
scope.PushMarker();
foreach (BoundVar v in e.BoundVars) {
if (!scope.Push(v.Name, v)) {
@@ -7118,7 +7129,7 @@ namespace Microsoft.Dafny
// ----- root is a local variable, parameter, or bound variable
r = new IdentifierExpr(id, id.val);
ResolveExpression(r, twoState, codeContext);
- r = ResolveSuffix(r, e, 1, twoState, codeContext, allowMethodCall, out call);
+ r = ResolveSuffix(r, e, 1, twoState, codeContext, allowMethodCall, out call);
} else if (moduleInfo.TopLevels.TryGetValue(id.val, out decl)) {
if (decl is AmbiguousTopLevelDecl) {
@@ -7126,10 +7137,10 @@ namespace Microsoft.Dafny
} else 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) {
- // in
+ // in
// datatype Id = Id
// you cannot refer to the constructor, instead this error message is thrown:
- // (bug?)
+ // (bug?)
Error(id, "name of type ('{0}') is used as a function", id.val);
// resolve the arguments nonetheless
foreach (var arg in e.Arguments) {
@@ -7322,7 +7333,7 @@ namespace Microsoft.Dafny
if (p < e.Tokens.Count) {
Contract.Assert(e.Arguments != null);
-
+
bool itIsAMethod = false;
if (allowMethodCall) {
var udt = r.Type.Normalize() as UserDefinedType;
diff --git a/Source/Dafny/Scanner.cs b/Source/Dafny/Scanner.cs
index 4b473e9d..87dee5aa 100644
--- a/Source/Dafny/Scanner.cs
+++ b/Source/Dafny/Scanner.cs
@@ -255,21 +255,21 @@ public class Scanner {
for (int i = 92; i <= 92; ++i) start[i] = 1;
for (int i = 95; i <= 95; ++i) start[i] = 1;
for (int i = 98; i <= 122; ++i) start[i] = 1;
- for (int i = 49; i <= 57; ++i) start[i] = 21;
+ for (int i = 49; i <= 57; ++i) start[i] = 22;
for (int i = 34; i <= 34; ++i) start[i] = 11;
- start[97] = 22;
- start[48] = 23;
+ start[97] = 23;
+ start[48] = 24;
start[58] = 64;
start[59] = 13;
start[123] = 14;
start[125] = 15;
start[40] = 16;
- start[42] = 17;
+ start[41] = 17;
+ start[42] = 18;
start[33] = 65;
start[61] = 66;
start[124] = 67;
- start[44] = 30;
- start[41] = 31;
+ start[44] = 31;
start[46] = 68;
start[60] = 69;
start[62] = 70;
@@ -491,21 +491,21 @@ public class Scanner {
void CheckLiteral() {
switch (t.val) {
- case "include": t.kind = 14; break;
- case "abstract": t.kind = 15; break;
- case "module": t.kind = 16; break;
- case "refines": t.kind = 17; break;
- case "import": t.kind = 18; break;
- case "opened": t.kind = 19; break;
- case "as": t.kind = 21; break;
- case "default": t.kind = 22; break;
- case "class": t.kind = 23; break;
- case "ghost": t.kind = 24; break;
- case "static": t.kind = 25; break;
- case "datatype": t.kind = 26; break;
- case "codatatype": t.kind = 27; break;
- case "var": t.kind = 29; break;
- case "type": t.kind = 31; break;
+ case "include": t.kind = 15; break;
+ case "abstract": t.kind = 16; break;
+ case "module": t.kind = 17; break;
+ case "refines": t.kind = 18; break;
+ case "import": t.kind = 19; break;
+ case "opened": t.kind = 20; break;
+ case "as": t.kind = 22; break;
+ case "default": t.kind = 23; break;
+ case "class": t.kind = 24; break;
+ case "ghost": t.kind = 25; break;
+ case "static": t.kind = 26; break;
+ case "datatype": t.kind = 27; break;
+ case "codatatype": t.kind = 28; break;
+ case "var": t.kind = 30; break;
+ case "type": t.kind = 32; break;
case "iterator": t.kind = 34; break;
case "yields": t.kind = 35; break;
case "returns": t.kind = 36; break;
@@ -648,65 +648,65 @@ public class Scanner {
case 17:
{t.kind = 12; break;}
case 18:
- if (ch == 'n') {AddCh(); goto case 19;}
- else {goto case 0;}
+ {t.kind = 13; break;}
case 19:
- if (ch <= '&' || ch >= '(' && ch <= '/' || ch >= ':' && ch <= '>' || ch == '@' || ch == '[' || ch >= ']' && ch <= '^' || ch == '`' || ch >= '{' && ch <= 65535) {apx++; AddCh(); goto case 20;}
+ if (ch == 'n') {AddCh(); goto case 20;}
else {goto case 0;}
case 20:
+ if (ch <= '&' || ch >= '(' && ch <= '/' || ch >= ':' && ch <= '>' || ch == '@' || ch == '[' || ch >= ']' && ch <= '^' || ch == '`' || ch >= '{' && ch <= 65535) {apx++; AddCh(); goto case 21;}
+ else {goto case 0;}
+ case 21:
{
tlen -= apx;
SetScannerBehindT();
- t.kind = 13; break;}
- case 21:
+ t.kind = 14; break;}
+ case 22:
recEnd = pos; recKind = 2;
- if (ch >= '0' && ch <= '9') {AddCh(); goto case 21;}
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 22;}
else if (ch == '.') {AddCh(); goto case 9;}
else {t.kind = 2; break;}
- case 22:
+ case 23:
recEnd = pos; recKind = 1;
if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'q' || ch >= 's' && ch <= 'z') {AddCh(); goto case 2;}
- else if (ch == 'r') {AddCh(); goto case 25;}
+ else if (ch == 'r') {AddCh(); goto case 26;}
else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 23:
+ case 24:
recEnd = pos; recKind = 2;
- if (ch >= '0' && ch <= '9') {AddCh(); goto case 21;}
+ if (ch >= '0' && ch <= '9') {AddCh(); goto case 22;}
else if (ch == 'x') {AddCh(); goto case 7;}
else if (ch == '.') {AddCh(); goto case 9;}
else {t.kind = 2; break;}
- case 24:
+ case 25:
recEnd = pos; recKind = 1;
- if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 24;}
+ if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 25;}
else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 25:
+ case 26:
recEnd = pos; recKind = 1;
if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'q' || ch >= 's' && ch <= 'z') {AddCh(); goto case 3;}
- else if (ch == 'r') {AddCh(); goto case 26;}
+ else if (ch == 'r') {AddCh(); goto case 27;}
else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 26:
+ case 27:
recEnd = pos; recKind = 1;
if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'b' && ch <= 'z') {AddCh(); goto case 4;}
- else if (ch == 'a') {AddCh(); goto case 27;}
+ else if (ch == 'a') {AddCh(); goto case 28;}
else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 27:
+ case 28:
recEnd = pos; recKind = 1;
if (ch == 39 || ch >= '0' && ch <= '9' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'x' || ch == 'z') {AddCh(); goto case 5;}
- else if (ch == 'y') {AddCh(); goto case 28;}
+ else if (ch == 'y') {AddCh(); goto case 29;}
else {t.kind = 1; t.val = new String(tval, 0, tlen); CheckLiteral(); return t;}
- case 28:
+ case 29:
recEnd = pos; recKind = 5;
if (ch == 39 || ch == '0' || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 6;}
- else if (ch >= '1' && ch <= '9') {AddCh(); goto case 29;}
+ else if (ch >= '1' && ch <= '9') {AddCh(); goto case 30;}
else {t.kind = 5; break;}
- case 29:
+ case 30:
recEnd = pos; recKind = 5;
- if (ch == 39 || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 24;}
- else if (ch >= '0' && ch <= '9') {AddCh(); goto case 29;}
+ if (ch == 39 || ch == '?' || ch >= 'A' && ch <= 'Z' || ch == 92 || ch == '_' || ch >= 'a' && ch <= 'z') {AddCh(); goto case 25;}
+ else if (ch >= '0' && ch <= '9') {AddCh(); goto case 30;}
else {t.kind = 5; break;}
- case 30:
- {t.kind = 30; break;}
case 31:
- {t.kind = 33; break;}
+ {t.kind = 31; break;}
case 32:
{t.kind = 37; break;}
case 33:
@@ -780,18 +780,18 @@ public class Scanner {
else {t.kind = 7; break;}
case 65:
recEnd = pos; recKind = 107;
- if (ch == 'i') {AddCh(); goto case 18;}
+ if (ch == 'i') {AddCh(); goto case 19;}
else if (ch == '=') {AddCh(); goto case 41;}
else {t.kind = 107; break;}
case 66:
- recEnd = pos; recKind = 20;
+ recEnd = pos; recKind = 21;
if (ch == '=') {AddCh(); goto case 71;}
else if (ch == '>') {AddCh(); goto case 38;}
- else {t.kind = 20; break;}
+ else {t.kind = 21; break;}
case 67:
- recEnd = pos; recKind = 28;
+ recEnd = pos; recKind = 29;
if (ch == '|') {AddCh(); goto case 53;}
- else {t.kind = 28; break;}
+ else {t.kind = 29; break;}
case 68:
recEnd = pos; recKind = 61;
if (ch == '.') {AddCh(); goto case 72;}
@@ -805,9 +805,9 @@ public class Scanner {
if (ch == '=') {AddCh(); goto case 40;}
else {t.kind = 39; break;}
case 71:
- recEnd = pos; recKind = 32;
+ recEnd = pos; recKind = 33;
if (ch == '>') {AddCh(); goto case 47;}
- else {t.kind = 32; break;}
+ else {t.kind = 33; break;}
case 72:
recEnd = pos; recKind = 120;
if (ch == '.') {AddCh(); goto case 32;}
diff --git a/Source/Dafny/Translator.cs b/Source/Dafny/Translator.cs
index 548547d2..496633a7 100644
--- a/Source/Dafny/Translator.cs
+++ b/Source/Dafny/Translator.cs
@@ -18,6 +18,7 @@ namespace Microsoft.Dafny {
[NotDelayed]
public Translator() {
+ InsertChecksums = 0 < CommandLineOptions.Clo.VerifySnapshots;
Bpl.Program boogieProgram = ReadPrelude();
if (boogieProgram != null) {
sink = boogieProgram;
@@ -409,13 +410,13 @@ namespace Microsoft.Dafny {
var impl = decl as Implementation;
if (impl != null && impl.FindStringAttribute("checksum") == null)
{
- impl.AddAttribute("checksum", "dummy");
+ impl.AddAttribute("checksum", "stable");
}
var func = decl as Bpl.Function;
if (func != null && func.FindStringAttribute("checksum") == null)
{
- func.AddAttribute("checksum", "dummy");
+ func.AddAttribute("checksum", "stable");
}
}
}
@@ -2614,7 +2615,7 @@ namespace Microsoft.Dafny {
public void InsertUniqueIdForImplementation(Bpl.Declaration decl)
{
var impl = decl as Bpl.Implementation;
- var prefix = UniqueIdPrefix ?? decl.tok.filename;
+ var prefix = UniqueIdPrefix ?? System.Text.RegularExpressions.Regex.Replace(decl.tok.filename, @".v\d+.dfy", ".dfy");
if (impl != null && !string.IsNullOrEmpty(prefix))
{
decl.AddAttribute("id", prefix + ":" + impl.Name + ":0");
@@ -5858,15 +5859,33 @@ namespace Microsoft.Dafny {
// assume $HeapSucc(oldHeap, $Heap);
// (a)
// assume (forall<alpha> o: ref, F: Field alpha ::
+ // { $Heap[o,F] }
// $Heap[o,F] = oldHeap[o,F] ||
// (exists x,y :: Range(x,y) && o == E(x,y) && F = f));
- // assume (forall x,y :: Range ==> $Heap[ E[$Heap:=oldHeap], F] == G[$Heap:=oldHeap]);
+ // assume (forall x,y :: Range ==> $Heap[ E[$Heap:=oldHeap], F] == G[$Heap:=oldHeap]); (**)
// (b)
// assume (forall<alpha> o: ref, F: Field alpha ::
+ // { $Heap[o,F] }
// $Heap[o,F] = oldHeap[o,F] ||
// (exists x,y :: Range(x,y) && o == A(x,y) && F = Index(I0,I1,...)));
- // assume (forall x,y :: Range ==> $Heap[ A[$Heap:=oldHeap], Index(I0,I1,...)] == G[$Heap:=oldHeap]);
+ // assume (forall x,y :: Range ==> $Heap[ A[$Heap:=oldHeap], Index(I0,I1,...)] == G[$Heap:=oldHeap]); (**)
// }
+ //
+ // Note: In order to get a good trigger for the quantifiers (**), we will attempt to make the parameters
+ // that select from $Heap in the LHS of the equalities as plain as possible. This involves taking the inverse
+ // of an expression, which isn't always easy or possible, so we settle for handling some common cases. In
+ // particular, we change:
+ // 0: forall i | R(i) { F(i).f := E(i); }
+ // 1: forall i | R(i) { A[F(i)] := E(i); }
+ // 2: forall i | R(i) { F(i)[N] := E(i); }
+ // where f is some field and A and N are expressions that do not depend on i, into:
+ // 0: forall j | Q(j) { j.f := E(F-1(j)); }
+ // 1: forall j | Q(j) { A[j] := E(F-1(j)); }
+ // 2: forall j | Q(j) { j[N] := E(F-1(j)); }
+ // where we ensure that, for all i and j:
+ // R(i) && j == F(i) <==> Q(j) && F-1(j) == i
+ // If the transformation succeeds, we use, respectively, j.f, A[j], and j[N] (each evaluated in the new heap) as
+ // the trigger of the quantifier generated.
var substMap = SetupBoundVarsAsLocals(s.BoundVars, definedness, locals, etran);
Expression range = Substitute(s.Range, null, substMap);
@@ -5932,6 +5951,7 @@ namespace Microsoft.Dafny {
// Here comes:
// assume (forall<alpha> o: ref, f: Field alpha ::
+ // { $Heap[o,f] }
// $Heap[o,f] = oldHeap[o,f] ||
// (exists x,y :: Range(x,y)[$Heap:=oldHeap] &&
// o == Object(x,y)[$Heap:=oldHeap] && f == Field(x,y)[$Heap:=oldHeap]));
@@ -5940,8 +5960,8 @@ namespace Microsoft.Dafny {
Bpl.IdentifierExpr o = new Bpl.IdentifierExpr(s.Tok, oVar);
Bpl.BoundVariable fVar = new Bpl.BoundVariable(s.Tok, new Bpl.TypedIdent(s.Tok, "$f", predef.FieldName(s.Tok, alpha)));
Bpl.IdentifierExpr f = new Bpl.IdentifierExpr(s.Tok, fVar);
- Bpl.Expr heapOF = ReadHeap(s.Tok, etran.HeapExpr, o, f);
- Bpl.Expr oldHeapOF = ReadHeap(s.Tok, prevHeap, o, f);
+ Bpl.Expr heapOF = ExpressionTranslator.ReadHeap(s.Tok, etran.HeapExpr, o, f);
+ Bpl.Expr oldHeapOF = ExpressionTranslator.ReadHeap(s.Tok, prevHeap, o, f);
List<Variable> xBvars = new List<Variable>();
var xBody = etran.TrBoundVariables(s.BoundVars, xBvars);
xBody = BplAnd(xBody, prevEtran.TrExpr(s.Range));
@@ -5951,30 +5971,249 @@ namespace Microsoft.Dafny {
xBody = BplAnd(xBody, Bpl.Expr.Eq(f, xField));
Bpl.Expr xObjField = new Bpl.ExistsExpr(s.Tok, xBvars, xBody);
Bpl.Expr body = Bpl.Expr.Or(Bpl.Expr.Eq(heapOF, oldHeapOF), xObjField);
- Bpl.Expr qq = new Bpl.ForallExpr(s.Tok, new List<TypeVariable> { alpha }, new List<Variable> { oVar, fVar }, body);
+ var tr = new Trigger(s.Tok, true, new List<Expr>() { heapOF });
+ Bpl.Expr qq = new Bpl.ForallExpr(s.Tok, new List<TypeVariable> { alpha }, new List<Variable> { oVar, fVar }, null, tr, body);
updater.Add(new Bpl.AssumeCmd(s.Tok, qq));
if (s0.Rhs is ExprRhs) {
- // assume (forall x,y :: Range(x,y)[$Heap:=oldHeap] ==>
- // $Heap[ Object(x,y)[$Heap:=oldHeap], Field(x,y)[$Heap:=oldHeap] ] == G[$Heap:=oldHeap] ));
- xBvars = new List<Variable>();
- Bpl.Expr xAnte = etran.TrBoundVariables(s.BoundVars, xBvars);
- xAnte = BplAnd(xAnte, prevEtran.TrExpr(s.Range));
+ Expression Fi = null;
+ Func<Expression,Expression> lhsBuilder = null;
+ lhs = s0.Lhs.Resolved;
+ var i = s.BoundVars[0];
+ if (s.BoundVars.Count == 1) {
+ //var lhsContext = null;
+ // Detect the following cases:
+ // 0: forall i | R(i) { F(i).f := E(i); }
+ // 1: forall i | R(i) { A[F(i)] := E(i); }
+ // 2: forall i | R(i) { F(i)[N] := E(i); }
+ if (lhs is FieldSelectExpr) {
+ var ll = (FieldSelectExpr)lhs;
+ Fi = ll.Obj;
+ lhsBuilder = e => { var l = new FieldSelectExpr(ll.tok, e, ll.FieldName); l.Field = ll.Field; l.Type = ll.Type; return l; };
+ } else if (lhs is SeqSelectExpr) {
+ var ll = (SeqSelectExpr)lhs;
+ Contract.Assert(ll.SelectOne);
+ if (!ContainsFreeVariable(ll.Seq, false, i)) {
+ Fi = ll.E0;
+ lhsBuilder = e => { var l = new SeqSelectExpr(ll.tok, true, ll.Seq, e, null); l.Type = ll.Type; return l; };
+ } else if (!ContainsFreeVariable(ll.E0, false, i)) {
+ Fi = ll.Seq;
+ lhsBuilder = e => { var l = new SeqSelectExpr(ll.tok, true, e, ll.E0, null); l.Type = ll.Type; return l; };
+ }
+ }
+ }
var rhs = ((ExprRhs)s0.Rhs).Expr;
- var g = prevEtran.TrExpr(rhs);
- GetObjFieldDetails(s0.Lhs.Resolved, prevEtran, out xObj, out xField);
- var xHeapOF = ReadHeap(s.Tok, etran.HeapExpr, xObj, xField);
-
- Type lhsType;
- if (lhs is FieldSelectExpr) {
- lhsType = ((FieldSelectExpr)lhs).Type;
- } else {
- lhsType = null;
+ bool usedInversion = false;
+ if (Fi != null) {
+ var j = new BoundVar(i.tok, i.Name + "#inv", Fi.Type);
+ var jj = Expression.CreateIdentExpr(j);
+ var jList = new List<BoundVar>() { j };
+ var vals = InvertExpression(i, j, s.Range, Fi);
+#if DEBUG_PRINT
+ Console.WriteLine("DEBUG: Trying to invert:");
+ Console.WriteLine("DEBUG: " + Printer.ExprToString(s.Range) + " && " + j.Name + " == " + Printer.ExprToString(Fi));
+ if (vals == null) {
+ Console.WriteLine("DEBUG: Can't");
+ } else {
+ Console.WriteLine("DEBUG: The inverse is the disjunction of the following:");
+ foreach (var val in vals) {
+ Console.WriteLine("DEBUG: " + Printer.ExprToString(val.Range) + " && " + Printer.ExprToString(val.FInverse) + " == " + i.Name);
+ }
+ }
+#endif
+ if (vals != null) {
+ foreach (var val in vals) {
+ qq = TrForall_NewValueAssumption(s.Tok, jList, val.Range, lhsBuilder(jj), Substitute(rhs, i, val.FInverse), true, etran, prevEtran);
+ updater.Add(new Bpl.AssumeCmd(s.Tok, qq));
+ }
+ usedInversion = true;
+ }
}
- g = CondApplyBox(rhs.tok, g, rhs.Type, lhsType);
+ if (!usedInversion) {
+ qq = TrForall_NewValueAssumption(s.Tok, s.BoundVars, s.Range, lhs, rhs, false, etran, prevEtran);
+ updater.Add(new Bpl.AssumeCmd(s.Tok, qq));
+ }
+ }
+ }
+
+ /// <summary>
+ /// Generate:
+ /// assume (forall x,y :: Range(x,y)[$Heap:=oldHeap] ==>
+ /// $Heap[ Object(x,y)[$Heap:=oldHeap], Field(x,y)[$Heap:=oldHeap] ] == G[$Heap:=oldHeap] ));
+ /// where
+ /// x,y represent boundVars
+ /// Object(x,y) is the first part of lhs
+ /// Field(x,y) is the second part of lhs
+ /// G is rhs
+ /// If lhsAsTrigger is true, then use the LHS of the equality above as the trigger; otherwise, don't specify any trigger.
+ /// </summary>
+ private Bpl.Expr TrForall_NewValueAssumption(IToken tok, List<BoundVar> boundVars, Expression range, Expression lhs, Expression rhs, bool lhsAsTrigger, ExpressionTranslator etran, ExpressionTranslator prevEtran) {
+ Contract.Requires(tok != null);
+ Contract.Requires(boundVars != null);
+ Contract.Requires(range != null);
+ Contract.Requires(lhs != null);
+ Contract.Requires(rhs != null);
+ Contract.Requires(etran != null);
+ Contract.Requires(prevEtran != null);
+
+ var xBvars = new List<Variable>();
+ Bpl.Expr xAnte = etran.TrBoundVariables(boundVars, xBvars);
+ xAnte = BplAnd(xAnte, prevEtran.TrExpr(range));
+ var g = prevEtran.TrExpr(rhs);
+ Bpl.Expr obj, field;
+ GetObjFieldDetails(lhs, prevEtran, out obj, out field);
+ var xHeapOF = ExpressionTranslator.ReadHeap(tok, etran.HeapExpr, obj, field);
- qq = new Bpl.ForallExpr(s.Tok, xBvars, Bpl.Expr.Imp(xAnte, Bpl.Expr.Eq(xHeapOF, g)));
- updater.Add(new Bpl.AssumeCmd(s.Tok, qq));
+ Type lhsType = lhs is FieldSelectExpr ? ((FieldSelectExpr)lhs).Type : null;
+ g = CondApplyBox(rhs.tok, g, rhs.Type, lhsType);
+
+ Trigger tr = lhsAsTrigger ? new Trigger(tok, true, new List<Bpl.Expr>() { xHeapOF }) : null;
+ return new Bpl.ForallExpr(tok, xBvars, tr, Bpl.Expr.Imp(xAnte, Bpl.Expr.Eq(xHeapOF, g)));
+ }
+
+ class ForallStmtTranslationValues
+ {
+ public readonly Expression Range;
+ public readonly Expression FInverse;
+ public ForallStmtTranslationValues(Expression range, Expression fInverse) {
+ Contract.Requires(range != null);
+ Contract.Requires(fInverse != null);
+ Range = range;
+ FInverse = fInverse;
+ }
+ public ForallStmtTranslationValues Subst(IVariable j, Expression e, Translator translator) {
+ Contract.Requires(j != null);
+ Contract.Requires(e != null);
+ Contract.Requires(translator != null);
+ var substMap = new Dictionary<IVariable, Expression>();
+ substMap.Add(j, e);
+ var v = new ForallStmtTranslationValues(translator.Substitute(Range, null, substMap), translator.Substitute(FInverse, null, substMap));
+ return v;
+ }
+ }
+
+ /// <summary>
+ /// Find piecewise inverse of F under R. More precisely, find lists of expressions P and F-1
+ /// such that
+ /// R(i) && j == F(i)
+ /// holds iff the disjunction of the following predicates holds:
+ /// P_0(j) && F-1_0(j) == i
+ /// ...
+ /// P_{n-1}(j) && F-1_{n-1}(j) == i
+ /// If no such disjunction is found, return null.
+ /// If such a disjunction is found, return for each disjunct:
+ /// * The predicate P_k(j), which is an expression that may have free occurrences of j (but no free occurrences of i)
+ /// * The expression F-1_k(j), which also may have free occurrences of j but not of i
+ /// </summary>
+ private List<ForallStmtTranslationValues> InvertExpression(BoundVar i, BoundVar j, Expression R, Expression F) {
+ Contract.Requires(i != null);
+ Contract.Requires(j != null);
+ Contract.Requires(R != null);
+ Contract.Requires(F != null);
+ var vals = new List<ForallStmtTranslationValues>(InvertExpressionIter(i, j, R, F));
+ if (vals.Count == 0) {
+ return null;
+ } else {
+ return vals;
+ }
+ }
+ /// <summary>
+ /// See InvertExpression.
+ /// </summary>
+ private IEnumerable<ForallStmtTranslationValues> InvertExpressionIter(BoundVar i, BoundVar j, Expression R, Expression F) {
+ Contract.Requires(i != null);
+ Contract.Requires(j != null);
+ Contract.Requires(R != null);
+ Contract.Requires(F != null);
+ F = F.Resolved;
+ if (!ContainsFreeVariable(F, false, i)) {
+ // We're looking at R(i) && j == K.
+ // We cannot invert j == K, but if we're lucky, R(i) contains a conjunct i==G.
+ Expression r = Expression.CreateBoolLiteral(R.tok, true);
+ Expression G = null;
+ foreach (var c in Expression.Conjuncts(R)) {
+ if (G == null && c is BinaryExpr) {
+ var bin = (BinaryExpr)c;
+ if (BinaryExpr.IsEqualityOp(bin.ResolvedOp)) {
+ var id = bin.E0.Resolved as IdentifierExpr;
+ if (id != null && id.Var == i) {
+ G = bin.E1;
+ continue;
+ }
+ id = bin.E1.Resolved as IdentifierExpr;
+ if (id != null && id.Var == i) {
+ G = bin.E0;
+ continue;
+ }
+ }
+ }
+ r = Expression.CreateAnd(r, c);
+ }
+ if (G != null) {
+ var jIsK = Expression.CreateEq(Expression.CreateIdentExpr(j), F, j.Type);
+ var rr = Substitute(r, i, G);
+ yield return new ForallStmtTranslationValues(Expression.CreateAnd(rr, jIsK), G);
+ }
+ } else if (F is IdentifierExpr) {
+ var e = (IdentifierExpr)F;
+ if (e.Var == i) {
+ // We're looking at R(i) && j == i, which is particularly easy to invert: R(j) && j == i
+ var jj = Expression.CreateIdentExpr(j);
+ yield return new ForallStmtTranslationValues(Substitute(R, i, jj), jj);
+ }
+ } else if (F is BinaryExpr) {
+ var bin = (BinaryExpr)F;
+ if (bin.ResolvedOp == BinaryExpr.ResolvedOpcode.Add) {
+ if (!ContainsFreeVariable(bin.E1, false, i)) {
+ // We're looking at: R(i) && j == f(i) + K.
+ // By a recursive call, we'll ask to invert: R(i) && j' == f(i).
+ // For each P_0(j') && f-1_0(j') == i we get back, we yield:
+ // P_0(j - K) && f-1_0(j - K) == i
+ var jMinusK = Expression.CreateSubtract(Expression.CreateIdentExpr(j), bin.E1);
+ foreach (var val in InvertExpression(i, j, R, bin.E0)) {
+ yield return val.Subst(j, jMinusK, this);
+ }
+ } else if (!ContainsFreeVariable(bin.E0, false, i)) {
+ // We're looking at: R(i) && j == K + f(i)
+ // Do as in previous case, but with operands reversed.
+ var jMinusK = Expression.CreateSubtract(Expression.CreateIdentExpr(j), bin.E0);
+ foreach (var val in InvertExpression(i, j, R, bin.E1)) {
+ yield return val.Subst(j, jMinusK, this);
+ }
+ }
+ } else if (bin.ResolvedOp == BinaryExpr.ResolvedOpcode.Sub) {
+ if (!ContainsFreeVariable(bin.E1, false, i)) {
+ // We're looking at: R(i) && j == f(i) - K
+ // Recurse on f(i) and then replace j := j + K
+ var jPlusK = Expression.CreateAdd(Expression.CreateIdentExpr(j), bin.E1);
+ foreach (var val in InvertExpression(i, j, R, bin.E0)) {
+ yield return val.Subst(j, jPlusK, this);
+ }
+ } else if (!ContainsFreeVariable(bin.E0, false, i)) {
+ // We're looking at: R(i) && j == K - f(i)
+ // Recurse on f(i) and then replace j := K - j
+ var kMinusJ = Expression.CreateAdd(Expression.CreateIdentExpr(j), bin.E0);
+ foreach (var val in InvertExpression(i, j, R, bin.E1)) {
+ yield return val.Subst(j, kMinusJ, this);
+ }
+ }
+ }
+ } else if (F is ITEExpr) {
+ var ife = (ITEExpr)F;
+ // We're looking at R(i) && j == if A(i) then B(i) else C(i), which is equivalent to the disjunction of:
+ // R(i) && A(i) && j == B(i)
+ // R(i) && !A(i) && j == C(i)
+ // We recurse on each one, yielding the results
+ var r = Expression.CreateAnd(R, ife.Test);
+ var valsThen = InvertExpression(i, j, r, ife.Thn);
+ if (valsThen != null) {
+ r = Expression.CreateAnd(R, Expression.CreateNot(ife.tok, ife.Test));
+ var valsElse = InvertExpression(i, j, r, ife.Els);
+ if (valsElse != null) {
+ foreach (var val in valsThen) { yield return val; }
+ foreach (var val in valsElse) { yield return val; }
+ }
+ }
}
}
@@ -6164,16 +6403,17 @@ namespace Microsoft.Dafny {
TrStmt_CheckWellformed(s.Range, definedness, locals, etran, false);
definedness.Add(new Bpl.AssumeCmd(s.Range.tok, etran.TrExpr(s.Range)));
- TrStmt(s.Body, definedness, locals, etran);
+ if (s.Body != null) {
+ TrStmt(s.Body, definedness, locals, etran);
- // check that postconditions hold
- foreach (var ens in s.Ens) {
- TrStmt_CheckWellformed(ens.E, definedness, locals, etran, false);
- if (!ens.IsFree) {
- bool splitHappened; // we actually don't care
- foreach (var split in TrSplitExpr(ens.E, etran, true, out splitHappened)) {
- if (split.IsChecked) {
- definedness.Add(Assert(split.E.tok, split.E, "possible violation of postcondition of forall statement"));
+ // check that postconditions hold
+ foreach (var ens in s.Ens) {
+ if (!ens.IsFree) {
+ bool splitHappened; // we actually don't care
+ foreach (var split in TrSplitExpr(ens.E, etran, true, out splitHappened)) {
+ if (split.IsChecked) {
+ definedness.Add(Assert(split.E.tok, split.E, "possible violation of postcondition of forall statement"));
+ }
}
}
}
@@ -8289,10 +8529,16 @@ namespace Microsoft.Dafny {
} else if (expr is SeqDisplayExpr) {
SeqDisplayExpr e = (SeqDisplayExpr)expr;
Bpl.Expr s = translator.FunctionCall(expr.tok, BuiltinFunction.SeqEmpty, predef.BoxType);
- foreach (Expression ee in e.Elements) {
- Bpl.Expr elt = BoxIfNecessary(expr.tok, TrExpr(ee), cce.NonNull(ee.Type));
+ bool isLit = true;
+ foreach (Expression ee in e.Elements) {
+ var rawElement = TrExpr(ee);
+ isLit = isLit && translator.IsLit(rawElement);
+ Bpl.Expr elt = BoxIfNecessary(expr.tok, rawElement, ee.Type);
s = translator.FunctionCall(expr.tok, BuiltinFunction.SeqBuild, predef.BoxType, s, elt);
}
+ if (isLit) {
+ s = translator.Lit(s, predef.BoxType);
+ }
return s;
} else if (expr is MapDisplayExpr) {
@@ -8313,14 +8559,15 @@ namespace Microsoft.Dafny {
Bpl.Expr result;
if (e.Field.IsMutable) {
result = ReadHeap(expr.tok, HeapExpr, obj, new Bpl.IdentifierExpr(expr.tok, translator.GetField(e.Field)));
- } else {
- result = new Bpl.NAryExpr(expr.tok, new Bpl.FunctionCall(translator.GetReadonlyField(e.Field)), new List<Bpl.Expr> { obj });
- if (translator.IsLit(obj)) {
- result = translator.Lit(result, translator.TrType(expr.Type));
- }
+ return translator.CondApplyUnbox(expr.tok, result, e.Field.Type, expr.Type);
+ } else {
+ result = new Bpl.NAryExpr(expr.tok, new Bpl.FunctionCall(translator.GetReadonlyField(e.Field)), new List<Bpl.Expr> { obj });
+ result = translator.CondApplyUnbox(expr.tok, result, e.Field.Type, expr.Type);
+ if (translator.IsLit(obj)) {
+ result = translator.Lit(result, translator.TrType(expr.Type));
+ }
+ return result;
}
- return translator.CondApplyUnbox(expr.tok, result, e.Field.Type, cce.NonNull(expr.Type));
-
} else if (expr is SeqSelectExpr) {
SeqSelectExpr e = (SeqSelectExpr)expr;
Bpl.Expr seq = TrExpr(e.Seq);
@@ -8366,13 +8613,20 @@ namespace Microsoft.Dafny {
if (e.Seq.Type.IsArrayType) {
seq = translator.FunctionCall(expr.tok, BuiltinFunction.SeqFromArray, elType, HeapExpr, seq);
}
+ var isLit = translator.IsLit(seq);
if (e1 != null) {
+ isLit = isLit && translator.IsLit(e1);
seq = translator.FunctionCall(expr.tok, BuiltinFunction.SeqTake, elType, seq, e1);
}
if (e0 != null) {
+ isLit = isLit && translator.IsLit(e0);
seq = translator.FunctionCall(expr.tok, BuiltinFunction.SeqDrop, elType, seq, e0);
}
// if e0 == null && e1 == null, then we have the identity operation seq[..] == seq;
+ if (isLit && (e0 != null || e1 != null)) {
+ // Lit-lift the expression
+ seq = translator.Lit(seq, translator.TrType(expr.Type));
+ }
return seq;
}
@@ -8446,12 +8700,13 @@ namespace Microsoft.Dafny {
var id = new Bpl.IdentifierExpr(e.tok, e.Function.FullSanitizedName, ty);
bool returnLit;
var args = FunctionInvocationArguments(e, layerArgument, out returnLit);
+
Expr result = new Bpl.NAryExpr(e.tok, new Bpl.FunctionCall(id), args);
+ result = translator.CondApplyUnbox(e.tok, result, e.Function.ResultType, e.Type);
if (returnLit && !translator.IsOpaqueFunction(e.Function)) {
result = translator.Lit(result, ty);
}
- return translator.CondApplyUnbox(e.tok, result, e.Function.ResultType, e.Type);
-
+ return result;
} else if (expr is DatatypeValue) {
DatatypeValue dtv = (DatatypeValue)expr;
Contract.Assert(dtv.Ctor != null); // since dtv has been successfully resolved
@@ -8465,7 +8720,7 @@ namespace Microsoft.Dafny {
args.Add(translator.CondApplyBox(expr.tok, bArg, cce.NonNull(arg.Type), t));
}
Bpl.IdentifierExpr id = new Bpl.IdentifierExpr(dtv.tok, dtv.Ctor.FullName, predef.DatatypeType);
- Expr ret = new Bpl.NAryExpr(dtv.tok, new Bpl.FunctionCall(id), args);
+ Bpl.Expr ret = new Bpl.NAryExpr(dtv.tok, new Bpl.FunctionCall(id), args);
if (isLit) {
ret = translator.Lit(ret, predef.DatatypeType);
}
@@ -8621,13 +8876,13 @@ namespace Microsoft.Dafny {
typ = Bpl.Type.Bool;
bOpcode = BinaryOperator.Opcode.Gt; break;
case BinaryExpr.ResolvedOpcode.Add:
- typ = Bpl.Type.Int;
+ typ = isReal ? Bpl.Type.Real : Bpl.Type.Int;
bOpcode = BinaryOperator.Opcode.Add; break;
case BinaryExpr.ResolvedOpcode.Sub:
- typ = Bpl.Type.Int;
+ typ = isReal ? Bpl.Type.Real : Bpl.Type.Int;
bOpcode = BinaryOperator.Opcode.Sub; break;
case BinaryExpr.ResolvedOpcode.Mul:
- typ = Bpl.Type.Int;
+ typ = isReal ? Bpl.Type.Real : Bpl.Type.Int;
bOpcode = BinaryOperator.Opcode.Mul; break;
case BinaryExpr.ResolvedOpcode.Div:
if (isReal) {
@@ -8862,9 +9117,9 @@ namespace Microsoft.Dafny {
} else if (expr is ITEExpr) {
ITEExpr e = (ITEExpr)expr;
- Bpl.Expr g = translator.RemoveLit(TrExpr(e.Test));
- Bpl.Expr thn = translator.RemoveLit(TrExpr(e.Thn));
- Bpl.Expr els = translator.RemoveLit(TrExpr(e.Els));
+ var g = translator.RemoveLit(TrExpr(e.Test));
+ var thn = translator.RemoveLit(TrExpr(e.Thn));
+ var els = translator.RemoveLit(TrExpr(e.Els));
return new NAryExpr(expr.tok, new IfThenElse(expr.tok), new List<Bpl.Expr> { g, thn, els });
} else if (expr is MatchExpr) {
@@ -9032,6 +9287,24 @@ namespace Microsoft.Dafny {
return translator.BoxIfNecessary(tok, e, fromType);
}
+ public static Bpl.NAryExpr ReadHeap(IToken tok, Expr heap, Expr r, Expr f) {
+ Contract.Requires(tok != null);
+ Contract.Requires(heap != null);
+ Contract.Requires(r != null);
+ Contract.Requires(f != null);
+ Contract.Ensures(Contract.Result<Bpl.NAryExpr>() != null);
+
+ List<Bpl.Expr> args = new List<Bpl.Expr>();
+ args.Add(heap);
+ args.Add(r);
+ args.Add(f);
+ Bpl.Type t = (f.Type != null) ? f.Type : f.ShallowType;
+ return new Bpl.NAryExpr(tok,
+ new Bpl.FunctionCall(new Bpl.IdentifierExpr(tok, "read", t.AsCtor.Arguments[0])),
+ args);
+ }
+
+
public static Bpl.NAryExpr UpdateHeap(IToken tok, Expr heap, Expr r, Expr f, Expr v) {
Contract.Requires(tok != null);
Contract.Requires(heap != null);
@@ -9193,8 +9466,10 @@ namespace Microsoft.Dafny {
enum BuiltinFunction
{
Lit,
+ LitInt,
+ LitReal,
LayerSucc,
-
+
Is, IsBox,
IsAlloc, IsAllocBox,
@@ -9273,9 +9548,21 @@ namespace Microsoft.Dafny {
}
Bpl.Expr Lit(Bpl.Expr expr, Bpl.Type typ) {
- return FunctionCall(expr.tok, BuiltinFunction.Lit, typ, expr);
+ Contract.Requires(expr != null);
+ Contract.Requires(typ != null);
+ // To avoid Boogie's int_2_U and U_2_int conversions, which seem to cause problems with
+ // arithmetic reasoning, we use several Lit functions. In particular, we use one for
+ // integers, one for reals, and one for everything else.
+ if (typ.IsInt) {
+ return FunctionCall(expr.tok, BuiltinFunction.LitInt, null, expr);
+ } else if (typ.IsReal) {
+ return FunctionCall(expr.tok, BuiltinFunction.LitReal, null, expr);
+ } else {
+ return FunctionCall(expr.tok, BuiltinFunction.Lit, typ, expr);
+ }
}
+
Bpl.Expr Lit(Bpl.Expr expr) {
return Lit(expr, expr.Type);
}
@@ -9283,19 +9570,20 @@ namespace Microsoft.Dafny {
Bpl.Expr GetLit(Bpl.Expr expr) {
if (expr is NAryExpr) {
NAryExpr app = (NAryExpr)expr;
- if (app.Fun.FunctionName == "Lit") {
- return app.Args[0];
+ switch (app.Fun.FunctionName) {
+ case "LitInt":
+ case "LitReal":
+ case "Lit":
+ return app.Args[0];
+ default:
+ break;
}
}
return null;
}
Bpl.Expr RemoveLit(Bpl.Expr expr) {
- var e = GetLit(expr);
- if (e == null) {
- e = expr;
- }
- return e;
+ return GetLit(expr) ?? expr;
}
bool IsLit(Bpl.Expr expr) {
@@ -9311,6 +9599,14 @@ namespace Microsoft.Dafny {
Contract.Ensures(Contract.Result<Bpl.NAryExpr>() != null);
switch (f) {
+ case BuiltinFunction.LitInt:
+ Contract.Assert(args.Length == 1);
+ Contract.Assert(typeInstantiation == null);
+ return FunctionCall(tok, "LitInt", Bpl.Type.Int, args);
+ case BuiltinFunction.LitReal:
+ Contract.Assert(args.Length == 1);
+ Contract.Assert(typeInstantiation == null);
+ return FunctionCall(tok, "LitReal", Bpl.Type.Real, args);
case BuiltinFunction.Lit:
Contract.Assert(args.Length == 1);
Contract.Assert(typeInstantiation != null);
@@ -10528,6 +10824,19 @@ namespace Microsoft.Dafny {
}
}
+ /// <summary>
+ /// Returns an expression like "expr", but where free occurrences of "v" have been replaced by "e".
+ /// </summary>
+ public Expression Substitute(Expression expr, IVariable v, Expression e) {
+ Contract.Requires(expr != null);
+ Contract.Requires(v != null);
+ Contract.Requires(e != null);
+ Contract.Ensures(Contract.Result<Expression>() != null);
+ var substMap = new Dictionary<IVariable, Expression>();
+ substMap.Add(v, e);
+ return Substitute(expr, null, substMap);
+ }
+
public Expression Substitute(Expression expr, Expression receiverReplacement, Dictionary<IVariable, Expression/*!*/>/*!*/ substMap, Dictionary<TypeParameter, Type>/*?*/ typeMap = null) {
Contract.Requires(expr != null);
Contract.Requires(cce.NonNullDictionaryAndValues(substMap));
@@ -10836,7 +11145,7 @@ namespace Microsoft.Dafny {
cases.Add(newCaseExpr);
}
if (anythingChanged) {
- var newME = new MatchExpr(expr.tok, src, cases);
+ var newME = new MatchExpr(expr.tok, src, cases, e.UsesOptionalBraces);
newME.MissingCases.AddRange(e.MissingCases);
newExpr = newME;
}
@@ -11133,7 +11442,7 @@ namespace Microsoft.Dafny {
r = rr;
} else if (stmt is MatchStmt) {
var s = (MatchStmt)stmt;
- var rr = new MatchStmt(s.Tok, s.EndTok, Substitute(s.Source), s.Cases.ConvertAll(SubstMatchCaseStmt));
+ var rr = new MatchStmt(s.Tok, s.EndTok, Substitute(s.Source), s.Cases.ConvertAll(SubstMatchCaseStmt), s.UsesOptionalBraces);
rr.MissingCases.AddRange(s.MissingCases);
r = rr;
} else if (stmt is AssignSuchThatStmt) {
diff --git a/Source/DafnyDriver/DafnyDriver.cs b/Source/DafnyDriver/DafnyDriver.cs
index 8f5b5300..01ee269e 100644
--- a/Source/DafnyDriver/DafnyDriver.cs
+++ b/Source/DafnyDriver/DafnyDriver.cs
@@ -99,7 +99,7 @@ namespace Microsoft.Dafny
}
- static ExitValue ProcessFiles(List<string/*!*/>/*!*/ fileNames)
+ static ExitValue ProcessFiles(List<string/*!*/>/*!*/ fileNames, bool lookForSnapshots = true)
{
Contract.Requires(cce.NonNullElements(fileNames));
@@ -110,7 +110,21 @@ namespace Microsoft.Dafny
{
Console.WriteLine();
Console.WriteLine("-------------------- {0} --------------------", f);
- var ev = ProcessFiles(new List<string> { f });
+ var ev = ProcessFiles(new List<string> { f }, lookForSnapshots);
+ if (exitValue != ev && ev != ExitValue.VERIFIED)
+ {
+ exitValue = ev;
+ }
+ }
+ return exitValue;
+ }
+
+ if (0 < CommandLineOptions.Clo.VerifySnapshots && lookForSnapshots)
+ {
+ var snapshotsByVersion = ExecutionEngine.LookForSnapshots(fileNames);
+ foreach (var s in snapshotsByVersion)
+ {
+ var ev = ProcessFiles(new List<string>(s), false);
if (exitValue != ev && ev != ExitValue.VERIFIED)
{
exitValue = ev;
@@ -213,7 +227,7 @@ namespace Microsoft.Dafny
ExecutionEngine.CollectModSets(program);
ExecutionEngine.CoalesceBlocks(program);
ExecutionEngine.Inline(program);
- return ExecutionEngine.InferAndVerify(program, stats);
+ return ExecutionEngine.InferAndVerify(program, stats, 1 < Dafny.DafnyOptions.Clo.VerifySnapshots ? "main_program_id" : null);
default:
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected outcome
diff --git a/Source/DafnyDriver/DafnyDriver.csproj b/Source/DafnyDriver/DafnyDriver.csproj
index 631b0194..cf664364 100644
--- a/Source/DafnyDriver/DafnyDriver.csproj
+++ b/Source/DafnyDriver/DafnyDriver.csproj
@@ -20,7 +20,7 @@
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation />
<IsWebBootstrapper>false</IsWebBootstrapper>
- <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+ <TargetFrameworkProfile></TargetFrameworkProfile>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
diff --git a/Source/DafnyExtension/DafnyDriver.cs b/Source/DafnyExtension/DafnyDriver.cs
index f4eb4fb7..ea21f12b 100644
--- a/Source/DafnyExtension/DafnyDriver.cs
+++ b/Source/DafnyExtension/DafnyDriver.cs
@@ -45,7 +45,7 @@ namespace DafnyLanguage
ExecutionEngine.printer = new DummyPrinter();
ExecutionEngine.errorInformationFactory = new DafnyErrorInformationFactory();
- ToggleIncrementalVerification();
+ ChangeIncrementalVerification(1);
}
}
@@ -215,11 +215,30 @@ namespace DafnyLanguage
}
}
- public static bool ToggleIncrementalVerification()
+ public static int IncrementalVerificationMode()
{
- // TODO(wuestholz): Change this once there are more than two options.
- Dafny.DafnyOptions.Clo.VerifySnapshots = (Dafny.DafnyOptions.Clo.VerifySnapshots + 1) % 2;
- return 0 < Dafny.DafnyOptions.Clo.VerifySnapshots;
+ return Dafny.DafnyOptions.Clo.VerifySnapshots;
+ }
+
+ public static int ChangeIncrementalVerification(int mode)
+ {
+ var old = Dafny.DafnyOptions.Clo.VerifySnapshots;
+ if (mode == 1 && old != 0)
+ {
+ // Disable mode 1.
+ Dafny.DafnyOptions.Clo.VerifySnapshots = 0;
+ }
+ else if (mode == 2 && old == 2)
+ {
+ // Disable mode 2.
+ Dafny.DafnyOptions.Clo.VerifySnapshots = 1;
+ }
+ else
+ {
+ // Enable mode.
+ Dafny.DafnyOptions.Clo.VerifySnapshots = mode;
+ }
+ return Dafny.DafnyOptions.Clo.VerifySnapshots;
}
public static bool Verify(Dafny.Program dafnyProgram, ResolverTagger resolver, string uniqueIdPrefix, string requestId, ErrorReporterDelegate er) {
@@ -230,7 +249,8 @@ namespace DafnyLanguage
resolver.ReInitializeVerificationErrors(requestId, boogieProgram.TopLevelDeclarations);
- PipelineOutcome oc = BoogiePipeline(boogieProgram, requestId, er);
+ // TODO(wuestholz): Maybe we should use a fixed program ID to limit the memory overhead due to the program cache in Boogie.
+ PipelineOutcome oc = BoogiePipeline(boogieProgram, 1 < Dafny.DafnyOptions.Clo.VerifySnapshots ? uniqueIdPrefix : null, requestId, er);
switch (oc) {
case PipelineOutcome.Done:
case PipelineOutcome.VerificationCompleted:
@@ -248,7 +268,7 @@ namespace DafnyLanguage
/// else. Hence, any resolution errors and type checking errors are due to errors in
/// the translation.
/// </summary>
- static PipelineOutcome BoogiePipeline(Bpl.Program/*!*/ program, string requestId, ErrorReporterDelegate er)
+ static PipelineOutcome BoogiePipeline(Bpl.Program/*!*/ program, string programId, string requestId, ErrorReporterDelegate er)
{
Contract.Requires(program != null);
@@ -257,8 +277,8 @@ namespace DafnyLanguage
ExecutionEngine.EliminateDeadVariables(program);
ExecutionEngine.CollectModSets(program);
ExecutionEngine.CoalesceBlocks(program);
- ExecutionEngine.Inline(program);
- return ExecutionEngine.InferAndVerify(program, new PipelineStatistics(), er, requestId);
+ ExecutionEngine.Inline(program);
+ return ExecutionEngine.InferAndVerify(program, new PipelineStatistics(), programId, er, requestId);
}
return oc;
}
diff --git a/Source/DafnyExtension/MenuProxy.cs b/Source/DafnyExtension/MenuProxy.cs
index a67ba602..11e1287f 100644
--- a/Source/DafnyExtension/MenuProxy.cs
+++ b/Source/DafnyExtension/MenuProxy.cs
@@ -17,9 +17,20 @@ namespace DafnyLanguage
this.DafnyMenuPackage = DafnyMenuPackage;
}
- public bool ToggleSnapshotVerification(IWpfTextView activeTextView)
+ public int ToggleSnapshotVerification(IWpfTextView activeTextView)
{
- return DafnyDriver.ToggleIncrementalVerification();
+ return DafnyDriver.ChangeIncrementalVerification(1);
+ }
+
+ public int ToggleMoreAdvancedSnapshotVerification(IWpfTextView activeTextView)
+ {
+ return DafnyDriver.ChangeIncrementalVerification(2);
+ }
+
+ public bool MoreAdvancedSnapshotVerificationCommandEnabled(IWpfTextView activeTextView)
+ {
+ return activeTextView != null
+ && 0 < DafnyDriver.IncrementalVerificationMode();
}
public bool StopVerifierCommandEnabled(IWpfTextView activeTextView)
diff --git a/Source/DafnyExtension/TokenTagger.cs b/Source/DafnyExtension/TokenTagger.cs
index 48f5d1b4..5068354a 100644
--- a/Source/DafnyExtension/TokenTagger.cs
+++ b/Source/DafnyExtension/TokenTagger.cs
@@ -5,6 +5,7 @@ using System.Linq;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;
+using System.Diagnostics.Contracts;
namespace DafnyLanguage
@@ -69,11 +70,12 @@ namespace DafnyLanguage
}
}
- internal sealed class DafnyTokenTagger : ITagger<DafnyTokenTag>
+ internal sealed class DafnyTokenTagger : ITagger<DafnyTokenTag>, IDisposable
{
ITextBuffer _buffer;
ITextSnapshot _snapshot;
List<TokenRegion> _regions;
+ bool _disposed;
internal DafnyTokenTagger(ITextBuffer buffer) {
_buffer = buffer;
@@ -83,6 +85,19 @@ namespace DafnyLanguage
_buffer.Changed += new EventHandler<TextContentChangedEventArgs>(ReparseFile);
}
+ public void Dispose() {
+ lock (this) {
+ if (!_disposed) {
+ _buffer.Changed -= ReparseFile;
+ _buffer = null;
+ _snapshot = null;
+ _regions = null;
+ _disposed = true;
+ }
+ }
+ GC.SuppressFinalize(this);
+ }
+
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
public IEnumerable<ITagSpan<DafnyTokenTag>> GetTags(NormalizedSnapshotSpanCollection spans) {
@@ -148,20 +163,24 @@ namespace DafnyLanguage
private static List<TokenRegion> Rescan(ITextSnapshot newSnapshot) {
List<TokenRegion> newRegions = new List<TokenRegion>();
- bool stillScanningLongComment = false;
- SnapshotPoint commentStart = new SnapshotPoint(); // used only when stillScanningLongComment
- SnapshotPoint commentEndAsWeKnowIt = new SnapshotPoint(); // used only when stillScanningLongComment
+ int longCommentDepth = 0;
+ SnapshotPoint commentStart = new SnapshotPoint(); // used only when longCommentDepth != 0
+ SnapshotPoint commentEndAsWeKnowIt = new SnapshotPoint(); // used only when longCommentDepth != 0
foreach (ITextSnapshotLine line in newSnapshot.Lines) {
string txt = line.GetText(); // the current line (without linebreak characters)
int N = txt.Length; // length of the current line
int cur = 0; // offset into the current line
- if (stillScanningLongComment) {
- if (ScanForEndOfComment(txt, ref cur)) {
+ if (longCommentDepth != 0) {
+ ScanForEndOfComment(txt, ref longCommentDepth, ref cur);
+ if (longCommentDepth == 0) {
+ // we just finished parsing a long comment
newRegions.Add(new TokenRegion(commentStart, new SnapshotPoint(newSnapshot, line.Start + cur), DafnyTokenKind.Comment));
- stillScanningLongComment = false;
} else {
+ // we're still parsing the long comment
+ Contract.Assert(cur == txt.Length);
commentEndAsWeKnowIt = new SnapshotPoint(newSnapshot, line.Start + cur);
+ goto OUTER_CONTINUE;
}
}
@@ -179,9 +198,9 @@ namespace DafnyLanguage
if ('a' <= ch && ch <= 'z') break;
if ('A' <= ch && ch <= 'Z') break;
if ('0' <= ch && ch <= '9') { ty = DafnyTokenKind.Number; break; }
+ if (ch == '\'' || ch == '_' || ch == '?' || ch == '\\') break; // parts of identifiers
if (ch == '"') { ty = DafnyTokenKind.String; break; }
if (ch == '/') { ty = DafnyTokenKind.Comment; break; }
- if (ch == '\'' || ch == '_' || ch == '?' || ch == '\\') break; // parts of identifiers
}
// advance to the end of the token
@@ -211,7 +230,7 @@ namespace DafnyLanguage
}
}
} else if (ty == DafnyTokenKind.Comment) {
- if (end == N) continue; // this was not the start of a comment
+ if (end == N) continue; // this was not the start of a comment; it was just a single "/" and we don't care to color it
char ch = txt[end];
if (ch == '/') {
// a short comment
@@ -220,15 +239,18 @@ namespace DafnyLanguage
// a long comment; find the matching "*/"
end++;
commentStart = new SnapshotPoint(newSnapshot, line.Start + cur);
- if (ScanForEndOfComment(txt, ref end)) {
+ Contract.Assert(longCommentDepth == 0);
+ longCommentDepth = 1;
+ ScanForEndOfComment(txt, ref longCommentDepth, ref end);
+ if (longCommentDepth == 0) {
+ // we finished scanning a long comment, and "end" is set to right after it
newRegions.Add(new TokenRegion(commentStart, new SnapshotPoint(newSnapshot, line.Start + end), DafnyTokenKind.Comment));
} else {
- stillScanningLongComment = true;
commentEndAsWeKnowIt = new SnapshotPoint(newSnapshot, line.Start + end);
}
continue;
} else {
- // not a comment
+ // not a comment; it was just a single "/" and we don't care to color it
continue;
}
} else {
@@ -322,7 +344,7 @@ namespace DafnyLanguage
#endregion
break;
default:
- continue; // it was an identifier
+ continue; // it was an identifier, so we don't color it
}
}
}
@@ -332,26 +354,40 @@ namespace DafnyLanguage
OUTER_CONTINUE: ;
}
- if (stillScanningLongComment) {
+ if (longCommentDepth != 0) {
+ // This was a malformed comment, running to the end of the buffer. Above, we let "commentEndAsWeKnowIt" be the end of the
+ // last line, so we can use it here.
newRegions.Add(new TokenRegion(commentStart, commentEndAsWeKnowIt, DafnyTokenKind.Comment));
}
return newRegions;
}
- private static bool ScanForEndOfComment(string txt, ref int end) {
- int N = txt.Length;
- for (; end < N; end++) {
+ /// <summary>
+ /// Scans "txt" beginning with depth "depth", which is assumed to be non-0. Any occurrences of "/*" or "*/"
+ /// increment or decrement "depth". If "depth" ever reaches 0, then "end" returns as the number of characters
+ /// consumed from "txt" (including the last "*/"). If "depth" is still non-0 when the entire "txt" has
+ /// been consumed, then "end" returns as the length of "txt". (Note, "end" may return as the length of "txt"
+ /// if "depth" is still non-0 or if "depth" became 0 from reading the last characters of "txt".)
+ /// </summary>
+ private static void ScanForEndOfComment(string txt, ref int depth, ref int end) {
+ Contract.Requires(depth > 0);
+
+ int Nminus1 = txt.Length - 1; // no reason ever to look at the last character of the line, unless the second-to-last character is '*' or '/'
+ for (; end < Nminus1; ) {
char ch = txt[end];
- if (ch == '*' && end + 1 < N) {
- ch = txt[end + 1];
- if (ch == '/') {
- end += 2;
- return true;
- }
+ if (ch == '*' && txt[end + 1] == '/') {
+ end += 2;
+ depth--;
+ if (depth == 0) { return; }
+ } else if (ch == '/' && txt[end + 1] == '*') {
+ end += 2;
+ depth++;
+ } else {
+ end++;
}
}
- return false; // hit end-of-line without finding end-of-comment
+ end = txt.Length; // we didn't look at the last character, but we still consumed all the output
}
}
diff --git a/Source/DafnyExtension/source.extension.vsixmanifest b/Source/DafnyExtension/source.extension.vsixmanifest
index 3b2316b9..f4f66193 100644
--- a/Source/DafnyExtension/source.extension.vsixmanifest
+++ b/Source/DafnyExtension/source.extension.vsixmanifest
@@ -6,7 +6,7 @@
<Description xml:space="preserve">This is a language mode for using the Dafny language inside Visual Studio.</Description>
</Metadata>
<Installation InstalledByMsi="false">
- <InstallationTarget Version="[11.0,12.0)" Id="Microsoft.VisualStudio.Pro" />
+ <InstallationTarget Version="[11.0,13.0)" Id="Microsoft.VisualStudio.Pro" />
</Installation>
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="4.5" />
diff --git a/Source/DafnyMenu/DafnyMenu.vsct b/Source/DafnyMenu/DafnyMenu.vsct
index 0e8c7855..813ccd23 100644
--- a/Source/DafnyMenu/DafnyMenu.vsct
+++ b/Source/DafnyMenu/DafnyMenu.vsct
@@ -103,6 +103,16 @@
</Strings>
</Button>
+ <Button guid="guidDafnyMenuCmdSet" id="cmdidToggleMoreAdvancedSnapshotVerification" priority="0x0105" type="Button">
+ <Parent guid="guidDafnyMenuCmdSet" id="DafnyMenuGroup" />
+ <CommandFlag>DefaultInvisible</CommandFlag>
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ <CommandFlag>TextChanges</CommandFlag>
+ <Strings>
+ <ButtonText>Enable more advanced on-demand re-verification</ButtonText>
+ </Strings>
+ </Button>
+
<Button guid="guidDafnyMenuCmdSet" id="cmdidToggleBVD" priority="0x010a" type="Button">
<Parent guid="guidDafnyMenuCmdSet" id="DafnyMenuGroup" />
<CommandFlag>DynamicVisibility</CommandFlag>
@@ -144,6 +154,7 @@
<IDSymbol name="cmdidStopVerifier" value="0x0102" />
<IDSymbol name="cmdidToggleSnapshotVerification" value="0x0103" />
<IDSymbol name="cmdidToggleBVD" value="0x0104" />
+ <IDSymbol name="cmdidToggleMoreAdvancedSnapshotVerification" value="0x0105" />
</GuidSymbol>
<!--
diff --git a/Source/DafnyMenu/DafnyMenuPackage.cs b/Source/DafnyMenu/DafnyMenuPackage.cs
index 114ddf10..58bf2a26 100644
--- a/Source/DafnyMenu/DafnyMenuPackage.cs
+++ b/Source/DafnyMenu/DafnyMenuPackage.cs
@@ -19,7 +19,13 @@ namespace DafnyLanguage.DafnyMenu
public interface IMenuProxy
{
- bool ToggleSnapshotVerification(IWpfTextView activeTextView);
+ int ToggleSnapshotVerification(IWpfTextView activeTextView);
+
+
+ int ToggleMoreAdvancedSnapshotVerification(IWpfTextView activeTextView);
+
+
+ bool MoreAdvancedSnapshotVerificationCommandEnabled(IWpfTextView activeTextView);
bool StopVerifierCommandEnabled(IWpfTextView activeTextView);
@@ -80,6 +86,7 @@ namespace DafnyLanguage.DafnyMenu
private OleMenuCommand runVerifierCommand;
private OleMenuCommand stopVerifierCommand;
private OleMenuCommand toggleSnapshotVerificationCommand;
+ private OleMenuCommand toggleMoreAdvancedSnapshotVerificationCommand;
private OleMenuCommand toggleBVDCommand;
bool BVDDisabled;
@@ -138,6 +145,11 @@ namespace DafnyLanguage.DafnyMenu
toggleSnapshotVerificationCommand = new OleMenuCommand(ToggleSnapshotVerificationCallback, toggleSnapshotVerificationCommandID);
mcs.AddCommand(toggleSnapshotVerificationCommand);
+ var toggleMoreAdvancedSnapshotVerificationCommandID = new CommandID(GuidList.guidDafnyMenuCmdSet, (int)PkgCmdIDList.cmdidToggleMoreAdvancedSnapshotVerification);
+ toggleMoreAdvancedSnapshotVerificationCommand = new OleMenuCommand(ToggleMoreAdvancedSnapshotVerificationCallback, toggleMoreAdvancedSnapshotVerificationCommandID);
+ toggleMoreAdvancedSnapshotVerificationCommand.BeforeQueryStatus += toggleMoreAdvancedSnapshotVerificationCommand_BeforeQueryStatus;
+ mcs.AddCommand(toggleMoreAdvancedSnapshotVerificationCommand);
+
var showErrorModelCommandID = new CommandID(GuidList.guidDafnyMenuCmdSet, (int)PkgCmdIDList.cmdidToggleBVD);
toggleBVDCommand = new OleMenuCommand(ToggleBVDCallback, showErrorModelCommandID);
toggleBVDCommand.Enabled = true;
@@ -191,8 +203,20 @@ namespace DafnyLanguage.DafnyMenu
var atv = ActiveTextView;
if (MenuProxy != null && atv != null)
{
- var on = MenuProxy.ToggleSnapshotVerification(atv);
- toggleSnapshotVerificationCommand.Text = (on ? "Disable" : "Enable") + " on-demand re-verification";
+ var mode = MenuProxy.ToggleSnapshotVerification(atv);
+ toggleSnapshotVerificationCommand.Text = (mode == 1 ? "Disable" : "Enable") + " on-demand re-verification";
+ toggleMoreAdvancedSnapshotVerificationCommand.Text = (mode == 2 ? "Disable" : "Enable") + " more advanced on-demand re-verification";
+ }
+ }
+
+ void ToggleMoreAdvancedSnapshotVerificationCallback(object sender, EventArgs e)
+ {
+ var atv = ActiveTextView;
+ if (MenuProxy != null && atv != null)
+ {
+ var mode = MenuProxy.ToggleMoreAdvancedSnapshotVerification(atv);
+ toggleSnapshotVerificationCommand.Text = (mode != 0 ? "Disable" : "Enable") + " on-demand re-verification";
+ toggleMoreAdvancedSnapshotVerificationCommand.Text = (mode == 2 ? "Disable" : "Enable") + " more advanced on-demand re-verification";
}
}
@@ -276,6 +300,16 @@ namespace DafnyLanguage.DafnyMenu
}
}
+ private void toggleMoreAdvancedSnapshotVerificationCommand_BeforeQueryStatus(object sender, EventArgs e)
+ {
+ var atv = ActiveTextView;
+ if (MenuProxy != null && atv != null)
+ {
+ var visible = MenuProxy.MoreAdvancedSnapshotVerificationCommandEnabled(atv);
+ toggleMoreAdvancedSnapshotVerificationCommand.Visible = visible;
+ }
+ }
+
void ToggleBVDCallback(object sender, EventArgs e)
{
BVDDisabled = !BVDDisabled;
diff --git a/Source/DafnyMenu/PkgCmdID.cs b/Source/DafnyMenu/PkgCmdID.cs
index f3452cb9..b6f30145 100644
--- a/Source/DafnyMenu/PkgCmdID.cs
+++ b/Source/DafnyMenu/PkgCmdID.cs
@@ -12,5 +12,6 @@ namespace DafnyLanguage.DafnyMenu
public const uint cmdidMenu = 0x1021;
public static uint cmdidToggleSnapshotVerification = 0x103;
public const uint cmdidToggleBVD = 0x104;
+ public static uint cmdidToggleMoreAdvancedSnapshotVerification = 0x105;
};
} \ No newline at end of file
diff --git a/Source/DafnyMenu/source.extension.vsixmanifest b/Source/DafnyMenu/source.extension.vsixmanifest
index 508078d4..7beeb69e 100644
--- a/Source/DafnyMenu/source.extension.vsixmanifest
+++ b/Source/DafnyMenu/source.extension.vsixmanifest
@@ -6,7 +6,7 @@
<Description xml:space="preserve">This is a menu for interacting with Dafny.</Description>
</Metadata>
<Installation InstalledByMsi="false">
- <InstallationTarget Version="[11.0,12.0)" Id="Microsoft.VisualStudio.Pro" />
+ <InstallationTarget Version="[11.0,13.0)" Id="Microsoft.VisualStudio.Pro" />
</Installation>
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="4.5" />