'From Cuis 2.0 of 24 February 2010 [latest update: #440] on 2 March 2010 at 3:27:45 pm'!

!CompiledMethod methodsFor: 'code analysis' stamp: 'jmv 2/28/2010 22:37'!
scanForEqSmallConstant

    "Dan Ingalls' search for arithmetic use of ==
Answer whether the receiver contains the pattern <expression> == <constant>,
where constant is -1, 0, 1, or 2...
	Smalltalk browseAllSelect: [:m | m scanForEqSmallConstant]
"



    | scanner |

    scanner _ InstructionStream on: self.

    ^ scanner scanFor: [:instr | (instr between: 116 and: 119) and: [scanner followingByte = 198]]



"

Smalltalk browseAllSelect: [:m | m scanForEqSmallConstant]

"! !


!Inspector methodsFor: 'menu commands' stamp: 'jmv 2/28/2010 22:33'!
chasePointers
	| selected  saved |
	self selectionIndex = 0 ifTrue: [^ self changed: #flash].
	selected := self selection.
	saved := self object.
	[self object: nil.
	(Smalltalk includesKey: #PointerFinder)
		ifTrue: [PointerFinder on: selected]
		ifFalse: [self inspectPointers]]
		ensure: [self object: saved]! !


!MessageNode methodsFor: 'printing' stamp: 'jmv 3/1/2010 10:20'!
printToDoOn: aStream indent: level

	| limitNode |
	self printReceiver: receiver on: aStream indent: level.

	(arguments last == nil or: [(arguments last isMemberOf: AssignmentNode) not])
		ifTrue: [limitNode := arguments first]
		ifFalse: [limitNode := arguments last value].
	(selector key = #to:by:do:
	 and: [(arguments at: 2) isConstantNumber
	 and: [(arguments at: 2) key = 1]])
		ifTrue: [self printKeywords: #to:do:
					arguments: (Array with: limitNode with: (arguments at: 3))
					on: aStream indent: level]
		ifFalse: [self printKeywords: selector key
					arguments: (Array with: limitNode) , arguments allButFirst
					on: aStream indent: level]! !

!MessageNode methodsFor: 'printing' stamp: 'jmv 3/1/2010 10:20'!
printWithClosureAnalysisToDoOn: aStream indent: level

	| limitNode |
	self printWithClosureAnalysisReceiver: receiver on: aStream indent: level.

	limitNode := (arguments last == nil
				or: [arguments last isAssignmentNode not])
					ifTrue: [arguments first]
					ifFalse: [arguments last value].
	(selector key = #to:by:do:
	 and: [(arguments at: 2) isConstantNumber
	 and: [(arguments at: 2) key = 1]])
		ifTrue: [self printWithClosureAnalysisKeywords: #to:do:
					arguments: (Array with: limitNode with: (arguments at: 3))
					on: aStream indent: level]
		ifFalse: [self printWithClosureAnalysisKeywords: selector key
					arguments: (Array with: limitNode) , arguments allButFirst
					on: aStream indent: level]! !


!Parser methodsFor: 'scanning' stamp: 'jmv 3/1/2010 10:08'!
advance
	| this |
	prevMark := hereMark.
	prevEnd := hereEnd.
	this := here.
	here := token.
	hereType := tokenType.
	hereMark := mark.
	hereEnd := source position - (source atEnd ifTrue: [hereChar = 30 asCharacter ifTrue: [0] ifFalse: [1]] ifFalse: [2]).
	self scanToken.
	"Transcript show: 'here: ', here printString, ' mark: ', hereMark printString, ' end: ', hereEnd printString; cr."
	^this! !


!Semaphore methodsFor: 'mutual exclusion' stamp: 'jmv 3/1/2010 10:23'!
critical: mutuallyExcludedBlock ifLocked: alternativeBlock
	"Evaluate mutuallyExcludedBlock only if the receiver is not currently in 
	the process of running the critical: message. If the receiver is, evaluate 
	mutuallyExcludedBlock after the other critical: message is finished."
	
	"Note: The following is tricky and depends on the fact that the VM will not switch between processes while executing byte codes (process switches happen only in real sends). The following test is written carefully so that it will result in bytecodes only.
	Do not change the following #== for #=, as #== is not a real message send, just a bytecode."
	excessSignals == 0 ifTrue: [
		"If we come here, then the semaphore was locked when the test executed. 
		Evaluate the alternative block and answer its result."
		^alternativeBlock value 
	].
	^self critical: mutuallyExcludedBlock! !


!Socket methodsFor: 'receiving' stamp: 'jmv 2/28/2010 22:35'!
receiveDataInto: aStringOrByteArray startingAt: aNumber
	"Receive data into the given buffer and return the number of bytes received. 
	Note the given buffer may be only partially filled by the received data.
	Waits for data once.  The answer may be zero (indicating that no data was 
	available before the socket closed)."

	| bytesRead closed |
	bytesRead := 0.
	closed := false.
	[closed not and: [bytesRead = 0]]
		whileTrue: [
			self waitForDataIfClosed: [closed := true].
			bytesRead := self primSocket: socketHandle
				receiveDataInto: aStringOrByteArray
				startingAt: aNumber
				count: aStringOrByteArray size-aNumber+1].
	^bytesRead
! !

!Socket methodsFor: 'receiving' stamp: 'jmv 2/28/2010 22:35'!
receiveDataSignallingClosedInto: aStringOrByteArray startingAt: aNumber
	"Receive data into the given buffer and return the number of bytes received. 
	Note the given buffer may be only partially filled by the received data.
	Waits for data until something is read or the socket is closed, upon which
	we signal."

	| bytesRead |
	bytesRead := 0.
	[bytesRead = 0]
		whileTrue: [
			self waitForData.
			bytesRead := self primSocket: socketHandle
				receiveDataInto: aStringOrByteArray
				startingAt: aNumber
				count: aStringOrByteArray size-aNumber+1].
	^bytesRead
! !


!Symbol methodsFor: 'testing' stamp: 'jmv 3/1/2010 10:07'!
isKeyword
	"Answer whether the receiver is a message keyword."

	^ self precedence = 3! !


!SystemDictionary methodsFor: 'browsing' stamp: 'jmv 3/2/2010 09:20'!
browseEqSmallConstant

    "Dan Ingalls' search for arithmetic use of ==
Answer whether the receiver contains the pattern <expression> == <constant>,
where constant is -1, 0, 1, or 2...
	Smalltalk browseEqSmallConstant
"

	Smalltalk browseAllSelect: [:m | m scanForEqSmallConstant]! !


!Time methodsFor: 'printing' stamp: 'jmv 2/28/2010 22:35'!
print24: hr24 showSeconds: showSeconds on: aStream 
	"Format is 'hh:mm:ss' or 'h:mm:ss am'  or, if showSeconds is false, 'hh:mm' or 'h:mm am'"

	| h m s |
	h := self hour. m := self minute. s := self second.
	hr24
		ifTrue: 
			[ h < 10 ifTrue: [ aStream nextPutAll: '0' ].
			h printOn: aStream ]
		ifFalse:
			[ h > 12
				ifTrue: [h - 12 printOn: aStream]
				ifFalse: 
					[h < 1
						ifTrue: [ 12 printOn: aStream ]
						ifFalse: [ h printOn: aStream ]]].

	aStream nextPutAll: (m < 10 ifTrue: [':0'] ifFalse: [':']).
	m printOn: aStream.

	showSeconds ifTrue:
		[ aStream nextPutAll: (s < 10 ifTrue: [':0'] ifFalse: [':']).
		self nanoSecond = 0
			ifTrue: [s asInteger printOn: aStream]
			ifFalse: [(s + (self nanoSecond / NanosInSecond) asFloat) printOn: aStream]].

	hr24 ifFalse:
		[ aStream nextPutAll: (h < 12 ifTrue: [' am'] ifFalse: [' pm']) ].
! !

