compiler/TLLVMCodeGenerator.st
changeset 15 10a95d798b36
parent 12 d716a8181fc1
child 16 17a2d1d9f205
--- a/compiler/TLLVMCodeGenerator.st	Tue Sep 22 17:43:38 2015 +0100
+++ b/compiler/TLLVMCodeGenerator.st	Wed Sep 23 22:21:44 2015 +0100
@@ -9,6 +9,7 @@
 	category:'Languages-Tea-Compiler-Internals'
 !
 
+
 !TLLVMCodeGenerator class methodsFor:'initialization'!
 
 initialize
@@ -79,16 +80,25 @@
 !TLLVMCodeGenerator methodsFor:'visiting'!
 
 visitArgument: anRBVariableNode
-    | binding |
+    | binding value |
 
     binding := anRBVariableNode binding.
-    binding isArgumentBinding ifTrue:[ 
-        (function parameterAt: binding index) name: anRBVariableNode name.
+    binding isArgumentBinding ifTrue:[
+        value :=  function parameterAt: binding index.
+        value name: binding name.
     ] ifFalse:[ 
-        self notYetImplemented.
+        | block allocas |
+
+        allocas := anRBVariableNode scope llvmAllocas.
+        block := asm block.
+        asm block: allocas.
+        value := asm alloca: (binding type asLLVMTypeInModule: context module)  as: binding name.
+        asm block: block.
     ].
+    binding llvmValue: value.
 
     "Created: / 02-09-2015 / 08:43:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-09-2015 / 21:47:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !TLLVMCodeGenerator methodsFor:'visitor-double dispatching'!
@@ -100,9 +110,15 @@
 !
 
 acceptAssignmentNode: anAssignmentNode 
-    self notYetImplemented
+    | value binding |
+
+    value := self visitNode: anAssignmentNode value.
+    binding := anAssignmentNode variable binding.
+    asm store: value _: binding llvmValue.
+    ^ value
 
     "Created: / 31-08-2015 / 10:14:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-09-2015 / 21:52:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 acceptBlockNode: aBlockNode 
@@ -151,25 +167,27 @@
     "Modified: / 16-09-2015 / 05:28:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-acceptInlineAssemblyNode: aTInlineAssemblyNode
-    | emitMethodNode emitMethod|
+acceptIfTrueNode: node 
+    | condition thenBody thenBlock thenResult joinBlock result |
+
+    condition := self visitNode: node receiver.  
+    thenBody  := node arguments first body.
+    thenBlock := function addBasicBlock.
+
+    joinBlock := function addBasicBlock.
 
-    emitMethodNode := RBMethodNode new.
-    emitMethodNode arguments: (aTInlineAssemblyNode arguments collect:[ :e|e copy]) , { RBVariableNode named: 'zelf' } , (aTInlineAssemblyNode topNode arguments collect:[ :e|e copy]).
-    emitMethodNode body: aTInlineAssemblyNode body copy.
-    emitMethodNode variableNodesDo:[ :variableNode |
-        variableNode name = 'self' ifTrue:[ 
-            variableNode name: 'zelf'.
-        ].
+    asm if: condition then: thenBlock else: joinBlock.
+    "/ Code true-branch
+    asm block: thenBlock.
+    thenResult := self visitNode: thenBody.
+    thenResult isReturnInst ifFalse:[  
+        joinBlock notNil ifTrue:[ joinBlock function addBasicBlock ].
+        asm br: joinBlock.
     ].
-    emitMethodNode selector:(String streamContents: [ :s | emitMethodNode arguments size timesRepeat:[s nextPutAll:'_:'] ]).
-    emitMethod := Compiler compile: emitMethodNode formattedCode forClass: UndefinedObject install: false.
-    emitMethod
-        valueWithReceiver: nil
-        arguments: { asm } , ((1 to: function numArgs) collect: [ :i | function parameterAt: i ])
 
-    "Created: / 02-09-2015 / 06:53:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 02-09-2015 / 10:30:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    asm block: joinBlock.
+
+    "Created: / 23-09-2015 / 21:57:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 acceptLiteralNode: aLiteralNode
@@ -193,13 +211,20 @@
 !
 
 acceptMethodNode: aMethodNode 
+    | allocas entry |
+
     function := aMethodNode binding asLLVMValueInModule: context module.
-    asm := function builder.
-    super acceptMethodNode: aMethodNode
+    allocas := function addBasicBlockNamed: 'allocas'.
+    entry := function addBasicBlockNamed: 'entry'.
+    aMethodNode scope llvmAllocas: allocas.
+    asm := entry builder.
+    super acceptMethodNode: aMethodNode.
+    "/ Finally, link allocas to entry.
+    asm block: allocas.
+    asm br: entry.
 
     "Created: / 31-08-2015 / 09:42:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 15-09-2015 / 07:17:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified (format): / 15-09-2015 / 08:17:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-09-2015 / 22:32:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 acceptOptimizedNode: anOptimizedNode 
@@ -214,6 +239,32 @@
     "Created: / 31-08-2015 / 10:13:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+acceptPrimitiveNode: aPragmaNode
+    | primitiveBlock methodIsForMeta emitMethodNode emitMethod |
+
+    primitiveBlock := aPragmaNode arguments first.
+    methodIsForMeta := aPragmaNode parent binding mclass isMetaclass.
+    emitMethodNode := RBMethodNode new.
+    emitMethodNode arguments: 
+                        (primitiveBlock arguments collect:[ :e|e copy]) , 
+                        (methodIsForMeta ifFalse:[{ RBVariableNode named: 'zelf' }] ifTrue:[#()]) , 
+                        (primitiveBlock topNode arguments collect:[ :e|e copy]).
+    emitMethodNode body: primitiveBlock body copy.
+    emitMethodNode variableNodesDo:[ :variableNode |
+        variableNode name = 'self' ifTrue:[ 
+            variableNode name: 'zelf'.
+        ].
+    ].
+    emitMethodNode selector:(String streamContents: [ :s | emitMethodNode arguments size timesRepeat:[s nextPutAll:'_:'] ]).
+    emitMethod := Compiler compile: emitMethodNode formattedCode forClass: UndefinedObject install: false.
+    emitMethod
+        valueWithReceiver: nil
+        arguments: { asm } , ((1 to: function numArgs) collect: [ :i | function parameterAt: i ])
+
+    "Created: / 22-09-2015 / 18:03:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-09-2015 / 06:27:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 acceptReturnNode: aReturnNode 
     | value |
 
@@ -237,9 +288,49 @@
 !
 
 acceptVariableNode: aVariableNode
-    self notYetImplemented
+    | binding |
+
+    binding := aVariableNode binding.
+    ^ binding isArgumentBinding ifTrue:[
+        binding llvmValue.
+    ] ifFalse:[ 
+        asm load: binding llvmValue.
+    ].
 
     "Created: / 31-08-2015 / 10:13:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-09-2015 / 22:30:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+acceptWhileTrueNode: node 
+    | loopConditionBlock loopConditionBody loopConditionResult loopBodyBody loopBodyBlock loopBodyResult joinBlock |
+
+    loopConditionBody := node receiver body.
+    loopConditionBlock := function addBasicBlock.
+
+    loopBodyBody  := node arguments first body.
+    loopBodyBlock := function addBasicBlock.
+
+    joinBlock := function addBasicBlock.
+
+    asm br: loopConditionBlock.
+    asm block: loopConditionBlock.
+    loopConditionResult := self visitNode: loopConditionBody.
+    asm if: loopConditionResult then: loopBodyBlock else: joinBlock.
+    asm block: loopBodyBlock.
+    loopBodyResult := self visitNode: loopBodyBody.
+    loopBodyResult isReturnInst ifFalse:[
+        asm br: loopConditionBlock
+    ].
+    asm block: joinBlock
+
+    "Created: / 23-09-2015 / 22:02:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TLLVMCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
 ! !