compiler/PPCFSACodeGen.st
changeset 502 1e45d3c96ec5
child 515 b5316ef15274
equal deleted inserted replaced
464:f6d77fee9811 502:1e45d3c96ec5
       
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
       
     2 
       
     3 "{ NameSpace: Smalltalk }"
       
     4 
       
     5 PPCCodeGen subclass:#PPCFSACodeGen
       
     6 	instanceVariableNames:'fsa backlinkStates'
       
     7 	classVariableNames:''
       
     8 	poolDictionaries:''
       
     9 	category:'PetitCompiler-Scanner'
       
    10 !
       
    11 
       
    12 !PPCFSACodeGen methodsFor:'accessing'!
       
    13 
       
    14 methodCategory
       
    15     ^ 'generated - scanning'
       
    16 ! !
       
    17 
       
    18 !PPCFSACodeGen methodsFor:'analysis'!
       
    19 
       
    20 beginOfRange: characterSet
       
    21     characterSet withIndexDo: [ :e :index | 
       
    22         e ifTrue: [ ^ index ]
       
    23     ].
       
    24     self error: 'should not happend'
       
    25 !
       
    26 
       
    27 endOfRange: characterSet
       
    28     | change |
       
    29     change := false.
       
    30     characterSet withIndexDo: [ :e :index | 
       
    31         e ifTrue: [ change := true ].
       
    32         (e not and: [ change ]) ifTrue: [ ^ index - 1]
       
    33     ].
       
    34     ^ characterSet size
       
    35 !
       
    36 
       
    37 isLetter: characterSet
       
    38     | changes previous |
       
    39     changes := 0.
       
    40     previous := false.
       
    41     characterSet withIndexDo: [ :e :index |
       
    42         (e == (Character codePoint: index) isLetter) ifFalse: [ ^ false ].
       
    43     ].
       
    44     ^ true
       
    45 !
       
    46 
       
    47 isSingleCharacter: characterSet
       
    48     ^ (characterSet select: [ :e | e ]) size = 1
       
    49 !
       
    50 
       
    51 isSingleRange: characterSet
       
    52     | changes previous |
       
    53     changes := 0.
       
    54     previous := false.
       
    55     characterSet do: [ :e | 
       
    56         (e == previous) ifFalse: [ changes := changes + 1 ].
       
    57         previous := e.
       
    58     ].
       
    59     ^ changes < 3
       
    60 ! !
       
    61 
       
    62 !PPCFSACodeGen methodsFor:'coding'!
       
    63 
       
    64 codeAbsoluteReturn: code
       
    65     self add: '^ ', code
       
    66 !
       
    67 
       
    68 codeAssertPeek: characterSet
       
    69     | character id extendedCharacterSet |
       
    70     
       
    71     (self isSingleCharacter: characterSet) ifTrue: [ 
       
    72         character := self character: characterSet.
       
    73         self addOnLine: 'self peek == ', character storeString.
       
    74         ^ self
       
    75     ].
       
    76 
       
    77     (self isLetter: characterSet) ifTrue: [ 
       
    78         self addOnLine: 'self peek isLetter'.
       
    79         ^ self
       
    80     ].
       
    81 
       
    82     (self isSingleRange: characterSet) ifTrue: [ 
       
    83         | begin end |
       
    84         begin := self beginOfRange: characterSet.
       
    85         end := self endOfRange: characterSet.
       
    86         self addOnLine: 'self peekBetween: ', begin asString, ' and: ', end asString.
       
    87         ^ self
       
    88     ].
       
    89 
       
    90     extendedCharacterSet := (characterSet asOrderedCollection addLast: false; yourself) asArray.
       
    91     id := self idFor: characterSet prefixed: 'characterSet'.
       
    92     
       
    93     self addConstant: extendedCharacterSet as: id.
       
    94     self addOnLine: id, ' at: self peek asInteger'.
       
    95 !
       
    96 
       
    97 codeAssertPeek: characterSet ifTrue: block
       
    98     self addOnLine: '('.
       
    99     self codeAssertPeek: characterSet.
       
   100     self addOnLine: ') ifTrue: ['.
       
   101     self indent.
       
   102     self code: block.
       
   103     self dedent.
       
   104     self add: ']'.
       
   105 !
       
   106 
       
   107 codeAssertPeek: characterSet orReturn: priority
       
   108     self add: '('.
       
   109     self codeAssertPeek: characterSet.
       
   110     self addOnLine: ') ifFalse: [ '.
       
   111     self codeReturnResult: priority.
       
   112     self addOnLine: ']'.
       
   113     self codeDot.
       
   114 !
       
   115 
       
   116 codeAssertPeek: characterSet whileTrue: block
       
   117     self add: '['.
       
   118     self codeAssertPeek: characterSet.
       
   119     self addOnLine: '] whileTrue: ['.
       
   120     self indent.
       
   121     self code: block.
       
   122     self dedent.
       
   123     self add: '].'.
       
   124     self nl.
       
   125 !
       
   126 
       
   127 codeEndBlock
       
   128     self dedent.	
       
   129     self add: ']'.
       
   130 !
       
   131 
       
   132 codeEndBlockWhileTrue
       
   133     self dedent.	
       
   134     self add: '] whileTrue.'.
       
   135 !
       
   136 
       
   137 codeIfFalse
       
   138     self addOnLine: ' ifFalse: ['.
       
   139 !
       
   140 
       
   141 codeNextChar
       
   142     self add: 'self step.'
       
   143 !
       
   144 
       
   145 codeNl
       
   146     self add: ''.
       
   147 !
       
   148 
       
   149 codeNlAssertPeek: characterSet
       
   150     self add: ''.
       
   151     self codeAssertPeek: characterSet.
       
   152 !
       
   153 
       
   154 codeNlReturnResult
       
   155     self add: '^ self return.'
       
   156 !
       
   157 
       
   158 codeNlReturnResult: priority
       
   159     priority isNil ifTrue: [ 
       
   160         ^ self codeNlReturnResult
       
   161     ].
       
   162     self add: '^ self returnPriority: ', priority asString, '.'
       
   163 !
       
   164 
       
   165 codeRecordMatch: state
       
   166     self add: 'self recordMatch: ', state storeString, '.'
       
   167 !
       
   168 
       
   169 codeRecordMatch: state priority: priority
       
   170     priority isNil ifTrue: [ 
       
   171         ^ self codeRecordMatch: state
       
   172     ].
       
   173     
       
   174     self add: 'self recordMatch: ', state storeString, ' priority: ', priority asString, '.'
       
   175 !
       
   176 
       
   177 codeReturnResult
       
   178     self addOnLine: '^ self return.'
       
   179 !
       
   180 
       
   181 codeReturnResult: priority
       
   182     priority isNil ifTrue: [ 
       
   183         ^ self codeReturnResult
       
   184     ].
       
   185 
       
   186     self addOnLine: '^ self returnPriority: ', priority asString, '.'
       
   187 !
       
   188 
       
   189 codeStartBlock
       
   190     self add: '['.
       
   191     self indent.
       
   192 ! !
       
   193 
       
   194 !PPCFSACodeGen methodsFor:'helpers'!
       
   195 
       
   196 character: characterSet
       
   197     self assert: (self isSingleCharacter: characterSet).
       
   198     characterSet withIndexDo: [ :e :index | e ifTrue: [ ^ Character codePoint: index ] ].
       
   199     
       
   200     self error: 'should not happen'
       
   201 ! !
       
   202 
       
   203 !PPCFSACodeGen methodsFor:'intitialization'!
       
   204 
       
   205 initialize
       
   206     super initialize.
       
   207     backlinkStates := IdentityDictionary new.
       
   208 
       
   209     "Modified: / 24-07-2015 / 15:03:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   210 ! !
       
   211