165 ! ! |
165 ! ! |
166 |
166 |
167 !PPCCodeGenerator methodsFor:'visiting'! |
167 !PPCCodeGenerator methodsFor:'visiting'! |
168 |
168 |
169 visitActionNode: node |
169 visitActionNode: node |
170 compiler addConstant: node block as: (compiler idFor: node). |
170 | elementVar | |
171 |
171 |
172 compiler addVariable: 'element'. |
172 compiler addConstant: node block as: (compiler idFor: node). |
173 compiler add: 'element := '. |
173 elementVar := compiler allocateTemporaryVariableNamed:'element'. |
174 compiler callOnLine: (self visit: node child). |
174 compiler add: elementVar,' := '. |
175 compiler add: 'error ifFalse: [ ^ ', (compiler idFor: node), ' value: element ].'. |
175 compiler callOnLine: (self visit: node child). |
176 compiler add: '^ failure'. |
176 compiler add: 'error ifFalse: [ ^ ', (compiler idFor: node), ' value: ',elementVar,' ].'. |
177 |
177 compiler add: '^ failure'. |
178 "Modified: / 23-04-2015 / 15:59:00 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
178 |
|
179 "Modified: / 05-05-2015 / 14:39:52 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
179 ! |
180 ! |
180 |
181 |
181 visitAndNode: node |
182 visitAndNode: node |
182 | mementoVar | |
183 | mementoVar | |
183 |
184 |
249 " |
250 " |
250 ^ self visit: child. |
251 ^ self visit: child. |
251 ! |
252 ! |
252 |
253 |
253 visitChoiceNode: node |
254 visitChoiceNode: node |
254 | firsts guard whitespaceConsumed | |
255 | firsts guard whitespaceConsumed elementVar | |
255 |
256 |
256 |
257 |
257 whitespaceConsumed := false. |
258 whitespaceConsumed := false. |
258 firsts := (node firstSetSuchThat: [ :e | (e isKindOf: PPCTrimmingTokenNode) or: [ e isTerminal ] ]). |
259 firsts := (node firstSetSuchThat: [ :e | (e isKindOf: PPCTrimmingTokenNode) or: [ e isTerminal ] ]). |
259 |
260 |
260 |
261 |
261 compiler addVariable: 'element'. |
262 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
262 "If we start with trimming token, we should invoke the whitespace parser" |
263 "If we start with trimming token, we should invoke the whitespace parser" |
263 (firsts allSatisfy: [ :e | e isKindOf: PPCTrimmingTokenNode ]) ifTrue: [ |
264 (firsts allSatisfy: [ :e | e isKindOf: PPCTrimmingTokenNode ]) ifTrue: [ |
264 self compileTokenWhitespace: firsts anyOne. |
265 self compileTokenWhitespace: firsts anyOne. |
265 whitespaceConsumed := true. |
266 whitespaceConsumed := true. |
266 ]. |
267 ]. |
267 |
268 |
268 1 to: node children size do: [ :idx | |child allowGuard | |
269 1 to: node children size do: [ :idx | |child allowGuard | |
269 child := node children at: idx. |
270 child := node children at: idx. |
270 " allowGuard := ((child isKindOf: PPCTrimmingTokenNode) and: [ whitespaceConsumed not ]) not. |
271 " allowGuard := ((child isKindOf: PPCTrimmingTokenNode) and: [ whitespaceConsumed not ]) not. |
271 " |
272 " |
272 allowGuard := whitespaceConsumed. |
273 allowGuard := whitespaceConsumed. |
273 |
274 |
274 (allowGuard and: [arguments guards and: [ (guard := PPCGuard on: child) makesSense ]]) ifTrue: [ |
275 (allowGuard and: [arguments guards and: [ (guard := PPCGuard on: child) makesSense ]]) ifTrue: [ |
275 guard id: (compiler idFor: guard prefixed: #guard). |
276 guard id: (compiler idFor: guard prefixed: #guard). |
276 guard compileGuard: compiler. |
277 guard compileGuard: compiler. |
277 compiler add: ' ifTrue: [ '. |
278 compiler add: ' ifTrue: [ '. |
278 compiler indent. |
279 compiler indent. |
279 compiler add: 'self clearError.'. |
280 compiler add: 'self clearError.'. |
280 compiler codeStoreValueOf: [self visit: child] intoVariable: 'element'. |
281 compiler codeStoreValueOf: [self visit: child] intoVariable: elementVar. |
281 compiler add: 'error ifFalse: [ ^ element ].'. |
282 compiler add: 'error ifFalse: [ ^ ',elementVar,' ].'. |
282 compiler dedent. |
283 compiler dedent. |
283 compiler add: ' ].'. |
284 compiler add: ' ].'. |
284 ] ifFalse: [ |
285 ] ifFalse: [ |
285 compiler add: 'self clearError.'. |
286 compiler add: 'self clearError.'. |
286 compiler codeStoreValueOf: [self visit: child] intoVariable: 'element'. |
287 compiler codeStoreValueOf: [self visit: child] intoVariable: elementVar. |
287 compiler add: 'error ifFalse: [ ^ element ].'. |
288 compiler add: 'error ifFalse: [ ^ ',elementVar,' ].'. |
288 ] |
289 ] |
289 ]. |
290 ]. |
290 compiler add: '^ self error: ''no choice suitable'''. |
291 compiler add: '^ self error: ''no choice suitable'''. |
291 |
292 |
292 "Modified: / 23-04-2015 / 21:40:23 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
293 "Modified: / 05-05-2015 / 14:10:01 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
293 ! |
294 ! |
294 |
295 |
295 visitEndOfFileNode: node |
296 visitEndOfFileNode: node |
296 compiler codeReturn: 'context atEnd ifTrue: [ #EOF ] ifFalse: [ self error: ''EOF expected!!'' ].'. |
297 compiler codeReturn: 'context atEnd ifTrue: [ #EOF ] ifFalse: [ self error: ''EOF expected!!'' ].'. |
297 ! |
298 ! |
370 compiler add: ' ].'. |
371 compiler add: ' ].'. |
371 compiler dedent. |
372 compiler dedent. |
372 ! |
373 ! |
373 |
374 |
374 visitNotNode: node |
375 visitNotNode: node |
375 |
376 | mementoVar | |
376 |
377 |
377 compiler addVariable: 'memento'. |
378 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
378 compiler add: (compiler smartRemember: node child). |
379 compiler add: (compiler smartRemember: node child to: mementoVar ). |
379 |
380 |
380 compiler call: (self visit: node child). |
381 compiler call: (self visit: node child). |
381 compiler add: (compiler smartRestore: node child). |
382 compiler add: (compiler smartRestore: node child from: mementoVar ). |
382 |
383 |
383 compiler add: '^ error ifFalse: [ self error ] ifTrue: [ self clearError. nil ]'. |
384 compiler add: '^ error ifFalse: [ self error ] ifTrue: [ self clearError. nil ]'. |
|
385 |
|
386 "Modified: / 05-05-2015 / 14:29:52 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
384 ! |
387 ! |
385 |
388 |
386 visitOptionalNode: node |
389 visitOptionalNode: node |
387 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
390 compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar. |
388 compiler add: 'error ifTrue: [ '. |
391 compiler add: 'error ifTrue: [ '. |
465 |
468 |
466 "Modified: / 23-04-2015 / 22:03:11 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
469 "Modified: / 23-04-2015 / 22:03:11 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
467 ! |
470 ! |
468 |
471 |
469 visitStarAnyNode: node |
472 visitStarAnyNode: node |
470 |
473 | retvalVar sizeVar | |
471 compiler addVariable: 'retval size'. |
474 |
472 compiler add: 'size := context size - context position.'. |
475 retvalVar := compiler allocateReturnVariable. |
473 compiler add: 'retval := Array new: size.'. |
476 sizeVar := compiler allocateTemporaryVariableNamed: 'size'. |
474 compiler add: '(1 to: size) do: [ :e | retval at: e put: context next ].'. |
477 compiler add: sizeVar , ' := context size - context position.'. |
475 compiler add: '^ retval'. |
478 compiler add: retvalVar,' := Array new: ',sizeVar,'.'. |
476 |
479 compiler add: '(1 to: ',sizeVar,') do: [ :e | ',retvalVar,' at: e put: context next ].'. |
|
480 compiler codeReturn. |
|
481 |
|
482 "Modified: / 05-05-2015 / 14:13:52 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
477 ! |
483 ! |
478 |
484 |
479 visitStarCharSetPredicateNode: node |
485 visitStarCharSetPredicateNode: node |
480 | classification classificationId | |
486 | classification classificationId | |
481 |
487 |
562 compiler dedent. |
568 compiler dedent. |
563 compiler add: '].'. |
569 compiler add: '].'. |
564 ! |
570 ! |
565 |
571 |
566 visitTokenSequenceNode: node |
572 visitTokenSequenceNode: node |
567 |
573 | mementoVar | |
568 |
574 |
569 compiler addVariable: 'memento'. |
575 mementoVar := compiler allocateTemporaryVariableNamed: 'memento'. |
570 compiler add: (compiler smartRemember: node). |
576 compiler add: (compiler smartRemember: node to: mementoVar). |
571 |
577 " |
572 " self addGuard: compiler." |
578 self addGuard: compiler. |
573 |
579 " |
574 compiler codeStoreValueOf: [ self visit: (node children at: 1) ] intoVariable: #whatever. |
580 compiler codeStoreValueOf: [ self visit: (node children at: 1) ] intoVariable: #whatever. |
575 compiler add: 'error ifTrue: [ ^ failure ].'. |
581 compiler add: 'error ifTrue: [ ^ failure ].'. |
576 |
582 |
577 2 to: (node children size) do: [ :idx | |child| |
583 2 to: (node children size) do: [ :idx | |child| |
578 child := node children at: idx. |
584 child := node children at: idx. |
579 compiler codeStoreValueOf: [ self visit: child ] intoVariable: #whatever. |
585 compiler codeStoreValueOf: [ self visit: child ] intoVariable: #whatever. |
580 compiler add: 'error ifTrue: [ ', (compiler smartRestore: node) ,' ^ failure ].'. |
586 compiler add: 'error ifTrue: [ ', (compiler smartRestore: node from: mementoVar) ,' ^ failure ].'. |
581 ]. |
587 ]. |
|
588 |
|
589 "Modified (comment): / 05-05-2015 / 14:31:57 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
582 ! |
590 ! |
583 |
591 |
584 visitTokenStarMessagePredicateNode: node |
592 visitTokenStarMessagePredicateNode: node |
585 |
593 |
586 compiler add: '[ context peek ', node message,' ] whileTrue: ['. |
594 compiler add: '[ context peek ', node message,' ] whileTrue: ['. |