["BUG"][FIX?]Incorrect Pseudo-Codefor#whileTrue:/#whileFalse:?

Bob Arning arning at charm.net
Sat Jan 6 04:21:22 UTC 2001


Hi Mark,

On Fri, 05 Jan 2001 21:45:29 -0600 Mark van Gulik <ghoul6 at home.net> wrote:
>On a hunch I tried stepping through this in the debugger.  As I suspected,
>it failed on the *second* call to jumpTo:.

That's not the only problem. The version I sent also fails for larger iteration counts. Below are several variations that do not suffer that problem. The one I like best from the readability perspective is #whileTrue4:, although it is not the fastest of the bunch.

Cheers,
Bob

-----code follows-----
'From Squeak2.9alpha of 17 July 2000 [latest update: #3231] on 5 January 2001 at 11:15:57 pm'!
"Change Set:		blockJump
Date:			4 January 2001
Author:			Bob Arning

Experimental implementation of #whileTrue: using Mark van Gulik's GOTO trick. 

Several flavors are tried and timings for all are compared.

The result are implementations that does not require compiler optimization and may cause less confusion."!


!ContextPart methodsFor: 'instruction decoding' stamp: 'RAA 1/5/2001 23:04'!
jumpTo: newPC stack: newSP

	self stackp: newSP.	"remove any extra"
	^pc _ newPC! !


!BlockContext methodsFor: 'controlling' stamp: 'RAA 1/5/2001 23:10'!
repeatEndlessly
	| loopAgain |
	"Evaluate the receiver repeatedly, ending only if the block explicitly returns."

	loopAgain _ thisContext pc.
	self value.
	thisContext jumpTo: loopAgain stack: 1.
	self halt.
! !

!BlockContext methodsFor: 'controlling' stamp: 'RAA 1/5/2001 23:01'!
whileTrue2: aBlock 
	| loopAgain |
"
| x |
x _ 0.
[(x _ x + 1) < 10] whileTrue2: [Transcript show: x printString; cr].
"
	loopAgain _ thisContext pc.
	self value ifFalse: [^self ].
	aBlock value.
	thisContext jumpTo: loopAgain stack: 2.
! !

!BlockContext methodsFor: 'controlling' stamp: 'RAA 1/4/2001 12:16'!
whileTrue2b: aBlock 
	| loopAgain |
"
| x |
x _ 0.
[(x _ x + 1) < 100] whileTrue2b: [Transcript show: x printString; cr].
"
	loopAgain _ thisContext pc + 5.	"5 is the size of the bytecodes for this statement"
	self value ifFalse: [^self].
	aBlock value.
	thisContext jumpTo: loopAgain stack: 2.
! !

!BlockContext methodsFor: 'controlling' stamp: 'RAA 1/4/2001 10:09'!
whileTrue3: aBlock 

"
| x |
x _ 0.
[(x _ x + 1) < 100] whileTrue3: [Transcript show: x printString; cr].
"
	self value ifFalse: [^self].
	aBlock value.
	thisContext restart.
! !

!BlockContext methodsFor: 'controlling' stamp: 'RAA 1/4/2001 10:21'!
whileTrue4: aBlock 

"
| x |
x _ 0.
[(x _ x + 1) < 100] whileTrue4: [Transcript show: x printString; cr].
"
	[
		self value ifFalse: [^self].
		aBlock value.
	] repeatEndlessly
! !

!BlockContext methodsFor: 'controlling' stamp: 'RAA 1/4/2001 11:58'!
whileTrueTests
"
[] whileTrueTests
"
	| x loops t0 t1 t2 t2b t3 t4 b1 |

	loops _ 1024 * 1024.
	x _ 0. b1 _ [(x _ x + 1) < loops].
	x _ 0. t0 _ [[(x _ x + 1) < loops] whileTrue: []] timeToRun.
	x _ 0. t1 _ [b1 whileTrue: []] timeToRun.
	x _ 0. t2 _ [b1 whileTrue2: []] timeToRun.
	x _ 0. t2b _ [b1 whileTrue2b: []] timeToRun.
	x _ 0. t3 _ [b1 whileTrue3: []] timeToRun.
	x _ 0. t4 _ [b1 whileTrue4: []] timeToRun.
	{t0. t1. t2. t2b. t3. t4} inspect.
! !

!BlockContext methodsFor: 'controlling' stamp: 'RAA 1/4/2001 12:10'!
whileTrueTests2
"
[] whileTrueTests2
"
	| x loops t0 t1 t2 t2b t3 t4 b1 argBlock |

	loops _ 1024 * 1024.
	x _ 0. b1 _ [(x _ x + 1) < loops].
	argBlock _ [x + x + x // 3].
	"the literal version"
	x _ 0. t0 _ [[(x _ x + 1) < loops] whileTrue: [x + x + x // 3]] timeToRun.

	"the variable versions"
	x _ 0. t1 _ [b1 whileTrue: argBlock] timeToRun.
	x _ 0. t2 _ [b1 whileTrue2: argBlock] timeToRun.
	x _ 0. t2b _ [b1 whileTrue2b: argBlock] timeToRun.
	x _ 0. t3 _ [b1 whileTrue3: argBlock] timeToRun.
	x _ 0. t4 _ [b1 whileTrue4: argBlock] timeToRun.
	{t0. t1. t2. t2b. t3. t4} inspect.
! !





More information about the Squeak-dev mailing list