<br><br><div class="gmail_quote">On Thu, Jan 13, 2011 at 9:33 AM, Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br><br><div class="gmail_quote"><div class="im">On Thu, Jan 13, 2011 at 2:29 AM, Bert Freudenberg <span dir="ltr">&lt;<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Here&#39;s another decompiler problem that I actually ran into in production code. When decompiling this method, either the block-local temp should remain block-local, or one of the vars needs to be renamed:<br>
<br>
blockLocalsAndArgs<br>
        | product |<br>
        product := 1.<br>
        1 to: 2 do: [:i |<br>
                i = 1<br>
                        ifTrue: [ | factor | factor := 6.<br>
                                product := product * factor ]<br>
                        ifFalse: [ #(9) do: [:factor |<br>
                                product := product * factor ] ] ].<br>
        ^ product = 13r42<br>
<br>
This works fine if decompiled without temps but the standard in Squeak is to use the actual temp names - just accept this as a method and switch to decompiled view.<br>
<br>
The best fix might be if the decompiler always declared the variables in the inner-most block possible. Maybe moving the declarations is not even that hard to do as a post-process on the AST?<br></blockquote><div><br></div>

</div><div>Right.  And there&#39;s now a visitor method for determining that scope, TempScopeEditor&gt;&gt;#blockNode:isEnclosingScopeFor:.  But I&#39;ve been too lazy^H^H^H^Hbusy to apply it in the context of the decompiler.  Feel free to feel motivated...</div>
</div></blockquote><div><br></div><div>No, no, no, no, no, no, no.  The visitor is VariableScopeFinder and the method is ofVariable: so aParseNode accept: (VariableScopeFinder new ofVariable: var) answers nil or the smallest enclosing scope for var in aParseNode.  See Parser&gt;&gt;declareUndeclaredTemps.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="gmail_quote">
<div><br></div><div>best</div><div>Eliot</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
- Bert -<br>
<br>
On 13.01.2011, at 00:51, Nicolas Cellier wrote:<br>
<br>
&gt; Follow up on unused temps :<br>
&gt;<br>
&gt; Wanna play with temps ? Try this :<br>
&gt;<br>
&gt; testUnusedVariable<br>
&gt;       self<br>
&gt;               compiling: &#39;griffle | goo | ^nil&#39;<br>
&gt;               shouldRaise: UnusedVariable;<br>
&gt;               compiling: &#39;griffle | | ^[ | goo | ]&#39;<br>
&gt;               shouldRaise: UnusedVariable;<br>
&gt;               compiling: &#39;griffle | | [ | goo | goo := nil. goo] yourself. ^[ | goo | ]&#39;<br>
&gt;               shouldRaise: UnusedVariable;<br>
&gt;               compiling: &#39;griffle | | [ | goo | ] yourself. ^[ | goo | goo := nil. goo]&#39;<br>
&gt;               shouldRaise: UnusedVariable<br>
&gt;<br>
&gt; What happens is that Parser.scopeTable has a single entry for &#39;goo&#39;.<br>
&gt; Consequently, the last registered goo wins.<br>
&gt; In the 3rd case, the last goo is unused, so hasRef = false, so<br>
&gt; UnusedVariable is raised.<br>
&gt; In the 4th case, the last goo nowHasRef, and we don&#39;t get any UnusedVariable.<br>
&gt;<br>
&gt; Until we get a scopeTable mapping each temp of each block, we gonna<br>
&gt; live in trouble.<br>
&gt;<br>
&gt; Nicolas<br>
<br>
<br>
<br>
</blockquote></div></div><br>
</blockquote></div><br>