--- a/compiler/PPCCodeGenerator.st Fri Jun 19 08:13:39 2015 +0100
+++ b/compiler/PPCCodeGenerator.st Fri Jul 24 15:37:23 2015 +0100
@@ -9,7 +9,6 @@
category:'PetitCompiler-Visitors'
!
-
!PPCCodeGenerator class methodsFor:'as yet unclassified'!
new
@@ -34,6 +33,88 @@
^ arguments guards
! !
+!PPCCodeGenerator methodsFor:'code generation'!
+
+generateChoiceChildOf: choiceNode atIndex: choiceChildNodeIndex useGuards: useGuards storeResultInto: resultVar
+
+ | children |
+
+ children := choiceNode children.
+ useGuards ifTrue:[
+ self addGuard: (children at: choiceChildNodeIndex) ifTrue: [
+ compiler add: 'self clearError.'.
+ compiler
+ codeAssignParsedValueOf:[ self visit:(children at: choiceChildNodeIndex) ]
+ to: resultVar.
+ compiler add: 'error ifFalse: [ '.
+ compiler codeReturn: resultVar.
+ compiler add: ' ].'.
+ ] ifFalse:[
+ compiler add: 'error := true.'.
+ ].
+ compiler add: 'error ifTrue:[ '.
+ choiceChildNodeIndex < children size ifTrue:[
+ self generateChoiceChildOf: choiceNode atIndex: choiceChildNodeIndex + 1 useGuards: useGuards storeResultInto: resultVar.
+ ] ifFalse:[
+ compiler codeError: 'no choice suitable'.
+ ].
+ compiler addOnLine: '].'.
+
+ ] ifFalse:[
+ choiceChildNodeIndex <= children size ifTrue:[
+ compiler add: 'self clearError.'.
+ compiler
+ codeAssignParsedValueOf:[ self visit:(children at: choiceChildNodeIndex) ]
+ to: resultVar.
+ compiler add: 'error ifFalse: [ '.
+ compiler codeReturn: resultVar.
+ compiler add: ' ].'.
+ self generateChoiceChildOf: choiceNode atIndex: choiceChildNodeIndex + 1 useGuards: useGuards storeResultInto: resultVar.
+ ] ifFalse:[
+ compiler codeError: 'no choice suitable'.
+ ].
+ ].
+
+
+!
+
+generateSequenceChildOf: sequenceNode atIndex: sequenceNodeChildIndex useMememntoVar: mementoVar storeResultInto: elementVars
+ | child childValueVar |
+
+ child := sequenceNode children at: sequenceNodeChildIndex.
+ childValueVar := elementVars at: sequenceNodeChildIndex.
+ compiler codeAssignParsedValueOf: [ self visit:child ]
+ to: childValueVar.
+ child acceptsEpsilon ifFalse: [
+ compiler codeIfErrorThen: [
+ "Handle error in the first element in a special way,
+ because one does not need to do backtracking if the first element fails."
+ (sequenceNodeChildIndex == 1) ifTrue: [
+ compiler codeReturn: 'failure'
+ ] ifFalse: [
+ compiler smartRestore: sequenceNode from: mementoVar.
+ compiler codeReturn: 'failure.'.
+ ]
+ ] else:[
+ sequenceNode returnParsedObjectsAsCollection ifTrue:[
+ compiler add: self retvalVar , ' at: ', sequenceNodeChildIndex asString, ' put: ', childValueVar, '.'.
+ ].
+ (sequenceNodeChildIndex < sequenceNode children size) ifTrue:[
+ self generateSequenceChildOf: sequenceNode atIndex: sequenceNodeChildIndex + 1 useMememntoVar: mementoVar storeResultInto: elementVars.
+ ].
+ ]
+
+ ] ifTrue:[
+ sequenceNode returnParsedObjectsAsCollection ifTrue:[
+ compiler add: self retvalVar , ' at: ', sequenceNodeChildIndex asString, ' put: ', childValueVar, '.'.
+ ].
+ (sequenceNodeChildIndex < sequenceNode children size) ifTrue:[
+ self generateSequenceChildOf: sequenceNode atIndex: sequenceNodeChildIndex + 1 useMememntoVar: mementoVar storeResultInto: elementVars.
+
+ ].
+ ]
+! !
+
!PPCCodeGenerator methodsFor:'guards'!
addGuard: node ifTrue: trueBlock ifFalse: falseBlock
@@ -401,54 +482,13 @@
!
visitChoiceNode: node
- | whitespaceConsumed allowGuard elementVar coding |
-
-
- elementVar := compiler allocateTemporaryVariableNamed: 'element'.
- whitespaceConsumed := self addGuardTrimming: node.
- allowGuard := whitespaceConsumed.
+ | whitespaceConsumed useGuards resultVar |
- allowGuard ifTrue:[
- coding :=
- [ :children :index |
- self addGuard: (children at: index) ifTrue: [
- compiler add: 'self clearError.'.
- compiler
- codeAssignParsedValueOf:[ self visit:(children at:index) ]
- to:elementVar.
- compiler add: 'error ifFalse: [ '.
- compiler codeReturn: elementVar.
- compiler add: ' ].'.
- ] ifFalse:[
- compiler add: 'error := true.'.
- ].
- compiler add: 'error ifTrue:[ '.
- index < children size ifTrue:[
- coding value: children value: index + 1.
- ] ifFalse:[
- compiler codeError: 'no choice suitable'.
- ].
- compiler add: '] '.
- ]
- ] ifFalse:[
- coding :=
- [ :children :index |
- index <= children size ifTrue:[
- compiler add: 'self clearError.'.
- compiler
- codeAssignParsedValueOf:[ self visit:(children at:index) ]
- to:elementVar.
- compiler add: 'error ifFalse: [ '.
- compiler codeReturn: elementVar.
- compiler add: ' ].'.
- coding value: children value: index + 1.
- ] ifFalse:[
- compiler codeError: 'no choice suitable'.
- ].
- ]
- ].
-
- coding value: node children value: 1.
+ resultVar := compiler allocateTemporaryVariableNamed: 'element'.
+ whitespaceConsumed := self addGuardTrimming: node.
+ useGuards := whitespaceConsumed.
+ self generateChoiceChildOf: node atIndex: 1 useGuards: useGuards storeResultInto: resultVar
+
"Modified: / 29-05-2015 / 07:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
@@ -462,12 +502,10 @@
compiler
codeAssignParsedValueOf:[ self visit:node child ]
to:self retvalVar.
- compiler add: 'context atEnd ifTrue: ['.
- compiler codeReturn.
- compiler add: '] ifFalse: ['.
- compiler codeError: 'End of input expected'.
- compiler add: '].'.
-
+ compiler codeIf: 'context atEnd'
+ then: [ compiler codeReturn ]
+ else: [ compiler codeError: 'End of input expected' ].
+
"Modified: / 26-05-2015 / 19:03:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
@@ -762,14 +800,13 @@
visitSequenceNode: node
- | elementVars mementoVar canBacktrack coding |
+ | elementVars mementoVar canBacktrack |
elementVars := node preferredChildrenVariableNames.
elementVars do:[:e |
compiler allocateTemporaryVariableNamed: e.
].
-
canBacktrack := (node children allButFirst allSatisfy: [:e | e acceptsEpsilon ]) not.
" self addGuardTrimming: node.
@@ -783,45 +820,7 @@
node returnParsedObjectsAsCollection ifTrue:[
compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar.
].
-
- coding := [ :index |
- | child childValueVar |
-
- child := node children at: index.
- childValueVar := elementVars at: index.
- compiler codeAssignParsedValueOf: [ self visit:child ]
- to: childValueVar.
- child acceptsEpsilon ifFalse: [
- compiler codeIfErrorThen: [
- "Handle error in the first element specially"
- "TODO: JK, please explain here why!!!!!!"
- index == 1 ifTrue:[
- compiler add: 'error ifTrue: [ ^ failure ].'.
- ] ifFalse:[
- compiler smartRestore: node from: mementoVar.
- compiler codeReturn: 'failure.'.
- ]
- ] else:[
- node returnParsedObjectsAsCollection ifTrue:[
- compiler add: self retvalVar , ' at: ', index asString, ' put: ', childValueVar, '.'.
- ].
- (index < node children size) ifTrue:[
- coding value: index + 1.
- ].
- ]
-
- ] ifTrue:[
- node returnParsedObjectsAsCollection ifTrue:[
- compiler add: self retvalVar , ' at: ', index asString, ' put: ', childValueVar, '.'.
- ].
- (index < node children size) ifTrue:[
- coding value: index + 1.
- ].
- ]
- ].
-
- coding value:1.
-
+ self generateSequenceChildOf: node atIndex: 1 useMememntoVar: mementoVar storeResultInto: elementVars.
compiler codeReturn
"Modified (comment): / 16-06-2015 / 06:38:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
@@ -1051,10 +1050,3 @@
"Modified: / 15-06-2015 / 17:59:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
-!PPCCodeGenerator class methodsFor:'documentation'!
-
-version_HG
-
- ^ '$Changeset: <not expanded> $'
-! !
-