On 18 May 2018, at 10:39, Marcus Denker <marcus.denker@inria.fr> wrote:
Hi,
the #binding: API until now did not allow to shadow globals. But there is actually no reason to forbid that (and it can actually be interesting, e.g. to compile code where one class ref is switched to another).
The Pull Request does:
- add comment to OCExtraBindingScope - categorize tests - change #lookupVar: to allow shadowing of Globals. - change test to reflect the new behaviour
This means you can do:
result := Smalltalk compiler bindings: {(#Object -> Point)} asDictionary; evaluate: 'Object newâ.
So what can we do with this? If you develop a compiler, it is always very annoying that any change that you do actually breaks the compiler if you do it wrong. Larger changes over multiple methods get quite hard to do. One thing that we will soon have is the âaccept for testâ feature that I posted recently. Another idea is to use the #bindings: feature of the compiler. I did small experiment, I added this method to the OpalCompiler class on the class side: prepareForDevelopment "this method sets up an overlay in the global var CompilerOverlay" <script> | overlayEnvironment | overlayEnvironment := Dictionary new. Smalltalk globals at: #CompilerOverlay put: overlayEnvironment. "now we put a copy of all the classes of the compiler package into the environment" self package definedClasses do: [ :class | overlayEnvironment at: class name put: class copy]. âthen we recompile the classes in the environment with itself as an overlay" overlayEnvironment valuesDo: [ :class | class methods do: [ :method | |newMethod| newMethod := class compiler bindings: overlayEnvironment; compile: method sourceCode. class addSelectorSilently: method selector withMethod: newMethod. ]]. After that is done, we have CompilerOverlay global that contains a copy of all the classes of the compiler recompiled so that they use all the classes inside this copy. So we now can set this copy as the main compiler for the image: SmalltalkImage compilerClass: (CompilerOverlay at: #OpalCompiler) And after that, you can put a #halt deep in the compiler (or do some change that needs multiple steps), yet compilation will not be affected. Most tests (not all) are writing in a way that they use classes from the package directly (they do not go via the global #compilerClass setting). So this means that one can now change the compiler as much as one wants, test it by running tests and then be quite sure that it will not break anything. Shortcomings: -> extensions are not treated, only the main package -> Not used much, for sure needs testing to see if this really works. -> Can we get rid of the #CompilerOverlay global? Marcus