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