-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add pushScope
, popScope
, hide
and reveal
commands
#891
Changes from all commits
65d0345
9870fea
9f0d713
8a118c7
6ed64bf
b4c04bb
3b50887
68c8c95
4c1cf1b
425ad07
a8dd806
d623f3d
ee992ed
41fe76a
c1d20b9
ed7da0b
0f68c37
8e8fcd9
8c9c1c1
d33ec71
f875217
ac628a1
603f8ea
c64b405
7bb898f
3c4de4d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
MSBuild_Logs/ | ||
|
||
.lit_test_times.txt | ||
|
||
# Nuget | ||
Source/packages/ | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#nullable enable | ||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.Boogie; | ||
|
||
/// <summary> | ||
/// Allows pushing and popping scopes inside a Boogie implementation. | ||
/// | ||
/// Right now these scopes only affect the state of what functions are hidden and revealed using the hide and reveal keywords. | ||
/// However, in the future these scopes should also allow lexical scoping and variable shadowing. | ||
/// </summary> | ||
public class ChangeScope : Cmd { | ||
public bool Push { get; } | ||
|
||
public ChangeScope(IToken tok, bool push) : base(tok) { | ||
Push = push; | ||
} | ||
|
||
public override void Resolve(ResolutionContext rc) { | ||
} | ||
|
||
public override void Typecheck(TypecheckingContext tc) { | ||
} | ||
|
||
public override void Emit(TokenTextWriter stream, int level) { | ||
} | ||
|
||
public override void AddAssignedVariables(List<Variable> vars) { | ||
} | ||
|
||
public override Absy StdDispatch(StandardVisitor visitor) { | ||
return this; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#nullable enable | ||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.Boogie; | ||
|
||
/// <summary> | ||
/// Can be used to hide or reveal a specific function, or all functions | ||
/// If pruning is turned on, a hidden function will be pruned despite being referenced in a Boogie implementation. | ||
/// The function is only partially pruned though: the function definition itself is kept, and only axioms | ||
/// that the function depends on, that are marked as hideable, are pruned. | ||
/// | ||
/// Hide and revealing takes into account lexical scoping: | ||
/// A popScope command will undo any hide and reveal operations that came after the last pushScope command. | ||
/// </summary> | ||
public class HideRevealCmd : Cmd { | ||
public bool Hide { get; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to push/pop, an |
||
private readonly FunctionCall? functionCall; | ||
|
||
public HideRevealCmd(IToken tok, bool hide) : base(tok) { | ||
this.Hide = hide; | ||
} | ||
|
||
public HideRevealCmd(IdentifierExpr name, bool hide) : base(name.tok) { | ||
this.Hide = hide; | ||
this.functionCall = new FunctionCall(name); | ||
} | ||
|
||
public Function? Function => functionCall?.Func; | ||
|
||
public override void Resolve(ResolutionContext rc) | ||
{ | ||
functionCall?.Resolve(rc, null); | ||
} | ||
|
||
public override void Typecheck(TypecheckingContext tc) | ||
{ | ||
} | ||
|
||
public override void Emit(TokenTextWriter stream, int level) | ||
{ | ||
stream.Write(this, level, Hide ? "hide " : "reveal "); | ||
stream.Write(this, level, Function == null ? "*" : Function.Name); | ||
stream.WriteLine(";"); | ||
} | ||
|
||
public override void AddAssignedVariables(List<Variable> vars) | ||
{ | ||
} | ||
|
||
public override Absy StdDispatch(StandardVisitor visitor) | ||
{ | ||
return visitor.VisitRevealCmd(this); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -564,11 +564,16 @@ VarOrType<out TypedIdent/*!*/ tyd, out QKeyValue kv> | |
|
||
/*------------------------------------------------------------------------*/ | ||
Axiom<out Axiom/*!*/ m> | ||
= (.Contract.Ensures(Contract.ValueAtReturn(out m) != null); Expr/*!*/ e; QKeyValue kv = null; .) | ||
= (. | ||
Contract.Ensures(Contract.ValueAtReturn(out m) != null); | ||
Expr/*!*/ e; | ||
QKeyValue kv = null; | ||
bool canHide = false; .) | ||
[ "hideable" (. canHide = true; .) ] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be more inclined to make this an attribute than a keyword, though I don't have a super strong opinion about that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about that, especially since adding a parsing keyword is more difficult implementation wise, but I can't really defend introducing keywords for half a feature and not for the other half. |
||
"axiom" | ||
{ Attribute<ref kv> } | ||
(. IToken/*!*/ x = t; .) | ||
Proposition<out e> ";" (. m = new Axiom(x,e, null, kv); .) | ||
Proposition<out e> ";" (. m = new Axiom(x,e, null, kv, canHide); .) | ||
. | ||
|
||
/*------------------------------------------------------------------------*/ | ||
|
@@ -1110,8 +1115,24 @@ LabelOrCmd<out Cmd c, out IToken label> | |
c = dummyCmd; label = null; | ||
Cmd/*!*/ cn; | ||
QKeyValue kv = null; | ||
bool isHide; | ||
IdentifierExpr hideRevealId = null; | ||
.) | ||
( LabelOrAssign<out c, out label> | ||
( ( | ||
( "reveal" (. isHide = false; .) | ||
| "hide" (. isHide = true; .) | ||
) | ||
( ident (. hideRevealId = new IdentifierExpr(t, t.val); .) | ||
| "*" | ||
) | ||
(. c = hideRevealId == null ? new HideRevealCmd(t, isHide) : new HideRevealCmd(hideRevealId, isHide); .) | ||
";" | ||
) | ||
| LabelOrAssign<out c, out label> | ||
| "popScope" (. c = new ChangeScope(t, false); .) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think anything else in Boogie, the language, uses camel case like this. I'd maybe prefer just |
||
";" | ||
| "pushScope" (. c = new ChangeScope(t, true); .) | ||
";" | ||
| "assert" (. x = t; .) | ||
{ Attribute<ref kv> } | ||
Proposition<out e> (. c = new AssertCmd(x, e, kv); .) | ||
|
@@ -1682,17 +1703,17 @@ Attribute<ref QKeyValue kv> | |
|
||
AttributeOrTrigger<ref QKeyValue kv, ref Trigger trig> | ||
= (. IToken/*!*/ tok; Expr/*!*/ e; List<Expr>/*!*/ es; | ||
string key; | ||
IToken id; | ||
List<object/*!*/> parameters; object/*!*/ param; | ||
.) | ||
"{" (. tok = t; .) | ||
( | ||
":" ident (. key = t.val; parameters = new List<object/*!*/>(); .) | ||
":" Ident<out id> (. parameters = new List<object/*!*/>(); .) | ||
[ AttributeParameter<out param> (. parameters.Add(param); .) | ||
{ "," AttributeParameter<out param> (. parameters.Add(param); .) | ||
} | ||
] | ||
(. if (key == "nopats") { | ||
(. if (id.val == "nopats") { | ||
if (parameters.Count == 1 && parameters[0] is Expr) { | ||
e = (Expr)parameters[0]; | ||
if(trig==null){ | ||
|
@@ -1705,9 +1726,9 @@ AttributeOrTrigger<ref QKeyValue kv, ref Trigger trig> | |
} | ||
} else { | ||
if (kv==null) { | ||
kv = new QKeyValue(tok, key, parameters, null); | ||
kv = new QKeyValue(tok, id.val, parameters, null); | ||
} else { | ||
kv.AddLast(new QKeyValue(tok, key, parameters, null)); | ||
kv.AddLast(new QKeyValue(tok, id.val, parameters, null)); | ||
} | ||
} | ||
.) | ||
|
@@ -1812,6 +1833,7 @@ Ident<out IToken/*!*/ x> | |
| "both" (. t.kind = _ident; .) // convert to ident | ||
| "left" (. t.kind = _ident; .) // convert to ident | ||
| "right" (. t.kind = _ident; .) // convert to ident | ||
| "hide" (. t.kind = _ident; .) // convert to ident | ||
) | ||
(. | ||
x = t; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An
enum
ofPush
andPop
would be a bit nicer than abool
here.