Thanks Juan. With the latest version of Eliot, the following are failing:<br><br>  self deny: [ | outerBlockTemp | [ outerBlockTemp printString ] isClean ] value.<br>  self deny: [ | outerBlockTemp | [ outerBlockTemp :=7 ] isClean ] value.<br>
  self deny: [ tempVar + 1 ] isClean.<br>  self deny: [ tempVar := 1 ] isClean.<br>  self deny: [ ClassVar + 1 ] isClean.<br>  self deny: [ ClassVar := 1 ] isClean.<br><br>Thanks<br><br><br><div class="gmail_quote">On Sat, Dec 3, 2011 at 3:01 AM, Juan Vuletich <span dir="ltr">&lt;<a href="mailto:juan@jvuletich.org">juan@jvuletich.org</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Eliot Miranda wrote:<div><div class="h5"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
On Fri, Dec 2, 20Tha11 at 4:01 PM, Juan Vuletich &lt;<a href="mailto:juan@jvuletich.org" target="_blank">juan@jvuletich.org</a> &lt;mailto:<a href="mailto:juan@jvuletich.org" target="_blank">juan@jvuletich.org</a>&gt;&gt; wrote:<br>

<br>
    Eliot Miranda wrote:<br>
<br>
        Hi Juan,<br>
<br>
        ...<br>
<br>
<br>
<br>
           I can say that it does indeed work. But I&#39;d be really<br>
        grateful if<br>
           Eliot took a good look at that code!<br>
<br>
<br>
        There is a much better way, using<br>
        InstructionStream&gt;&gt;<u></u>interpreetNextInstructionFor: which<br>
        abstracts away from the bytecode encoding and allows one to<br>
        simply use messages.  e.g. look at<br>
<br>
        and (SortedCollection sortBlock: [:a :b| a compare: b<br>
        caseSensitive: false]) sortBlock abstractBytecodes evaluates to<br>
<br>
        an OrderedCollection(#<u></u>pushTemporaryVariable:<br>
        #pushTemporaryVariable: #pushConstant: #send:super:numArgs:)<br>
<br>
        So a check for clean blocks would check for a block&#39;s<br>
        abstractBytecodes not including some particular set of banned<br>
        messages (which I *think* is pushReceiver<br>
        pushReceiverVariable: popIntoReceiverVariable:<br>
        storeIntoReceiverVariable: methodReturnConstant:<br>
        methodReturnReceiver methodReturnTop).<br>
<br>
        e.g.<br>
<br>
        isClean<br>
             ^(self abstractBytecodes intersection: #(pushReceiver<br>
        pushReceiverVariable: popIntoReceiverVariable:<br>
        storeIntoReceiverVariable: methodReturnConstant:<br>
        methodReturnReceiver methodReturnTop)) isEmpty<br>
<br>
<br>
           Cheers,<br>
           Juan Vuletich<br>
<br>
<br>
<br>
<br>
        --         best,<br>
        Eliot<br>
<br>
<br>
    Thanks Eliot. However, it looks to me that this needs more tweaking. <br>
<br>
&lt;blush&gt;Damn right :)  I&#39;ve done zero testing.  It was just an example&lt;/blush&gt;<br>
 <br>
    For instance, your method answers true for<br>
      [ xx size ] isClean<br>
    and<br>
      [ ^ nil ] isClean<br>
    while mine answers false for both. Maybe we could serialize non<br>
    local returns using the Compiler (although we won&#39;t be able to<br>
    return anywhere), but external variable acess is a problem.<br>
<br>
    Will keep playing with this for a while...<br>
<br>
<br>
Can you (can I??) write some tests?  What&#39;s xx in the above?  Ah! [^nil] isn&#39;t clean in my code since it should be pc &lt;= end, not pc &lt; end!!  Try the attached...<br>
</blockquote>
<br></div></div>
This is a start:<br>
<br>
testIsClean<br>
   &quot;<br>
   ClosureTests new testIsClean<br>
   &quot;<br>
   | tempVar |<br>
   tempVar := 1.<br>
   self assert: [ 3 + 4 ] isClean.<br>
   self assert: [ :a | a * 2 ] isClean.<br>
   self assert: [ Smalltalk size ] isClean.<br>
   self assert: [ :blockArg | blockArg printString ] isClean.<br>
   self assert: [ | blockTemp | blockTemp printString ] isClean.<br>
   self assert: [ | blockTemp | blockTemp :=7 ] isClean.<br>
   self deny: [ | outerBlockTemp | [ outerBlockTemp printString ] isClean ] value.<br>
   self deny: [ | outerBlockTemp | [ outerBlockTemp :=7 ] isClean ] value.<br>
   self deny: [ tempVar + 1 ] isClean.<br>
   self deny: [ tempVar := 1 ] isClean.<br>
   self deny: [ ivar + 1 ] isClean.<br>
   self deny: [ ivar := 1 ] isClean.<br>
   self deny: [ ^ true ] isClean.<br>
   self deny: [ self printString ] isClean.<br>
   self deny: [ ^ self ] isClean.<br>
   self deny: [ ClassVar + 1 ] isClean.<br>
   self deny: [ ClassVar := 1 ] isClean.<br>
<br>
This test passes with my implementation.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 <br>
<br>
    Cheers,<br>
    Juan Vuletich<br>
<br>
<br>
<br>
<br>
-- <br>
best,<br>
Eliot<br>
<br>
</blockquote>
<br></div>
Cheers,<span class="HOEnZb"><font color="#888888"><br>
Juan Vuletich<br>
<br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br>Mariano<br><a href="http://marianopeck.wordpress.com" target="_blank">http://marianopeck.wordpress.com</a><br><br>