-
Notifications
You must be signed in to change notification settings - Fork 257
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
No flatten for most backends #5528
Merged
keyboardDrummer
merged 46 commits into
dafny-lang:master
from
keyboardDrummer:noFlattenForAllBackends
Jun 5, 2024
Merged
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
97d81e2
Add patterns/codeSize test
keyboardDrummer e77441a
Update codeSize test
keyboardDrummer 547317f
Split off statement part from SPCG
keyboardDrummer 55b4cde
Draft of nested match compiler
keyboardDrummer b4bc5cf
Save
keyboardDrummer f10aa78
Generated code looks good upon visual inspection
keyboardDrummer ee9ae6f
Generated code compiles and runs
keyboardDrummer 069dddb
Move NestedMatch generation to just C#
keyboardDrummer da513a0
Attempt at implementation for expressions
keyboardDrummer 88536c8
Ran formatter
keyboardDrummer f13be6e
Fixes
keyboardDrummer a61d607
Update C# code generator zo it also uses custom generation for nested…
keyboardDrummer 846ad62
Regen GeneratedFromDafny code
keyboardDrummer 85c1b20
Revert "Regen GeneratedFromDafny code"
keyboardDrummer 3660a37
Fix gen
keyboardDrummer 26000a5
Fixes for generics
keyboardDrummer 2805584
Update generated files
keyboardDrummer 09f39f8
Merge branch 'master' into noFlattenForCSharp
keyboardDrummer 82a5d71
Fix bug related to disjoint patterns
keyboardDrummer c32be6f
Merge branch 'noFlattenForCSharp' of github.com:keyboardDrummer/dafny…
keyboardDrummer 861cee7
Merge remote-tracking branch 'origin/master' into noFlattenForCSharp
keyboardDrummer 1e25d7b
Fix literal pattern bug
keyboardDrummer 6791e43
Remove DatatypeWrapperEraser.IsErasableDatatypeWrapper check
keyboardDrummer eedcf47
Ran formatter
keyboardDrummer 6f981ab
Fix bug in disjunctive assignments
keyboardDrummer 0bd8c0d
Merge branch 'master' into noFlattenForCSharp
keyboardDrummer 903f2bf
Trigger CI
keyboardDrummer 5d9dc07
Merge branch 'noFlattenForCSharp' of github.com:keyboardDrummer/dafny…
keyboardDrummer 9477c6f
Fixes
keyboardDrummer b919fa8
Refactoring
keyboardDrummer c6de95b
Add force integration tests code
keyboardDrummer 0672492
Merge branch 'master' into noFlattenForCSharp
keyboardDrummer 3c86dd7
Convert if else chains to switch
keyboardDrummer e45420a
Merge commit 'a748799eef1d7~1' into noFlattenForCSharp
keyboardDrummer b8de307
Merge commit 'a748799eef1d7' into noFlattenForCSharp
keyboardDrummer f97bf09
Merge remote-tracking branch 'origin/master' into noFlattenForCSharp
keyboardDrummer 75bb47e
Ran formatter
keyboardDrummer e1bb707
Refactoring
keyboardDrummer dbcb4a4
Further refactoring
keyboardDrummer 420a13b
Further refactoring
keyboardDrummer 5f860c9
Attempt at using nested matches for all backends
keyboardDrummer 808d090
Use flattened matches for DafnyCodeGenerator
keyboardDrummer 126344a
Reintroduce flattening for Java
keyboardDrummer a1011f7
Fixes
keyboardDrummer 387b35f
Remove codeSize test
keyboardDrummer 49e0c55
Update expect files
keyboardDrummer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Attempt at using nested matches for all backends
- Loading branch information
commit 5f860c9482f2c94e9a384d5825fcc1adc56856cc
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -513,7 +513,160 @@ public abstract partial class SinglePassCodeGenerator { | |
} | ||
|
||
protected virtual void EmitNestedMatchStmt(NestedMatchStmt match, ConcreteSyntaxTree writer) { | ||
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. This is where the changes in this file start. |
||
TrStmt(match.Flattened, writer); | ||
EmitNestedMatchGeneric(match, (caseIndex, caseBody) => { | ||
TrStmtList(match.Cases[caseIndex].Body, caseBody); | ||
}, writer, false); | ||
} | ||
|
||
/// <summary> | ||
/// | ||
/// match a | ||
/// case X(Y(b),Z(W(c)) => body1 | ||
/// case r => body2 | ||
/// | ||
/// var unmatched = true; | ||
/// if (unmatched && a is X) { | ||
/// var x1 = ((X)a).1; | ||
/// if (x1 is Y) { | ||
/// var b = ((Y)x1).1; | ||
/// | ||
/// var x2 = ((X)a).2; | ||
/// if (x2 is Z) { | ||
/// var x4 = ((Z)x2).1; | ||
/// if (x4 is W) { | ||
/// var c = ((W)x4).1; | ||
/// body1; | ||
/// } | ||
/// } | ||
/// } | ||
/// } | ||
/// if (unmatched) { | ||
/// var r = a; | ||
/// body2; | ||
/// } | ||
/// | ||
/// </summary> | ||
private void EmitNestedMatchGeneric(INestedMatch match, Action<int, ConcreteSyntaxTree> emitBody, | ||
ConcreteSyntaxTree output, bool bodyExpected) { | ||
if (match.Cases.Count == 0) { | ||
if (bodyExpected) { | ||
// the verifier would have proved we never get here; still, we need some code that will compile | ||
EmitAbsurd(null, output); | ||
} | ||
} else { | ||
string sourceName = ProtectedFreshId("_source"); | ||
DeclareLocalVar(sourceName, match.Source.Type, match.Source.tok, match.Source, false, output); | ||
|
||
string unmatched = ProtectedFreshId("unmatched"); | ||
DeclareLocalVar(unmatched, Type.Bool, match.Source.Tok, Expression.CreateBoolLiteral(match.Source.Tok, true), false, output); | ||
|
||
var sourceType = match.Source.Type.NormalizeExpand(); | ||
for (var index = 0; index < match.Cases.Count; index++) { | ||
var myCase = match.Cases[index]; | ||
var lastCase = index == match.Cases.Count - 1; | ||
var result = EmitIf(out var guardWriter, false, output); | ||
guardWriter.Write(unmatched); | ||
var innerWriter = EmitNestedMatchCaseConditions(sourceName, sourceType, myCase.Pat, result, lastCase); | ||
Coverage.Instrument(myCase.Tok, "case body", innerWriter); | ||
EmitAssignment(unmatched, Type.Bool, False, Type.Bool, innerWriter); | ||
|
||
emitBody(index, innerWriter); | ||
} | ||
|
||
if (bodyExpected) { | ||
EmitAbsurd(null, output); | ||
} | ||
} | ||
} | ||
|
||
private ConcreteSyntaxTree EmitNestedMatchCaseConditions(string sourceName, | ||
Type sourceType, | ||
ExtendedPattern pattern, ConcreteSyntaxTree writer, bool lastCase) { | ||
|
||
var litExpression = MatchFlattener.GetLiteralExpressionFromPattern(pattern); | ||
if (litExpression != null) { | ||
var thenWriter = EmitIf(out var guardWriter, false, writer); | ||
CompileBinOp(BinaryExpr.ResolvedOpcode.EqCommon, sourceType, litExpression.Type, pattern.Tok, Type.Bool, | ||
out var opString, out var preOpString, out var postOpString, out var callString, out var staticCallString, | ||
out _, out _, out _, out _, | ||
writer); | ||
var right = new ConcreteSyntaxTree(); | ||
EmitExpr(litExpression, false, right, writer); | ||
EmitBinaryExprUsingConcreteSyntax(guardWriter, Type.Bool, preOpString, opString, new LineSegment(sourceName), right, callString, staticCallString, postOpString); | ||
writer = thenWriter; | ||
} else if (pattern is IdPattern idPattern) { | ||
if (idPattern.BoundVar != null) { | ||
var boundVar = idPattern.BoundVar; | ||
var valueWriter = DeclareLocalVar(IdName(boundVar), boundVar.Type, idPattern.Tok, writer); | ||
valueWriter.Write(sourceName); | ||
return writer; | ||
} else { | ||
writer = EmitNestedMatchStmtCaseConstructor(sourceName, sourceType, idPattern, writer, lastCase); | ||
} | ||
|
||
} else if (pattern is DisjunctivePattern disjunctivePattern) { | ||
string disjunctiveMatch = ProtectedFreshId("disjunctiveMatch"); | ||
DeclareLocalVar(disjunctiveMatch, Type.Bool, disjunctivePattern.Tok, Expression.CreateBoolLiteral(disjunctivePattern.Tok, false), false, writer); | ||
foreach (var alternative in disjunctivePattern.Alternatives) { | ||
var alternativeWriter = EmitNestedMatchCaseConditions(sourceName, sourceType, alternative, writer, lastCase); | ||
EmitAssignment(disjunctiveMatch, Type.Bool, True, Type.Bool, alternativeWriter); | ||
} | ||
writer = EmitIf(out var guardWriter, false, writer); | ||
guardWriter.Write(disjunctiveMatch); | ||
} else { | ||
throw new Exception(); | ||
} | ||
|
||
return writer; | ||
} | ||
|
||
private ConcreteSyntaxTree EmitNestedMatchStmtCaseConstructor(string sourceName, Type sourceType, | ||
IdPattern idPattern, | ||
ConcreteSyntaxTree result, bool lastCase) { | ||
var ctor = idPattern.Ctor; | ||
|
||
if (!lastCase && ctor.EnclosingDatatype.Ctors.Count != 1) { | ||
result = EmitIf(out var guardWriter, false, result); | ||
EmitConstructorCheck(sourceName, ctor, guardWriter); | ||
} | ||
|
||
var userDefinedType = (UserDefinedType)sourceType.NormalizeExpand(); | ||
|
||
var typeSubstMap = | ||
TypeParameter.SubstitutionMap(userDefinedType.ResolvedClass.TypeArgs, userDefinedType.TypeArgs); | ||
int nonGhostIndex = 0; // number of processed non-ghost arguments | ||
for (int index = 0; index < ctor.Formals.Count; index++) { | ||
var arg = ctor.Formals[index]; | ||
|
||
if (arg.IsGhost) { | ||
continue; | ||
} | ||
|
||
var type = arg.Type.Subst(typeSubstMap); | ||
// ((Dt_Ctor0)source._D).a0; | ||
var destructor = new ConcreteSyntaxTree(); | ||
EmitDestructor(wr => EmitIdentifier(sourceName, wr), arg, nonGhostIndex, ctor, | ||
() => SelectNonGhost(userDefinedType.ResolvedClass, userDefinedType.TypeArgs), type, destructor); | ||
|
||
if (idPattern.Arguments != null) { | ||
string newSourceName; | ||
var childPattern = idPattern.Arguments[index]; | ||
if (childPattern is IdPattern { BoundVar: not null } childIdPattern) { | ||
var boundVar = childIdPattern.BoundVar; | ||
newSourceName = IdName(boundVar); | ||
var valueWriter = DeclareLocalVar(newSourceName, boundVar.Type, idPattern.Tok, result); | ||
valueWriter.Append(destructor); | ||
} else { | ||
newSourceName = ProtectedFreshId(arg.CompileName); | ||
var valueWriter = DeclareLocalVar(newSourceName, type, idPattern.Tok, result); | ||
valueWriter.Append(destructor); | ||
result = EmitNestedMatchCaseConditions(newSourceName, type, childPattern, result, lastCase); | ||
} | ||
} | ||
nonGhostIndex++; | ||
} | ||
|
||
return result; | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This is where the changes in this file start.