-
Notifications
You must be signed in to change notification settings - Fork 260
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
feat: Modules in the python backend #1871
Conversation
Source/Dafny/Compilers/Compiler.cs
Outdated
@@ -1194,6 +1196,8 @@ public enum ResolvedUnaryOp { BoolNot, BitwiseNot, Cardinality } | |||
var w = DeclareDatatype(dt, wr); | |||
if (w != null) { | |||
CompileClassMembers(program, dt, w); | |||
} else if (this is not CppCompiler) { |
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.
The alternative is living with a \n
when there's a tuple. I personally don't like either.
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.
Could this be an attribute of each of the compilers that the main code checks to decide whether to add the \n
?
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 code is a little strange, we always add a \n
in L1161 for every TopLevelDecl that's compiled. Sometimes we only find out later that we don't have to do anything. This leaves unsightly whitespace in the generated sources. Looking it is no fun.
The concrete problem here is a hack in the cpp compiler. They include the ClassMembers on the first pass, so they can't have the second one. To avoid that, they act like they didn't do anything.
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.
Sounds like we can still define an attribute, even if it's a weird name like CompilesClassMembersOnTheFirstPass
or whatever. :)
Referring to concrete subclasses here is just a recipe for weird hard-to-debug edge cases as we add more compilers.
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.
Now, it's this one field we happen to overwrite in this one compiler.
Source/Dafny/Compilers/Compiler.cs
Outdated
@@ -1238,8 +1242,10 @@ public enum ResolvedUnaryOp { BoolNot, BitwiseNot, Cardinality } | |||
} | |||
} else if (d is ValuetypeDecl) { | |||
// nop | |||
wr.DeleteLast(); |
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.
That's a bit scary: are we sure that we know which character this will be deleting?
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.
Reasonably so, the test go trough after all. At least in this case it should be.
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.
I agree this is very risky and makes the code an order of magnitude harder to reason about confidently. I'd define whatever additional Compiler
attributes you need to specialize the behavior without doing this.
I hesitate to even mention it, but IF this was absolutely necessary, I would at least provide an argument to DeleteLast
to specify WHAT you expect to be deleted, so at least you have a chance of catching bugs if the state is ever not what you thought it would be.
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.
I think it's reasonably nice now.
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.
Thanks for starting to tackle the confusing labelling on the BraceStyle
enum!
compiledName = IdProtect((string)idParam); | ||
break; | ||
default: | ||
Contract.Assert(false); // unexpected ID |
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.
I'd prefer throwing an exception instead. Contract.Assert
is turned off for release builds, and we don't the chance of a user hitting this case and failing in a weird way elsewhere because of the default ""
value.
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 a very common pattern in our code base and all the other implementations of GetSpecialFieldInfo
do it this way, but I can change it if you feel strongly about it. I'd argue that a user will notice it at the very latest when their generated code doesn't compile.
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.
Okay, I'll let it go for now. I'll consider this something we should clean up when we address #1390 more generally.
@@ -7,10 +7,11 @@ | |||
|
|||
namespace Microsoft.Dafny { | |||
public enum BraceStyle { |
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.
Since you're already touching most of the references to this type, I think the time is right to fix the name and call it BlockStyle
instead. That will resolve the weird redundancy in BraceStyle.Brace
and just plain contradiction in BraceStyle.NewlineNoBrace
(which would just become BlockStyle.Newline
).
I think then Space
would also be renamed to SpaceBrace
?
Source/Dafny/Compilers/Compiler.cs
Outdated
@@ -1194,6 +1196,8 @@ public enum ResolvedUnaryOp { BoolNot, BitwiseNot, Cardinality } | |||
var w = DeclareDatatype(dt, wr); | |||
if (w != null) { | |||
CompileClassMembers(program, dt, w); | |||
} else if (this is not CppCompiler) { |
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.
Sounds like we can still define an attribute, even if it's a weird name like CompilesClassMembersOnTheFirstPass
or whatever. :)
Referring to concrete subclasses here is just a recipe for weird hard-to-debug edge cases as we add more compilers.
Source/Dafny/Compilers/Compiler.cs
Outdated
@@ -1238,8 +1242,10 @@ public enum ResolvedUnaryOp { BoolNot, BitwiseNot, Cardinality } | |||
} | |||
} else if (d is ValuetypeDecl) { | |||
// nop | |||
wr.DeleteLast(); |
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.
I agree this is very risky and makes the code an order of magnitude harder to reason about confidently. I'd define whatever additional Compiler
attributes you need to specialize the behavior without doing this.
I hesitate to even mention it, but IF this was absolutely necessary, I would at least provide an argument to DeleteLast
to specify WHAT you expect to be deleted, so at least you have a chance of catching bugs if the state is ever not what you thought it would be.
|
||
var customReceiver = !forBodyInheritance && NeedsCustomReceiver(m); |
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.
Did all of this disappear because customReceiver
is never true in our test cases so far?
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.
Exactly.
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.
Great, I'm definitely in favour of removing code with no testing coverage (assuming it's not easy to add a test instead).
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.
Much better, thanks for the improvements! Just the one small tweak and then LGTM.
compiledName = IdProtect((string)idParam); | ||
break; | ||
default: | ||
Contract.Assert(false); // unexpected ID |
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.
Okay, I'll let it go for now. I'll consider this something we should clean up when we address #1390 more generally.
protected abstract ConcreteSyntaxTree CreateIterator(IteratorDecl iter, ConcreteSyntaxTree wr); | ||
/// <summary> | ||
/// Returns an IClassWriter that can be used to write additional members. If "dt" is already written | ||
/// in the DafnyRuntime.targetlanguage file, then returns "null". | ||
/// </summary> | ||
protected abstract IClassWriter/*?*/ DeclareDatatype(DatatypeDecl dt, ConcreteSyntaxTree wr); | ||
protected virtual bool DatatypeDeclarationAndMemberCompilationAreSeparate => true; |
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.
Much better name than my suggestion :)
@@ -114,6 +115,12 @@ public T Append<T>(T node) | |||
return this; | |||
} | |||
|
|||
public void DeleteLast() { |
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.
Very glad we don't need this any more. Now let's remove the method so no one is tempted by the dark side in the future. :)
public enum BraceStyle { | ||
public enum BlockStyle { | ||
Nothing, | ||
Space, | ||
Newline, | ||
NewlineNoBrace | ||
Brace, | ||
SpaceBrace, | ||
NewlineBrace | ||
} |
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.
SO much better, thank you!
Adds support for modules, and increases the stinginess w.r.t. whitespace in the generated code.
By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.