'From Squeak6.0alpha of 19 January 586155 [latest update: #19594] on 22 April 2020 at 6:04:12 pm'!
Inspector subclass: #CogProcessorAlienInspectorRevised
	instanceVariableNames: 'alien registerSelectors pcSelector registerCache'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Cog-Processors'!
Model subclass: #CogProcessorAlienMock
	instanceVariableNames: 'bitsInWord'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Cog-Processors'!

!CogProcessorAlienInspectorRevised methodsFor: 'accessing - ui' stamp: 'mt 12/19/2019 18:02'!
pc

	^ self alien perform: self pcSelector! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing - ui' stamp: 'mt 12/19/2019 18:03'!
pcText

	^ self pc asString! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing - ui' stamp: 'mt 12/19/2019 17:49'!
registerAt: aRegisterSelector

	^ self alien perform: aRegisterSelector! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing - ui' stamp: 'mt 12/19/2019 18:19'!
registerTextAt: aRegisterSelector

	| raw current last highlights |
	current := self registerAt: aRegisterSelector.
	last := self registerCache at: aRegisterSelector ifAbsent: [].
	self registerCache at: aRegisterSelector put: current.	

	highlights := (last = current 
		ifTrue: ["no change, no highlights"
			#() ]
		ifFalse: ["Highlight that this register has a new value."
			{TextEmphasis bold. TextColor color: Color salmon}]).

	raw := String streamContents: [:s |
		current
			printOn: s
			base: (2 raisedTo: self bitsPerDigit)
			length: self alien bitsInWord / self bitsPerDigit
			padded: true].
		
	^ (String streamContents: [:s |
		raw groupsOf: self digitsPerGroup atATimeCollect: [:group |
			s nextPutAll: group; space]])
				asText addAllAttributes: highlights; yourself! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing - ui' stamp: 'mt 12/19/2019 18:19'!
text

	| max |
	max := (self registerSelectors ifEmpty: [1] ifNotEmpty: [:s | (s collect: #size) max]).
	
	^ Text streamContents: [:s |
		s
			nextPutAll: ('PC' padded: #right to: max with: Character space);
			nextPutAll: ' = ';
			nextPutAll: self pcText;
			cr.
		
		self registerSelectors do: [:selector |
			s
				nextPutAll: ((selector asUppercase padded: #right to: max with: Character space)
					asText addAttribute: (PluggableTextAttribute evalBlock: [self interpret: selector]));
				nextPutAll: ' = ';
				nextPutAll: (self registerTextAt: selector);
				cr]]! !

!CogProcessorAlienInspectorRevised methodsFor: 'evaluation' stamp: 'mt 4/22/2020 17:58'!
evaluateExpression: exp
	"Callback from text widget after do-it, print-it, inspect-it, etc... The return value will be fed  back."

	| register value |
	[
		register := (exp asString findTokens: '=') first withBlanksTrimmed asLowercase asSymbol.
		value := self registerCache at: register.
		self interpret: register.
		^ value
	] ifError: [
		"Regular code evaluation."
		
		^ self doItReceiver class evaluatorClass new 
			evaluate: exp readStream
			in: self doItContext
			to: self doItReceiver
			environment: self environment
			notifying: nil
			ifFail: [^ nil]
			logged: true.
	].	
! !

!CogProcessorAlienInspectorRevised methodsFor: 'evaluation' stamp: 'mt 12/19/2019 18:30'!
interpret: registerSelector
	"Offer some ways of interpretation."
	
	| value options choice |

	self flag: #updates. "mt: The cache value corresponds maybe to the value at interaction time. In case the register changes quickly and it takes the user some time to make a choice?"
	value := self registerCache at: registerSelector.
	
	options := Dictionary newFrom: {
		'Object' -> #interpret:asObject:.
		'Stack frame' -> #interpret:asStackFrame:.
		'Integer' -> #interpret:asInteger:.
		'Character' -> #interpret:asCharacter:.
	}.
	
	choice := Project uiManager
		chooseFrom: options keys
		values: options values
		title: ('Interpret {1} as ...' format: {registerSelector asUppercase}).
		
	choice ifNotNil: [:selector |
		self perform: selector with: registerSelector with: value].! !

!CogProcessorAlienInspectorRevised methodsFor: 'evaluation' stamp: 'mt 12/19/2019 18:29'!
interpret: registerSelector asCharacter: registerValue
	
	registerValue asCharacter explore.! !

!CogProcessorAlienInspectorRevised methodsFor: 'evaluation' stamp: 'mt 12/19/2019 18:29'!
interpret: registerSelector asInteger: registerValue
	
	registerValue explore.! !

!CogProcessorAlienInspectorRevised methodsFor: 'evaluation' stamp: 'mt 12/19/2019 18:29'!
interpret: registerSelector asObject: registerValue
	
	self shouldBeImplemented.
	! !

!CogProcessorAlienInspectorRevised methodsFor: 'evaluation' stamp: 'mt 12/19/2019 18:28'!
interpret: registerSelector asStackFrame: registerValue
	
	self shouldBeImplemented.
	! !

!CogProcessorAlienInspectorRevised methodsFor: 'defaults' stamp: 'mt 12/19/2019 17:12'!
bitsPerDigit
	"How to format the register state?"
	
	^ 4! !

!CogProcessorAlienInspectorRevised methodsFor: 'defaults' stamp: 'mt 12/19/2019 17:34'!
digitsPerGroup
	"How to format the register state?"
	
	^ 2! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing' stamp: 'mt 4/22/2020 17:55'!
alien
	^ self object! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing' stamp: 'mt 4/22/2020 17:55'!
alien: aCogProcessorAlien
	
	self object: aCogProcessorAlien.! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing' stamp: 'mt 12/19/2019 18:01'!
pcSelector

	^ pcSelector! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing' stamp: 'mt 12/19/2019 18:01'!
pcSelector: anObject

	pcSelector := anObject.! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing' stamp: 'mt 12/19/2019 18:05'!
registerCache

	^ registerCache! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing' stamp: 'mt 12/19/2019 18:05'!
registerCache: anObject

	registerCache := anObject.! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing' stamp: 'mt 12/19/2019 16:56'!
registerSelectors

	^ registerSelectors! !

!CogProcessorAlienInspectorRevised methodsFor: 'accessing' stamp: 'mt 12/19/2019 17:03'!
registerSelectors: anObject

	registerSelectors := anObject.
	self changed: #text.! !

!CogProcessorAlienInspectorRevised methodsFor: 'toolbuilder' stamp: 'mt 4/22/2020 17:41'!
buildValuePaneWith: builder
	"Overridden because register contents are more legible in a mono-spaced font."
	
	^ (super buildValuePaneWith: builder)
		font: Preferences standardFixedFont;
		yourself! !

!CogProcessorAlienInspectorRevised methodsFor: 'initialization' stamp: 'mt 12/19/2019 18:06'!
initialize

	super initialize.
	
	self registerSelectors: OrderedCollection new.
	self pcSelector: #pc.
	
	self registerCache: IdentityDictionary new.! !

!CogProcessorAlienInspectorRevised methodsFor: 'menu - commands' stamp: 'mt 4/22/2020 17:54'!
addAllRegisters: someRegisterSelectors

	self registerSelectors addAll: someRegisterSelectors.
	self changed: #contents.! !

!CogProcessorAlienInspectorRevised methodsFor: 'menu - commands' stamp: 'mt 4/22/2020 17:49'!
addRegister

	| answer |
	answer := Project uiManager
		request: 'Which register to add to inspection?'
		initialAnswer: '#eax'.

	answer ifEmpty: [^ self].
	
	(Compiler evaluate: answer) in: [:selector |
		self registerSelectors add: selector.
		self changed: #contents].! !

!CogProcessorAlienInspectorRevised methodsFor: 'menu - commands' stamp: 'mt 4/22/2020 17:54'!
addRegister: aRegisterSelector

	self registerSelectors add: aRegisterSelector.
	self changed: #contents.! !

!CogProcessorAlienInspectorRevised methodsFor: 'menu - commands' stamp: 'mt 4/22/2020 17:53'!
removeAllRegisters

	(Project uiManager confirm: 'Are you sure?')
		ifFalse: [^ self].
		
	self registerSelectors removeAll.
	self changed: #contents.! !

!CogProcessorAlienInspectorRevised methodsFor: 'menu - construction' stamp: 'mt 4/22/2020 18:00'!
addFieldItemsTo: aMenu

	super addFieldItemsTo: aMenu.

	aMenu addLine.
	
	aMenu addTranslatedList: #(
			('add register'			addRegister)
			('remove all registers'	removeAllRegisters)).! !

!CogProcessorAlienInspectorRevised methodsFor: 'fields' stamp: 'mt 4/22/2020 17:51'!
fieldRegisters

	^ (self newFieldForType: #misc key: #registers)
		name: 'registers'; emphasizeName;
		valueGetter: [:alien | self text]; printValueAsIs;
		yourself! !

!CogProcessorAlienInspectorRevised methodsFor: 'fields - streaming' stamp: 'mt 4/22/2020 17:51'!
streamBaseFieldsOn: aStream

	super streamBaseFieldsOn: aStream.
	aStream nextPut: self fieldRegisters.! !


!CogProcessorAlienInspectorRevised class methodsFor: 'instance creation' stamp: 'mt 4/22/2020 17:54'!
open
	"This is just an example."

	^ ToolBuilder open: (
			self new
				alien: (CogProcessorAlienMock new bitsInWord: 64);
				addAllRegisters: #(eax ebx ecx xmm0high);
				yourself)! !


!CogProcessorAlienMock methodsFor: 'accessing' stamp: 'mt 12/19/2019 17:26'!
doesNotUnderstand: msg

	msg numArgs = 0
		ifTrue: [^ self randomValue].
	
	^ super doesNotUnderstand: msg! !

!CogProcessorAlienMock methodsFor: 'accessing' stamp: 'mt 12/19/2019 17:59'!
pc

	^ 500 atRandom! !

!CogProcessorAlienMock methodsFor: 'accessing' stamp: 'mt 12/19/2019 18:15'!
randomValue
	"Return a fixed value from time to time to test the inspector highlight."
	
	^ #(true false false) atRandom
		ifTrue: [(ThreadSafeRandom next * (2 raisedTo: self bitsInWord)) truncated]
		ifFalse: [42]! !

!CogProcessorAlienMock methodsFor: 'Cog API' stamp: 'mt 12/19/2019 17:40'!
bitsInWord

	^ bitsInWord ifNil: [32]! !

!CogProcessorAlienMock methodsFor: 'Cog API' stamp: 'mt 12/19/2019 17:40'!
bitsInWord: aNumber

	bitsInWord := aNumber.! !


!CogProcessorAlienMock class methodsFor: 'instance creation' stamp: 'mt 12/19/2019 16:48'!
new

	^ self basicNew initialize! !

CogProcessorAlienInspectorRevised removeSelector: #buildWith:!
CogProcessorAlienInspectorRevised removeSelector: #defaultWindowColor!
CogProcessorAlienInspectorRevised removeSelector: #inspect:!
CogProcessorAlienInspectorRevised removeSelector: #inspectAll:!
CogProcessorAlienInspectorRevised removeSelector: #inspectNone!
CogProcessorAlienInspectorRevised removeSelector: #stepIn:!
CogProcessorAlienInspectorRevised removeSelector: #stepTimeIn:!
CogProcessorAlienInspectorRevised removeSelector: #wantsStepsIn:!
CogProcessorAlienInspectorRevised removeSelector: #windowTitle!
CogProcessorAlienInspectorRevised removeSelector: #windowTitle:!

!CogProcessorAlienInspectorRevised reorganize!
('accessing - ui' pc pcText registerAt: registerTextAt: text)
('evaluation' evaluateExpression: interpret: interpret:asCharacter: interpret:asInteger: interpret:asObject: interpret:asStackFrame:)
('defaults' bitsPerDigit digitsPerGroup)
('accessing' alien alien: pcSelector pcSelector: registerCache registerCache: registerSelectors registerSelectors:)
('toolbuilder' buildValuePaneWith:)
('initialization' initialize)
('menu - commands' addAllRegisters: addRegister addRegister: removeAllRegisters)
('menu - construction' addFieldItemsTo:)
('fields' fieldRegisters)
('fields - streaming' streamBaseFieldsOn:)
!

