Skip to content

Commit 40dfcdb

Browse files
author
Rustan Leino
committed
Allow TLA+ style conjunctions and disjunctions. More precisely, allow && and || to optionally occur before the first (and possibly only) term of a conjunction or disjunction, respectively.
Also, allow an ML style prefix | in front of the first constructor of a datatype. Thanks, Github/xinhaoyuan, for these source contributions. (Note, I did not include the prefix commas.) Closes #91
1 parent a00b907 commit 40dfcdb

File tree

7 files changed

+277
-92
lines changed

7 files changed

+277
-92
lines changed

Source/Dafny/Dafny.atg

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ DatatypeDecl<DeclModifierData dmod, ModuleDefinition/*!*/ module, out DatatypeDe
10201020
NoUSIdent<out id>
10211021
[ GenericParameters<typeArgs> ]
10221022
"=" (. bodyStart = t; .)
1023-
DatatypeMemberDecl<ctors>
1023+
[ "|" ] DatatypeMemberDecl<ctors>
10241024
{ "|" DatatypeMemberDecl<ctors> }
10251025
[ SYNC ";"
10261026
// This semi-colon used to be required, but it seems silly to have it.
@@ -2661,23 +2661,51 @@ ImpliesExpression<out Expression e0, bool allowSemi, bool allowLambda, bool allo
26612661
.
26622662
/*------------------------------------------------------------------------*/
26632663
LogicalExpression<out Expression e0, bool allowSemi, bool allowLambda, bool allowBitwiseOps>
2664-
= (. Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1; .)
2665-
RelationalExpression<out e0, allowSemi, allowLambda, allowBitwiseOps>
2666-
[ IF(IsAndOp() || IsOrOp()) /* read a LogicalExpression as far as possible */
2667-
( AndOp (. x = t; .)
2668-
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1); .)
2669-
{ IF(IsAndOp()) /* read a conjunction as far as possible */
2670-
AndOp (. x = t; .)
2671-
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1); .)
2672-
}
2673-
| OrOp (. x = t; .)
2674-
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1); .)
2675-
{ IF(IsOrOp()) /* read a disjunction as far as possible */
2676-
OrOp (. x = t; .)
2677-
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1); .)
2678-
}
2679-
)
2680-
]
2664+
= (. Contract.Ensures(Contract.ValueAtReturn(out e0) != null); IToken/*!*/ x; Expression/*!*/ e1;
2665+
Expression first;
2666+
e0 = null; /* mute the warning */
2667+
.)
2668+
( AndOp (. x = t; .)
2669+
RelationalExpression<out e0, allowSemi, allowLambda, allowBitwiseOps> (. first = e0; .)
2670+
{ IF(IsAndOp()) /* read a conjunction as far as possible */
2671+
AndOp (. x = t; .)
2672+
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1); .)
2673+
}
2674+
(. if (e0 == first) {
2675+
// There was only one conjunct. To make sure that the type checker still checks it to
2676+
// be a boolean, we conjoin "true" to its left.
2677+
e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, new LiteralExpr(x, true), e0);
2678+
}
2679+
.)
2680+
| OrOp (. x = t; .)
2681+
RelationalExpression<out e0, allowSemi, allowLambda, allowBitwiseOps> (. first = e0; .)
2682+
{ IF(IsOrOp()) /* read a disjunction as far as possible */
2683+
OrOp (. x = t; .)
2684+
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1); .)
2685+
}
2686+
(. if (e0 == first) {
2687+
// There was only one disjunct. To make sure that the type checker still checks it to
2688+
// be a boolean, we disjoin [sic] "false" to its left.
2689+
e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, new LiteralExpr(x, false), e0);
2690+
}
2691+
.)
2692+
| RelationalExpression<out e0, allowSemi, allowLambda, allowBitwiseOps>
2693+
[ IF(IsAndOp() || IsOrOp()) /* read a LogicalExpression as far as possible */
2694+
( AndOp (. x = t; .)
2695+
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1); .)
2696+
{ IF(IsAndOp()) /* read a conjunction as far as possible */
2697+
AndOp (. x = t; .)
2698+
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.And, e0, e1); .)
2699+
}
2700+
| OrOp (. x = t; .)
2701+
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1); .)
2702+
{ IF(IsOrOp()) /* read a disjunction as far as possible */
2703+
OrOp (. x = t; .)
2704+
RelationalExpression<out e1, allowSemi, allowLambda, allowBitwiseOps> (. e0 = new BinaryExpr(x, BinaryExpr.Opcode.Or, e0, e1); .)
2705+
}
2706+
)
2707+
]
2708+
)
26812709
.
26822710
/*------------------------------------------------------------------------*/
26832711
RelationalExpression<out Expression e, bool allowSemi, bool allowLambda, bool allowBitwiseOps>

0 commit comments

Comments
 (0)