Action inlining [1/x]: Initial support for inlining actions parsers (i.e., ==>)
authorJan Vrany <jan.vrany@fit.cvut.cz>
Tue, 02 Jun 2015 00:16:55 +0100
changeset 479 6316a98b7150
parent 478 711c8bc1ec04
child 480 5b0254cca4db
Action inlining [1/x]: Initial support for inlining actions parsers (i.e., ==>) The code of the action is now inlined into parsing method rather then delegated to stored block. Mapping parser (i.e., map:[...]) are not supported and not detected, so using them cause crash. This will be fixed later.
compiler/PPCCodeBlock.st
compiler/PPCCodeGenerator.st
compiler/PPCCompiler.st
compiler/PPCMethod.st
--- a/compiler/PPCCodeBlock.st	Mon Jun 01 23:15:52 2015 +0100
+++ b/compiler/PPCCodeBlock.st	Tue Jun 02 00:16:55 2015 +0100
@@ -37,14 +37,31 @@
 
 !PPCCodeBlock methodsFor:'code generation'!
 
-code: aStringOrBlock
-    aStringOrBlock isString ifTrue:[ 
-        buffer nextPutAll: aStringOrBlock
-    ] ifFalse:[ 
-        aStringOrBlock value
+code: aStringOrBlockOrRBParseNode
+    aStringOrBlockOrRBParseNode isString ifTrue:[ 
+        buffer nextPutAll: aStringOrBlockOrRBParseNode
+    ] ifFalse:[
+        (aStringOrBlockOrRBParseNode isKindOf: RBProgramNode) ifTrue:[ 
+            aStringOrBlockOrRBParseNode isSequence ifTrue:[
+                aStringOrBlockOrRBParseNode temporaries do:[:e |  
+                    self allocateTemporaryVariableNamed: e name.      
+                ].
+                aStringOrBlockOrRBParseNode statements do:[:e|
+                    buffer nextPutAll: e formattedCode; nextPut: $..  
+                    self nl; codeIndent.
+                ].
+
+            ] ifFalse:[  
+                buffer nextPutAll: aStringOrBlockOrRBParseNode formattedCode.  
+            ].
+
+        ] ifFalse:[  
+            aStringOrBlockOrRBParseNode value
+        ].
     ].
 
     "Created: / 01-06-2015 / 21:07:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-06-2015 / 00:06:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 codeIndent
--- a/compiler/PPCCodeGenerator.st	Mon Jun 01 23:15:52 2015 +0100
+++ b/compiler/PPCCodeGenerator.st	Tue Jun 02 00:16:55 2015 +0100
@@ -204,19 +204,41 @@
 !PPCCodeGenerator methodsFor:'visiting'!
 
 visitActionNode: node
-    | blockId |
+    | blockNode blockBody blockNodesVar |
 
-    blockId := 'block_', (compiler idFor: node).
-    compiler addConstant: node block as: blockId.
-        
+    blockNode := node block ast copy.
+    self assert: blockNode arguments size == 1.
+    blockNodesVar := blockNode arguments first .
+    blockBody := blockNode body.
+    "Replace all references to blockNodeVar to retvalVar..."
+    blockBody variableNodesDo:[:variableNode| 
+        variableNode name = blockNodesVar name ifTrue:[ 
+            variableNode token value: self retvalVar.
+        ].
+    ].
+    "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.
+    ].
+
     compiler codeStoreValueOf: [ self visit: node child ] intoVariable: self retvalVar.
     compiler codeIf: 'error' then: [ 
         compiler codeReturn: 'failure'. 
-    ] else: [ 
-        compiler codeReturn: blockId, ' value: ', self retvalVar. 
+    ] else: [
+        compiler code: blockBody.    
     ]
 
-    "Modified (format): / 01-06-2015 / 23:03:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-06-2015 / 23:58:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 visitAndNode: node
--- a/compiler/PPCCompiler.st	Mon Jun 01 23:15:52 2015 +0100
+++ b/compiler/PPCCompiler.st	Tue Jun 02 00:16:55 2015 +0100
@@ -173,6 +173,12 @@
 
 !PPCCompiler methodsFor:'code generation - coding'!
 
+code:aStringOrBlockOrRBParseNode
+    currentMethod code: aStringOrBlockOrRBParseNode
+
+    "Created: / 01-06-2015 / 23:49:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 codeAssign: code to: variable
     self assert: variable isNil not.
     
--- a/compiler/PPCMethod.st	Mon Jun 01 23:15:52 2015 +0100
+++ b/compiler/PPCMethod.st	Tue Jun 02 00:16:55 2015 +0100
@@ -102,10 +102,11 @@
 
 !PPCMethod methodsFor:'code generation'!
 
-code: aStringOrBlock
-    buffer code: aStringOrBlock.
+code: aStringOrBlockOrRBParseNode
+    buffer code: aStringOrBlockOrRBParseNode.
 
     "Created: / 01-06-2015 / 22:31:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 01-06-2015 / 23:50:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 codeBlock: contents