15 !PPCCompiler class methodsFor:'instance creation'! |
15 !PPCCompiler class methodsFor:'instance creation'! |
16 |
16 |
17 new |
17 new |
18 "return an initialized instance" |
18 "return an initialized instance" |
19 |
19 |
20 ^ self basicNew initializeForCompiledClassName: 'PPGeneratedParser' |
20 ^ self on: PPCArguments default |
21 ! |
|
22 |
|
23 newForCompiledClassName: aString |
|
24 "return an initialized instance" |
|
25 self halt: 'deprecated'. |
|
26 ^ self basicNew initializeForCompiledClassName: aString |
|
27 ! |
21 ! |
28 |
22 |
29 on: aPPCArguments |
23 on: aPPCArguments |
30 "return an initialized instance" |
24 "return an initialized instance" |
31 |
25 |
32 ^ self basicNew |
26 ^ self basicNew |
33 arguments: aPPCArguments; |
27 arguments: aPPCArguments; |
34 initializeForCompiledClassName: aPPCArguments name |
28 initializeForCompiledClassName: aPPCArguments parserName |
35 ! ! |
29 ! ! |
36 |
30 |
37 !PPCCompiler methodsFor:'accessing'! |
31 !PPCCompiler methodsFor:'accessing'! |
38 |
32 |
39 arguments: args |
33 arguments: args |
69 ! ! |
63 ! ! |
70 |
64 |
71 !PPCCompiler methodsFor:'cleaning'! |
65 !PPCCompiler methodsFor:'cleaning'! |
72 |
66 |
73 clean: class |
67 clean: class |
74 " Transcript crShow: 'Cleaning time: ', |
68 " Transcript show: ('Cleaning time: ', |
75 [ |
69 [ |
76 " self cleanGeneratedMethods: class. |
70 " self cleanGeneratedMethods: class. |
77 self cleanInstVars: class. |
71 self cleanInstVars: class. |
78 self cleanConstants: class. |
72 self cleanConstants: class. |
79 " ] timeToRun asMilliSeconds asString, 'ms'." |
73 " ] timeToRun asMilliSeconds asString, 'ms'); cr. " |
80 ! |
74 ! |
81 |
75 |
82 cleanConstants: class |
76 cleanConstants: class |
83 class constants removeAll. |
77 class constants removeAll. |
84 ! |
78 ! |
169 ] |
171 ] |
170 ! ! |
172 ! ! |
171 |
173 |
172 !PPCCompiler methodsFor:'code generation - coding'! |
174 !PPCCompiler methodsFor:'code generation - coding'! |
173 |
175 |
|
176 code:aStringOrBlockOrRBParseNode |
|
177 currentMethod code: aStringOrBlockOrRBParseNode |
|
178 |
|
179 "Created: / 01-06-2015 / 23:49:11 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
180 ! |
|
181 |
174 codeAssign: code to: variable |
182 codeAssign: code to: variable |
175 self assert: variable isNil not. |
183 self assert: variable isNil not. |
176 |
184 |
177 "TODO JK: Hack alert, whatever is magic constant!!" |
185 "TODO JK: Hack alert, whatever is magic constant!!" |
178 (variable == #whatever) ifFalse: [ |
186 (variable == #whatever) ifFalse: [ |
179 "Do not assign, if somebody does not care!!" |
187 "Do not assign, if somebody does not care!!" |
180 self add: variable ,' := ', code. |
188 self add: variable ,' := ', code. |
181 ] |
189 ] |
182 ! |
190 ! |
183 |
191 |
|
192 codeAssignParsedValueOf:aBlock to:aString |
|
193 | tmpVarirable method | |
|
194 |
|
195 self assert:aBlock isBlock. |
|
196 self assert:aString isNil not. |
|
197 tmpVarirable := returnVariable. |
|
198 returnVariable := aString. |
|
199 method := [ |
|
200 aBlock value |
|
201 ] ensure:[ returnVariable := tmpVarirable ]. |
|
202 self assert: (method isKindOf: PPCMethod). |
|
203 method isInline ifTrue:[ |
|
204 self callOnLine:method |
|
205 ] ifFalse:[ |
|
206 self codeEvaluateAndAssign:(method call) to:aString. |
|
207 ] |
|
208 |
|
209 "Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
210 ! |
|
211 |
|
212 codeBlock: contents |
|
213 currentMethod codeBlock: contents |
|
214 |
|
215 "Created: / 01-06-2015 / 22:35:32 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
216 ! |
|
217 |
184 codeClearError |
218 codeClearError |
185 self add: 'self clearError.'. |
219 self add: 'self clearError.'. |
|
220 ! |
|
221 |
|
222 codeDot |
|
223 self addOnLine:'.'. |
|
224 |
|
225 "Created: / 16-06-2015 / 06:09:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
186 ! |
226 ! |
187 |
227 |
188 codeError |
228 codeError |
189 self add: 'self error: ''message notspecified''.'. |
229 self add: 'self error: ''message notspecified''.'. |
190 ! |
230 ! |
202 |
242 |
203 "TODO JK: Hack alert, whatever is magic constant!!" |
243 "TODO JK: Hack alert, whatever is magic constant!!" |
204 (variable == #whatever) ifFalse: [ |
244 (variable == #whatever) ifFalse: [ |
205 "Do not assign, if somebody does not care!!" |
245 "Do not assign, if somebody does not care!!" |
206 self add: variable, ' ', selector,' ', argument. |
246 self add: variable, ' ', selector,' ', argument. |
207 ] ifTrue: [ |
247 ] ifTrue: [ |
208 "In case argument has a side effect" |
248 "In case argument has a side effect" |
209 self add: argument |
249 self add: argument |
210 ] |
250 ] |
211 ! |
251 ! |
212 |
252 |
213 codeEvaluateAndAssign: argument to: variable |
253 codeEvaluateAndAssign: argument to: variable |
214 self assert: variable isNil not. |
254 self assert: variable isNil not. |
235 ] |
275 ] |
236 |
276 |
237 "Modified: / 10-05-2015 / 07:39:47 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
277 "Modified: / 10-05-2015 / 07:39:47 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
238 ! |
278 ! |
239 |
279 |
|
280 codeIf: condition then: then |
|
281 self codeIf: condition then: then else: nil |
|
282 |
|
283 "Created: / 16-06-2015 / 06:07:06 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
284 ! |
|
285 |
|
286 codeIf: condition then: then else: else |
|
287 currentMethod |
|
288 add: '('; |
|
289 code: condition; |
|
290 addOnLine: ')'. |
|
291 then notNil ifTrue:[ |
|
292 currentMethod |
|
293 addOnLine:' ifTrue:'; |
|
294 codeBlock: then. |
|
295 ]. |
|
296 else notNil ifTrue:[ |
|
297 currentMethod |
|
298 addOnLine:' ifFalse:'; |
|
299 codeBlock: else. |
|
300 ]. |
|
301 self codeDot. |
|
302 |
|
303 "Created: / 01-06-2015 / 22:43:15 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
304 "Modified: / 16-06-2015 / 06:09:33 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
305 ! |
|
306 |
|
307 codeIfErrorThen: then |
|
308 ^ self codeIf: 'error' then: then else: nil |
|
309 |
|
310 "Created: / 16-06-2015 / 06:06:44 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
311 ! |
|
312 |
|
313 codeIfErrorThen: then else: else |
|
314 ^ self codeIf: 'error' then: then else: else |
|
315 |
|
316 "Created: / 16-06-2015 / 06:05:56 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
317 ! |
|
318 |
240 codeNextToken |
319 codeNextToken |
241 self add: 'self nextToken.' |
320 self add: 'self nextToken.' |
242 |
321 |
243 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
322 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
244 "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
323 "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
245 ! |
324 ! |
246 |
325 |
|
326 codeProfileStart |
|
327 self add: 'context methodInvoked: #', currentMethod methodName, '.' |
|
328 |
|
329 "Created: / 01-06-2015 / 21:17:19 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
330 ! |
|
331 |
|
332 codeProfileStop |
|
333 self add: 'context methodFinished: #', currentMethod methodName, '.' |
|
334 |
|
335 "Created: / 01-06-2015 / 21:19:11 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
336 ! |
|
337 |
247 codeReturn |
338 codeReturn |
248 currentMethod isInline ifTrue: [ |
339 currentMethod isInline ifTrue: [ |
249 "If inlined, the return variable already holds the value" |
340 "If inlined, the return variable already holds the value" |
250 ] ifFalse: [ |
341 ] ifFalse: [ |
251 self add: '^ ', currentMethod returnVariable |
342 arguments profile ifTrue:[ |
252 ]. |
343 self codeProfileStop. |
|
344 ]. |
|
345 self add: '^ ', currentMethod returnVariable |
|
346 ]. |
253 |
347 |
254 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
348 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
255 "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
349 "Modified: / 01-06-2015 / 21:49:04 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
256 ! |
350 ! |
257 |
351 |
258 codeReturn: code |
352 codeReturn: code |
259 " - returns whatever is in code OR |
353 " - returns whatever is in code OR |
260 - assigns whatever is in code into the returnVariable" |
354 - assigns whatever is in code into the returnVariable" |
261 currentMethod isInline ifTrue:[ |
355 currentMethod isInline ifTrue:[ |
262 self codeEvaluateAndAssign: code to: currentMethod returnVariable. |
356 self codeEvaluateAndAssign: code to: currentMethod returnVariable. |
263 ] ifFalse: [ |
357 ] ifFalse: [ |
264 self add: '^ ', code |
358 arguments profile ifTrue:[ |
|
359 self codeProfileStop. |
|
360 ]. |
|
361 self add: '^ ', code |
265 ] |
362 ] |
266 |
363 |
267 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
364 "Created: / 23-04-2015 / 18:01:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
268 "Modified: / 23-04-2015 / 20:51:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
365 "Modified: / 01-06-2015 / 21:48:51 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
366 ! |
|
367 |
|
368 codeReturnParsedValueOf:aBlock |
|
369 | tmpVarirable method | |
|
370 |
|
371 self assert:aBlock isBlock. |
|
372 tmpVarirable := returnVariable. |
|
373 method := aBlock value. |
|
374 self assert: returnVariable == tmpVarirable. |
|
375 self assert: (method isKindOf: PPCMethod). |
|
376 method isInline ifTrue:[ |
|
377 self callOnLine:method. |
|
378 self codeReturn: returnVariable. |
|
379 ] ifFalse:[ |
|
380 self codeReturn: method call. |
|
381 |
|
382 ] |
|
383 |
|
384 "Created: / 23-04-2015 / 18:21:51 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
269 ! |
385 ! |
270 |
386 |
271 codeStoreValueOf: aBlock intoVariable: aString |
387 codeStoreValueOf: aBlock intoVariable: aString |
272 | tmpVarirable method | |
388 | tmpVarirable method | |
273 self assert: aBlock isBlock. |
389 self assert: aBlock isBlock. |
417 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
533 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
418 indentationLevel := currentMethod indentationLevel. |
534 indentationLevel := currentMethod indentationLevel. |
419 |
535 |
420 currentMethod := PPCInlinedMethod new. |
536 currentMethod := PPCInlinedMethod new. |
421 currentMethod id: id. |
537 currentMethod id: id. |
422 currentMethod profile: arguments profile. |
|
423 currentMethod returnVariable: returnVariable. |
538 currentMethod returnVariable: returnVariable. |
424 currentMethod indentationLevel: indentationLevel. |
539 currentMethod indentationLevel: indentationLevel. |
425 self push. |
540 self push. |
426 |
541 |
427 "Modified: / 23-04-2015 / 18:28:26 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
542 "Modified: / 01-06-2015 / 21:48:35 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
428 ! |
543 ! |
429 |
544 |
430 startMethod: id |
545 startMethod: id |
431 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
546 (cache includesKey: id) ifTrue: [ self error: 'OOOUPS!!' ]. |
432 |
547 |
433 currentMethod := PPCMethod new. |
548 currentMethod := PPCMethod new. |
434 currentMethod id: id. |
549 currentMethod id: id. |
435 currentMethod profile: arguments profile. |
550 arguments profile ifTrue:[ |
|
551 self codeProfileStart. |
|
552 ]. |
436 self push. |
553 self push. |
437 |
554 |
438 self cache: id as: currentMethod. |
555 self cache: id as: currentMethod. |
439 |
556 |
440 "Modified: / 23-04-2015 / 18:36:23 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
557 "Modified: / 01-06-2015 / 21:19:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
441 ! |
558 ! |
442 |
559 |
443 stopInline |
560 stopInline |
444 |
|
445 ^ self pop. |
561 ^ self pop. |
446 |
562 |
447 "Modified: / 23-04-2015 / 18:28:33 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
563 "Modified: / 01-06-2015 / 21:37:59 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
448 ! |
564 ! |
449 |
565 |
450 stopMethod |
566 stopMethod |
451 self cache: currentMethod methodName as: currentMethod. |
567 self cache: currentMethod methodName as: currentMethod. |
452 |
568 |
453 "arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ]." |
569 "arguments profile ifTrue: [ Transcript show: currentMethod code; cr. ]." |
454 ^ self pop. |
570 ^ self pop. |
455 |
571 |
456 "Modified: / 01-05-2015 / 14:18:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
572 "Modified: / 01-06-2015 / 21:38:05 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
457 ! |
573 ! |
458 |
574 |
459 top |
575 top |
460 ^ compilerStack top |
576 ^ compilerStack top |
461 ! ! |
577 ! ! |
462 |
578 |
463 !PPCCompiler methodsFor:'code generation - variables'! |
579 !PPCCompiler methodsFor:'code generation - variables'! |
464 |
580 |
465 allocateReturnVariable |
581 allocateReturnVariable |
466 "Return a new variable to store parsed value" |
582 ^ self allocateReturnVariableNamed: 'retval' |
467 |
583 |
468 ^ currentMethod allocateReturnVariable |
584 "Created: / 23-04-2015 / 18:03:40 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
469 |
585 "Modified: / 15-06-2015 / 17:52:56 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
470 "Created: / 23-04-2015 / 17:58:00 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
586 ! |
471 "Modified (comment): / 23-04-2015 / 21:12:57 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
587 |
|
588 allocateReturnVariableNamed: name |
|
589 "Allocate (or return previously allocated one) temporary variable used for |
|
590 storing a parser's return value (the parsed object)" |
|
591 ^ currentMethod allocateReturnVariableNamed: name |
|
592 |
|
593 "Created: / 15-06-2015 / 18:04:48 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
472 ! |
594 ! |
473 |
595 |
474 allocateTemporaryVariableNamed: preferredName |
596 allocateTemporaryVariableNamed: preferredName |
475 "Allocate a new variable with (preferably) given name. |
597 "Allocate a new variable with (preferably) given name. |
476 Returns a real variable name that should be used." |
598 Returns a real variable name that should be used." |