--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/PPCFSACodeGen.st Fri Jul 24 15:06:54 2015 +0100
@@ -0,0 +1,211 @@
+"{ 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>"
+! !
+