136 |
132 |
137 callOnLine: anotherMethod |
133 callOnLine: anotherMethod |
138 currentMethod addOnLine: anotherMethod call. |
134 currentMethod addOnLine: anotherMethod call. |
139 ! |
135 ! |
140 |
136 |
141 checkCache: id |
|
142 | method value | |
|
143 "Check if method is already compiled/hand written" |
|
144 method := compiledParser compiledMethodAt: id ifAbsent: [ nil ]. |
|
145 method ifNotNil: [ ^ lastMethod := PPCCompiledMethod new id: id; yourself ]. |
|
146 |
|
147 ^ (value := self cachedValue: id) ifNotNil: [ lastMethod := value ]. |
|
148 ! |
|
149 |
|
150 dedent |
137 dedent |
151 currentMethod dedent |
138 currentMethod dedent |
152 ! |
139 ! |
153 |
140 |
154 indent |
141 indent |
155 currentMethod indent |
142 currentMethod indent |
156 ! |
143 ! |
157 |
144 |
158 nl |
145 nl |
159 currentMethod nl |
146 currentMethod nl |
160 ! |
|
161 |
|
162 pop |
|
163 | array | |
|
164 array := compilerStack pop. |
|
165 currentMethod := array first |
|
166 ! |
|
167 |
|
168 push |
|
169 | array | |
|
170 array := { currentMethod }. |
|
171 compilerStack push: array. |
|
172 (compilerStack size > 500 )ifTrue: [ self error: 'unless it is very complex grammar, there is an error somewhere' ] |
|
173 ! |
147 ! |
174 |
148 |
175 smartRemember: parser |
149 smartRemember: parser |
176 ^ self smartRemember: parser to: #memento |
150 ^ self smartRemember: parser to: #memento |
177 ! |
151 ! |
192 ^ 'context lwRestore: ', mementoName, '.'. |
166 ^ 'context lwRestore: ', mementoName, '.'. |
193 ]. |
167 ]. |
194 ^ 'context restore: ', mementoName, '.'. |
168 ^ 'context restore: ', mementoName, '.'. |
195 ! |
169 ! |
196 |
170 |
197 startMethod: id |
|
198 | sender | |
|
199 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
|
200 self push. |
|
201 |
|
202 |
|
203 currentMethod := PPCMethod new. |
|
204 currentMethod id: id. |
|
205 currentMethod profile: self profile. |
|
206 self cache: id as: currentMethod. |
|
207 |
|
208 sender := thisContext sender receiver. |
|
209 self add: '"Method generated from ', sender asString, '"'. |
|
210 ! |
|
211 |
|
212 startTokenMode |
171 startTokenMode |
213 tokenMode := true |
172 tokenMode := true |
214 ! |
173 ! |
215 |
174 |
216 stopInline |
|
217 | sender | |
|
218 sender := thisContext sender receiver. |
|
219 self add: '"Inlined by ', sender asString, '"'. |
|
220 lastMethod := currentMethod. |
|
221 currentMethod := nil. |
|
222 self pop. |
|
223 ! |
|
224 |
|
225 stopMethod |
|
226 self cache: currentMethod methodName as: currentMethod. |
|
227 lastMethod := currentMethod. |
|
228 currentMethod := nil. |
|
229 self pop. |
|
230 ! |
|
231 |
|
232 stopTokenMode |
175 stopTokenMode |
233 tokenMode := false |
176 tokenMode := false |
234 ! ! |
177 ! ! |
235 |
178 |
236 !PPCCompiler methodsFor:'code generation - ids'! |
179 !PPCCompiler methodsFor:'code generation - ids'! |
242 idFor: object prefixed: prefix effect: effect |
185 idFor: object prefixed: prefix effect: effect |
243 ^ self idFor: object prefixed: prefix suffixed: '' effect: effect. |
186 ^ self idFor: object prefixed: prefix suffixed: '' effect: effect. |
244 ! |
187 ! |
245 |
188 |
246 idFor: object prefixed: prefix suffixed: suffix effect: effect |
189 idFor: object prefixed: prefix suffixed: suffix effect: effect |
247 | body | |
190 | body id | |
|
191 |
|
192 "Halt if: [ (object isKindOf: PPCNode) and: [object name = #smalltalk_ws ] ]." |
|
193 |
|
194 " ((object isKindOf: PPCNode) and: [object name = #smalltalk_ws ]) ifTrue: [ Transcript crShow: 'st_ws' ]. |
|
195 " |
248 ^ ids at: object ifAbsentPut: [ |
196 ^ ids at: object ifAbsentPut: [ |
249 ((object isKindOf: PPCNode) and: [object name isNotNil]) ifTrue: [ |
197 ((object isKindOf: PPCNode) and: [object name isNotNil]) ifTrue: [ |
250 (object name, suffix) asSymbol |
198 "Halt if: [ object name = #smalltalk_ws ]." |
|
199 " (object name = #smalltalk_ws) ifTrue: [Transcript crShow: 'NEW st_ws']. |
|
200 " |
|
201 id := (object name, suffix) asSymbol. |
|
202 "Make sure, that the generated ID is uniqe!!" |
|
203 ((ids values select: [ :e | e = id ]) isEmpty) ifTrue: [ id ] |
|
204 ifFalse: [ |
|
205 body := ids size asString. |
|
206 (id, '_', body) asSymbol |
|
207 ] |
251 ] ifFalse: [ |
208 ] ifFalse: [ |
252 body := ids size asString. |
209 body := ids size asString. |
253 (prefix asString, '_', body, suffix) asSymbol |
210 (prefix asString, '_', body, suffix) asSymbol |
254 ] |
211 ] |
255 ] |
212 ] |
|
213 ! ! |
|
214 |
|
215 !PPCCompiler methodsFor:'code generation - support'! |
|
216 |
|
217 checkCache: id |
|
218 | method | |
|
219 "Check if method is hand written" |
|
220 method := compiledParser compiledMethodAt: id ifAbsent: [ nil ]. |
|
221 method ifNotNil: [ ^ PPCCompiledMethod new id: id; yourself ]. |
|
222 |
|
223 ^ self cachedValue: id |
|
224 ! |
|
225 |
|
226 pop |
|
227 | retval | |
|
228 retval := compilerStack pop. |
|
229 compilerStack isEmpty ifFalse: [ currentMethod := compilerStack top ]. |
|
230 ^ retval |
|
231 |
|
232 "Modified: / 21-11-2014 / 12:27:25 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
233 ! |
|
234 |
|
235 push |
|
236 compilerStack push: currentMethod. |
|
237 (compilerStack size > 500 )ifTrue: [ self error: 'unless it is very complex grammar, there is an error somewhere' ] |
|
238 |
|
239 "Modified: / 21-11-2014 / 12:27:18 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
240 ! |
|
241 |
|
242 startInline: id |
|
243 | sender | |
|
244 |
|
245 currentMethod := PPCInlinedMethod new. |
|
246 currentMethod id: id. |
|
247 currentMethod profile: self profile. |
|
248 self push. |
|
249 |
|
250 |
|
251 sender := thisContext sender receiver. |
|
252 self addComment: 'START inlining by ', sender asString. |
|
253 ! |
|
254 |
|
255 startMethod: id |
|
256 | sender | |
|
257 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
|
258 |
|
259 currentMethod := PPCMethod new. |
|
260 currentMethod id: id. |
|
261 currentMethod profile: self profile. |
|
262 self push. |
|
263 |
|
264 self cache: id as: currentMethod. |
|
265 |
|
266 sender := thisContext sender receiver. |
|
267 self addComment: 'START of method generated by ', sender asString. |
|
268 ! |
|
269 |
|
270 stopInline |
|
271 | sender | |
|
272 sender := thisContext sender receiver. |
|
273 self addComment: 'STOP inlining by ', sender asString. |
|
274 ^ self pop. |
|
275 ! |
|
276 |
|
277 stopMethod |
|
278 | sender | |
|
279 sender := thisContext sender receiver. |
|
280 self addComment: 'END of method generated by ', sender asString. |
|
281 |
|
282 self cache: currentMethod methodName as: currentMethod. |
|
283 ^ self pop. |
|
284 ! |
|
285 |
|
286 top |
|
287 ^ compilerStack top |
256 ! ! |
288 ! ! |
257 |
289 |
258 !PPCCompiler methodsFor:'compiling'! |
290 !PPCCompiler methodsFor:'compiling'! |
259 |
291 |
260 compile: aPPParser as: name |
292 compile: aPPParser as: name |
270 ^ parser |
302 ^ parser |
271 |
303 |
272 ! |
304 ! |
273 |
305 |
274 compileTree: compilerTree as: name parser: parser params: params |
306 compileTree: compilerTree as: name parser: parser params: params |
275 | | |
307 | | |
276 params do: [ :p | |
308 params do: [ :p | |
277 (p key = #guards) ifTrue: [ self guards: p value ]. |
309 (p key = #guards) ifTrue: [ self guards: p value ]. |
278 ]. |
310 ]. |
279 |
311 |
280 |
312 |
281 ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ |
313 ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ |
282 | rPackageOrganizer | |
314 | rPackageOrganizer | |
283 rPackageOrganizer := Smalltalk at: #RPackageOrganizer. |
315 rPackageOrganizer := Smalltalk at: #RPackageOrganizer. |
284 rPackageOrganizer notNil ifTrue:[ |
316 rPackageOrganizer notNil ifTrue:[ |
285 rPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'. |
317 rPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'. |
286 ]. |
318 ]. |
287 |
319 |
288 compiledParser := (Smalltalk at: name ifAbsent: [ nil ]). |
320 compiledParser := (Smalltalk at: name ifAbsent: [ nil ]). |
289 compiledParser ifNil: [ |
321 compiledParser ifNil: [ |
290 PPCompiledParser subclass: name |
322 PPCompiledParser subclass: name |
291 instanceVariableNames:'' |
323 instanceVariableNames:'' |
293 poolDictionaries:'' |
325 poolDictionaries:'' |
294 category:'PetitCompiler-Generated'. |
326 category:'PetitCompiler-Generated'. |
295 compiledParser := Smalltalk at: name. |
327 compiledParser := Smalltalk at: name. |
296 ] ifNotNil: [ |
328 ] ifNotNil: [ |
297 self clean: compiledParser |
329 self clean: compiledParser |
298 ]. |
330 ]. |
299 ] ifFalse: [ |
331 ] ifFalse: [ |
300 RPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'. |
332 RPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'. |
301 compiledParser := (Smalltalk at: name ifAbsent: [ nil ]). |
333 compiledParser := (Smalltalk at: name ifAbsent: [ nil ]). |
302 compiledParser ifNil: [ |
334 compiledParser ifNil: [ |
303 PPCompiledParser subclass: name. |
335 PPCompiledParser subclass: name. |
304 compiledParser := Smalltalk at: name. |
336 compiledParser := Smalltalk at: name. |
305 compiledParser category: 'PetitCompiler-Generated' |
337 compiledParser category: 'PetitCompiler-Generated' |
306 ] ifNotNil: [ |
338 ] ifNotNil: [ |
307 self clean: compiledParser |
339 self clean: compiledParser |
308 ]. |
340 ]. |
309 ]. |
341 ]. |
310 compiledParser constants removeAll. |
342 compiledParser constants removeAll. |
311 |
343 |
312 |
344 rootNode := compilerTree. |
313 self startMethod: #start. |
345 self precomputeFirstSets: rootNode. |
314 self add: '^ '. |
346 self precomputeFollowSets: rootNode. |
315 self callOnLine: (compilerTree compileWith: self). |
347 self precomputeFollowSetsWithTokens: rootNode. |
316 self stopMethod. |
348 |
317 |
349 self startMethod: #start. |
318 self installVariablesAndMethods. |
350 self add: '^ '. |
319 |
351 self callOnLine: (compilerTree compileWith: self). |
320 compiledParser referringParser: parser. |
352 self stopMethod. |
321 ^ compiledParser |
353 |
322 |
354 self installVariablesAndMethods. |
323 "Modified: / 05-11-2014 / 23:17:02 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
355 |
|
356 compiledParser referringParser: parser. |
|
357 ^ compiledParser |
324 ! |
358 ! |
325 |
359 |
326 copy: parser |
360 copy: parser |
327 ^ parser transform: [ :p | p copy ]. |
361 ^ parser transform: [ :p | p copy ]. |
328 ! |
362 ! |
332 class compileSilently: method code classified: 'generated'. |
366 class compileSilently: method code classified: 'generated'. |
333 ] |
367 ] |
334 ! |
368 ! |
335 |
369 |
336 installVariables: class |
370 installVariables: class |
337 | string | |
371 | string | |
338 string := class constants keys inject: '' into: [:r :e | r, ' ', e ]. |
372 string := class constants keys inject: '' into: [:r :e | r, ' ', e ]. |
339 PPCompiledParser subclass: class name instanceVariableNames: string classVariableNames: '' poolDictionaries:'' category: 'PetitCompiler-Generated'. |
373 PPCompiledParser subclass: class name instanceVariableNames: string classVariableNames: '' poolDictionaries: '' category: 'PetitCompiler-Generated'. |
340 |
|
341 "Modified: / 26-10-2014 / 22:01:45 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
342 ! |
374 ! |
343 |
375 |
344 installVariablesAndMethods |
376 installVariablesAndMethods |
345 "Updates the class and compile generated code" |
377 "Updates the class and compile generated code" |
346 |
378 |
354 instances. Therefore, to install methods in in correct class, we have |
386 instances. Therefore, to install methods in in correct class, we have |
355 to refetch new version from system dictionary. On Pharo it should not harm." |
387 to refetch new version from system dictionary. On Pharo it should not harm." |
356 compiledParser := Smalltalk at: compiledParserClassName. |
388 compiledParser := Smalltalk at: compiledParserClassName. |
357 |
389 |
358 self installMethods: compiledParser. |
390 self installMethods: compiledParser. |
359 |
|
360 "Created: / 30-10-2014 / 23:15:44 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
361 ! |
391 ! |
362 |
392 |
363 optimize: parser params: params |
393 optimize: parser params: params |
364 | retval | |
394 | retval | |
365 retval := parser optimizeTree: params. |
395 retval := parser optimizeTree: params. |
366 retval checkTree. |
396 retval checkTree. |
367 ^ retval |
397 ^ retval |
|
398 ! |
|
399 |
|
400 precomputeFirstSets: root |
|
401 | firstSets | |
|
402 firstSets := root firstSets. |
|
403 |
|
404 root allNodesDo: [ :node | |
|
405 node firstSet: (firstSets at: node). |
|
406 ] |
|
407 |
|
408 ! |
|
409 |
|
410 precomputeFollowSets: root |
|
411 | followSets | |
|
412 followSets := root followSets. |
|
413 |
|
414 root allNodesDo: [ :node | |
|
415 node followSet: (followSets at: node). |
|
416 ] |
|
417 |
|
418 ! |
|
419 |
|
420 precomputeFollowSetsWithTokens: root |
|
421 | followSets | |
|
422 followSets := root followSetsSuchThat: [:e | e isTerminal or: [ e isKindOf: PPCTrimmingTokenNode ]]. |
|
423 |
|
424 root allNodesDo: [ :node | |
|
425 node followSetWithTokens: (followSets at: node). |
|
426 ] |
|
427 |
368 ! |
428 ! |
369 |
429 |
370 toCompilerTree: parser |
430 toCompilerTree: parser |
371 ^ parser asCompilerTree |
431 ^ parser asCompilerTree |
372 ! ! |
432 ! ! |