Hi All,<div><br></div><div> I just got bittenhard (not for the first time) by & and | (implemented both by integers and booleans) being translated into && (== and:) and || (== or:). So the following in constant folding in the StackToRegisterMappingCogit</div>
<div><br></div><div><div><span class="Apple-tab-span" style="white-space:pre">        </span>(argIsInt and: [rcvrIsInt]) ifTrue:</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>[rcvrInt := objectMemory integerValueOf: rcvrInt.</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span> argInt := objectMemory integerValueOf: argInt.</div><div><span class="Apple-tab-span" style="white-space:pre">                </span> primDescriptor opcode caseOf: {</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>[AddRR]<span class="Apple-tab-span" style="white-space:pre">        </span>-> [result := rcvrInt + argInt].</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>[SubRR]<span class="Apple-tab-span" style="white-space:pre">        </span>-> [result := rcvrInt - argInt].</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>[AndRR]<span class="Apple-tab-span" style="white-space:pre">        </span>-> [result := rcvrInt &: argInt].</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>[OrRR]<span class="Apple-tab-span" style="white-space:pre">        </span>-> [result := rcvrInt | argInt] }.</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>(objectMemory isIntegerValue: result) ifTrue:</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>["Must annotate the bytecode for correct pc mapping."</div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>self annotateBytecode: self Label.</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>^self ssPop: 2; ssPushConstant: (objectMemory integerObjectOf: result)].</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>^self genSpecialSelectorSend].</div></div><div><br></div><div>produced valid results in the simulator, but was translated to</div><div><br></div><div><div>
if (argIsInt</div><div> && (rcvrIsInt)) {</div><div> rcvrInt = (rcvrInt >> 1);</div><div> argInt = (argInt >> 1);</div><div><br></div><div> switch ((primDescriptor->opcode)) {</div>
<div> case AddRR:</div><div> result = rcvrInt + argInt;</div><div> break;</div><div> case SubRR:</div><div> result = rcvrInt - argInt;</div><div> break;</div>
<div> case AndRR:</div><div> result = rcvrInt && argInt;</div><div> break;</div><div> case OrRR:</div><div> result = rcvrInt || argInt;</div><div>
break;</div><div> default:</div><div> error("Case not found and no otherwise clause");</div><div> }</div><div> if (isIntegerValue(result)) {</div><div> annotateBytecode(gLabel());</div>
<div> return ssPop(2),ssPushConstant(((result << 1) | 1));</div><div> }</div><div> return genSpecialSelectorSend();</div><div> }</div></div><div><br></div><div>and so e.g. 16r4000 bitOr: 16r8000 evaluated to 1, not 49152.</div>
<div><br></div><div>Three approaches come to mind, </div><div>a) emit a warning when & and | are used with variables and/or literals as opposed to message sends, e.g. warn for 1 | 2, var | var et al, but not for (a > b) | (b > c) et al</div>
<div>b) translate | to | and & to &</div><div>c) translate expr | expr to expr || expr and expr & expr to expr && expr, but translate varOrLiteral | anything to varOrLiteral | anything and varOrLiteral & anything to varOrLiteral & anything, and vice verse.</div>
<div><br></div><div>I'm for b) since a relational expression such as a > 1 is defined in C to be either 1 or 0, and so in C (oneOrZero | oneOrZero) == (oneOrZero || oneOrZero) and (oneOrZero & oneOrZero) == (oneOrZero && oneOrZero).</div>
<div><br></div><div>Thoughts, opinions?</div><div><br></div><div>best (hurting),</div><div>Eliot</div>