compiler/PPCCodeGenerator.st
changeset 502 1e45d3c96ec5
parent 464 f6d77fee9811
child 503 ff58cd9f1f3c
child 515 b5316ef15274
--- a/compiler/PPCCodeGenerator.st	Thu May 21 14:12:22 2015 +0100
+++ b/compiler/PPCCodeGenerator.st	Fri Jul 24 15:06:54 2015 +0100
@@ -33,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
@@ -107,12 +189,33 @@
     ^ compiler checkCache: (compiler idFor: node)
 ! !
 
+!PPCCodeGenerator methodsFor:'private'!
+
+withAllVariableNodesOf: anRBProgramNode do: aBlock
+    "Enumerate all chilren of `anRBProgramNode` (including itself)
+     and evaluate `aBlock` for each variable node.
+     This is a replacement for Smalltalk/X's RBProgramNode>>variableNodesDo:
+     which is not present in Pharo"
+
+    anRBProgramNode isVariable ifTrue:[ 
+        aBlock value: anRBProgramNode.
+        ^ self.
+    ].
+    anRBProgramNode children do:[:each | 
+        self withAllVariableNodesOf: each do: aBlock
+    ].
+
+    "Created: / 18-06-2015 / 22:02:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !PPCCodeGenerator methodsFor:'support'!
 
 compileTokenWhitespace: node
     compiler add: 'context atWs ifFalse: ['.
     compiler indent.
-        compiler codeStoreValueOf: [ self visit: node whitespace ] intoVariable: #whatever.
+        compiler 
+              codeAssignParsedValueOf:[ self visit:node whitespace ]
+              to:#whatever.
         compiler add: 'context setWs.'.
     compiler dedent.
     compiler add: '].'.
@@ -155,23 +258,25 @@
 !
 
 retvalVar
-    ^ compiler currentReturnVariable 
+    ^ compiler currentReturnVariable
+
+    "Modified: / 15-06-2015 / 18:20:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 startMethodForNode:node
     node isMarkedForInline ifTrue:[ 
-		compiler startInline: (compiler idFor: node).
-		compiler addComment: 'BEGIN inlined code of ' , node printString.
-		compiler indent.
+        compiler startInline: (compiler idFor: node).
+        compiler addComment: 'BEGIN inlined code of ' , node printString.
+        compiler indent.
     ] ifFalse:[ 
-		compiler startMethod: (compiler idFor: node).
-		compiler addComment: 'GENERATED by ' , node printString.
-		compiler allocateReturnVariable.
+        compiler startMethod: (compiler idFor: node).
+        compiler addComment: 'GENERATED by ' , node printString.
+        compiler allocateReturnVariable.
     ].
 
     "Created: / 23-04-2015 / 15:51:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 23-04-2015 / 19:13:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified (comment): / 23-04-2015 / 21:31:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 15-06-2015 / 18:03:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 stopMethodForNode:aPPCNode
@@ -204,19 +309,102 @@
 !PPCCodeGenerator methodsFor:'visiting'!
 
 visitActionNode: node
-    | blockId |
+    | blockNode blockBody blockNodesVar blockNeedsCollection blockMatches childValueVars |
+
+    blockNode := node block sourceNode copy.
+    self assert: blockNode arguments size == 1.
+    blockNodesVar := blockNode arguments first .
+    blockBody := blockNode body.
+
+    "Now, analyze block body, search for all references to
+     block arg <barg> and check if in all cases it's used 
+     in one of the following patterns:
+
+        * <barg> first , <barg> second, ... , <barg> sixth
+        * <barg> at: <integer constant>
+
+     If so, then the block code can be inlined and the intermediate
+     result collection need not to be created. Keep this information
+     in temporary `blockNeedsCollection`. 
+     During the analysis, remember all nodes that matches the pattern
+     in a dictionary `blockMatches` mapping the node to actual temporary
+     variable where the node is used. This will be later used for block's node
+     rewriting"
+    blockNeedsCollection := true.
+    node child isSequenceNode ifTrue:[
+        blockNeedsCollection := false.
+        blockMatches := IdentityDictionary new."Must use IDENTITY dict as nodes have overwritten their #=!!!!!!"
+        childValueVars := node child preferredChildrenVariableNames.
+        self withAllVariableNodesOf: blockBody do:[:variableNode| 
+            variableNode name = blockNodesVar name ifTrue:[ 
+                "Check if variable node matches..."
+                variableNode parent isMessage ifTrue:[ 
+                    | parent |
+
+                    parent := variableNode parent.
+                    "Check for <barg> at: <number>"
+                    ((parent selector == #at:) and:[ parent arguments first isLiteralNumber ]) ifTrue:[ 
+                        blockMatches at: parent put: (childValueVars at: parent arguments first value).
+                    ] ifFalse:[ 
+                        "Check for <barg> first / second / ..."
+                        | i |
 
-    blockId := 'block_', (compiler idFor: node).
-    compiler addConstant: node block as: blockId.
-        
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar.
-    compiler add: 'error ifFalse: ['.
-    compiler codeReturn: blockId, ' value: ', self retvalVar.
-    compiler add: '] ifTrue: ['.
-    compiler codeReturn: 'failure'.
-    compiler add: '].'.
+                        i := #(first second third fourth fifth sixth) indexOf: parent selector.
+                        i ~~ 0 ifTrue:[ 
+                            blockMatches at: parent put: (childValueVars at: i).
+                        ] ifFalse:[ 
+                            blockNeedsCollection := true.
+                        ].
+                    ].
+                ] ifFalse:[ 
+                    blockNeedsCollection := true.
+                ].
+            ].
+        ].
+    ].
 
-    "Modified: / 23-04-2015 / 15:59:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    blockNeedsCollection ifTrue:[
+        "Bad, we have to use the collection.
+         Replace all references to blockNodeVar to retvalVar..."
+        self withAllVariableNodesOf: blockBody do:[:variableNode| 
+            variableNode name = blockNodesVar name ifTrue:[ 
+                variableNode name: self retvalVar.
+            ].
+        ].
+    ] ifFalse:[ 
+        "Good, can avoid intermediate collection.
+         Replace references to collection with corresponding temporary variable"
+        blockMatches keysAndValuesDo:[:matchingNode :childValueVar |
+            matchingNode parent replaceNode: matchingNode withNode: (RBVariableNode named: childValueVar).
+        ].
+        node child returnParsedObjectsAsCollection: false. 
+    ].
+
+    "Block return value is return value of last statement.
+     So if the method is not inline, make last statement a return.
+        if the method is inline, make it assignment to retvalVar."
+    blockBody statements notEmpty ifTrue:["Care for empty blocks - [:t | ] !!"
+        compiler currentMethod isInline ifTrue:[ 
+            |  assignment |
+
+            assignment := RBAssignmentNode variable: (RBVariableNode named: self retvalVar) value:  blockBody statements last.
+            blockBody replaceNode: blockBody statements last withNode: assignment.
+        ] ifFalse:[  
+            | return |
+
+            return := RBReturnNode value: blockBody statements last.
+            blockBody replaceNode: blockBody statements last withNode: return.
+        ].
+    ].
+
+    compiler codeAssignParsedValueOf:[ self visit:node child ] to:self retvalVar.
+    compiler codeIfErrorThen: [ 
+        compiler codeReturn: 'failure'. 
+    ] else: [
+        compiler code: blockBody.    
+    ]
+
+    "Modified: / 19-06-2015 / 07:05:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 visitAndNode: node
@@ -225,7 +413,9 @@
     mementoVar := compiler allocateTemporaryVariableNamed: 'memento'.
     compiler smartRemember: node child to: mementoVar.
 
-    compiler codeStoreValueOf: [ self visit: node child  ] intoVariable: self retvalVar.
+    compiler 
+          codeAssignParsedValueOf:[ self visit:node child ]
+          to:self retvalVar.
     compiler smartRestore: node child from: mementoVar.
 
     compiler codeReturn.
@@ -292,33 +482,15 @@
 !
 
 visitChoiceNode: node
-    |  whitespaceConsumed elementVar |
-    "The code is not ready for inlining"
-    self assert: node isMarkedForInline not.
+    |  whitespaceConsumed useGuards resultVar  |
+
+    resultVar := compiler allocateTemporaryVariableNamed: 'element'.
+    whitespaceConsumed := self addGuardTrimming: node.
+    useGuards := whitespaceConsumed.
+    self generateChoiceChildOf: node atIndex: 1 useGuards: useGuards storeResultInto: resultVar
     
 
-    elementVar := compiler allocateTemporaryVariableNamed: 'element'.
-    whitespaceConsumed :=	 self addGuardTrimming: node.
-
-    1 to: node children size do: [ :idx  | |child allowGuard |
-        child := node children at: idx.
-        allowGuard := whitespaceConsumed.
-
-        allowGuard ifTrue: [ 
-            self addGuard: child ifTrue: [ 
-                compiler add: 'self clearError.'.
-                compiler codeStoreValueOf:  [self visit: child] intoVariable: elementVar.
-                compiler add: 'error ifFalse: [ ^ ', elementVar, ' ].'.
-            ] ifFalse: nil.
-        ] ifFalse: [ 
-                compiler add: 'self clearError.'.
-                compiler codeStoreValueOf:  [self visit: child] intoVariable: elementVar.
-                compiler add: 'error ifFalse: [ ^ ', elementVar, ' ].'.
-        ]
-    ].
-    compiler codeError: 'no choice suitable'.
-
-    "Modified: / 23-04-2015 / 21:40:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-05-2015 / 07:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 visitEndOfFileNode: node
@@ -327,17 +499,21 @@
 
 visitEndOfInputNode: node
 
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar.
-    compiler add: 'context atEnd ifTrue: ['.
-    compiler codeReturn.	
-    compiler add: '] ifFalse: ['.
-    compiler codeError: 'End of input expected'.
-    compiler add: ']'.
+    compiler 
+          codeAssignParsedValueOf:[ self visit:node child ]
+          to:self retvalVar.
+    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>"
 !
 
 visitForwardNode: node
 
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar.
+    compiler 
+          codeAssignParsedValueOf:[ self visit:node child ]
+          to:self retvalVar.
     compiler codeReturn.
 !
 
@@ -357,6 +533,71 @@
     compiler add: '].'.
 !
 
+visitMappedActionNode: node
+    | child blockNode blockBody |
+
+    child := node child.
+    blockNode := node block sourceNode copy.
+    blockBody := blockNode body.
+
+    "Block return value is return value of last statement.
+     So if the method is not inline, make last statement a return.
+        if the method is inline, make it assignment to retvalVar."
+    compiler currentMethod isInline ifTrue:[ 
+        |  assignment |
+
+        assignment := RBAssignmentNode variable: (RBVariableNode named: self retvalVar) value:  blockBody statements last.
+        blockBody replaceNode: blockBody statements last withNode: assignment.
+    ] ifFalse:[  
+        | return |
+
+        return := RBReturnNode value: blockBody statements last.
+        blockBody replaceNode: blockBody statements last withNode: return.
+    ].
+
+    child isSequenceNode ifTrue:[  
+        child isMarkedForInline ifTrue:[ 
+            child preferredChildrenVariableNames: blockNode argumentNames.
+            child returnParsedObjectsAsCollection: false.
+        ].
+    ] ifFalse:[ 
+        "Child is not a sequence so it 'returns' only one object.
+         Therefore the block takes only one argument and it's value
+         is value of child's retval.
+         In the block, replace all references to block argument to
+         my retvalVar. "
+        | blockArg |
+
+        blockArg := blockNode arguments first.
+        self withAllVariableNodesOf: blockBody do:[:variableNode| 
+            variableNode name = blockArg name ifTrue:[ 
+                variableNode name: self retvalVar.
+            ].
+        ]. 
+    ].
+
+    compiler codeAssignParsedValueOf: [ self visit: child ] to: self retvalVar.
+    compiler codeIf: 'error' then: [ 
+        compiler codeReturn: 'failure'. 
+    ] else: [
+        "If the child is sequence and not inlined, extract
+         nodes from returned collection into used-to-be block variables"
+        (child isSequenceNode and:[ child returnParsedObjectsAsCollection ]) ifTrue:[
+            blockNode arguments withIndexDo:[ :arg :idx |
+                node child isMarkedForInline ifFalse:[ 
+                    compiler allocateTemporaryVariableNamed: arg name.
+                    compiler codeAssign: (self retvalVar , ' at: ', idx printString) to: arg name.
+                ].
+                compiler addOnLine: '.'; nl.
+            ].
+        ].
+        compiler code: blockBody.    
+    ]
+
+    "Created: / 02-06-2015 / 17:28:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-06-2015 / 07:06:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 visitMessagePredicateNode: node
     compiler add: '(context peek ', node message, ') ifFalse: ['.
     compiler codeError: 'predicate not found'.
@@ -443,7 +684,7 @@
     mementoVar := compiler allocateTemporaryVariableNamed: 'memento'.
     compiler smartRemember: node child to: mementoVar.
     
-    compiler codeStoreValueOf: [ self visit: node child  ] intoVariable: #whatever.
+    compiler codeAssignParsedValueOf:[ self visit:node child ] to:#whatever.
     compiler smartRestore: node child from: mementoVar.
 
     compiler add: '^ error ifFalse: [ self error ] ifTrue: [ self clearError. nil ]'.
@@ -452,7 +693,9 @@
 !
 
 visitOptionalNode: node
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar.
+    compiler 
+          codeAssignParsedValueOf:[ self visit:node child ]
+          to:self retvalVar.
     compiler add: 'error ifTrue: [ '.
     compiler indent.
     compiler add: 'self clearError. '.
@@ -475,32 +718,37 @@
                 
     elementVar := compiler allocateTemporaryVariableNamed:  'element'.
      
-"	self tokenGuards ifTrue: [ 
+"       self tokenGuards ifTrue: [ 
         compiler codeTokenGuard: node ifFalse: [ compiler codeError: 'at least one occurence expected' ].   
     ].
 "        
     compiler codeAssign: 'OrderedCollection new.' to: self retvalVar.
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar.
+    compiler codeAssignParsedValueOf:[ self visit:node child ] to:elementVar.
 
     compiler add: 'error ifTrue: ['.
     compiler codeError: 'at least one occurence expected'.
     compiler add: '] ifFalse: ['.
     compiler indent.
-        compiler add: self retvalVar , ' add: ',elementVar , '.'.
-            
-        compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar.
+        (self retvalVar ~~ #whatever) ifTrue:[
+            compiler add: self retvalVar , ' add: ',elementVar , '.'.
+        ].            
+        compiler codeAssignParsedValueOf:[ self visit:node child ] to:elementVar.
         compiler add: '[ error ] whileFalse: ['.
         compiler indent.
-        compiler add: self retvalVar , ' add: ',elementVar , '.'.
-        compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar.
+        (self retvalVar ~~ #whatever) ifTrue:[
+            compiler add: self retvalVar , ' add: ',elementVar , '.'.
+        ].
+        compiler codeAssignParsedValueOf:[ self visit:node child ] to:elementVar.
         compiler dedent.
         compiler add: '].'.
         compiler add: 'self clearError.'.
-        compiler codeReturn: self retvalVar , ' asArray.'.         
+        (self retvalVar ~~ #whatever) ifTrue:[ 
+            compiler codeReturn: self retvalVar , ' asArray.'.         
+        ].
     compiler dedent.
     compiler add: '].'.
 
-    "Modified (comment): / 23-04-2015 / 21:30:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 26-05-2015 / 19:04:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 visitPredicateNode: node
@@ -530,12 +778,14 @@
         compiler smartRemember: node to: mementoVar.
     ].
 
-    compiler codeStoreValueOf: [ self visit: (node children at: 1) ] intoVariable: #whatever.
+    compiler 
+          codeAssignParsedValueOf:[ self visit:(node children at:1) ]
+          to:#whatever.
     compiler add: 'error ifTrue: [ ^ failure ].'.
 
     2 to: (node children size) do: [ :idx  | |child|
         child := node children at: idx.
-        compiler codeStoreValueOf: [ self visit: child ] intoVariable: #whatever.
+        compiler codeAssignParsedValueOf:[ self visit:child ] to:#whatever.
         
         child acceptsEpsilon ifFalse: [   
             compiler add: 'error ifTrue: [ '.
@@ -550,55 +800,43 @@
 
 visitSequenceNode: node
 
-    | elementVar mementoVar canBacktrack |
+    | elementVars mementoVar canBacktrack  |
 
-    elementVar := compiler allocateTemporaryVariableNamed: 'element'.
+    elementVars := node preferredChildrenVariableNames.
+    elementVars do:[:e | 
+        compiler allocateTemporaryVariableNamed: e.  
+    ].
+
     canBacktrack := (node children allButFirst allSatisfy: [:e | e acceptsEpsilon ]) not.
 
-"	self addGuardTrimming: node.
+"       self addGuardTrimming: node.
     self addGuard: node ifTrue: nil ifFalse: [ compiler addOnLine: ' ^ self error' ].
 "
     canBacktrack ifTrue: [ 
         mementoVar := compiler allocateTemporaryVariableNamed: 'memento'.
         compiler smartRemember: node to: mementoVar.
     ].
-    
-    compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar.
 
-    compiler codeStoreValueOf: [ self visit: (node children at: 1)]  intoVariable: elementVar.
-    compiler add: 'error ifTrue: [ ^ failure ].'.
-    compiler add: self retvalVar , ' at: 1 put: ', elementVar, '.'.
-    
-    2 to: (node children size) do: [ :idx  | |child|
-        child := node children at: idx.
-        compiler codeStoreValueOf: [ self visit: child ]  intoVariable: elementVar.
-      
-        child acceptsEpsilon ifFalse: [   
-            compiler add: 'error ifTrue: [ '.
-            compiler indent.
-            compiler smartRestore: node from: mementoVar.
-            compiler add: '^ failure.'.
-            compiler dedent.
-            compiler add: '].'.
-        ].
-        compiler add: self retvalVar , ' at: ', idx asString, ' put: ',elementVar,'.'.
+    node returnParsedObjectsAsCollection ifTrue:[
+        compiler codeAssign: 'Array new: ', node children size asString, '.' to: self retvalVar.
     ].
+    self generateSequenceChildOf: node atIndex: 1 useMememntoVar: mementoVar storeResultInto: elementVars.
     compiler codeReturn
 
-    "Modified: / 23-04-2015 / 22:03:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 16-06-2015 / 06:38:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 visitStarAnyNode: node
     | retvalVar sizeVar |
 
-    retvalVar := compiler allocateReturnVariable.
+    retvalVar := self retvalVar.
     sizeVar := compiler allocateTemporaryVariableNamed: 'size'.  
     compiler add: sizeVar , ' := context size - context position.'.
     compiler add: retvalVar,' := Array new: ',sizeVar,'.'.
     compiler add: '(1 to: ',sizeVar,') do: [ :e | ',retvalVar,' at: e put: context next ].'.
     compiler codeReturn.
-    
-    "Modified: / 05-05-2015 / 14:13:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+
+    "Modified: / 15-06-2015 / 18:53:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 visitStarCharSetPredicateNode: node
@@ -639,11 +877,11 @@
     self addGuard: node child ifTrue: nil ifFalse: [ compiler codeReturn: '#()' ].
 
     compiler codeAssign: 'OrderedCollection new.' to: self retvalVar.
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar.
+    compiler codeAssignParsedValueOf:[ self visit:node child ] to:elementVar.
     compiler add: '[ error ] whileFalse: ['.
     compiler indent.
     compiler add: self retvalVar, ' add: ', elementVar, '.'.
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar.
+    compiler codeAssignParsedValueOf:[ self visit:node child ] to:elementVar.
     compiler dedent.
     compiler add: '].'.
     compiler codeClearError.
@@ -654,7 +892,7 @@
     | elementVar |
     
     elementVar := compiler allocateTemporaryVariableNamed: 'element'.	
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: elementVar.
+    compiler codeAssignParsedValueOf:[ self visit:node child ] to:elementVar.
     compiler add: 'error ifFalse: [ '.
     compiler codeReturn: elementVar, ' ', node block asString, '.'.
     compiler add: '] ifTrue: ['.
@@ -681,7 +919,7 @@
     compiler profileTokenRead: (compiler idFor: node).
     
     compiler codeAssign: 'context position + 1.' to: startVar.
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever.
+    compiler codeAssignParsedValueOf:[ self visit:node child ] to:#whatever.
     compiler add: 'error ifFalse: [ '.
     compiler indent.	
     compiler codeAssign: 'context position.' to: endVar.
@@ -710,7 +948,7 @@
 !
 
 visitTokenWhitespaceNode: node
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever.
+    compiler codeAssignParsedValueOf:[ self visit:node child ] to:#whatever.
     compiler codeReturn.
 !
 
@@ -723,7 +961,9 @@
     compiler smartRemember: node child to: mementoVar.
     compiler add: 'context skipSeparators.'.
 
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar.
+    compiler 
+          codeAssignParsedValueOf:[ self visit:node child ]
+          to:self retvalVar.
     
     compiler add: 'error ifTrue: [ '.
     compiler indent.
@@ -763,7 +1003,7 @@
     ].
 
     compiler codeAssign: 'context position + 1.' to: startVar.
-    compiler codeStoreValueOf: [ self visit: node child ] intoVariable: #whatever.
+    compiler codeAssignParsedValueOf:[ self visit:node child ] to:#whatever.
 
     (arguments guards and: [(guard := PPCGuard on: node) makesSense]) ifTrue: [ 
         compiler dedent.
@@ -802,9 +1042,11 @@
     compiler codeClearError.
     compiler add: '(', self retvalVar, ' := ', id, ' parseOn: context) isPetitFailure'.
     compiler indent.
-    compiler add: ' ifTrue: [self error: retval message at: ', self retvalVar, ' position ].'.
+    compiler add: ' ifTrue: [self error: ', self retvalVar, ' message at: ', self retvalVar, ' position ].'.
     compiler dedent.
     compiler add: 'error := ', self retvalVar, ' isPetitFailure.'.
     compiler codeReturn.
+
+    "Modified: / 15-06-2015 / 17:59:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !