[FIX] array literals

Yoshiki Ohshima ohshima at is.titech.ac.jp
Fri Jan 26 20:57:48 UTC 2001


  Hello,

  I found that I can't create a menu that has only one menu
item with its label string and the action selector are
equal, in terms of String>>=.  For example, a menu created
by the following expression doesn't work.

    SelectionMenu
        labelList: #('suspend')
        lines: #()
        selections: #(suspend)

  This is because that the Compiler (Encoder) trys to merge
the "same" literals, the selector to be #perform'ed is 'suspend'
not #suspend.

  I ended up with a mutually recursive equality check in
LiteralArray.  Attached is the code.

  -- Yoshiki

-------------- next part --------------
'From Squeak2.9alpha of 13 June 2000 [latest update: #3076] on 27 January 2001 at 5:16:40 am'!
Dictionary subclass: #LiteralDictionary
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'System-Compiler'!
!LiteralDictionary commentStamp: '<historical>' prior: 0!
A LiteralDictionary, like an IdentityDictionary, has a special test for equality.  In this case it is simple equality between objects of like class.  This allows equal Float or String literals to be shared without the possibility of erroneously sharing, say, 1 and 1.0!


!LiteralDictionary methodsFor: 'as yet unclassified' stamp: 'yo 1/27/2001 05:06'!
arrayEquality: x and: y

	x size = y size ifFalse: [^ false].
	x with: y do: [:e1 :e2 | 
		(self literalEquality: e1 and: e2) ifFalse: [^ false]
	].
	^true.
! !

!LiteralDictionary methodsFor: 'as yet unclassified' stamp: 'yo 1/27/2001 05:13'!
literalEquality: x and: y

	^ (x class = Array and: [y class = Array]) ifTrue: [
		self arrayEquality: x and: y.
	] ifFalse: [
		(x class == y class) and: [x key = y]
	].
! !

!LiteralDictionary methodsFor: 'as yet unclassified' stamp: 'yo 1/27/2001 05:10'!
scanFor: anObject
	"Scan the key array for the first slot containing either a nil (indicating an empty slot) or an element that matches anObject. Answer the index of that slot or zero if no slot is found. This method will be overridden in various subclasses that have different interpretations for matching elements."
	| element start finish |
	start _ (anObject hash \\ array size) + 1.
	finish _ array size.

	"Search from (hash mod size) to the end."
	start to: finish do:
		[:index | ((element _ array at: index) == nil
					or: [self literalEquality: element key and: anObject])
					ifTrue: [^ index ]].

	"Search from 1 to where we started."
	1 to: start-1 do:
		[:index | ((element _ array at: index) == nil
					or: [self literalEquality: element key and: anObject])
					ifTrue: [^ index ]].

	^ 0  "No match AND no empty slot"! !


More information about the Squeak-dev mailing list