diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 5942aaa2224..10e55030d0c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -37,7 +37,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction codeBuilder.addStartExpression() generateLoadArguments() - expressionWalker(function.bodyExpression) + evaluateCodeBlock(function.bodyExpression, startLabel = null, finishLabel = null, scopeDepth = 0) + if (returnType is LLVMVoidType) { codeBuilder.addVoidReturn() @@ -71,7 +72,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction } } - private fun expressionWalker(expr: PsiElement?, scopeDepth: Int = 0) { + private fun evaluateCodeBlock(expr: PsiElement?, startLabel: LLVMLabel?, finishLabel: LLVMLabel?, scopeDepth: Int) { + codeBuilder.markWithLabel(startLabel) + expressionWalker(expr, scopeDepth = scopeDepth) + codeBuilder.addUnconditionJump(finishLabel ?: return) + } + + private fun expressionWalker(expr: PsiElement?, scopeDepth: Int) { when (expr) { is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1) is KtProperty -> evaluateLeafPsiElement(expr.firstChild as LeafPsiElement, scopeDepth) @@ -205,7 +212,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null val thenExpression = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null - val elseExpression = thenExpression.getNextSiblingIgnoringWhitespaceAndComments() ?: return null + val elseKeyword = thenExpression.getNextSiblingIgnoringWhitespaceAndComments() ?: return null + val elseExpression = elseKeyword.getNextSiblingIgnoringWhitespaceAndComments() ?: return null return executeCondition(condition.firstChild as KtBinaryExpression, thenExpression.firstChild, elseExpression.firstChild, scopeDepth + 1) @@ -215,9 +223,15 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1) val thenLabel = codeBuilder.getNewLabel() val elseLabel = codeBuilder.getNewLabel() + val endLabel = codeBuilder.getNewLabel() codeBuilder.addCondition(conditionResult, thenLabel, elseLabel) + evaluateCodeBlock(thenExpression, thenLabel, endLabel, scopeDepth + 1) + evaluateCodeBlock(elseExpression, elseLabel, endLabel, scopeDepth + 1) + + codeBuilder.markWithLabel(endLabel) + return null } @@ -254,8 +268,9 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction private fun evaluateReturnInstruction(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? { val next = element.getNextSiblingIgnoringWhitespaceAndComments() val retVar = evaluateExpression(next, scopeDepth) as LLVMSingleValue + val retNativeValue = codeBuilder.receiveNativeValue(retVar) - codeBuilder.addReturnOperator(retVar) + codeBuilder.addReturnOperator(retNativeValue) return null } } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt index dcfe82aaba8..eea1407dfa2 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -2,6 +2,7 @@ package org.kotlinnative.translator.llvm import com.intellij.psi.tree.IElementType import org.jetbrains.kotlin.lexer.KtTokens +import org.kotlinnative.translator.llvm.types.LLVMIntType import org.kotlinnative.translator.llvm.types.LLVMType class LLVMBuilder { @@ -23,9 +24,9 @@ class LLVMBuilder { return LLVMVariable("%var$variableCount", type, kotlinName = kotlinName, pointer = pointer) } - fun getNewLabel(): LLVMLabel { + fun getNewLabel(scope: LLVMScope = LLVMLocalScope()): LLVMLabel { labelCount++ - return LLVMLabel("%label$labelCount") + return LLVMLabel("label$labelCount", scope) } fun addLLVMCode(code: String) { @@ -97,6 +98,15 @@ class LLVMBuilder { llvmCode.appendln(code) } + fun markWithLabel(label: LLVMLabel?) { + if (label != null) + llvmCode.appendln("${label.label}:") + } + + fun addNopInstruction() { + llvmCode.appendln(getNewVariable(LLVMIntType()).toString() + " = add i1 0, 0 ; nop instruction") + } + fun storeVariable(target: LLVMVariable, source: LLVMSingleValue) { val code = "store ${source.type} $source, ${target.getType()} $target, align ${source.type?.align!!}" llvmCode.appendln(code) @@ -140,6 +150,10 @@ class LLVMBuilder { llvmCode.appendln("br ${condition.getType()} $condition, label $thenLabel, label $elseLabel") } + fun addUnconditionJump(label: LLVMLabel) { + llvmCode.appendln("br label $label") + } + fun createClass(name: String, fields: List) { val code = "%class.$name = type { ${fields.map { it.type }.joinToString()} }" llvmCode.appendln(code) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMLabel.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMLabel.kt index 1d37ac43af7..69500ca41f6 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMLabel.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMLabel.kt @@ -1,6 +1,6 @@ package org.kotlinnative.translator.llvm -class LLVMLabel(val label: String) : LLVMNode() { +class LLVMLabel(val label: String, val scope: LLVMScope) : LLVMNode() { - override fun toString(): String = label + override fun toString(): String = "$scope$label" } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt new file mode 100644 index 00000000000..0d6e88a3e19 --- /dev/null +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt @@ -0,0 +1,12 @@ +package org.kotlinnative.translator.llvm + +open class LLVMScope + +class LLVMGlobalScope : LLVMScope() { + override fun toString() = "@" +} + +class LLVMLocalScope : LLVMScope() { + override fun toString() = "%" +} +