30 compiler := aPPCCompiler |
29 compiler := aPPCCompiler |
31 ! |
30 ! |
32 |
31 |
33 guards |
32 guards |
34 ^ arguments guards |
33 ^ arguments guards |
|
34 ! ! |
|
35 |
|
36 !PPCCodeGenerator methodsFor:'code generation'! |
|
37 |
|
38 generateChoiceChildOf: choiceNode atIndex: choiceChildNodeIndex useGuards: useGuards storeResultInto: resultVar |
|
39 |
|
40 | children | |
|
41 |
|
42 children := choiceNode children. |
|
43 useGuards ifTrue:[ |
|
44 self addGuard: (children at: choiceChildNodeIndex) ifTrue: [ |
|
45 compiler add: 'self clearError.'. |
|
46 compiler |
|
47 codeAssignParsedValueOf:[ self visit:(children at: choiceChildNodeIndex) ] |
|
48 to: resultVar. |
|
49 compiler add: 'error ifFalse: [ '. |
|
50 compiler codeReturn: resultVar. |
|
51 compiler add: ' ].'. |
|
52 ] ifFalse:[ |
|
53 compiler add: 'error := true.'. |
|
54 ]. |
|
55 compiler add: 'error ifTrue:[ '. |
|
56 choiceChildNodeIndex < children size ifTrue:[ |
|
57 self generateChoiceChildOf: choiceNode atIndex: choiceChildNodeIndex + 1 useGuards: useGuards storeResultInto: resultVar. |
|
58 ] ifFalse:[ |
|
59 compiler codeError: 'no choice suitable'. |
|
60 ]. |
|
61 compiler addOnLine: '].'. |
|
62 |
|
63 ] ifFalse:[ |
|
64 choiceChildNodeIndex <= children size ifTrue:[ |
|
65 compiler add: 'self clearError.'. |
|
66 compiler |
|
67 codeAssignParsedValueOf:[ self visit:(children at: choiceChildNodeIndex) ] |
|
68 to: resultVar. |
|
69 compiler add: 'error ifFalse: [ '. |
|
70 compiler codeReturn: resultVar. |
|
71 compiler add: ' ].'. |
|
72 self generateChoiceChildOf: choiceNode atIndex: choiceChildNodeIndex + 1 useGuards: useGuards storeResultInto: resultVar. |
|
73 ] ifFalse:[ |
|
74 compiler codeError: 'no choice suitable'. |
|
75 ]. |
|
76 ]. |
|
77 |
|
78 |
|
79 ! |
|
80 |
|
81 generateSequenceChildOf: sequenceNode atIndex: sequenceNodeChildIndex useMememntoVar: mementoVar storeResultInto: elementVars |
|
82 | child childValueVar | |
|
83 |
|
84 child := sequenceNode children at: sequenceNodeChildIndex. |
|
85 childValueVar := elementVars at: sequenceNodeChildIndex. |
|
86 compiler codeAssignParsedValueOf: [ self visit:child ] |
|
87 to: childValueVar. |
|
88 child acceptsEpsilon ifFalse: [ |
|
89 compiler codeIfErrorThen: [ |
|
90 "Handle error in the first element in a special way, |
|
91 because one does not need to do backtracking if the first element fails." |
|
92 (sequenceNodeChildIndex == 1) ifTrue: [ |
|
93 compiler codeReturn: 'failure' |
|
94 ] ifFalse: [ |
|
95 compiler smartRestore: sequenceNode from: mementoVar. |
|
96 compiler codeReturn: 'failure.'. |
|
97 ] |
|
98 ] else:[ |
|
99 sequenceNode returnParsedObjectsAsCollection ifTrue:[ |
|
100 compiler add: self retvalVar , ' at: ', sequenceNodeChildIndex asString, ' put: ', childValueVar, '.'. |
|
101 ]. |
|
102 (sequenceNodeChildIndex < sequenceNode children size) ifTrue:[ |
|
103 self generateSequenceChildOf: sequenceNode atIndex: sequenceNodeChildIndex + 1 useMememntoVar: mementoVar storeResultInto: elementVars. |
|
104 ]. |
|
105 ] |
|
106 |
|
107 ] ifTrue:[ |
|
108 sequenceNode returnParsedObjectsAsCollection ifTrue:[ |
|
109 compiler add: self retvalVar , ' at: ', sequenceNodeChildIndex asString, ' put: ', childValueVar, '.'. |
|
110 ]. |
|
111 (sequenceNodeChildIndex < sequenceNode children size) ifTrue:[ |
|
112 self generateSequenceChildOf: sequenceNode atIndex: sequenceNodeChildIndex + 1 useMememntoVar: mementoVar storeResultInto: elementVars. |
|
113 |
|
114 ]. |
|
115 ] |
35 ! ! |
116 ! ! |
36 |
117 |
37 !PPCCodeGenerator methodsFor:'guards'! |
118 !PPCCodeGenerator methodsFor:'guards'! |
38 |
119 |
39 addGuard: node ifTrue: trueBlock ifFalse: falseBlock |
120 addGuard: node ifTrue: trueBlock ifFalse: falseBlock |
399 |
480 |
400 ^ self visit: child. |
481 ^ self visit: child. |
401 ! |
482 ! |
402 |
483 |
403 visitChoiceNode: node |
484 visitChoiceNode: node |
404 | whitespaceConsumed allowGuard elementVar coding | |
485 | whitespaceConsumed useGuards resultVar | |
405 |
486 |
406 |
487 resultVar := compiler allocateTemporaryVariableNamed: 'element'. |
407 elementVar := compiler allocateTemporaryVariableNamed: 'element'. |
|
408 whitespaceConsumed := self addGuardTrimming: node. |
488 whitespaceConsumed := self addGuardTrimming: node. |
409 allowGuard := whitespaceConsumed. |
489 useGuards := whitespaceConsumed. |
410 |
490 self generateChoiceChildOf: node atIndex: 1 useGuards: useGuards storeResultInto: resultVar |
411 allowGuard ifTrue:[ |
491 |
412 coding := |
|
413 [ :children :index | |
|
414 self addGuard: (children at: index) ifTrue: [ |
|
415 compiler add: 'self clearError.'. |
|
416 compiler |
|
417 codeAssignParsedValueOf:[ self visit:(children at:index) ] |
|
418 to:elementVar. |
|
419 compiler add: 'error ifFalse: [ '. |
|
420 compiler codeReturn: elementVar. |
|
421 compiler add: ' ].'. |
|
422 ] ifFalse:[ |
|
423 compiler add: 'error := true.'. |
|
424 ]. |
|
425 compiler add: 'error ifTrue:[ '. |
|
426 index < children size ifTrue:[ |
|
427 coding value: children value: index + 1. |
|
428 ] ifFalse:[ |
|
429 compiler codeError: 'no choice suitable'. |
|
430 ]. |
|
431 compiler add: '] '. |
|
432 ] |
|
433 ] ifFalse:[ |
|
434 coding := |
|
435 [ :children :index | |
|
436 index <= children size ifTrue:[ |
|
437 compiler add: 'self clearError.'. |
|
438 compiler |
|
439 codeAssignParsedValueOf:[ self visit:(children at:index) ] |
|
440 to:elementVar. |
|
441 compiler add: 'error ifFalse: [ '. |
|
442 compiler codeReturn: elementVar. |
|
443 compiler add: ' ].'. |
|
444 coding value: children value: index + 1. |
|
445 ] ifFalse:[ |
|
446 compiler codeError: 'no choice suitable'. |
|
447 ]. |
|
448 ] |
|
449 ]. |
|
450 |
|
451 coding value: node children value: 1. |
|
452 |
492 |
453 "Modified: / 29-05-2015 / 07:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
493 "Modified: / 29-05-2015 / 07:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
454 ! |
494 ! |
455 |
495 |
456 visitEndOfFileNode: node |
496 visitEndOfFileNode: node |
460 visitEndOfInputNode: node |
500 visitEndOfInputNode: node |
461 |
501 |
462 compiler |
502 compiler |
463 codeAssignParsedValueOf:[ self visit:node child ] |
503 codeAssignParsedValueOf:[ self visit:node child ] |
464 to:self retvalVar. |
504 to:self retvalVar. |
465 compiler add: 'context atEnd ifTrue: ['. |
505 compiler codeIf: 'context atEnd' |
466 compiler codeReturn. |
506 then: [ compiler codeReturn ] |
467 compiler add: '] ifFalse: ['. |
507 else: [ compiler codeError: 'End of input expected' ]. |
468 compiler codeError: 'End of input expected'. |
508 |
469 compiler add: '].'. |
|
470 |
|
471 "Modified: / 26-05-2015 / 19:03:09 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
509 "Modified: / 26-05-2015 / 19:03:09 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
472 ! |
510 ! |
473 |
511 |
474 visitForwardNode: node |
512 visitForwardNode: node |
475 |
513 |
760 ]. |
798 ]. |
761 ! |
799 ! |
762 |
800 |
763 visitSequenceNode: node |
801 visitSequenceNode: node |
764 |
802 |
765 | elementVars mementoVar canBacktrack coding | |
803 | elementVars mementoVar canBacktrack | |
766 |
804 |
767 elementVars := node preferredChildrenVariableNames. |
805 elementVars := node preferredChildrenVariableNames. |
768 elementVars do:[:e | |
806 elementVars do:[:e | |
769 compiler allocateTemporaryVariableNamed: e. |
807 compiler allocateTemporaryVariableNamed: e. |
770 ]. |
808 ]. |
771 |
|
772 |
809 |
773 canBacktrack := (node children allButFirst allSatisfy: [:e | e acceptsEpsilon ]) not. |
810 canBacktrack := (node children allButFirst allSatisfy: [:e | e acceptsEpsilon ]) not. |
774 |
811 |
775 " self addGuardTrimming: node. |
812 " self addGuardTrimming: node. |
776 self addGuard: node ifTrue: nil ifFalse: [ compiler addOnLine: ' ^ self error' ]. |
813 self addGuard: node ifTrue: nil ifFalse: [ compiler addOnLine: ' ^ self error' ]. |
781 ]. |
818 ]. |
782 |
819 |
783 node returnParsedObjectsAsCollection ifTrue:[ |
820 node returnParsedObjectsAsCollection ifTrue:[ |
784 compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar. |
821 compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar. |
785 ]. |
822 ]. |
786 |
823 self generateSequenceChildOf: node atIndex: 1 useMememntoVar: mementoVar storeResultInto: elementVars. |
787 coding := [ :index | |
|
788 | child childValueVar | |
|
789 |
|
790 child := node children at: index. |
|
791 childValueVar := elementVars at: index. |
|
792 compiler codeAssignParsedValueOf: [ self visit:child ] |
|
793 to: childValueVar. |
|
794 child acceptsEpsilon ifFalse: [ |
|
795 compiler codeIfErrorThen: [ |
|
796 "Handle error in the first element specially" |
|
797 "TODO: JK, please explain here why!!!!!!" |
|
798 index == 1 ifTrue:[ |
|
799 compiler add: 'error ifTrue: [ ^ failure ].'. |
|
800 ] ifFalse:[ |
|
801 compiler smartRestore: node from: mementoVar. |
|
802 compiler codeReturn: 'failure.'. |
|
803 ] |
|
804 ] else:[ |
|
805 node returnParsedObjectsAsCollection ifTrue:[ |
|
806 compiler add: self retvalVar , ' at: ', index asString, ' put: ', childValueVar, '.'. |
|
807 ]. |
|
808 (index < node children size) ifTrue:[ |
|
809 coding value: index + 1. |
|
810 ]. |
|
811 ] |
|
812 |
|
813 ] ifTrue:[ |
|
814 node returnParsedObjectsAsCollection ifTrue:[ |
|
815 compiler add: self retvalVar , ' at: ', index asString, ' put: ', childValueVar, '.'. |
|
816 ]. |
|
817 (index < node children size) ifTrue:[ |
|
818 coding value: index + 1. |
|
819 ]. |
|
820 ] |
|
821 ]. |
|
822 |
|
823 coding value:1. |
|
824 |
|
825 compiler codeReturn |
824 compiler codeReturn |
826 |
825 |
827 "Modified (comment): / 16-06-2015 / 06:38:02 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
826 "Modified (comment): / 16-06-2015 / 06:38:02 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
828 ! |
827 ! |
829 |
828 |