diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 17508ed651e..432e073c5a5 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -67,8 +67,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction private fun generateLoadArguments() { args?.forEach { val loadVariable = LLVMVariable("%${it.label}", it.type, it.label, false) - codeBuilder.loadArgument(loadVariable) - variableManager.addVariable(it.label, loadVariable, 2) + val allocVar = codeBuilder.loadArgument(loadVariable) + variableManager.addVariable(it.label, allocVar, 2) } } @@ -207,11 +207,37 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth) KtTokens.VAL_KEYWORD -> evaluateValExpression(element, scopeDepth) KtTokens.VAR_KEYWORD -> evaluateValExpression(element, scopeDepth) - KtTokens.IF_KEYWORD -> evaluateIfOperator(element, scopeDepth, false) + KtTokens.IF_KEYWORD -> evaluateIfOperator(element, scopeDepth, containReturn = false) + KtTokens.WHILE_KEYWORD -> evaluateWhileOperator(element, scopeDepth) else -> null } } + private fun evaluateWhileOperator(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? { + var getBrackets = element.getNextSiblingIgnoringWhitespaceAndComments() ?: return null + val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null + getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null + val bodyExpression = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null + + return executeWhileBlock(condition.firstChild as KtBinaryExpression, bodyExpression.firstChild, scopeDepth) + } + + private fun executeWhileBlock(condition: KtBinaryExpression, bodyExpression: PsiElement, scopeDepth: Int): LLVMVariable? { + val conditionLable = codeBuilder.getNewLabel(prefix = "while") + val bodyLable = codeBuilder.getNewLabel(prefix = "while") + val exitLable = codeBuilder.getNewLabel(prefix = "while") + + codeBuilder.addUnconditionJump(conditionLable) + codeBuilder.markWithLabel(conditionLable) + val conditionResult = evaluateBinaryExpression(condition, scopeDepth + 1) + + codeBuilder.addCondition(conditionResult, bodyLable, exitLable) + evaluateCodeBlock(bodyExpression, bodyLable, conditionLable, scopeDepth + 1) + codeBuilder.markWithLabel(exitLable) + + return null + } + private fun evaluateIfOperator(element: LeafPsiElement, scopeDepth: Int, containReturn: Boolean): LLVMVariable? { var getBrackets = element.getNextSiblingIgnoringWhitespaceAndComments() ?: return null val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null @@ -231,9 +257,9 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1) val variable = codeBuilder.getNewVariable(LLVMIntType(), true) codeBuilder.allocVar(variable) - val thenLabel = codeBuilder.getNewLabel() - val elseLabel = codeBuilder.getNewLabel() - val endLabel = codeBuilder.getNewLabel() + val thenLabel = codeBuilder.getNewLabel(prefix = "if") + val elseLabel = codeBuilder.getNewLabel(prefix = "if") + val endLabel = codeBuilder.getNewLabel(prefix = "if") codeBuilder.addCondition(conditionResult, thenLabel, elseLabel) codeBuilder.markWithLabel(thenLabel) @@ -249,10 +275,10 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction } private fun executeIfBlock(condition: KtBinaryExpression, thenExpression: PsiElement, elseExpression: PsiElement?, scopeDepth: Int): LLVMVariable? { - val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1) - val thenLabel = codeBuilder.getNewLabel() - val elseLabel = codeBuilder.getNewLabel() - val endLabel = codeBuilder.getNewLabel() + val conditionResult = evaluateBinaryExpression(condition, scopeDepth + 1) + val thenLabel = codeBuilder.getNewLabel(prefix = "if") + val elseLabel = codeBuilder.getNewLabel(prefix = "if") + val endLabel = codeBuilder.getNewLabel(prefix = "if") codeBuilder.addCondition(conditionResult, thenLabel, elseLabel) @@ -271,6 +297,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null when (assignExpression) { + //TODO resolving is LLVMVariable -> { assignExpression.kotlinName = identifier!!.text assignExpression.pointer = false @@ -278,6 +305,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction } is LLVMConstant -> { val newVar = variableManager.getVariable(identifier!!.text, LLVMIntType(), pointer = true) + codeBuilder.addConstant(newVar, assignExpression) variableManager.addVariable(identifier.text, newVar, scopeDepth) } @@ -288,7 +316,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction codeBuilder.addLLVMCode(assignExpression.call(result).toString()) } else -> { - codeBuilder.addAssignment(LLVMVariable("%${identifier!!.text}", null, identifier.text), assignExpression) + codeBuilder.addAssignment(LLVMVariable("%${identifier!!.text}", LLVMIntType(), identifier.text), assignExpression) } } return null diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt index 2df1ca51551..807db2fe17c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt @@ -28,7 +28,7 @@ class VariableManager { val ourVersion = variableVersion.getOrDefault(name, 0) + 1 variableVersion.put(name, ourVersion) - return LLVMVariable("%managed.${name}.${ourVersion}", kotlinName = name, type = type, pointer = pointer) + return LLVMVariable("%managed.$name.$ourVersion", kotlinName = name, type = type, pointer = pointer) } } \ 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 3cdffb4b557..74f118c31bc 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -24,14 +24,14 @@ class LLVMBuilder(val arm: Boolean) { } } - fun getNewVariable(type: LLVMType?, pointer: Boolean = false, kotlinName: String? = null): LLVMVariable { + fun getNewVariable(type: LLVMType, pointer: Boolean = false, kotlinName: String? = null): LLVMVariable { variableCount++ return LLVMVariable("%var$variableCount", type, kotlinName, pointer) } - fun getNewLabel(scope: LLVMScope = LLVMLocalScope()): LLVMLabel { + fun getNewLabel(scope: LLVMScope = LLVMLocalScope(), prefix: String): LLVMLabel { labelCount++ - return LLVMLabel("label$labelCount", scope) + return LLVMLabel("label.$prefix.$labelCount", scope) } fun addLLVMCode(code: String) { @@ -117,36 +117,38 @@ class LLVMBuilder(val arm: Boolean) { llvmCode.appendln(code) } - fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true) { - addVariableByRef(LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, true), llvmVariable, store) + fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable { + val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, true) + addVariableByRef(allocVar, llvmVariable, store) + return allocVar } fun loadVariable(target: LLVMVariable, source: LLVMVariable) { - val code = "$target = load ${target.type}, ${source.getType()} $source, align ${target.type?.align!!}" + val code = "$target = load ${target.type}, ${source.getType()} $source, align ${target.type.align}" llvmCode.appendln(code) } fun allocVar(target: LLVMVariable) { - llvmCode.appendln("$target = alloca ${target.type}, align ${target.type?.align!!}") + llvmCode.appendln("$target = alloca ${target.type}, align ${target.type.align}") } fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable, store: Boolean) { - llvmCode.appendln("$targetVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.align}") + llvmCode.appendln("$targetVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type.align}") if (store) { - llvmCode.appendln("store ${sourceVariable.getType()} $sourceVariable, ${targetVariable.getType()} $targetVariable, align ${targetVariable.type?.align}") + llvmCode.appendln("store ${sourceVariable.getType()} $sourceVariable, ${targetVariable.getType()} $targetVariable, align ${targetVariable.type.align}") } } fun addConstant(allocVariable: LLVMVariable, constantValue: LLVMConstant) { - llvmCode.appendln("$allocVariable = alloca ${allocVariable.type}, align ${allocVariable.type?.align}") - llvmCode.appendln("store ${allocVariable.type} $constantValue, ${allocVariable.getType()} $allocVariable, align ${allocVariable.type?.align}") + llvmCode.appendln("$allocVariable = alloca ${allocVariable.type}, align ${allocVariable.type.align}") + llvmCode.appendln("store ${allocVariable.type} $constantValue, ${allocVariable.getType()} $allocVariable, align ${allocVariable.type.align}") } fun loadAndGetVariable(source: LLVMVariable): LLVMVariable { assert(!source.pointer) val target = getNewVariable(source.type, source.pointer, source.kotlinName) - val code = "$target = load ${target.type}, ${source.getType()} $source, align ${target.type?.align!!}" + val code = "$target = load ${target.type}, ${source.getType()} $source, align ${target.type.align}" llvmCode.appendln(code) return target } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt index 329341343f1..b1a0b19593f 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMClassVariable.kt @@ -3,4 +3,4 @@ package org.kotlinnative.translator.llvm import org.kotlinnative.translator.llvm.types.LLVMType -class LLVMClassVariable(label: String, type: LLVMType? = null, val offset: Int = 0) : LLVMVariable(label, type) +class LLVMClassVariable(label: String, type: LLVMType, val offset: Int = 0) : LLVMVariable(label, type) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt index 7bc2816c44c..a98bdb25570 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt @@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm import org.kotlinnative.translator.llvm.types.LLVMType -open class LLVMVariable(val label: String, override val type: LLVMType? = null, var kotlinName: String? = null, override var pointer: Boolean = false) : LLVMSingleValue() { +open class LLVMVariable(val label: String, override val type: LLVMType, var kotlinName: String? = null, override var pointer: Boolean = false) : LLVMSingleValue() { override fun getType(): String = type.toString() + if (pointer) "*" else ""