34 ! ! |
35 ! ! |
35 |
36 |
36 !PPCCompiler methodsFor:'accessing'! |
37 !PPCCompiler methodsFor:'accessing'! |
37 |
38 |
38 arguments: args |
39 arguments: args |
39 arguments := args |
40 arguments := args |
40 ! |
41 ! |
41 |
42 |
42 compiledParser |
43 compiledParser |
43 ^ compiledParser |
44 ^ compiledParser |
|
45 ! |
|
46 |
|
47 compiledParserSuperclass |
|
48 ^ compiledParserSuperclass ifNil: [ PPCompiledParser ] |
44 ! |
49 ! |
45 |
50 |
46 currentNonInlineMethod |
51 currentNonInlineMethod |
47 ^ compilerStack |
52 ^ compilerStack |
48 detect:[:m | m isInline not ] |
53 detect:[:m | m isInline not ] |
49 ifNone:[ self error: 'No non-inlined method'] |
54 ifNone:[ self error: 'No non-inlined method'] |
50 |
55 |
51 "Created: / 23-04-2015 / 17:33:31 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
56 "Created: / 23-04-2015 / 17:33:31 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
52 ! |
57 ! |
53 |
58 |
54 currentReturnVariable |
59 currentReturnVariable |
55 ^ currentMethod returnVariable |
60 ^ currentMethod returnVariable |
56 ! |
61 ! |
57 |
62 |
58 ids |
63 ids |
59 ^ ids |
64 ^ ids |
60 ! |
|
61 |
|
62 rootNode |
|
63 ^ rootNode |
|
64 ! ! |
65 ! ! |
65 |
66 |
66 !PPCCompiler methodsFor:'cleaning'! |
67 !PPCCompiler methodsFor:'cleaning'! |
67 |
68 |
68 clean: class |
69 clean: class |
69 " Transcript crShow: 'Cleaning time: ', |
70 " Transcript crShow: 'Cleaning time: ', |
70 [ |
71 [ |
71 " self cleanGeneratedMethods: class. |
72 " self cleanGeneratedMethods: class. |
72 self cleanInstVars: class. |
73 self cleanInstVars: class. |
73 self cleanConstants: class. |
74 self cleanConstants: class. |
74 " ] timeToRun asMilliSeconds asString, 'ms'." |
75 " ] timeToRun asMilliSeconds asString, 'ms'." |
75 ! |
76 ! |
76 |
77 |
77 cleanConstants: class |
78 cleanConstants: class |
78 class constants removeAll. |
79 class constants removeAll. |
79 ! |
80 ! |
80 |
81 |
81 cleanGeneratedMethods: class |
82 cleanGeneratedMethods: class |
82 ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ |
83 ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ |
83 class methodsDo: [ :mthd | |
84 class methodsDo: [ :mthd | |
84 mthd category = #generated ifTrue:[ |
85 mthd category = #generated ifTrue:[ |
85 class removeSelector: mthd selector. |
86 class removeSelector: mthd selector. |
86 ] |
87 ] |
87 ] |
88 ] |
88 ] ifFalse: [ |
89 ] ifFalse: [ |
89 (class allSelectorsInProtocol: #generated) do: [ :selector | |
90 (class allSelectorsInProtocol: #generated) do: [ :selector | |
90 class removeSelectorSilently: selector ]. |
91 class removeSelectorSilently: selector ]. |
91 ] |
92 ] |
92 ! |
93 ! |
93 |
94 |
94 cleanInstVars: class |
95 cleanInstVars: class |
95 class class instanceVariableNames: ''. |
96 class class instanceVariableNames: ''. |
96 ! |
97 ! |
97 |
98 |
98 cleanParsers: class |
99 cleanParsers: class |
99 class parsers removeAll. |
100 class parsers removeAll. |
100 ! ! |
101 ! ! |
101 |
102 |
102 !PPCCompiler methodsFor:'code generation'! |
103 !PPCCompiler methodsFor:'code generation'! |
103 |
104 |
104 add: string |
105 add: string |
105 currentMethod add: string. |
106 currentMethod add: string. |
106 ! |
107 ! |
107 |
108 |
108 addComment: string |
109 addComment: string |
109 currentMethod add: '"', string, '"'. |
110 currentMethod add: '"', string, '"'. |
110 ! |
111 ! |
111 |
112 |
112 addConstant: value as: name |
113 addConstant: value as: name |
113 constants at: name put: value |
114 constants at: name put: value |
114 ! |
115 ! |
115 |
116 |
116 addOnLine: string |
117 addOnLine: string |
117 currentMethod addOnLine: string. |
118 currentMethod addOnLine: string. |
118 ! |
119 ! |
119 |
120 |
120 addVariable: name |
121 addVariable: name |
121 ^ self currentNonInlineMethod addVariable: name |
122 ^ self currentNonInlineMethod addVariable: name |
122 |
123 |
123 "Modified: / 23-04-2015 / 17:34:02 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
124 "Modified: / 23-04-2015 / 17:34:02 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
124 ! |
125 ! |
125 |
126 |
126 call: anotherMethod |
127 call: anotherMethod |
127 currentMethod add: anotherMethod call. |
128 currentMethod add: anotherMethod call. |
128 ! |
129 ! |
129 |
130 |
130 callOnLine: anotherMethod |
131 callOnLine: anotherMethod |
131 currentMethod addOnLine: anotherMethod call. |
132 currentMethod addOnLine: anotherMethod call. |
132 ! |
133 ! |
133 |
134 |
134 dedent |
135 dedent |
135 currentMethod dedent |
136 currentMethod dedent |
136 ! |
137 ! |
137 |
138 |
138 indent |
139 indent |
139 currentMethod indent |
140 currentMethod indent |
140 ! |
141 ! |
141 |
142 |
142 nl |
143 nl |
143 currentMethod nl |
144 currentMethod nl |
144 ! |
145 ! |
145 |
146 |
146 smartRemember: parser |
147 smartRemember: parser to: variableName |
147 self flag: 'deprecated'. |
148 parser isContextFree ifTrue: [ |
148 ^ self smartRemember: parser to: #memento |
149 self codeAssign: 'context lwRemember.' |
149 ! |
150 to: variableName. |
150 |
151 ] ifFalse: [ |
151 smartRemember: parser to: variableName |
152 self codeAssign: 'context remember.' |
152 parser isContextFree ifTrue: [ |
153 to: variableName. |
153 ^ variableName, ' := context lwRemember.'. |
154 ] |
154 ]. |
|
155 ^ variableName, ':= context remember.' |
|
156 ! |
|
157 |
|
158 smartRestore: parser |
|
159 self flag: 'deprecated'. |
|
160 ^ self smartRestore: parser from: #memento |
|
161 ! |
155 ! |
162 |
156 |
163 smartRestore: parser from: mementoName |
157 smartRestore: parser from: mementoName |
164 parser isContextFree ifTrue: [ |
158 parser isContextFree ifTrue: [ |
165 ^ 'context lwRestore: ', mementoName, '.'. |
159 self add: 'context lwRestore: ', mementoName, '.'. |
166 ]. |
160 ] ifFalse: [ |
167 ^ 'context restore: ', mementoName, '.'. |
161 self add: 'context restore: ', mementoName, '.'. |
|
162 ] |
168 ! ! |
163 ! ! |
169 |
164 |
170 !PPCCompiler methodsFor:'code generation - coding'! |
165 !PPCCompiler methodsFor:'code generation - coding'! |
171 |
166 |
172 codeAssign: code to: variable |
167 codeAssign: code to: variable |
173 self assert: variable isNil not. |
168 self assert: variable isNil not. |
174 |
169 |
175 "TODO JK: Hack alert, whatever is magic constant!!" |
170 "TODO JK: Hack alert, whatever is magic constant!!" |
176 (variable == #whatever) ifFalse: [ |
171 (variable == #whatever) ifFalse: [ |
177 "Do not assign, if somebody does not care!!" |
172 "Do not assign, if somebody does not care!!" |
178 self add: variable ,' := ', code. |
173 self add: variable ,' := ', code. |
179 ] ifTrue: [ |
174 ] ifTrue: [ |
180 "In case code hava a side effect" |
175 "In case code hava a side effect" |
181 self add: code |
176 self add: code |
182 ] |
177 ] |
183 ! |
178 ! |
184 |
179 |
185 codeClearError |
180 codeClearError |
186 self add: 'self clearError.'. |
181 self add: 'self clearError.'. |
187 ! |
182 ! |
188 |
183 |
189 codeError: errorMessage |
184 codeError: errorMessage |
190 self add: 'self error: ''', errorMessage, '''.' |
185 self add: 'self error: ''', errorMessage, '''.' |
191 ! |
186 ! |
192 |
187 |
193 codeHalt |
188 codeHalt |
194 self add: 'self halt. ' |
189 self add: 'self halt. ' |
|
190 ! |
|
191 |
|
192 codeHaltIfShiftPressed |
|
193 arguments debug ifTrue: [ |
|
194 self add: 'Halt ifShiftPressed.' |
|
195 ] |
|
196 ! |
|
197 |
|
198 codeNextToken |
|
199 self add: 'self nextToken.' |
|
200 |
|
201 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
202 "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
195 ! |
203 ! |
196 |
204 |
197 codeReturn |
205 codeReturn |
198 currentMethod isInline ifTrue: [ |
206 currentMethod isInline ifTrue: [ |
199 "If inlined, the return variable already holds the value" |
207 "If inlined, the return variable already holds the value" |
204 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
212 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
205 "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
213 "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
206 ! |
214 ! |
207 |
215 |
208 codeReturn: code |
216 codeReturn: code |
209 " - returns whatever is in code OR |
217 " - returns whatever is in code OR |
210 - assigns whatever is in code into the returnVariable" |
218 - assigns whatever is in code into the returnVariable" |
211 currentMethod isInline ifTrue:[ |
219 currentMethod isInline ifTrue:[ |
212 self codeAssign: code to: currentMethod returnVariable. |
220 self codeAssign: code to: currentMethod returnVariable. |
213 ] ifFalse: [ |
221 ] ifFalse: [ |
214 self add: '^ ', code |
222 self add: '^ ', code |
215 ] |
223 ] |
216 |
224 |
217 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
225 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
218 "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
226 "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
219 ! |
227 ! |
220 |
228 |
221 codeStoreValueOf: aBlock intoVariable: aString |
229 codeStoreValueOf: aBlock intoVariable: aString |
222 | tmpVarirable method | |
230 | tmpVarirable method | |
223 self assert: aBlock isBlock. |
231 self assert: aBlock isBlock. |
224 self assert: aString isNil not. |
232 self assert: aString isNil not. |
225 |
233 |
226 tmpVarirable := returnVariable. |
234 tmpVarirable := returnVariable. |
227 returnVariable := aString. |
235 returnVariable := aString. |
228 method := [ |
236 method := [ |
229 aBlock value |
237 aBlock value |
230 ] ensure: [ |
238 ] ensure: [ |
231 returnVariable := tmpVarirable |
239 returnVariable := tmpVarirable |
232 ]. |
240 ]. |
233 |
241 |
234 method isInline ifTrue: [ |
242 method isInline ifTrue: [ |
235 self callOnLine: method |
243 self callOnLine: method |
236 ] ifFalse: [ |
244 ] ifFalse: [ |
237 self codeAssign: (method call) to: aString. |
245 self codeAssign: (method call) to: aString. |
238 ] |
246 ] |
239 |
247 |
240 "Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
248 "Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
249 ! |
|
250 |
|
251 codeTranscriptShow: text |
|
252 (arguments profile) ifTrue: [ |
|
253 self add: 'Transcript show: ', text storeString, '; cr.'. |
|
254 ] |
241 ! ! |
255 ! ! |
242 |
256 |
243 !PPCCompiler methodsFor:'code generation - ids'! |
257 !PPCCompiler methodsFor:'code generation - ids'! |
244 |
258 |
|
259 asSelector: string |
|
260 "e.g. '234znak 43 ) 2' asLegalSelector = #v234znak432" |
|
261 |
|
262 | toUse | |
|
263 toUse := string select: [:char | char isAlphaNumeric or: [ char = $_ ] ]. |
|
264 (toUse isEmpty or: [ toUse first isLetter not ]) |
|
265 ifTrue: [ toUse := 'v', toUse ]. |
|
266 ^ toUse uncapitalized asSymbol. |
|
267 ! |
|
268 |
245 idFor: object |
269 idFor: object |
246 self assert: (object isKindOf: PPCNode). |
270 self assert: (object isKindOf: PPCNode). |
247 ^ self idFor: object prefixed: object prefix suffixed: object suffix effect: #none |
271 ^ self idFor: object prefixed: object prefix suffixed: object suffix effect: #none |
248 ! |
272 ! |
249 |
273 |
250 idFor: object prefixed: prefix |
274 idFor: object prefixed: prefix |
251 ^ self idFor: object prefixed: prefix effect: #none |
275 ^ self idFor: object prefixed: prefix effect: #none |
252 ! |
276 ! |
253 |
277 |
254 idFor: object prefixed: prefix effect: effect |
278 idFor: object prefixed: prefix effect: effect |
255 ^ self idFor: object prefixed: prefix suffixed: '' effect: effect. |
279 ^ self idFor: object prefixed: prefix suffixed: '' effect: effect. |
256 ! |
280 ! |
257 |
281 |
258 idFor: object prefixed: prefix suffixed: suffix effect: effect |
282 idFor: object prefixed: prefix suffixed: suffix effect: effect |
259 | name id | |
283 | name id | |
260 ^ ids at: object ifAbsentPut: [ |
284 ^ ids at: object ifAbsentPut: [ |
261 ((object isKindOf: PPCNode) and: [object name isNotNil]) ifTrue: [ |
285 ((object isKindOf: PPCNode) and: [object name isNotNil]) ifTrue: [ |
262 "Do not use prefix, if there is a name" |
286 "Do not use prefix, if there is a name" |
263 name := object name. |
287 name := self asSelector: object name. |
264 "Selector sanitizing inlined here as Smalltalk/X does not |
288 id := (name, suffix) asSymbol. |
265 support asLegalSelector" |
289 |
266 name := name select: [:char | char isAlphaNumeric]. |
290 "Make sure, that the generated ID is uniqe!!" |
267 (name isEmpty or: [ name first isLetter not ]) |
291 (ids includes: id) ifTrue: [ |
268 ifTrue: [ name := 'v', name ]. |
292 (id, '_', ids size asString) asSymbol |
269 id := (name, suffix) asSymbol. |
293 ] ifFalse: [ |
270 |
294 id |
271 "Make sure, that the generated ID is uniqe!!" |
295 ] |
272 (ids includes: id) ifTrue: [ |
296 ] ifFalse: [ |
273 (id, '_', ids size asString) asSymbol |
297 (prefix, '_', (ids size asString), suffix) asSymbol |
274 ] ifFalse: [ |
|
275 id |
|
276 ] |
|
277 ] ifFalse: [ |
|
278 (prefix, '_', (ids size asString), suffix) asSymbol |
|
279 ] |
|
280 ] |
298 ] |
281 |
299 ] |
282 "Modified: / 01-05-2015 / 14:38:37 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
300 ! |
|
301 |
|
302 idFor: object suffixed: suffix |
|
303 self assert: (object isKindOf: PPCNode) description: 'Shold use PPCNode for ids'. |
|
304 ^ self idFor: object prefixed: object prefix suffixed: suffix effect: #none |
283 ! ! |
305 ! ! |
284 |
306 |
285 !PPCCompiler methodsFor:'code generation - support'! |
307 !PPCCompiler methodsFor:'code generation - support'! |
286 |
308 |
287 cache: id as: value |
309 cache: id as: value |
288 cache at: id put: value. |
310 cache at: id put: value. |
289 ! |
311 ! |
290 |
312 |
291 cachedValue: id |
313 cachedValue: id |
292 ^ cache at: id ifAbsent: [ nil ] |
314 ^ cache at: id ifAbsent: [ nil ] |
293 ! |
315 ! |
294 |
316 |
295 checkCache: id |
317 checkCache: id |
296 | method | |
318 | method | |
297 "Check if method is hand written" |
319 "Check if method is hand written" |
298 method := compiledParser ifNotNil: [ compiledParser compiledMethodAt: id ifAbsent: [ nil ] ]. |
320 method := compiledParser ifNotNil: [ compiledParser compiledMethodAt: id ifAbsent: [ nil ] ]. |
299 method ifNotNil: [ ^ PPCCompiledMethod new id: id; yourself ]. |
321 method ifNotNil: [ ^ PPCCompiledMethod new id: id; yourself ]. |
300 |
322 |
301 ^ self cachedValue: id |
323 ^ self cachedValue: id |
302 ! |
324 ! |
303 |
325 |
304 pop |
326 pop |
305 | retval | |
327 | retval | |
306 retval := compilerStack pop. |
328 retval := compilerStack pop. |
307 currentMethod := compilerStack isEmpty |
329 currentMethod := compilerStack isEmpty |
308 ifTrue: [ nil ] |
330 ifTrue: [ nil ] |
309 ifFalse: [ compilerStack top ]. |
331 ifFalse: [ compilerStack top ]. |
310 ^ retval |
332 ^ retval |
311 |
333 |
312 "Modified: / 21-11-2014 / 12:27:25 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
334 "Modified: / 21-11-2014 / 12:27:25 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
313 ! |
335 ! |
314 |
336 |
315 push |
337 push |
316 compilerStack push: currentMethod. |
338 compilerStack push: currentMethod. |
317 (compilerStack size > 500 )ifTrue: [ self error: 'unless it is very complex grammar, there is an error somewhere' ] |
339 (compilerStack size > 500 )ifTrue: [ self error: 'unless it is very complex grammar, there is an error somewhere' ] |
318 |
340 |
319 "Modified: / 21-11-2014 / 12:27:18 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
341 "Modified: / 21-11-2014 / 12:27:18 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
320 ! |
342 ! |
321 |
343 |
322 startInline: id |
344 startInline: id |
323 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
345 | indentationLevel | |
324 |
346 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
325 currentMethod := PPCInlinedMethod new. |
347 indentationLevel := currentMethod indentationLevel. |
326 currentMethod id: id. |
348 |
327 currentMethod profile: arguments profile. |
349 currentMethod := PPCInlinedMethod new. |
328 currentMethod returnVariable: returnVariable. |
350 currentMethod id: id. |
329 self push. |
351 currentMethod profile: arguments profile. |
|
352 currentMethod returnVariable: returnVariable. |
|
353 currentMethod indentationLevel: indentationLevel. |
|
354 self push. |
330 |
355 |
331 "Modified: / 23-04-2015 / 18:28:26 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
356 "Modified: / 23-04-2015 / 18:28:26 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
332 ! |
357 ! |
333 |
358 |
334 startMethod: id |
359 startMethod: id |
335 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
360 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
336 |
361 |
337 currentMethod := PPCMethod new. |
362 currentMethod := PPCMethod new. |
338 currentMethod id: id. |
363 currentMethod id: id. |
339 currentMethod profile: arguments profile. |
364 currentMethod profile: arguments profile. |
340 self push. |
365 self push. |
341 |
366 |
342 self cache: id as: currentMethod. |
367 self cache: id as: currentMethod. |
343 |
368 |
344 "Modified: / 23-04-2015 / 18:36:23 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
369 "Modified: / 23-04-2015 / 18:36:23 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
345 ! |
370 ! |
346 |
371 |
347 stopInline |
372 stopInline |
348 |
373 |
349 ^ self pop. |
374 ^ self pop. |
350 |
375 |
351 "Modified: / 23-04-2015 / 18:28:33 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
376 "Modified: / 23-04-2015 / 18:28:33 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
352 ! |
377 ! |
353 |
378 |
354 stopMethod |
379 stopMethod |
355 self cache: currentMethod methodName as: currentMethod. |
380 self cache: currentMethod methodName as: currentMethod. |
356 |
381 |
357 arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ]. |
382 arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ]. |
358 ^ self pop. |
383 ^ self pop. |
359 |
384 |
360 "Modified: / 01-05-2015 / 14:18:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
385 "Modified: / 01-05-2015 / 14:18:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
361 ! |
386 ! |
362 |
387 |
363 top |
388 top |
364 ^ compilerStack top |
389 ^ compilerStack top |
365 ! ! |
390 ! ! |
366 |
391 |
367 !PPCCompiler methodsFor:'code generation - variables'! |
392 !PPCCompiler methodsFor:'code generation - variables'! |
368 |
393 |
369 allocateReturnVariable |
394 allocateReturnVariable |
385 ! ! |
410 ! ! |
386 |
411 |
387 !PPCCompiler methodsFor:'compiling'! |
412 !PPCCompiler methodsFor:'compiling'! |
388 |
413 |
389 compileParser |
414 compileParser |
390 self installVariables. |
415 self installVariables. |
391 self installMethods. |
416 self installMethods. |
392 self installClassConstants. |
417 self installClassConstants. |
393 |
418 |
394 ^ compiledParser |
419 ^ compiledParser |
395 ! |
420 ! |
396 |
421 |
397 copy: parser |
422 copy: parser |
398 ^ parser transform: [ :p | p copy ]. |
423 ^ parser transform: [ :p | p copy ]. |
399 ! |
424 ! |
400 |
425 |
401 installClassConstants |
426 installClassConstants |
402 constants keysAndValuesDo: [ :key :value | |
427 constants keysAndValuesDo: [ :key :value | |
403 compiledParser constants at: key put: value |
428 compiledParser constants at: key put: value |
404 ] |
429 ] |
405 ! |
430 ! |
406 |
431 |
407 installMethods |
432 installMethods |
408 cache keysAndValuesDo: [ :key :method | |
433 cache keysAndValuesDo: [ :key :method | |
409 compiledParser compileSilently: method code classified: 'generated'. |
434 compiledParser compileSilently: method code classified: 'generated'. |
410 ] |
435 ] |
411 ! |
436 ! |
412 |
437 |
413 installVariables |
438 installVariables |
414 | varString | |
439 | varString | |
415 varString := constants keys inject: '' into: [:r :e | r, ' ', e ]. |
440 varString := constants keys inject: '' into: [:r :e | r, ' ', e ]. |
416 |
441 |
417 PPCompiledParser |
442 (self compiledParserSuperclass) |
418 subclass: compiledParserName |
443 subclass: compiledParserName |
419 instanceVariableNames: varString |
444 instanceVariableNames: varString |
420 classVariableNames: '' |
445 classVariableNames: '' |
421 poolDictionaries: '' |
446 poolDictionaries: '' |
422 category: 'PetitCompiler-Generated'. |
447 category: 'PetitCompiler-Generated'. |
423 |
448 |
424 compiledParser := Smalltalk at: compiledParserName. |
449 compiledParser := Smalltalk at: compiledParserName. |
425 ! |
|
426 |
|
427 precomputeFirstSets: root |
|
428 | firstSets | |
|
429 firstSets := root firstSets. |
|
430 |
|
431 root allNodesDo: [ :node | |
|
432 node firstSet: (firstSets at: node). |
|
433 ] |
|
434 |
|
435 ! |
|
436 |
|
437 precomputeFollowSets: root |
|
438 | followSets | |
|
439 followSets := root followSets. |
|
440 |
|
441 root allNodesDo: [ :node | |
|
442 node followSet: (followSets at: node). |
|
443 ] |
|
444 |
|
445 ! |
|
446 |
|
447 precomputeFollowSetsWithTokens: root |
|
448 | followSets | |
|
449 followSets := root followSetsSuchThat: [:e | e isTerminal or: [ e isKindOf: PPCTrimmingTokenNode ]]. |
|
450 |
|
451 root allNodesDo: [ :node | |
|
452 node followSetWithTokens: (followSets at: node). |
|
453 ] |
|
454 |
|
455 ! |
|
456 |
|
457 toCompilerTree: parser |
|
458 ^ parser asCompilerTree |
|
459 ! ! |
450 ! ! |
460 |
451 |
461 !PPCCompiler methodsFor:'initialization'! |
452 !PPCCompiler methodsFor:'initialization'! |
462 |
453 |
463 initializeForCompiledClassName: aString |
454 initializeForCompiledClassName: aString |
464 |
455 |
465 self initialize. |
456 self initialize. |
466 compilerStack := Stack new. |
457 compilerStack := Stack new. |
467 cache := IdentityDictionary new. |
458 cache := IdentityDictionary new. |
468 constants := IdentityDictionary new. |
459 constants := IdentityDictionary new. |
469 ids := IdentityDictionary new. |
460 ids := IdentityDictionary new. |
470 |
461 |
471 |
462 |
472 compiledParserName := aString asSymbol. |
463 compiledParserName := aString asSymbol. |
473 |
464 |
474 ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ |
465 ((Smalltalk respondsTo:#isSmalltalkX) and:[ Smalltalk isSmalltalkX ]) ifTrue:[ |
475 | rPackageOrganizer | |
466 | rPackageOrganizer | |
476 rPackageOrganizer := Smalltalk at: #RPackageOrganizer. |
467 rPackageOrganizer := Smalltalk at: #RPackageOrganizer. |
477 rPackageOrganizer notNil ifTrue:[ |
468 rPackageOrganizer notNil ifTrue:[ |
478 rPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'. |
469 rPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'. |
479 ]. |
470 ]. |
480 ] ifFalse: [ |
471 ] ifFalse: [ |
481 RPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'. |
472 RPackageOrganizer default registerPackageNamed: 'PetitCompiler-Generated'. |
482 ]. |
473 ]. |
483 |
474 |
484 Smalltalk at: compiledParserName ifPresent: [ :class | |
475 Smalltalk at: compiledParserName ifPresent: [ :class | |
485 compiledParser := class. |
476 compiledParser := class. |
486 self clean: compiledParser. |
477 self clean: compiledParser. |
487 ]. |
478 ]. |
|
479 |
|
480 |
|
481 Transcript cr; show: 'intialized for: ', aString; cr. |
488 ! ! |
482 ! ! |
489 |
483 |
490 !PPCCompiler class methodsFor:'documentation'! |
484 !PPCCompiler class methodsFor:'documentation'! |
491 |
485 |
492 version_HG |
486 version_HG |