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.
--- 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