compiler/PPCIdGenerator.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Mon, 17 Aug 2015 12:13:16 +0100
changeset 515 b5316ef15274
child 518 a6d8b93441b0
permissions -rw-r--r--
Updated to PetitCompiler-JanKurs.160, PetitCompiler-Tests-JanKurs.112, PetitCompiler-Extras-Tests-JanKurs.25, PetitCompiler-Benchmarks-JanKurs.17 Name: PetitCompiler-JanKurs.160 Author: JanKurs Time: 17-08-2015, 09:52:26.291 AM UUID: 3b4bfc98-8098-4951-af83-a59e2585b121 Name: PetitCompiler-Tests-JanKurs.112 Author: JanKurs Time: 16-08-2015, 05:00:32.936 PM UUID: 85613d47-08f3-406f-9823-9cdab451e805 Name: PetitCompiler-Extras-Tests-JanKurs.25 Author: JanKurs Time: 16-08-2015, 05:00:10.328 PM UUID: 09731810-51a1-4151-8d3a-56b636fbd1f7 Name: PetitCompiler-Benchmarks-JanKurs.17 Author: JanKurs Time: 05-08-2015, 05:29:32.407 PM UUID: e544b5f1-bcf8-470b-93a6-d2363e4dfc8a

"{ Package: 'stx:goodies/petitparser/compiler' }"

"{ NameSpace: Smalltalk }"

Object subclass:#PPCIdGenerator
	instanceVariableNames:'idCache numericIdCache'
	classVariableNames:''
	poolDictionaries:''
	category:'PetitCompiler-Compiler-Codegen'
!

!PPCIdGenerator class methodsFor:'as yet unclassified'!

new
    ^ self basicNew initialize
! !

!PPCIdGenerator methodsFor:'accessing'!

ids
    ^ idCache keys
!

numericIdCache
    ^ numericIdCache
!

numericIds
    ^ numericIdCache keys
! !

!PPCIdGenerator methodsFor:'as yet unclassified'!

asSelector: string
    "e.g. '234znak 43 ) 2' asLegalSelector = #v234znak432"
    
    | toUse |

    toUse := string select: [:char | char isAlphaNumeric or: [ char = $_ ] ].
    (toUse isEmpty or: [ toUse first isLetter not ])
        ifTrue: [ toUse := 'v', toUse ].
    toUse first isUppercase ifFalse:[
        toUse := toUse copy.
        toUse at: 1 put: toUse first asLowercase
    ].
    ^toUse

    "Modified: / 10-05-2015 / 07:29:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

cachedSuchThat: block ifNone: noneBlock
    | key |
    key := idCache keys detect: block ifNone: [ nil ].
    key isNil ifTrue: [ ^ noneBlock value ].
    
    ^ idCache at: key
!

generateIdFor: object defaultName: defaultName prefix: prefix suffix: suffix  
    | name count |
    object canHavePPCId ifTrue: [ 
        name := object hasName ifTrue: [ object name ] ifFalse: [ object defaultName ].
        name := self asSelector: name asString.
        
        "JK: I am not sure, if prefix and suffix should be applied to the name or not..."
        suffix isNil ifFalse: [ 
            name := name, '_', suffix.		
        ].
    
        prefix isNil ifFalse: [ 
            name := prefix , '_', name.		
        ].	
        
        "(idCache contains: [ :e | e = name ]) ifTrue: [  self error: 'Duplicit names?' ]."
    ] ifFalse: [ 
        name := defaultName.

        prefix isNil ifFalse: [ 
            name := prefix , '_', name.		
        ].

        suffix isNil ifFalse: [ 
            name := name, '_', suffix.		
        ].

        name := self asSelector: name asString.
        
    ].

    (idCache contains: [ :e | e = name ]) ifTrue: [  
        count := 2. 
        
        [	| tmpName |	
            tmpName := (name, '_', count asString).
            idCache contains: [:e | e = tmpName ]
        ] whileTrue: [ count := count + 1 ].

        name := name, '_', count asString
    ].
    
    ^ name asSymbol
!

idFor: object
    self assert: object canHavePPCId.
    ^ self idFor: object defaultName: object defaultName prefix: object prefix suffix: object suffix
!

idFor: object defaultName: defaultName
    ^ self idFor: object defaultName: defaultName prefix: nil suffix: nil
!

idFor: object defaultName: defaultName prefix: prefix
    ^ self idFor: object defaultName: defaultName prefix: prefix suffix: ''
!

idFor: object defaultName: defaultName prefix: prefix suffix: suffix
    ^ idCache at: object ifAbsentPut: [ 
        self generateIdFor: object defaultName: defaultName prefix: prefix suffix: suffix
    ]
!

isCachedSuchThat: block
    ^ idCache keys contains: block
!

isCachedSuchThat: block ifTrue: trueBlock ifFalse: falseBlock
    ^ (idCache keys contains: block) ifTrue: [trueBlock value] ifFalse: [falseBlock value]
!

numericIdFor: object
    self assert: object isSymbol.
    ^ numericIdCache at: object ifAbsentPut: [ 
        numericIdCache at: object put: (numericIdCache size) + 1
    ]
! !

!PPCIdGenerator methodsFor:'initialization'!

initialize
    super initialize.
    idCache := IdentityDictionary new.
    numericIdCache := IdentityDictionary new.
! !