compiler/PPCFSACodeGen.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Mon, 17 Aug 2015 12:13:16 +0100
changeset 515 b5316ef15274
parent 502 1e45d3c96ec5
child 524 f6f68d32de73
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 }"

PPCCodeGen subclass:#PPCFSACodeGen
	instanceVariableNames:'fsa backlinkStates compiler'
	classVariableNames:''
	poolDictionaries:''
	category:'PetitCompiler-Scanner'
!

!PPCFSACodeGen methodsFor:'accessing'!

methodCategory
    ^ 'generated - scanning'
! !

!PPCFSACodeGen methodsFor:'coding'!

codeAbsoluteReturn: code
    self add: '^ ', code
!

codeAssertPeek: t
    |   id  |
    self assert: (t isKindOf: PEGFsaTransition).

    (t isPredicateTransition and: [t isEOF]) ifTrue: [ 
        self addOnLine: 'currentChar isNil'.
        ^ self
    ].

    
    (t isPredicateTransition) ifTrue: [ 
        self addOnLine: t predicate asString, ' value: currentChar codePoint'.
        ^ self
    ].

    (t isAny) ifTrue: [ 
        self addOnLine: 'true'.
        ^ self
    ].

    
    (t isSingleCharacter) ifTrue: [ 
        self addOnLine: 'currentChar == ', t character storeString.
        ^ self
    ].

    (t isNotSingleCharacter) ifTrue: [ 
        self addOnLine: 'currentChar ~~ ', t notCharacter storeString.
        ^ self
    ].

    (t isLetter) ifTrue: [ 
        self addOnLine: 'currentChar isLetter'.
        ^ self
    ].

    (t isWord) ifTrue: [ 
        self addOnLine: 'currentChar isAlphaNumeric'.
        ^ self
    ].

    (t isDigit) ifTrue: [ 
        self addOnLine: 'currentChar isDigit'.
        ^ self
    ].

    (t isSingleRange) ifTrue: [ 
        | begin end |
        begin := t beginOfRange.
        end := t endOfRange.
        self addOnLine: 'self peekBetween: ', begin asString, ' and: ', end asString.
        ^ self
    ].

    
    id := idGen cachedSuchThat: [ :e | e = t characterSet ] 
                    ifNone: [ self idFor: t characterSet defaultName: 'characterSet' ].
    
    self addConstant: t characterSet as: id.
    self addOnLine: '(currentChar isNotNil) and: [',  id, ' at: currentChar codePoint ]'.
!

codeAssertPeek: transition ifFalse: falseBlock
    self add: '('.
    self codeAssertPeek: transition.
    self addOnLine: ') ifFalse: [ '.
    falseBlock value.
    self addOnLine: ']'.
    self codeDot.
!

codeAssertPeek: t ifTrue: block
    self addOnLine: '('.
    self codeAssertPeek: t.
    self addOnLine: ') ifTrue: ['.
    self indent.
    self code: block.
    self dedent.
    self add: ']'.
!

codeAssertPeek: transition orReturn: priority
    self error: 'deprecated'.
    self add: '('.
    self codeAssertPeek: transition.
    self addOnLine: ') ifFalse: [ '.
    self codeReturnResult: priority.
    self addOnLine: ']'.
    self codeDot.
!

codeAssertPeek: transition whileTrue: block
    self add: '['.
    self codeAssertPeek: transition.
    self addOnLine: '] whileTrue: ['.
    self indent.
    self code: block.
    self dedent.
    self add: '].'.
    self nl.
!

codeEndBlock
    self dedent.	
    self add: ']'.
!

codeEndBlockWhileTrue
    self dedent.	
    self add: '] whileTrue.'.
!

codeIfFalse
    self addOnLine: ' ifFalse: ['.
!

codeNextChar
    self add: 'self step.'
!

codeNl
    self add: ''.
!

codeNlAssertPeek: characterSet
    self add: ''.
    self codeAssertPeek: characterSet.
!

codeNlReturnResult
    self add: '^ self return.'
!

codeNlReturnResult: priority
    priority isNil ifTrue: [ 
        ^ self codeNlReturnResult
    ].
    self add: '^ self returnPriority: ', priority asString, '.'
!

codeRecordDistinctMatch: retval offset: value
    self add: 'self recordDistinctMatch: ', retval storeString, ' offset: ', value storeString, '.'
!

codeRecordMatch: state priority: priority
    priority isNil ifTrue: [ 
        ^ self codeRecordMatch: state
    ].
    
    self add: 'self recordMatch: ', state storeString, ' priority: ', priority asString, '.'
!

codeReturnResult
    self addOnLine: '^ self return.'
!

codeReturnResult: priority
    priority isNil ifTrue: [ 
        ^ self codeReturnResult
    ].

    self addOnLine: '^ self returnPriority: ', priority asString, '.'
!

codeStartBlock
    self add: '['.
    self indent.
! !

!PPCFSACodeGen methodsFor:'coding - results'!

codeRecordDistinctMatch: retval
    self add: 'self recordDistinctMatch: ', retval storeString, '.'
!

codeRecordFailure: index
    self assert: index isInteger.
    self add: 'self recordFailure: ', index asString, '.'
!

codeRecordMatch: retval
    self add: 'self recordMatch: ', retval storeString, '.'
!

codeRecordMatch: retval offset: offset
    self add: 'self recordMatch: ', retval storeString, ' offset: ', offset storeString, '.'
!

codeReturn
    self addOnLine: '^ self'
!

codeReturnDistinct
    self addOnLine: '^ self returnDistinct.'
! !

!PPCFSACodeGen methodsFor:'intitialization'!

initialize
    super initialize.
    
    compiler := PPCCodeGen new.
    backlinkStates := IdentityDictionary new.
! !