|
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 |