compiler/PPCFSACodeGen.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Fri, 24 Jul 2015 15:06:54 +0100
changeset 502 1e45d3c96ec5
child 515 b5316ef15274
permissions -rw-r--r--
Updated to PetitCompiler-JanVrany.135, PetitCompiler-Tests-JanKurs.93, PetitCompiler-Extras-Tests-JanVrany.16, PetitCompiler-Benchmarks-JanKurs.12 Name: PetitCompiler-JanVrany.135 Author: JanVrany Time: 22-07-2015, 06:53:29.127 PM UUID: 890178b5-275d-46af-a2ad-1738998f07cb Ancestors: PetitCompiler-JanVrany.134 Name: PetitCompiler-Tests-JanKurs.93 Author: JanKurs Time: 20-07-2015, 11:30:10.283 PM UUID: 6473e671-ad70-42ca-b6c3-654b78edc531 Ancestors: PetitCompiler-Tests-JanKurs.92 Name: PetitCompiler-Extras-Tests-JanVrany.16 Author: JanVrany Time: 22-07-2015, 05:18:22.387 PM UUID: 8f6f9129-dbba-49b1-9402-038470742f98 Ancestors: PetitCompiler-Extras-Tests-JanKurs.15 Name: PetitCompiler-Benchmarks-JanKurs.12 Author: JanKurs Time: 06-07-2015, 02:10:06.901 PM UUID: cb24f1ac-46a4-494d-9780-64576f0f0dba Ancestors: PetitCompiler-Benchmarks-JanKurs.11, PetitCompiler-Benchmarks-JanVrany.e29bd90f388e.20150619081300

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

"{ NameSpace: Smalltalk }"

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

!PPCFSACodeGen methodsFor:'accessing'!

methodCategory
    ^ 'generated - scanning'
! !

!PPCFSACodeGen methodsFor:'analysis'!

beginOfRange: characterSet
    characterSet withIndexDo: [ :e :index | 
        e ifTrue: [ ^ index ]
    ].
    self error: 'should not happend'
!

endOfRange: characterSet
    | change |
    change := false.
    characterSet withIndexDo: [ :e :index | 
        e ifTrue: [ change := true ].
        (e not and: [ change ]) ifTrue: [ ^ index - 1]
    ].
    ^ characterSet size
!

isLetter: characterSet
    | changes previous |
    changes := 0.
    previous := false.
    characterSet withIndexDo: [ :e :index |
        (e == (Character codePoint: index) isLetter) ifFalse: [ ^ false ].
    ].
    ^ true
!

isSingleCharacter: characterSet
    ^ (characterSet select: [ :e | e ]) size = 1
!

isSingleRange: characterSet
    | changes previous |
    changes := 0.
    previous := false.
    characterSet do: [ :e | 
        (e == previous) ifFalse: [ changes := changes + 1 ].
        previous := e.
    ].
    ^ changes < 3
! !

!PPCFSACodeGen methodsFor:'coding'!

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

codeAssertPeek: characterSet
    | character id extendedCharacterSet |
    
    (self isSingleCharacter: characterSet) ifTrue: [ 
        character := self character: characterSet.
        self addOnLine: 'self peek == ', character storeString.
        ^ self
    ].

    (self isLetter: characterSet) ifTrue: [ 
        self addOnLine: 'self peek isLetter'.
        ^ self
    ].

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

    extendedCharacterSet := (characterSet asOrderedCollection addLast: false; yourself) asArray.
    id := self idFor: characterSet prefixed: 'characterSet'.
    
    self addConstant: extendedCharacterSet as: id.
    self addOnLine: id, ' at: self peek asInteger'.
!

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

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

codeAssertPeek: characterSet whileTrue: block
    self add: '['.
    self codeAssertPeek: characterSet.
    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, '.'
!

codeRecordMatch: state
    self add: 'self recordMatch: ', state 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:'helpers'!

character: characterSet
    self assert: (self isSingleCharacter: characterSet).
    characterSet withIndexDo: [ :e :index | e ifTrue: [ ^ Character codePoint: index ] ].
    
    self error: 'should not happen'
! !

!PPCFSACodeGen methodsFor:'intitialization'!

initialize
    super initialize.
    backlinkStates := IdentityDictionary new.

    "Modified: / 24-07-2015 / 15:03:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !