<br><br><div class="gmail_quote">On Tue, Mar 3, 2009 at 11:58 AM, John M McIntosh <span dir="ltr"><<a href="mailto:johnmci@smalltalkconsulting.com">johnmci@smalltalkconsulting.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
Er, well the shift left/right assembler operations are signed or unsigned, but TYPED languages usually figure out which one to use based on the type of the operators.</blockquote><div><br></div><div>Forget about assembler. In C "signed >> expr" is an arithmetic (signed) shift; "unsigned >> expr" is a logical (unsigned) one. In Smalltalk "negative bitShift: negative" is an arithmetic shift, "non-negative bitShift: negative" is a logical one. These are perfectly compatible, and both are useful. In Smalltalk you can always write</div>
<div> (foo bitAnd: (1 bitShift: preShiftFieldWidth) - 1) bitShift: expr</div><div>if you want to perform a logical shift.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
But since Smalltalk is type-less,</blockquote><div><br></div><div>No, that's not it. In fact, Smalltalk is strongly typed. Try bit shifting true. Quite possible in C; not possible in Smalltalk. Smalltalk has infinite precision so an unsigned value is simply a non-negative one. The reason, I think, that Slang casts to unsigned is a hack to do with the default type of oops being sqInt (signed). But this is a mistake. Look at the definition of primitiveBitShift and ask yourself why this even works?</div>
<div><br></div><div><div>primitiveBitShift </div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| integerReceiver integerArgument shifted |</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>integerArgument := self popInteger.</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>integerReceiver := self popPos32BitInteger.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>self successful ifTrue: [</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>integerArgument >= 0 ifTrue: [</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>"Left shift -- must fail if we lose bits beyond 32"</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>self success: integerArgument <= 31.</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>shifted := integerReceiver << integerArgument.</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>self success: (shifted >> integerArgument) = integerReceiver.</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>] ifFalse: [</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>"Right shift -- OK to lose bits"</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>self success: integerArgument >= -31.</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>shifted := integerReceiver bitShift: integerArgument.</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>].</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>self successful</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>ifTrue: [self push: (self positive32BitIntegerFor: shifted)]</div><div>
<span class="Apple-tab-span" style="white-space:pre">                </span>ifFalse: [self unPop: 2]</div><div><br></div><div>It took me a few minutes of staring at</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>shifted := integerReceiver bitShift: integerArgument.</div>
<div>(which can't possibly work for negative values if Slang, as it does, casts to unsigned) before I realised that</div><div><br></div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>integerReceiver := self popPos32BitInteger.</div>
<div><br></div><div>means the primitive simply fails for negative receivers (!!!!!!!!!!!!!).</div><div><br></div><div>I've noticed this before and I've forgotten it (I'm a bit like a goldfish in that regard) and I find it no less shocking each time I trip over it.</div>
</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">What if you code up a unsigned shift operator so there is no question that you want to do unsigned shifting, which also makes the SLANG coder just a bit more aware he has a choice to make, casting is ok, but people forget. Also I can do senders of, then later wonder why am I not doing that here/there?</blockquote>
<div><br></div><div>Right. I've recently added #asUnsignedInteger as a concise cast to unsigned.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Having been bitten by signed shifting issues in the past, I can agree it's unpleasant.</blockquote><div><br></div><div><br></div><div><br></div><div>So look, surely shifts should be signed by default and be unsigned if the argument is unsigned, e.g./i.e.</div>
<div><br></div><div><div>!Integer methodsFor: '*VMMaker-interpreter simulator' stamp: 'eem 2/19/2009 18:33'!</div><div>asUnsignedInteger</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>self assert: self >= 0.</div>
<div><span class="Apple-tab-span" style="white-space: pre; ">        </span>^self! !</div><div><br></div><div>and in CCodeGenerator>>initializeCTranslationDictionary:</div><div> ...</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>#asUnsignedInteger<span class="Apple-tab-span" style="white-space: pre; ">                        </span>#generateAsUnsignedInteger:on:indent:</div>
<div> ...</div><div><br></div><div>and</div><div><div>!CCodeGenerator methodsFor: 'C translation' stamp: 'eem 2/15/2009 16:38'!</div><div>generateAsUnsignedInteger: msgNode on: aStream indent: level</div>
<div><span class="Apple-tab-span" style="white-space: pre; ">        </span>"Generate the C code for this message onto the given stream."</div><div><br></div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>aStream nextPutAll:'((usqInt)'.</div>
<div><span class="Apple-tab-span" style="white-space: pre; ">        </span>self emitCExpression: msgNode receiver on: aStream.</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>aStream nextPut: $)! !</div>
<div><br></div></div></div><div>and I autochange all senders of >> and bitShift: throughout the plugins, primitives and Interpreter to use asUnsignedInteger. Do I dare? Am I insane?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
<br>
PS I note we have methods to do unsigned compare logic when dealing with oop address so that *we* know we are doing something special, since people just couldn't manage the casts correctly.<div><div></div><div class="h5">
<br>
<br>
On 3-Mar-09, at 11:50 AM, Eliot Miranda wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi All,<br>
<br>
I'm being bitten by Slang's treatment of bitShift: & >>. In both cases (generateBitShift:on:indent: & generateShiftRight:on:indent:) Slang generates an unsigned shift by explicitly casting the shifted expression to usqInt. I can understand the benefit of having an unsigned shift. But there are times when one really needs a signed shift. Further, the Smalltalk versions of both bitShift: and >> are signed shifts.<br>
<br>
Dare I change e.g. generateShiftRight:on:indent: to leave the expression alone and generate either a signed or an unsigned shift based on the variable's declaration? Or must I live with a maddening cCode: '(signed)' inSmalltalk: [] carbuncle?<br>
<br>
E.<br>
</blockquote>
<br></div></div><font color="#888888">
--<br>
===========================================================================<br>
John M. McIntosh <<a href="mailto:johnmci@smalltalkconsulting.com" target="_blank">johnmci@smalltalkconsulting.com</a>><br>
Corporate Smalltalk Consulting Ltd. <a href="http://www.smalltalkconsulting.com" target="_blank">http://www.smalltalkconsulting.com</a><br>
===========================================================================<br>
<br>
<br>
<br>
</font></blockquote></div><br>